>2]=f;return 0;},k:function(a){a=G(a);window.console.log(a);},i:function(a){a=G(a);return Date.parse(a);},l:function(a,b,d,e){a=G(a);b=G(b);d=G(d);d=`Quickjs -- ${a}: ${b}\n${d}`;0!==e?window.alert(d):window.console.error(d);}};(function(){function a(f){c.asm=f.exports;x=c.asm.m;ba();O=c.asm.v;da.unshift(c.asm.n);P--;c.monitorRunDependencies&&c.monitorRunDependencies(P);0==P&&(null!==Q&&(clearInterval(Q),Q=null),R&&(f=R,R=null,f()));}function b(f){a(f.instance);}function d(f){return ka().then(function(g){return WebAssembly.instantiate(g,e);}).then(function(g){return g;}).then(f,function(g){u("failed to asynchronously prepare wasm: "+g);w(g);});}var e={a:oa};P++;c.monitorRunDependencies&&c.monitorRunDependencies(P);if(c.instantiateWasm)try{return c.instantiateWasm(e,a);}catch(f){return u("Module.instantiateWasm callback failed with error: "+f),!1;}(function(){return v||"function"!=typeof WebAssembly.instantiateStreaming||T(U)||"function"!=typeof fetch?d(b):fetch(U,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(b,function(g){u("wasm streaming compile failed: "+g);u("falling back to ArrayBuffer instantiation");return d(b);});});})().catch(n);return{};})();c.___wasm_call_ctors=function(){return(c.___wasm_call_ctors=c.asm.n).apply(null,arguments);};c._evalInSandbox=function(){return(c._evalInSandbox=c.asm.o).apply(null,arguments);};c._nukeSandbox=function(){return(c._nukeSandbox=c.asm.p).apply(null,arguments);};c._init=function(){return(c._init=c.asm.q).apply(null,arguments);};c._commFun=function(){return(c._commFun=c.asm.r).apply(null,arguments);};c._dumpMemoryUse=function(){return(c._dumpMemoryUse=c.asm.s).apply(null,arguments);};var L=c._malloc=function(){return(L=c._malloc=c.asm.t).apply(null,arguments);};c._free=function(){return(c._free=c.asm.u).apply(null,arguments);};var E=c.stackSave=function(){return(E=c.stackSave=c.asm.w).apply(null,arguments);},F=c.stackRestore=function(){return(F=c.stackRestore=c.asm.x).apply(null,arguments);},A=c.stackAlloc=function(){return(A=c.stackAlloc=c.asm.y).apply(null,arguments);};c.ccall=z;c.cwrap=function(a,b,d,e){d=d||[];var f=d.every(function(g){return"number"===g;});return"string"!==b&&f&&!e?c["_"+a]:function(){return z(a,b,d,arguments,e);};};c.stringToNewUTF8=X;var Y;R=function pa(){Y||Z();Y||(R=pa);};function Z(){function a(){if(!Y&&(Y=!0,c.calledRun=!0,!y)){V(da);h(c);if(c.onRuntimeInitialized)c.onRuntimeInitialized();if(c.postRun)for("function"==typeof c.postRun&&(c.postRun=[c.postRun]);c.postRun.length;){var b=c.postRun.shift();ea.unshift(b);}V(ea);}}if(!(0 {
+ if (typeof callbackId !== "number" || typeof nMilliseconds !== "number") {
+ return;
+ }
+ if (callbackId === 0) {
+ this.win.clearTimeout(this.timeoutIds.get(callbackId));
+ }
+ const id = this.win.setTimeout(() => {
+ this.timeoutIds.delete(callbackId);
+ this.callSandboxFunction("timeoutCb", {
+ callbackId,
+ interval: false
+ });
+ }, nMilliseconds);
+ this.timeoutIds.set(callbackId, id);
+ },
+ clearTimeout: callbackId => {
+ this.win.clearTimeout(this.timeoutIds.get(callbackId));
+ this.timeoutIds.delete(callbackId);
+ },
+ setInterval: (callbackId, nMilliseconds) => {
+ if (typeof callbackId !== "number" || typeof nMilliseconds !== "number") {
+ return;
+ }
+ const id = this.win.setInterval(() => {
+ this.callSandboxFunction("timeoutCb", {
+ callbackId,
+ interval: true
+ });
+ }, nMilliseconds);
+ this.timeoutIds.set(callbackId, id);
+ },
+ clearInterval: callbackId => {
+ this.win.clearInterval(this.timeoutIds.get(callbackId));
+ this.timeoutIds.delete(callbackId);
+ },
+ alert: cMsg => {
+ if (typeof cMsg !== "string") {
+ return;
+ }
+ this.win.alert(cMsg);
+ },
+ confirm: cMsg => {
+ if (typeof cMsg !== "string") {
+ return false;
+ }
+ return this.win.confirm(cMsg);
+ },
+ prompt: (cQuestion, cDefault) => {
+ if (typeof cQuestion !== "string" || typeof cDefault !== "string") {
+ return null;
+ }
+ return this.win.prompt(cQuestion, cDefault);
+ },
+ parseURL: cUrl => {
+ const url = new this.win.URL(cUrl);
+ const props = ["hash", "host", "hostname", "href", "origin", "password", "pathname", "port", "protocol", "search", "searchParams", "username"];
+ return Object.fromEntries(props.map(name => [name, url[name].toString()]));
+ },
+ send: data => {
+ if (!data) {
+ return;
+ }
+ const event = new this.win.CustomEvent("updatefromsandbox", {
+ detail: this.importValueFromSandbox(data)
+ });
+ this.win.dispatchEvent(event);
+ }
+ };
+ Object.setPrototypeOf(externals, null);
+ return (name, args) => {
+ try {
+ const result = externals[name](...args);
+ return this.exportValueToSandbox(result);
+ } catch (error) {
+ throw this.createErrorForSandbox(error?.toString() ?? "");
+ }
+ };
+ }
+}
+;// CONCATENATED MODULE: ./src/pdf.sandbox.js
+
+
+const pdfjsVersion = '4.0.379';
+const pdfjsBuild = '9e14d04fd';
+class SandboxSupport extends SandboxSupportBase {
+ exportValueToSandbox(val) {
+ return JSON.stringify(val);
+ }
+ importValueFromSandbox(val) {
+ return val;
+ }
+ createErrorForSandbox(errorMessage) {
+ return new Error(errorMessage);
+ }
+}
+class Sandbox {
+ constructor(win, module) {
+ this.support = new SandboxSupport(win, this);
+ module.externalCall = this.support.createSandboxExternals();
+ this._module = module;
+ this._alertOnError = 0;
+ }
+ create(data) {
+ const code = ['var __webpack_exports__ = globalThis.pdfjsSandbox = {};\n\n;// CONCATENATED MODULE: ./src/scripting_api/constants.js\nconst Border = Object.freeze({\n s: "solid",\n d: "dashed",\n b: "beveled",\n i: "inset",\n u: "underline"\n});\nconst Cursor = Object.freeze({\n visible: 0,\n hidden: 1,\n delay: 2\n});\nconst Display = Object.freeze({\n visible: 0,\n hidden: 1,\n noPrint: 2,\n noView: 3\n});\nconst Font = Object.freeze({\n Times: "Times-Roman",\n TimesB: "Times-Bold",\n TimesI: "Times-Italic",\n TimesBI: "Times-BoldItalic",\n Helv: "Helvetica",\n HelvB: "Helvetica-Bold",\n HelvI: "Helvetica-Oblique",\n HelvBI: "Helvetica-BoldOblique",\n Cour: "Courier",\n CourB: "Courier-Bold",\n CourI: "Courier-Oblique",\n CourBI: "Courier-BoldOblique",\n Symbol: "Symbol",\n ZapfD: "ZapfDingbats",\n KaGo: "HeiseiKakuGo-W5-UniJIS-UCS2-H",\n KaMi: "HeiseiMin-W3-UniJIS-UCS2-H"\n});\nconst Highlight = Object.freeze({\n n: "none",\n i: "invert",\n p: "push",\n o: "outline"\n});\nconst Position = Object.freeze({\n textOnly: 0,\n iconOnly: 1,\n iconTextV: 2,\n textIconV: 3,\n iconTextH: 4,\n textIconH: 5,\n overlay: 6\n});\nconst ScaleHow = Object.freeze({\n proportional: 0,\n anamorphic: 1\n});\nconst ScaleWhen = Object.freeze({\n always: 0,\n never: 1,\n tooBig: 2,\n tooSmall: 3\n});\nconst Style = Object.freeze({\n ch: "check",\n cr: "cross",\n di: "diamond",\n ci: "circle",\n st: "star",\n sq: "square"\n});\nconst Trans = Object.freeze({\n blindsH: "BlindsHorizontal",\n blindsV: "BlindsVertical",\n boxI: "BoxIn",\n boxO: "BoxOut",\n dissolve: "Dissolve",\n glitterD: "GlitterDown",\n glitterR: "GlitterRight",\n glitterRD: "GlitterRightDown",\n random: "Random",\n replace: "Replace",\n splitHI: "SplitHorizontalIn",\n splitHO: "SplitHorizontalOut",\n splitVI: "SplitVerticalIn",\n splitVO: "SplitVerticalOut",\n wipeD: "WipeDown",\n wipeL: "WipeLeft",\n wipeR: "WipeRight",\n wipeU: "WipeUp"\n});\nconst ZoomType = Object.freeze({\n none: "NoVary",\n fitP: "FitPage",\n fitW: "FitWidth",\n fitH: "FitHeight",\n fitV: "FitVisibleWidth",\n pref: "Preferred",\n refW: "ReflowWidth"\n});\nconst GlobalConstants = Object.freeze({\n IDS_GREATER_THAN: "Invalid value: must be greater than or equal to % s.",\n IDS_GT_AND_LT: "Invalid value: must be greater than or equal to % s " + "and less than or equal to % s.",\n IDS_LESS_THAN: "Invalid value: must be less than or equal to % s.",\n IDS_INVALID_MONTH: "** Invalid **",\n IDS_INVALID_DATE: "Invalid date / time: please ensure that the date / time exists.Field",\n IDS_INVALID_DATE2: " should match format ",\n IDS_INVALID_VALUE: "The value entered does not match the format of the field",\n IDS_AM: "am",\n IDS_PM: "pm",\n IDS_MONTH_INFO: "January[1] February[2] March[3] April[4] May[5] " + "June[6] July[7] August[8] September[9] October[10] " + "November[11] December[12] Sept[9] Jan[1] Feb[2] Mar[3] " + "Apr[4] Jun[6] Jul[7] Aug[8] Sep[9] Oct[10] Nov[11] Dec[12]",\n IDS_STARTUP_CONSOLE_MSG: "** ^ _ ^ **",\n RE_NUMBER_ENTRY_DOT_SEP: ["[+-]?\\\\d*\\\\.?\\\\d*"],\n RE_NUMBER_COMMIT_DOT_SEP: ["[+-]?\\\\d+(\\\\.\\\\d+)?", "[+-]?\\\\.\\\\d+", "[+-]?\\\\d+\\\\."],\n RE_NUMBER_ENTRY_COMMA_SEP: ["[+-]?\\\\d*,?\\\\d*"],\n RE_NUMBER_COMMIT_COMMA_SEP: ["[+-]?\\\\d+([.,]\\\\d+)?", "[+-]?[.,]\\\\d+", "[+-]?\\\\d+[.,]"],\n RE_ZIP_ENTRY: ["\\\\d{0,5}"],\n RE_ZIP_COMMIT: ["\\\\d{5}"],\n RE_ZIP4_ENTRY: ["\\\\d{0,5}(\\\\.|[- ])?\\\\d{0,4}"],\n RE_ZIP4_COMMIT: ["\\\\d{5}(\\\\.|[- ])?\\\\d{4}"],\n RE_PHONE_ENTRY: ["\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,4}", "\\\\(\\\\d{0,3}", "\\\\(\\\\d{0,3}\\\\)(\\\\.|[- ])?\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,4}", "\\\\(\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,4}", "\\\\d{0,3}\\\\)(\\\\.|[- ])?\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,4}", "011(\\\\.|[- \\\\d])*"],\n RE_PHONE_COMMIT: ["\\\\d{3}(\\\\.|[- ])?\\\\d{4}", "\\\\d{3}(\\\\.|[- ])?\\\\d{3}(\\\\.|[- ])?\\\\d{4}", "\\\\(\\\\d{3}\\\\)(\\\\.|[- ])?\\\\d{3}(\\\\.|[- ])?\\\\d{4}", "011(\\\\.|[- \\\\d])*"],\n RE_SSN_ENTRY: ["\\\\d{0,3}(\\\\.|[- ])?\\\\d{0,2}(\\\\.|[- ])?\\\\d{0,4}"],\n RE_SSN_COMMIT: ["\\\\d{3}(\\\\.|[- ])?\\\\d{2}(\\\\.|[- ])?\\\\d{4}"]\n});\n\n;// CONCATENATED MODULE: ./src/scripting_api/common.js\nconst FieldType = {\n none: 0,\n number: 1,\n percent: 2,\n date: 3,\n time: 4\n};\nfunction createActionsMap(actions) {\n const actionsMap = new Map();\n if (actions) {\n for (const [eventType, actionsForEvent] of Object.entries(actions)) {\n actionsMap.set(eventType, actionsForEvent);\n }\n }\n return actionsMap;\n}\nfunction getFieldType(actions) {\n let format = actions.get("Format");\n if (!format) {\n return FieldType.none;\n }\n format = format[0];\n format = format.trim();\n if (format.startsWith("AFNumber_")) {\n return FieldType.number;\n }\n if (format.startsWith("AFPercent_")) {\n return FieldType.percent;\n }\n if (format.startsWith("AFDate_")) {\n return FieldType.date;\n }\n if (format.startsWith("AFTime_")) {\n return FieldType.time;\n }\n return FieldType.none;\n}\n\n;// CONCATENATED MODULE: ./src/shared/scripting_utils.js\nfunction makeColorComp(n) {\n return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0");\n}\nfunction scaleAndClamp(x) {\n return Math.max(0, Math.min(255, 255 * x));\n}\nclass ColorConverters {\n static CMYK_G([c, y, m, k]) {\n return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)];\n }\n static G_CMYK([g]) {\n return ["CMYK", 0, 0, 0, 1 - g];\n }\n static G_RGB([g]) {\n return ["RGB", g, g, g];\n }\n static G_rgb([g]) {\n g = scaleAndClamp(g);\n return [g, g, g];\n }\n static G_HTML([g]) {\n const G = makeColorComp(g);\n return `#${G}${G}${G}`;\n }\n static RGB_G([r, g, b]) {\n return ["G", 0.3 * r + 0.59 * g + 0.11 * b];\n }\n static RGB_rgb(color) {\n return color.map(scaleAndClamp);\n }\n static RGB_HTML(color) {\n return `#${color.map(makeColorComp).join("")}`;\n }\n static T_HTML() {\n return "#00000000";\n }\n static T_rgb() {\n return [null];\n }\n static CMYK_RGB([c, y, m, k]) {\n return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)];\n }\n static CMYK_rgb([c, y, m, k]) {\n return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))];\n }\n static CMYK_HTML(components) {\n const rgb = this.CMYK_RGB(components).slice(1);\n return this.RGB_HTML(rgb);\n }\n static RGB_CMYK([r, g, b]) {\n const c = 1 - r;\n const m = 1 - g;\n const y = 1 - b;\n const k = Math.min(c, m, y);\n return ["CMYK", c, m, y, k];\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/pdf_object.js\nclass PDFObject {\n constructor(data) {\n this._expandos = Object.create(null);\n this._send = data.send || null;\n this._id = data.id || null;\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/color.js\n\n\nclass Color extends PDFObject {\n constructor() {\n super({});\n this.transparent = ["T"];\n this.black = ["G", 0];\n this.white = ["G", 1];\n this.red = ["RGB", 1, 0, 0];\n this.green = ["RGB", 0, 1, 0];\n this.blue = ["RGB", 0, 0, 1];\n this.cyan = ["CMYK", 1, 0, 0, 0];\n this.magenta = ["CMYK", 0, 1, 0, 0];\n this.yellow = ["CMYK", 0, 0, 1, 0];\n this.dkGray = ["G", 0.25];\n this.gray = ["G", 0.5];\n this.ltGray = ["G", 0.75];\n }\n static _isValidSpace(cColorSpace) {\n return typeof cColorSpace === "string" && (cColorSpace === "T" || cColorSpace === "G" || cColorSpace === "RGB" || cColorSpace === "CMYK");\n }\n static _isValidColor(colorArray) {\n if (!Array.isArray(colorArray) || colorArray.length === 0) {\n return false;\n }\n const space = colorArray[0];\n if (!Color._isValidSpace(space)) {\n return false;\n }\n switch (space) {\n case "T":\n if (colorArray.length !== 1) {\n return false;\n }\n break;\n case "G":\n if (colorArray.length !== 2) {\n return false;\n }\n break;\n case "RGB":\n if (colorArray.length !== 4) {\n return false;\n }\n break;\n case "CMYK":\n if (colorArray.length !== 5) {\n return false;\n }\n break;\n default:\n return false;\n }\n return colorArray.slice(1).every(c => typeof c === "number" && c >= 0 && c <= 1);\n }\n static _getCorrectColor(colorArray) {\n return Color._isValidColor(colorArray) ? colorArray : ["G", 0];\n }\n convert(colorArray, cColorSpace) {\n if (!Color._isValidSpace(cColorSpace)) {\n return this.black;\n }\n if (cColorSpace === "T") {\n return ["T"];\n }\n colorArray = Color._getCorrectColor(colorArray);\n if (colorArray[0] === cColorSpace) {\n return colorArray;\n }\n if (colorArray[0] === "T") {\n return this.convert(this.black, cColorSpace);\n }\n return ColorConverters[`${colorArray[0]}_${cColorSpace}`](colorArray.slice(1));\n }\n equal(colorArray1, colorArray2) {\n colorArray1 = Color._getCorrectColor(colorArray1);\n colorArray2 = Color._getCorrectColor(colorArray2);\n if (colorArray1[0] === "T" || colorArray2[0] === "T") {\n return colorArray1[0] === "T" && colorArray2[0] === "T";\n }\n if (colorArray1[0] !== colorArray2[0]) {\n colorArray2 = this.convert(colorArray2, colorArray1[0]);\n }\n return colorArray1.slice(1).every((c, i) => c === colorArray2[i + 1]);\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/field.js\n\n\n\nclass Field extends PDFObject {\n constructor(data) {\n super(data);\n this.alignment = data.alignment || "left";\n this.borderStyle = data.borderStyle || "";\n this.buttonAlignX = data.buttonAlignX || 50;\n this.buttonAlignY = data.buttonAlignY || 50;\n this.buttonFitBounds = data.buttonFitBounds;\n this.buttonPosition = data.buttonPosition;\n this.buttonScaleHow = data.buttonScaleHow;\n this.ButtonScaleWhen = data.buttonScaleWhen;\n this.calcOrderIndex = data.calcOrderIndex;\n this.comb = data.comb;\n this.commitOnSelChange = data.commitOnSelChange;\n this.currentValueIndices = data.currentValueIndices;\n this.defaultStyle = data.defaultStyle;\n this.defaultValue = data.defaultValue;\n this.doNotScroll = data.doNotScroll;\n this.doNotSpellCheck = data.doNotSpellCheck;\n this.delay = data.delay;\n this.display = data.display;\n this.doc = data.doc.wrapped;\n this.editable = data.editable;\n this.exportValues = data.exportValues;\n this.fileSelect = data.fileSelect;\n this.hidden = data.hidden;\n this.highlight = data.highlight;\n this.lineWidth = data.lineWidth;\n this.multiline = data.multiline;\n this.multipleSelection = !!data.multipleSelection;\n this.name = data.name;\n this.password = data.password;\n this.print = data.print;\n this.radiosInUnison = data.radiosInUnison;\n this.readonly = data.readonly;\n this.rect = data.rect;\n this.required = data.required;\n this.richText = data.richText;\n this.richValue = data.richValue;\n this.style = data.style;\n this.submitName = data.submitName;\n this.textFont = data.textFont;\n this.textSize = data.textSize;\n this.type = data.type;\n this.userName = data.userName;\n this._actions = createActionsMap(data.actions);\n this._browseForFileToSubmit = data.browseForFileToSubmit || null;\n this._buttonCaption = null;\n this._buttonIcon = null;\n this._charLimit = data.charLimit;\n this._children = null;\n this._currentValueIndices = data.currentValueIndices || 0;\n this._document = data.doc;\n this._fieldPath = data.fieldPath;\n this._fillColor = data.fillColor || ["T"];\n this._isChoice = Array.isArray(data.items);\n this._items = data.items || [];\n this._hasValue = data.hasOwnProperty("value");\n this._page = data.page || 0;\n this._strokeColor = data.strokeColor || ["G", 0];\n this._textColor = data.textColor || ["G", 0];\n this._value = null;\n this._kidIds = data.kidIds || null;\n this._fieldType = getFieldType(this._actions);\n this._siblings = data.siblings || null;\n this._rotation = data.rotation || 0;\n this._globalEval = data.globalEval;\n this._appObjects = data.appObjects;\n this.value = data.value || "";\n }\n get currentValueIndices() {\n if (!this._isChoice) {\n return 0;\n }\n return this._currentValueIndices;\n }\n set currentValueIndices(indices) {\n if (!this._isChoice) {\n return;\n }\n if (!Array.isArray(indices)) {\n indices = [indices];\n }\n if (!indices.every(i => typeof i === "number" && Number.isInteger(i) && i >= 0 && i < this.numItems)) {\n return;\n }\n indices.sort();\n if (this.multipleSelection) {\n this._currentValueIndices = indices;\n this._value = [];\n indices.forEach(i => {\n this._value.push(this._items[i].displayValue);\n });\n } else if (indices.length > 0) {\n indices = indices.splice(1, indices.length - 1);\n this._currentValueIndices = indices[0];\n this._value = this._items[this._currentValueIndices];\n }\n this._send({\n id: this._id,\n indices\n });\n }\n get fillColor() {\n return this._fillColor;\n }\n set fillColor(color) {\n if (Color._isValidColor(color)) {\n this._fillColor = color;\n }\n }\n get bgColor() {\n return this.fillColor;\n }\n set bgColor(color) {\n this.fillColor = color;\n }\n get charLimit() {\n return this._charLimit;\n }\n set charLimit(limit) {\n if (typeof limit !== "number") {\n throw new Error("Invalid argument value");\n }\n this._charLimit = Math.max(0, Math.floor(limit));\n }\n get numItems() {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n return this._items.length;\n }\n set numItems(_) {\n throw new Error("field.numItems is read-only");\n }\n get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(color) {\n if (Color._isValidColor(color)) {\n this._strokeColor = color;\n }\n }\n get borderColor() {\n return this.strokeColor;\n }\n set borderColor(color) {\n this.strokeColor = color;\n }\n get page() {\n return this._page;\n }\n set page(_) {\n throw new Error("field.page is read-only");\n }\n get rotation() {\n return this._rotation;\n }\n set rotation(angle) {\n angle = Math.floor(angle);\n if (angle % 90 !== 0) {\n throw new Error("Invalid rotation: must be a multiple of 90");\n }\n angle %= 360;\n if (angle < 0) {\n angle += 360;\n }\n this._rotation = angle;\n }\n get textColor() {\n return this._textColor;\n }\n set textColor(color) {\n if (Color._isValidColor(color)) {\n this._textColor = color;\n }\n }\n get fgColor() {\n return this.textColor;\n }\n set fgColor(color) {\n this.textColor = color;\n }\n get value() {\n return this._value;\n }\n set value(value) {\n if (this._isChoice) {\n this._setChoiceValue(value);\n return;\n }\n if (value === "" || typeof value !== "string" || this._fieldType >= FieldType.date) {\n this._originalValue = undefined;\n this._value = value;\n return;\n }\n this._originalValue = value;\n const _value = value.trim().replace(",", ".");\n this._value = !isNaN(_value) ? parseFloat(_value) : value;\n }\n _getValue() {\n return this._originalValue ?? this.value;\n }\n _setChoiceValue(value) {\n if (this.multipleSelection) {\n if (!Array.isArray(value)) {\n value = [value];\n }\n const values = new Set(value);\n if (Array.isArray(this._currentValueIndices)) {\n this._currentValueIndices.length = 0;\n this._value.length = 0;\n } else {\n this._currentValueIndices = [];\n this._value = [];\n }\n this._items.forEach((item, i) => {\n if (values.has(item.exportValue)) {\n this._currentValueIndices.push(i);\n this._value.push(item.exportValue);\n }\n });\n } else {\n if (Array.isArray(value)) {\n value = value[0];\n }\n const index = this._items.findIndex(({\n exportValue\n }) => value === exportValue);\n if (index !== -1) {\n this._currentValueIndices = index;\n this._value = this._items[index].exportValue;\n }\n }\n }\n get valueAsString() {\n return (this._value ?? "").toString();\n }\n set valueAsString(_) {}\n browseForFileToSubmit() {\n if (this._browseForFileToSubmit) {\n this._browseForFileToSubmit();\n }\n }\n buttonGetCaption(nFace = 0) {\n if (this._buttonCaption) {\n return this._buttonCaption[nFace];\n }\n return "";\n }\n buttonGetIcon(nFace = 0) {\n if (this._buttonIcon) {\n return this._buttonIcon[nFace];\n }\n return null;\n }\n buttonImportIcon(cPath = null, nPave = 0) {}\n buttonSetCaption(cCaption, nFace = 0) {\n if (!this._buttonCaption) {\n this._buttonCaption = ["", "", ""];\n }\n this._buttonCaption[nFace] = cCaption;\n }\n buttonSetIcon(oIcon, nFace = 0) {\n if (!this._buttonIcon) {\n this._buttonIcon = [null, null, null];\n }\n this._buttonIcon[nFace] = oIcon;\n }\n checkThisBox(nWidget, bCheckIt = true) {}\n clearItems() {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n this._items = [];\n this._send({\n id: this._id,\n clear: null\n });\n }\n deleteItemAt(nIdx = null) {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n if (!this.numItems) {\n return;\n }\n if (nIdx === null) {\n nIdx = Array.isArray(this._currentValueIndices) ? this._currentValueIndices[0] : this._currentValueIndices;\n nIdx ||= 0;\n }\n if (nIdx < 0 || nIdx >= this.numItems) {\n nIdx = this.numItems - 1;\n }\n this._items.splice(nIdx, 1);\n if (Array.isArray(this._currentValueIndices)) {\n let index = this._currentValueIndices.findIndex(i => i >= nIdx);\n if (index !== -1) {\n if (this._currentValueIndices[index] === nIdx) {\n this._currentValueIndices.splice(index, 1);\n }\n for (const ii = this._currentValueIndices.length; index < ii; index++) {\n --this._currentValueIndices[index];\n }\n }\n } else if (this._currentValueIndices === nIdx) {\n this._currentValueIndices = this.numItems > 0 ? 0 : -1;\n } else if (this._currentValueIndices > nIdx) {\n --this._currentValueIndices;\n }\n this._send({\n id: this._id,\n remove: nIdx\n });\n }\n getItemAt(nIdx = -1, bExportValue = false) {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n if (nIdx < 0 || nIdx >= this.numItems) {\n nIdx = this.numItems - 1;\n }\n const item = this._items[nIdx];\n return bExportValue ? item.exportValue : item.displayValue;\n }\n getArray() {\n if (this._kidIds) {\n const array = [];\n const fillArrayWithKids = kidIds => {\n for (const id of kidIds) {\n const obj = this._appObjects[id];\n if (!obj) {\n continue;\n }\n if (obj.obj._hasValue) {\n array.push(obj.wrapped);\n }\n if (obj.obj._kidIds) {\n fillArrayWithKids(obj.obj._kidIds);\n }\n }\n };\n fillArrayWithKids(this._kidIds);\n return array;\n }\n if (this._children === null) {\n this._children = this._document.obj._getTerminalChildren(this._fieldPath);\n }\n return this._children;\n }\n getLock() {\n return undefined;\n }\n isBoxChecked(nWidget) {\n return false;\n }\n isDefaultChecked(nWidget) {\n return false;\n }\n insertItemAt(cName, cExport = undefined, nIdx = 0) {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n if (!cName) {\n return;\n }\n if (nIdx < 0 || nIdx > this.numItems) {\n nIdx = this.numItems;\n }\n if (this._items.some(({\n displayValue\n }) => displayValue === cName)) {\n return;\n }\n if (cExport === undefined) {\n cExport = cName;\n }\n const data = {\n displayValue: cName,\n exportValue: cExport\n };\n this._items.splice(nIdx, 0, data);\n if (Array.isArray(this._currentValueIndices)) {\n let index = this._currentValueIndices.findIndex(i => i >= nIdx);\n if (index !== -1) {\n for (const ii = this._currentValueIndices.length; index < ii; index++) {\n ++this._currentValueIndices[index];\n }\n }\n } else if (this._currentValueIndices >= nIdx) {\n ++this._currentValueIndices;\n }\n this._send({\n id: this._id,\n insert: {\n index: nIdx,\n ...data\n }\n });\n }\n setAction(cTrigger, cScript) {\n if (typeof cTrigger !== "string" || typeof cScript !== "string") {\n return;\n }\n if (!(cTrigger in this._actions)) {\n this._actions[cTrigger] = [];\n }\n this._actions[cTrigger].push(cScript);\n }\n setFocus() {\n this._send({\n id: this._id,\n focus: true\n });\n }\n setItems(oArray) {\n if (!this._isChoice) {\n throw new Error("Not a choice widget");\n }\n this._items.length = 0;\n for (const element of oArray) {\n let displayValue, exportValue;\n if (Array.isArray(element)) {\n displayValue = element[0]?.toString() || "";\n exportValue = element[1]?.toString() || "";\n } else {\n displayValue = exportValue = element?.toString() || "";\n }\n this._items.push({\n displayValue,\n exportValue\n });\n }\n this._currentValueIndices = 0;\n this._send({\n id: this._id,\n items: this._items\n });\n }\n setLock() {}\n signatureGetModifications() {}\n signatureGetSeedValue() {}\n signatureInfo() {}\n signatureSetSeedValue() {}\n signatureSign() {}\n signatureValidate() {}\n _isButton() {\n return false;\n }\n _reset() {\n this.value = this.defaultValue;\n }\n _runActions(event) {\n const eventName = event.name;\n if (!this._actions.has(eventName)) {\n return false;\n }\n const actions = this._actions.get(eventName);\n try {\n for (const action of actions) {\n this._globalEval(action);\n }\n } catch (error) {\n event.rc = false;\n throw error;\n }\n return true;\n }\n}\nclass RadioButtonField extends Field {\n constructor(otherButtons, data) {\n super(data);\n this.exportValues = [this.exportValues];\n this._radioIds = [this._id];\n this._radioActions = [this._actions];\n for (const radioData of otherButtons) {\n this.exportValues.push(radioData.exportValues);\n this._radioIds.push(radioData.id);\n this._radioActions.push(createActionsMap(radioData.actions));\n if (this._value === radioData.exportValues) {\n this._id = radioData.id;\n }\n }\n this._hasBeenInitialized = true;\n this._value = data.value || "";\n }\n get value() {\n return this._value;\n }\n set value(value) {\n if (!this._hasBeenInitialized) {\n return;\n }\n if (value === null || value === undefined) {\n this._value = "";\n }\n const i = this.exportValues.indexOf(value);\n if (0 <= i && i < this._radioIds.length) {\n this._id = this._radioIds[i];\n this._value = value;\n } else if (value === "Off" && this._radioIds.length === 2) {\n const nextI = (1 + this._radioIds.indexOf(this._id)) % 2;\n this._id = this._radioIds[nextI];\n this._value = this.exportValues[nextI];\n }\n }\n checkThisBox(nWidget, bCheckIt = true) {\n if (nWidget < 0 || nWidget >= this._radioIds.length || !bCheckIt) {\n return;\n }\n this._id = this._radioIds[nWidget];\n this._value = this.exportValues[nWidget];\n this._send({\n id: this._id,\n value: this._value\n });\n }\n isBoxChecked(nWidget) {\n return nWidget >= 0 && nWidget < this._radioIds.length && this._id === this._radioIds[nWidget];\n }\n isDefaultChecked(nWidget) {\n return nWidget >= 0 && nWidget < this.exportValues.length && this.defaultValue === this.exportValues[nWidget];\n }\n _getExportValue(state) {\n const i = this._radioIds.indexOf(this._id);\n return this.exportValues[i];\n }\n _runActions(event) {\n const i = this._radioIds.indexOf(this._id);\n this._actions = this._radioActions[i];\n return super._runActions(event);\n }\n _isButton() {\n return true;\n }\n}\nclass CheckboxField extends RadioButtonField {\n get value() {\n return this._value;\n }\n set value(value) {\n if (!value || value === "Off") {\n this._value = "Off";\n } else {\n super.value = value;\n }\n }\n _getExportValue(state) {\n return state ? super._getExportValue(state) : "Off";\n }\n isBoxChecked(nWidget) {\n if (this._value === "Off") {\n return false;\n }\n return super.isBoxChecked(nWidget);\n }\n isDefaultChecked(nWidget) {\n if (this.defaultValue === "Off") {\n return this._value === "Off";\n }\n return super.isDefaultChecked(nWidget);\n }\n checkThisBox(nWidget, bCheckIt = true) {\n if (nWidget < 0 || nWidget >= this._radioIds.length) {\n return;\n }\n this._id = this._radioIds[nWidget];\n this._value = bCheckIt ? this.exportValues[nWidget] : "Off";\n this._send({\n id: this._id,\n value: this._value\n });\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/aform.js\n\nclass AForm {\n constructor(document, app, util, color) {\n this._document = document;\n this._app = app;\n this._util = util;\n this._color = color;\n this._dateFormats = ["m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm", "d-mmm-yy", "dd-mmm-yy", "yy-mm-dd", "mmm-yy", "mmmm-yy", "mmm d, yyyy", "mmmm d, yyyy", "m/d/yy h:MM tt", "m/d/yy HH:MM"];\n this._timeFormats = ["HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"];\n this._dateActionsCache = new Map();\n this._emailRegex = new RegExp("^[a-zA-Z0-9.!#$%&\'*+\\\\/=?^_`{|}~-]+" + "@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?" + "(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$");\n }\n _mkTargetName(event) {\n return event.target ? `[ ${event.target.name} ]` : "";\n }\n _tryToGuessDate(cFormat, cDate) {\n let actions = this._dateActionsCache.get(cFormat);\n if (!actions) {\n actions = [];\n this._dateActionsCache.set(cFormat, actions);\n cFormat.replaceAll(/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, function (match, d, m, y, H, M, s) {\n if (d) {\n actions.push((n, date) => {\n if (n >= 1 && n <= 31) {\n date.setDate(n);\n return true;\n }\n return false;\n });\n } else if (m) {\n actions.push((n, date) => {\n if (n >= 1 && n <= 12) {\n date.setMonth(n - 1);\n return true;\n }\n return false;\n });\n } else if (y) {\n actions.push((n, date) => {\n if (n < 50) {\n n += 2000;\n } else if (n < 100) {\n n += 1900;\n }\n date.setYear(n);\n return true;\n });\n } else if (H) {\n actions.push((n, date) => {\n if (n >= 0 && n <= 23) {\n date.setHours(n);\n return true;\n }\n return false;\n });\n } else if (M) {\n actions.push((n, date) => {\n if (n >= 0 && n <= 59) {\n date.setMinutes(n);\n return true;\n }\n return false;\n });\n } else if (s) {\n actions.push((n, date) => {\n if (n >= 0 && n <= 59) {\n date.setSeconds(n);\n return true;\n }\n return false;\n });\n }\n return "";\n });\n }\n const number = /\\d+/g;\n let i = 0;\n let array;\n const date = new Date();\n while ((array = number.exec(cDate)) !== null) {\n if (i < actions.length) {\n if (!actions[i++](parseInt(array[0]), date)) {\n return null;\n }\n } else {\n break;\n }\n }\n if (i === 0) {\n return null;\n }\n return date;\n }\n _parseDate(cFormat, cDate) {\n let date = null;\n try {\n date = this._util.scand(cFormat, cDate);\n } catch {}\n if (!date) {\n date = Date.parse(cDate);\n date = isNaN(date) ? this._tryToGuessDate(cFormat, cDate) : new Date(date);\n }\n return date;\n }\n AFMergeChange(event = globalThis.event) {\n if (event.willCommit) {\n return event.value.toString();\n }\n return this._app._eventDispatcher.mergeChange(event);\n }\n AFParseDateEx(cString, cOrder) {\n return this._parseDate(cOrder, cString);\n }\n AFExtractNums(str) {\n if (typeof str === "number") {\n return [str];\n }\n if (!str || typeof str !== "string") {\n return null;\n }\n const first = str.charAt(0);\n if (first === "." || first === ",") {\n str = `0${str}`;\n }\n const numbers = str.match(/(\\d+)/g);\n if (numbers.length === 0) {\n return null;\n }\n return numbers;\n }\n AFMakeNumber(str) {\n if (typeof str === "number") {\n return str;\n }\n if (typeof str !== "string") {\n return null;\n }\n str = str.trim().replace(",", ".");\n const number = parseFloat(str);\n if (isNaN(number) || !isFinite(number)) {\n return null;\n }\n return number;\n }\n AFMakeArrayFromList(string) {\n if (typeof string === "string") {\n return string.split(/, ?/g);\n }\n return string;\n }\n AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) {\n const event = globalThis.event;\n if (!event.value) {\n return;\n }\n let value = this.AFMakeNumber(event.value);\n if (value === null) {\n event.value = "";\n return;\n }\n const sign = Math.sign(value);\n const buf = [];\n let hasParen = false;\n if (sign === -1 && bCurrencyPrepend && negStyle === 0) {\n buf.push("-");\n }\n if ((negStyle === 2 || negStyle === 3) && sign === -1) {\n buf.push("(");\n hasParen = true;\n }\n if (bCurrencyPrepend) {\n buf.push(strCurrency);\n }\n sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4);\n buf.push("%,", sepStyle, ".", nDec.toString(), "f");\n if (!bCurrencyPrepend) {\n buf.push(strCurrency);\n }\n if (hasParen) {\n buf.push(")");\n }\n if (negStyle === 1 || negStyle === 3) {\n event.target.textColor = sign === 1 ? this._color.black : this._color.red;\n }\n if ((negStyle !== 0 || bCurrencyPrepend) && sign === -1) {\n value = -value;\n }\n const formatStr = buf.join("");\n event.value = this._util.printf(formatStr, value);\n }\n AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) {\n const event = globalThis.event;\n let value = this.AFMergeChange(event);\n if (!value) {\n return;\n }\n value = value.trim();\n let pattern;\n if (sepStyle > 1) {\n pattern = event.willCommit ? /^[+-]?(\\d+(,\\d*)?|,\\d+)$/ : /^[+-]?\\d*,?\\d*$/;\n } else {\n pattern = event.willCommit ? /^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)$/ : /^[+-]?\\d*\\.?\\d*$/;\n }\n if (!pattern.test(value)) {\n if (event.willCommit) {\n const err = `${GlobalConstants.IDS_INVALID_VALUE} ${this._mkTargetName(event)}`;\n this._app.alert(err);\n }\n event.rc = false;\n }\n if (event.willCommit && sepStyle > 1) {\n event.value = parseFloat(value.replace(",", "."));\n }\n }\n AFPercent_Format(nDec, sepStyle, percentPrepend = false) {\n if (typeof nDec !== "number") {\n return;\n }\n if (typeof sepStyle !== "number") {\n return;\n }\n if (nDec < 0) {\n throw new Error("Invalid nDec value in AFPercent_Format");\n }\n const event = globalThis.event;\n if (nDec > 512) {\n event.value = "%";\n return;\n }\n nDec = Math.floor(nDec);\n sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4);\n let value = this.AFMakeNumber(event.value);\n if (value === null) {\n event.value = "%";\n return;\n }\n const formatStr = `%,${sepStyle}.${nDec}f`;\n value = this._util.printf(formatStr, value * 100);\n event.value = percentPrepend ? `%${value}` : `${value}%`;\n }\n AFPercent_Keystroke(nDec, sepStyle) {\n this.AFNumber_Keystroke(nDec, sepStyle, 0, 0, "", true);\n }\n AFDate_FormatEx(cFormat) {\n const event = globalThis.event;\n const value = event.value;\n if (!value) {\n return;\n }\n const date = this._parseDate(cFormat, value);\n if (date !== null) {\n event.value = this._util.printd(cFormat, date);\n }\n }\n AFDate_Format(pdf) {\n if (pdf >= 0 && pdf < this._dateFormats.length) {\n this.AFDate_FormatEx(this._dateFormats[pdf]);\n }\n }\n AFDate_KeystrokeEx(cFormat) {\n const event = globalThis.event;\n if (!event.willCommit) {\n return;\n }\n const value = this.AFMergeChange(event);\n if (!value) {\n return;\n }\n if (this._parseDate(cFormat, value) === null) {\n const invalid = GlobalConstants.IDS_INVALID_DATE;\n const invalid2 = GlobalConstants.IDS_INVALID_DATE2;\n const err = `${invalid} ${this._mkTargetName(event)}${invalid2}${cFormat}`;\n this._app.alert(err);\n event.rc = false;\n }\n }\n AFDate_Keystroke(pdf) {\n if (pdf >= 0 && pdf < this._dateFormats.length) {\n this.AFDate_KeystrokeEx(this._dateFormats[pdf]);\n }\n }\n AFRange_Validate(bGreaterThan, nGreaterThan, bLessThan, nLessThan) {\n const event = globalThis.event;\n if (!event.value) {\n return;\n }\n const value = this.AFMakeNumber(event.value);\n if (value === null) {\n return;\n }\n bGreaterThan = !!bGreaterThan;\n bLessThan = !!bLessThan;\n if (bGreaterThan) {\n nGreaterThan = this.AFMakeNumber(nGreaterThan);\n if (nGreaterThan === null) {\n return;\n }\n }\n if (bLessThan) {\n nLessThan = this.AFMakeNumber(nLessThan);\n if (nLessThan === null) {\n return;\n }\n }\n let err = "";\n if (bGreaterThan && bLessThan) {\n if (value < nGreaterThan || value > nLessThan) {\n err = this._util.printf(GlobalConstants.IDS_GT_AND_LT, nGreaterThan, nLessThan);\n }\n } else if (bGreaterThan) {\n if (value < nGreaterThan) {\n err = this._util.printf(GlobalConstants.IDS_GREATER_THAN, nGreaterThan);\n }\n } else if (value > nLessThan) {\n err = this._util.printf(GlobalConstants.IDS_LESS_THAN, nLessThan);\n }\n if (err) {\n this._app.alert(err);\n event.rc = false;\n }\n }\n AFSimple(cFunction, nValue1, nValue2) {\n const value1 = this.AFMakeNumber(nValue1);\n if (value1 === null) {\n throw new Error("Invalid nValue1 in AFSimple");\n }\n const value2 = this.AFMakeNumber(nValue2);\n if (value2 === null) {\n throw new Error("Invalid nValue2 in AFSimple");\n }\n switch (cFunction) {\n case "AVG":\n return (value1 + value2) / 2;\n case "SUM":\n return value1 + value2;\n case "PRD":\n return value1 * value2;\n case "MIN":\n return Math.min(value1, value2);\n case "MAX":\n return Math.max(value1, value2);\n }\n throw new Error("Invalid cFunction in AFSimple");\n }\n AFSimple_Calculate(cFunction, cFields) {\n const actions = {\n AVG: args => args.reduce((acc, value) => acc + value, 0) / args.length,\n SUM: args => args.reduce((acc, value) => acc + value, 0),\n PRD: args => args.reduce((acc, value) => acc * value, 1),\n MIN: args => args.reduce((acc, value) => Math.min(acc, value), Number.MAX_VALUE),\n MAX: args => args.reduce((acc, value) => Math.max(acc, value), Number.MIN_VALUE)\n };\n if (!(cFunction in actions)) {\n throw new TypeError("Invalid function in AFSimple_Calculate");\n }\n const event = globalThis.event;\n const values = [];\n cFields = this.AFMakeArrayFromList(cFields);\n for (const cField of cFields) {\n const field = this._document.getField(cField);\n if (!field) {\n continue;\n }\n for (const child of field.getArray()) {\n const number = this.AFMakeNumber(child.value);\n if (number !== null) {\n values.push(number);\n }\n }\n }\n if (values.length === 0) {\n event.value = cFunction === "PRD" ? 1 : 0;\n return;\n }\n const res = actions[cFunction](values);\n event.value = Math.round(1e6 * res) / 1e6;\n }\n AFSpecial_Format(psf) {\n const event = globalThis.event;\n if (!event.value) {\n return;\n }\n psf = this.AFMakeNumber(psf);\n let formatStr;\n switch (psf) {\n case 0:\n formatStr = "99999";\n break;\n case 1:\n formatStr = "99999-9999";\n break;\n case 2:\n formatStr = this._util.printx("9999999999", event.value).length >= 10 ? "(999) 999-9999" : "999-9999";\n break;\n case 3:\n formatStr = "999-99-9999";\n break;\n default:\n throw new Error("Invalid psf in AFSpecial_Format");\n }\n event.value = this._util.printx(formatStr, event.value);\n }\n AFSpecial_KeystrokeEx(cMask) {\n if (!cMask) {\n return;\n }\n const event = globalThis.event;\n const value = this.AFMergeChange(event);\n if (!value) {\n return;\n }\n const checkers = new Map([["9", char => char >= "0" && char <= "9"], ["A", char => "a" <= char && char <= "z" || "A" <= char && char <= "Z"], ["O", char => "a" <= char && char <= "z" || "A" <= char && char <= "Z" || "0" <= char && char <= "9"], ["X", char => true]]);\n function _checkValidity(_value, _cMask) {\n for (let i = 0, ii = _value.length; i < ii; i++) {\n const mask = _cMask.charAt(i);\n const char = _value.charAt(i);\n const checker = checkers.get(mask);\n if (checker) {\n if (!checker(char)) {\n return false;\n }\n } else if (mask !== char) {\n return false;\n }\n }\n return true;\n }\n const err = `${GlobalConstants.IDS_INVALID_VALUE} = "${cMask}"`;\n if (value.length > cMask.length) {\n this._app.alert(err);\n event.rc = false;\n return;\n }\n if (event.willCommit) {\n if (value.length < cMask.length) {\n this._app.alert(err);\n event.rc = false;\n return;\n }\n if (!_checkValidity(value, cMask)) {\n this._app.alert(err);\n event.rc = false;\n return;\n }\n event.value += cMask.substring(value.length);\n return;\n }\n if (value.length < cMask.length) {\n cMask = cMask.substring(0, value.length);\n }\n if (!_checkValidity(value, cMask)) {\n this._app.alert(err);\n event.rc = false;\n }\n }\n AFSpecial_Keystroke(psf) {\n const event = globalThis.event;\n psf = this.AFMakeNumber(psf);\n let formatStr;\n switch (psf) {\n case 0:\n formatStr = "99999";\n break;\n case 1:\n formatStr = "99999-9999";\n break;\n case 2:\n const value = this.AFMergeChange(event);\n formatStr = value.length > 8 || value.startsWith("(") ? "(999) 999-9999" : "999-9999";\n break;\n case 3:\n formatStr = "999-99-9999";\n break;\n default:\n throw new Error("Invalid psf in AFSpecial_Keystroke");\n }\n this.AFSpecial_KeystrokeEx(formatStr);\n }\n AFTime_FormatEx(cFormat) {\n this.AFDate_FormatEx(cFormat);\n }\n AFTime_Format(pdf) {\n if (pdf >= 0 && pdf < this._timeFormats.length) {\n this.AFDate_FormatEx(this._timeFormats[pdf]);\n }\n }\n AFTime_KeystrokeEx(cFormat) {\n this.AFDate_KeystrokeEx(cFormat);\n }\n AFTime_Keystroke(pdf) {\n if (pdf >= 0 && pdf < this._timeFormats.length) {\n this.AFDate_KeystrokeEx(this._timeFormats[pdf]);\n }\n }\n eMailValidate(str) {\n return this._emailRegex.test(str);\n }\n AFExactMatch(rePatterns, str) {\n if (rePatterns instanceof RegExp) {\n return str.match(rePatterns)?.[0] === str || 0;\n }\n return rePatterns.findIndex(re => str.match(re)?.[0] === str) + 1;\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/app_utils.js\nconst VIEWER_TYPE = "PDF.js";\nconst VIEWER_VARIATION = "Full";\nconst VIEWER_VERSION = 21.00720099;\nconst FORMS_VERSION = 21.00720099;\nconst USERACTIVATION_CALLBACKID = 0;\nconst USERACTIVATION_MAXTIME_VALIDITY = 5000;\nfunction serializeError(error) {\n const value = `${error.toString()}\\n${error.stack}`;\n return {\n command: "error",\n value\n };\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/event.js\n\nclass Event {\n constructor(data) {\n this.change = data.change || "";\n this.changeEx = data.changeEx || null;\n this.commitKey = data.commitKey || 0;\n this.fieldFull = data.fieldFull || false;\n this.keyDown = data.keyDown || false;\n this.modifier = data.modifier || false;\n this.name = data.name;\n this.rc = true;\n this.richChange = data.richChange || [];\n this.richChangeEx = data.richChangeEx || [];\n this.richValue = data.richValue || [];\n this.selEnd = data.selEnd ?? -1;\n this.selStart = data.selStart ?? -1;\n this.shift = data.shift || false;\n this.source = data.source || null;\n this.target = data.target || null;\n this.targetName = "";\n this.type = "Field";\n this.value = data.value || "";\n this.willCommit = data.willCommit || false;\n }\n}\nclass EventDispatcher {\n constructor(document, calculationOrder, objects, externalCall) {\n this._document = document;\n this._calculationOrder = calculationOrder;\n this._objects = objects;\n this._externalCall = externalCall;\n this._document.obj._eventDispatcher = this;\n this._isCalculating = false;\n }\n mergeChange(event) {\n let value = event.value;\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value !== "string") {\n value = value.toString();\n }\n const prefix = event.selStart >= 0 ? value.substring(0, event.selStart) : "";\n const postfix = event.selEnd >= 0 && event.selEnd <= value.length ? value.substring(event.selEnd) : "";\n return `${prefix}${event.change}${postfix}`;\n }\n userActivation() {\n this._document.obj._userActivation = true;\n this._externalCall("setTimeout", [USERACTIVATION_CALLBACKID, USERACTIVATION_MAXTIME_VALIDITY]);\n }\n dispatch(baseEvent) {\n const id = baseEvent.id;\n if (!(id in this._objects)) {\n let event;\n if (id === "doc" || id === "page") {\n event = globalThis.event = new Event(baseEvent);\n event.source = event.target = this._document.wrapped;\n event.name = baseEvent.name;\n }\n if (id === "doc") {\n const eventName = event.name;\n if (eventName === "Open") {\n this.userActivation();\n this._document.obj._initActions();\n this.formatAll();\n }\n if (!["DidPrint", "DidSave", "WillPrint", "WillSave"].includes(eventName)) {\n this.userActivation();\n }\n this._document.obj._dispatchDocEvent(event.name);\n } else if (id === "page") {\n this.userActivation();\n this._document.obj._dispatchPageEvent(event.name, baseEvent.actions, baseEvent.pageNumber);\n } else if (id === "app" && baseEvent.name === "ResetForm") {\n this.userActivation();\n for (const fieldId of baseEvent.ids) {\n const obj = this._objects[fieldId];\n obj?.obj._reset();\n }\n }\n return;\n }\n const name = baseEvent.name;\n const source = this._objects[id];\n const event = globalThis.event = new Event(baseEvent);\n let savedChange;\n this.userActivation();\n if (source.obj._isButton()) {\n source.obj._id = id;\n event.value = source.obj._getExportValue(event.value);\n if (name === "Action") {\n source.obj._value = event.value;\n }\n }\n switch (name) {\n case "Keystroke":\n savedChange = {\n value: event.value,\n changeEx: event.changeEx,\n change: event.change,\n selStart: event.selStart,\n selEnd: event.selEnd\n };\n break;\n case "Blur":\n case "Focus":\n Object.defineProperty(event, "value", {\n configurable: false,\n writable: false,\n enumerable: true,\n value: event.value\n });\n break;\n case "Validate":\n this.runValidation(source, event);\n return;\n case "Action":\n this.runActions(source, source, event, name);\n this.runCalculate(source, event);\n return;\n }\n this.runActions(source, source, event, name);\n if (name !== "Keystroke") {\n return;\n }\n if (event.rc) {\n if (event.willCommit) {\n this.runValidation(source, event);\n } else {\n if (source.obj._isChoice) {\n source.obj.value = savedChange.changeEx;\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value: source.obj.value\n });\n return;\n }\n const value = source.obj.value = this.mergeChange(event);\n let selStart, selEnd;\n if (event.selStart !== savedChange.selStart || event.selEnd !== savedChange.selEnd) {\n selStart = event.selStart;\n selEnd = event.selEnd;\n } else {\n selEnd = selStart = savedChange.selStart + event.change.length;\n }\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value,\n selRange: [selStart, selEnd]\n });\n }\n } else if (!event.willCommit) {\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value: savedChange.value,\n selRange: [savedChange.selStart, savedChange.selEnd]\n });\n } else {\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value: "",\n formattedValue: null,\n selRange: [0, 0]\n });\n }\n }\n formatAll() {\n const event = globalThis.event = new Event({});\n for (const source of Object.values(this._objects)) {\n event.value = source.obj.value;\n this.runActions(source, source, event, "Format");\n }\n }\n runValidation(source, event) {\n const didValidateRun = this.runActions(source, source, event, "Validate");\n if (event.rc) {\n source.obj.value = event.value;\n this.runCalculate(source, event);\n const savedValue = source.obj._getValue();\n event.value = source.obj.value;\n let formattedValue = null;\n if (this.runActions(source, source, event, "Format")) {\n formattedValue = event.value?.toString?.();\n }\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value: savedValue,\n formattedValue\n });\n event.value = savedValue;\n } else if (didValidateRun) {\n source.obj._send({\n id: source.obj._id,\n siblings: source.obj._siblings,\n value: "",\n formattedValue: null,\n selRange: [0, 0],\n focus: true\n });\n }\n }\n runActions(source, target, event, eventName) {\n event.source = source.wrapped;\n event.target = target.wrapped;\n event.name = eventName;\n event.targetName = target.obj.name;\n event.rc = true;\n return target.obj._runActions(event);\n }\n calculateNow() {\n if (!this._calculationOrder || this._isCalculating || !this._document.obj.calculate) {\n return;\n }\n this._isCalculating = true;\n const first = this._calculationOrder[0];\n const source = this._objects[first];\n globalThis.event = new Event({});\n try {\n this.runCalculate(source, globalThis.event);\n } catch (error) {\n this._isCalculating = false;\n throw error;\n }\n this._isCalculating = false;\n }\n runCalculate(source, event) {\n if (!this._calculationOrder || !this._document.obj.calculate) {\n return;\n }\n for (const targetId of this._calculationOrder) {\n if (!(targetId in this._objects)) {\n continue;\n }\n if (!this._document.obj.calculate) {\n break;\n }\n event.value = null;\n const target = this._objects[targetId];\n let savedValue = target.obj.value;\n this.runActions(source, target, event, "Calculate");\n if (!event.rc) {\n continue;\n }\n if (event.value !== null) {\n target.obj.value = event.value;\n }\n event.value = target.obj.value;\n this.runActions(target, target, event, "Validate");\n if (!event.rc) {\n if (target.obj.value !== savedValue) {\n target.wrapped.value = savedValue;\n }\n continue;\n }\n savedValue = event.value = target.obj.value;\n let formattedValue = null;\n if (this.runActions(target, target, event, "Format")) {\n formattedValue = event.value?.toString?.();\n }\n target.obj._send({\n id: target.obj._id,\n siblings: target.obj._siblings,\n value: savedValue,\n formattedValue\n });\n }\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/fullscreen.js\n\n\nclass FullScreen extends PDFObject {\n constructor(data) {\n super(data);\n this._backgroundColor = [];\n this._clickAdvances = true;\n this._cursor = Cursor.hidden;\n this._defaultTransition = "";\n this._escapeExits = true;\n this._isFullScreen = true;\n this._loop = false;\n this._timeDelay = 3600;\n this._usePageTiming = false;\n this._useTimer = false;\n }\n get backgroundColor() {\n return this._backgroundColor;\n }\n set backgroundColor(_) {}\n get clickAdvances() {\n return this._clickAdvances;\n }\n set clickAdvances(_) {}\n get cursor() {\n return this._cursor;\n }\n set cursor(_) {}\n get defaultTransition() {\n return this._defaultTransition;\n }\n set defaultTransition(_) {}\n get escapeExits() {\n return this._escapeExits;\n }\n set escapeExits(_) {}\n get isFullScreen() {\n return this._isFullScreen;\n }\n set isFullScreen(_) {}\n get loop() {\n return this._loop;\n }\n set loop(_) {}\n get timeDelay() {\n return this._timeDelay;\n }\n set timeDelay(_) {}\n get transitions() {\n return ["Replace", "WipeRight", "WipeLeft", "WipeDown", "WipeUp", "SplitHorizontalIn", "SplitHorizontalOut", "SplitVerticalIn", "SplitVerticalOut", "BlindsHorizontal", "BlindsVertical", "BoxIn", "BoxOut", "GlitterRight", "GlitterDown", "GlitterRightDown", "Dissolve", "Random"];\n }\n set transitions(_) {\n throw new Error("fullscreen.transitions is read-only");\n }\n get usePageTiming() {\n return this._usePageTiming;\n }\n set usePageTiming(_) {}\n get useTimer() {\n return this._useTimer;\n }\n set useTimer(_) {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/thermometer.js\n\nclass Thermometer extends PDFObject {\n constructor(data) {\n super(data);\n this._cancelled = false;\n this._duration = 100;\n this._text = "";\n this._value = 0;\n }\n get cancelled() {\n return this._cancelled;\n }\n set cancelled(_) {\n throw new Error("thermometer.cancelled is read-only");\n }\n get duration() {\n return this._duration;\n }\n set duration(val) {\n this._duration = val;\n }\n get text() {\n return this._text;\n }\n set text(val) {\n this._text = val;\n }\n get value() {\n return this._value;\n }\n set value(val) {\n this._value = val;\n }\n begin() {}\n end() {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/app.js\n\n\n\n\n\n\nclass App extends PDFObject {\n constructor(data) {\n super(data);\n this._constants = null;\n this._focusRect = true;\n this._fs = null;\n this._language = App._getLanguage(data.language);\n this._openInPlace = false;\n this._platform = App._getPlatform(data.platform);\n this._runtimeHighlight = false;\n this._runtimeHighlightColor = ["T"];\n this._thermometer = null;\n this._toolbar = false;\n this._document = data._document;\n this._proxyHandler = data.proxyHandler;\n this._objects = Object.create(null);\n this._eventDispatcher = new EventDispatcher(this._document, data.calculationOrder, this._objects, data.externalCall);\n this._timeoutIds = new WeakMap();\n if (typeof FinalizationRegistry !== "undefined") {\n this._timeoutIdsRegistry = new FinalizationRegistry(this._cleanTimeout.bind(this));\n } else {\n this._timeoutIdsRegistry = null;\n }\n this._timeoutCallbackIds = new Map();\n this._timeoutCallbackId = USERACTIVATION_CALLBACKID + 1;\n this._globalEval = data.globalEval;\n this._externalCall = data.externalCall;\n }\n _dispatchEvent(pdfEvent) {\n this._eventDispatcher.dispatch(pdfEvent);\n }\n _registerTimeoutCallback(cExpr) {\n const id = this._timeoutCallbackId++;\n this._timeoutCallbackIds.set(id, cExpr);\n return id;\n }\n _unregisterTimeoutCallback(id) {\n this._timeoutCallbackIds.delete(id);\n }\n _evalCallback({\n callbackId,\n interval\n }) {\n if (callbackId === USERACTIVATION_CALLBACKID) {\n this._document.obj._userActivation = false;\n return;\n }\n const expr = this._timeoutCallbackIds.get(callbackId);\n if (!interval) {\n this._unregisterTimeoutCallback(callbackId);\n }\n if (expr) {\n this._globalEval(expr);\n }\n }\n _registerTimeout(callbackId, interval) {\n const timeout = Object.create(null);\n const id = {\n callbackId,\n interval\n };\n this._timeoutIds.set(timeout, id);\n this._timeoutIdsRegistry?.register(timeout, id);\n return timeout;\n }\n _unregisterTimeout(timeout) {\n this._timeoutIdsRegistry?.unregister(timeout);\n const data = this._timeoutIds.get(timeout);\n if (!data) {\n return;\n }\n this._timeoutIds.delete(timeout);\n this._cleanTimeout(data);\n }\n _cleanTimeout({\n callbackId,\n interval\n }) {\n this._unregisterTimeoutCallback(callbackId);\n if (interval) {\n this._externalCall("clearInterval", [callbackId]);\n } else {\n this._externalCall("clearTimeout", [callbackId]);\n }\n }\n static _getPlatform(platform) {\n if (typeof platform === "string") {\n platform = platform.toLowerCase();\n if (platform.includes("win")) {\n return "WIN";\n } else if (platform.includes("mac")) {\n return "MAC";\n }\n }\n return "UNIX";\n }\n static _getLanguage(language) {\n const [main, sub] = language.toLowerCase().split(/[-_]/);\n switch (main) {\n case "zh":\n if (sub === "cn" || sub === "sg") {\n return "CHS";\n }\n return "CHT";\n case "da":\n return "DAN";\n case "de":\n return "DEU";\n case "es":\n return "ESP";\n case "fr":\n return "FRA";\n case "it":\n return "ITA";\n case "ko":\n return "KOR";\n case "ja":\n return "JPN";\n case "nl":\n return "NLD";\n case "no":\n return "NOR";\n case "pt":\n if (sub === "br") {\n return "PTB";\n }\n return "ENU";\n case "fi":\n return "SUO";\n case "SV":\n return "SVE";\n default:\n return "ENU";\n }\n }\n get activeDocs() {\n return [this._document.wrapped];\n }\n set activeDocs(_) {\n throw new Error("app.activeDocs is read-only");\n }\n get calculate() {\n return this._document.obj.calculate;\n }\n set calculate(calculate) {\n this._document.obj.calculate = calculate;\n }\n get constants() {\n if (!this._constants) {\n this._constants = Object.freeze({\n align: Object.freeze({\n left: 0,\n center: 1,\n right: 2,\n top: 3,\n bottom: 4\n })\n });\n }\n return this._constants;\n }\n set constants(_) {\n throw new Error("app.constants is read-only");\n }\n get focusRect() {\n return this._focusRect;\n }\n set focusRect(val) {\n this._focusRect = val;\n }\n get formsVersion() {\n return FORMS_VERSION;\n }\n set formsVersion(_) {\n throw new Error("app.formsVersion is read-only");\n }\n get fromPDFConverters() {\n return [];\n }\n set fromPDFConverters(_) {\n throw new Error("app.fromPDFConverters is read-only");\n }\n get fs() {\n if (this._fs === null) {\n this._fs = new Proxy(new FullScreen({\n send: this._send\n }), this._proxyHandler);\n }\n return this._fs;\n }\n set fs(_) {\n throw new Error("app.fs is read-only");\n }\n get language() {\n return this._language;\n }\n set language(_) {\n throw new Error("app.language is read-only");\n }\n get media() {\n return undefined;\n }\n set media(_) {\n throw new Error("app.media is read-only");\n }\n get monitors() {\n return [];\n }\n set monitors(_) {\n throw new Error("app.monitors is read-only");\n }\n get numPlugins() {\n return 0;\n }\n set numPlugins(_) {\n throw new Error("app.numPlugins is read-only");\n }\n get openInPlace() {\n return this._openInPlace;\n }\n set openInPlace(val) {\n this._openInPlace = val;\n }\n get platform() {\n return this._platform;\n }\n set platform(_) {\n throw new Error("app.platform is read-only");\n }\n get plugins() {\n return [];\n }\n set plugins(_) {\n throw new Error("app.plugins is read-only");\n }\n get printColorProfiles() {\n return [];\n }\n set printColorProfiles(_) {\n throw new Error("app.printColorProfiles is read-only");\n }\n get printerNames() {\n return [];\n }\n set printerNames(_) {\n throw new Error("app.printerNames is read-only");\n }\n get runtimeHighlight() {\n return this._runtimeHighlight;\n }\n set runtimeHighlight(val) {\n this._runtimeHighlight = val;\n }\n get runtimeHighlightColor() {\n return this._runtimeHighlightColor;\n }\n set runtimeHighlightColor(val) {\n if (Color._isValidColor(val)) {\n this._runtimeHighlightColor = val;\n }\n }\n get thermometer() {\n if (this._thermometer === null) {\n this._thermometer = new Proxy(new Thermometer({\n send: this._send\n }), this._proxyHandler);\n }\n return this._thermometer;\n }\n set thermometer(_) {\n throw new Error("app.thermometer is read-only");\n }\n get toolbar() {\n return this._toolbar;\n }\n set toolbar(val) {\n this._toolbar = val;\n }\n get toolbarHorizontal() {\n return this.toolbar;\n }\n set toolbarHorizontal(value) {\n this.toolbar = value;\n }\n get toolbarVertical() {\n return this.toolbar;\n }\n set toolbarVertical(value) {\n this.toolbar = value;\n }\n get viewerType() {\n return VIEWER_TYPE;\n }\n set viewerType(_) {\n throw new Error("app.viewerType is read-only");\n }\n get viewerVariation() {\n return VIEWER_VARIATION;\n }\n set viewerVariation(_) {\n throw new Error("app.viewerVariation is read-only");\n }\n get viewerVersion() {\n return VIEWER_VERSION;\n }\n set viewerVersion(_) {\n throw new Error("app.viewerVersion is read-only");\n }\n addMenuItem() {}\n addSubMenu() {}\n addToolButton() {}\n alert(cMsg, nIcon = 0, nType = 0, cTitle = "PDF.js", oDoc = null, oCheckbox = null) {\n if (!this._document.obj._userActivation) {\n return 0;\n }\n this._document.obj._userActivation = false;\n if (cMsg && typeof cMsg === "object") {\n nType = cMsg.nType;\n cMsg = cMsg.cMsg;\n }\n cMsg = (cMsg || "").toString();\n nType = typeof nType !== "number" || isNaN(nType) || nType < 0 || nType > 3 ? 0 : nType;\n if (nType >= 2) {\n return this._externalCall("confirm", [cMsg]) ? 4 : 3;\n }\n this._externalCall("alert", [cMsg]);\n return 1;\n }\n beep() {}\n beginPriv() {}\n browseForDoc() {}\n clearInterval(oInterval) {\n this._unregisterTimeout(oInterval);\n }\n clearTimeOut(oTime) {\n this._unregisterTimeout(oTime);\n }\n endPriv() {}\n execDialog() {}\n execMenuItem(item) {\n if (!this._document.obj._userActivation) {\n return;\n }\n this._document.obj._userActivation = false;\n switch (item) {\n case "SaveAs":\n if (this._document.obj._disableSaving) {\n return;\n }\n this._send({\n command: item\n });\n break;\n case "FirstPage":\n case "LastPage":\n case "NextPage":\n case "PrevPage":\n case "ZoomViewIn":\n case "ZoomViewOut":\n this._send({\n command: item\n });\n break;\n case "FitPage":\n this._send({\n command: "zoom",\n value: "page-fit"\n });\n break;\n case "Print":\n if (this._document.obj._disablePrinting) {\n return;\n }\n this._send({\n command: "print"\n });\n break;\n }\n }\n getNthPlugInName() {}\n getPath() {}\n goBack() {}\n goForward() {}\n hideMenuItem() {}\n hideToolbarButton() {}\n launchURL() {}\n listMenuItems() {}\n listToolbarButtons() {}\n loadPolicyFile() {}\n mailGetAddrs() {}\n mailMsg() {}\n newDoc() {}\n newCollection() {}\n newFDF() {}\n openDoc() {}\n openFDF() {}\n popUpMenu() {}\n popUpMenuEx() {}\n removeToolButton() {}\n response(cQuestion, cTitle = "", cDefault = "", bPassword = "", cLabel = "") {\n if (cQuestion && typeof cQuestion === "object") {\n cDefault = cQuestion.cDefault;\n cQuestion = cQuestion.cQuestion;\n }\n cQuestion = (cQuestion || "").toString();\n cDefault = (cDefault || "").toString();\n return this._externalCall("prompt", [cQuestion, cDefault || ""]);\n }\n setInterval(cExpr, nMilliseconds = 0) {\n if (cExpr && typeof cExpr === "object") {\n nMilliseconds = cExpr.nMilliseconds || 0;\n cExpr = cExpr.cExpr;\n }\n if (typeof cExpr !== "string") {\n throw new TypeError("First argument of app.setInterval must be a string");\n }\n if (typeof nMilliseconds !== "number") {\n throw new TypeError("Second argument of app.setInterval must be a number");\n }\n const callbackId = this._registerTimeoutCallback(cExpr);\n this._externalCall("setInterval", [callbackId, nMilliseconds]);\n return this._registerTimeout(callbackId, true);\n }\n setTimeOut(cExpr, nMilliseconds = 0) {\n if (cExpr && typeof cExpr === "object") {\n nMilliseconds = cExpr.nMilliseconds || 0;\n cExpr = cExpr.cExpr;\n }\n if (typeof cExpr !== "string") {\n throw new TypeError("First argument of app.setTimeOut must be a string");\n }\n if (typeof nMilliseconds !== "number") {\n throw new TypeError("Second argument of app.setTimeOut must be a number");\n }\n const callbackId = this._registerTimeoutCallback(cExpr);\n this._externalCall("setTimeout", [callbackId, nMilliseconds]);\n return this._registerTimeout(callbackId, false);\n }\n trustedFunction() {}\n trustPropagatorFunction() {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/console.js\n\nclass Console extends PDFObject {\n clear() {\n this._send({\n id: "clear"\n });\n }\n hide() {}\n println(msg) {\n if (typeof msg === "string") {\n this._send({\n command: "println",\n value: "PDF.js Console:: " + msg\n });\n }\n }\n show() {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/print_params.js\nclass PrintParams {\n constructor(data) {\n this.binaryOk = true;\n this.bitmapDPI = 150;\n this.booklet = {\n binding: 0,\n duplexMode: 0,\n subsetFrom: 0,\n subsetTo: -1\n };\n this.colorOverride = 0;\n this.colorProfile = "";\n this.constants = Object.freeze({\n bookletBindings: Object.freeze({\n Left: 0,\n Right: 1,\n LeftTall: 2,\n RightTall: 3\n }),\n bookletDuplexMode: Object.freeze({\n BothSides: 0,\n FrontSideOnly: 1,\n BasicSideOnly: 2\n }),\n colorOverrides: Object.freeze({\n auto: 0,\n gray: 1,\n mono: 2\n }),\n fontPolicies: Object.freeze({\n everyPage: 0,\n jobStart: 1,\n pageRange: 2\n }),\n handling: Object.freeze({\n none: 0,\n fit: 1,\n shrink: 2,\n tileAll: 3,\n tileLarge: 4,\n nUp: 5,\n booklet: 6\n }),\n interactionLevel: Object.freeze({\n automatic: 0,\n full: 1,\n silent: 2\n }),\n nUpPageOrders: Object.freeze({\n Horizontal: 0,\n HorizontalReversed: 1,\n Vertical: 2\n }),\n printContents: Object.freeze({\n doc: 0,\n docAndComments: 1,\n formFieldsOnly: 2\n }),\n flagValues: Object.freeze({\n applyOverPrint: 1,\n applySoftProofSettings: 1 << 1,\n applyWorkingColorSpaces: 1 << 2,\n emitHalftones: 1 << 3,\n emitPostScriptXObjects: 1 << 4,\n emitFormsAsPSForms: 1 << 5,\n maxJP2KRes: 1 << 6,\n setPageSize: 1 << 7,\n suppressBG: 1 << 8,\n suppressCenter: 1 << 9,\n suppressCJKFontSubst: 1 << 10,\n suppressCropClip: 1 << 1,\n suppressRotate: 1 << 12,\n suppressTransfer: 1 << 13,\n suppressUCR: 1 << 14,\n useTrapAnnots: 1 << 15,\n usePrintersMarks: 1 << 16\n }),\n rasterFlagValues: Object.freeze({\n textToOutline: 1,\n strokesToOutline: 1 << 1,\n allowComplexClip: 1 << 2,\n preserveOverprint: 1 << 3\n }),\n subsets: Object.freeze({\n all: 0,\n even: 1,\n odd: 2\n }),\n tileMarks: Object.freeze({\n none: 0,\n west: 1,\n east: 2\n }),\n usages: Object.freeze({\n auto: 0,\n use: 1,\n noUse: 2\n })\n });\n this.downloadFarEastFonts = false;\n this.fileName = "";\n this.firstPage = 0;\n this.flags = 0;\n this.fontPolicy = 0;\n this.gradientDPI = 150;\n this.interactive = 1;\n this.lastPage = data.lastPage;\n this.npUpAutoRotate = false;\n this.npUpNumPagesH = 2;\n this.npUpNumPagesV = 2;\n this.npUpPageBorder = false;\n this.npUpPageOrder = 0;\n this.pageHandling = 0;\n this.pageSubset = 0;\n this.printAsImage = false;\n this.printContent = 0;\n this.printerName = "";\n this.psLevel = 0;\n this.rasterFlags = 0;\n this.reversePages = false;\n this.tileLabel = false;\n this.tileMark = 0;\n this.tileOverlap = 0;\n this.tileScale = 1.0;\n this.transparencyLevel = 75;\n this.usePrinterCRD = 0;\n this.useT1Conversion = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/doc.js\n\n\n\n\n\nconst DOC_EXTERNAL = false;\nclass InfoProxyHandler {\n static get(obj, prop) {\n return obj[prop.toLowerCase()];\n }\n static set(obj, prop, value) {\n throw new Error(`doc.info.${prop} is read-only`);\n }\n}\nclass Doc extends PDFObject {\n constructor(data) {\n super(data);\n this._expandos = globalThis;\n this._baseURL = data.baseURL || "";\n this._calculate = true;\n this._delay = false;\n this._dirty = false;\n this._disclosed = false;\n this._media = undefined;\n this._metadata = data.metadata || "";\n this._noautocomplete = undefined;\n this._nocache = undefined;\n this._spellDictionaryOrder = [];\n this._spellLanguageOrder = [];\n this._printParams = null;\n this._fields = new Map();\n this._fieldNames = [];\n this._event = null;\n this._author = data.Author || "";\n this._creator = data.Creator || "";\n this._creationDate = this._getDate(data.CreationDate) || null;\n this._docID = data.docID || ["", ""];\n this._documentFileName = data.filename || "";\n this._filesize = data.filesize || 0;\n this._keywords = data.Keywords || "";\n this._layout = data.layout || "";\n this._modDate = this._getDate(data.ModDate) || null;\n this._numFields = 0;\n this._numPages = data.numPages || 1;\n this._pageNum = data.pageNum || 0;\n this._producer = data.Producer || "";\n this._securityHandler = data.EncryptFilterName || null;\n this._subject = data.Subject || "";\n this._title = data.Title || "";\n this._URL = data.URL || "";\n this._info = new Proxy({\n title: this._title,\n author: this._author,\n authors: data.authors || [this._author],\n subject: this._subject,\n keywords: this._keywords,\n creator: this._creator,\n producer: this._producer,\n creationdate: this._creationDate,\n moddate: this._modDate,\n trapped: data.Trapped || "Unknown"\n }, InfoProxyHandler);\n this._zoomType = ZoomType.none;\n this._zoom = data.zoom || 100;\n this._actions = createActionsMap(data.actions);\n this._globalEval = data.globalEval;\n this._pageActions = new Map();\n this._userActivation = false;\n this._disablePrinting = false;\n this._disableSaving = false;\n }\n _initActions() {\n const dontRun = new Set(["WillClose", "WillSave", "DidSave", "WillPrint", "DidPrint", "OpenAction"]);\n this._disableSaving = true;\n for (const actionName of this._actions.keys()) {\n if (!dontRun.has(actionName)) {\n this._runActions(actionName);\n }\n }\n this._runActions("OpenAction");\n this._disableSaving = false;\n }\n _dispatchDocEvent(name) {\n switch (name) {\n case "Open":\n this._disableSaving = true;\n this._runActions("OpenAction");\n this._disableSaving = false;\n break;\n case "WillPrint":\n this._disablePrinting = true;\n try {\n this._runActions(name);\n } catch (error) {\n this._send(serializeError(error));\n }\n this._send({\n command: "WillPrintFinished"\n });\n this._disablePrinting = false;\n break;\n case "WillSave":\n this._disableSaving = true;\n this._runActions(name);\n this._disableSaving = false;\n break;\n default:\n this._runActions(name);\n }\n }\n _dispatchPageEvent(name, actions, pageNumber) {\n if (name === "PageOpen") {\n if (!this._pageActions.has(pageNumber)) {\n this._pageActions.set(pageNumber, createActionsMap(actions));\n }\n this._pageNum = pageNumber - 1;\n }\n actions = this._pageActions.get(pageNumber)?.get(name);\n if (actions) {\n for (const action of actions) {\n this._globalEval(action);\n }\n }\n }\n _runActions(name) {\n const actions = this._actions.get(name);\n if (actions) {\n for (const action of actions) {\n this._globalEval(action);\n }\n }\n }\n _addField(name, field) {\n this._fields.set(name, field);\n this._fieldNames.push(name);\n this._numFields++;\n }\n _getDate(date) {\n if (!date || date.length < 15 || !date.startsWith("D:")) {\n return date;\n }\n date = date.substring(2);\n const year = date.substring(0, 4);\n const month = date.substring(4, 6);\n const day = date.substring(6, 8);\n const hour = date.substring(8, 10);\n const minute = date.substring(10, 12);\n const o = date.charAt(12);\n let second, offsetPos;\n if (o === "Z" || o === "+" || o === "-") {\n second = "00";\n offsetPos = 12;\n } else {\n second = date.substring(12, 14);\n offsetPos = 14;\n }\n const offset = date.substring(offsetPos).replaceAll("\'", "");\n return new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}${offset}`);\n }\n get author() {\n return this._author;\n }\n set author(_) {\n throw new Error("doc.author is read-only");\n }\n get baseURL() {\n return this._baseURL;\n }\n set baseURL(baseURL) {\n this._baseURL = baseURL;\n }\n get bookmarkRoot() {\n return undefined;\n }\n set bookmarkRoot(_) {\n throw new Error("doc.bookmarkRoot is read-only");\n }\n get calculate() {\n return this._calculate;\n }\n set calculate(calculate) {\n this._calculate = calculate;\n }\n get creator() {\n return this._creator;\n }\n set creator(_) {\n throw new Error("doc.creator is read-only");\n }\n get dataObjects() {\n return [];\n }\n set dataObjects(_) {\n throw new Error("doc.dataObjects is read-only");\n }\n get delay() {\n return this._delay;\n }\n set delay(delay) {\n this._delay = delay;\n }\n get dirty() {\n return this._dirty;\n }\n set dirty(dirty) {\n this._dirty = dirty;\n }\n get disclosed() {\n return this._disclosed;\n }\n set disclosed(disclosed) {\n this._disclosed = disclosed;\n }\n get docID() {\n return this._docID;\n }\n set docID(_) {\n throw new Error("doc.docID is read-only");\n }\n get documentFileName() {\n return this._documentFileName;\n }\n set documentFileName(_) {\n throw new Error("doc.documentFileName is read-only");\n }\n get dynamicXFAForm() {\n return false;\n }\n set dynamicXFAForm(_) {\n throw new Error("doc.dynamicXFAForm is read-only");\n }\n get external() {\n return DOC_EXTERNAL;\n }\n set external(_) {\n throw new Error("doc.external is read-only");\n }\n get filesize() {\n return this._filesize;\n }\n set filesize(_) {\n throw new Error("doc.filesize is read-only");\n }\n get hidden() {\n return false;\n }\n set hidden(_) {\n throw new Error("doc.hidden is read-only");\n }\n get hostContainer() {\n return undefined;\n }\n set hostContainer(_) {\n throw new Error("doc.hostContainer is read-only");\n }\n get icons() {\n return undefined;\n }\n set icons(_) {\n throw new Error("doc.icons is read-only");\n }\n get info() {\n return this._info;\n }\n set info(_) {\n throw new Error("doc.info is read-only");\n }\n get innerAppWindowRect() {\n return [0, 0, 0, 0];\n }\n set innerAppWindowRect(_) {\n throw new Error("doc.innerAppWindowRect is read-only");\n }\n get innerDocWindowRect() {\n return [0, 0, 0, 0];\n }\n set innerDocWindowRect(_) {\n throw new Error("doc.innerDocWindowRect is read-only");\n }\n get isModal() {\n return false;\n }\n set isModal(_) {\n throw new Error("doc.isModal is read-only");\n }\n get keywords() {\n return this._keywords;\n }\n set keywords(_) {\n throw new Error("doc.keywords is read-only");\n }\n get layout() {\n return this._layout;\n }\n set layout(value) {\n if (!this._userActivation) {\n return;\n }\n this._userActivation = false;\n if (typeof value !== "string") {\n return;\n }\n if (value !== "SinglePage" && value !== "OneColumn" && value !== "TwoColumnLeft" && value !== "TwoPageLeft" && value !== "TwoColumnRight" && value !== "TwoPageRight") {\n value = "SinglePage";\n }\n this._send({\n command: "layout",\n value\n });\n this._layout = value;\n }\n get media() {\n return this._media;\n }\n set media(media) {\n this._media = media;\n }\n get metadata() {\n return this._metadata;\n }\n set metadata(metadata) {\n this._metadata = metadata;\n }\n get modDate() {\n return this._modDate;\n }\n set modDate(_) {\n throw new Error("doc.modDate is read-only");\n }\n get mouseX() {\n return 0;\n }\n set mouseX(_) {\n throw new Error("doc.mouseX is read-only");\n }\n get mouseY() {\n return 0;\n }\n set mouseY(_) {\n throw new Error("doc.mouseY is read-only");\n }\n get noautocomplete() {\n return this._noautocomplete;\n }\n set noautocomplete(noautocomplete) {\n this._noautocomplete = noautocomplete;\n }\n get nocache() {\n return this._nocache;\n }\n set nocache(nocache) {\n this._nocache = nocache;\n }\n get numFields() {\n return this._numFields;\n }\n set numFields(_) {\n throw new Error("doc.numFields is read-only");\n }\n get numPages() {\n return this._numPages;\n }\n set numPages(_) {\n throw new Error("doc.numPages is read-only");\n }\n get numTemplates() {\n return 0;\n }\n set numTemplates(_) {\n throw new Error("doc.numTemplates is read-only");\n }\n get outerAppWindowRect() {\n return [0, 0, 0, 0];\n }\n set outerAppWindowRect(_) {\n throw new Error("doc.outerAppWindowRect is read-only");\n }\n get outerDocWindowRect() {\n return [0, 0, 0, 0];\n }\n set outerDocWindowRect(_) {\n throw new Error("doc.outerDocWindowRect is read-only");\n }\n get pageNum() {\n return this._pageNum;\n }\n set pageNum(value) {\n if (!this._userActivation) {\n return;\n }\n this._userActivation = false;\n if (typeof value !== "number" || value < 0 || value >= this._numPages) {\n return;\n }\n this._send({\n command: "page-num",\n value\n });\n this._pageNum = value;\n }\n get pageWindowRect() {\n return [0, 0, 0, 0];\n }\n set pageWindowRect(_) {\n throw new Error("doc.pageWindowRect is read-only");\n }\n get path() {\n return "";\n }\n set path(_) {\n throw new Error("doc.path is read-only");\n }\n get permStatusReady() {\n return true;\n }\n set permStatusReady(_) {\n throw new Error("doc.permStatusReady is read-only");\n }\n get producer() {\n return this._producer;\n }\n set producer(_) {\n throw new Error("doc.producer is read-only");\n }\n get requiresFullSave() {\n return false;\n }\n set requiresFullSave(_) {\n throw new Error("doc.requiresFullSave is read-only");\n }\n get securityHandler() {\n return this._securityHandler;\n }\n set securityHandler(_) {\n throw new Error("doc.securityHandler is read-only");\n }\n get selectedAnnots() {\n return [];\n }\n set selectedAnnots(_) {\n throw new Error("doc.selectedAnnots is read-only");\n }\n get sounds() {\n return [];\n }\n set sounds(_) {\n throw new Error("doc.sounds is read-only");\n }\n get spellDictionaryOrder() {\n return this._spellDictionaryOrder;\n }\n set spellDictionaryOrder(spellDictionaryOrder) {\n this._spellDictionaryOrder = spellDictionaryOrder;\n }\n get spellLanguageOrder() {\n return this._spellLanguageOrder;\n }\n set spellLanguageOrder(spellLanguageOrder) {\n this._spellLanguageOrder = spellLanguageOrder;\n }\n get subject() {\n return this._subject;\n }\n set subject(_) {\n throw new Error("doc.subject is read-only");\n }\n get templates() {\n return [];\n }\n set templates(_) {\n throw new Error("doc.templates is read-only");\n }\n get title() {\n return this._title;\n }\n set title(_) {\n throw new Error("doc.title is read-only");\n }\n get URL() {\n return this._URL;\n }\n set URL(_) {\n throw new Error("doc.URL is read-only");\n }\n get viewState() {\n return undefined;\n }\n set viewState(_) {\n throw new Error("doc.viewState is read-only");\n }\n get xfa() {\n return this._xfa;\n }\n set xfa(_) {\n throw new Error("doc.xfa is read-only");\n }\n get XFAForeground() {\n return false;\n }\n set XFAForeground(_) {\n throw new Error("doc.XFAForeground is read-only");\n }\n get zoomType() {\n return this._zoomType;\n }\n set zoomType(type) {\n if (!this._userActivation) {\n return;\n }\n this._userActivation = false;\n if (typeof type !== "string") {\n return;\n }\n switch (type) {\n case ZoomType.none:\n this._send({\n command: "zoom",\n value: 1\n });\n break;\n case ZoomType.fitP:\n this._send({\n command: "zoom",\n value: "page-fit"\n });\n break;\n case ZoomType.fitW:\n this._send({\n command: "zoom",\n value: "page-width"\n });\n break;\n case ZoomType.fitH:\n this._send({\n command: "zoom",\n value: "page-height"\n });\n break;\n case ZoomType.fitV:\n this._send({\n command: "zoom",\n value: "auto"\n });\n break;\n case ZoomType.pref:\n case ZoomType.refW:\n break;\n default:\n return;\n }\n this._zoomType = type;\n }\n get zoom() {\n return this._zoom;\n }\n set zoom(value) {\n if (!this._userActivation) {\n return;\n }\n this._userActivation = false;\n if (typeof value !== "number" || value < 8.33 || value > 6400) {\n return;\n }\n this._send({\n command: "zoom",\n value: value / 100\n });\n }\n addAnnot() {}\n addField() {}\n addIcon() {}\n addLink() {}\n addRecipientListCryptFilter() {}\n addRequirement() {}\n addScript() {}\n addThumbnails() {}\n addWatermarkFromFile() {}\n addWatermarkFromText() {}\n addWeblinks() {}\n bringToFront() {}\n calculateNow() {\n this._eventDispatcher.calculateNow();\n }\n closeDoc() {}\n colorConvertPage() {}\n createDataObject() {}\n createTemplate() {}\n deletePages() {}\n deleteSound() {}\n embedDocAsDataObject() {}\n embedOutputIntent() {}\n encryptForRecipients() {}\n encryptUsingPolicy() {}\n exportAsFDF() {}\n exportAsFDFStr() {}\n exportAsText() {}\n exportAsXFDF() {}\n exportAsXFDFStr() {}\n exportDataObject() {}\n exportXFAData() {}\n extractPages() {}\n flattenPages() {}\n getAnnot() {}\n getAnnots() {}\n getAnnot3D() {}\n getAnnots3D() {}\n getColorConvertAction() {}\n getDataObject() {}\n getDataObjectContents() {}\n _getField(cName) {\n if (cName && typeof cName === "object") {\n cName = cName.cName;\n }\n if (typeof cName !== "string") {\n throw new TypeError("Invalid field name: must be a string");\n }\n const searchedField = this._fields.get(cName);\n if (searchedField) {\n return searchedField;\n }\n const parts = cName.split("#");\n let childIndex = NaN;\n if (parts.length === 2) {\n childIndex = Math.floor(parseFloat(parts[1]));\n cName = parts[0];\n }\n for (const [name, field] of this._fields.entries()) {\n if (name.endsWith(cName)) {\n if (!isNaN(childIndex)) {\n const children = this._getChildren(name);\n if (childIndex < 0 || childIndex >= children.length) {\n childIndex = 0;\n }\n if (childIndex < children.length) {\n this._fields.set(cName, children[childIndex]);\n return children[childIndex];\n }\n }\n this._fields.set(cName, field);\n return field;\n }\n }\n return null;\n }\n getField(cName) {\n const field = this._getField(cName);\n if (!field) {\n return null;\n }\n return field.wrapped;\n }\n _getChildren(fieldName) {\n const len = fieldName.length;\n const children = [];\n const pattern = /^\\.[^.]+$/;\n for (const [name, field] of this._fields.entries()) {\n if (name.startsWith(fieldName)) {\n const finalPart = name.slice(len);\n if (pattern.test(finalPart)) {\n children.push(field);\n }\n }\n }\n return children;\n }\n _getTerminalChildren(fieldName) {\n const children = [];\n const len = fieldName.length;\n for (const [name, field] of this._fields.entries()) {\n if (name.startsWith(fieldName)) {\n const finalPart = name.slice(len);\n if (field.obj._hasValue && (finalPart === "" || finalPart.startsWith("."))) {\n children.push(field.wrapped);\n }\n }\n }\n return children;\n }\n getIcon() {}\n getLegalWarnings() {}\n getLinks() {}\n getNthFieldName(nIndex) {\n if (nIndex && typeof nIndex === "object") {\n nIndex = nIndex.nIndex;\n }\n if (typeof nIndex !== "number") {\n throw new TypeError("Invalid field index: must be a number");\n }\n if (0 <= nIndex && nIndex < this.numFields) {\n return this._fieldNames[Math.trunc(nIndex)];\n }\n return null;\n }\n getNthTemplate() {\n return null;\n }\n getOCGs() {}\n getOCGOrder() {}\n getPageBox() {}\n getPageLabel() {}\n getPageNthWord() {}\n getPageNthWordQuads() {}\n getPageNumWords() {}\n getPageRotation() {}\n getPageTransition() {}\n getPrintParams() {\n return this._printParams ||= new PrintParams({\n lastPage: this._numPages - 1\n });\n }\n getSound() {}\n getTemplate() {}\n getURL() {}\n gotoNamedDest() {}\n importAnFDF() {}\n importAnXFDF() {}\n importDataObject() {}\n importIcon() {}\n importSound() {}\n importTextData() {}\n importXFAData() {}\n insertPages() {}\n mailDoc() {}\n mailForm() {}\n movePage() {}\n newPage() {}\n openDataObject() {}\n print(bUI = true, nStart = 0, nEnd = -1, bSilent = false, bShrinkToFit = false, bPrintAsImage = false, bReverse = false, bAnnotations = true, printParams = null) {\n if (this._disablePrinting || !this._userActivation) {\n return;\n }\n this._userActivation = false;\n if (bUI && typeof bUI === "object") {\n nStart = bUI.nStart;\n nEnd = bUI.nEnd;\n bSilent = bUI.bSilent;\n bShrinkToFit = bUI.bShrinkToFit;\n bPrintAsImage = bUI.bPrintAsImage;\n bReverse = bUI.bReverse;\n bAnnotations = bUI.bAnnotations;\n printParams = bUI.printParams;\n bUI = bUI.bUI;\n }\n if (printParams) {\n nStart = printParams.firstPage;\n nEnd = printParams.lastPage;\n }\n nStart = typeof nStart === "number" ? Math.max(0, Math.trunc(nStart)) : 0;\n nEnd = typeof nEnd === "number" ? Math.max(0, Math.trunc(nEnd)) : -1;\n this._send({\n command: "print",\n start: nStart,\n end: nEnd\n });\n }\n removeDataObject() {}\n removeField() {}\n removeIcon() {}\n removeLinks() {}\n removeRequirement() {}\n removeScript() {}\n removeTemplate() {}\n removeThumbnails() {}\n removeWeblinks() {}\n replacePages() {}\n resetForm(aFields = null) {\n if (aFields && typeof aFields === "object" && !Array.isArray(aFields)) {\n aFields = aFields.aFields;\n }\n if (aFields && !Array.isArray(aFields)) {\n aFields = [aFields];\n }\n let mustCalculate = false;\n let fieldsToReset;\n if (aFields) {\n fieldsToReset = [];\n for (const fieldName of aFields) {\n if (!fieldName) {\n continue;\n }\n if (typeof fieldName !== "string") {\n fieldsToReset = null;\n break;\n }\n const field = this._getField(fieldName);\n if (!field) {\n continue;\n }\n fieldsToReset.push(field);\n mustCalculate = true;\n }\n }\n if (!fieldsToReset) {\n fieldsToReset = this._fields.values();\n mustCalculate = this._fields.size !== 0;\n }\n for (const field of fieldsToReset) {\n field.obj.value = field.obj.defaultValue;\n this._send({\n id: field.obj._id,\n siblings: field.obj._siblings,\n value: field.obj.defaultValue,\n formattedValue: null,\n selRange: [0, 0]\n });\n }\n if (mustCalculate) {\n this.calculateNow();\n }\n }\n saveAs() {}\n scroll() {}\n selectPageNthWord() {}\n setAction() {}\n setDataObjectContents() {}\n setOCGOrder() {}\n setPageAction() {}\n setPageBoxes() {}\n setPageLabels() {}\n setPageRotations() {}\n setPageTabOrder() {}\n setPageTransitions() {}\n spawnPageFromTemplate() {}\n submitForm() {}\n syncAnnotScan() {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/proxy.js\nclass ProxyHandler {\n constructor() {\n this.nosend = new Set(["delay"]);\n }\n get(obj, prop) {\n if (prop in obj._expandos) {\n const val = obj._expandos[prop];\n if (typeof val === "function") {\n return val.bind(obj);\n }\n return val;\n }\n if (typeof prop === "string" && !prop.startsWith("_") && prop in obj) {\n const val = obj[prop];\n if (typeof val === "function") {\n return val.bind(obj);\n }\n return val;\n }\n return undefined;\n }\n set(obj, prop, value) {\n if (obj._kidIds) {\n obj._kidIds.forEach(id => {\n obj._appObjects[id].wrapped[prop] = value;\n });\n }\n if (typeof prop === "string" && !prop.startsWith("_") && prop in obj) {\n const old = obj[prop];\n obj[prop] = value;\n if (!this.nosend.has(prop) && obj._send && obj._id !== null && typeof old !== "function") {\n const data = {\n id: obj._id\n };\n data[prop] = prop === "value" ? obj._getValue() : obj[prop];\n if (!obj._siblings) {\n obj._send(data);\n } else {\n data.siblings = obj._siblings;\n obj._send(data);\n }\n }\n } else {\n obj._expandos[prop] = value;\n }\n return true;\n }\n has(obj, prop) {\n return prop in obj._expandos || typeof prop === "string" && !prop.startsWith("_") && prop in obj;\n }\n getPrototypeOf(obj) {\n return null;\n }\n setPrototypeOf(obj, proto) {\n return false;\n }\n isExtensible(obj) {\n return true;\n }\n preventExtensions(obj) {\n return false;\n }\n getOwnPropertyDescriptor(obj, prop) {\n if (prop in obj._expandos) {\n return {\n configurable: true,\n enumerable: true,\n value: obj._expandos[prop]\n };\n }\n if (typeof prop === "string" && !prop.startsWith("_") && prop in obj) {\n return {\n configurable: true,\n enumerable: true,\n value: obj[prop]\n };\n }\n return undefined;\n }\n defineProperty(obj, key, descriptor) {\n Object.defineProperty(obj._expandos, key, descriptor);\n return true;\n }\n deleteProperty(obj, prop) {\n if (prop in obj._expandos) {\n delete obj._expandos[prop];\n }\n }\n ownKeys(obj) {\n const fromExpandos = Reflect.ownKeys(obj._expandos);\n const fromObj = Reflect.ownKeys(obj).filter(k => !k.startsWith("_"));\n return fromExpandos.concat(fromObj);\n }\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/util.js\n\nclass Util extends PDFObject {\n constructor(data) {\n super(data);\n this._scandCache = new Map();\n this._months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];\n this._days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];\n this.MILLISECONDS_IN_DAY = 86400000;\n this.MILLISECONDS_IN_WEEK = 604800000;\n this._externalCall = data.externalCall;\n }\n printf(...args) {\n if (args.length === 0) {\n throw new Error("Invalid number of params in printf");\n }\n if (typeof args[0] !== "string") {\n throw new TypeError("First argument of printf must be a string");\n }\n const pattern = /%(,[0-4])?([+ 0#]+)?(\\d+)?(\\.\\d+)?(.)/g;\n const PLUS = 1;\n const SPACE = 2;\n const ZERO = 4;\n const HASH = 8;\n let i = 0;\n return args[0].replaceAll(pattern, function (match, nDecSep, cFlags, nWidth, nPrecision, cConvChar) {\n if (cConvChar !== "d" && cConvChar !== "f" && cConvChar !== "s" && cConvChar !== "x") {\n const buf = ["%"];\n for (const str of [nDecSep, cFlags, nWidth, nPrecision, cConvChar]) {\n if (str) {\n buf.push(str);\n }\n }\n return buf.join("");\n }\n i++;\n if (i === args.length) {\n throw new Error("Not enough arguments in printf");\n }\n const arg = args[i];\n if (cConvChar === "s") {\n return arg.toString();\n }\n let flags = 0;\n if (cFlags) {\n for (const flag of cFlags) {\n switch (flag) {\n case "+":\n flags |= PLUS;\n break;\n case " ":\n flags |= SPACE;\n break;\n case "0":\n flags |= ZERO;\n break;\n case "#":\n flags |= HASH;\n break;\n }\n }\n }\n cFlags = flags;\n if (nWidth) {\n nWidth = parseInt(nWidth);\n }\n let intPart = Math.trunc(arg);\n if (cConvChar === "x") {\n let hex = Math.abs(intPart).toString(16).toUpperCase();\n if (nWidth !== undefined) {\n hex = hex.padStart(nWidth, cFlags & ZERO ? "0" : " ");\n }\n if (cFlags & HASH) {\n hex = `0x${hex}`;\n }\n return hex;\n }\n if (nPrecision) {\n nPrecision = parseInt(nPrecision.substring(1));\n }\n nDecSep = nDecSep ? nDecSep.substring(1) : "0";\n const separators = {\n 0: [",", "."],\n 1: ["", "."],\n 2: [".", ","],\n 3: ["", ","],\n 4: ["\'", "."]\n };\n const [thousandSep, decimalSep] = separators[nDecSep];\n let decPart = "";\n if (cConvChar === "f") {\n decPart = nPrecision !== undefined ? Math.abs(arg - intPart).toFixed(nPrecision) : Math.abs(arg - intPart).toString();\n if (decPart.length > 2) {\n decPart = `${decimalSep}${decPart.substring(2)}`;\n } else {\n if (decPart === "1") {\n intPart += Math.sign(arg);\n }\n decPart = cFlags & HASH ? "." : "";\n }\n }\n let sign = "";\n if (intPart < 0) {\n sign = "-";\n intPart = -intPart;\n } else if (cFlags & PLUS) {\n sign = "+";\n } else if (cFlags & SPACE) {\n sign = " ";\n }\n if (thousandSep && intPart >= 1000) {\n const buf = [];\n while (true) {\n buf.push((intPart % 1000).toString().padStart(3, "0"));\n intPart = Math.trunc(intPart / 1000);\n if (intPart < 1000) {\n buf.push(intPart.toString());\n break;\n }\n }\n intPart = buf.reverse().join(thousandSep);\n } else {\n intPart = intPart.toString();\n }\n let n = `${intPart}${decPart}`;\n if (nWidth !== undefined) {\n n = n.padStart(nWidth - sign.length, cFlags & ZERO ? "0" : " ");\n }\n return `${sign}${n}`;\n });\n }\n iconStreamFromIcon() {}\n printd(cFormat, oDate) {\n switch (cFormat) {\n case 0:\n return this.printd("D:yyyymmddHHMMss", oDate);\n case 1:\n return this.printd("yyyy.mm.dd HH:MM:ss", oDate);\n case 2:\n return this.printd("m/d/yy h:MM:ss tt", oDate);\n }\n const handlers = {\n mmmm: data => {\n return this._months[data.month];\n },\n mmm: data => {\n return this._months[data.month].substring(0, 3);\n },\n mm: data => {\n return (data.month + 1).toString().padStart(2, "0");\n },\n m: data => {\n return (data.month + 1).toString();\n },\n dddd: data => {\n return this._days[data.dayOfWeek];\n },\n ddd: data => {\n return this._days[data.dayOfWeek].substring(0, 3);\n },\n dd: data => {\n return data.day.toString().padStart(2, "0");\n },\n d: data => {\n return data.day.toString();\n },\n yyyy: data => {\n return data.year.toString();\n },\n yy: data => {\n return (data.year % 100).toString().padStart(2, "0");\n },\n HH: data => {\n return data.hours.toString().padStart(2, "0");\n },\n H: data => {\n return data.hours.toString();\n },\n hh: data => {\n return (1 + (data.hours + 11) % 12).toString().padStart(2, "0");\n },\n h: data => {\n return (1 + (data.hours + 11) % 12).toString();\n },\n MM: data => {\n return data.minutes.toString().padStart(2, "0");\n },\n M: data => {\n return data.minutes.toString();\n },\n ss: data => {\n return data.seconds.toString().padStart(2, "0");\n },\n s: data => {\n return data.seconds.toString();\n },\n tt: data => {\n return data.hours < 12 ? "am" : "pm";\n },\n t: data => {\n return data.hours < 12 ? "a" : "p";\n }\n };\n const data = {\n year: oDate.getFullYear(),\n month: oDate.getMonth(),\n day: oDate.getDate(),\n dayOfWeek: oDate.getDay(),\n hours: oDate.getHours(),\n minutes: oDate.getMinutes(),\n seconds: oDate.getSeconds()\n };\n const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t|\\\\.)/g;\n return cFormat.replaceAll(patterns, function (match, pattern) {\n if (pattern in handlers) {\n return handlers[pattern](data);\n }\n return pattern.charCodeAt(1);\n });\n }\n printx(cFormat, cSource) {\n cSource = (cSource ?? "").toString();\n const handlers = [x => x, x => x.toUpperCase(), x => x.toLowerCase()];\n const buf = [];\n let i = 0;\n const ii = cSource.length;\n let currCase = handlers[0];\n let escaped = false;\n for (const command of cFormat) {\n if (escaped) {\n buf.push(command);\n escaped = false;\n continue;\n }\n if (i >= ii) {\n break;\n }\n switch (command) {\n case "?":\n buf.push(currCase(cSource.charAt(i++)));\n break;\n case "X":\n while (i < ii) {\n const char = cSource.charAt(i++);\n if ("a" <= char && char <= "z" || "A" <= char && char <= "Z" || "0" <= char && char <= "9") {\n buf.push(currCase(char));\n break;\n }\n }\n break;\n case "A":\n while (i < ii) {\n const char = cSource.charAt(i++);\n if ("a" <= char && char <= "z" || "A" <= char && char <= "Z") {\n buf.push(currCase(char));\n break;\n }\n }\n break;\n case "9":\n while (i < ii) {\n const char = cSource.charAt(i++);\n if ("0" <= char && char <= "9") {\n buf.push(char);\n break;\n }\n }\n break;\n case "*":\n while (i < ii) {\n buf.push(currCase(cSource.charAt(i++)));\n }\n break;\n case "\\\\":\n escaped = true;\n break;\n case ">":\n currCase = handlers[1];\n break;\n case "<":\n currCase = handlers[2];\n break;\n case "=":\n currCase = handlers[0];\n break;\n default:\n buf.push(command);\n }\n }\n return buf.join("");\n }\n scand(cFormat, cDate) {\n if (typeof cDate !== "string") {\n return new Date(cDate);\n }\n if (cDate === "") {\n return new Date();\n }\n switch (cFormat) {\n case 0:\n return this.scand("D:yyyymmddHHMMss", cDate);\n case 1:\n return this.scand("yyyy.mm.dd HH:MM:ss", cDate);\n case 2:\n return this.scand("m/d/yy h:MM:ss tt", cDate);\n }\n if (!this._scandCache.has(cFormat)) {\n const months = this._months;\n const days = this._days;\n const handlers = {\n mmmm: {\n pattern: `(${months.join("|")})`,\n action: (value, data) => {\n data.month = months.indexOf(value);\n }\n },\n mmm: {\n pattern: `(${months.map(month => month.substring(0, 3)).join("|")})`,\n action: (value, data) => {\n data.month = months.findIndex(month => month.substring(0, 3) === value);\n }\n },\n mm: {\n pattern: `(\\\\d{2})`,\n action: (value, data) => {\n data.month = parseInt(value) - 1;\n }\n },\n m: {\n pattern: `(\\\\d{1,2})`,\n action: (value, data) => {\n data.month = parseInt(value) - 1;\n }\n },\n dddd: {\n pattern: `(${days.join("|")})`,\n action: (value, data) => {\n data.day = days.indexOf(value);\n }\n },\n ddd: {\n pattern: `(${days.map(day => day.substring(0, 3)).join("|")})`,\n action: (value, data) => {\n data.day = days.findIndex(day => day.substring(0, 3) === value);\n }\n },\n dd: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.day = parseInt(value);\n }\n },\n d: {\n pattern: "(\\\\d{1,2})",\n action: (value, data) => {\n data.day = parseInt(value);\n }\n },\n yyyy: {\n pattern: "(\\\\d{4})",\n action: (value, data) => {\n data.year = parseInt(value);\n }\n },\n yy: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.year = 2000 + parseInt(value);\n }\n },\n HH: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.hours = parseInt(value);\n }\n },\n H: {\n pattern: "(\\\\d{1,2})",\n action: (value, data) => {\n data.hours = parseInt(value);\n }\n },\n hh: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.hours = parseInt(value);\n }\n },\n h: {\n pattern: "(\\\\d{1,2})",\n action: (value, data) => {\n data.hours = parseInt(value);\n }\n },\n MM: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.minutes = parseInt(value);\n }\n },\n M: {\n pattern: "(\\\\d{1,2})",\n action: (value, data) => {\n data.minutes = parseInt(value);\n }\n },\n ss: {\n pattern: "(\\\\d{2})",\n action: (value, data) => {\n data.seconds = parseInt(value);\n }\n },\n s: {\n pattern: "(\\\\d{1,2})",\n action: (value, data) => {\n data.seconds = parseInt(value);\n }\n },\n tt: {\n pattern: "([aApP][mM])",\n action: (value, data) => {\n const char = value.charAt(0);\n data.am = char === "a" || char === "A";\n }\n },\n t: {\n pattern: "([aApP])",\n action: (value, data) => {\n data.am = value === "a" || value === "A";\n }\n }\n };\n const escapedFormat = cFormat.replaceAll(/[.*+\\-?^${}()|[\\]\\\\]/g, "\\\\$&");\n const patterns = /(mmmm|mmm|mm|m|dddd|ddd|dd|d|yyyy|yy|HH|H|hh|h|MM|M|ss|s|tt|t)/g;\n const actions = [];\n const re = escapedFormat.replaceAll(patterns, function (match, patternElement) {\n const {\n pattern,\n action\n } = handlers[patternElement];\n actions.push(action);\n return pattern;\n });\n this._scandCache.set(cFormat, [re, actions]);\n }\n const [re, actions] = this._scandCache.get(cFormat);\n const matches = new RegExp(`^${re}$`, "g").exec(cDate);\n if (!matches || matches.length !== actions.length + 1) {\n return null;\n }\n const data = {\n year: 2000,\n month: 0,\n day: 1,\n hours: 0,\n minutes: 0,\n seconds: 0,\n am: null\n };\n actions.forEach((action, i) => action(matches[i + 1], data));\n if (data.am !== null) {\n data.hours = data.hours % 12 + (data.am ? 0 : 12);\n }\n return new Date(data.year, data.month, data.day, data.hours, data.minutes, data.seconds);\n }\n spansToXML() {}\n stringFromStream() {}\n xmlToSpans() {}\n}\n\n;// CONCATENATED MODULE: ./src/scripting_api/initialization.js\n\n\n\n\n\n\n\n\n\n\nfunction initSandbox(params) {\n delete globalThis.pdfjsScripting;\n const externalCall = globalThis.callExternalFunction;\n delete globalThis.callExternalFunction;\n const globalEval = code => globalThis.eval(code);\n const send = data => externalCall("send", [data]);\n const proxyHandler = new ProxyHandler();\n const {\n data\n } = params;\n const doc = new Doc({\n send,\n globalEval,\n ...data.docInfo\n });\n const _document = {\n obj: doc,\n wrapped: new Proxy(doc, proxyHandler)\n };\n const app = new App({\n send,\n globalEval,\n externalCall,\n _document,\n calculationOrder: data.calculationOrder,\n proxyHandler,\n ...data.appInfo\n });\n const util = new Util({\n externalCall\n });\n const appObjects = app._objects;\n if (data.objects) {\n const annotations = [];\n for (const [name, objs] of Object.entries(data.objects)) {\n annotations.length = 0;\n let container = null;\n for (const obj of objs) {\n if (obj.type !== "") {\n annotations.push(obj);\n } else {\n container = obj;\n }\n }\n let obj = container;\n if (annotations.length > 0) {\n obj = annotations[0];\n obj.send = send;\n }\n obj.globalEval = globalEval;\n obj.doc = _document;\n obj.fieldPath = name;\n obj.appObjects = appObjects;\n let field;\n switch (obj.type) {\n case "radiobutton":\n {\n const otherButtons = annotations.slice(1);\n field = new RadioButtonField(otherButtons, obj);\n break;\n }\n case "checkbox":\n {\n const otherButtons = annotations.slice(1);\n field = new CheckboxField(otherButtons, obj);\n break;\n }\n case "text":\n if (annotations.length <= 1) {\n field = new Field(obj);\n break;\n }\n obj.siblings = annotations.map(x => x.id).slice(1);\n field = new Field(obj);\n break;\n default:\n field = new Field(obj);\n }\n const wrapped = new Proxy(field, proxyHandler);\n const _object = {\n obj: field,\n wrapped\n };\n doc._addField(name, _object);\n for (const object of objs) {\n appObjects[object.id] = _object;\n }\n if (container) {\n appObjects[container.id] = _object;\n }\n }\n }\n const color = new Color();\n globalThis.event = null;\n globalThis.global = Object.create(null);\n globalThis.app = new Proxy(app, proxyHandler);\n globalThis.color = new Proxy(color, proxyHandler);\n globalThis.console = new Proxy(new Console({\n send\n }), proxyHandler);\n globalThis.util = new Proxy(util, proxyHandler);\n globalThis.border = Border;\n globalThis.cursor = Cursor;\n globalThis.display = Display;\n globalThis.font = Font;\n globalThis.highlight = Highlight;\n globalThis.position = Position;\n globalThis.scaleHow = ScaleHow;\n globalThis.scaleWhen = ScaleWhen;\n globalThis.style = Style;\n globalThis.trans = Trans;\n globalThis.zoomtype = ZoomType;\n globalThis.ADBE = {\n Reader_Value_Asked: true,\n Viewer_Value_Asked: true\n };\n const aform = new AForm(doc, app, util, color);\n for (const name of Object.getOwnPropertyNames(AForm.prototype)) {\n if (name !== "constructor" && !name.startsWith("_")) {\n globalThis[name] = aform[name].bind(aform);\n }\n }\n for (const [name, value] of Object.entries(GlobalConstants)) {\n Object.defineProperty(globalThis, name, {\n value,\n writable: false\n });\n }\n Object.defineProperties(globalThis, {\n ColorConvert: {\n value: color.convert.bind(color),\n writable: true\n },\n ColorEqual: {\n value: color.equal.bind(color),\n writable: true\n }\n });\n const properties = Object.create(null);\n for (const name of Object.getOwnPropertyNames(Doc.prototype)) {\n if (name === "constructor" || name.startsWith("_")) {\n continue;\n }\n const descriptor = Object.getOwnPropertyDescriptor(Doc.prototype, name);\n if (descriptor.get) {\n properties[name] = {\n get: descriptor.get.bind(doc),\n set: descriptor.set.bind(doc)\n };\n } else {\n properties[name] = {\n value: Doc.prototype[name].bind(doc)\n };\n }\n }\n Object.defineProperties(globalThis, properties);\n const functions = {\n dispatchEvent: app._dispatchEvent.bind(app),\n timeoutCb: app._evalCallback.bind(app)\n };\n return (name, args) => {\n try {\n functions[name](args);\n } catch (error) {\n send(serializeError(error));\n }\n };\n}\n\n;// CONCATENATED MODULE: ./src/pdf.scripting.js\n\nconst pdfjsVersion = \'4.0.379\';\nconst pdfjsBuild = \'9e14d04fd\';\nglobalThis.pdfjsScripting = {\n initSandbox: initSandbox\n};\n'];
+ code.push("delete dump;");
+ let success = false;
+ let buf = 0;
+ try {
+ const sandboxData = JSON.stringify(data);
+ code.push(`pdfjsScripting.initSandbox({ data: ${sandboxData} })`);
+ buf = this._module.stringToNewUTF8(code.join("\n"));
+ success = !!this._module.ccall("init", "number", ["number", "number"], [buf, this._alertOnError]);
+ } catch (error) {
+ console.error(error);
+ } finally {
+ if (buf) {
+ this._module.ccall("free", "number", ["number"], [buf]);
+ }
+ }
+ if (success) {
+ this.support.commFun = this._module.cwrap("commFun", null, ["string", "string"]);
+ } else {
+ this.nukeSandbox();
+ throw new Error("Cannot start sandbox");
+ }
+ }
+ dispatchEvent(event) {
+ this.support?.callSandboxFunction("dispatchEvent", event);
+ }
+ dumpMemoryUse() {
+ this._module?.ccall("dumpMemoryUse", null, []);
+ }
+ nukeSandbox() {
+ if (this._module !== null) {
+ this.support.destroy();
+ this.support = null;
+ this._module.ccall("nukeSandbox", null, []);
+ this._module = null;
+ }
+ }
+ evalForTesting(code, key) {
+ throw new Error("Not implemented: evalForTesting");
+ }
+}
+function QuickJSSandbox() {
+ return quickjs_eval().then(module => {
+ return new Sandbox(window, module);
+ });
+}
+
+var __webpack_exports__QuickJSSandbox = __webpack_exports__.QuickJSSandbox;
+export { __webpack_exports__QuickJSSandbox as QuickJSSandbox };
+
+//# sourceMappingURL=pdf.sandbox.mjs.map
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/build/pdf.worker.mjs b/www/lib/pdfjs/modern/build/pdf.worker.mjs
new file mode 100644
index 000000000..05552b1b1
--- /dev/null
+++ b/www/lib/pdfjs/modern/build/pdf.worker.mjs
@@ -0,0 +1,57171 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * JavaScript code in this page
+ *
+ * Copyright 2023 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * JavaScript code in this page
+ */
+
+/******/ // The require scope
+/******/ var __webpack_require__ = {};
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/define property getters */
+/******/ (() => {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = (exports, definition) => {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ (() => {
+/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+/******/ })();
+/******/
+/************************************************************************/
+var __webpack_exports__ = globalThis.pdfjsWorker = {};
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ WorkerMessageHandler: () => (/* reexport */ WorkerMessageHandler)
+});
+
+;// CONCATENATED MODULE: ./src/shared/util.js
+const isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser");
+const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+const MAX_IMAGE_SIZE_TO_CACHE = 10e6;
+const LINE_FACTOR = 1.35;
+const LINE_DESCENT_FACTOR = 0.35;
+const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
+const RenderingIntentFlag = {
+ ANY: 0x01,
+ DISPLAY: 0x02,
+ PRINT: 0x04,
+ SAVE: 0x08,
+ ANNOTATIONS_FORMS: 0x10,
+ ANNOTATIONS_STORAGE: 0x20,
+ ANNOTATIONS_DISABLE: 0x40,
+ OPLIST: 0x100
+};
+const AnnotationMode = {
+ DISABLE: 0,
+ ENABLE: 1,
+ ENABLE_FORMS: 2,
+ ENABLE_STORAGE: 3
+};
+const AnnotationEditorPrefix = "pdfjs_internal_editor_";
+const AnnotationEditorType = {
+ DISABLE: -1,
+ NONE: 0,
+ FREETEXT: 3,
+ HIGHLIGHT: 9,
+ STAMP: 13,
+ INK: 15
+};
+const AnnotationEditorParamsType = {
+ RESIZE: 1,
+ CREATE: 2,
+ FREETEXT_SIZE: 11,
+ FREETEXT_COLOR: 12,
+ FREETEXT_OPACITY: 13,
+ INK_COLOR: 21,
+ INK_THICKNESS: 22,
+ INK_OPACITY: 23,
+ HIGHLIGHT_COLOR: 31,
+ HIGHLIGHT_DEFAULT_COLOR: 32
+};
+const PermissionFlag = {
+ PRINT: 0x04,
+ MODIFY_CONTENTS: 0x08,
+ COPY: 0x10,
+ MODIFY_ANNOTATIONS: 0x20,
+ FILL_INTERACTIVE_FORMS: 0x100,
+ COPY_FOR_ACCESSIBILITY: 0x200,
+ ASSEMBLE: 0x400,
+ PRINT_HIGH_QUALITY: 0x800
+};
+const TextRenderingMode = {
+ FILL: 0,
+ STROKE: 1,
+ FILL_STROKE: 2,
+ INVISIBLE: 3,
+ FILL_ADD_TO_PATH: 4,
+ STROKE_ADD_TO_PATH: 5,
+ FILL_STROKE_ADD_TO_PATH: 6,
+ ADD_TO_PATH: 7,
+ FILL_STROKE_MASK: 3,
+ ADD_TO_PATH_FLAG: 4
+};
+const ImageKind = {
+ GRAYSCALE_1BPP: 1,
+ RGB_24BPP: 2,
+ RGBA_32BPP: 3
+};
+const AnnotationType = {
+ TEXT: 1,
+ LINK: 2,
+ FREETEXT: 3,
+ LINE: 4,
+ SQUARE: 5,
+ CIRCLE: 6,
+ POLYGON: 7,
+ POLYLINE: 8,
+ HIGHLIGHT: 9,
+ UNDERLINE: 10,
+ SQUIGGLY: 11,
+ STRIKEOUT: 12,
+ STAMP: 13,
+ CARET: 14,
+ INK: 15,
+ POPUP: 16,
+ FILEATTACHMENT: 17,
+ SOUND: 18,
+ MOVIE: 19,
+ WIDGET: 20,
+ SCREEN: 21,
+ PRINTERMARK: 22,
+ TRAPNET: 23,
+ WATERMARK: 24,
+ THREED: 25,
+ REDACT: 26
+};
+const AnnotationReplyType = {
+ GROUP: "Group",
+ REPLY: "R"
+};
+const AnnotationFlag = {
+ INVISIBLE: 0x01,
+ HIDDEN: 0x02,
+ PRINT: 0x04,
+ NOZOOM: 0x08,
+ NOROTATE: 0x10,
+ NOVIEW: 0x20,
+ READONLY: 0x40,
+ LOCKED: 0x80,
+ TOGGLENOVIEW: 0x100,
+ LOCKEDCONTENTS: 0x200
+};
+const AnnotationFieldFlag = {
+ READONLY: 0x0000001,
+ REQUIRED: 0x0000002,
+ NOEXPORT: 0x0000004,
+ MULTILINE: 0x0001000,
+ PASSWORD: 0x0002000,
+ NOTOGGLETOOFF: 0x0004000,
+ RADIO: 0x0008000,
+ PUSHBUTTON: 0x0010000,
+ COMBO: 0x0020000,
+ EDIT: 0x0040000,
+ SORT: 0x0080000,
+ FILESELECT: 0x0100000,
+ MULTISELECT: 0x0200000,
+ DONOTSPELLCHECK: 0x0400000,
+ DONOTSCROLL: 0x0800000,
+ COMB: 0x1000000,
+ RICHTEXT: 0x2000000,
+ RADIOSINUNISON: 0x2000000,
+ COMMITONSELCHANGE: 0x4000000
+};
+const AnnotationBorderStyleType = {
+ SOLID: 1,
+ DASHED: 2,
+ BEVELED: 3,
+ INSET: 4,
+ UNDERLINE: 5
+};
+const AnnotationActionEventType = {
+ E: "Mouse Enter",
+ X: "Mouse Exit",
+ D: "Mouse Down",
+ U: "Mouse Up",
+ Fo: "Focus",
+ Bl: "Blur",
+ PO: "PageOpen",
+ PC: "PageClose",
+ PV: "PageVisible",
+ PI: "PageInvisible",
+ K: "Keystroke",
+ F: "Format",
+ V: "Validate",
+ C: "Calculate"
+};
+const DocumentActionEventType = {
+ WC: "WillClose",
+ WS: "WillSave",
+ DS: "DidSave",
+ WP: "WillPrint",
+ DP: "DidPrint"
+};
+const PageActionEventType = {
+ O: "PageOpen",
+ C: "PageClose"
+};
+const VerbosityLevel = {
+ ERRORS: 0,
+ WARNINGS: 1,
+ INFOS: 5
+};
+const CMapCompressionType = {
+ NONE: 0,
+ BINARY: 1
+};
+const OPS = {
+ dependency: 1,
+ setLineWidth: 2,
+ setLineCap: 3,
+ setLineJoin: 4,
+ setMiterLimit: 5,
+ setDash: 6,
+ setRenderingIntent: 7,
+ setFlatness: 8,
+ setGState: 9,
+ save: 10,
+ restore: 11,
+ transform: 12,
+ moveTo: 13,
+ lineTo: 14,
+ curveTo: 15,
+ curveTo2: 16,
+ curveTo3: 17,
+ closePath: 18,
+ rectangle: 19,
+ stroke: 20,
+ closeStroke: 21,
+ fill: 22,
+ eoFill: 23,
+ fillStroke: 24,
+ eoFillStroke: 25,
+ closeFillStroke: 26,
+ closeEOFillStroke: 27,
+ endPath: 28,
+ clip: 29,
+ eoClip: 30,
+ beginText: 31,
+ endText: 32,
+ setCharSpacing: 33,
+ setWordSpacing: 34,
+ setHScale: 35,
+ setLeading: 36,
+ setFont: 37,
+ setTextRenderingMode: 38,
+ setTextRise: 39,
+ moveText: 40,
+ setLeadingMoveText: 41,
+ setTextMatrix: 42,
+ nextLine: 43,
+ showText: 44,
+ showSpacedText: 45,
+ nextLineShowText: 46,
+ nextLineSetSpacingShowText: 47,
+ setCharWidth: 48,
+ setCharWidthAndBounds: 49,
+ setStrokeColorSpace: 50,
+ setFillColorSpace: 51,
+ setStrokeColor: 52,
+ setStrokeColorN: 53,
+ setFillColor: 54,
+ setFillColorN: 55,
+ setStrokeGray: 56,
+ setFillGray: 57,
+ setStrokeRGBColor: 58,
+ setFillRGBColor: 59,
+ setStrokeCMYKColor: 60,
+ setFillCMYKColor: 61,
+ shadingFill: 62,
+ beginInlineImage: 63,
+ beginImageData: 64,
+ endInlineImage: 65,
+ paintXObject: 66,
+ markPoint: 67,
+ markPointProps: 68,
+ beginMarkedContent: 69,
+ beginMarkedContentProps: 70,
+ endMarkedContent: 71,
+ beginCompat: 72,
+ endCompat: 73,
+ paintFormXObjectBegin: 74,
+ paintFormXObjectEnd: 75,
+ beginGroup: 76,
+ endGroup: 77,
+ beginAnnotation: 80,
+ endAnnotation: 81,
+ paintImageMaskXObject: 83,
+ paintImageMaskXObjectGroup: 84,
+ paintImageXObject: 85,
+ paintInlineImageXObject: 86,
+ paintInlineImageXObjectGroup: 87,
+ paintImageXObjectRepeat: 88,
+ paintImageMaskXObjectRepeat: 89,
+ paintSolidColorImageMask: 90,
+ constructPath: 91
+};
+const PasswordResponses = {
+ NEED_PASSWORD: 1,
+ INCORRECT_PASSWORD: 2
+};
+let verbosity = VerbosityLevel.WARNINGS;
+function setVerbosityLevel(level) {
+ if (Number.isInteger(level)) {
+ verbosity = level;
+ }
+}
+function getVerbosityLevel() {
+ return verbosity;
+}
+function info(msg) {
+ if (verbosity >= VerbosityLevel.INFOS) {
+ console.log(`Info: ${msg}`);
+ }
+}
+function warn(msg) {
+ if (verbosity >= VerbosityLevel.WARNINGS) {
+ console.log(`Warning: ${msg}`);
+ }
+}
+function unreachable(msg) {
+ throw new Error(msg);
+}
+function assert(cond, msg) {
+ if (!cond) {
+ unreachable(msg);
+ }
+}
+function _isValidProtocol(url) {
+ switch (url?.protocol) {
+ case "http:":
+ case "https:":
+ case "ftp:":
+ case "mailto:":
+ case "tel:":
+ return true;
+ default:
+ return false;
+ }
+}
+function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
+ if (!url) {
+ return null;
+ }
+ try {
+ if (options && typeof url === "string") {
+ if (options.addDefaultProtocol && url.startsWith("www.")) {
+ const dots = url.match(/\./g);
+ if (dots?.length >= 2) {
+ url = `http://${url}`;
+ }
+ }
+ if (options.tryConvertEncoding) {
+ try {
+ url = stringToUTF8String(url);
+ } catch {}
+ }
+ }
+ const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
+ if (_isValidProtocol(absoluteUrl)) {
+ return absoluteUrl;
+ }
+ } catch {}
+ return null;
+}
+function shadow(obj, prop, value, nonSerializable = false) {
+ Object.defineProperty(obj, prop, {
+ value,
+ enumerable: !nonSerializable,
+ configurable: true,
+ writable: false
+ });
+ return value;
+}
+const BaseException = function BaseExceptionClosure() {
+ function BaseException(message, name) {
+ if (this.constructor === BaseException) {
+ unreachable("Cannot initialize BaseException.");
+ }
+ this.message = message;
+ this.name = name;
+ }
+ BaseException.prototype = new Error();
+ BaseException.constructor = BaseException;
+ return BaseException;
+}();
+class PasswordException extends BaseException {
+ constructor(msg, code) {
+ super(msg, "PasswordException");
+ this.code = code;
+ }
+}
+class UnknownErrorException extends BaseException {
+ constructor(msg, details) {
+ super(msg, "UnknownErrorException");
+ this.details = details;
+ }
+}
+class InvalidPDFException extends BaseException {
+ constructor(msg) {
+ super(msg, "InvalidPDFException");
+ }
+}
+class MissingPDFException extends BaseException {
+ constructor(msg) {
+ super(msg, "MissingPDFException");
+ }
+}
+class UnexpectedResponseException extends BaseException {
+ constructor(msg, status) {
+ super(msg, "UnexpectedResponseException");
+ this.status = status;
+ }
+}
+class FormatError extends BaseException {
+ constructor(msg) {
+ super(msg, "FormatError");
+ }
+}
+class AbortException extends BaseException {
+ constructor(msg) {
+ super(msg, "AbortException");
+ }
+}
+function bytesToString(bytes) {
+ if (typeof bytes !== "object" || bytes?.length === undefined) {
+ unreachable("Invalid argument for bytesToString");
+ }
+ const length = bytes.length;
+ const MAX_ARGUMENT_COUNT = 8192;
+ if (length < MAX_ARGUMENT_COUNT) {
+ return String.fromCharCode.apply(null, bytes);
+ }
+ const strBuf = [];
+ for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) {
+ const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);
+ const chunk = bytes.subarray(i, chunkEnd);
+ strBuf.push(String.fromCharCode.apply(null, chunk));
+ }
+ return strBuf.join("");
+}
+function stringToBytes(str) {
+ if (typeof str !== "string") {
+ unreachable("Invalid argument for stringToBytes");
+ }
+ const length = str.length;
+ const bytes = new Uint8Array(length);
+ for (let i = 0; i < length; ++i) {
+ bytes[i] = str.charCodeAt(i) & 0xff;
+ }
+ return bytes;
+}
+function string32(value) {
+ return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
+}
+function objectSize(obj) {
+ return Object.keys(obj).length;
+}
+function objectFromMap(map) {
+ const obj = Object.create(null);
+ for (const [key, value] of map) {
+ obj[key] = value;
+ }
+ return obj;
+}
+function isLittleEndian() {
+ const buffer8 = new Uint8Array(4);
+ buffer8[0] = 1;
+ const view32 = new Uint32Array(buffer8.buffer, 0, 1);
+ return view32[0] === 1;
+}
+function isEvalSupported() {
+ try {
+ new Function("");
+ return true;
+ } catch {
+ return false;
+ }
+}
+class FeatureTest {
+ static get isLittleEndian() {
+ return shadow(this, "isLittleEndian", isLittleEndian());
+ }
+ static get isEvalSupported() {
+ return shadow(this, "isEvalSupported", isEvalSupported());
+ }
+ static get isOffscreenCanvasSupported() {
+ return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined");
+ }
+ static get platform() {
+ if (typeof navigator !== "undefined" && typeof navigator?.platform === "string") {
+ return shadow(this, "platform", {
+ isMac: navigator.platform.includes("Mac")
+ });
+ }
+ return shadow(this, "platform", {
+ isMac: false
+ });
+ }
+ static get isCSSRoundSupported() {
+ return shadow(this, "isCSSRoundSupported", globalThis.CSS?.supports?.("width: round(1.5px, 1px)"));
+ }
+}
+const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0"));
+class Util {
+ static makeHexColor(r, g, b) {
+ return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`;
+ }
+ static scaleMinMax(transform, minMax) {
+ let temp;
+ if (transform[0]) {
+ if (transform[0] < 0) {
+ temp = minMax[0];
+ minMax[0] = minMax[1];
+ minMax[1] = temp;
+ }
+ minMax[0] *= transform[0];
+ minMax[1] *= transform[0];
+ if (transform[3] < 0) {
+ temp = minMax[2];
+ minMax[2] = minMax[3];
+ minMax[3] = temp;
+ }
+ minMax[2] *= transform[3];
+ minMax[3] *= transform[3];
+ } else {
+ temp = minMax[0];
+ minMax[0] = minMax[2];
+ minMax[2] = temp;
+ temp = minMax[1];
+ minMax[1] = minMax[3];
+ minMax[3] = temp;
+ if (transform[1] < 0) {
+ temp = minMax[2];
+ minMax[2] = minMax[3];
+ minMax[3] = temp;
+ }
+ minMax[2] *= transform[1];
+ minMax[3] *= transform[1];
+ if (transform[2] < 0) {
+ temp = minMax[0];
+ minMax[0] = minMax[1];
+ minMax[1] = temp;
+ }
+ minMax[0] *= transform[2];
+ minMax[1] *= transform[2];
+ }
+ minMax[0] += transform[4];
+ minMax[1] += transform[4];
+ minMax[2] += transform[5];
+ minMax[3] += transform[5];
+ }
+ static transform(m1, m2) {
+ return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];
+ }
+ static applyTransform(p, m) {
+ const xt = p[0] * m[0] + p[1] * m[2] + m[4];
+ const yt = p[0] * m[1] + p[1] * m[3] + m[5];
+ return [xt, yt];
+ }
+ static applyInverseTransform(p, m) {
+ const d = m[0] * m[3] - m[1] * m[2];
+ const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
+ const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
+ return [xt, yt];
+ }
+ static getAxialAlignedBoundingBox(r, m) {
+ const p1 = this.applyTransform(r, m);
+ const p2 = this.applyTransform(r.slice(2, 4), m);
+ const p3 = this.applyTransform([r[0], r[3]], m);
+ const p4 = this.applyTransform([r[2], r[1]], m);
+ return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];
+ }
+ static inverseTransform(m) {
+ const d = m[0] * m[3] - m[1] * m[2];
+ return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];
+ }
+ static singularValueDecompose2dScale(m) {
+ const transpose = [m[0], m[2], m[1], m[3]];
+ const a = m[0] * transpose[0] + m[1] * transpose[2];
+ const b = m[0] * transpose[1] + m[1] * transpose[3];
+ const c = m[2] * transpose[0] + m[3] * transpose[2];
+ const d = m[2] * transpose[1] + m[3] * transpose[3];
+ const first = (a + d) / 2;
+ const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;
+ const sx = first + second || 1;
+ const sy = first - second || 1;
+ return [Math.sqrt(sx), Math.sqrt(sy)];
+ }
+ static normalizeRect(rect) {
+ const r = rect.slice(0);
+ if (rect[0] > rect[2]) {
+ r[0] = rect[2];
+ r[2] = rect[0];
+ }
+ if (rect[1] > rect[3]) {
+ r[1] = rect[3];
+ r[3] = rect[1];
+ }
+ return r;
+ }
+ static intersect(rect1, rect2) {
+ const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2]));
+ const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2]));
+ if (xLow > xHigh) {
+ return null;
+ }
+ const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3]));
+ const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3]));
+ if (yLow > yHigh) {
+ return null;
+ }
+ return [xLow, yLow, xHigh, yHigh];
+ }
+ static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) {
+ const tvalues = [],
+ bounds = [[], []];
+ let a, b, c, t, t1, t2, b2ac, sqrtb2ac;
+ for (let i = 0; i < 2; ++i) {
+ if (i === 0) {
+ b = 6 * x0 - 12 * x1 + 6 * x2;
+ a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
+ c = 3 * x1 - 3 * x0;
+ } else {
+ b = 6 * y0 - 12 * y1 + 6 * y2;
+ a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
+ c = 3 * y1 - 3 * y0;
+ }
+ if (Math.abs(a) < 1e-12) {
+ if (Math.abs(b) < 1e-12) {
+ continue;
+ }
+ t = -c / b;
+ if (0 < t && t < 1) {
+ tvalues.push(t);
+ }
+ continue;
+ }
+ b2ac = b * b - 4 * c * a;
+ sqrtb2ac = Math.sqrt(b2ac);
+ if (b2ac < 0) {
+ continue;
+ }
+ t1 = (-b + sqrtb2ac) / (2 * a);
+ if (0 < t1 && t1 < 1) {
+ tvalues.push(t1);
+ }
+ t2 = (-b - sqrtb2ac) / (2 * a);
+ if (0 < t2 && t2 < 1) {
+ tvalues.push(t2);
+ }
+ }
+ let j = tvalues.length,
+ mt;
+ const jlen = j;
+ while (j--) {
+ t = tvalues[j];
+ mt = 1 - t;
+ bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;
+ bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;
+ }
+ bounds[0][jlen] = x0;
+ bounds[1][jlen] = y0;
+ bounds[0][jlen + 1] = x3;
+ bounds[1][jlen + 1] = y3;
+ bounds[0].length = bounds[1].length = jlen + 2;
+ return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])];
+ }
+}
+const PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac];
+function stringToPDFString(str) {
+ if (str[0] >= "\xEF") {
+ let encoding;
+ if (str[0] === "\xFE" && str[1] === "\xFF") {
+ encoding = "utf-16be";
+ if (str.length % 2 === 1) {
+ str = str.slice(0, -1);
+ }
+ } else if (str[0] === "\xFF" && str[1] === "\xFE") {
+ encoding = "utf-16le";
+ if (str.length % 2 === 1) {
+ str = str.slice(0, -1);
+ }
+ } else if (str[0] === "\xEF" && str[1] === "\xBB" && str[2] === "\xBF") {
+ encoding = "utf-8";
+ }
+ if (encoding) {
+ try {
+ const decoder = new TextDecoder(encoding, {
+ fatal: true
+ });
+ const buffer = stringToBytes(str);
+ const decoded = decoder.decode(buffer);
+ if (!decoded.includes("\x1b")) {
+ return decoded;
+ }
+ return decoded.replaceAll(/\x1b[^\x1b]*(?:\x1b|$)/g, "");
+ } catch (ex) {
+ warn(`stringToPDFString: "${ex}".`);
+ }
+ }
+ }
+ const strBuf = [];
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const charCode = str.charCodeAt(i);
+ if (charCode === 0x1b) {
+ while (++i < ii && str.charCodeAt(i) !== 0x1b) {}
+ continue;
+ }
+ const code = PDFStringTranslateTable[charCode];
+ strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
+ }
+ return strBuf.join("");
+}
+function stringToUTF8String(str) {
+ return decodeURIComponent(escape(str));
+}
+function utf8StringToString(str) {
+ return unescape(encodeURIComponent(str));
+}
+function isArrayBuffer(v) {
+ return typeof v === "object" && v?.byteLength !== undefined;
+}
+function isArrayEqual(arr1, arr2) {
+ if (arr1.length !== arr2.length) {
+ return false;
+ }
+ for (let i = 0, ii = arr1.length; i < ii; i++) {
+ if (arr1[i] !== arr2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+function getModificationDate(date = new Date()) {
+ const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")];
+ return buffer.join("");
+}
+class PromiseCapability {
+ #settled = false;
+ constructor() {
+ this.promise = new Promise((resolve, reject) => {
+ this.resolve = data => {
+ this.#settled = true;
+ resolve(data);
+ };
+ this.reject = reason => {
+ this.#settled = true;
+ reject(reason);
+ };
+ });
+ }
+ get settled() {
+ return this.#settled;
+ }
+}
+let NormalizeRegex = null;
+let NormalizationMap = null;
+function normalizeUnicode(str) {
+ if (!NormalizeRegex) {
+ NormalizeRegex = /([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;
+ NormalizationMap = new Map([["ſt", "ſt"]]);
+ }
+ return str.replaceAll(NormalizeRegex, (_, p1, p2) => {
+ return p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2);
+ });
+}
+function getUuid() {
+ if (typeof crypto !== "undefined" && typeof crypto?.randomUUID === "function") {
+ return crypto.randomUUID();
+ }
+ const buf = new Uint8Array(32);
+ if (typeof crypto !== "undefined" && typeof crypto?.getRandomValues === "function") {
+ crypto.getRandomValues(buf);
+ } else {
+ for (let i = 0; i < 32; i++) {
+ buf[i] = Math.floor(Math.random() * 255);
+ }
+ }
+ return bytesToString(buf);
+}
+const AnnotationPrefix = "pdfjs_internal_id_";
+
+;// CONCATENATED MODULE: ./src/core/primitives.js
+
+const CIRCULAR_REF = Symbol("CIRCULAR_REF");
+const EOF = Symbol("EOF");
+let CmdCache = Object.create(null);
+let NameCache = Object.create(null);
+let RefCache = Object.create(null);
+function clearPrimitiveCaches() {
+ CmdCache = Object.create(null);
+ NameCache = Object.create(null);
+ RefCache = Object.create(null);
+}
+class Name {
+ constructor(name) {
+ this.name = name;
+ }
+ static get(name) {
+ return NameCache[name] ||= new Name(name);
+ }
+}
+class Cmd {
+ constructor(cmd) {
+ this.cmd = cmd;
+ }
+ static get(cmd) {
+ return CmdCache[cmd] ||= new Cmd(cmd);
+ }
+}
+const nonSerializable = function nonSerializableClosure() {
+ return nonSerializable;
+};
+class Dict {
+ constructor(xref = null) {
+ this._map = Object.create(null);
+ this.xref = xref;
+ this.objId = null;
+ this.suppressEncryption = false;
+ this.__nonSerializable__ = nonSerializable;
+ }
+ assignXref(newXref) {
+ this.xref = newXref;
+ }
+ get size() {
+ return Object.keys(this._map).length;
+ }
+ get(key1, key2, key3) {
+ let value = this._map[key1];
+ if (value === undefined && key2 !== undefined) {
+ value = this._map[key2];
+ if (value === undefined && key3 !== undefined) {
+ value = this._map[key3];
+ }
+ }
+ if (value instanceof Ref && this.xref) {
+ return this.xref.fetch(value, this.suppressEncryption);
+ }
+ return value;
+ }
+ async getAsync(key1, key2, key3) {
+ let value = this._map[key1];
+ if (value === undefined && key2 !== undefined) {
+ value = this._map[key2];
+ if (value === undefined && key3 !== undefined) {
+ value = this._map[key3];
+ }
+ }
+ if (value instanceof Ref && this.xref) {
+ return this.xref.fetchAsync(value, this.suppressEncryption);
+ }
+ return value;
+ }
+ getArray(key1, key2, key3) {
+ let value = this._map[key1];
+ if (value === undefined && key2 !== undefined) {
+ value = this._map[key2];
+ if (value === undefined && key3 !== undefined) {
+ value = this._map[key3];
+ }
+ }
+ if (value instanceof Ref && this.xref) {
+ value = this.xref.fetch(value, this.suppressEncryption);
+ }
+ if (Array.isArray(value)) {
+ value = value.slice();
+ for (let i = 0, ii = value.length; i < ii; i++) {
+ if (value[i] instanceof Ref && this.xref) {
+ value[i] = this.xref.fetch(value[i], this.suppressEncryption);
+ }
+ }
+ }
+ return value;
+ }
+ getRaw(key) {
+ return this._map[key];
+ }
+ getKeys() {
+ return Object.keys(this._map);
+ }
+ getRawValues() {
+ return Object.values(this._map);
+ }
+ set(key, value) {
+ this._map[key] = value;
+ }
+ has(key) {
+ return this._map[key] !== undefined;
+ }
+ forEach(callback) {
+ for (const key in this._map) {
+ callback(key, this.get(key));
+ }
+ }
+ static get empty() {
+ const emptyDict = new Dict(null);
+ emptyDict.set = (key, value) => {
+ unreachable("Should not call `set` on the empty dictionary.");
+ };
+ return shadow(this, "empty", emptyDict);
+ }
+ static merge({
+ xref,
+ dictArray,
+ mergeSubDicts = false
+ }) {
+ const mergedDict = new Dict(xref),
+ properties = new Map();
+ for (const dict of dictArray) {
+ if (!(dict instanceof Dict)) {
+ continue;
+ }
+ for (const [key, value] of Object.entries(dict._map)) {
+ let property = properties.get(key);
+ if (property === undefined) {
+ property = [];
+ properties.set(key, property);
+ } else if (!mergeSubDicts || !(value instanceof Dict)) {
+ continue;
+ }
+ property.push(value);
+ }
+ }
+ for (const [name, values] of properties) {
+ if (values.length === 1 || !(values[0] instanceof Dict)) {
+ mergedDict._map[name] = values[0];
+ continue;
+ }
+ const subDict = new Dict(xref);
+ for (const dict of values) {
+ for (const [key, value] of Object.entries(dict._map)) {
+ if (subDict._map[key] === undefined) {
+ subDict._map[key] = value;
+ }
+ }
+ }
+ if (subDict.size > 0) {
+ mergedDict._map[name] = subDict;
+ }
+ }
+ properties.clear();
+ return mergedDict.size > 0 ? mergedDict : Dict.empty;
+ }
+ clone() {
+ const dict = new Dict(this.xref);
+ for (const key of this.getKeys()) {
+ dict.set(key, this.getRaw(key));
+ }
+ return dict;
+ }
+}
+class Ref {
+ constructor(num, gen) {
+ this.num = num;
+ this.gen = gen;
+ }
+ toString() {
+ if (this.gen === 0) {
+ return `${this.num}R`;
+ }
+ return `${this.num}R${this.gen}`;
+ }
+ static fromString(str) {
+ const ref = RefCache[str];
+ if (ref) {
+ return ref;
+ }
+ const m = /^(\d+)R(\d*)$/.exec(str);
+ if (!m || m[1] === "0") {
+ return null;
+ }
+ return RefCache[str] = new Ref(parseInt(m[1]), !m[2] ? 0 : parseInt(m[2]));
+ }
+ static get(num, gen) {
+ const key = gen === 0 ? `${num}R` : `${num}R${gen}`;
+ return RefCache[key] ||= new Ref(num, gen);
+ }
+}
+class RefSet {
+ constructor(parent = null) {
+ this._set = new Set(parent?._set);
+ }
+ has(ref) {
+ return this._set.has(ref.toString());
+ }
+ put(ref) {
+ this._set.add(ref.toString());
+ }
+ remove(ref) {
+ this._set.delete(ref.toString());
+ }
+ [Symbol.iterator]() {
+ return this._set.values();
+ }
+ clear() {
+ this._set.clear();
+ }
+}
+class RefSetCache {
+ constructor() {
+ this._map = new Map();
+ }
+ get size() {
+ return this._map.size;
+ }
+ get(ref) {
+ return this._map.get(ref.toString());
+ }
+ has(ref) {
+ return this._map.has(ref.toString());
+ }
+ put(ref, obj) {
+ this._map.set(ref.toString(), obj);
+ }
+ putAlias(ref, aliasRef) {
+ this._map.set(ref.toString(), this.get(aliasRef));
+ }
+ [Symbol.iterator]() {
+ return this._map.values();
+ }
+ clear() {
+ this._map.clear();
+ }
+}
+function isName(v, name) {
+ return v instanceof Name && (name === undefined || v.name === name);
+}
+function isCmd(v, cmd) {
+ return v instanceof Cmd && (cmd === undefined || v.cmd === cmd);
+}
+function isDict(v, type) {
+ return v instanceof Dict && (type === undefined || isName(v.get("Type"), type));
+}
+function isRefsEqual(v1, v2) {
+ return v1.num === v2.num && v1.gen === v2.gen;
+}
+
+;// CONCATENATED MODULE: ./src/core/base_stream.js
+
+class BaseStream {
+ constructor() {
+ if (this.constructor === BaseStream) {
+ unreachable("Cannot initialize BaseStream.");
+ }
+ }
+ get length() {
+ unreachable("Abstract getter `length` accessed");
+ }
+ get isEmpty() {
+ unreachable("Abstract getter `isEmpty` accessed");
+ }
+ get isDataLoaded() {
+ return shadow(this, "isDataLoaded", true);
+ }
+ getByte() {
+ unreachable("Abstract method `getByte` called");
+ }
+ getBytes(length) {
+ unreachable("Abstract method `getBytes` called");
+ }
+ peekByte() {
+ const peekedByte = this.getByte();
+ if (peekedByte !== -1) {
+ this.pos--;
+ }
+ return peekedByte;
+ }
+ peekBytes(length) {
+ const bytes = this.getBytes(length);
+ this.pos -= bytes.length;
+ return bytes;
+ }
+ getUint16() {
+ const b0 = this.getByte();
+ const b1 = this.getByte();
+ if (b0 === -1 || b1 === -1) {
+ return -1;
+ }
+ return (b0 << 8) + b1;
+ }
+ getInt32() {
+ const b0 = this.getByte();
+ const b1 = this.getByte();
+ const b2 = this.getByte();
+ const b3 = this.getByte();
+ return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
+ }
+ getByteRange(begin, end) {
+ unreachable("Abstract method `getByteRange` called");
+ }
+ getString(length) {
+ return bytesToString(this.getBytes(length));
+ }
+ skip(n) {
+ this.pos += n || 1;
+ }
+ reset() {
+ unreachable("Abstract method `reset` called");
+ }
+ moveStart() {
+ unreachable("Abstract method `moveStart` called");
+ }
+ makeSubStream(start, length, dict = null) {
+ unreachable("Abstract method `makeSubStream` called");
+ }
+ getBaseStreams() {
+ return null;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/core_utils.js
+
+
+
+const PDF_VERSION_REGEXP = /^[1-9]\.\d$/;
+function getLookupTableFactory(initializer) {
+ let lookup;
+ return function () {
+ if (initializer) {
+ lookup = Object.create(null);
+ initializer(lookup);
+ initializer = null;
+ }
+ return lookup;
+ };
+}
+class MissingDataException extends BaseException {
+ constructor(begin, end) {
+ super(`Missing data [${begin}, ${end})`, "MissingDataException");
+ this.begin = begin;
+ this.end = end;
+ }
+}
+class ParserEOFException extends BaseException {
+ constructor(msg) {
+ super(msg, "ParserEOFException");
+ }
+}
+class XRefEntryException extends BaseException {
+ constructor(msg) {
+ super(msg, "XRefEntryException");
+ }
+}
+class XRefParseException extends BaseException {
+ constructor(msg) {
+ super(msg, "XRefParseException");
+ }
+}
+function arrayBuffersToBytes(arr) {
+ const length = arr.length;
+ if (length === 0) {
+ return new Uint8Array(0);
+ }
+ if (length === 1) {
+ return new Uint8Array(arr[0]);
+ }
+ let dataLength = 0;
+ for (let i = 0; i < length; i++) {
+ dataLength += arr[i].byteLength;
+ }
+ const data = new Uint8Array(dataLength);
+ let pos = 0;
+ for (let i = 0; i < length; i++) {
+ const item = new Uint8Array(arr[i]);
+ data.set(item, pos);
+ pos += item.byteLength;
+ }
+ return data;
+}
+function getInheritableProperty({
+ dict,
+ key,
+ getArray = false,
+ stopWhenFound = true
+}) {
+ let values;
+ const visited = new RefSet();
+ while (dict instanceof Dict && !(dict.objId && visited.has(dict.objId))) {
+ if (dict.objId) {
+ visited.put(dict.objId);
+ }
+ const value = getArray ? dict.getArray(key) : dict.get(key);
+ if (value !== undefined) {
+ if (stopWhenFound) {
+ return value;
+ }
+ (values ||= []).push(value);
+ }
+ dict = dict.get("Parent");
+ }
+ return values;
+}
+const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
+function toRomanNumerals(number, lowerCase = false) {
+ assert(Number.isInteger(number) && number > 0, "The number should be a positive integer.");
+ const romanBuf = [];
+ let pos;
+ while (number >= 1000) {
+ number -= 1000;
+ romanBuf.push("M");
+ }
+ pos = number / 100 | 0;
+ number %= 100;
+ romanBuf.push(ROMAN_NUMBER_MAP[pos]);
+ pos = number / 10 | 0;
+ number %= 10;
+ romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
+ romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
+ const romanStr = romanBuf.join("");
+ return lowerCase ? romanStr.toLowerCase() : romanStr;
+}
+function log2(x) {
+ if (x <= 0) {
+ return 0;
+ }
+ return Math.ceil(Math.log2(x));
+}
+function readInt8(data, offset) {
+ return data[offset] << 24 >> 24;
+}
+function readUint16(data, offset) {
+ return data[offset] << 8 | data[offset + 1];
+}
+function readUint32(data, offset) {
+ return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
+}
+function isWhiteSpace(ch) {
+ return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a;
+}
+function parseXFAPath(path) {
+ const positionPattern = /(.+)\[(\d+)\]$/;
+ return path.split(".").map(component => {
+ const m = component.match(positionPattern);
+ if (m) {
+ return {
+ name: m[1],
+ pos: parseInt(m[2], 10)
+ };
+ }
+ return {
+ name: component,
+ pos: 0
+ };
+ });
+}
+function escapePDFName(str) {
+ const buffer = [];
+ let start = 0;
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const char = str.charCodeAt(i);
+ if (char < 0x21 || char > 0x7e || char === 0x23 || char === 0x28 || char === 0x29 || char === 0x3c || char === 0x3e || char === 0x5b || char === 0x5d || char === 0x7b || char === 0x7d || char === 0x2f || char === 0x25) {
+ if (start < i) {
+ buffer.push(str.substring(start, i));
+ }
+ buffer.push(`#${char.toString(16)}`);
+ start = i + 1;
+ }
+ }
+ if (buffer.length === 0) {
+ return str;
+ }
+ if (start < str.length) {
+ buffer.push(str.substring(start, str.length));
+ }
+ return buffer.join("");
+}
+function escapeString(str) {
+ return str.replaceAll(/([()\\\n\r])/g, match => {
+ if (match === "\n") {
+ return "\\n";
+ } else if (match === "\r") {
+ return "\\r";
+ }
+ return `\\${match}`;
+ });
+}
+function _collectJS(entry, xref, list, parents) {
+ if (!entry) {
+ return;
+ }
+ let parent = null;
+ if (entry instanceof Ref) {
+ if (parents.has(entry)) {
+ return;
+ }
+ parent = entry;
+ parents.put(parent);
+ entry = xref.fetch(entry);
+ }
+ if (Array.isArray(entry)) {
+ for (const element of entry) {
+ _collectJS(element, xref, list, parents);
+ }
+ } else if (entry instanceof Dict) {
+ if (isName(entry.get("S"), "JavaScript")) {
+ const js = entry.get("JS");
+ let code;
+ if (js instanceof BaseStream) {
+ code = js.getString();
+ } else if (typeof js === "string") {
+ code = js;
+ }
+ code &&= stringToPDFString(code).replaceAll("\x00", "");
+ if (code) {
+ list.push(code);
+ }
+ }
+ _collectJS(entry.getRaw("Next"), xref, list, parents);
+ }
+ if (parent) {
+ parents.remove(parent);
+ }
+}
+function collectActions(xref, dict, eventType) {
+ const actions = Object.create(null);
+ const additionalActionsDicts = getInheritableProperty({
+ dict,
+ key: "AA",
+ stopWhenFound: false
+ });
+ if (additionalActionsDicts) {
+ for (let i = additionalActionsDicts.length - 1; i >= 0; i--) {
+ const additionalActions = additionalActionsDicts[i];
+ if (!(additionalActions instanceof Dict)) {
+ continue;
+ }
+ for (const key of additionalActions.getKeys()) {
+ const action = eventType[key];
+ if (!action) {
+ continue;
+ }
+ const actionDict = additionalActions.getRaw(key);
+ const parents = new RefSet();
+ const list = [];
+ _collectJS(actionDict, xref, list, parents);
+ if (list.length > 0) {
+ actions[action] = list;
+ }
+ }
+ }
+ }
+ if (dict.has("A")) {
+ const actionDict = dict.get("A");
+ const parents = new RefSet();
+ const list = [];
+ _collectJS(actionDict, xref, list, parents);
+ if (list.length > 0) {
+ actions.Action = list;
+ }
+ }
+ return objectSize(actions) > 0 ? actions : null;
+}
+const XMLEntities = {
+ 0x3c: "<",
+ 0x3e: ">",
+ 0x26: "&",
+ 0x22: """,
+ 0x27: "'"
+};
+function encodeToXmlString(str) {
+ const buffer = [];
+ let start = 0;
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const char = str.codePointAt(i);
+ if (0x20 <= char && char <= 0x7e) {
+ const entity = XMLEntities[char];
+ if (entity) {
+ if (start < i) {
+ buffer.push(str.substring(start, i));
+ }
+ buffer.push(entity);
+ start = i + 1;
+ }
+ } else {
+ if (start < i) {
+ buffer.push(str.substring(start, i));
+ }
+ buffer.push(`${char.toString(16).toUpperCase()};`);
+ if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {
+ i++;
+ }
+ start = i + 1;
+ }
+ }
+ if (buffer.length === 0) {
+ return str;
+ }
+ if (start < str.length) {
+ buffer.push(str.substring(start, str.length));
+ }
+ return buffer.join("");
+}
+function validateFontName(fontFamily, mustWarn = false) {
+ const m = /^("|').*("|')$/.exec(fontFamily);
+ if (m && m[1] === m[2]) {
+ const re = new RegExp(`[^\\\\]${m[1]}`);
+ if (re.test(fontFamily.slice(1, -1))) {
+ if (mustWarn) {
+ warn(`FontFamily contains unescaped ${m[1]}: ${fontFamily}.`);
+ }
+ return false;
+ }
+ } else {
+ for (const ident of fontFamily.split(/[ \t]+/)) {
+ if (/^(\d|(-(\d|-)))/.test(ident) || !/^[\w-\\]+$/.test(ident)) {
+ if (mustWarn) {
+ warn(`FontFamily contains invalid : ${fontFamily}.`);
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+}
+function validateCSSFont(cssFontInfo) {
+ const DEFAULT_CSS_FONT_OBLIQUE = "14";
+ const DEFAULT_CSS_FONT_WEIGHT = "400";
+ const CSS_FONT_WEIGHT_VALUES = new Set(["100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "normal", "bold", "bolder", "lighter"]);
+ const {
+ fontFamily,
+ fontWeight,
+ italicAngle
+ } = cssFontInfo;
+ if (!validateFontName(fontFamily, true)) {
+ return false;
+ }
+ const weight = fontWeight ? fontWeight.toString() : "";
+ cssFontInfo.fontWeight = CSS_FONT_WEIGHT_VALUES.has(weight) ? weight : DEFAULT_CSS_FONT_WEIGHT;
+ const angle = parseFloat(italicAngle);
+ cssFontInfo.italicAngle = isNaN(angle) || angle < -90 || angle > 90 ? DEFAULT_CSS_FONT_OBLIQUE : italicAngle.toString();
+ return true;
+}
+function recoverJsURL(str) {
+ const URL_OPEN_METHODS = ["app.launchURL", "window.open", "xfa.host.gotoURL"];
+ const regex = new RegExp("^\\s*(" + URL_OPEN_METHODS.join("|").replaceAll(".", "\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i");
+ const jsUrl = regex.exec(str);
+ if (jsUrl?.[2]) {
+ const url = jsUrl[2];
+ let newWindow = false;
+ if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") {
+ newWindow = true;
+ }
+ return {
+ url,
+ newWindow
+ };
+ }
+ return null;
+}
+function numberToString(value) {
+ if (Number.isInteger(value)) {
+ return value.toString();
+ }
+ const roundedValue = Math.round(value * 100);
+ if (roundedValue % 100 === 0) {
+ return (roundedValue / 100).toString();
+ }
+ if (roundedValue % 10 === 0) {
+ return value.toFixed(1);
+ }
+ return value.toFixed(2);
+}
+function getNewAnnotationsMap(annotationStorage) {
+ if (!annotationStorage) {
+ return null;
+ }
+ const newAnnotationsByPage = new Map();
+ for (const [key, value] of annotationStorage) {
+ if (!key.startsWith(AnnotationEditorPrefix)) {
+ continue;
+ }
+ let annotations = newAnnotationsByPage.get(value.pageIndex);
+ if (!annotations) {
+ annotations = [];
+ newAnnotationsByPage.set(value.pageIndex, annotations);
+ }
+ annotations.push(value);
+ }
+ return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null;
+}
+function isAscii(str) {
+ return /^[\x00-\x7F]*$/.test(str);
+}
+function stringToUTF16HexString(str) {
+ const buf = [];
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const char = str.charCodeAt(i);
+ buf.push((char >> 8 & 0xff).toString(16).padStart(2, "0"), (char & 0xff).toString(16).padStart(2, "0"));
+ }
+ return buf.join("");
+}
+function stringToUTF16String(str, bigEndian = false) {
+ const buf = [];
+ if (bigEndian) {
+ buf.push("\xFE\xFF");
+ }
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const char = str.charCodeAt(i);
+ buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
+ }
+ return buf.join("");
+}
+function getRotationMatrix(rotation, width, height) {
+ switch (rotation) {
+ case 90:
+ return [0, 1, -1, 0, width, 0];
+ case 180:
+ return [-1, 0, 0, -1, width, height];
+ case 270:
+ return [0, -1, 1, 0, 0, height];
+ default:
+ throw new Error("Invalid rotation");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/stream.js
+
+
+class Stream extends BaseStream {
+ constructor(arrayBuffer, start, length, dict) {
+ super();
+ this.bytes = arrayBuffer instanceof Uint8Array ? arrayBuffer : new Uint8Array(arrayBuffer);
+ this.start = start || 0;
+ this.pos = this.start;
+ this.end = start + length || this.bytes.length;
+ this.dict = dict;
+ }
+ get length() {
+ return this.end - this.start;
+ }
+ get isEmpty() {
+ return this.length === 0;
+ }
+ getByte() {
+ if (this.pos >= this.end) {
+ return -1;
+ }
+ return this.bytes[this.pos++];
+ }
+ getBytes(length) {
+ const bytes = this.bytes;
+ const pos = this.pos;
+ const strEnd = this.end;
+ if (!length) {
+ return bytes.subarray(pos, strEnd);
+ }
+ let end = pos + length;
+ if (end > strEnd) {
+ end = strEnd;
+ }
+ this.pos = end;
+ return bytes.subarray(pos, end);
+ }
+ getByteRange(begin, end) {
+ if (begin < 0) {
+ begin = 0;
+ }
+ if (end > this.end) {
+ end = this.end;
+ }
+ return this.bytes.subarray(begin, end);
+ }
+ reset() {
+ this.pos = this.start;
+ }
+ moveStart() {
+ this.start = this.pos;
+ }
+ makeSubStream(start, length, dict = null) {
+ return new Stream(this.bytes.buffer, start, length, dict);
+ }
+}
+class StringStream extends Stream {
+ constructor(str) {
+ super(stringToBytes(str));
+ }
+}
+class NullStream extends Stream {
+ constructor() {
+ super(new Uint8Array(0));
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/chunked_stream.js
+
+
+
+class ChunkedStream extends Stream {
+ constructor(length, chunkSize, manager) {
+ super(new Uint8Array(length), 0, length, null);
+ this.chunkSize = chunkSize;
+ this._loadedChunks = new Set();
+ this.numChunks = Math.ceil(length / chunkSize);
+ this.manager = manager;
+ this.progressiveDataLength = 0;
+ this.lastSuccessfulEnsureByteChunk = -1;
+ }
+ getMissingChunks() {
+ const chunks = [];
+ for (let chunk = 0, n = this.numChunks; chunk < n; ++chunk) {
+ if (!this._loadedChunks.has(chunk)) {
+ chunks.push(chunk);
+ }
+ }
+ return chunks;
+ }
+ get numChunksLoaded() {
+ return this._loadedChunks.size;
+ }
+ get isDataLoaded() {
+ return this.numChunksLoaded === this.numChunks;
+ }
+ onReceiveData(begin, chunk) {
+ const chunkSize = this.chunkSize;
+ if (begin % chunkSize !== 0) {
+ throw new Error(`Bad begin offset: ${begin}`);
+ }
+ const end = begin + chunk.byteLength;
+ if (end % chunkSize !== 0 && end !== this.bytes.length) {
+ throw new Error(`Bad end offset: ${end}`);
+ }
+ this.bytes.set(new Uint8Array(chunk), begin);
+ const beginChunk = Math.floor(begin / chunkSize);
+ const endChunk = Math.floor((end - 1) / chunkSize) + 1;
+ for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
+ this._loadedChunks.add(curChunk);
+ }
+ }
+ onReceiveProgressiveData(data) {
+ let position = this.progressiveDataLength;
+ const beginChunk = Math.floor(position / this.chunkSize);
+ this.bytes.set(new Uint8Array(data), position);
+ position += data.byteLength;
+ this.progressiveDataLength = position;
+ const endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize);
+ for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
+ this._loadedChunks.add(curChunk);
+ }
+ }
+ ensureByte(pos) {
+ if (pos < this.progressiveDataLength) {
+ return;
+ }
+ const chunk = Math.floor(pos / this.chunkSize);
+ if (chunk > this.numChunks) {
+ return;
+ }
+ if (chunk === this.lastSuccessfulEnsureByteChunk) {
+ return;
+ }
+ if (!this._loadedChunks.has(chunk)) {
+ throw new MissingDataException(pos, pos + 1);
+ }
+ this.lastSuccessfulEnsureByteChunk = chunk;
+ }
+ ensureRange(begin, end) {
+ if (begin >= end) {
+ return;
+ }
+ if (end <= this.progressiveDataLength) {
+ return;
+ }
+ const beginChunk = Math.floor(begin / this.chunkSize);
+ if (beginChunk > this.numChunks) {
+ return;
+ }
+ const endChunk = Math.min(Math.floor((end - 1) / this.chunkSize) + 1, this.numChunks);
+ for (let chunk = beginChunk; chunk < endChunk; ++chunk) {
+ if (!this._loadedChunks.has(chunk)) {
+ throw new MissingDataException(begin, end);
+ }
+ }
+ }
+ nextEmptyChunk(beginChunk) {
+ const numChunks = this.numChunks;
+ for (let i = 0; i < numChunks; ++i) {
+ const chunk = (beginChunk + i) % numChunks;
+ if (!this._loadedChunks.has(chunk)) {
+ return chunk;
+ }
+ }
+ return null;
+ }
+ hasChunk(chunk) {
+ return this._loadedChunks.has(chunk);
+ }
+ getByte() {
+ const pos = this.pos;
+ if (pos >= this.end) {
+ return -1;
+ }
+ if (pos >= this.progressiveDataLength) {
+ this.ensureByte(pos);
+ }
+ return this.bytes[this.pos++];
+ }
+ getBytes(length) {
+ const bytes = this.bytes;
+ const pos = this.pos;
+ const strEnd = this.end;
+ if (!length) {
+ if (strEnd > this.progressiveDataLength) {
+ this.ensureRange(pos, strEnd);
+ }
+ return bytes.subarray(pos, strEnd);
+ }
+ let end = pos + length;
+ if (end > strEnd) {
+ end = strEnd;
+ }
+ if (end > this.progressiveDataLength) {
+ this.ensureRange(pos, end);
+ }
+ this.pos = end;
+ return bytes.subarray(pos, end);
+ }
+ getByteRange(begin, end) {
+ if (begin < 0) {
+ begin = 0;
+ }
+ if (end > this.end) {
+ end = this.end;
+ }
+ if (end > this.progressiveDataLength) {
+ this.ensureRange(begin, end);
+ }
+ return this.bytes.subarray(begin, end);
+ }
+ makeSubStream(start, length, dict = null) {
+ if (length) {
+ if (start + length > this.progressiveDataLength) {
+ this.ensureRange(start, start + length);
+ }
+ } else if (start >= this.progressiveDataLength) {
+ this.ensureByte(start);
+ }
+ function ChunkedStreamSubstream() {}
+ ChunkedStreamSubstream.prototype = Object.create(this);
+ ChunkedStreamSubstream.prototype.getMissingChunks = function () {
+ const chunkSize = this.chunkSize;
+ const beginChunk = Math.floor(this.start / chunkSize);
+ const endChunk = Math.floor((this.end - 1) / chunkSize) + 1;
+ const missingChunks = [];
+ for (let chunk = beginChunk; chunk < endChunk; ++chunk) {
+ if (!this._loadedChunks.has(chunk)) {
+ missingChunks.push(chunk);
+ }
+ }
+ return missingChunks;
+ };
+ Object.defineProperty(ChunkedStreamSubstream.prototype, "isDataLoaded", {
+ get() {
+ if (this.numChunksLoaded === this.numChunks) {
+ return true;
+ }
+ return this.getMissingChunks().length === 0;
+ },
+ configurable: true
+ });
+ const subStream = new ChunkedStreamSubstream();
+ subStream.pos = subStream.start = start;
+ subStream.end = start + length || this.end;
+ subStream.dict = dict;
+ return subStream;
+ }
+ getBaseStreams() {
+ return [this];
+ }
+}
+class ChunkedStreamManager {
+ constructor(pdfNetworkStream, args) {
+ this.length = args.length;
+ this.chunkSize = args.rangeChunkSize;
+ this.stream = new ChunkedStream(this.length, this.chunkSize, this);
+ this.pdfNetworkStream = pdfNetworkStream;
+ this.disableAutoFetch = args.disableAutoFetch;
+ this.msgHandler = args.msgHandler;
+ this.currRequestId = 0;
+ this._chunksNeededByRequest = new Map();
+ this._requestsByChunk = new Map();
+ this._promisesByRequest = new Map();
+ this.progressiveDataLength = 0;
+ this.aborted = false;
+ this._loadedStreamCapability = new PromiseCapability();
+ }
+ sendRequest(begin, end) {
+ const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end);
+ if (!rangeReader.isStreamingSupported) {
+ rangeReader.onProgress = this.onProgress.bind(this);
+ }
+ let chunks = [],
+ loaded = 0;
+ return new Promise((resolve, reject) => {
+ const readChunk = ({
+ value,
+ done
+ }) => {
+ try {
+ if (done) {
+ const chunkData = arrayBuffersToBytes(chunks);
+ chunks = null;
+ resolve(chunkData);
+ return;
+ }
+ loaded += value.byteLength;
+ if (rangeReader.isStreamingSupported) {
+ this.onProgress({
+ loaded
+ });
+ }
+ chunks.push(value);
+ rangeReader.read().then(readChunk, reject);
+ } catch (e) {
+ reject(e);
+ }
+ };
+ rangeReader.read().then(readChunk, reject);
+ }).then(data => {
+ if (this.aborted) {
+ return;
+ }
+ this.onReceiveData({
+ chunk: data,
+ begin
+ });
+ });
+ }
+ requestAllChunks(noFetch = false) {
+ if (!noFetch) {
+ const missingChunks = this.stream.getMissingChunks();
+ this._requestChunks(missingChunks);
+ }
+ return this._loadedStreamCapability.promise;
+ }
+ _requestChunks(chunks) {
+ const requestId = this.currRequestId++;
+ const chunksNeeded = new Set();
+ this._chunksNeededByRequest.set(requestId, chunksNeeded);
+ for (const chunk of chunks) {
+ if (!this.stream.hasChunk(chunk)) {
+ chunksNeeded.add(chunk);
+ }
+ }
+ if (chunksNeeded.size === 0) {
+ return Promise.resolve();
+ }
+ const capability = new PromiseCapability();
+ this._promisesByRequest.set(requestId, capability);
+ const chunksToRequest = [];
+ for (const chunk of chunksNeeded) {
+ let requestIds = this._requestsByChunk.get(chunk);
+ if (!requestIds) {
+ requestIds = [];
+ this._requestsByChunk.set(chunk, requestIds);
+ chunksToRequest.push(chunk);
+ }
+ requestIds.push(requestId);
+ }
+ if (chunksToRequest.length > 0) {
+ const groupedChunksToRequest = this.groupChunks(chunksToRequest);
+ for (const groupedChunk of groupedChunksToRequest) {
+ const begin = groupedChunk.beginChunk * this.chunkSize;
+ const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length);
+ this.sendRequest(begin, end).catch(capability.reject);
+ }
+ }
+ return capability.promise.catch(reason => {
+ if (this.aborted) {
+ return;
+ }
+ throw reason;
+ });
+ }
+ getStream() {
+ return this.stream;
+ }
+ requestRange(begin, end) {
+ end = Math.min(end, this.length);
+ const beginChunk = this.getBeginChunk(begin);
+ const endChunk = this.getEndChunk(end);
+ const chunks = [];
+ for (let chunk = beginChunk; chunk < endChunk; ++chunk) {
+ chunks.push(chunk);
+ }
+ return this._requestChunks(chunks);
+ }
+ requestRanges(ranges = []) {
+ const chunksToRequest = [];
+ for (const range of ranges) {
+ const beginChunk = this.getBeginChunk(range.begin);
+ const endChunk = this.getEndChunk(range.end);
+ for (let chunk = beginChunk; chunk < endChunk; ++chunk) {
+ if (!chunksToRequest.includes(chunk)) {
+ chunksToRequest.push(chunk);
+ }
+ }
+ }
+ chunksToRequest.sort(function (a, b) {
+ return a - b;
+ });
+ return this._requestChunks(chunksToRequest);
+ }
+ groupChunks(chunks) {
+ const groupedChunks = [];
+ let beginChunk = -1;
+ let prevChunk = -1;
+ for (let i = 0, ii = chunks.length; i < ii; ++i) {
+ const chunk = chunks[i];
+ if (beginChunk < 0) {
+ beginChunk = chunk;
+ }
+ if (prevChunk >= 0 && prevChunk + 1 !== chunk) {
+ groupedChunks.push({
+ beginChunk,
+ endChunk: prevChunk + 1
+ });
+ beginChunk = chunk;
+ }
+ if (i + 1 === chunks.length) {
+ groupedChunks.push({
+ beginChunk,
+ endChunk: chunk + 1
+ });
+ }
+ prevChunk = chunk;
+ }
+ return groupedChunks;
+ }
+ onProgress(args) {
+ this.msgHandler.send("DocProgress", {
+ loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded,
+ total: this.length
+ });
+ }
+ onReceiveData(args) {
+ const chunk = args.chunk;
+ const isProgressive = args.begin === undefined;
+ const begin = isProgressive ? this.progressiveDataLength : args.begin;
+ const end = begin + chunk.byteLength;
+ const beginChunk = Math.floor(begin / this.chunkSize);
+ const endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize);
+ if (isProgressive) {
+ this.stream.onReceiveProgressiveData(chunk);
+ this.progressiveDataLength = end;
+ } else {
+ this.stream.onReceiveData(begin, chunk);
+ }
+ if (this.stream.isDataLoaded) {
+ this._loadedStreamCapability.resolve(this.stream);
+ }
+ const loadedRequests = [];
+ for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
+ const requestIds = this._requestsByChunk.get(curChunk);
+ if (!requestIds) {
+ continue;
+ }
+ this._requestsByChunk.delete(curChunk);
+ for (const requestId of requestIds) {
+ const chunksNeeded = this._chunksNeededByRequest.get(requestId);
+ if (chunksNeeded.has(curChunk)) {
+ chunksNeeded.delete(curChunk);
+ }
+ if (chunksNeeded.size > 0) {
+ continue;
+ }
+ loadedRequests.push(requestId);
+ }
+ }
+ if (!this.disableAutoFetch && this._requestsByChunk.size === 0) {
+ let nextEmptyChunk;
+ if (this.stream.numChunksLoaded === 1) {
+ const lastChunk = this.stream.numChunks - 1;
+ if (!this.stream.hasChunk(lastChunk)) {
+ nextEmptyChunk = lastChunk;
+ }
+ } else {
+ nextEmptyChunk = this.stream.nextEmptyChunk(endChunk);
+ }
+ if (Number.isInteger(nextEmptyChunk)) {
+ this._requestChunks([nextEmptyChunk]);
+ }
+ }
+ for (const requestId of loadedRequests) {
+ const capability = this._promisesByRequest.get(requestId);
+ this._promisesByRequest.delete(requestId);
+ capability.resolve();
+ }
+ this.msgHandler.send("DocProgress", {
+ loaded: this.stream.numChunksLoaded * this.chunkSize,
+ total: this.length
+ });
+ }
+ onError(err) {
+ this._loadedStreamCapability.reject(err);
+ }
+ getBeginChunk(begin) {
+ return Math.floor(begin / this.chunkSize);
+ }
+ getEndChunk(end) {
+ return Math.floor((end - 1) / this.chunkSize) + 1;
+ }
+ abort(reason) {
+ this.aborted = true;
+ this.pdfNetworkStream?.cancelAllRequests(reason);
+ for (const capability of this._promisesByRequest.values()) {
+ capability.reject(reason);
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/colorspace.js
+
+
+
+
+function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {
+ const COMPONENTS = 3;
+ alpha01 = alpha01 !== 1 ? 0 : alpha01;
+ const xRatio = w1 / w2;
+ const yRatio = h1 / h2;
+ let newIndex = 0,
+ oldIndex;
+ const xScaled = new Uint16Array(w2);
+ const w1Scanline = w1 * COMPONENTS;
+ for (let i = 0; i < w2; i++) {
+ xScaled[i] = Math.floor(i * xRatio) * COMPONENTS;
+ }
+ for (let i = 0; i < h2; i++) {
+ const py = Math.floor(i * yRatio) * w1Scanline;
+ for (let j = 0; j < w2; j++) {
+ oldIndex = py + xScaled[j];
+ dest[newIndex++] = src[oldIndex++];
+ dest[newIndex++] = src[oldIndex++];
+ dest[newIndex++] = src[oldIndex++];
+ newIndex += alpha01;
+ }
+ }
+}
+class ColorSpace {
+ constructor(name, numComps) {
+ if (this.constructor === ColorSpace) {
+ unreachable("Cannot initialize ColorSpace.");
+ }
+ this.name = name;
+ this.numComps = numComps;
+ }
+ getRgb(src, srcOffset) {
+ const rgb = new Uint8ClampedArray(3);
+ this.getRgbItem(src, srcOffset, rgb, 0);
+ return rgb;
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ unreachable("Should not call ColorSpace.getRgbItem");
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ unreachable("Should not call ColorSpace.getRgbBuffer");
+ }
+ getOutputLength(inputLength, alpha01) {
+ unreachable("Should not call ColorSpace.getOutputLength");
+ }
+ isPassthrough(bits) {
+ return false;
+ }
+ isDefaultDecode(decodeMap, bpc) {
+ return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
+ }
+ fillRgb(dest, originalWidth, originalHeight, width, height, actualHeight, bpc, comps, alpha01) {
+ const count = originalWidth * originalHeight;
+ let rgbBuf = null;
+ const numComponentColors = 1 << bpc;
+ const needsResizing = originalHeight !== height || originalWidth !== width;
+ if (this.isPassthrough(bpc)) {
+ rgbBuf = comps;
+ } else if (this.numComps === 1 && count > numComponentColors && this.name !== "DeviceGray" && this.name !== "DeviceRGB") {
+ const allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : new Uint16Array(numComponentColors);
+ for (let i = 0; i < numComponentColors; i++) {
+ allColors[i] = i;
+ }
+ const colorMap = new Uint8ClampedArray(numComponentColors * 3);
+ this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bpc, 0);
+ if (!needsResizing) {
+ let destPos = 0;
+ for (let i = 0; i < count; ++i) {
+ const key = comps[i] * 3;
+ dest[destPos++] = colorMap[key];
+ dest[destPos++] = colorMap[key + 1];
+ dest[destPos++] = colorMap[key + 2];
+ destPos += alpha01;
+ }
+ } else {
+ rgbBuf = new Uint8Array(count * 3);
+ let rgbPos = 0;
+ for (let i = 0; i < count; ++i) {
+ const key = comps[i] * 3;
+ rgbBuf[rgbPos++] = colorMap[key];
+ rgbBuf[rgbPos++] = colorMap[key + 1];
+ rgbBuf[rgbPos++] = colorMap[key + 2];
+ }
+ }
+ } else if (!needsResizing) {
+ this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, alpha01);
+ } else {
+ rgbBuf = new Uint8ClampedArray(count * 3);
+ this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, 0);
+ }
+ if (rgbBuf) {
+ if (needsResizing) {
+ resizeRgbImage(rgbBuf, dest, originalWidth, originalHeight, width, height, alpha01);
+ } else {
+ let destPos = 0,
+ rgbPos = 0;
+ for (let i = 0, ii = width * actualHeight; i < ii; i++) {
+ dest[destPos++] = rgbBuf[rgbPos++];
+ dest[destPos++] = rgbBuf[rgbPos++];
+ dest[destPos++] = rgbBuf[rgbPos++];
+ destPos += alpha01;
+ }
+ }
+ }
+ }
+ get usesZeroToOneRange() {
+ return shadow(this, "usesZeroToOneRange", true);
+ }
+ static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {
+ if (!localColorSpaceCache) {
+ throw new Error('ColorSpace._cache - expected "localColorSpaceCache" argument.');
+ }
+ if (!parsedColorSpace) {
+ throw new Error('ColorSpace._cache - expected "parsedColorSpace" argument.');
+ }
+ let csName, csRef;
+ if (cacheKey instanceof Ref) {
+ csRef = cacheKey;
+ cacheKey = xref.fetch(cacheKey);
+ }
+ if (cacheKey instanceof Name) {
+ csName = cacheKey.name;
+ }
+ if (csName || csRef) {
+ localColorSpaceCache.set(csName, csRef, parsedColorSpace);
+ }
+ }
+ static getCached(cacheKey, xref, localColorSpaceCache) {
+ if (!localColorSpaceCache) {
+ throw new Error('ColorSpace.getCached - expected "localColorSpaceCache" argument.');
+ }
+ if (cacheKey instanceof Ref) {
+ const localColorSpace = localColorSpaceCache.getByRef(cacheKey);
+ if (localColorSpace) {
+ return localColorSpace;
+ }
+ try {
+ cacheKey = xref.fetch(cacheKey);
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ }
+ }
+ if (cacheKey instanceof Name) {
+ const localColorSpace = localColorSpaceCache.getByName(cacheKey.name);
+ if (localColorSpace) {
+ return localColorSpace;
+ }
+ }
+ return null;
+ }
+ static async parseAsync({
+ cs,
+ xref,
+ resources = null,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ }) {
+ const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory);
+ this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
+ return parsedColorSpace;
+ }
+ static parse({
+ cs,
+ xref,
+ resources = null,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ }) {
+ const cachedColorSpace = this.getCached(cs, xref, localColorSpaceCache);
+ if (cachedColorSpace) {
+ return cachedColorSpace;
+ }
+ const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory);
+ this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
+ return parsedColorSpace;
+ }
+ static _parse(cs, xref, resources = null, pdfFunctionFactory) {
+ cs = xref.fetchIfRef(cs);
+ if (cs instanceof Name) {
+ switch (cs.name) {
+ case "G":
+ case "DeviceGray":
+ return this.singletons.gray;
+ case "RGB":
+ case "DeviceRGB":
+ return this.singletons.rgb;
+ case "CMYK":
+ case "DeviceCMYK":
+ return this.singletons.cmyk;
+ case "Pattern":
+ return new PatternCS(null);
+ default:
+ if (resources instanceof Dict) {
+ const colorSpaces = resources.get("ColorSpace");
+ if (colorSpaces instanceof Dict) {
+ const resourcesCS = colorSpaces.get(cs.name);
+ if (resourcesCS) {
+ if (resourcesCS instanceof Name) {
+ return this._parse(resourcesCS, xref, resources, pdfFunctionFactory);
+ }
+ cs = resourcesCS;
+ break;
+ }
+ }
+ }
+ throw new FormatError(`Unrecognized ColorSpace: ${cs.name}`);
+ }
+ }
+ if (Array.isArray(cs)) {
+ const mode = xref.fetchIfRef(cs[0]).name;
+ let params, numComps, baseCS, whitePoint, blackPoint, gamma;
+ switch (mode) {
+ case "G":
+ case "DeviceGray":
+ return this.singletons.gray;
+ case "RGB":
+ case "DeviceRGB":
+ return this.singletons.rgb;
+ case "CMYK":
+ case "DeviceCMYK":
+ return this.singletons.cmyk;
+ case "CalGray":
+ params = xref.fetchIfRef(cs[1]);
+ whitePoint = params.getArray("WhitePoint");
+ blackPoint = params.getArray("BlackPoint");
+ gamma = params.get("Gamma");
+ return new CalGrayCS(whitePoint, blackPoint, gamma);
+ case "CalRGB":
+ params = xref.fetchIfRef(cs[1]);
+ whitePoint = params.getArray("WhitePoint");
+ blackPoint = params.getArray("BlackPoint");
+ gamma = params.getArray("Gamma");
+ const matrix = params.getArray("Matrix");
+ return new CalRGBCS(whitePoint, blackPoint, gamma, matrix);
+ case "ICCBased":
+ const stream = xref.fetchIfRef(cs[1]);
+ const dict = stream.dict;
+ numComps = dict.get("N");
+ const alt = dict.get("Alternate");
+ if (alt) {
+ const altCS = this._parse(alt, xref, resources, pdfFunctionFactory);
+ if (altCS.numComps === numComps) {
+ return altCS;
+ }
+ warn("ICCBased color space: Ignoring incorrect /Alternate entry.");
+ }
+ if (numComps === 1) {
+ return this.singletons.gray;
+ } else if (numComps === 3) {
+ return this.singletons.rgb;
+ } else if (numComps === 4) {
+ return this.singletons.cmyk;
+ }
+ break;
+ case "Pattern":
+ baseCS = cs[1] || null;
+ if (baseCS) {
+ baseCS = this._parse(baseCS, xref, resources, pdfFunctionFactory);
+ }
+ return new PatternCS(baseCS);
+ case "I":
+ case "Indexed":
+ baseCS = this._parse(cs[1], xref, resources, pdfFunctionFactory);
+ const hiVal = xref.fetchIfRef(cs[2]) + 1;
+ const lookup = xref.fetchIfRef(cs[3]);
+ return new IndexedCS(baseCS, hiVal, lookup);
+ case "Separation":
+ case "DeviceN":
+ const name = xref.fetchIfRef(cs[1]);
+ numComps = Array.isArray(name) ? name.length : 1;
+ baseCS = this._parse(cs[2], xref, resources, pdfFunctionFactory);
+ const tintFn = pdfFunctionFactory.create(cs[3]);
+ return new AlternateCS(numComps, baseCS, tintFn);
+ case "Lab":
+ params = xref.fetchIfRef(cs[1]);
+ whitePoint = params.getArray("WhitePoint");
+ blackPoint = params.getArray("BlackPoint");
+ const range = params.getArray("Range");
+ return new LabCS(whitePoint, blackPoint, range);
+ default:
+ throw new FormatError(`Unimplemented ColorSpace object: ${mode}`);
+ }
+ }
+ throw new FormatError(`Unrecognized ColorSpace object: ${cs}`);
+ }
+ static isDefaultDecode(decode, numComps) {
+ if (!Array.isArray(decode)) {
+ return true;
+ }
+ if (numComps * 2 !== decode.length) {
+ warn("The decode map is not the correct length");
+ return true;
+ }
+ for (let i = 0, ii = decode.length; i < ii; i += 2) {
+ if (decode[i] !== 0 || decode[i + 1] !== 1) {
+ return false;
+ }
+ }
+ return true;
+ }
+ static get singletons() {
+ return shadow(this, "singletons", {
+ get gray() {
+ return shadow(this, "gray", new DeviceGrayCS());
+ },
+ get rgb() {
+ return shadow(this, "rgb", new DeviceRgbCS());
+ },
+ get cmyk() {
+ return shadow(this, "cmyk", new DeviceCmykCS());
+ }
+ });
+ }
+}
+class AlternateCS extends ColorSpace {
+ constructor(numComps, base, tintFn) {
+ super("Alternate", numComps);
+ this.base = base;
+ this.tintFn = tintFn;
+ this.tmpBuf = new Float32Array(base.numComps);
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ const tmpBuf = this.tmpBuf;
+ this.tintFn(src, srcOffset, tmpBuf, 0);
+ this.base.getRgbItem(tmpBuf, 0, dest, destOffset);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const tintFn = this.tintFn;
+ const base = this.base;
+ const scale = 1 / ((1 << bits) - 1);
+ const baseNumComps = base.numComps;
+ const usesZeroToOneRange = base.usesZeroToOneRange;
+ const isPassthrough = (base.isPassthrough(8) || !usesZeroToOneRange) && alpha01 === 0;
+ let pos = isPassthrough ? destOffset : 0;
+ const baseBuf = isPassthrough ? dest : new Uint8ClampedArray(baseNumComps * count);
+ const numComps = this.numComps;
+ const scaled = new Float32Array(numComps);
+ const tinted = new Float32Array(baseNumComps);
+ let i, j;
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < numComps; j++) {
+ scaled[j] = src[srcOffset++] * scale;
+ }
+ tintFn(scaled, 0, tinted, 0);
+ if (usesZeroToOneRange) {
+ for (j = 0; j < baseNumComps; j++) {
+ baseBuf[pos++] = tinted[j] * 255;
+ }
+ } else {
+ base.getRgbItem(tinted, 0, baseBuf, pos);
+ pos += baseNumComps;
+ }
+ }
+ if (!isPassthrough) {
+ base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8, alpha01);
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return this.base.getOutputLength(inputLength * this.base.numComps / this.numComps, alpha01);
+ }
+}
+class PatternCS extends ColorSpace {
+ constructor(baseCS) {
+ super("Pattern", null);
+ this.base = baseCS;
+ }
+ isDefaultDecode(decodeMap, bpc) {
+ unreachable("Should not call PatternCS.isDefaultDecode");
+ }
+}
+class IndexedCS extends ColorSpace {
+ constructor(base, highVal, lookup) {
+ super("Indexed", 1);
+ this.base = base;
+ this.highVal = highVal;
+ const length = base.numComps * highVal;
+ this.lookup = new Uint8Array(length);
+ if (lookup instanceof BaseStream) {
+ const bytes = lookup.getBytes(length);
+ this.lookup.set(bytes);
+ } else if (typeof lookup === "string") {
+ for (let i = 0; i < length; ++i) {
+ this.lookup[i] = lookup.charCodeAt(i) & 0xff;
+ }
+ } else {
+ throw new FormatError(`IndexedCS - unrecognized lookup table: ${lookup}`);
+ }
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ const numComps = this.base.numComps;
+ const start = src[srcOffset] * numComps;
+ this.base.getRgbBuffer(this.lookup, start, 1, dest, destOffset, 8, 0);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const base = this.base;
+ const numComps = base.numComps;
+ const outputDelta = base.getOutputLength(numComps, alpha01);
+ const lookup = this.lookup;
+ for (let i = 0; i < count; ++i) {
+ const lookupPos = src[srcOffset++] * numComps;
+ base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8, alpha01);
+ destOffset += outputDelta;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return this.base.getOutputLength(inputLength * this.base.numComps, alpha01);
+ }
+ isDefaultDecode(decodeMap, bpc) {
+ if (!Array.isArray(decodeMap)) {
+ return true;
+ }
+ if (decodeMap.length !== 2) {
+ warn("Decode map length is not correct");
+ return true;
+ }
+ if (!Number.isInteger(bpc) || bpc < 1) {
+ warn("Bits per component is not correct");
+ return true;
+ }
+ return decodeMap[0] === 0 && decodeMap[1] === (1 << bpc) - 1;
+ }
+}
+class DeviceGrayCS extends ColorSpace {
+ constructor() {
+ super("DeviceGray", 1);
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ const c = src[srcOffset] * 255;
+ dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c;
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const scale = 255 / ((1 << bits) - 1);
+ let j = srcOffset,
+ q = destOffset;
+ for (let i = 0; i < count; ++i) {
+ const c = scale * src[j++];
+ dest[q++] = c;
+ dest[q++] = c;
+ dest[q++] = c;
+ q += alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength * (3 + alpha01);
+ }
+}
+class DeviceRgbCS extends ColorSpace {
+ constructor() {
+ super("DeviceRGB", 3);
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ dest[destOffset] = src[srcOffset] * 255;
+ dest[destOffset + 1] = src[srcOffset + 1] * 255;
+ dest[destOffset + 2] = src[srcOffset + 2] * 255;
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ if (bits === 8 && alpha01 === 0) {
+ dest.set(src.subarray(srcOffset, srcOffset + count * 3), destOffset);
+ return;
+ }
+ const scale = 255 / ((1 << bits) - 1);
+ let j = srcOffset,
+ q = destOffset;
+ for (let i = 0; i < count; ++i) {
+ dest[q++] = scale * src[j++];
+ dest[q++] = scale * src[j++];
+ dest[q++] = scale * src[j++];
+ q += alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength * (3 + alpha01) / 3 | 0;
+ }
+ isPassthrough(bits) {
+ return bits === 8;
+ }
+}
+class DeviceCmykCS extends ColorSpace {
+ constructor() {
+ super("DeviceCMYK", 4);
+ }
+ #toRgb(src, srcOffset, srcScale, dest, destOffset) {
+ const c = src[srcOffset] * srcScale;
+ const m = src[srcOffset + 1] * srcScale;
+ const y = src[srcOffset + 2] * srcScale;
+ const k = src[srcOffset + 3] * srcScale;
+ dest[destOffset] = 255 + c * (-4.387332384609988 * c + 54.48615194189176 * m + 18.82290502165302 * y + 212.25662451639585 * k + -285.2331026137004) + m * (1.7149763477362134 * m - 5.6096736904047315 * y + -17.873870861415444 * k - 5.497006427196366) + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 17.5119270841813) + k * (-21.86122147463605 * k - 189.48180835922747);
+ dest[destOffset + 1] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k + -79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + k * (-20.737325471181034 * k - 187.80453709719578);
+ dest[destOffset + 2] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k + -14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k + -193.58209356861505) + k * (-22.33816807309886 * k - 180.12613974708367);
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ this.#toRgb(src, srcOffset, 1, dest, destOffset);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const scale = 1 / ((1 << bits) - 1);
+ for (let i = 0; i < count; i++) {
+ this.#toRgb(src, srcOffset, scale, dest, destOffset);
+ srcOffset += 4;
+ destOffset += 3 + alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength / 4 * (3 + alpha01) | 0;
+ }
+}
+class CalGrayCS extends ColorSpace {
+ constructor(whitePoint, blackPoint, gamma) {
+ super("CalGray", 1);
+ if (!whitePoint) {
+ throw new FormatError("WhitePoint missing - required for color space CalGray");
+ }
+ [this.XW, this.YW, this.ZW] = whitePoint;
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
+ this.G = gamma || 1;
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
+ throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);
+ }
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info(`Invalid BlackPoint for ${this.name}, falling back to default.`);
+ this.XB = this.YB = this.ZB = 0;
+ }
+ if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
+ warn(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ` + `ZB: ${this.ZB}, only default values are supported.`);
+ }
+ if (this.G < 1) {
+ info(`Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`);
+ this.G = 1;
+ }
+ }
+ #toRgb(src, srcOffset, dest, destOffset, scale) {
+ const A = src[srcOffset] * scale;
+ const AG = A ** this.G;
+ const L = this.YW * AG;
+ const val = Math.max(295.8 * L ** 0.3333333333333333 - 40.8, 0);
+ dest[destOffset] = val;
+ dest[destOffset + 1] = val;
+ dest[destOffset + 2] = val;
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const scale = 1 / ((1 << bits) - 1);
+ for (let i = 0; i < count; ++i) {
+ this.#toRgb(src, srcOffset, dest, destOffset, scale);
+ srcOffset += 1;
+ destOffset += 3 + alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength * (3 + alpha01);
+ }
+}
+class CalRGBCS extends ColorSpace {
+ static #BRADFORD_SCALE_MATRIX = new Float32Array([0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296]);
+ static #BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([0.9869929, -0.1470543, 0.1599627, 0.4323053, 0.5183603, 0.0492912, -0.0085287, 0.0400428, 0.9684867]);
+ static #SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([3.2404542, -1.5371385, -0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434, -0.2040259, 1.0572252]);
+ static #FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]);
+ static #tempNormalizeMatrix = new Float32Array(3);
+ static #tempConvertMatrix1 = new Float32Array(3);
+ static #tempConvertMatrix2 = new Float32Array(3);
+ static #DECODE_L_CONSTANT = ((8 + 16) / 116) ** 3 / 8.0;
+ constructor(whitePoint, blackPoint, gamma, matrix) {
+ super("CalRGB", 3);
+ if (!whitePoint) {
+ throw new FormatError("WhitePoint missing - required for color space CalRGB");
+ }
+ const [XW, YW, ZW] = this.whitePoint = whitePoint;
+ const [XB, YB, ZB] = this.blackPoint = blackPoint || new Float32Array(3);
+ [this.GR, this.GG, this.GB] = gamma || new Float32Array([1, 1, 1]);
+ [this.MXA, this.MYA, this.MZA, this.MXB, this.MYB, this.MZB, this.MXC, this.MYC, this.MZC] = matrix || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
+ if (XW < 0 || ZW < 0 || YW !== 1) {
+ throw new FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`);
+ }
+ if (XB < 0 || YB < 0 || ZB < 0) {
+ info(`Invalid BlackPoint for ${this.name} [${XB}, ${YB}, ${ZB}], ` + "falling back to default.");
+ this.blackPoint = new Float32Array(3);
+ }
+ if (this.GR < 0 || this.GG < 0 || this.GB < 0) {
+ info(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ` + `${this.name}, falling back to default.`);
+ this.GR = this.GG = this.GB = 1;
+ }
+ }
+ #matrixProduct(a, b, result) {
+ result[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+ result[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2];
+ result[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2];
+ }
+ #toFlat(sourceWhitePoint, LMS, result) {
+ result[0] = LMS[0] * 1 / sourceWhitePoint[0];
+ result[1] = LMS[1] * 1 / sourceWhitePoint[1];
+ result[2] = LMS[2] * 1 / sourceWhitePoint[2];
+ }
+ #toD65(sourceWhitePoint, LMS, result) {
+ const D65X = 0.95047;
+ const D65Y = 1;
+ const D65Z = 1.08883;
+ result[0] = LMS[0] * D65X / sourceWhitePoint[0];
+ result[1] = LMS[1] * D65Y / sourceWhitePoint[1];
+ result[2] = LMS[2] * D65Z / sourceWhitePoint[2];
+ }
+ #sRGBTransferFunction(color) {
+ if (color <= 0.0031308) {
+ return this.#adjustToRange(0, 1, 12.92 * color);
+ }
+ if (color >= 0.99554525) {
+ return 1;
+ }
+ return this.#adjustToRange(0, 1, (1 + 0.055) * color ** (1 / 2.4) - 0.055);
+ }
+ #adjustToRange(min, max, value) {
+ return Math.max(min, Math.min(max, value));
+ }
+ #decodeL(L) {
+ if (L < 0) {
+ return -this.#decodeL(-L);
+ }
+ if (L > 8.0) {
+ return ((L + 16) / 116) ** 3;
+ }
+ return L * CalRGBCS.#DECODE_L_CONSTANT;
+ }
+ #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) {
+ if (sourceBlackPoint[0] === 0 && sourceBlackPoint[1] === 0 && sourceBlackPoint[2] === 0) {
+ result[0] = XYZ_Flat[0];
+ result[1] = XYZ_Flat[1];
+ result[2] = XYZ_Flat[2];
+ return;
+ }
+ const zeroDecodeL = this.#decodeL(0);
+ const X_DST = zeroDecodeL;
+ const X_SRC = this.#decodeL(sourceBlackPoint[0]);
+ const Y_DST = zeroDecodeL;
+ const Y_SRC = this.#decodeL(sourceBlackPoint[1]);
+ const Z_DST = zeroDecodeL;
+ const Z_SRC = this.#decodeL(sourceBlackPoint[2]);
+ const X_Scale = (1 - X_DST) / (1 - X_SRC);
+ const X_Offset = 1 - X_Scale;
+ const Y_Scale = (1 - Y_DST) / (1 - Y_SRC);
+ const Y_Offset = 1 - Y_Scale;
+ const Z_Scale = (1 - Z_DST) / (1 - Z_SRC);
+ const Z_Offset = 1 - Z_Scale;
+ result[0] = XYZ_Flat[0] * X_Scale + X_Offset;
+ result[1] = XYZ_Flat[1] * Y_Scale + Y_Offset;
+ result[2] = XYZ_Flat[2] * Z_Scale + Z_Offset;
+ }
+ #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) {
+ if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) {
+ result[0] = XYZ_In[0];
+ result[1] = XYZ_In[1];
+ result[2] = XYZ_In[2];
+ return;
+ }
+ const LMS = result;
+ this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
+ const LMS_Flat = CalRGBCS.#tempNormalizeMatrix;
+ this.#toFlat(sourceWhitePoint, LMS, LMS_Flat);
+ this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_Flat, result);
+ }
+ #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) {
+ const LMS = result;
+ this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
+ const LMS_D65 = CalRGBCS.#tempNormalizeMatrix;
+ this.#toD65(sourceWhitePoint, LMS, LMS_D65);
+ this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_D65, result);
+ }
+ #toRgb(src, srcOffset, dest, destOffset, scale) {
+ const A = this.#adjustToRange(0, 1, src[srcOffset] * scale);
+ const B = this.#adjustToRange(0, 1, src[srcOffset + 1] * scale);
+ const C = this.#adjustToRange(0, 1, src[srcOffset + 2] * scale);
+ const AGR = A === 1 ? 1 : A ** this.GR;
+ const BGG = B === 1 ? 1 : B ** this.GG;
+ const CGB = C === 1 ? 1 : C ** this.GB;
+ const X = this.MXA * AGR + this.MXB * BGG + this.MXC * CGB;
+ const Y = this.MYA * AGR + this.MYB * BGG + this.MYC * CGB;
+ const Z = this.MZA * AGR + this.MZB * BGG + this.MZC * CGB;
+ const XYZ = CalRGBCS.#tempConvertMatrix1;
+ XYZ[0] = X;
+ XYZ[1] = Y;
+ XYZ[2] = Z;
+ const XYZ_Flat = CalRGBCS.#tempConvertMatrix2;
+ this.#normalizeWhitePointToFlat(this.whitePoint, XYZ, XYZ_Flat);
+ const XYZ_Black = CalRGBCS.#tempConvertMatrix1;
+ this.#compensateBlackPoint(this.blackPoint, XYZ_Flat, XYZ_Black);
+ const XYZ_D65 = CalRGBCS.#tempConvertMatrix2;
+ this.#normalizeWhitePointToD65(CalRGBCS.#FLAT_WHITEPOINT_MATRIX, XYZ_Black, XYZ_D65);
+ const SRGB = CalRGBCS.#tempConvertMatrix1;
+ this.#matrixProduct(CalRGBCS.#SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB);
+ dest[destOffset] = this.#sRGBTransferFunction(SRGB[0]) * 255;
+ dest[destOffset + 1] = this.#sRGBTransferFunction(SRGB[1]) * 255;
+ dest[destOffset + 2] = this.#sRGBTransferFunction(SRGB[2]) * 255;
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const scale = 1 / ((1 << bits) - 1);
+ for (let i = 0; i < count; ++i) {
+ this.#toRgb(src, srcOffset, dest, destOffset, scale);
+ srcOffset += 3;
+ destOffset += 3 + alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength * (3 + alpha01) / 3 | 0;
+ }
+}
+class LabCS extends ColorSpace {
+ constructor(whitePoint, blackPoint, range) {
+ super("Lab", 3);
+ if (!whitePoint) {
+ throw new FormatError("WhitePoint missing - required for color space Lab");
+ }
+ [this.XW, this.YW, this.ZW] = whitePoint;
+ [this.amin, this.amax, this.bmin, this.bmax] = range || [-100, 100, -100, 100];
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
+ throw new FormatError("Invalid WhitePoint components, no fallback available");
+ }
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
+ info("Invalid BlackPoint, falling back to default");
+ this.XB = this.YB = this.ZB = 0;
+ }
+ if (this.amin > this.amax || this.bmin > this.bmax) {
+ info("Invalid Range, falling back to defaults");
+ this.amin = -100;
+ this.amax = 100;
+ this.bmin = -100;
+ this.bmax = 100;
+ }
+ }
+ #fn_g(x) {
+ return x >= 6 / 29 ? x ** 3 : 108 / 841 * (x - 4 / 29);
+ }
+ #decode(value, high1, low2, high2) {
+ return low2 + value * (high2 - low2) / high1;
+ }
+ #toRgb(src, srcOffset, maxVal, dest, destOffset) {
+ let Ls = src[srcOffset];
+ let as = src[srcOffset + 1];
+ let bs = src[srcOffset + 2];
+ if (maxVal !== false) {
+ Ls = this.#decode(Ls, maxVal, 0, 100);
+ as = this.#decode(as, maxVal, this.amin, this.amax);
+ bs = this.#decode(bs, maxVal, this.bmin, this.bmax);
+ }
+ if (as > this.amax) {
+ as = this.amax;
+ } else if (as < this.amin) {
+ as = this.amin;
+ }
+ if (bs > this.bmax) {
+ bs = this.bmax;
+ } else if (bs < this.bmin) {
+ bs = this.bmin;
+ }
+ const M = (Ls + 16) / 116;
+ const L = M + as / 500;
+ const N = M - bs / 200;
+ const X = this.XW * this.#fn_g(L);
+ const Y = this.YW * this.#fn_g(M);
+ const Z = this.ZW * this.#fn_g(N);
+ let r, g, b;
+ if (this.ZW < 1) {
+ r = X * 3.1339 + Y * -1.617 + Z * -0.4906;
+ g = X * -0.9785 + Y * 1.916 + Z * 0.0333;
+ b = X * 0.072 + Y * -0.229 + Z * 1.4057;
+ } else {
+ r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
+ g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
+ b = X * 0.0557 + Y * -0.204 + Z * 1.057;
+ }
+ dest[destOffset] = Math.sqrt(r) * 255;
+ dest[destOffset + 1] = Math.sqrt(g) * 255;
+ dest[destOffset + 2] = Math.sqrt(b) * 255;
+ }
+ getRgbItem(src, srcOffset, dest, destOffset) {
+ this.#toRgb(src, srcOffset, false, dest, destOffset);
+ }
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
+ const maxVal = (1 << bits) - 1;
+ for (let i = 0; i < count; i++) {
+ this.#toRgb(src, srcOffset, maxVal, dest, destOffset);
+ srcOffset += 3;
+ destOffset += 3 + alpha01;
+ }
+ }
+ getOutputLength(inputLength, alpha01) {
+ return inputLength * (3 + alpha01) / 3 | 0;
+ }
+ isDefaultDecode(decodeMap, bpc) {
+ return true;
+ }
+ get usesZeroToOneRange() {
+ return shadow(this, "usesZeroToOneRange", false);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/binary_cmap.js
+
+function hexToInt(a, size) {
+ let n = 0;
+ for (let i = 0; i <= size; i++) {
+ n = n << 8 | a[i];
+ }
+ return n >>> 0;
+}
+function hexToStr(a, size) {
+ if (size === 1) {
+ return String.fromCharCode(a[0], a[1]);
+ }
+ if (size === 3) {
+ return String.fromCharCode(a[0], a[1], a[2], a[3]);
+ }
+ return String.fromCharCode(...a.subarray(0, size + 1));
+}
+function addHex(a, b, size) {
+ let c = 0;
+ for (let i = size; i >= 0; i--) {
+ c += a[i] + b[i];
+ a[i] = c & 255;
+ c >>= 8;
+ }
+}
+function incHex(a, size) {
+ let c = 1;
+ for (let i = size; i >= 0 && c > 0; i--) {
+ c += a[i];
+ a[i] = c & 255;
+ c >>= 8;
+ }
+}
+const MAX_NUM_SIZE = 16;
+const MAX_ENCODED_NUM_SIZE = 19;
+class BinaryCMapStream {
+ constructor(data) {
+ this.buffer = data;
+ this.pos = 0;
+ this.end = data.length;
+ this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);
+ }
+ readByte() {
+ if (this.pos >= this.end) {
+ return -1;
+ }
+ return this.buffer[this.pos++];
+ }
+ readNumber() {
+ let n = 0;
+ let last;
+ do {
+ const b = this.readByte();
+ if (b < 0) {
+ throw new FormatError("unexpected EOF in bcmap");
+ }
+ last = !(b & 0x80);
+ n = n << 7 | b & 0x7f;
+ } while (!last);
+ return n;
+ }
+ readSigned() {
+ const n = this.readNumber();
+ return n & 1 ? ~(n >>> 1) : n >>> 1;
+ }
+ readHex(num, size) {
+ num.set(this.buffer.subarray(this.pos, this.pos + size + 1));
+ this.pos += size + 1;
+ }
+ readHexNumber(num, size) {
+ let last;
+ const stack = this.tmpBuf;
+ let sp = 0;
+ do {
+ const b = this.readByte();
+ if (b < 0) {
+ throw new FormatError("unexpected EOF in bcmap");
+ }
+ last = !(b & 0x80);
+ stack[sp++] = b & 0x7f;
+ } while (!last);
+ let i = size,
+ buffer = 0,
+ bufferSize = 0;
+ while (i >= 0) {
+ while (bufferSize < 8 && stack.length > 0) {
+ buffer |= stack[--sp] << bufferSize;
+ bufferSize += 7;
+ }
+ num[i] = buffer & 255;
+ i--;
+ buffer >>= 8;
+ bufferSize -= 8;
+ }
+ }
+ readHexSigned(num, size) {
+ this.readHexNumber(num, size);
+ const sign = num[size] & 1 ? 255 : 0;
+ let c = 0;
+ for (let i = 0; i <= size; i++) {
+ c = (c & 1) << 8 | num[i];
+ num[i] = c >> 1 ^ sign;
+ }
+ }
+ readString() {
+ const len = this.readNumber(),
+ buf = new Array(len);
+ for (let i = 0; i < len; i++) {
+ buf[i] = this.readNumber();
+ }
+ return String.fromCharCode(...buf);
+ }
+}
+class BinaryCMapReader {
+ async process(data, cMap, extend) {
+ const stream = new BinaryCMapStream(data);
+ const header = stream.readByte();
+ cMap.vertical = !!(header & 1);
+ let useCMap = null;
+ const start = new Uint8Array(MAX_NUM_SIZE);
+ const end = new Uint8Array(MAX_NUM_SIZE);
+ const char = new Uint8Array(MAX_NUM_SIZE);
+ const charCode = new Uint8Array(MAX_NUM_SIZE);
+ const tmp = new Uint8Array(MAX_NUM_SIZE);
+ let code;
+ let b;
+ while ((b = stream.readByte()) >= 0) {
+ const type = b >> 5;
+ if (type === 7) {
+ switch (b & 0x1f) {
+ case 0:
+ stream.readString();
+ break;
+ case 1:
+ useCMap = stream.readString();
+ break;
+ }
+ continue;
+ }
+ const sequence = !!(b & 0x10);
+ const dataSize = b & 15;
+ if (dataSize + 1 > MAX_NUM_SIZE) {
+ throw new Error("BinaryCMapReader.process: Invalid dataSize.");
+ }
+ const ucs2DataSize = 1;
+ const subitemsCount = stream.readNumber();
+ switch (type) {
+ case 0:
+ stream.readHex(start, dataSize);
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(end, dataSize);
+ stream.readHexNumber(start, dataSize);
+ addHex(start, end, dataSize);
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize));
+ }
+ break;
+ case 1:
+ stream.readHex(start, dataSize);
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ stream.readNumber();
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(end, dataSize);
+ stream.readHexNumber(start, dataSize);
+ addHex(start, end, dataSize);
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ stream.readNumber();
+ }
+ break;
+ case 2:
+ stream.readHex(char, dataSize);
+ code = stream.readNumber();
+ cMap.mapOne(hexToInt(char, dataSize), code);
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(char, dataSize);
+ if (!sequence) {
+ stream.readHexNumber(tmp, dataSize);
+ addHex(char, tmp, dataSize);
+ }
+ code = stream.readSigned() + (code + 1);
+ cMap.mapOne(hexToInt(char, dataSize), code);
+ }
+ break;
+ case 3:
+ stream.readHex(start, dataSize);
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ code = stream.readNumber();
+ cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(end, dataSize);
+ if (!sequence) {
+ stream.readHexNumber(start, dataSize);
+ addHex(start, end, dataSize);
+ } else {
+ start.set(end);
+ }
+ stream.readHexNumber(end, dataSize);
+ addHex(end, start, dataSize);
+ code = stream.readNumber();
+ cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code);
+ }
+ break;
+ case 4:
+ stream.readHex(char, ucs2DataSize);
+ stream.readHex(charCode, dataSize);
+ cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(char, ucs2DataSize);
+ if (!sequence) {
+ stream.readHexNumber(tmp, ucs2DataSize);
+ addHex(char, tmp, ucs2DataSize);
+ }
+ incHex(charCode, dataSize);
+ stream.readHexSigned(tmp, dataSize);
+ addHex(charCode, tmp, dataSize);
+ cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize));
+ }
+ break;
+ case 5:
+ stream.readHex(start, ucs2DataSize);
+ stream.readHexNumber(end, ucs2DataSize);
+ addHex(end, start, ucs2DataSize);
+ stream.readHex(charCode, dataSize);
+ cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));
+ for (let i = 1; i < subitemsCount; i++) {
+ incHex(end, ucs2DataSize);
+ if (!sequence) {
+ stream.readHexNumber(start, ucs2DataSize);
+ addHex(start, end, ucs2DataSize);
+ } else {
+ start.set(end);
+ }
+ stream.readHexNumber(end, ucs2DataSize);
+ addHex(end, start, ucs2DataSize);
+ stream.readHex(charCode, dataSize);
+ cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize));
+ }
+ break;
+ default:
+ throw new Error(`BinaryCMapReader.process - unknown type: ${type}`);
+ }
+ }
+ if (useCMap) {
+ return extend(useCMap);
+ }
+ return cMap;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/decode_stream.js
+
+
+const emptyBuffer = new Uint8Array(0);
+class DecodeStream extends BaseStream {
+ constructor(maybeMinBufferLength) {
+ super();
+ this._rawMinBufferLength = maybeMinBufferLength || 0;
+ this.pos = 0;
+ this.bufferLength = 0;
+ this.eof = false;
+ this.buffer = emptyBuffer;
+ this.minBufferLength = 512;
+ if (maybeMinBufferLength) {
+ while (this.minBufferLength < maybeMinBufferLength) {
+ this.minBufferLength *= 2;
+ }
+ }
+ }
+ get isEmpty() {
+ while (!this.eof && this.bufferLength === 0) {
+ this.readBlock();
+ }
+ return this.bufferLength === 0;
+ }
+ ensureBuffer(requested) {
+ const buffer = this.buffer;
+ if (requested <= buffer.byteLength) {
+ return buffer;
+ }
+ let size = this.minBufferLength;
+ while (size < requested) {
+ size *= 2;
+ }
+ const buffer2 = new Uint8Array(size);
+ buffer2.set(buffer);
+ return this.buffer = buffer2;
+ }
+ getByte() {
+ const pos = this.pos;
+ while (this.bufferLength <= pos) {
+ if (this.eof) {
+ return -1;
+ }
+ this.readBlock();
+ }
+ return this.buffer[this.pos++];
+ }
+ getBytes(length) {
+ const pos = this.pos;
+ let end;
+ if (length) {
+ this.ensureBuffer(pos + length);
+ end = pos + length;
+ while (!this.eof && this.bufferLength < end) {
+ this.readBlock();
+ }
+ const bufEnd = this.bufferLength;
+ if (end > bufEnd) {
+ end = bufEnd;
+ }
+ } else {
+ while (!this.eof) {
+ this.readBlock();
+ }
+ end = this.bufferLength;
+ }
+ this.pos = end;
+ return this.buffer.subarray(pos, end);
+ }
+ reset() {
+ this.pos = 0;
+ }
+ makeSubStream(start, length, dict = null) {
+ if (length === undefined) {
+ while (!this.eof) {
+ this.readBlock();
+ }
+ } else {
+ const end = start + length;
+ while (this.bufferLength <= end && !this.eof) {
+ this.readBlock();
+ }
+ }
+ return new Stream(this.buffer, start, length, dict);
+ }
+ getBaseStreams() {
+ return this.str ? this.str.getBaseStreams() : null;
+ }
+}
+class StreamsSequenceStream extends DecodeStream {
+ constructor(streams, onError = null) {
+ let maybeLength = 0;
+ for (const stream of streams) {
+ maybeLength += stream instanceof DecodeStream ? stream._rawMinBufferLength : stream.length;
+ }
+ super(maybeLength);
+ this.streams = streams;
+ this._onError = onError;
+ }
+ readBlock() {
+ const streams = this.streams;
+ if (streams.length === 0) {
+ this.eof = true;
+ return;
+ }
+ const stream = streams.shift();
+ let chunk;
+ try {
+ chunk = stream.getBytes();
+ } catch (reason) {
+ if (this._onError) {
+ this._onError(reason, stream.dict?.objId);
+ return;
+ }
+ throw reason;
+ }
+ const bufferLength = this.bufferLength;
+ const newLength = bufferLength + chunk.length;
+ const buffer = this.ensureBuffer(newLength);
+ buffer.set(chunk, bufferLength);
+ this.bufferLength = newLength;
+ }
+ getBaseStreams() {
+ const baseStreamsBuf = [];
+ for (const stream of this.streams) {
+ const baseStreams = stream.getBaseStreams();
+ if (baseStreams) {
+ baseStreamsBuf.push(...baseStreams);
+ }
+ }
+ return baseStreamsBuf.length > 0 ? baseStreamsBuf : null;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/ascii_85_stream.js
+
+
+class Ascii85Stream extends DecodeStream {
+ constructor(str, maybeLength) {
+ if (maybeLength) {
+ maybeLength *= 0.8;
+ }
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ this.input = new Uint8Array(5);
+ }
+ readBlock() {
+ const TILDA_CHAR = 0x7e;
+ const Z_LOWER_CHAR = 0x7a;
+ const EOF = -1;
+ const str = this.str;
+ let c = str.getByte();
+ while (isWhiteSpace(c)) {
+ c = str.getByte();
+ }
+ if (c === EOF || c === TILDA_CHAR) {
+ this.eof = true;
+ return;
+ }
+ const bufferLength = this.bufferLength;
+ let buffer, i;
+ if (c === Z_LOWER_CHAR) {
+ buffer = this.ensureBuffer(bufferLength + 4);
+ for (i = 0; i < 4; ++i) {
+ buffer[bufferLength + i] = 0;
+ }
+ this.bufferLength += 4;
+ } else {
+ const input = this.input;
+ input[0] = c;
+ for (i = 1; i < 5; ++i) {
+ c = str.getByte();
+ while (isWhiteSpace(c)) {
+ c = str.getByte();
+ }
+ input[i] = c;
+ if (c === EOF || c === TILDA_CHAR) {
+ break;
+ }
+ }
+ buffer = this.ensureBuffer(bufferLength + i - 1);
+ this.bufferLength += i - 1;
+ if (i < 5) {
+ for (; i < 5; ++i) {
+ input[i] = 0x21 + 84;
+ }
+ this.eof = true;
+ }
+ let t = 0;
+ for (i = 0; i < 5; ++i) {
+ t = t * 85 + (input[i] - 0x21);
+ }
+ for (i = 3; i >= 0; --i) {
+ buffer[bufferLength + i] = t & 0xff;
+ t >>= 8;
+ }
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/ascii_hex_stream.js
+
+class AsciiHexStream extends DecodeStream {
+ constructor(str, maybeLength) {
+ if (maybeLength) {
+ maybeLength *= 0.5;
+ }
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ this.firstDigit = -1;
+ }
+ readBlock() {
+ const UPSTREAM_BLOCK_SIZE = 8000;
+ const bytes = this.str.getBytes(UPSTREAM_BLOCK_SIZE);
+ if (!bytes.length) {
+ this.eof = true;
+ return;
+ }
+ const maxDecodeLength = bytes.length + 1 >> 1;
+ const buffer = this.ensureBuffer(this.bufferLength + maxDecodeLength);
+ let bufferLength = this.bufferLength;
+ let firstDigit = this.firstDigit;
+ for (const ch of bytes) {
+ let digit;
+ if (ch >= 0x30 && ch <= 0x39) {
+ digit = ch & 0x0f;
+ } else if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
+ digit = (ch & 0x0f) + 9;
+ } else if (ch === 0x3e) {
+ this.eof = true;
+ break;
+ } else {
+ continue;
+ }
+ if (firstDigit < 0) {
+ firstDigit = digit;
+ } else {
+ buffer[bufferLength++] = firstDigit << 4 | digit;
+ firstDigit = -1;
+ }
+ }
+ if (firstDigit >= 0 && this.eof) {
+ buffer[bufferLength++] = firstDigit << 4;
+ firstDigit = -1;
+ }
+ this.firstDigit = firstDigit;
+ this.bufferLength = bufferLength;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/ccitt.js
+
+const ccittEOL = -2;
+const ccittEOF = -1;
+const twoDimPass = 0;
+const twoDimHoriz = 1;
+const twoDimVert0 = 2;
+const twoDimVertR1 = 3;
+const twoDimVertL1 = 4;
+const twoDimVertR2 = 5;
+const twoDimVertL2 = 6;
+const twoDimVertR3 = 7;
+const twoDimVertL3 = 8;
+const twoDimTable = [[-1, -1], [-1, -1], [7, twoDimVertL3], [7, twoDimVertR3], [6, twoDimVertL2], [6, twoDimVertL2], [6, twoDimVertR2], [6, twoDimVertR2], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0]];
+const whiteTable1 = [[-1, -1], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [12, 1984], [12, 2048], [12, 2112], [12, 2176], [12, 2240], [12, 2304], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [12, 2368], [12, 2432], [12, 2496], [12, 2560]];
+const whiteTable2 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 29], [8, 29], [8, 30], [8, 30], [8, 45], [8, 45], [8, 46], [8, 46], [7, 22], [7, 22], [7, 22], [7, 22], [7, 23], [7, 23], [7, 23], [7, 23], [8, 47], [8, 47], [8, 48], [8, 48], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [7, 20], [7, 20], [7, 20], [7, 20], [8, 33], [8, 33], [8, 34], [8, 34], [8, 35], [8, 35], [8, 36], [8, 36], [8, 37], [8, 37], [8, 38], [8, 38], [7, 19], [7, 19], [7, 19], [7, 19], [8, 31], [8, 31], [8, 32], [8, 32], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [8, 53], [8, 53], [8, 54], [8, 54], [7, 26], [7, 26], [7, 26], [7, 26], [8, 39], [8, 39], [8, 40], [8, 40], [8, 41], [8, 41], [8, 42], [8, 42], [8, 43], [8, 43], [8, 44], [8, 44], [7, 21], [7, 21], [7, 21], [7, 21], [7, 28], [7, 28], [7, 28], [7, 28], [8, 61], [8, 61], [8, 62], [8, 62], [8, 63], [8, 63], [8, 0], [8, 0], [8, 320], [8, 320], [8, 384], [8, 384], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [7, 27], [7, 27], [7, 27], [7, 27], [8, 59], [8, 59], [8, 60], [8, 60], [9, 1472], [9, 1536], [9, 1600], [9, 1728], [7, 18], [7, 18], [7, 18], [7, 18], [7, 24], [7, 24], [7, 24], [7, 24], [8, 49], [8, 49], [8, 50], [8, 50], [8, 51], [8, 51], [8, 52], [8, 52], [7, 25], [7, 25], [7, 25], [7, 25], [8, 55], [8, 55], [8, 56], [8, 56], [8, 57], [8, 57], [8, 58], [8, 58], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [8, 448], [8, 448], [8, 512], [8, 512], [9, 704], [9, 768], [8, 640], [8, 640], [8, 576], [8, 576], [9, 832], [9, 896], [9, 960], [9, 1024], [9, 1088], [9, 1152], [9, 1216], [9, 1280], [9, 1344], [9, 1408], [7, 256], [7, 256], [7, 256], [7, 256], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7]];
+const blackTable1 = [[-1, -1], [-1, -1], [12, ccittEOL], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]];
+const blackTable2 = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]];
+const blackTable3 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]];
+class CCITTFaxDecoder {
+ constructor(source, options = {}) {
+ if (!source || typeof source.next !== "function") {
+ throw new Error('CCITTFaxDecoder - invalid "source" parameter.');
+ }
+ this.source = source;
+ this.eof = false;
+ this.encoding = options.K || 0;
+ this.eoline = options.EndOfLine || false;
+ this.byteAlign = options.EncodedByteAlign || false;
+ this.columns = options.Columns || 1728;
+ this.rows = options.Rows || 0;
+ this.eoblock = options.EndOfBlock ?? true;
+ this.black = options.BlackIs1 || false;
+ this.codingLine = new Uint32Array(this.columns + 1);
+ this.refLine = new Uint32Array(this.columns + 2);
+ this.codingLine[0] = this.columns;
+ this.codingPos = 0;
+ this.row = 0;
+ this.nextLine2D = this.encoding < 0;
+ this.inputBits = 0;
+ this.inputBuf = 0;
+ this.outputBits = 0;
+ this.rowsDone = false;
+ let code1;
+ while ((code1 = this._lookBits(12)) === 0) {
+ this._eatBits(1);
+ }
+ if (code1 === 1) {
+ this._eatBits(12);
+ }
+ if (this.encoding > 0) {
+ this.nextLine2D = !this._lookBits(1);
+ this._eatBits(1);
+ }
+ }
+ readNextChar() {
+ if (this.eof) {
+ return -1;
+ }
+ const refLine = this.refLine;
+ const codingLine = this.codingLine;
+ const columns = this.columns;
+ let refPos, blackPixels, bits, i;
+ if (this.outputBits === 0) {
+ if (this.rowsDone) {
+ this.eof = true;
+ }
+ if (this.eof) {
+ return -1;
+ }
+ this.err = false;
+ let code1, code2, code3;
+ if (this.nextLine2D) {
+ for (i = 0; codingLine[i] < columns; ++i) {
+ refLine[i] = codingLine[i];
+ }
+ refLine[i++] = columns;
+ refLine[i] = columns;
+ codingLine[0] = 0;
+ this.codingPos = 0;
+ refPos = 0;
+ blackPixels = 0;
+ while (codingLine[this.codingPos] < columns) {
+ code1 = this._getTwoDimCode();
+ switch (code1) {
+ case twoDimPass:
+ this._addPixels(refLine[refPos + 1], blackPixels);
+ if (refLine[refPos + 1] < columns) {
+ refPos += 2;
+ }
+ break;
+ case twoDimHoriz:
+ code1 = code2 = 0;
+ if (blackPixels) {
+ do {
+ code1 += code3 = this._getBlackCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = this._getWhiteCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = this._getWhiteCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = this._getBlackCode();
+ } while (code3 >= 64);
+ }
+ this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
+ if (codingLine[this.codingPos] < columns) {
+ this._addPixels(codingLine[this.codingPos] + code2, blackPixels ^ 1);
+ }
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ break;
+ case twoDimVertR3:
+ this._addPixels(refLine[refPos] + 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ ++refPos;
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVertR2:
+ this._addPixels(refLine[refPos] + 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ ++refPos;
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVertR1:
+ this._addPixels(refLine[refPos] + 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ ++refPos;
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVert0:
+ this._addPixels(refLine[refPos], blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ ++refPos;
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVertL3:
+ this._addPixelsNeg(refLine[refPos] - 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ if (refPos > 0) {
+ --refPos;
+ } else {
+ ++refPos;
+ }
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVertL2:
+ this._addPixelsNeg(refLine[refPos] - 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ if (refPos > 0) {
+ --refPos;
+ } else {
+ ++refPos;
+ }
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case twoDimVertL1:
+ this._addPixelsNeg(refLine[refPos] - 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[this.codingPos] < columns) {
+ if (refPos > 0) {
+ --refPos;
+ } else {
+ ++refPos;
+ }
+ while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
+ refPos += 2;
+ }
+ }
+ break;
+ case ccittEOF:
+ this._addPixels(columns, 0);
+ this.eof = true;
+ break;
+ default:
+ info("bad 2d code");
+ this._addPixels(columns, 0);
+ this.err = true;
+ }
+ }
+ } else {
+ codingLine[0] = 0;
+ this.codingPos = 0;
+ blackPixels = 0;
+ while (codingLine[this.codingPos] < columns) {
+ code1 = 0;
+ if (blackPixels) {
+ do {
+ code1 += code3 = this._getBlackCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = this._getWhiteCode();
+ } while (code3 >= 64);
+ }
+ this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
+ blackPixels ^= 1;
+ }
+ }
+ let gotEOL = false;
+ if (this.byteAlign) {
+ this.inputBits &= ~7;
+ }
+ if (!this.eoblock && this.row === this.rows - 1) {
+ this.rowsDone = true;
+ } else {
+ code1 = this._lookBits(12);
+ if (this.eoline) {
+ while (code1 !== ccittEOF && code1 !== 1) {
+ this._eatBits(1);
+ code1 = this._lookBits(12);
+ }
+ } else {
+ while (code1 === 0) {
+ this._eatBits(1);
+ code1 = this._lookBits(12);
+ }
+ }
+ if (code1 === 1) {
+ this._eatBits(12);
+ gotEOL = true;
+ } else if (code1 === ccittEOF) {
+ this.eof = true;
+ }
+ }
+ if (!this.eof && this.encoding > 0 && !this.rowsDone) {
+ this.nextLine2D = !this._lookBits(1);
+ this._eatBits(1);
+ }
+ if (this.eoblock && gotEOL && this.byteAlign) {
+ code1 = this._lookBits(12);
+ if (code1 === 1) {
+ this._eatBits(12);
+ if (this.encoding > 0) {
+ this._lookBits(1);
+ this._eatBits(1);
+ }
+ if (this.encoding >= 0) {
+ for (i = 0; i < 4; ++i) {
+ code1 = this._lookBits(12);
+ if (code1 !== 1) {
+ info("bad rtc code: " + code1);
+ }
+ this._eatBits(12);
+ if (this.encoding > 0) {
+ this._lookBits(1);
+ this._eatBits(1);
+ }
+ }
+ }
+ this.eof = true;
+ }
+ } else if (this.err && this.eoline) {
+ while (true) {
+ code1 = this._lookBits(13);
+ if (code1 === ccittEOF) {
+ this.eof = true;
+ return -1;
+ }
+ if (code1 >> 1 === 1) {
+ break;
+ }
+ this._eatBits(1);
+ }
+ this._eatBits(12);
+ if (this.encoding > 0) {
+ this._eatBits(1);
+ this.nextLine2D = !(code1 & 1);
+ }
+ }
+ this.outputBits = codingLine[0] > 0 ? codingLine[this.codingPos = 0] : codingLine[this.codingPos = 1];
+ this.row++;
+ }
+ let c;
+ if (this.outputBits >= 8) {
+ c = this.codingPos & 1 ? 0 : 0xff;
+ this.outputBits -= 8;
+ if (this.outputBits === 0 && codingLine[this.codingPos] < columns) {
+ this.codingPos++;
+ this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];
+ }
+ } else {
+ bits = 8;
+ c = 0;
+ do {
+ if (typeof this.outputBits !== "number") {
+ throw new FormatError('Invalid /CCITTFaxDecode data, "outputBits" must be a number.');
+ }
+ if (this.outputBits > bits) {
+ c <<= bits;
+ if (!(this.codingPos & 1)) {
+ c |= 0xff >> 8 - bits;
+ }
+ this.outputBits -= bits;
+ bits = 0;
+ } else {
+ c <<= this.outputBits;
+ if (!(this.codingPos & 1)) {
+ c |= 0xff >> 8 - this.outputBits;
+ }
+ bits -= this.outputBits;
+ this.outputBits = 0;
+ if (codingLine[this.codingPos] < columns) {
+ this.codingPos++;
+ this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];
+ } else if (bits > 0) {
+ c <<= bits;
+ bits = 0;
+ }
+ }
+ } while (bits);
+ }
+ if (this.black) {
+ c ^= 0xff;
+ }
+ return c;
+ }
+ _addPixels(a1, blackPixels) {
+ const codingLine = this.codingLine;
+ let codingPos = this.codingPos;
+ if (a1 > codingLine[codingPos]) {
+ if (a1 > this.columns) {
+ info("row is wrong length");
+ this.err = true;
+ a1 = this.columns;
+ }
+ if (codingPos & 1 ^ blackPixels) {
+ ++codingPos;
+ }
+ codingLine[codingPos] = a1;
+ }
+ this.codingPos = codingPos;
+ }
+ _addPixelsNeg(a1, blackPixels) {
+ const codingLine = this.codingLine;
+ let codingPos = this.codingPos;
+ if (a1 > codingLine[codingPos]) {
+ if (a1 > this.columns) {
+ info("row is wrong length");
+ this.err = true;
+ a1 = this.columns;
+ }
+ if (codingPos & 1 ^ blackPixels) {
+ ++codingPos;
+ }
+ codingLine[codingPos] = a1;
+ } else if (a1 < codingLine[codingPos]) {
+ if (a1 < 0) {
+ info("invalid code");
+ this.err = true;
+ a1 = 0;
+ }
+ while (codingPos > 0 && a1 < codingLine[codingPos - 1]) {
+ --codingPos;
+ }
+ codingLine[codingPos] = a1;
+ }
+ this.codingPos = codingPos;
+ }
+ _findTableCode(start, end, table, limit) {
+ const limitValue = limit || 0;
+ for (let i = start; i <= end; ++i) {
+ let code = this._lookBits(i);
+ if (code === ccittEOF) {
+ return [true, 1, false];
+ }
+ if (i < end) {
+ code <<= end - i;
+ }
+ if (!limitValue || code >= limitValue) {
+ const p = table[code - limitValue];
+ if (p[0] === i) {
+ this._eatBits(i);
+ return [true, p[1], true];
+ }
+ }
+ }
+ return [false, 0, false];
+ }
+ _getTwoDimCode() {
+ let code = 0;
+ let p;
+ if (this.eoblock) {
+ code = this._lookBits(7);
+ p = twoDimTable[code];
+ if (p?.[0] > 0) {
+ this._eatBits(p[0]);
+ return p[1];
+ }
+ } else {
+ const result = this._findTableCode(1, 7, twoDimTable);
+ if (result[0] && result[2]) {
+ return result[1];
+ }
+ }
+ info("Bad two dim code");
+ return ccittEOF;
+ }
+ _getWhiteCode() {
+ let code = 0;
+ let p;
+ if (this.eoblock) {
+ code = this._lookBits(12);
+ if (code === ccittEOF) {
+ return 1;
+ }
+ p = code >> 5 === 0 ? whiteTable1[code] : whiteTable2[code >> 3];
+ if (p[0] > 0) {
+ this._eatBits(p[0]);
+ return p[1];
+ }
+ } else {
+ let result = this._findTableCode(1, 9, whiteTable2);
+ if (result[0]) {
+ return result[1];
+ }
+ result = this._findTableCode(11, 12, whiteTable1);
+ if (result[0]) {
+ return result[1];
+ }
+ }
+ info("bad white code");
+ this._eatBits(1);
+ return 1;
+ }
+ _getBlackCode() {
+ let code, p;
+ if (this.eoblock) {
+ code = this._lookBits(13);
+ if (code === ccittEOF) {
+ return 1;
+ }
+ if (code >> 7 === 0) {
+ p = blackTable1[code];
+ } else if (code >> 9 === 0 && code >> 7 !== 0) {
+ p = blackTable2[(code >> 1) - 64];
+ } else {
+ p = blackTable3[code >> 7];
+ }
+ if (p[0] > 0) {
+ this._eatBits(p[0]);
+ return p[1];
+ }
+ } else {
+ let result = this._findTableCode(2, 6, blackTable3);
+ if (result[0]) {
+ return result[1];
+ }
+ result = this._findTableCode(7, 12, blackTable2, 64);
+ if (result[0]) {
+ return result[1];
+ }
+ result = this._findTableCode(10, 13, blackTable1);
+ if (result[0]) {
+ return result[1];
+ }
+ }
+ info("bad black code");
+ this._eatBits(1);
+ return 1;
+ }
+ _lookBits(n) {
+ let c;
+ while (this.inputBits < n) {
+ if ((c = this.source.next()) === -1) {
+ if (this.inputBits === 0) {
+ return ccittEOF;
+ }
+ return this.inputBuf << n - this.inputBits & 0xffff >> 16 - n;
+ }
+ this.inputBuf = this.inputBuf << 8 | c;
+ this.inputBits += 8;
+ }
+ return this.inputBuf >> this.inputBits - n & 0xffff >> 16 - n;
+ }
+ _eatBits(n) {
+ if ((this.inputBits -= n) < 0) {
+ this.inputBits = 0;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/ccitt_stream.js
+
+
+
+class CCITTFaxStream extends DecodeStream {
+ constructor(str, maybeLength, params) {
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ if (!(params instanceof Dict)) {
+ params = Dict.empty;
+ }
+ const source = {
+ next() {
+ return str.getByte();
+ }
+ };
+ this.ccittFaxDecoder = new CCITTFaxDecoder(source, {
+ K: params.get("K"),
+ EndOfLine: params.get("EndOfLine"),
+ EncodedByteAlign: params.get("EncodedByteAlign"),
+ Columns: params.get("Columns"),
+ Rows: params.get("Rows"),
+ EndOfBlock: params.get("EndOfBlock"),
+ BlackIs1: params.get("BlackIs1")
+ });
+ }
+ readBlock() {
+ while (!this.eof) {
+ const c = this.ccittFaxDecoder.readNextChar();
+ if (c === -1) {
+ this.eof = true;
+ return;
+ }
+ this.ensureBuffer(this.bufferLength + 1);
+ this.buffer[this.bufferLength++] = c;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/flate_stream.js
+
+
+const codeLenCodeMap = new Int32Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
+const lengthDecode = new Int32Array([0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a, 0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f, 0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073, 0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102]);
+const distDecode = new Int32Array([0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d, 0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1, 0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01, 0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001]);
+const fixedLitCodeTab = [new Int32Array([0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0, 0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0, 0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0, 0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8, 0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8, 0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8, 0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4, 0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4, 0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4, 0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc, 0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec, 0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc, 0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2, 0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2, 0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2, 0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca, 0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea, 0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da, 0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6, 0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6, 0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6, 0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce, 0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee, 0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de, 0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe, 0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1, 0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1, 0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1, 0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9, 0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9, 0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9, 0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5, 0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5, 0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5, 0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd, 0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed, 0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd, 0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3, 0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3, 0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3, 0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb, 0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb, 0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db, 0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7, 0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7, 0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7, 0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf, 0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef, 0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df, 0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff]), 9];
+const fixedDistCodeTab = [new Int32Array([0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c, 0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000, 0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d, 0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000]), 5];
+class FlateStream extends DecodeStream {
+ constructor(str, maybeLength) {
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ const cmf = str.getByte();
+ const flg = str.getByte();
+ if (cmf === -1 || flg === -1) {
+ throw new FormatError(`Invalid header in flate stream: ${cmf}, ${flg}`);
+ }
+ if ((cmf & 0x0f) !== 0x08) {
+ throw new FormatError(`Unknown compression method in flate stream: ${cmf}, ${flg}`);
+ }
+ if (((cmf << 8) + flg) % 31 !== 0) {
+ throw new FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`);
+ }
+ if (flg & 0x20) {
+ throw new FormatError(`FDICT bit set in flate stream: ${cmf}, ${flg}`);
+ }
+ this.codeSize = 0;
+ this.codeBuf = 0;
+ }
+ getBits(bits) {
+ const str = this.str;
+ let codeSize = this.codeSize;
+ let codeBuf = this.codeBuf;
+ let b;
+ while (codeSize < bits) {
+ if ((b = str.getByte()) === -1) {
+ throw new FormatError("Bad encoding in flate stream");
+ }
+ codeBuf |= b << codeSize;
+ codeSize += 8;
+ }
+ b = codeBuf & (1 << bits) - 1;
+ this.codeBuf = codeBuf >> bits;
+ this.codeSize = codeSize -= bits;
+ return b;
+ }
+ getCode(table) {
+ const str = this.str;
+ const codes = table[0];
+ const maxLen = table[1];
+ let codeSize = this.codeSize;
+ let codeBuf = this.codeBuf;
+ let b;
+ while (codeSize < maxLen) {
+ if ((b = str.getByte()) === -1) {
+ break;
+ }
+ codeBuf |= b << codeSize;
+ codeSize += 8;
+ }
+ const code = codes[codeBuf & (1 << maxLen) - 1];
+ const codeLen = code >> 16;
+ const codeVal = code & 0xffff;
+ if (codeLen < 1 || codeSize < codeLen) {
+ throw new FormatError("Bad encoding in flate stream");
+ }
+ this.codeBuf = codeBuf >> codeLen;
+ this.codeSize = codeSize - codeLen;
+ return codeVal;
+ }
+ generateHuffmanTable(lengths) {
+ const n = lengths.length;
+ let maxLen = 0;
+ let i;
+ for (i = 0; i < n; ++i) {
+ if (lengths[i] > maxLen) {
+ maxLen = lengths[i];
+ }
+ }
+ const size = 1 << maxLen;
+ const codes = new Int32Array(size);
+ for (let len = 1, code = 0, skip = 2; len <= maxLen; ++len, code <<= 1, skip <<= 1) {
+ for (let val = 0; val < n; ++val) {
+ if (lengths[val] === len) {
+ let code2 = 0;
+ let t = code;
+ for (i = 0; i < len; ++i) {
+ code2 = code2 << 1 | t & 1;
+ t >>= 1;
+ }
+ for (i = code2; i < size; i += skip) {
+ codes[i] = len << 16 | val;
+ }
+ ++code;
+ }
+ }
+ }
+ return [codes, maxLen];
+ }
+ #endsStreamOnError(err) {
+ info(err);
+ this.eof = true;
+ }
+ readBlock() {
+ let buffer, len;
+ const str = this.str;
+ let hdr = this.getBits(3);
+ if (hdr & 1) {
+ this.eof = true;
+ }
+ hdr >>= 1;
+ if (hdr === 0) {
+ let b;
+ if ((b = str.getByte()) === -1) {
+ this.#endsStreamOnError("Bad block header in flate stream");
+ return;
+ }
+ let blockLen = b;
+ if ((b = str.getByte()) === -1) {
+ this.#endsStreamOnError("Bad block header in flate stream");
+ return;
+ }
+ blockLen |= b << 8;
+ if ((b = str.getByte()) === -1) {
+ this.#endsStreamOnError("Bad block header in flate stream");
+ return;
+ }
+ let check = b;
+ if ((b = str.getByte()) === -1) {
+ this.#endsStreamOnError("Bad block header in flate stream");
+ return;
+ }
+ check |= b << 8;
+ if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) {
+ throw new FormatError("Bad uncompressed block length in flate stream");
+ }
+ this.codeBuf = 0;
+ this.codeSize = 0;
+ const bufferLength = this.bufferLength,
+ end = bufferLength + blockLen;
+ buffer = this.ensureBuffer(end);
+ this.bufferLength = end;
+ if (blockLen === 0) {
+ if (str.peekByte() === -1) {
+ this.eof = true;
+ }
+ } else {
+ const block = str.getBytes(blockLen);
+ buffer.set(block, bufferLength);
+ if (block.length < blockLen) {
+ this.eof = true;
+ }
+ }
+ return;
+ }
+ let litCodeTable;
+ let distCodeTable;
+ if (hdr === 1) {
+ litCodeTable = fixedLitCodeTab;
+ distCodeTable = fixedDistCodeTab;
+ } else if (hdr === 2) {
+ const numLitCodes = this.getBits(5) + 257;
+ const numDistCodes = this.getBits(5) + 1;
+ const numCodeLenCodes = this.getBits(4) + 4;
+ const codeLenCodeLengths = new Uint8Array(codeLenCodeMap.length);
+ let i;
+ for (i = 0; i < numCodeLenCodes; ++i) {
+ codeLenCodeLengths[codeLenCodeMap[i]] = this.getBits(3);
+ }
+ const codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);
+ len = 0;
+ i = 0;
+ const codes = numLitCodes + numDistCodes;
+ const codeLengths = new Uint8Array(codes);
+ let bitsLength, bitsOffset, what;
+ while (i < codes) {
+ const code = this.getCode(codeLenCodeTab);
+ if (code === 16) {
+ bitsLength = 2;
+ bitsOffset = 3;
+ what = len;
+ } else if (code === 17) {
+ bitsLength = 3;
+ bitsOffset = 3;
+ what = len = 0;
+ } else if (code === 18) {
+ bitsLength = 7;
+ bitsOffset = 11;
+ what = len = 0;
+ } else {
+ codeLengths[i++] = len = code;
+ continue;
+ }
+ let repeatLength = this.getBits(bitsLength) + bitsOffset;
+ while (repeatLength-- > 0) {
+ codeLengths[i++] = what;
+ }
+ }
+ litCodeTable = this.generateHuffmanTable(codeLengths.subarray(0, numLitCodes));
+ distCodeTable = this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes));
+ } else {
+ throw new FormatError("Unknown block type in flate stream");
+ }
+ buffer = this.buffer;
+ let limit = buffer ? buffer.length : 0;
+ let pos = this.bufferLength;
+ while (true) {
+ let code1 = this.getCode(litCodeTable);
+ if (code1 < 256) {
+ if (pos + 1 >= limit) {
+ buffer = this.ensureBuffer(pos + 1);
+ limit = buffer.length;
+ }
+ buffer[pos++] = code1;
+ continue;
+ }
+ if (code1 === 256) {
+ this.bufferLength = pos;
+ return;
+ }
+ code1 -= 257;
+ code1 = lengthDecode[code1];
+ let code2 = code1 >> 16;
+ if (code2 > 0) {
+ code2 = this.getBits(code2);
+ }
+ len = (code1 & 0xffff) + code2;
+ code1 = this.getCode(distCodeTable);
+ code1 = distDecode[code1];
+ code2 = code1 >> 16;
+ if (code2 > 0) {
+ code2 = this.getBits(code2);
+ }
+ const dist = (code1 & 0xffff) + code2;
+ if (pos + len >= limit) {
+ buffer = this.ensureBuffer(pos + len);
+ limit = buffer.length;
+ }
+ for (let k = 0; k < len; ++k, ++pos) {
+ buffer[pos] = buffer[pos - dist];
+ }
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/arithmetic_decoder.js
+const QeTable = [{
+ qe: 0x5601,
+ nmps: 1,
+ nlps: 1,
+ switchFlag: 1
+}, {
+ qe: 0x3401,
+ nmps: 2,
+ nlps: 6,
+ switchFlag: 0
+}, {
+ qe: 0x1801,
+ nmps: 3,
+ nlps: 9,
+ switchFlag: 0
+}, {
+ qe: 0x0ac1,
+ nmps: 4,
+ nlps: 12,
+ switchFlag: 0
+}, {
+ qe: 0x0521,
+ nmps: 5,
+ nlps: 29,
+ switchFlag: 0
+}, {
+ qe: 0x0221,
+ nmps: 38,
+ nlps: 33,
+ switchFlag: 0
+}, {
+ qe: 0x5601,
+ nmps: 7,
+ nlps: 6,
+ switchFlag: 1
+}, {
+ qe: 0x5401,
+ nmps: 8,
+ nlps: 14,
+ switchFlag: 0
+}, {
+ qe: 0x4801,
+ nmps: 9,
+ nlps: 14,
+ switchFlag: 0
+}, {
+ qe: 0x3801,
+ nmps: 10,
+ nlps: 14,
+ switchFlag: 0
+}, {
+ qe: 0x3001,
+ nmps: 11,
+ nlps: 17,
+ switchFlag: 0
+}, {
+ qe: 0x2401,
+ nmps: 12,
+ nlps: 18,
+ switchFlag: 0
+}, {
+ qe: 0x1c01,
+ nmps: 13,
+ nlps: 20,
+ switchFlag: 0
+}, {
+ qe: 0x1601,
+ nmps: 29,
+ nlps: 21,
+ switchFlag: 0
+}, {
+ qe: 0x5601,
+ nmps: 15,
+ nlps: 14,
+ switchFlag: 1
+}, {
+ qe: 0x5401,
+ nmps: 16,
+ nlps: 14,
+ switchFlag: 0
+}, {
+ qe: 0x5101,
+ nmps: 17,
+ nlps: 15,
+ switchFlag: 0
+}, {
+ qe: 0x4801,
+ nmps: 18,
+ nlps: 16,
+ switchFlag: 0
+}, {
+ qe: 0x3801,
+ nmps: 19,
+ nlps: 17,
+ switchFlag: 0
+}, {
+ qe: 0x3401,
+ nmps: 20,
+ nlps: 18,
+ switchFlag: 0
+}, {
+ qe: 0x3001,
+ nmps: 21,
+ nlps: 19,
+ switchFlag: 0
+}, {
+ qe: 0x2801,
+ nmps: 22,
+ nlps: 19,
+ switchFlag: 0
+}, {
+ qe: 0x2401,
+ nmps: 23,
+ nlps: 20,
+ switchFlag: 0
+}, {
+ qe: 0x2201,
+ nmps: 24,
+ nlps: 21,
+ switchFlag: 0
+}, {
+ qe: 0x1c01,
+ nmps: 25,
+ nlps: 22,
+ switchFlag: 0
+}, {
+ qe: 0x1801,
+ nmps: 26,
+ nlps: 23,
+ switchFlag: 0
+}, {
+ qe: 0x1601,
+ nmps: 27,
+ nlps: 24,
+ switchFlag: 0
+}, {
+ qe: 0x1401,
+ nmps: 28,
+ nlps: 25,
+ switchFlag: 0
+}, {
+ qe: 0x1201,
+ nmps: 29,
+ nlps: 26,
+ switchFlag: 0
+}, {
+ qe: 0x1101,
+ nmps: 30,
+ nlps: 27,
+ switchFlag: 0
+}, {
+ qe: 0x0ac1,
+ nmps: 31,
+ nlps: 28,
+ switchFlag: 0
+}, {
+ qe: 0x09c1,
+ nmps: 32,
+ nlps: 29,
+ switchFlag: 0
+}, {
+ qe: 0x08a1,
+ nmps: 33,
+ nlps: 30,
+ switchFlag: 0
+}, {
+ qe: 0x0521,
+ nmps: 34,
+ nlps: 31,
+ switchFlag: 0
+}, {
+ qe: 0x0441,
+ nmps: 35,
+ nlps: 32,
+ switchFlag: 0
+}, {
+ qe: 0x02a1,
+ nmps: 36,
+ nlps: 33,
+ switchFlag: 0
+}, {
+ qe: 0x0221,
+ nmps: 37,
+ nlps: 34,
+ switchFlag: 0
+}, {
+ qe: 0x0141,
+ nmps: 38,
+ nlps: 35,
+ switchFlag: 0
+}, {
+ qe: 0x0111,
+ nmps: 39,
+ nlps: 36,
+ switchFlag: 0
+}, {
+ qe: 0x0085,
+ nmps: 40,
+ nlps: 37,
+ switchFlag: 0
+}, {
+ qe: 0x0049,
+ nmps: 41,
+ nlps: 38,
+ switchFlag: 0
+}, {
+ qe: 0x0025,
+ nmps: 42,
+ nlps: 39,
+ switchFlag: 0
+}, {
+ qe: 0x0015,
+ nmps: 43,
+ nlps: 40,
+ switchFlag: 0
+}, {
+ qe: 0x0009,
+ nmps: 44,
+ nlps: 41,
+ switchFlag: 0
+}, {
+ qe: 0x0005,
+ nmps: 45,
+ nlps: 42,
+ switchFlag: 0
+}, {
+ qe: 0x0001,
+ nmps: 45,
+ nlps: 43,
+ switchFlag: 0
+}, {
+ qe: 0x5601,
+ nmps: 46,
+ nlps: 46,
+ switchFlag: 0
+}];
+class ArithmeticDecoder {
+ constructor(data, start, end) {
+ this.data = data;
+ this.bp = start;
+ this.dataEnd = end;
+ this.chigh = data[start];
+ this.clow = 0;
+ this.byteIn();
+ this.chigh = this.chigh << 7 & 0xffff | this.clow >> 9 & 0x7f;
+ this.clow = this.clow << 7 & 0xffff;
+ this.ct -= 7;
+ this.a = 0x8000;
+ }
+ byteIn() {
+ const data = this.data;
+ let bp = this.bp;
+ if (data[bp] === 0xff) {
+ if (data[bp + 1] > 0x8f) {
+ this.clow += 0xff00;
+ this.ct = 8;
+ } else {
+ bp++;
+ this.clow += data[bp] << 9;
+ this.ct = 7;
+ this.bp = bp;
+ }
+ } else {
+ bp++;
+ this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00;
+ this.ct = 8;
+ this.bp = bp;
+ }
+ if (this.clow > 0xffff) {
+ this.chigh += this.clow >> 16;
+ this.clow &= 0xffff;
+ }
+ }
+ readBit(contexts, pos) {
+ let cx_index = contexts[pos] >> 1,
+ cx_mps = contexts[pos] & 1;
+ const qeTableIcx = QeTable[cx_index];
+ const qeIcx = qeTableIcx.qe;
+ let d;
+ let a = this.a - qeIcx;
+ if (this.chigh < qeIcx) {
+ if (a < qeIcx) {
+ a = qeIcx;
+ d = cx_mps;
+ cx_index = qeTableIcx.nmps;
+ } else {
+ a = qeIcx;
+ d = 1 ^ cx_mps;
+ if (qeTableIcx.switchFlag === 1) {
+ cx_mps = d;
+ }
+ cx_index = qeTableIcx.nlps;
+ }
+ } else {
+ this.chigh -= qeIcx;
+ if ((a & 0x8000) !== 0) {
+ this.a = a;
+ return cx_mps;
+ }
+ if (a < qeIcx) {
+ d = 1 ^ cx_mps;
+ if (qeTableIcx.switchFlag === 1) {
+ cx_mps = d;
+ }
+ cx_index = qeTableIcx.nlps;
+ } else {
+ d = cx_mps;
+ cx_index = qeTableIcx.nmps;
+ }
+ }
+ do {
+ if (this.ct === 0) {
+ this.byteIn();
+ }
+ a <<= 1;
+ this.chigh = this.chigh << 1 & 0xffff | this.clow >> 15 & 1;
+ this.clow = this.clow << 1 & 0xffff;
+ this.ct--;
+ } while ((a & 0x8000) === 0);
+ this.a = a;
+ contexts[pos] = cx_index << 1 | cx_mps;
+ return d;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jbig2.js
+
+
+
+
+class Jbig2Error extends BaseException {
+ constructor(msg) {
+ super(`JBIG2 error: ${msg}`, "Jbig2Error");
+ }
+}
+class ContextCache {
+ getContexts(id) {
+ if (id in this) {
+ return this[id];
+ }
+ return this[id] = new Int8Array(1 << 16);
+ }
+}
+class DecodingContext {
+ constructor(data, start, end) {
+ this.data = data;
+ this.start = start;
+ this.end = end;
+ }
+ get decoder() {
+ const decoder = new ArithmeticDecoder(this.data, this.start, this.end);
+ return shadow(this, "decoder", decoder);
+ }
+ get contextCache() {
+ const cache = new ContextCache();
+ return shadow(this, "contextCache", cache);
+ }
+}
+const MAX_INT_32 = 2 ** 31 - 1;
+const MIN_INT_32 = -(2 ** 31);
+function decodeInteger(contextCache, procedure, decoder) {
+ const contexts = contextCache.getContexts(procedure);
+ let prev = 1;
+ function readBits(length) {
+ let v = 0;
+ for (let i = 0; i < length; i++) {
+ const bit = decoder.readBit(contexts, prev);
+ prev = prev < 256 ? prev << 1 | bit : (prev << 1 | bit) & 511 | 256;
+ v = v << 1 | bit;
+ }
+ return v >>> 0;
+ }
+ const sign = readBits(1);
+ const value = readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(32) + 4436 : readBits(12) + 340 : readBits(8) + 84 : readBits(6) + 20 : readBits(4) + 4 : readBits(2);
+ let signedValue;
+ if (sign === 0) {
+ signedValue = value;
+ } else if (value > 0) {
+ signedValue = -value;
+ }
+ if (signedValue >= MIN_INT_32 && signedValue <= MAX_INT_32) {
+ return signedValue;
+ }
+ return null;
+}
+function decodeIAID(contextCache, decoder, codeLength) {
+ const contexts = contextCache.getContexts("IAID");
+ let prev = 1;
+ for (let i = 0; i < codeLength; i++) {
+ const bit = decoder.readBit(contexts, prev);
+ prev = prev << 1 | bit;
+ }
+ if (codeLength < 31) {
+ return prev & (1 << codeLength) - 1;
+ }
+ return prev & 0x7fffffff;
+}
+const SegmentTypes = ["SymbolDictionary", null, null, null, "IntermediateTextRegion", null, "ImmediateTextRegion", "ImmediateLosslessTextRegion", null, null, null, null, null, null, null, null, "PatternDictionary", null, null, null, "IntermediateHalftoneRegion", null, "ImmediateHalftoneRegion", "ImmediateLosslessHalftoneRegion", null, null, null, null, null, null, null, null, null, null, null, null, "IntermediateGenericRegion", null, "ImmediateGenericRegion", "ImmediateLosslessGenericRegion", "IntermediateGenericRefinementRegion", null, "ImmediateGenericRefinementRegion", "ImmediateLosslessGenericRefinementRegion", null, null, null, null, "PageInformation", "EndOfPage", "EndOfStripe", "EndOfFile", "Profiles", "Tables", null, null, null, null, null, null, null, null, "Extension"];
+const CodingTemplates = [[{
+ x: -1,
+ y: -2
+}, {
+ x: 0,
+ y: -2
+}, {
+ x: 1,
+ y: -2
+}, {
+ x: -2,
+ y: -1
+}, {
+ x: -1,
+ y: -1
+}, {
+ x: 0,
+ y: -1
+}, {
+ x: 1,
+ y: -1
+}, {
+ x: 2,
+ y: -1
+}, {
+ x: -4,
+ y: 0
+}, {
+ x: -3,
+ y: 0
+}, {
+ x: -2,
+ y: 0
+}, {
+ x: -1,
+ y: 0
+}], [{
+ x: -1,
+ y: -2
+}, {
+ x: 0,
+ y: -2
+}, {
+ x: 1,
+ y: -2
+}, {
+ x: 2,
+ y: -2
+}, {
+ x: -2,
+ y: -1
+}, {
+ x: -1,
+ y: -1
+}, {
+ x: 0,
+ y: -1
+}, {
+ x: 1,
+ y: -1
+}, {
+ x: 2,
+ y: -1
+}, {
+ x: -3,
+ y: 0
+}, {
+ x: -2,
+ y: 0
+}, {
+ x: -1,
+ y: 0
+}], [{
+ x: -1,
+ y: -2
+}, {
+ x: 0,
+ y: -2
+}, {
+ x: 1,
+ y: -2
+}, {
+ x: -2,
+ y: -1
+}, {
+ x: -1,
+ y: -1
+}, {
+ x: 0,
+ y: -1
+}, {
+ x: 1,
+ y: -1
+}, {
+ x: -2,
+ y: 0
+}, {
+ x: -1,
+ y: 0
+}], [{
+ x: -3,
+ y: -1
+}, {
+ x: -2,
+ y: -1
+}, {
+ x: -1,
+ y: -1
+}, {
+ x: 0,
+ y: -1
+}, {
+ x: 1,
+ y: -1
+}, {
+ x: -4,
+ y: 0
+}, {
+ x: -3,
+ y: 0
+}, {
+ x: -2,
+ y: 0
+}, {
+ x: -1,
+ y: 0
+}]];
+const RefinementTemplates = [{
+ coding: [{
+ x: 0,
+ y: -1
+ }, {
+ x: 1,
+ y: -1
+ }, {
+ x: -1,
+ y: 0
+ }],
+ reference: [{
+ x: 0,
+ y: -1
+ }, {
+ x: 1,
+ y: -1
+ }, {
+ x: -1,
+ y: 0
+ }, {
+ x: 0,
+ y: 0
+ }, {
+ x: 1,
+ y: 0
+ }, {
+ x: -1,
+ y: 1
+ }, {
+ x: 0,
+ y: 1
+ }, {
+ x: 1,
+ y: 1
+ }]
+}, {
+ coding: [{
+ x: -1,
+ y: -1
+ }, {
+ x: 0,
+ y: -1
+ }, {
+ x: 1,
+ y: -1
+ }, {
+ x: -1,
+ y: 0
+ }],
+ reference: [{
+ x: 0,
+ y: -1
+ }, {
+ x: -1,
+ y: 0
+ }, {
+ x: 0,
+ y: 0
+ }, {
+ x: 1,
+ y: 0
+ }, {
+ x: 0,
+ y: 1
+ }, {
+ x: 1,
+ y: 1
+ }]
+}];
+const ReusedContexts = [0x9b25, 0x0795, 0x00e5, 0x0195];
+const RefinementReusedContexts = [0x0020, 0x0008];
+function decodeBitmapTemplate0(width, height, decodingContext) {
+ const decoder = decodingContext.decoder;
+ const contexts = decodingContext.contextCache.getContexts("GB");
+ const bitmap = [];
+ let contextLabel, i, j, pixel, row, row1, row2;
+ const OLD_PIXEL_MASK = 0x7bf7;
+ for (i = 0; i < height; i++) {
+ row = bitmap[i] = new Uint8Array(width);
+ row1 = i < 1 ? row : bitmap[i - 1];
+ row2 = i < 2 ? row : bitmap[i - 2];
+ contextLabel = row2[0] << 13 | row2[1] << 12 | row2[2] << 11 | row1[0] << 7 | row1[1] << 6 | row1[2] << 5 | row1[3] << 4;
+ for (j = 0; j < width; j++) {
+ row[j] = pixel = decoder.readBit(contexts, contextLabel);
+ contextLabel = (contextLabel & OLD_PIXEL_MASK) << 1 | (j + 3 < width ? row2[j + 3] << 11 : 0) | (j + 4 < width ? row1[j + 4] << 4 : 0) | pixel;
+ }
+ }
+ return bitmap;
+}
+function decodeBitmap(mmr, width, height, templateIndex, prediction, skip, at, decodingContext) {
+ if (mmr) {
+ const input = new Reader(decodingContext.data, decodingContext.start, decodingContext.end);
+ return decodeMMRBitmap(input, width, height, false);
+ }
+ if (templateIndex === 0 && !skip && !prediction && at.length === 4 && at[0].x === 3 && at[0].y === -1 && at[1].x === -3 && at[1].y === -1 && at[2].x === 2 && at[2].y === -2 && at[3].x === -2 && at[3].y === -2) {
+ return decodeBitmapTemplate0(width, height, decodingContext);
+ }
+ const useskip = !!skip;
+ const template = CodingTemplates[templateIndex].concat(at);
+ template.sort(function (a, b) {
+ return a.y - b.y || a.x - b.x;
+ });
+ const templateLength = template.length;
+ const templateX = new Int8Array(templateLength);
+ const templateY = new Int8Array(templateLength);
+ const changingTemplateEntries = [];
+ let reuseMask = 0,
+ minX = 0,
+ maxX = 0,
+ minY = 0;
+ let c, k;
+ for (k = 0; k < templateLength; k++) {
+ templateX[k] = template[k].x;
+ templateY[k] = template[k].y;
+ minX = Math.min(minX, template[k].x);
+ maxX = Math.max(maxX, template[k].x);
+ minY = Math.min(minY, template[k].y);
+ if (k < templateLength - 1 && template[k].y === template[k + 1].y && template[k].x === template[k + 1].x - 1) {
+ reuseMask |= 1 << templateLength - 1 - k;
+ } else {
+ changingTemplateEntries.push(k);
+ }
+ }
+ const changingEntriesLength = changingTemplateEntries.length;
+ const changingTemplateX = new Int8Array(changingEntriesLength);
+ const changingTemplateY = new Int8Array(changingEntriesLength);
+ const changingTemplateBit = new Uint16Array(changingEntriesLength);
+ for (c = 0; c < changingEntriesLength; c++) {
+ k = changingTemplateEntries[c];
+ changingTemplateX[c] = template[k].x;
+ changingTemplateY[c] = template[k].y;
+ changingTemplateBit[c] = 1 << templateLength - 1 - k;
+ }
+ const sbb_left = -minX;
+ const sbb_top = -minY;
+ const sbb_right = width - maxX;
+ const pseudoPixelContext = ReusedContexts[templateIndex];
+ let row = new Uint8Array(width);
+ const bitmap = [];
+ const decoder = decodingContext.decoder;
+ const contexts = decodingContext.contextCache.getContexts("GB");
+ let ltp = 0,
+ j,
+ i0,
+ j0,
+ contextLabel = 0,
+ bit,
+ shift;
+ for (let i = 0; i < height; i++) {
+ if (prediction) {
+ const sltp = decoder.readBit(contexts, pseudoPixelContext);
+ ltp ^= sltp;
+ if (ltp) {
+ bitmap.push(row);
+ continue;
+ }
+ }
+ row = new Uint8Array(row);
+ bitmap.push(row);
+ for (j = 0; j < width; j++) {
+ if (useskip && skip[i][j]) {
+ row[j] = 0;
+ continue;
+ }
+ if (j >= sbb_left && j < sbb_right && i >= sbb_top) {
+ contextLabel = contextLabel << 1 & reuseMask;
+ for (k = 0; k < changingEntriesLength; k++) {
+ i0 = i + changingTemplateY[k];
+ j0 = j + changingTemplateX[k];
+ bit = bitmap[i0][j0];
+ if (bit) {
+ bit = changingTemplateBit[k];
+ contextLabel |= bit;
+ }
+ }
+ } else {
+ contextLabel = 0;
+ shift = templateLength - 1;
+ for (k = 0; k < templateLength; k++, shift--) {
+ j0 = j + templateX[k];
+ if (j0 >= 0 && j0 < width) {
+ i0 = i + templateY[k];
+ if (i0 >= 0) {
+ bit = bitmap[i0][j0];
+ if (bit) {
+ contextLabel |= bit << shift;
+ }
+ }
+ }
+ }
+ }
+ const pixel = decoder.readBit(contexts, contextLabel);
+ row[j] = pixel;
+ }
+ }
+ return bitmap;
+}
+function decodeRefinement(width, height, templateIndex, referenceBitmap, offsetX, offsetY, prediction, at, decodingContext) {
+ let codingTemplate = RefinementTemplates[templateIndex].coding;
+ if (templateIndex === 0) {
+ codingTemplate = codingTemplate.concat([at[0]]);
+ }
+ const codingTemplateLength = codingTemplate.length;
+ const codingTemplateX = new Int32Array(codingTemplateLength);
+ const codingTemplateY = new Int32Array(codingTemplateLength);
+ let k;
+ for (k = 0; k < codingTemplateLength; k++) {
+ codingTemplateX[k] = codingTemplate[k].x;
+ codingTemplateY[k] = codingTemplate[k].y;
+ }
+ let referenceTemplate = RefinementTemplates[templateIndex].reference;
+ if (templateIndex === 0) {
+ referenceTemplate = referenceTemplate.concat([at[1]]);
+ }
+ const referenceTemplateLength = referenceTemplate.length;
+ const referenceTemplateX = new Int32Array(referenceTemplateLength);
+ const referenceTemplateY = new Int32Array(referenceTemplateLength);
+ for (k = 0; k < referenceTemplateLength; k++) {
+ referenceTemplateX[k] = referenceTemplate[k].x;
+ referenceTemplateY[k] = referenceTemplate[k].y;
+ }
+ const referenceWidth = referenceBitmap[0].length;
+ const referenceHeight = referenceBitmap.length;
+ const pseudoPixelContext = RefinementReusedContexts[templateIndex];
+ const bitmap = [];
+ const decoder = decodingContext.decoder;
+ const contexts = decodingContext.contextCache.getContexts("GR");
+ let ltp = 0;
+ for (let i = 0; i < height; i++) {
+ if (prediction) {
+ const sltp = decoder.readBit(contexts, pseudoPixelContext);
+ ltp ^= sltp;
+ if (ltp) {
+ throw new Jbig2Error("prediction is not supported");
+ }
+ }
+ const row = new Uint8Array(width);
+ bitmap.push(row);
+ for (let j = 0; j < width; j++) {
+ let i0, j0;
+ let contextLabel = 0;
+ for (k = 0; k < codingTemplateLength; k++) {
+ i0 = i + codingTemplateY[k];
+ j0 = j + codingTemplateX[k];
+ if (i0 < 0 || j0 < 0 || j0 >= width) {
+ contextLabel <<= 1;
+ } else {
+ contextLabel = contextLabel << 1 | bitmap[i0][j0];
+ }
+ }
+ for (k = 0; k < referenceTemplateLength; k++) {
+ i0 = i + referenceTemplateY[k] - offsetY;
+ j0 = j + referenceTemplateX[k] - offsetX;
+ if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {
+ contextLabel <<= 1;
+ } else {
+ contextLabel = contextLabel << 1 | referenceBitmap[i0][j0];
+ }
+ }
+ const pixel = decoder.readBit(contexts, contextLabel);
+ row[j] = pixel;
+ }
+ }
+ return bitmap;
+}
+function decodeSymbolDictionary(huffman, refinement, symbols, numberOfNewSymbols, numberOfExportedSymbols, huffmanTables, templateIndex, at, refinementTemplateIndex, refinementAt, decodingContext, huffmanInput) {
+ if (huffman && refinement) {
+ throw new Jbig2Error("symbol refinement with Huffman is not supported");
+ }
+ const newSymbols = [];
+ let currentHeight = 0;
+ let symbolCodeLength = log2(symbols.length + numberOfNewSymbols);
+ const decoder = decodingContext.decoder;
+ const contextCache = decodingContext.contextCache;
+ let tableB1, symbolWidths;
+ if (huffman) {
+ tableB1 = getStandardTable(1);
+ symbolWidths = [];
+ symbolCodeLength = Math.max(symbolCodeLength, 1);
+ }
+ while (newSymbols.length < numberOfNewSymbols) {
+ const deltaHeight = huffman ? huffmanTables.tableDeltaHeight.decode(huffmanInput) : decodeInteger(contextCache, "IADH", decoder);
+ currentHeight += deltaHeight;
+ let currentWidth = 0,
+ totalWidth = 0;
+ const firstSymbol = huffman ? symbolWidths.length : 0;
+ while (true) {
+ const deltaWidth = huffman ? huffmanTables.tableDeltaWidth.decode(huffmanInput) : decodeInteger(contextCache, "IADW", decoder);
+ if (deltaWidth === null) {
+ break;
+ }
+ currentWidth += deltaWidth;
+ totalWidth += currentWidth;
+ let bitmap;
+ if (refinement) {
+ const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder);
+ if (numberOfInstances > 1) {
+ bitmap = decodeTextRegion(huffman, refinement, currentWidth, currentHeight, 0, numberOfInstances, 1, symbols.concat(newSymbols), symbolCodeLength, 0, 0, 1, 0, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, 0, huffmanInput);
+ } else {
+ const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);
+ const rdx = decodeInteger(contextCache, "IARDX", decoder);
+ const rdy = decodeInteger(contextCache, "IARDY", decoder);
+ const symbol = symbolId < symbols.length ? symbols[symbolId] : newSymbols[symbolId - symbols.length];
+ bitmap = decodeRefinement(currentWidth, currentHeight, refinementTemplateIndex, symbol, rdx, rdy, false, refinementAt, decodingContext);
+ }
+ newSymbols.push(bitmap);
+ } else if (huffman) {
+ symbolWidths.push(currentWidth);
+ } else {
+ bitmap = decodeBitmap(false, currentWidth, currentHeight, templateIndex, false, null, at, decodingContext);
+ newSymbols.push(bitmap);
+ }
+ }
+ if (huffman && !refinement) {
+ const bitmapSize = huffmanTables.tableBitmapSize.decode(huffmanInput);
+ huffmanInput.byteAlign();
+ let collectiveBitmap;
+ if (bitmapSize === 0) {
+ collectiveBitmap = readUncompressedBitmap(huffmanInput, totalWidth, currentHeight);
+ } else {
+ const originalEnd = huffmanInput.end;
+ const bitmapEnd = huffmanInput.position + bitmapSize;
+ huffmanInput.end = bitmapEnd;
+ collectiveBitmap = decodeMMRBitmap(huffmanInput, totalWidth, currentHeight, false);
+ huffmanInput.end = originalEnd;
+ huffmanInput.position = bitmapEnd;
+ }
+ const numberOfSymbolsDecoded = symbolWidths.length;
+ if (firstSymbol === numberOfSymbolsDecoded - 1) {
+ newSymbols.push(collectiveBitmap);
+ } else {
+ let i,
+ y,
+ xMin = 0,
+ xMax,
+ bitmapWidth,
+ symbolBitmap;
+ for (i = firstSymbol; i < numberOfSymbolsDecoded; i++) {
+ bitmapWidth = symbolWidths[i];
+ xMax = xMin + bitmapWidth;
+ symbolBitmap = [];
+ for (y = 0; y < currentHeight; y++) {
+ symbolBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
+ }
+ newSymbols.push(symbolBitmap);
+ xMin = xMax;
+ }
+ }
+ }
+ }
+ const exportedSymbols = [],
+ flags = [];
+ let currentFlag = false,
+ i,
+ ii;
+ const totalSymbolsLength = symbols.length + numberOfNewSymbols;
+ while (flags.length < totalSymbolsLength) {
+ let runLength = huffman ? tableB1.decode(huffmanInput) : decodeInteger(contextCache, "IAEX", decoder);
+ while (runLength--) {
+ flags.push(currentFlag);
+ }
+ currentFlag = !currentFlag;
+ }
+ for (i = 0, ii = symbols.length; i < ii; i++) {
+ if (flags[i]) {
+ exportedSymbols.push(symbols[i]);
+ }
+ }
+ for (let j = 0; j < numberOfNewSymbols; i++, j++) {
+ if (flags[i]) {
+ exportedSymbols.push(newSymbols[j]);
+ }
+ }
+ return exportedSymbols;
+}
+function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, numberOfSymbolInstances, stripSize, inputSymbols, symbolCodeLength, transposed, dsOffset, referenceCorner, combinationOperator, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, logStripSize, huffmanInput) {
+ if (huffman && refinement) {
+ throw new Jbig2Error("refinement with Huffman is not supported");
+ }
+ const bitmap = [];
+ let i, row;
+ for (i = 0; i < height; i++) {
+ row = new Uint8Array(width);
+ if (defaultPixelValue) {
+ for (let j = 0; j < width; j++) {
+ row[j] = defaultPixelValue;
+ }
+ }
+ bitmap.push(row);
+ }
+ const decoder = decodingContext.decoder;
+ const contextCache = decodingContext.contextCache;
+ let stripT = huffman ? -huffmanTables.tableDeltaT.decode(huffmanInput) : -decodeInteger(contextCache, "IADT", decoder);
+ let firstS = 0;
+ i = 0;
+ while (i < numberOfSymbolInstances) {
+ const deltaT = huffman ? huffmanTables.tableDeltaT.decode(huffmanInput) : decodeInteger(contextCache, "IADT", decoder);
+ stripT += deltaT;
+ const deltaFirstS = huffman ? huffmanTables.tableFirstS.decode(huffmanInput) : decodeInteger(contextCache, "IAFS", decoder);
+ firstS += deltaFirstS;
+ let currentS = firstS;
+ do {
+ let currentT = 0;
+ if (stripSize > 1) {
+ currentT = huffman ? huffmanInput.readBits(logStripSize) : decodeInteger(contextCache, "IAIT", decoder);
+ }
+ const t = stripSize * stripT + currentT;
+ const symbolId = huffman ? huffmanTables.symbolIDTable.decode(huffmanInput) : decodeIAID(contextCache, decoder, symbolCodeLength);
+ const applyRefinement = refinement && (huffman ? huffmanInput.readBit() : decodeInteger(contextCache, "IARI", decoder));
+ let symbolBitmap = inputSymbols[symbolId];
+ let symbolWidth = symbolBitmap[0].length;
+ let symbolHeight = symbolBitmap.length;
+ if (applyRefinement) {
+ const rdw = decodeInteger(contextCache, "IARDW", decoder);
+ const rdh = decodeInteger(contextCache, "IARDH", decoder);
+ const rdx = decodeInteger(contextCache, "IARDX", decoder);
+ const rdy = decodeInteger(contextCache, "IARDY", decoder);
+ symbolWidth += rdw;
+ symbolHeight += rdh;
+ symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, (rdh >> 1) + rdy, false, refinementAt, decodingContext);
+ }
+ const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1);
+ const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0);
+ let s2, t2, symbolRow;
+ if (transposed) {
+ for (s2 = 0; s2 < symbolHeight; s2++) {
+ row = bitmap[offsetS + s2];
+ if (!row) {
+ continue;
+ }
+ symbolRow = symbolBitmap[s2];
+ const maxWidth = Math.min(width - offsetT, symbolWidth);
+ switch (combinationOperator) {
+ case 0:
+ for (t2 = 0; t2 < maxWidth; t2++) {
+ row[offsetT + t2] |= symbolRow[t2];
+ }
+ break;
+ case 2:
+ for (t2 = 0; t2 < maxWidth; t2++) {
+ row[offsetT + t2] ^= symbolRow[t2];
+ }
+ break;
+ default:
+ throw new Jbig2Error(`operator ${combinationOperator} is not supported`);
+ }
+ }
+ currentS += symbolHeight - 1;
+ } else {
+ for (t2 = 0; t2 < symbolHeight; t2++) {
+ row = bitmap[offsetT + t2];
+ if (!row) {
+ continue;
+ }
+ symbolRow = symbolBitmap[t2];
+ switch (combinationOperator) {
+ case 0:
+ for (s2 = 0; s2 < symbolWidth; s2++) {
+ row[offsetS + s2] |= symbolRow[s2];
+ }
+ break;
+ case 2:
+ for (s2 = 0; s2 < symbolWidth; s2++) {
+ row[offsetS + s2] ^= symbolRow[s2];
+ }
+ break;
+ default:
+ throw new Jbig2Error(`operator ${combinationOperator} is not supported`);
+ }
+ }
+ currentS += symbolWidth - 1;
+ }
+ i++;
+ const deltaS = huffman ? huffmanTables.tableDeltaS.decode(huffmanInput) : decodeInteger(contextCache, "IADS", decoder);
+ if (deltaS === null) {
+ break;
+ }
+ currentS += deltaS + dsOffset;
+ } while (true);
+ }
+ return bitmap;
+}
+function decodePatternDictionary(mmr, patternWidth, patternHeight, maxPatternIndex, template, decodingContext) {
+ const at = [];
+ if (!mmr) {
+ at.push({
+ x: -patternWidth,
+ y: 0
+ });
+ if (template === 0) {
+ at.push({
+ x: -3,
+ y: -1
+ }, {
+ x: 2,
+ y: -2
+ }, {
+ x: -2,
+ y: -2
+ });
+ }
+ }
+ const collectiveWidth = (maxPatternIndex + 1) * patternWidth;
+ const collectiveBitmap = decodeBitmap(mmr, collectiveWidth, patternHeight, template, false, null, at, decodingContext);
+ const patterns = [];
+ for (let i = 0; i <= maxPatternIndex; i++) {
+ const patternBitmap = [];
+ const xMin = patternWidth * i;
+ const xMax = xMin + patternWidth;
+ for (let y = 0; y < patternHeight; y++) {
+ patternBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
+ }
+ patterns.push(patternBitmap);
+ }
+ return patterns;
+}
+function decodeHalftoneRegion(mmr, patterns, template, regionWidth, regionHeight, defaultPixelValue, enableSkip, combinationOperator, gridWidth, gridHeight, gridOffsetX, gridOffsetY, gridVectorX, gridVectorY, decodingContext) {
+ const skip = null;
+ if (enableSkip) {
+ throw new Jbig2Error("skip is not supported");
+ }
+ if (combinationOperator !== 0) {
+ throw new Jbig2Error(`operator "${combinationOperator}" is not supported in halftone region`);
+ }
+ const regionBitmap = [];
+ let i, j, row;
+ for (i = 0; i < regionHeight; i++) {
+ row = new Uint8Array(regionWidth);
+ if (defaultPixelValue) {
+ for (j = 0; j < regionWidth; j++) {
+ row[j] = defaultPixelValue;
+ }
+ }
+ regionBitmap.push(row);
+ }
+ const numberOfPatterns = patterns.length;
+ const pattern0 = patterns[0];
+ const patternWidth = pattern0[0].length,
+ patternHeight = pattern0.length;
+ const bitsPerValue = log2(numberOfPatterns);
+ const at = [];
+ if (!mmr) {
+ at.push({
+ x: template <= 1 ? 3 : 2,
+ y: -1
+ });
+ if (template === 0) {
+ at.push({
+ x: -3,
+ y: -1
+ }, {
+ x: 2,
+ y: -2
+ }, {
+ x: -2,
+ y: -2
+ });
+ }
+ }
+ const grayScaleBitPlanes = [];
+ let mmrInput, bitmap;
+ if (mmr) {
+ mmrInput = new Reader(decodingContext.data, decodingContext.start, decodingContext.end);
+ }
+ for (i = bitsPerValue - 1; i >= 0; i--) {
+ if (mmr) {
+ bitmap = decodeMMRBitmap(mmrInput, gridWidth, gridHeight, true);
+ } else {
+ bitmap = decodeBitmap(false, gridWidth, gridHeight, template, false, skip, at, decodingContext);
+ }
+ grayScaleBitPlanes[i] = bitmap;
+ }
+ let mg, ng, bit, patternIndex, patternBitmap, x, y, patternRow, regionRow;
+ for (mg = 0; mg < gridHeight; mg++) {
+ for (ng = 0; ng < gridWidth; ng++) {
+ bit = 0;
+ patternIndex = 0;
+ for (j = bitsPerValue - 1; j >= 0; j--) {
+ bit ^= grayScaleBitPlanes[j][mg][ng];
+ patternIndex |= bit << j;
+ }
+ patternBitmap = patterns[patternIndex];
+ x = gridOffsetX + mg * gridVectorY + ng * gridVectorX >> 8;
+ y = gridOffsetY + mg * gridVectorX - ng * gridVectorY >> 8;
+ if (x >= 0 && x + patternWidth <= regionWidth && y >= 0 && y + patternHeight <= regionHeight) {
+ for (i = 0; i < patternHeight; i++) {
+ regionRow = regionBitmap[y + i];
+ patternRow = patternBitmap[i];
+ for (j = 0; j < patternWidth; j++) {
+ regionRow[x + j] |= patternRow[j];
+ }
+ }
+ } else {
+ let regionX, regionY;
+ for (i = 0; i < patternHeight; i++) {
+ regionY = y + i;
+ if (regionY < 0 || regionY >= regionHeight) {
+ continue;
+ }
+ regionRow = regionBitmap[regionY];
+ patternRow = patternBitmap[i];
+ for (j = 0; j < patternWidth; j++) {
+ regionX = x + j;
+ if (regionX >= 0 && regionX < regionWidth) {
+ regionRow[regionX] |= patternRow[j];
+ }
+ }
+ }
+ }
+ }
+ }
+ return regionBitmap;
+}
+function readSegmentHeader(data, start) {
+ const segmentHeader = {};
+ segmentHeader.number = readUint32(data, start);
+ const flags = data[start + 4];
+ const segmentType = flags & 0x3f;
+ if (!SegmentTypes[segmentType]) {
+ throw new Jbig2Error("invalid segment type: " + segmentType);
+ }
+ segmentHeader.type = segmentType;
+ segmentHeader.typeName = SegmentTypes[segmentType];
+ segmentHeader.deferredNonRetain = !!(flags & 0x80);
+ const pageAssociationFieldSize = !!(flags & 0x40);
+ const referredFlags = data[start + 5];
+ let referredToCount = referredFlags >> 5 & 7;
+ const retainBits = [referredFlags & 31];
+ let position = start + 6;
+ if (referredFlags === 7) {
+ referredToCount = readUint32(data, position - 1) & 0x1fffffff;
+ position += 3;
+ let bytes = referredToCount + 7 >> 3;
+ retainBits[0] = data[position++];
+ while (--bytes > 0) {
+ retainBits.push(data[position++]);
+ }
+ } else if (referredFlags === 5 || referredFlags === 6) {
+ throw new Jbig2Error("invalid referred-to flags");
+ }
+ segmentHeader.retainBits = retainBits;
+ let referredToSegmentNumberSize = 4;
+ if (segmentHeader.number <= 256) {
+ referredToSegmentNumberSize = 1;
+ } else if (segmentHeader.number <= 65536) {
+ referredToSegmentNumberSize = 2;
+ }
+ const referredTo = [];
+ let i, ii;
+ for (i = 0; i < referredToCount; i++) {
+ let number;
+ if (referredToSegmentNumberSize === 1) {
+ number = data[position];
+ } else if (referredToSegmentNumberSize === 2) {
+ number = readUint16(data, position);
+ } else {
+ number = readUint32(data, position);
+ }
+ referredTo.push(number);
+ position += referredToSegmentNumberSize;
+ }
+ segmentHeader.referredTo = referredTo;
+ if (!pageAssociationFieldSize) {
+ segmentHeader.pageAssociation = data[position++];
+ } else {
+ segmentHeader.pageAssociation = readUint32(data, position);
+ position += 4;
+ }
+ segmentHeader.length = readUint32(data, position);
+ position += 4;
+ if (segmentHeader.length === 0xffffffff) {
+ if (segmentType === 38) {
+ const genericRegionInfo = readRegionSegmentInformation(data, position);
+ const genericRegionSegmentFlags = data[position + RegionSegmentInformationFieldLength];
+ const genericRegionMmr = !!(genericRegionSegmentFlags & 1);
+ const searchPatternLength = 6;
+ const searchPattern = new Uint8Array(searchPatternLength);
+ if (!genericRegionMmr) {
+ searchPattern[0] = 0xff;
+ searchPattern[1] = 0xac;
+ }
+ searchPattern[2] = genericRegionInfo.height >>> 24 & 0xff;
+ searchPattern[3] = genericRegionInfo.height >> 16 & 0xff;
+ searchPattern[4] = genericRegionInfo.height >> 8 & 0xff;
+ searchPattern[5] = genericRegionInfo.height & 0xff;
+ for (i = position, ii = data.length; i < ii; i++) {
+ let j = 0;
+ while (j < searchPatternLength && searchPattern[j] === data[i + j]) {
+ j++;
+ }
+ if (j === searchPatternLength) {
+ segmentHeader.length = i + searchPatternLength;
+ break;
+ }
+ }
+ if (segmentHeader.length === 0xffffffff) {
+ throw new Jbig2Error("segment end was not found");
+ }
+ } else {
+ throw new Jbig2Error("invalid unknown segment length");
+ }
+ }
+ segmentHeader.headerEnd = position;
+ return segmentHeader;
+}
+function readSegments(header, data, start, end) {
+ const segments = [];
+ let position = start;
+ while (position < end) {
+ const segmentHeader = readSegmentHeader(data, position);
+ position = segmentHeader.headerEnd;
+ const segment = {
+ header: segmentHeader,
+ data
+ };
+ if (!header.randomAccess) {
+ segment.start = position;
+ position += segmentHeader.length;
+ segment.end = position;
+ }
+ segments.push(segment);
+ if (segmentHeader.type === 51) {
+ break;
+ }
+ }
+ if (header.randomAccess) {
+ for (let i = 0, ii = segments.length; i < ii; i++) {
+ segments[i].start = position;
+ position += segments[i].header.length;
+ segments[i].end = position;
+ }
+ }
+ return segments;
+}
+function readRegionSegmentInformation(data, start) {
+ return {
+ width: readUint32(data, start),
+ height: readUint32(data, start + 4),
+ x: readUint32(data, start + 8),
+ y: readUint32(data, start + 12),
+ combinationOperator: data[start + 16] & 7
+ };
+}
+const RegionSegmentInformationFieldLength = 17;
+function processSegment(segment, visitor) {
+ const header = segment.header;
+ const data = segment.data,
+ end = segment.end;
+ let position = segment.start;
+ let args, at, i, atLength;
+ switch (header.type) {
+ case 0:
+ const dictionary = {};
+ const dictionaryFlags = readUint16(data, position);
+ dictionary.huffman = !!(dictionaryFlags & 1);
+ dictionary.refinement = !!(dictionaryFlags & 2);
+ dictionary.huffmanDHSelector = dictionaryFlags >> 2 & 3;
+ dictionary.huffmanDWSelector = dictionaryFlags >> 4 & 3;
+ dictionary.bitmapSizeSelector = dictionaryFlags >> 6 & 1;
+ dictionary.aggregationInstancesSelector = dictionaryFlags >> 7 & 1;
+ dictionary.bitmapCodingContextUsed = !!(dictionaryFlags & 256);
+ dictionary.bitmapCodingContextRetained = !!(dictionaryFlags & 512);
+ dictionary.template = dictionaryFlags >> 10 & 3;
+ dictionary.refinementTemplate = dictionaryFlags >> 12 & 1;
+ position += 2;
+ if (!dictionary.huffman) {
+ atLength = dictionary.template === 0 ? 4 : 1;
+ at = [];
+ for (i = 0; i < atLength; i++) {
+ at.push({
+ x: readInt8(data, position),
+ y: readInt8(data, position + 1)
+ });
+ position += 2;
+ }
+ dictionary.at = at;
+ }
+ if (dictionary.refinement && !dictionary.refinementTemplate) {
+ at = [];
+ for (i = 0; i < 2; i++) {
+ at.push({
+ x: readInt8(data, position),
+ y: readInt8(data, position + 1)
+ });
+ position += 2;
+ }
+ dictionary.refinementAt = at;
+ }
+ dictionary.numberOfExportedSymbols = readUint32(data, position);
+ position += 4;
+ dictionary.numberOfNewSymbols = readUint32(data, position);
+ position += 4;
+ args = [dictionary, header.number, header.referredTo, data, position, end];
+ break;
+ case 6:
+ case 7:
+ const textRegion = {};
+ textRegion.info = readRegionSegmentInformation(data, position);
+ position += RegionSegmentInformationFieldLength;
+ const textRegionSegmentFlags = readUint16(data, position);
+ position += 2;
+ textRegion.huffman = !!(textRegionSegmentFlags & 1);
+ textRegion.refinement = !!(textRegionSegmentFlags & 2);
+ textRegion.logStripSize = textRegionSegmentFlags >> 2 & 3;
+ textRegion.stripSize = 1 << textRegion.logStripSize;
+ textRegion.referenceCorner = textRegionSegmentFlags >> 4 & 3;
+ textRegion.transposed = !!(textRegionSegmentFlags & 64);
+ textRegion.combinationOperator = textRegionSegmentFlags >> 7 & 3;
+ textRegion.defaultPixelValue = textRegionSegmentFlags >> 9 & 1;
+ textRegion.dsOffset = textRegionSegmentFlags << 17 >> 27;
+ textRegion.refinementTemplate = textRegionSegmentFlags >> 15 & 1;
+ if (textRegion.huffman) {
+ const textRegionHuffmanFlags = readUint16(data, position);
+ position += 2;
+ textRegion.huffmanFS = textRegionHuffmanFlags & 3;
+ textRegion.huffmanDS = textRegionHuffmanFlags >> 2 & 3;
+ textRegion.huffmanDT = textRegionHuffmanFlags >> 4 & 3;
+ textRegion.huffmanRefinementDW = textRegionHuffmanFlags >> 6 & 3;
+ textRegion.huffmanRefinementDH = textRegionHuffmanFlags >> 8 & 3;
+ textRegion.huffmanRefinementDX = textRegionHuffmanFlags >> 10 & 3;
+ textRegion.huffmanRefinementDY = textRegionHuffmanFlags >> 12 & 3;
+ textRegion.huffmanRefinementSizeSelector = !!(textRegionHuffmanFlags & 0x4000);
+ }
+ if (textRegion.refinement && !textRegion.refinementTemplate) {
+ at = [];
+ for (i = 0; i < 2; i++) {
+ at.push({
+ x: readInt8(data, position),
+ y: readInt8(data, position + 1)
+ });
+ position += 2;
+ }
+ textRegion.refinementAt = at;
+ }
+ textRegion.numberOfSymbolInstances = readUint32(data, position);
+ position += 4;
+ args = [textRegion, header.referredTo, data, position, end];
+ break;
+ case 16:
+ const patternDictionary = {};
+ const patternDictionaryFlags = data[position++];
+ patternDictionary.mmr = !!(patternDictionaryFlags & 1);
+ patternDictionary.template = patternDictionaryFlags >> 1 & 3;
+ patternDictionary.patternWidth = data[position++];
+ patternDictionary.patternHeight = data[position++];
+ patternDictionary.maxPatternIndex = readUint32(data, position);
+ position += 4;
+ args = [patternDictionary, header.number, data, position, end];
+ break;
+ case 22:
+ case 23:
+ const halftoneRegion = {};
+ halftoneRegion.info = readRegionSegmentInformation(data, position);
+ position += RegionSegmentInformationFieldLength;
+ const halftoneRegionFlags = data[position++];
+ halftoneRegion.mmr = !!(halftoneRegionFlags & 1);
+ halftoneRegion.template = halftoneRegionFlags >> 1 & 3;
+ halftoneRegion.enableSkip = !!(halftoneRegionFlags & 8);
+ halftoneRegion.combinationOperator = halftoneRegionFlags >> 4 & 7;
+ halftoneRegion.defaultPixelValue = halftoneRegionFlags >> 7 & 1;
+ halftoneRegion.gridWidth = readUint32(data, position);
+ position += 4;
+ halftoneRegion.gridHeight = readUint32(data, position);
+ position += 4;
+ halftoneRegion.gridOffsetX = readUint32(data, position) & 0xffffffff;
+ position += 4;
+ halftoneRegion.gridOffsetY = readUint32(data, position) & 0xffffffff;
+ position += 4;
+ halftoneRegion.gridVectorX = readUint16(data, position);
+ position += 2;
+ halftoneRegion.gridVectorY = readUint16(data, position);
+ position += 2;
+ args = [halftoneRegion, header.referredTo, data, position, end];
+ break;
+ case 38:
+ case 39:
+ const genericRegion = {};
+ genericRegion.info = readRegionSegmentInformation(data, position);
+ position += RegionSegmentInformationFieldLength;
+ const genericRegionSegmentFlags = data[position++];
+ genericRegion.mmr = !!(genericRegionSegmentFlags & 1);
+ genericRegion.template = genericRegionSegmentFlags >> 1 & 3;
+ genericRegion.prediction = !!(genericRegionSegmentFlags & 8);
+ if (!genericRegion.mmr) {
+ atLength = genericRegion.template === 0 ? 4 : 1;
+ at = [];
+ for (i = 0; i < atLength; i++) {
+ at.push({
+ x: readInt8(data, position),
+ y: readInt8(data, position + 1)
+ });
+ position += 2;
+ }
+ genericRegion.at = at;
+ }
+ args = [genericRegion, data, position, end];
+ break;
+ case 48:
+ const pageInfo = {
+ width: readUint32(data, position),
+ height: readUint32(data, position + 4),
+ resolutionX: readUint32(data, position + 8),
+ resolutionY: readUint32(data, position + 12)
+ };
+ if (pageInfo.height === 0xffffffff) {
+ delete pageInfo.height;
+ }
+ const pageSegmentFlags = data[position + 16];
+ readUint16(data, position + 17);
+ pageInfo.lossless = !!(pageSegmentFlags & 1);
+ pageInfo.refinement = !!(pageSegmentFlags & 2);
+ pageInfo.defaultPixelValue = pageSegmentFlags >> 2 & 1;
+ pageInfo.combinationOperator = pageSegmentFlags >> 3 & 3;
+ pageInfo.requiresBuffer = !!(pageSegmentFlags & 32);
+ pageInfo.combinationOperatorOverride = !!(pageSegmentFlags & 64);
+ args = [pageInfo];
+ break;
+ case 49:
+ break;
+ case 50:
+ break;
+ case 51:
+ break;
+ case 53:
+ args = [header.number, data, position, end];
+ break;
+ case 62:
+ break;
+ default:
+ throw new Jbig2Error(`segment type ${header.typeName}(${header.type}) is not implemented`);
+ }
+ const callbackName = "on" + header.typeName;
+ if (callbackName in visitor) {
+ visitor[callbackName].apply(visitor, args);
+ }
+}
+function processSegments(segments, visitor) {
+ for (let i = 0, ii = segments.length; i < ii; i++) {
+ processSegment(segments[i], visitor);
+ }
+}
+function parseJbig2Chunks(chunks) {
+ const visitor = new SimpleSegmentVisitor();
+ for (let i = 0, ii = chunks.length; i < ii; i++) {
+ const chunk = chunks[i];
+ const segments = readSegments({}, chunk.data, chunk.start, chunk.end);
+ processSegments(segments, visitor);
+ }
+ return visitor.buffer;
+}
+function parseJbig2(data) {
+ throw new Error("Not implemented: parseJbig2");
+}
+class SimpleSegmentVisitor {
+ onPageInformation(info) {
+ this.currentPageInfo = info;
+ const rowSize = info.width + 7 >> 3;
+ const buffer = new Uint8ClampedArray(rowSize * info.height);
+ if (info.defaultPixelValue) {
+ buffer.fill(0xff);
+ }
+ this.buffer = buffer;
+ }
+ drawBitmap(regionInfo, bitmap) {
+ const pageInfo = this.currentPageInfo;
+ const width = regionInfo.width,
+ height = regionInfo.height;
+ const rowSize = pageInfo.width + 7 >> 3;
+ const combinationOperator = pageInfo.combinationOperatorOverride ? regionInfo.combinationOperator : pageInfo.combinationOperator;
+ const buffer = this.buffer;
+ const mask0 = 128 >> (regionInfo.x & 7);
+ let offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3);
+ let i, j, mask, offset;
+ switch (combinationOperator) {
+ case 0:
+ for (i = 0; i < height; i++) {
+ mask = mask0;
+ offset = offset0;
+ for (j = 0; j < width; j++) {
+ if (bitmap[i][j]) {
+ buffer[offset] |= mask;
+ }
+ mask >>= 1;
+ if (!mask) {
+ mask = 128;
+ offset++;
+ }
+ }
+ offset0 += rowSize;
+ }
+ break;
+ case 2:
+ for (i = 0; i < height; i++) {
+ mask = mask0;
+ offset = offset0;
+ for (j = 0; j < width; j++) {
+ if (bitmap[i][j]) {
+ buffer[offset] ^= mask;
+ }
+ mask >>= 1;
+ if (!mask) {
+ mask = 128;
+ offset++;
+ }
+ }
+ offset0 += rowSize;
+ }
+ break;
+ default:
+ throw new Jbig2Error(`operator ${combinationOperator} is not supported`);
+ }
+ }
+ onImmediateGenericRegion(region, data, start, end) {
+ const regionInfo = region.info;
+ const decodingContext = new DecodingContext(data, start, end);
+ const bitmap = decodeBitmap(region.mmr, regionInfo.width, regionInfo.height, region.template, region.prediction, null, region.at, decodingContext);
+ this.drawBitmap(regionInfo, bitmap);
+ }
+ onImmediateLosslessGenericRegion() {
+ this.onImmediateGenericRegion(...arguments);
+ }
+ onSymbolDictionary(dictionary, currentSegment, referredSegments, data, start, end) {
+ let huffmanTables, huffmanInput;
+ if (dictionary.huffman) {
+ huffmanTables = getSymbolDictionaryHuffmanTables(dictionary, referredSegments, this.customTables);
+ huffmanInput = new Reader(data, start, end);
+ }
+ let symbols = this.symbols;
+ if (!symbols) {
+ this.symbols = symbols = {};
+ }
+ const inputSymbols = [];
+ for (const referredSegment of referredSegments) {
+ const referredSymbols = symbols[referredSegment];
+ if (referredSymbols) {
+ inputSymbols.push(...referredSymbols);
+ }
+ }
+ const decodingContext = new DecodingContext(data, start, end);
+ symbols[currentSegment] = decodeSymbolDictionary(dictionary.huffman, dictionary.refinement, inputSymbols, dictionary.numberOfNewSymbols, dictionary.numberOfExportedSymbols, huffmanTables, dictionary.template, dictionary.at, dictionary.refinementTemplate, dictionary.refinementAt, decodingContext, huffmanInput);
+ }
+ onImmediateTextRegion(region, referredSegments, data, start, end) {
+ const regionInfo = region.info;
+ let huffmanTables, huffmanInput;
+ const symbols = this.symbols;
+ const inputSymbols = [];
+ for (const referredSegment of referredSegments) {
+ const referredSymbols = symbols[referredSegment];
+ if (referredSymbols) {
+ inputSymbols.push(...referredSymbols);
+ }
+ }
+ const symbolCodeLength = log2(inputSymbols.length);
+ if (region.huffman) {
+ huffmanInput = new Reader(data, start, end);
+ huffmanTables = getTextRegionHuffmanTables(region, referredSegments, this.customTables, inputSymbols.length, huffmanInput);
+ }
+ const decodingContext = new DecodingContext(data, start, end);
+ const bitmap = decodeTextRegion(region.huffman, region.refinement, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.numberOfSymbolInstances, region.stripSize, inputSymbols, symbolCodeLength, region.transposed, region.dsOffset, region.referenceCorner, region.combinationOperator, huffmanTables, region.refinementTemplate, region.refinementAt, decodingContext, region.logStripSize, huffmanInput);
+ this.drawBitmap(regionInfo, bitmap);
+ }
+ onImmediateLosslessTextRegion() {
+ this.onImmediateTextRegion(...arguments);
+ }
+ onPatternDictionary(dictionary, currentSegment, data, start, end) {
+ let patterns = this.patterns;
+ if (!patterns) {
+ this.patterns = patterns = {};
+ }
+ const decodingContext = new DecodingContext(data, start, end);
+ patterns[currentSegment] = decodePatternDictionary(dictionary.mmr, dictionary.patternWidth, dictionary.patternHeight, dictionary.maxPatternIndex, dictionary.template, decodingContext);
+ }
+ onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
+ const patterns = this.patterns[referredSegments[0]];
+ const regionInfo = region.info;
+ const decodingContext = new DecodingContext(data, start, end);
+ const bitmap = decodeHalftoneRegion(region.mmr, patterns, region.template, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.enableSkip, region.combinationOperator, region.gridWidth, region.gridHeight, region.gridOffsetX, region.gridOffsetY, region.gridVectorX, region.gridVectorY, decodingContext);
+ this.drawBitmap(regionInfo, bitmap);
+ }
+ onImmediateLosslessHalftoneRegion() {
+ this.onImmediateHalftoneRegion(...arguments);
+ }
+ onTables(currentSegment, data, start, end) {
+ let customTables = this.customTables;
+ if (!customTables) {
+ this.customTables = customTables = {};
+ }
+ customTables[currentSegment] = decodeTablesSegment(data, start, end);
+ }
+}
+class HuffmanLine {
+ constructor(lineData) {
+ if (lineData.length === 2) {
+ this.isOOB = true;
+ this.rangeLow = 0;
+ this.prefixLength = lineData[0];
+ this.rangeLength = 0;
+ this.prefixCode = lineData[1];
+ this.isLowerRange = false;
+ } else {
+ this.isOOB = false;
+ this.rangeLow = lineData[0];
+ this.prefixLength = lineData[1];
+ this.rangeLength = lineData[2];
+ this.prefixCode = lineData[3];
+ this.isLowerRange = lineData[4] === "lower";
+ }
+ }
+}
+class HuffmanTreeNode {
+ constructor(line) {
+ this.children = [];
+ if (line) {
+ this.isLeaf = true;
+ this.rangeLength = line.rangeLength;
+ this.rangeLow = line.rangeLow;
+ this.isLowerRange = line.isLowerRange;
+ this.isOOB = line.isOOB;
+ } else {
+ this.isLeaf = false;
+ }
+ }
+ buildTree(line, shift) {
+ const bit = line.prefixCode >> shift & 1;
+ if (shift <= 0) {
+ this.children[bit] = new HuffmanTreeNode(line);
+ } else {
+ let node = this.children[bit];
+ if (!node) {
+ this.children[bit] = node = new HuffmanTreeNode(null);
+ }
+ node.buildTree(line, shift - 1);
+ }
+ }
+ decodeNode(reader) {
+ if (this.isLeaf) {
+ if (this.isOOB) {
+ return null;
+ }
+ const htOffset = reader.readBits(this.rangeLength);
+ return this.rangeLow + (this.isLowerRange ? -htOffset : htOffset);
+ }
+ const node = this.children[reader.readBit()];
+ if (!node) {
+ throw new Jbig2Error("invalid Huffman data");
+ }
+ return node.decodeNode(reader);
+ }
+}
+class HuffmanTable {
+ constructor(lines, prefixCodesDone) {
+ if (!prefixCodesDone) {
+ this.assignPrefixCodes(lines);
+ }
+ this.rootNode = new HuffmanTreeNode(null);
+ for (let i = 0, ii = lines.length; i < ii; i++) {
+ const line = lines[i];
+ if (line.prefixLength > 0) {
+ this.rootNode.buildTree(line, line.prefixLength - 1);
+ }
+ }
+ }
+ decode(reader) {
+ return this.rootNode.decodeNode(reader);
+ }
+ assignPrefixCodes(lines) {
+ const linesLength = lines.length;
+ let prefixLengthMax = 0;
+ for (let i = 0; i < linesLength; i++) {
+ prefixLengthMax = Math.max(prefixLengthMax, lines[i].prefixLength);
+ }
+ const histogram = new Uint32Array(prefixLengthMax + 1);
+ for (let i = 0; i < linesLength; i++) {
+ histogram[lines[i].prefixLength]++;
+ }
+ let currentLength = 1,
+ firstCode = 0,
+ currentCode,
+ currentTemp,
+ line;
+ histogram[0] = 0;
+ while (currentLength <= prefixLengthMax) {
+ firstCode = firstCode + histogram[currentLength - 1] << 1;
+ currentCode = firstCode;
+ currentTemp = 0;
+ while (currentTemp < linesLength) {
+ line = lines[currentTemp];
+ if (line.prefixLength === currentLength) {
+ line.prefixCode = currentCode;
+ currentCode++;
+ }
+ currentTemp++;
+ }
+ currentLength++;
+ }
+ }
+}
+function decodeTablesSegment(data, start, end) {
+ const flags = data[start];
+ const lowestValue = readUint32(data, start + 1) & 0xffffffff;
+ const highestValue = readUint32(data, start + 5) & 0xffffffff;
+ const reader = new Reader(data, start + 9, end);
+ const prefixSizeBits = (flags >> 1 & 7) + 1;
+ const rangeSizeBits = (flags >> 4 & 7) + 1;
+ const lines = [];
+ let prefixLength,
+ rangeLength,
+ currentRangeLow = lowestValue;
+ do {
+ prefixLength = reader.readBits(prefixSizeBits);
+ rangeLength = reader.readBits(rangeSizeBits);
+ lines.push(new HuffmanLine([currentRangeLow, prefixLength, rangeLength, 0]));
+ currentRangeLow += 1 << rangeLength;
+ } while (currentRangeLow < highestValue);
+ prefixLength = reader.readBits(prefixSizeBits);
+ lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"]));
+ prefixLength = reader.readBits(prefixSizeBits);
+ lines.push(new HuffmanLine([highestValue, prefixLength, 32, 0]));
+ if (flags & 1) {
+ prefixLength = reader.readBits(prefixSizeBits);
+ lines.push(new HuffmanLine([prefixLength, 0]));
+ }
+ return new HuffmanTable(lines, false);
+}
+const standardTablesCache = {};
+function getStandardTable(number) {
+ let table = standardTablesCache[number];
+ if (table) {
+ return table;
+ }
+ let lines;
+ switch (number) {
+ case 1:
+ lines = [[0, 1, 4, 0x0], [16, 2, 8, 0x2], [272, 3, 16, 0x6], [65808, 3, 32, 0x7]];
+ break;
+ case 2:
+ lines = [[0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [75, 6, 32, 0x3e], [6, 0x3f]];
+ break;
+ case 3:
+ lines = [[-256, 8, 8, 0xfe], [0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [-257, 8, 32, 0xff, "lower"], [75, 7, 32, 0x7e], [6, 0x3e]];
+ break;
+ case 4:
+ lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [76, 5, 32, 0x1f]];
+ break;
+ case 5:
+ lines = [[-255, 7, 8, 0x7e], [1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [-256, 7, 32, 0x7f, "lower"], [76, 6, 32, 0x3e]];
+ break;
+ case 6:
+ lines = [[-2048, 5, 10, 0x1c], [-1024, 4, 9, 0x8], [-512, 4, 8, 0x9], [-256, 4, 7, 0xa], [-128, 5, 6, 0x1d], [-64, 5, 5, 0x1e], [-32, 4, 5, 0xb], [0, 2, 7, 0x0], [128, 3, 7, 0x2], [256, 3, 8, 0x3], [512, 4, 9, 0xc], [1024, 4, 10, 0xd], [-2049, 6, 32, 0x3e, "lower"], [2048, 6, 32, 0x3f]];
+ break;
+ case 7:
+ lines = [[-1024, 4, 9, 0x8], [-512, 3, 8, 0x0], [-256, 4, 7, 0x9], [-128, 5, 6, 0x1a], [-64, 5, 5, 0x1b], [-32, 4, 5, 0xa], [0, 4, 5, 0xb], [32, 5, 5, 0x1c], [64, 5, 6, 0x1d], [128, 4, 7, 0xc], [256, 3, 8, 0x1], [512, 3, 9, 0x2], [1024, 3, 10, 0x3], [-1025, 5, 32, 0x1e, "lower"], [2048, 5, 32, 0x1f]];
+ break;
+ case 8:
+ lines = [[-15, 8, 3, 0xfc], [-7, 9, 1, 0x1fc], [-5, 8, 1, 0xfd], [-3, 9, 0, 0x1fd], [-2, 7, 0, 0x7c], [-1, 4, 0, 0xa], [0, 2, 1, 0x0], [2, 5, 0, 0x1a], [3, 6, 0, 0x3a], [4, 3, 4, 0x4], [20, 6, 1, 0x3b], [22, 4, 4, 0xb], [38, 4, 5, 0xc], [70, 5, 6, 0x1b], [134, 5, 7, 0x1c], [262, 6, 7, 0x3c], [390, 7, 8, 0x7d], [646, 6, 10, 0x3d], [-16, 9, 32, 0x1fe, "lower"], [1670, 9, 32, 0x1ff], [2, 0x1]];
+ break;
+ case 9:
+ lines = [[-31, 8, 4, 0xfc], [-15, 9, 2, 0x1fc], [-11, 8, 2, 0xfd], [-7, 9, 1, 0x1fd], [-5, 7, 1, 0x7c], [-3, 4, 1, 0xa], [-1, 3, 1, 0x2], [1, 3, 1, 0x3], [3, 5, 1, 0x1a], [5, 6, 1, 0x3a], [7, 3, 5, 0x4], [39, 6, 2, 0x3b], [43, 4, 5, 0xb], [75, 4, 6, 0xc], [139, 5, 7, 0x1b], [267, 5, 8, 0x1c], [523, 6, 8, 0x3c], [779, 7, 9, 0x7d], [1291, 6, 11, 0x3d], [-32, 9, 32, 0x1fe, "lower"], [3339, 9, 32, 0x1ff], [2, 0x0]];
+ break;
+ case 10:
+ lines = [[-21, 7, 4, 0x7a], [-5, 8, 0, 0xfc], [-4, 7, 0, 0x7b], [-3, 5, 0, 0x18], [-2, 2, 2, 0x0], [2, 5, 0, 0x19], [3, 6, 0, 0x36], [4, 7, 0, 0x7c], [5, 8, 0, 0xfd], [6, 2, 6, 0x1], [70, 5, 5, 0x1a], [102, 6, 5, 0x37], [134, 6, 6, 0x38], [198, 6, 7, 0x39], [326, 6, 8, 0x3a], [582, 6, 9, 0x3b], [1094, 6, 10, 0x3c], [2118, 7, 11, 0x7d], [-22, 8, 32, 0xfe, "lower"], [4166, 8, 32, 0xff], [2, 0x2]];
+ break;
+ case 11:
+ lines = [[1, 1, 0, 0x0], [2, 2, 1, 0x2], [4, 4, 0, 0xc], [5, 4, 1, 0xd], [7, 5, 1, 0x1c], [9, 5, 2, 0x1d], [13, 6, 2, 0x3c], [17, 7, 2, 0x7a], [21, 7, 3, 0x7b], [29, 7, 4, 0x7c], [45, 7, 5, 0x7d], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]];
+ break;
+ case 12:
+ lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 1, 0x6], [5, 5, 0, 0x1c], [6, 5, 1, 0x1d], [8, 6, 1, 0x3c], [10, 7, 0, 0x7a], [11, 7, 1, 0x7b], [13, 7, 2, 0x7c], [17, 7, 3, 0x7d], [25, 7, 4, 0x7e], [41, 8, 5, 0xfe], [73, 8, 32, 0xff]];
+ break;
+ case 13:
+ lines = [[1, 1, 0, 0x0], [2, 3, 0, 0x4], [3, 4, 0, 0xc], [4, 5, 0, 0x1c], [5, 4, 1, 0xd], [7, 3, 3, 0x5], [15, 6, 1, 0x3a], [17, 6, 2, 0x3b], [21, 6, 3, 0x3c], [29, 6, 4, 0x3d], [45, 6, 5, 0x3e], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]];
+ break;
+ case 14:
+ lines = [[-2, 3, 0, 0x4], [-1, 3, 0, 0x5], [0, 1, 0, 0x0], [1, 3, 0, 0x6], [2, 3, 0, 0x7]];
+ break;
+ case 15:
+ lines = [[-24, 7, 4, 0x7c], [-8, 6, 2, 0x3c], [-4, 5, 1, 0x1c], [-2, 4, 0, 0xc], [-1, 3, 0, 0x4], [0, 1, 0, 0x0], [1, 3, 0, 0x5], [2, 4, 0, 0xd], [3, 5, 1, 0x1d], [5, 6, 2, 0x3d], [9, 7, 4, 0x7d], [-25, 7, 32, 0x7e, "lower"], [25, 7, 32, 0x7f]];
+ break;
+ default:
+ throw new Jbig2Error(`standard table B.${number} does not exist`);
+ }
+ for (let i = 0, ii = lines.length; i < ii; i++) {
+ lines[i] = new HuffmanLine(lines[i]);
+ }
+ table = new HuffmanTable(lines, true);
+ standardTablesCache[number] = table;
+ return table;
+}
+class Reader {
+ constructor(data, start, end) {
+ this.data = data;
+ this.start = start;
+ this.end = end;
+ this.position = start;
+ this.shift = -1;
+ this.currentByte = 0;
+ }
+ readBit() {
+ if (this.shift < 0) {
+ if (this.position >= this.end) {
+ throw new Jbig2Error("end of data while reading bit");
+ }
+ this.currentByte = this.data[this.position++];
+ this.shift = 7;
+ }
+ const bit = this.currentByte >> this.shift & 1;
+ this.shift--;
+ return bit;
+ }
+ readBits(numBits) {
+ let result = 0,
+ i;
+ for (i = numBits - 1; i >= 0; i--) {
+ result |= this.readBit() << i;
+ }
+ return result;
+ }
+ byteAlign() {
+ this.shift = -1;
+ }
+ next() {
+ if (this.position >= this.end) {
+ return -1;
+ }
+ return this.data[this.position++];
+ }
+}
+function getCustomHuffmanTable(index, referredTo, customTables) {
+ let currentIndex = 0;
+ for (let i = 0, ii = referredTo.length; i < ii; i++) {
+ const table = customTables[referredTo[i]];
+ if (table) {
+ if (index === currentIndex) {
+ return table;
+ }
+ currentIndex++;
+ }
+ }
+ throw new Jbig2Error("can't find custom Huffman table");
+}
+function getTextRegionHuffmanTables(textRegion, referredTo, customTables, numberOfSymbols, reader) {
+ const codes = [];
+ for (let i = 0; i <= 34; i++) {
+ const codeLength = reader.readBits(4);
+ codes.push(new HuffmanLine([i, codeLength, 0, 0]));
+ }
+ const runCodesTable = new HuffmanTable(codes, false);
+ codes.length = 0;
+ for (let i = 0; i < numberOfSymbols;) {
+ const codeLength = runCodesTable.decode(reader);
+ if (codeLength >= 32) {
+ let repeatedLength, numberOfRepeats, j;
+ switch (codeLength) {
+ case 32:
+ if (i === 0) {
+ throw new Jbig2Error("no previous value in symbol ID table");
+ }
+ numberOfRepeats = reader.readBits(2) + 3;
+ repeatedLength = codes[i - 1].prefixLength;
+ break;
+ case 33:
+ numberOfRepeats = reader.readBits(3) + 3;
+ repeatedLength = 0;
+ break;
+ case 34:
+ numberOfRepeats = reader.readBits(7) + 11;
+ repeatedLength = 0;
+ break;
+ default:
+ throw new Jbig2Error("invalid code length in symbol ID table");
+ }
+ for (j = 0; j < numberOfRepeats; j++) {
+ codes.push(new HuffmanLine([i, repeatedLength, 0, 0]));
+ i++;
+ }
+ } else {
+ codes.push(new HuffmanLine([i, codeLength, 0, 0]));
+ i++;
+ }
+ }
+ reader.byteAlign();
+ const symbolIDTable = new HuffmanTable(codes, false);
+ let customIndex = 0,
+ tableFirstS,
+ tableDeltaS,
+ tableDeltaT;
+ switch (textRegion.huffmanFS) {
+ case 0:
+ case 1:
+ tableFirstS = getStandardTable(textRegion.huffmanFS + 6);
+ break;
+ case 3:
+ tableFirstS = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ break;
+ default:
+ throw new Jbig2Error("invalid Huffman FS selector");
+ }
+ switch (textRegion.huffmanDS) {
+ case 0:
+ case 1:
+ case 2:
+ tableDeltaS = getStandardTable(textRegion.huffmanDS + 8);
+ break;
+ case 3:
+ tableDeltaS = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ break;
+ default:
+ throw new Jbig2Error("invalid Huffman DS selector");
+ }
+ switch (textRegion.huffmanDT) {
+ case 0:
+ case 1:
+ case 2:
+ tableDeltaT = getStandardTable(textRegion.huffmanDT + 11);
+ break;
+ case 3:
+ tableDeltaT = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ break;
+ default:
+ throw new Jbig2Error("invalid Huffman DT selector");
+ }
+ if (textRegion.refinement) {
+ throw new Jbig2Error("refinement with Huffman is not supported");
+ }
+ return {
+ symbolIDTable,
+ tableFirstS,
+ tableDeltaS,
+ tableDeltaT
+ };
+}
+function getSymbolDictionaryHuffmanTables(dictionary, referredTo, customTables) {
+ let customIndex = 0,
+ tableDeltaHeight,
+ tableDeltaWidth;
+ switch (dictionary.huffmanDHSelector) {
+ case 0:
+ case 1:
+ tableDeltaHeight = getStandardTable(dictionary.huffmanDHSelector + 4);
+ break;
+ case 3:
+ tableDeltaHeight = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ break;
+ default:
+ throw new Jbig2Error("invalid Huffman DH selector");
+ }
+ switch (dictionary.huffmanDWSelector) {
+ case 0:
+ case 1:
+ tableDeltaWidth = getStandardTable(dictionary.huffmanDWSelector + 2);
+ break;
+ case 3:
+ tableDeltaWidth = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ break;
+ default:
+ throw new Jbig2Error("invalid Huffman DW selector");
+ }
+ let tableBitmapSize, tableAggregateInstances;
+ if (dictionary.bitmapSizeSelector) {
+ tableBitmapSize = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ customIndex++;
+ } else {
+ tableBitmapSize = getStandardTable(1);
+ }
+ if (dictionary.aggregationInstancesSelector) {
+ tableAggregateInstances = getCustomHuffmanTable(customIndex, referredTo, customTables);
+ } else {
+ tableAggregateInstances = getStandardTable(1);
+ }
+ return {
+ tableDeltaHeight,
+ tableDeltaWidth,
+ tableBitmapSize,
+ tableAggregateInstances
+ };
+}
+function readUncompressedBitmap(reader, width, height) {
+ const bitmap = [];
+ for (let y = 0; y < height; y++) {
+ const row = new Uint8Array(width);
+ bitmap.push(row);
+ for (let x = 0; x < width; x++) {
+ row[x] = reader.readBit();
+ }
+ reader.byteAlign();
+ }
+ return bitmap;
+}
+function decodeMMRBitmap(input, width, height, endOfBlock) {
+ const params = {
+ K: -1,
+ Columns: width,
+ Rows: height,
+ BlackIs1: true,
+ EndOfBlock: endOfBlock
+ };
+ const decoder = new CCITTFaxDecoder(input, params);
+ const bitmap = [];
+ let currentByte,
+ eof = false;
+ for (let y = 0; y < height; y++) {
+ const row = new Uint8Array(width);
+ bitmap.push(row);
+ let shift = -1;
+ for (let x = 0; x < width; x++) {
+ if (shift < 0) {
+ currentByte = decoder.readNextChar();
+ if (currentByte === -1) {
+ currentByte = 0;
+ eof = true;
+ }
+ shift = 7;
+ }
+ row[x] = currentByte >> shift & 1;
+ shift--;
+ }
+ }
+ if (endOfBlock && !eof) {
+ const lookForEOFLimit = 5;
+ for (let i = 0; i < lookForEOFLimit; i++) {
+ if (decoder.readNextChar() === -1) {
+ break;
+ }
+ }
+ }
+ return bitmap;
+}
+class Jbig2Image {
+ parseChunks(chunks) {
+ return parseJbig2Chunks(chunks);
+ }
+ parse(data) {
+ throw new Error("Not implemented: Jbig2Image.parse");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jbig2_stream.js
+
+
+
+
+
+class Jbig2Stream extends DecodeStream {
+ constructor(stream, maybeLength, params) {
+ super(maybeLength);
+ this.stream = stream;
+ this.dict = stream.dict;
+ this.maybeLength = maybeLength;
+ this.params = params;
+ }
+ get bytes() {
+ return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
+ }
+ ensureBuffer(requested) {}
+ readBlock() {
+ if (this.eof) {
+ return;
+ }
+ const jbig2Image = new Jbig2Image();
+ const chunks = [];
+ if (this.params instanceof Dict) {
+ const globalsStream = this.params.get("JBIG2Globals");
+ if (globalsStream instanceof BaseStream) {
+ const globals = globalsStream.getBytes();
+ chunks.push({
+ data: globals,
+ start: 0,
+ end: globals.length
+ });
+ }
+ }
+ chunks.push({
+ data: this.bytes,
+ start: 0,
+ end: this.bytes.length
+ });
+ const data = jbig2Image.parseChunks(chunks);
+ const dataLength = data.length;
+ for (let i = 0; i < dataLength; i++) {
+ data[i] ^= 0xff;
+ }
+ this.buffer = data;
+ this.bufferLength = dataLength;
+ this.eof = true;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/shared/image_utils.js
+
+function convertToRGBA(params) {
+ switch (params.kind) {
+ case ImageKind.GRAYSCALE_1BPP:
+ return convertBlackAndWhiteToRGBA(params);
+ case ImageKind.RGB_24BPP:
+ return convertRGBToRGBA(params);
+ }
+ return null;
+}
+function convertBlackAndWhiteToRGBA({
+ src,
+ srcPos = 0,
+ dest,
+ width,
+ height,
+ nonBlackColor = 0xffffffff,
+ inverseDecode = false
+}) {
+ const black = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;
+ const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor];
+ const widthInSource = width >> 3;
+ const widthRemainder = width & 7;
+ const srcLength = src.length;
+ dest = new Uint32Array(dest.buffer);
+ let destPos = 0;
+ for (let i = 0; i < height; i++) {
+ for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {
+ const elem = srcPos < srcLength ? src[srcPos] : 255;
+ dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;
+ dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;
+ }
+ if (widthRemainder === 0) {
+ continue;
+ }
+ const elem = srcPos < srcLength ? src[srcPos++] : 255;
+ for (let j = 0; j < widthRemainder; j++) {
+ dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping;
+ }
+ }
+ return {
+ srcPos,
+ destPos
+ };
+}
+function convertRGBToRGBA({
+ src,
+ srcPos = 0,
+ dest,
+ destPos = 0,
+ width,
+ height
+}) {
+ let i = 0;
+ const len32 = src.length >> 2;
+ const src32 = new Uint32Array(src.buffer, srcPos, len32);
+ if (FeatureTest.isLittleEndian) {
+ for (; i < len32 - 2; i += 3, destPos += 4) {
+ const s1 = src32[i];
+ const s2 = src32[i + 1];
+ const s3 = src32[i + 2];
+ dest[destPos] = s1 | 0xff000000;
+ dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000;
+ dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000;
+ dest[destPos + 3] = s3 >>> 8 | 0xff000000;
+ }
+ for (let j = i * 4, jj = src.length; j < jj; j += 3) {
+ dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000;
+ }
+ } else {
+ for (; i < len32 - 2; i += 3, destPos += 4) {
+ const s1 = src32[i];
+ const s2 = src32[i + 1];
+ const s3 = src32[i + 2];
+ dest[destPos] = s1 | 0xff;
+ dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff;
+ dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff;
+ dest[destPos + 3] = s3 << 8 | 0xff;
+ }
+ for (let j = i * 4, jj = src.length; j < jj; j += 3) {
+ dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff;
+ }
+ }
+ return {
+ srcPos,
+ destPos
+ };
+}
+function grayToRGBA(src, dest) {
+ if (FeatureTest.isLittleEndian) {
+ for (let i = 0, ii = src.length; i < ii; i++) {
+ dest[i] = src[i] * 0x10101 | 0xff000000;
+ }
+ } else {
+ for (let i = 0, ii = src.length; i < ii; i++) {
+ dest[i] = src[i] * 0x1010100 | 0x000000ff;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jpg.js
+
+
+
+class JpegError extends BaseException {
+ constructor(msg) {
+ super(`JPEG error: ${msg}`, "JpegError");
+ }
+}
+class DNLMarkerError extends BaseException {
+ constructor(message, scanLines) {
+ super(message, "DNLMarkerError");
+ this.scanLines = scanLines;
+ }
+}
+class EOIMarkerError extends BaseException {
+ constructor(msg) {
+ super(msg, "EOIMarkerError");
+ }
+}
+const dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);
+const dctCos1 = 4017;
+const dctSin1 = 799;
+const dctCos3 = 3406;
+const dctSin3 = 2276;
+const dctCos6 = 1567;
+const dctSin6 = 3784;
+const dctSqrt2 = 5793;
+const dctSqrt1d2 = 2896;
+function buildHuffmanTable(codeLengths, values) {
+ let k = 0,
+ i,
+ j,
+ length = 16;
+ while (length > 0 && !codeLengths[length - 1]) {
+ length--;
+ }
+ const code = [{
+ children: [],
+ index: 0
+ }];
+ let p = code[0],
+ q;
+ for (i = 0; i < length; i++) {
+ for (j = 0; j < codeLengths[i]; j++) {
+ p = code.pop();
+ p.children[p.index] = values[k];
+ while (p.index > 0) {
+ p = code.pop();
+ }
+ p.index++;
+ code.push(p);
+ while (code.length <= i) {
+ code.push(q = {
+ children: [],
+ index: 0
+ });
+ p.children[p.index] = q.children;
+ p = q;
+ }
+ k++;
+ }
+ if (i + 1 < length) {
+ code.push(q = {
+ children: [],
+ index: 0
+ });
+ p.children[p.index] = q.children;
+ p = q;
+ }
+ }
+ return code[0].children;
+}
+function getBlockBufferOffset(component, row, col) {
+ return 64 * ((component.blocksPerLine + 1) * row + col);
+}
+function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive, parseDNLMarker = false) {
+ const mcusPerLine = frame.mcusPerLine;
+ const progressive = frame.progressive;
+ const startOffset = offset;
+ let bitsData = 0,
+ bitsCount = 0;
+ function readBit() {
+ if (bitsCount > 0) {
+ bitsCount--;
+ return bitsData >> bitsCount & 1;
+ }
+ bitsData = data[offset++];
+ if (bitsData === 0xff) {
+ const nextByte = data[offset++];
+ if (nextByte) {
+ if (nextByte === 0xdc && parseDNLMarker) {
+ offset += 2;
+ const scanLines = readUint16(data, offset);
+ offset += 2;
+ if (scanLines > 0 && scanLines !== frame.scanLines) {
+ throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data", scanLines);
+ }
+ } else if (nextByte === 0xd9) {
+ if (parseDNLMarker) {
+ const maybeScanLines = blockRow * (frame.precision === 8 ? 8 : 0);
+ if (maybeScanLines > 0 && Math.round(frame.scanLines / maybeScanLines) >= 5) {
+ throw new DNLMarkerError("Found EOI marker (0xFFD9) while parsing scan data, " + "possibly caused by incorrect `scanLines` parameter", maybeScanLines);
+ }
+ }
+ throw new EOIMarkerError("Found EOI marker (0xFFD9) while parsing scan data");
+ }
+ throw new JpegError(`unexpected marker ${(bitsData << 8 | nextByte).toString(16)}`);
+ }
+ }
+ bitsCount = 7;
+ return bitsData >>> 7;
+ }
+ function decodeHuffman(tree) {
+ let node = tree;
+ while (true) {
+ node = node[readBit()];
+ switch (typeof node) {
+ case "number":
+ return node;
+ case "object":
+ continue;
+ }
+ throw new JpegError("invalid huffman sequence");
+ }
+ }
+ function receive(length) {
+ let n = 0;
+ while (length > 0) {
+ n = n << 1 | readBit();
+ length--;
+ }
+ return n;
+ }
+ function receiveAndExtend(length) {
+ if (length === 1) {
+ return readBit() === 1 ? 1 : -1;
+ }
+ const n = receive(length);
+ if (n >= 1 << length - 1) {
+ return n;
+ }
+ return n + (-1 << length) + 1;
+ }
+ function decodeBaseline(component, blockOffset) {
+ const t = decodeHuffman(component.huffmanTableDC);
+ const diff = t === 0 ? 0 : receiveAndExtend(t);
+ component.blockData[blockOffset] = component.pred += diff;
+ let k = 1;
+ while (k < 64) {
+ const rs = decodeHuffman(component.huffmanTableAC);
+ const s = rs & 15,
+ r = rs >> 4;
+ if (s === 0) {
+ if (r < 15) {
+ break;
+ }
+ k += 16;
+ continue;
+ }
+ k += r;
+ const z = dctZigZag[k];
+ component.blockData[blockOffset + z] = receiveAndExtend(s);
+ k++;
+ }
+ }
+ function decodeDCFirst(component, blockOffset) {
+ const t = decodeHuffman(component.huffmanTableDC);
+ const diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
+ component.blockData[blockOffset] = component.pred += diff;
+ }
+ function decodeDCSuccessive(component, blockOffset) {
+ component.blockData[blockOffset] |= readBit() << successive;
+ }
+ let eobrun = 0;
+ function decodeACFirst(component, blockOffset) {
+ if (eobrun > 0) {
+ eobrun--;
+ return;
+ }
+ let k = spectralStart;
+ const e = spectralEnd;
+ while (k <= e) {
+ const rs = decodeHuffman(component.huffmanTableAC);
+ const s = rs & 15,
+ r = rs >> 4;
+ if (s === 0) {
+ if (r < 15) {
+ eobrun = receive(r) + (1 << r) - 1;
+ break;
+ }
+ k += 16;
+ continue;
+ }
+ k += r;
+ const z = dctZigZag[k];
+ component.blockData[blockOffset + z] = receiveAndExtend(s) * (1 << successive);
+ k++;
+ }
+ }
+ let successiveACState = 0,
+ successiveACNextValue;
+ function decodeACSuccessive(component, blockOffset) {
+ let k = spectralStart;
+ const e = spectralEnd;
+ let r = 0;
+ let s;
+ let rs;
+ while (k <= e) {
+ const offsetZ = blockOffset + dctZigZag[k];
+ const sign = component.blockData[offsetZ] < 0 ? -1 : 1;
+ switch (successiveACState) {
+ case 0:
+ rs = decodeHuffman(component.huffmanTableAC);
+ s = rs & 15;
+ r = rs >> 4;
+ if (s === 0) {
+ if (r < 15) {
+ eobrun = receive(r) + (1 << r);
+ successiveACState = 4;
+ } else {
+ r = 16;
+ successiveACState = 1;
+ }
+ } else {
+ if (s !== 1) {
+ throw new JpegError("invalid ACn encoding");
+ }
+ successiveACNextValue = receiveAndExtend(s);
+ successiveACState = r ? 2 : 3;
+ }
+ continue;
+ case 1:
+ case 2:
+ if (component.blockData[offsetZ]) {
+ component.blockData[offsetZ] += sign * (readBit() << successive);
+ } else {
+ r--;
+ if (r === 0) {
+ successiveACState = successiveACState === 2 ? 3 : 0;
+ }
+ }
+ break;
+ case 3:
+ if (component.blockData[offsetZ]) {
+ component.blockData[offsetZ] += sign * (readBit() << successive);
+ } else {
+ component.blockData[offsetZ] = successiveACNextValue << successive;
+ successiveACState = 0;
+ }
+ break;
+ case 4:
+ if (component.blockData[offsetZ]) {
+ component.blockData[offsetZ] += sign * (readBit() << successive);
+ }
+ break;
+ }
+ k++;
+ }
+ if (successiveACState === 4) {
+ eobrun--;
+ if (eobrun === 0) {
+ successiveACState = 0;
+ }
+ }
+ }
+ let blockRow = 0;
+ function decodeMcu(component, decode, mcu, row, col) {
+ const mcuRow = mcu / mcusPerLine | 0;
+ const mcuCol = mcu % mcusPerLine;
+ blockRow = mcuRow * component.v + row;
+ const blockCol = mcuCol * component.h + col;
+ const blockOffset = getBlockBufferOffset(component, blockRow, blockCol);
+ decode(component, blockOffset);
+ }
+ function decodeBlock(component, decode, mcu) {
+ blockRow = mcu / component.blocksPerLine | 0;
+ const blockCol = mcu % component.blocksPerLine;
+ const blockOffset = getBlockBufferOffset(component, blockRow, blockCol);
+ decode(component, blockOffset);
+ }
+ const componentsLength = components.length;
+ let component, i, j, k, n;
+ let decodeFn;
+ if (progressive) {
+ if (spectralStart === 0) {
+ decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
+ } else {
+ decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive;
+ }
+ } else {
+ decodeFn = decodeBaseline;
+ }
+ let mcu = 0,
+ fileMarker;
+ const mcuExpected = componentsLength === 1 ? components[0].blocksPerLine * components[0].blocksPerColumn : mcusPerLine * frame.mcusPerColumn;
+ let h, v;
+ while (mcu <= mcuExpected) {
+ const mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;
+ if (mcuToRead > 0) {
+ for (i = 0; i < componentsLength; i++) {
+ components[i].pred = 0;
+ }
+ eobrun = 0;
+ if (componentsLength === 1) {
+ component = components[0];
+ for (n = 0; n < mcuToRead; n++) {
+ decodeBlock(component, decodeFn, mcu);
+ mcu++;
+ }
+ } else {
+ for (n = 0; n < mcuToRead; n++) {
+ for (i = 0; i < componentsLength; i++) {
+ component = components[i];
+ h = component.h;
+ v = component.v;
+ for (j = 0; j < v; j++) {
+ for (k = 0; k < h; k++) {
+ decodeMcu(component, decodeFn, mcu, j, k);
+ }
+ }
+ }
+ mcu++;
+ }
+ }
+ }
+ bitsCount = 0;
+ fileMarker = findNextFileMarker(data, offset);
+ if (!fileMarker) {
+ break;
+ }
+ if (fileMarker.invalid) {
+ const partialMsg = mcuToRead > 0 ? "unexpected" : "excessive";
+ warn(`decodeScan - ${partialMsg} MCU data, current marker is: ${fileMarker.invalid}`);
+ offset = fileMarker.offset;
+ }
+ if (fileMarker.marker >= 0xffd0 && fileMarker.marker <= 0xffd7) {
+ offset += 2;
+ } else {
+ break;
+ }
+ }
+ return offset - startOffset;
+}
+function quantizeAndInverse(component, blockBufferOffset, p) {
+ const qt = component.quantizationTable,
+ blockData = component.blockData;
+ let v0, v1, v2, v3, v4, v5, v6, v7;
+ let p0, p1, p2, p3, p4, p5, p6, p7;
+ let t;
+ if (!qt) {
+ throw new JpegError("missing required Quantization Table.");
+ }
+ for (let row = 0; row < 64; row += 8) {
+ p0 = blockData[blockBufferOffset + row];
+ p1 = blockData[blockBufferOffset + row + 1];
+ p2 = blockData[blockBufferOffset + row + 2];
+ p3 = blockData[blockBufferOffset + row + 3];
+ p4 = blockData[blockBufferOffset + row + 4];
+ p5 = blockData[blockBufferOffset + row + 5];
+ p6 = blockData[blockBufferOffset + row + 6];
+ p7 = blockData[blockBufferOffset + row + 7];
+ p0 *= qt[row];
+ if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
+ t = dctSqrt2 * p0 + 512 >> 10;
+ p[row] = t;
+ p[row + 1] = t;
+ p[row + 2] = t;
+ p[row + 3] = t;
+ p[row + 4] = t;
+ p[row + 5] = t;
+ p[row + 6] = t;
+ p[row + 7] = t;
+ continue;
+ }
+ p1 *= qt[row + 1];
+ p2 *= qt[row + 2];
+ p3 *= qt[row + 3];
+ p4 *= qt[row + 4];
+ p5 *= qt[row + 5];
+ p6 *= qt[row + 6];
+ p7 *= qt[row + 7];
+ v0 = dctSqrt2 * p0 + 128 >> 8;
+ v1 = dctSqrt2 * p4 + 128 >> 8;
+ v2 = p2;
+ v3 = p6;
+ v4 = dctSqrt1d2 * (p1 - p7) + 128 >> 8;
+ v7 = dctSqrt1d2 * (p1 + p7) + 128 >> 8;
+ v5 = p3 << 4;
+ v6 = p5 << 4;
+ v0 = v0 + v1 + 1 >> 1;
+ v1 = v0 - v1;
+ t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8;
+ v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8;
+ v3 = t;
+ v4 = v4 + v6 + 1 >> 1;
+ v6 = v4 - v6;
+ v7 = v7 + v5 + 1 >> 1;
+ v5 = v7 - v5;
+ v0 = v0 + v3 + 1 >> 1;
+ v3 = v0 - v3;
+ v1 = v1 + v2 + 1 >> 1;
+ v2 = v1 - v2;
+ t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;
+ v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;
+ v7 = t;
+ t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;
+ v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;
+ v6 = t;
+ p[row] = v0 + v7;
+ p[row + 7] = v0 - v7;
+ p[row + 1] = v1 + v6;
+ p[row + 6] = v1 - v6;
+ p[row + 2] = v2 + v5;
+ p[row + 5] = v2 - v5;
+ p[row + 3] = v3 + v4;
+ p[row + 4] = v3 - v4;
+ }
+ for (let col = 0; col < 8; ++col) {
+ p0 = p[col];
+ p1 = p[col + 8];
+ p2 = p[col + 16];
+ p3 = p[col + 24];
+ p4 = p[col + 32];
+ p5 = p[col + 40];
+ p6 = p[col + 48];
+ p7 = p[col + 56];
+ if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
+ t = dctSqrt2 * p0 + 8192 >> 14;
+ if (t < -2040) {
+ t = 0;
+ } else if (t >= 2024) {
+ t = 255;
+ } else {
+ t = t + 2056 >> 4;
+ }
+ blockData[blockBufferOffset + col] = t;
+ blockData[blockBufferOffset + col + 8] = t;
+ blockData[blockBufferOffset + col + 16] = t;
+ blockData[blockBufferOffset + col + 24] = t;
+ blockData[blockBufferOffset + col + 32] = t;
+ blockData[blockBufferOffset + col + 40] = t;
+ blockData[blockBufferOffset + col + 48] = t;
+ blockData[blockBufferOffset + col + 56] = t;
+ continue;
+ }
+ v0 = dctSqrt2 * p0 + 2048 >> 12;
+ v1 = dctSqrt2 * p4 + 2048 >> 12;
+ v2 = p2;
+ v3 = p6;
+ v4 = dctSqrt1d2 * (p1 - p7) + 2048 >> 12;
+ v7 = dctSqrt1d2 * (p1 + p7) + 2048 >> 12;
+ v5 = p3;
+ v6 = p5;
+ v0 = (v0 + v1 + 1 >> 1) + 4112;
+ v1 = v0 - v1;
+ t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12;
+ v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12;
+ v3 = t;
+ v4 = v4 + v6 + 1 >> 1;
+ v6 = v4 - v6;
+ v7 = v7 + v5 + 1 >> 1;
+ v5 = v7 - v5;
+ v0 = v0 + v3 + 1 >> 1;
+ v3 = v0 - v3;
+ v1 = v1 + v2 + 1 >> 1;
+ v2 = v1 - v2;
+ t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12;
+ v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12;
+ v7 = t;
+ t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12;
+ v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12;
+ v6 = t;
+ p0 = v0 + v7;
+ p7 = v0 - v7;
+ p1 = v1 + v6;
+ p6 = v1 - v6;
+ p2 = v2 + v5;
+ p5 = v2 - v5;
+ p3 = v3 + v4;
+ p4 = v3 - v4;
+ if (p0 < 16) {
+ p0 = 0;
+ } else if (p0 >= 4080) {
+ p0 = 255;
+ } else {
+ p0 >>= 4;
+ }
+ if (p1 < 16) {
+ p1 = 0;
+ } else if (p1 >= 4080) {
+ p1 = 255;
+ } else {
+ p1 >>= 4;
+ }
+ if (p2 < 16) {
+ p2 = 0;
+ } else if (p2 >= 4080) {
+ p2 = 255;
+ } else {
+ p2 >>= 4;
+ }
+ if (p3 < 16) {
+ p3 = 0;
+ } else if (p3 >= 4080) {
+ p3 = 255;
+ } else {
+ p3 >>= 4;
+ }
+ if (p4 < 16) {
+ p4 = 0;
+ } else if (p4 >= 4080) {
+ p4 = 255;
+ } else {
+ p4 >>= 4;
+ }
+ if (p5 < 16) {
+ p5 = 0;
+ } else if (p5 >= 4080) {
+ p5 = 255;
+ } else {
+ p5 >>= 4;
+ }
+ if (p6 < 16) {
+ p6 = 0;
+ } else if (p6 >= 4080) {
+ p6 = 255;
+ } else {
+ p6 >>= 4;
+ }
+ if (p7 < 16) {
+ p7 = 0;
+ } else if (p7 >= 4080) {
+ p7 = 255;
+ } else {
+ p7 >>= 4;
+ }
+ blockData[blockBufferOffset + col] = p0;
+ blockData[blockBufferOffset + col + 8] = p1;
+ blockData[blockBufferOffset + col + 16] = p2;
+ blockData[blockBufferOffset + col + 24] = p3;
+ blockData[blockBufferOffset + col + 32] = p4;
+ blockData[blockBufferOffset + col + 40] = p5;
+ blockData[blockBufferOffset + col + 48] = p6;
+ blockData[blockBufferOffset + col + 56] = p7;
+ }
+}
+function buildComponentData(frame, component) {
+ const blocksPerLine = component.blocksPerLine;
+ const blocksPerColumn = component.blocksPerColumn;
+ const computationBuffer = new Int16Array(64);
+ for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
+ for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) {
+ const offset = getBlockBufferOffset(component, blockRow, blockCol);
+ quantizeAndInverse(component, offset, computationBuffer);
+ }
+ }
+ return component.blockData;
+}
+function findNextFileMarker(data, currentPos, startPos = currentPos) {
+ const maxPos = data.length - 1;
+ let newPos = startPos < currentPos ? startPos : currentPos;
+ if (currentPos >= maxPos) {
+ return null;
+ }
+ const currentMarker = readUint16(data, currentPos);
+ if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) {
+ return {
+ invalid: null,
+ marker: currentMarker,
+ offset: currentPos
+ };
+ }
+ let newMarker = readUint16(data, newPos);
+ while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) {
+ if (++newPos >= maxPos) {
+ return null;
+ }
+ newMarker = readUint16(data, newPos);
+ }
+ return {
+ invalid: currentMarker.toString(16),
+ marker: newMarker,
+ offset: newPos
+ };
+}
+class JpegImage {
+ constructor({
+ decodeTransform = null,
+ colorTransform = -1
+ } = {}) {
+ this._decodeTransform = decodeTransform;
+ this._colorTransform = colorTransform;
+ }
+ parse(data, {
+ dnlScanLines = null
+ } = {}) {
+ function readDataBlock() {
+ const length = readUint16(data, offset);
+ offset += 2;
+ let endOffset = offset + length - 2;
+ const fileMarker = findNextFileMarker(data, endOffset, offset);
+ if (fileMarker?.invalid) {
+ warn("readDataBlock - incorrect length, current marker is: " + fileMarker.invalid);
+ endOffset = fileMarker.offset;
+ }
+ const array = data.subarray(offset, endOffset);
+ offset += array.length;
+ return array;
+ }
+ function prepareComponents(frame) {
+ const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
+ const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
+ for (const component of frame.components) {
+ const blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH);
+ const blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / frame.maxV);
+ const blocksPerLineForMcu = mcusPerLine * component.h;
+ const blocksPerColumnForMcu = mcusPerColumn * component.v;
+ const blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
+ component.blockData = new Int16Array(blocksBufferSize);
+ component.blocksPerLine = blocksPerLine;
+ component.blocksPerColumn = blocksPerColumn;
+ }
+ frame.mcusPerLine = mcusPerLine;
+ frame.mcusPerColumn = mcusPerColumn;
+ }
+ let offset = 0;
+ let jfif = null;
+ let adobe = null;
+ let frame, resetInterval;
+ let numSOSMarkers = 0;
+ const quantizationTables = [];
+ const huffmanTablesAC = [],
+ huffmanTablesDC = [];
+ let fileMarker = readUint16(data, offset);
+ offset += 2;
+ if (fileMarker !== 0xffd8) {
+ throw new JpegError("SOI not found");
+ }
+ fileMarker = readUint16(data, offset);
+ offset += 2;
+ markerLoop: while (fileMarker !== 0xffd9) {
+ let i, j, l;
+ switch (fileMarker) {
+ case 0xffe0:
+ case 0xffe1:
+ case 0xffe2:
+ case 0xffe3:
+ case 0xffe4:
+ case 0xffe5:
+ case 0xffe6:
+ case 0xffe7:
+ case 0xffe8:
+ case 0xffe9:
+ case 0xffea:
+ case 0xffeb:
+ case 0xffec:
+ case 0xffed:
+ case 0xffee:
+ case 0xffef:
+ case 0xfffe:
+ const appData = readDataBlock();
+ if (fileMarker === 0xffe0) {
+ if (appData[0] === 0x4a && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) {
+ jfif = {
+ version: {
+ major: appData[5],
+ minor: appData[6]
+ },
+ densityUnits: appData[7],
+ xDensity: appData[8] << 8 | appData[9],
+ yDensity: appData[10] << 8 | appData[11],
+ thumbWidth: appData[12],
+ thumbHeight: appData[13],
+ thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13])
+ };
+ }
+ }
+ if (fileMarker === 0xffee) {
+ if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6f && appData[3] === 0x62 && appData[4] === 0x65) {
+ adobe = {
+ version: appData[5] << 8 | appData[6],
+ flags0: appData[7] << 8 | appData[8],
+ flags1: appData[9] << 8 | appData[10],
+ transformCode: appData[11]
+ };
+ }
+ }
+ break;
+ case 0xffdb:
+ const quantizationTablesLength = readUint16(data, offset);
+ offset += 2;
+ const quantizationTablesEnd = quantizationTablesLength + offset - 2;
+ let z;
+ while (offset < quantizationTablesEnd) {
+ const quantizationTableSpec = data[offset++];
+ const tableData = new Uint16Array(64);
+ if (quantizationTableSpec >> 4 === 0) {
+ for (j = 0; j < 64; j++) {
+ z = dctZigZag[j];
+ tableData[z] = data[offset++];
+ }
+ } else if (quantizationTableSpec >> 4 === 1) {
+ for (j = 0; j < 64; j++) {
+ z = dctZigZag[j];
+ tableData[z] = readUint16(data, offset);
+ offset += 2;
+ }
+ } else {
+ throw new JpegError("DQT - invalid table spec");
+ }
+ quantizationTables[quantizationTableSpec & 15] = tableData;
+ }
+ break;
+ case 0xffc0:
+ case 0xffc1:
+ case 0xffc2:
+ if (frame) {
+ throw new JpegError("Only single frame JPEGs supported");
+ }
+ offset += 2;
+ frame = {};
+ frame.extended = fileMarker === 0xffc1;
+ frame.progressive = fileMarker === 0xffc2;
+ frame.precision = data[offset++];
+ const sofScanLines = readUint16(data, offset);
+ offset += 2;
+ frame.scanLines = dnlScanLines || sofScanLines;
+ frame.samplesPerLine = readUint16(data, offset);
+ offset += 2;
+ frame.components = [];
+ frame.componentIds = {};
+ const componentsCount = data[offset++];
+ let maxH = 0,
+ maxV = 0;
+ for (i = 0; i < componentsCount; i++) {
+ const componentId = data[offset];
+ const h = data[offset + 1] >> 4;
+ const v = data[offset + 1] & 15;
+ if (maxH < h) {
+ maxH = h;
+ }
+ if (maxV < v) {
+ maxV = v;
+ }
+ const qId = data[offset + 2];
+ l = frame.components.push({
+ h,
+ v,
+ quantizationId: qId,
+ quantizationTable: null
+ });
+ frame.componentIds[componentId] = l - 1;
+ offset += 3;
+ }
+ frame.maxH = maxH;
+ frame.maxV = maxV;
+ prepareComponents(frame);
+ break;
+ case 0xffc4:
+ const huffmanLength = readUint16(data, offset);
+ offset += 2;
+ for (i = 2; i < huffmanLength;) {
+ const huffmanTableSpec = data[offset++];
+ const codeLengths = new Uint8Array(16);
+ let codeLengthSum = 0;
+ for (j = 0; j < 16; j++, offset++) {
+ codeLengthSum += codeLengths[j] = data[offset];
+ }
+ const huffmanValues = new Uint8Array(codeLengthSum);
+ for (j = 0; j < codeLengthSum; j++, offset++) {
+ huffmanValues[j] = data[offset];
+ }
+ i += 17 + codeLengthSum;
+ (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);
+ }
+ break;
+ case 0xffdd:
+ offset += 2;
+ resetInterval = readUint16(data, offset);
+ offset += 2;
+ break;
+ case 0xffda:
+ const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;
+ offset += 2;
+ const selectorsCount = data[offset++],
+ components = [];
+ for (i = 0; i < selectorsCount; i++) {
+ const index = data[offset++];
+ const componentIndex = frame.componentIds[index];
+ const component = frame.components[componentIndex];
+ component.index = index;
+ const tableSpec = data[offset++];
+ component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4];
+ component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];
+ components.push(component);
+ }
+ const spectralStart = data[offset++],
+ spectralEnd = data[offset++],
+ successiveApproximation = data[offset++];
+ try {
+ const processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15, parseDNLMarker);
+ offset += processed;
+ } catch (ex) {
+ if (ex instanceof DNLMarkerError) {
+ warn(`${ex.message} -- attempting to re-parse the JPEG image.`);
+ return this.parse(data, {
+ dnlScanLines: ex.scanLines
+ });
+ } else if (ex instanceof EOIMarkerError) {
+ warn(`${ex.message} -- ignoring the rest of the image data.`);
+ break markerLoop;
+ }
+ throw ex;
+ }
+ break;
+ case 0xffdc:
+ offset += 4;
+ break;
+ case 0xffff:
+ if (data[offset] !== 0xff) {
+ offset--;
+ }
+ break;
+ default:
+ const nextFileMarker = findNextFileMarker(data, offset - 2, offset - 3);
+ if (nextFileMarker?.invalid) {
+ warn("JpegImage.parse - unexpected data, current marker is: " + nextFileMarker.invalid);
+ offset = nextFileMarker.offset;
+ break;
+ }
+ if (!nextFileMarker || offset >= data.length - 1) {
+ warn("JpegImage.parse - reached the end of the image data " + "without finding an EOI marker (0xFFD9).");
+ break markerLoop;
+ }
+ throw new JpegError("JpegImage.parse - unknown marker: " + fileMarker.toString(16));
+ }
+ fileMarker = readUint16(data, offset);
+ offset += 2;
+ }
+ if (!frame) {
+ throw new JpegError("JpegImage.parse - no frame data found.");
+ }
+ this.width = frame.samplesPerLine;
+ this.height = frame.scanLines;
+ this.jfif = jfif;
+ this.adobe = adobe;
+ this.components = [];
+ for (const component of frame.components) {
+ const quantizationTable = quantizationTables[component.quantizationId];
+ if (quantizationTable) {
+ component.quantizationTable = quantizationTable;
+ }
+ this.components.push({
+ index: component.index,
+ output: buildComponentData(frame, component),
+ scaleX: component.h / frame.maxH,
+ scaleY: component.v / frame.maxV,
+ blocksPerLine: component.blocksPerLine,
+ blocksPerColumn: component.blocksPerColumn
+ });
+ }
+ this.numComponents = this.components.length;
+ return undefined;
+ }
+ _getLinearizedBlockData(width, height, isSourcePDF = false) {
+ const scaleX = this.width / width,
+ scaleY = this.height / height;
+ let component, componentScaleX, componentScaleY, blocksPerScanline;
+ let x, y, i, j, k;
+ let index;
+ let offset = 0;
+ let output;
+ const numComponents = this.components.length;
+ const dataLength = width * height * numComponents;
+ const data = new Uint8ClampedArray(dataLength);
+ const xScaleBlockOffset = new Uint32Array(width);
+ const mask3LSB = 0xfffffff8;
+ let lastComponentScaleX;
+ for (i = 0; i < numComponents; i++) {
+ component = this.components[i];
+ componentScaleX = component.scaleX * scaleX;
+ componentScaleY = component.scaleY * scaleY;
+ offset = i;
+ output = component.output;
+ blocksPerScanline = component.blocksPerLine + 1 << 3;
+ if (componentScaleX !== lastComponentScaleX) {
+ for (x = 0; x < width; x++) {
+ j = 0 | x * componentScaleX;
+ xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7;
+ }
+ lastComponentScaleX = componentScaleX;
+ }
+ for (y = 0; y < height; y++) {
+ j = 0 | y * componentScaleY;
+ index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3;
+ for (x = 0; x < width; x++) {
+ data[offset] = output[index + xScaleBlockOffset[x]];
+ offset += numComponents;
+ }
+ }
+ }
+ let transform = this._decodeTransform;
+ if (!isSourcePDF && numComponents === 4 && !transform) {
+ transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]);
+ }
+ if (transform) {
+ for (i = 0; i < dataLength;) {
+ for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
+ data[i] = (data[i] * transform[k] >> 8) + transform[k + 1];
+ }
+ }
+ }
+ return data;
+ }
+ get _isColorConversionNeeded() {
+ if (this.adobe) {
+ return !!this.adobe.transformCode;
+ }
+ if (this.numComponents === 3) {
+ if (this._colorTransform === 0) {
+ return false;
+ } else if (this.components[0].index === 0x52 && this.components[1].index === 0x47 && this.components[2].index === 0x42) {
+ return false;
+ }
+ return true;
+ }
+ if (this._colorTransform === 1) {
+ return true;
+ }
+ return false;
+ }
+ _convertYccToRgb(data) {
+ let Y, Cb, Cr;
+ for (let i = 0, length = data.length; i < length; i += 3) {
+ Y = data[i];
+ Cb = data[i + 1];
+ Cr = data[i + 2];
+ data[i] = Y - 179.456 + 1.402 * Cr;
+ data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;
+ data[i + 2] = Y - 226.816 + 1.772 * Cb;
+ }
+ return data;
+ }
+ _convertYccToRgba(data, out) {
+ for (let i = 0, j = 0, length = data.length; i < length; i += 3, j += 4) {
+ const Y = data[i];
+ const Cb = data[i + 1];
+ const Cr = data[i + 2];
+ out[j] = Y - 179.456 + 1.402 * Cr;
+ out[j + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;
+ out[j + 2] = Y - 226.816 + 1.772 * Cb;
+ out[j + 3] = 255;
+ }
+ return out;
+ }
+ _convertYcckToRgb(data) {
+ let Y, Cb, Cr, k;
+ let offset = 0;
+ for (let i = 0, length = data.length; i < length; i += 4) {
+ Y = data[i];
+ Cb = data[i + 1];
+ Cr = data[i + 2];
+ k = data[i + 3];
+ data[offset++] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776);
+ data[offset++] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);
+ data[offset++] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);
+ }
+ return data.subarray(0, offset);
+ }
+ _convertYcckToRgba(data) {
+ for (let i = 0, length = data.length; i < length; i += 4) {
+ const Y = data[i];
+ const Cb = data[i + 1];
+ const Cr = data[i + 2];
+ const k = data[i + 3];
+ data[i] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776);
+ data[i + 1] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);
+ data[i + 2] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);
+ data[i + 3] = 255;
+ }
+ return data;
+ }
+ _convertYcckToCmyk(data) {
+ let Y, Cb, Cr;
+ for (let i = 0, length = data.length; i < length; i += 4) {
+ Y = data[i];
+ Cb = data[i + 1];
+ Cr = data[i + 2];
+ data[i] = 434.456 - Y - 1.402 * Cr;
+ data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr;
+ data[i + 2] = 481.816 - Y - 1.772 * Cb;
+ }
+ return data;
+ }
+ _convertCmykToRgb(data) {
+ let c, m, y, k;
+ let offset = 0;
+ for (let i = 0, length = data.length; i < length; i += 4) {
+ c = data[i];
+ m = data[i + 1];
+ y = data[i + 2];
+ k = data[i + 3];
+ data[offset++] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254);
+ data[offset++] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168);
+ data[offset++] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144);
+ }
+ return data.subarray(0, offset);
+ }
+ _convertCmykToRgba(data) {
+ for (let i = 0, length = data.length; i < length; i += 4) {
+ const c = data[i];
+ const m = data[i + 1];
+ const y = data[i + 2];
+ const k = data[i + 3];
+ data[i] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254);
+ data[i + 1] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168);
+ data[i + 2] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144);
+ data[i + 3] = 255;
+ }
+ return data;
+ }
+ getData({
+ width,
+ height,
+ forceRGBA = false,
+ forceRGB = false,
+ isSourcePDF = false
+ }) {
+ if (this.numComponents > 4) {
+ throw new JpegError("Unsupported color mode");
+ }
+ const data = this._getLinearizedBlockData(width, height, isSourcePDF);
+ if (this.numComponents === 1 && (forceRGBA || forceRGB)) {
+ const len = data.length * (forceRGBA ? 4 : 3);
+ const rgbaData = new Uint8ClampedArray(len);
+ let offset = 0;
+ if (forceRGBA) {
+ grayToRGBA(data, new Uint32Array(rgbaData.buffer));
+ } else {
+ for (const grayColor of data) {
+ rgbaData[offset++] = grayColor;
+ rgbaData[offset++] = grayColor;
+ rgbaData[offset++] = grayColor;
+ }
+ }
+ return rgbaData;
+ } else if (this.numComponents === 3 && this._isColorConversionNeeded) {
+ if (forceRGBA) {
+ const rgbaData = new Uint8ClampedArray(data.length / 3 * 4);
+ return this._convertYccToRgba(data, rgbaData);
+ }
+ return this._convertYccToRgb(data);
+ } else if (this.numComponents === 4) {
+ if (this._isColorConversionNeeded) {
+ if (forceRGBA) {
+ return this._convertYcckToRgba(data);
+ }
+ if (forceRGB) {
+ return this._convertYcckToRgb(data);
+ }
+ return this._convertYcckToCmyk(data);
+ } else if (forceRGBA) {
+ return this._convertCmykToRgba(data);
+ } else if (forceRGB) {
+ return this._convertCmykToRgb(data);
+ }
+ }
+ return data;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jpeg_stream.js
+
+
+
+
+class JpegStream extends DecodeStream {
+ constructor(stream, maybeLength, params) {
+ let ch;
+ while ((ch = stream.getByte()) !== -1) {
+ if (ch === 0xff) {
+ stream.skip(-1);
+ break;
+ }
+ }
+ super(maybeLength);
+ this.stream = stream;
+ this.dict = stream.dict;
+ this.maybeLength = maybeLength;
+ this.params = params;
+ }
+ get bytes() {
+ return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
+ }
+ ensureBuffer(requested) {}
+ readBlock() {
+ if (this.eof) {
+ return;
+ }
+ const jpegOptions = {
+ decodeTransform: undefined,
+ colorTransform: undefined
+ };
+ const decodeArr = this.dict.getArray("D", "Decode");
+ if ((this.forceRGBA || this.forceRGB) && Array.isArray(decodeArr)) {
+ const bitsPerComponent = this.dict.get("BPC", "BitsPerComponent") || 8;
+ const decodeArrLength = decodeArr.length;
+ const transform = new Int32Array(decodeArrLength);
+ let transformNeeded = false;
+ const maxValue = (1 << bitsPerComponent) - 1;
+ for (let i = 0; i < decodeArrLength; i += 2) {
+ transform[i] = (decodeArr[i + 1] - decodeArr[i]) * 256 | 0;
+ transform[i + 1] = decodeArr[i] * maxValue | 0;
+ if (transform[i] !== 256 || transform[i + 1] !== 0) {
+ transformNeeded = true;
+ }
+ }
+ if (transformNeeded) {
+ jpegOptions.decodeTransform = transform;
+ }
+ }
+ if (this.params instanceof Dict) {
+ const colorTransform = this.params.get("ColorTransform");
+ if (Number.isInteger(colorTransform)) {
+ jpegOptions.colorTransform = colorTransform;
+ }
+ }
+ const jpegImage = new JpegImage(jpegOptions);
+ jpegImage.parse(this.bytes);
+ const data = jpegImage.getData({
+ width: this.drawWidth,
+ height: this.drawHeight,
+ forceRGBA: this.forceRGBA,
+ forceRGB: this.forceRGB,
+ isSourcePDF: true
+ });
+ this.buffer = data;
+ this.bufferLength = data.length;
+ this.eof = true;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jpx.js
+
+
+
+class JpxError extends BaseException {
+ constructor(msg) {
+ super(`JPX error: ${msg}`, "JpxError");
+ }
+}
+const SubbandsGainLog2 = {
+ LL: 0,
+ LH: 1,
+ HL: 1,
+ HH: 2
+};
+class JpxImage {
+ constructor() {
+ this.failOnCorruptedImage = false;
+ }
+ parse(data) {
+ const head = readUint16(data, 0);
+ if (head === 0xff4f) {
+ this.parseCodestream(data, 0, data.length);
+ return;
+ }
+ const length = data.length;
+ let position = 0;
+ while (position < length) {
+ let headerSize = 8;
+ let lbox = readUint32(data, position);
+ const tbox = readUint32(data, position + 4);
+ position += headerSize;
+ if (lbox === 1) {
+ lbox = readUint32(data, position) * 4294967296 + readUint32(data, position + 4);
+ position += 8;
+ headerSize += 8;
+ }
+ if (lbox === 0) {
+ lbox = length - position + headerSize;
+ }
+ if (lbox < headerSize) {
+ throw new JpxError("Invalid box field size");
+ }
+ const dataLength = lbox - headerSize;
+ let jumpDataLength = true;
+ switch (tbox) {
+ case 0x6a703268:
+ jumpDataLength = false;
+ break;
+ case 0x636f6c72:
+ const method = data[position];
+ if (method === 1) {
+ const colorspace = readUint32(data, position + 3);
+ switch (colorspace) {
+ case 16:
+ case 17:
+ case 18:
+ break;
+ default:
+ warn("Unknown colorspace " + colorspace);
+ break;
+ }
+ } else if (method === 2) {
+ info("ICC profile not supported");
+ }
+ break;
+ case 0x6a703263:
+ this.parseCodestream(data, position, position + dataLength);
+ break;
+ case 0x6a502020:
+ if (readUint32(data, position) !== 0x0d0a870a) {
+ warn("Invalid JP2 signature");
+ }
+ break;
+ case 0x6a501a1a:
+ case 0x66747970:
+ case 0x72726571:
+ case 0x72657320:
+ case 0x69686472:
+ break;
+ default:
+ const headerType = String.fromCharCode(tbox >> 24 & 0xff, tbox >> 16 & 0xff, tbox >> 8 & 0xff, tbox & 0xff);
+ warn(`Unsupported header type ${tbox} (${headerType}).`);
+ break;
+ }
+ if (jumpDataLength) {
+ position += dataLength;
+ }
+ }
+ }
+ parseImageProperties(stream) {
+ let newByte = stream.getByte();
+ while (newByte >= 0) {
+ const oldByte = newByte;
+ newByte = stream.getByte();
+ const code = oldByte << 8 | newByte;
+ if (code === 0xff51) {
+ stream.skip(4);
+ const Xsiz = stream.getInt32() >>> 0;
+ const Ysiz = stream.getInt32() >>> 0;
+ const XOsiz = stream.getInt32() >>> 0;
+ const YOsiz = stream.getInt32() >>> 0;
+ stream.skip(16);
+ const Csiz = stream.getUint16();
+ this.width = Xsiz - XOsiz;
+ this.height = Ysiz - YOsiz;
+ this.componentsCount = Csiz;
+ this.bitsPerComponent = 8;
+ return;
+ }
+ }
+ throw new JpxError("No size marker found in JPX stream");
+ }
+ parseCodestream(data, start, end) {
+ const context = {};
+ let doNotRecover = false;
+ try {
+ let position = start;
+ while (position + 1 < end) {
+ const code = readUint16(data, position);
+ position += 2;
+ let length = 0,
+ j,
+ sqcd,
+ spqcds,
+ spqcdSize,
+ scalarExpounded,
+ tile;
+ switch (code) {
+ case 0xff4f:
+ context.mainHeader = true;
+ break;
+ case 0xffd9:
+ break;
+ case 0xff51:
+ length = readUint16(data, position);
+ const siz = {};
+ siz.Xsiz = readUint32(data, position + 4);
+ siz.Ysiz = readUint32(data, position + 8);
+ siz.XOsiz = readUint32(data, position + 12);
+ siz.YOsiz = readUint32(data, position + 16);
+ siz.XTsiz = readUint32(data, position + 20);
+ siz.YTsiz = readUint32(data, position + 24);
+ siz.XTOsiz = readUint32(data, position + 28);
+ siz.YTOsiz = readUint32(data, position + 32);
+ const componentsCount = readUint16(data, position + 36);
+ siz.Csiz = componentsCount;
+ const components = [];
+ j = position + 38;
+ for (let i = 0; i < componentsCount; i++) {
+ const component = {
+ precision: (data[j] & 0x7f) + 1,
+ isSigned: !!(data[j] & 0x80),
+ XRsiz: data[j + 1],
+ YRsiz: data[j + 2]
+ };
+ j += 3;
+ calculateComponentDimensions(component, siz);
+ components.push(component);
+ }
+ context.SIZ = siz;
+ context.components = components;
+ calculateTileGrids(context, components);
+ context.QCC = [];
+ context.COC = [];
+ break;
+ case 0xff5c:
+ length = readUint16(data, position);
+ const qcd = {};
+ j = position + 2;
+ sqcd = data[j++];
+ switch (sqcd & 0x1f) {
+ case 0:
+ spqcdSize = 8;
+ scalarExpounded = true;
+ break;
+ case 1:
+ spqcdSize = 16;
+ scalarExpounded = false;
+ break;
+ case 2:
+ spqcdSize = 16;
+ scalarExpounded = true;
+ break;
+ default:
+ throw new Error("Invalid SQcd value " + sqcd);
+ }
+ qcd.noQuantization = spqcdSize === 8;
+ qcd.scalarExpounded = scalarExpounded;
+ qcd.guardBits = sqcd >> 5;
+ spqcds = [];
+ while (j < length + position) {
+ const spqcd = {};
+ if (spqcdSize === 8) {
+ spqcd.epsilon = data[j++] >> 3;
+ spqcd.mu = 0;
+ } else {
+ spqcd.epsilon = data[j] >> 3;
+ spqcd.mu = (data[j] & 0x7) << 8 | data[j + 1];
+ j += 2;
+ }
+ spqcds.push(spqcd);
+ }
+ qcd.SPqcds = spqcds;
+ if (context.mainHeader) {
+ context.QCD = qcd;
+ } else {
+ context.currentTile.QCD = qcd;
+ context.currentTile.QCC = [];
+ }
+ break;
+ case 0xff5d:
+ length = readUint16(data, position);
+ const qcc = {};
+ j = position + 2;
+ let cqcc;
+ if (context.SIZ.Csiz < 257) {
+ cqcc = data[j++];
+ } else {
+ cqcc = readUint16(data, j);
+ j += 2;
+ }
+ sqcd = data[j++];
+ switch (sqcd & 0x1f) {
+ case 0:
+ spqcdSize = 8;
+ scalarExpounded = true;
+ break;
+ case 1:
+ spqcdSize = 16;
+ scalarExpounded = false;
+ break;
+ case 2:
+ spqcdSize = 16;
+ scalarExpounded = true;
+ break;
+ default:
+ throw new Error("Invalid SQcd value " + sqcd);
+ }
+ qcc.noQuantization = spqcdSize === 8;
+ qcc.scalarExpounded = scalarExpounded;
+ qcc.guardBits = sqcd >> 5;
+ spqcds = [];
+ while (j < length + position) {
+ const spqcd = {};
+ if (spqcdSize === 8) {
+ spqcd.epsilon = data[j++] >> 3;
+ spqcd.mu = 0;
+ } else {
+ spqcd.epsilon = data[j] >> 3;
+ spqcd.mu = (data[j] & 0x7) << 8 | data[j + 1];
+ j += 2;
+ }
+ spqcds.push(spqcd);
+ }
+ qcc.SPqcds = spqcds;
+ if (context.mainHeader) {
+ context.QCC[cqcc] = qcc;
+ } else {
+ context.currentTile.QCC[cqcc] = qcc;
+ }
+ break;
+ case 0xff52:
+ length = readUint16(data, position);
+ const cod = {};
+ j = position + 2;
+ const scod = data[j++];
+ cod.entropyCoderWithCustomPrecincts = !!(scod & 1);
+ cod.sopMarkerUsed = !!(scod & 2);
+ cod.ephMarkerUsed = !!(scod & 4);
+ cod.progressionOrder = data[j++];
+ cod.layersCount = readUint16(data, j);
+ j += 2;
+ cod.multipleComponentTransform = data[j++];
+ cod.decompositionLevelsCount = data[j++];
+ cod.xcb = (data[j++] & 0xf) + 2;
+ cod.ycb = (data[j++] & 0xf) + 2;
+ const blockStyle = data[j++];
+ cod.selectiveArithmeticCodingBypass = !!(blockStyle & 1);
+ cod.resetContextProbabilities = !!(blockStyle & 2);
+ cod.terminationOnEachCodingPass = !!(blockStyle & 4);
+ cod.verticallyStripe = !!(blockStyle & 8);
+ cod.predictableTermination = !!(blockStyle & 16);
+ cod.segmentationSymbolUsed = !!(blockStyle & 32);
+ cod.reversibleTransformation = data[j++];
+ if (cod.entropyCoderWithCustomPrecincts) {
+ const precinctsSizes = [];
+ while (j < length + position) {
+ const precinctsSize = data[j++];
+ precinctsSizes.push({
+ PPx: precinctsSize & 0xf,
+ PPy: precinctsSize >> 4
+ });
+ }
+ cod.precinctsSizes = precinctsSizes;
+ }
+ const unsupported = [];
+ if (cod.selectiveArithmeticCodingBypass) {
+ unsupported.push("selectiveArithmeticCodingBypass");
+ }
+ if (cod.terminationOnEachCodingPass) {
+ unsupported.push("terminationOnEachCodingPass");
+ }
+ if (cod.verticallyStripe) {
+ unsupported.push("verticallyStripe");
+ }
+ if (cod.predictableTermination) {
+ unsupported.push("predictableTermination");
+ }
+ if (unsupported.length > 0) {
+ doNotRecover = true;
+ warn(`JPX: Unsupported COD options (${unsupported.join(", ")}).`);
+ }
+ if (context.mainHeader) {
+ context.COD = cod;
+ } else {
+ context.currentTile.COD = cod;
+ context.currentTile.COC = [];
+ }
+ break;
+ case 0xff90:
+ length = readUint16(data, position);
+ tile = {};
+ tile.index = readUint16(data, position + 2);
+ tile.length = readUint32(data, position + 4);
+ tile.dataEnd = tile.length + position - 2;
+ tile.partIndex = data[position + 8];
+ tile.partsCount = data[position + 9];
+ context.mainHeader = false;
+ if (tile.partIndex === 0) {
+ tile.COD = context.COD;
+ tile.COC = context.COC.slice(0);
+ tile.QCD = context.QCD;
+ tile.QCC = context.QCC.slice(0);
+ }
+ context.currentTile = tile;
+ break;
+ case 0xff93:
+ tile = context.currentTile;
+ if (tile.partIndex === 0) {
+ initializeTile(context, tile.index);
+ buildPackets(context);
+ }
+ length = tile.dataEnd - position;
+ parseTilePackets(context, data, position, length);
+ break;
+ case 0xff53:
+ warn("JPX: Codestream code 0xFF53 (COC) is not implemented.");
+ case 0xff55:
+ case 0xff57:
+ case 0xff58:
+ case 0xff64:
+ length = readUint16(data, position);
+ break;
+ default:
+ throw new Error("Unknown codestream code: " + code.toString(16));
+ }
+ position += length;
+ }
+ } catch (e) {
+ if (doNotRecover || this.failOnCorruptedImage) {
+ throw new JpxError(e.message);
+ } else {
+ warn(`JPX: Trying to recover from: "${e.message}".`);
+ }
+ }
+ this.tiles = transformComponents(context);
+ this.width = context.SIZ.Xsiz - context.SIZ.XOsiz;
+ this.height = context.SIZ.Ysiz - context.SIZ.YOsiz;
+ this.componentsCount = context.SIZ.Csiz;
+ }
+}
+function calculateComponentDimensions(component, siz) {
+ component.x0 = Math.ceil(siz.XOsiz / component.XRsiz);
+ component.x1 = Math.ceil(siz.Xsiz / component.XRsiz);
+ component.y0 = Math.ceil(siz.YOsiz / component.YRsiz);
+ component.y1 = Math.ceil(siz.Ysiz / component.YRsiz);
+ component.width = component.x1 - component.x0;
+ component.height = component.y1 - component.y0;
+}
+function calculateTileGrids(context, components) {
+ const siz = context.SIZ;
+ const tiles = [];
+ let tile;
+ const numXtiles = Math.ceil((siz.Xsiz - siz.XTOsiz) / siz.XTsiz);
+ const numYtiles = Math.ceil((siz.Ysiz - siz.YTOsiz) / siz.YTsiz);
+ for (let q = 0; q < numYtiles; q++) {
+ for (let p = 0; p < numXtiles; p++) {
+ tile = {};
+ tile.tx0 = Math.max(siz.XTOsiz + p * siz.XTsiz, siz.XOsiz);
+ tile.ty0 = Math.max(siz.YTOsiz + q * siz.YTsiz, siz.YOsiz);
+ tile.tx1 = Math.min(siz.XTOsiz + (p + 1) * siz.XTsiz, siz.Xsiz);
+ tile.ty1 = Math.min(siz.YTOsiz + (q + 1) * siz.YTsiz, siz.Ysiz);
+ tile.width = tile.tx1 - tile.tx0;
+ tile.height = tile.ty1 - tile.ty0;
+ tile.components = [];
+ tiles.push(tile);
+ }
+ }
+ context.tiles = tiles;
+ const componentsCount = siz.Csiz;
+ for (let i = 0, ii = componentsCount; i < ii; i++) {
+ const component = components[i];
+ for (let j = 0, jj = tiles.length; j < jj; j++) {
+ const tileComponent = {};
+ tile = tiles[j];
+ tileComponent.tcx0 = Math.ceil(tile.tx0 / component.XRsiz);
+ tileComponent.tcy0 = Math.ceil(tile.ty0 / component.YRsiz);
+ tileComponent.tcx1 = Math.ceil(tile.tx1 / component.XRsiz);
+ tileComponent.tcy1 = Math.ceil(tile.ty1 / component.YRsiz);
+ tileComponent.width = tileComponent.tcx1 - tileComponent.tcx0;
+ tileComponent.height = tileComponent.tcy1 - tileComponent.tcy0;
+ tile.components[i] = tileComponent;
+ }
+ }
+}
+function getBlocksDimensions(context, component, r) {
+ const codOrCoc = component.codingStyleParameters;
+ const result = {};
+ if (!codOrCoc.entropyCoderWithCustomPrecincts) {
+ result.PPx = 15;
+ result.PPy = 15;
+ } else {
+ result.PPx = codOrCoc.precinctsSizes[r].PPx;
+ result.PPy = codOrCoc.precinctsSizes[r].PPy;
+ }
+ result.xcb_ = r > 0 ? Math.min(codOrCoc.xcb, result.PPx - 1) : Math.min(codOrCoc.xcb, result.PPx);
+ result.ycb_ = r > 0 ? Math.min(codOrCoc.ycb, result.PPy - 1) : Math.min(codOrCoc.ycb, result.PPy);
+ return result;
+}
+function buildPrecincts(context, resolution, dimensions) {
+ const precinctWidth = 1 << dimensions.PPx;
+ const precinctHeight = 1 << dimensions.PPy;
+ const isZeroRes = resolution.resLevel === 0;
+ const precinctWidthInSubband = 1 << dimensions.PPx + (isZeroRes ? 0 : -1);
+ const precinctHeightInSubband = 1 << dimensions.PPy + (isZeroRes ? 0 : -1);
+ const numprecinctswide = resolution.trx1 > resolution.trx0 ? Math.ceil(resolution.trx1 / precinctWidth) - Math.floor(resolution.trx0 / precinctWidth) : 0;
+ const numprecinctshigh = resolution.try1 > resolution.try0 ? Math.ceil(resolution.try1 / precinctHeight) - Math.floor(resolution.try0 / precinctHeight) : 0;
+ const numprecincts = numprecinctswide * numprecinctshigh;
+ resolution.precinctParameters = {
+ precinctWidth,
+ precinctHeight,
+ numprecinctswide,
+ numprecinctshigh,
+ numprecincts,
+ precinctWidthInSubband,
+ precinctHeightInSubband
+ };
+}
+function buildCodeblocks(context, subband, dimensions) {
+ const xcb_ = dimensions.xcb_;
+ const ycb_ = dimensions.ycb_;
+ const codeblockWidth = 1 << xcb_;
+ const codeblockHeight = 1 << ycb_;
+ const cbx0 = subband.tbx0 >> xcb_;
+ const cby0 = subband.tby0 >> ycb_;
+ const cbx1 = subband.tbx1 + codeblockWidth - 1 >> xcb_;
+ const cby1 = subband.tby1 + codeblockHeight - 1 >> ycb_;
+ const precinctParameters = subband.resolution.precinctParameters;
+ const codeblocks = [];
+ const precincts = [];
+ let i, j, codeblock, precinctNumber;
+ for (j = cby0; j < cby1; j++) {
+ for (i = cbx0; i < cbx1; i++) {
+ codeblock = {
+ cbx: i,
+ cby: j,
+ tbx0: codeblockWidth * i,
+ tby0: codeblockHeight * j,
+ tbx1: codeblockWidth * (i + 1),
+ tby1: codeblockHeight * (j + 1)
+ };
+ codeblock.tbx0_ = Math.max(subband.tbx0, codeblock.tbx0);
+ codeblock.tby0_ = Math.max(subband.tby0, codeblock.tby0);
+ codeblock.tbx1_ = Math.min(subband.tbx1, codeblock.tbx1);
+ codeblock.tby1_ = Math.min(subband.tby1, codeblock.tby1);
+ const pi = Math.floor((codeblock.tbx0_ - subband.tbx0) / precinctParameters.precinctWidthInSubband);
+ const pj = Math.floor((codeblock.tby0_ - subband.tby0) / precinctParameters.precinctHeightInSubband);
+ precinctNumber = pi + pj * precinctParameters.numprecinctswide;
+ codeblock.precinctNumber = precinctNumber;
+ codeblock.subbandType = subband.type;
+ codeblock.Lblock = 3;
+ if (codeblock.tbx1_ <= codeblock.tbx0_ || codeblock.tby1_ <= codeblock.tby0_) {
+ continue;
+ }
+ codeblocks.push(codeblock);
+ let precinct = precincts[precinctNumber];
+ if (precinct !== undefined) {
+ if (i < precinct.cbxMin) {
+ precinct.cbxMin = i;
+ } else if (i > precinct.cbxMax) {
+ precinct.cbxMax = i;
+ }
+ if (j < precinct.cbyMin) {
+ precinct.cbxMin = j;
+ } else if (j > precinct.cbyMax) {
+ precinct.cbyMax = j;
+ }
+ } else {
+ precincts[precinctNumber] = precinct = {
+ cbxMin: i,
+ cbyMin: j,
+ cbxMax: i,
+ cbyMax: j
+ };
+ }
+ codeblock.precinct = precinct;
+ }
+ }
+ subband.codeblockParameters = {
+ codeblockWidth: xcb_,
+ codeblockHeight: ycb_,
+ numcodeblockwide: cbx1 - cbx0 + 1,
+ numcodeblockhigh: cby1 - cby0 + 1
+ };
+ subband.codeblocks = codeblocks;
+ subband.precincts = precincts;
+}
+function createPacket(resolution, precinctNumber, layerNumber) {
+ const precinctCodeblocks = [];
+ const subbands = resolution.subbands;
+ for (let i = 0, ii = subbands.length; i < ii; i++) {
+ const subband = subbands[i];
+ const codeblocks = subband.codeblocks;
+ for (let j = 0, jj = codeblocks.length; j < jj; j++) {
+ const codeblock = codeblocks[j];
+ if (codeblock.precinctNumber !== precinctNumber) {
+ continue;
+ }
+ precinctCodeblocks.push(codeblock);
+ }
+ }
+ return {
+ layerNumber,
+ codeblocks: precinctCodeblocks
+ };
+}
+function LayerResolutionComponentPositionIterator(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const layersCount = tile.codingStyleDefaultParameters.layersCount;
+ const componentsCount = siz.Csiz;
+ let maxDecompositionLevelsCount = 0;
+ for (let q = 0; q < componentsCount; q++) {
+ maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, tile.components[q].codingStyleParameters.decompositionLevelsCount);
+ }
+ let l = 0,
+ r = 0,
+ i = 0,
+ k = 0;
+ this.nextPacket = function JpxImage_nextPacket() {
+ for (; l < layersCount; l++) {
+ for (; r <= maxDecompositionLevelsCount; r++) {
+ for (; i < componentsCount; i++) {
+ const component = tile.components[i];
+ if (r > component.codingStyleParameters.decompositionLevelsCount) {
+ continue;
+ }
+ const resolution = component.resolutions[r];
+ const numprecincts = resolution.precinctParameters.numprecincts;
+ for (; k < numprecincts;) {
+ const packet = createPacket(resolution, k, l);
+ k++;
+ return packet;
+ }
+ k = 0;
+ }
+ i = 0;
+ }
+ r = 0;
+ }
+ throw new JpxError("Out of packets");
+ };
+}
+function ResolutionLayerComponentPositionIterator(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const layersCount = tile.codingStyleDefaultParameters.layersCount;
+ const componentsCount = siz.Csiz;
+ let maxDecompositionLevelsCount = 0;
+ for (let q = 0; q < componentsCount; q++) {
+ maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, tile.components[q].codingStyleParameters.decompositionLevelsCount);
+ }
+ let r = 0,
+ l = 0,
+ i = 0,
+ k = 0;
+ this.nextPacket = function JpxImage_nextPacket() {
+ for (; r <= maxDecompositionLevelsCount; r++) {
+ for (; l < layersCount; l++) {
+ for (; i < componentsCount; i++) {
+ const component = tile.components[i];
+ if (r > component.codingStyleParameters.decompositionLevelsCount) {
+ continue;
+ }
+ const resolution = component.resolutions[r];
+ const numprecincts = resolution.precinctParameters.numprecincts;
+ for (; k < numprecincts;) {
+ const packet = createPacket(resolution, k, l);
+ k++;
+ return packet;
+ }
+ k = 0;
+ }
+ i = 0;
+ }
+ l = 0;
+ }
+ throw new JpxError("Out of packets");
+ };
+}
+function ResolutionPositionComponentLayerIterator(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const layersCount = tile.codingStyleDefaultParameters.layersCount;
+ const componentsCount = siz.Csiz;
+ let l, r, c, p;
+ let maxDecompositionLevelsCount = 0;
+ for (c = 0; c < componentsCount; c++) {
+ const component = tile.components[c];
+ maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, component.codingStyleParameters.decompositionLevelsCount);
+ }
+ const maxNumPrecinctsInLevel = new Int32Array(maxDecompositionLevelsCount + 1);
+ for (r = 0; r <= maxDecompositionLevelsCount; ++r) {
+ let maxNumPrecincts = 0;
+ for (c = 0; c < componentsCount; ++c) {
+ const resolutions = tile.components[c].resolutions;
+ if (r < resolutions.length) {
+ maxNumPrecincts = Math.max(maxNumPrecincts, resolutions[r].precinctParameters.numprecincts);
+ }
+ }
+ maxNumPrecinctsInLevel[r] = maxNumPrecincts;
+ }
+ l = 0;
+ r = 0;
+ c = 0;
+ p = 0;
+ this.nextPacket = function JpxImage_nextPacket() {
+ for (; r <= maxDecompositionLevelsCount; r++) {
+ for (; p < maxNumPrecinctsInLevel[r]; p++) {
+ for (; c < componentsCount; c++) {
+ const component = tile.components[c];
+ if (r > component.codingStyleParameters.decompositionLevelsCount) {
+ continue;
+ }
+ const resolution = component.resolutions[r];
+ const numprecincts = resolution.precinctParameters.numprecincts;
+ if (p >= numprecincts) {
+ continue;
+ }
+ for (; l < layersCount;) {
+ const packet = createPacket(resolution, p, l);
+ l++;
+ return packet;
+ }
+ l = 0;
+ }
+ c = 0;
+ }
+ p = 0;
+ }
+ throw new JpxError("Out of packets");
+ };
+}
+function PositionComponentResolutionLayerIterator(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const layersCount = tile.codingStyleDefaultParameters.layersCount;
+ const componentsCount = siz.Csiz;
+ const precinctsSizes = getPrecinctSizesInImageScale(tile);
+ const precinctsIterationSizes = precinctsSizes;
+ let l = 0,
+ r = 0,
+ c = 0,
+ px = 0,
+ py = 0;
+ this.nextPacket = function JpxImage_nextPacket() {
+ for (; py < precinctsIterationSizes.maxNumHigh; py++) {
+ for (; px < precinctsIterationSizes.maxNumWide; px++) {
+ for (; c < componentsCount; c++) {
+ const component = tile.components[c];
+ const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount;
+ for (; r <= decompositionLevelsCount; r++) {
+ const resolution = component.resolutions[r];
+ const sizeInImageScale = precinctsSizes.components[c].resolutions[r];
+ const k = getPrecinctIndexIfExist(px, py, sizeInImageScale, precinctsIterationSizes, resolution);
+ if (k === null) {
+ continue;
+ }
+ for (; l < layersCount;) {
+ const packet = createPacket(resolution, k, l);
+ l++;
+ return packet;
+ }
+ l = 0;
+ }
+ r = 0;
+ }
+ c = 0;
+ }
+ px = 0;
+ }
+ throw new JpxError("Out of packets");
+ };
+}
+function ComponentPositionResolutionLayerIterator(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const layersCount = tile.codingStyleDefaultParameters.layersCount;
+ const componentsCount = siz.Csiz;
+ const precinctsSizes = getPrecinctSizesInImageScale(tile);
+ let l = 0,
+ r = 0,
+ c = 0,
+ px = 0,
+ py = 0;
+ this.nextPacket = function JpxImage_nextPacket() {
+ for (; c < componentsCount; ++c) {
+ const component = tile.components[c];
+ const precinctsIterationSizes = precinctsSizes.components[c];
+ const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount;
+ for (; py < precinctsIterationSizes.maxNumHigh; py++) {
+ for (; px < precinctsIterationSizes.maxNumWide; px++) {
+ for (; r <= decompositionLevelsCount; r++) {
+ const resolution = component.resolutions[r];
+ const sizeInImageScale = precinctsIterationSizes.resolutions[r];
+ const k = getPrecinctIndexIfExist(px, py, sizeInImageScale, precinctsIterationSizes, resolution);
+ if (k === null) {
+ continue;
+ }
+ for (; l < layersCount;) {
+ const packet = createPacket(resolution, k, l);
+ l++;
+ return packet;
+ }
+ l = 0;
+ }
+ r = 0;
+ }
+ px = 0;
+ }
+ py = 0;
+ }
+ throw new JpxError("Out of packets");
+ };
+}
+function getPrecinctIndexIfExist(pxIndex, pyIndex, sizeInImageScale, precinctIterationSizes, resolution) {
+ const posX = pxIndex * precinctIterationSizes.minWidth;
+ const posY = pyIndex * precinctIterationSizes.minHeight;
+ if (posX % sizeInImageScale.width !== 0 || posY % sizeInImageScale.height !== 0) {
+ return null;
+ }
+ const startPrecinctRowIndex = posY / sizeInImageScale.width * resolution.precinctParameters.numprecinctswide;
+ return posX / sizeInImageScale.height + startPrecinctRowIndex;
+}
+function getPrecinctSizesInImageScale(tile) {
+ const componentsCount = tile.components.length;
+ let minWidth = Number.MAX_VALUE;
+ let minHeight = Number.MAX_VALUE;
+ let maxNumWide = 0;
+ let maxNumHigh = 0;
+ const sizePerComponent = new Array(componentsCount);
+ for (let c = 0; c < componentsCount; c++) {
+ const component = tile.components[c];
+ const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount;
+ const sizePerResolution = new Array(decompositionLevelsCount + 1);
+ let minWidthCurrentComponent = Number.MAX_VALUE;
+ let minHeightCurrentComponent = Number.MAX_VALUE;
+ let maxNumWideCurrentComponent = 0;
+ let maxNumHighCurrentComponent = 0;
+ let scale = 1;
+ for (let r = decompositionLevelsCount; r >= 0; --r) {
+ const resolution = component.resolutions[r];
+ const widthCurrentResolution = scale * resolution.precinctParameters.precinctWidth;
+ const heightCurrentResolution = scale * resolution.precinctParameters.precinctHeight;
+ minWidthCurrentComponent = Math.min(minWidthCurrentComponent, widthCurrentResolution);
+ minHeightCurrentComponent = Math.min(minHeightCurrentComponent, heightCurrentResolution);
+ maxNumWideCurrentComponent = Math.max(maxNumWideCurrentComponent, resolution.precinctParameters.numprecinctswide);
+ maxNumHighCurrentComponent = Math.max(maxNumHighCurrentComponent, resolution.precinctParameters.numprecinctshigh);
+ sizePerResolution[r] = {
+ width: widthCurrentResolution,
+ height: heightCurrentResolution
+ };
+ scale <<= 1;
+ }
+ minWidth = Math.min(minWidth, minWidthCurrentComponent);
+ minHeight = Math.min(minHeight, minHeightCurrentComponent);
+ maxNumWide = Math.max(maxNumWide, maxNumWideCurrentComponent);
+ maxNumHigh = Math.max(maxNumHigh, maxNumHighCurrentComponent);
+ sizePerComponent[c] = {
+ resolutions: sizePerResolution,
+ minWidth: minWidthCurrentComponent,
+ minHeight: minHeightCurrentComponent,
+ maxNumWide: maxNumWideCurrentComponent,
+ maxNumHigh: maxNumHighCurrentComponent
+ };
+ }
+ return {
+ components: sizePerComponent,
+ minWidth,
+ minHeight,
+ maxNumWide,
+ maxNumHigh
+ };
+}
+function buildPackets(context) {
+ const siz = context.SIZ;
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const componentsCount = siz.Csiz;
+ for (let c = 0; c < componentsCount; c++) {
+ const component = tile.components[c];
+ const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount;
+ const resolutions = [];
+ const subbands = [];
+ for (let r = 0; r <= decompositionLevelsCount; r++) {
+ const blocksDimensions = getBlocksDimensions(context, component, r);
+ const resolution = {};
+ const scale = 1 << decompositionLevelsCount - r;
+ resolution.trx0 = Math.ceil(component.tcx0 / scale);
+ resolution.try0 = Math.ceil(component.tcy0 / scale);
+ resolution.trx1 = Math.ceil(component.tcx1 / scale);
+ resolution.try1 = Math.ceil(component.tcy1 / scale);
+ resolution.resLevel = r;
+ buildPrecincts(context, resolution, blocksDimensions);
+ resolutions.push(resolution);
+ let subband;
+ if (r === 0) {
+ subband = {};
+ subband.type = "LL";
+ subband.tbx0 = Math.ceil(component.tcx0 / scale);
+ subband.tby0 = Math.ceil(component.tcy0 / scale);
+ subband.tbx1 = Math.ceil(component.tcx1 / scale);
+ subband.tby1 = Math.ceil(component.tcy1 / scale);
+ subband.resolution = resolution;
+ buildCodeblocks(context, subband, blocksDimensions);
+ subbands.push(subband);
+ resolution.subbands = [subband];
+ } else {
+ const bscale = 1 << decompositionLevelsCount - r + 1;
+ const resolutionSubbands = [];
+ subband = {};
+ subband.type = "HL";
+ subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5);
+ subband.tby0 = Math.ceil(component.tcy0 / bscale);
+ subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5);
+ subband.tby1 = Math.ceil(component.tcy1 / bscale);
+ subband.resolution = resolution;
+ buildCodeblocks(context, subband, blocksDimensions);
+ subbands.push(subband);
+ resolutionSubbands.push(subband);
+ subband = {};
+ subband.type = "LH";
+ subband.tbx0 = Math.ceil(component.tcx0 / bscale);
+ subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5);
+ subband.tbx1 = Math.ceil(component.tcx1 / bscale);
+ subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5);
+ subband.resolution = resolution;
+ buildCodeblocks(context, subband, blocksDimensions);
+ subbands.push(subband);
+ resolutionSubbands.push(subband);
+ subband = {};
+ subband.type = "HH";
+ subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5);
+ subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5);
+ subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5);
+ subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5);
+ subband.resolution = resolution;
+ buildCodeblocks(context, subband, blocksDimensions);
+ subbands.push(subband);
+ resolutionSubbands.push(subband);
+ resolution.subbands = resolutionSubbands;
+ }
+ }
+ component.resolutions = resolutions;
+ component.subbands = subbands;
+ }
+ const progressionOrder = tile.codingStyleDefaultParameters.progressionOrder;
+ switch (progressionOrder) {
+ case 0:
+ tile.packetsIterator = new LayerResolutionComponentPositionIterator(context);
+ break;
+ case 1:
+ tile.packetsIterator = new ResolutionLayerComponentPositionIterator(context);
+ break;
+ case 2:
+ tile.packetsIterator = new ResolutionPositionComponentLayerIterator(context);
+ break;
+ case 3:
+ tile.packetsIterator = new PositionComponentResolutionLayerIterator(context);
+ break;
+ case 4:
+ tile.packetsIterator = new ComponentPositionResolutionLayerIterator(context);
+ break;
+ default:
+ throw new JpxError(`Unsupported progression order ${progressionOrder}`);
+ }
+}
+function parseTilePackets(context, data, offset, dataLength) {
+ let position = 0;
+ let buffer,
+ bufferSize = 0,
+ skipNextBit = false;
+ function readBits(count) {
+ while (bufferSize < count) {
+ const b = data[offset + position];
+ position++;
+ if (skipNextBit) {
+ buffer = buffer << 7 | b;
+ bufferSize += 7;
+ skipNextBit = false;
+ } else {
+ buffer = buffer << 8 | b;
+ bufferSize += 8;
+ }
+ if (b === 0xff) {
+ skipNextBit = true;
+ }
+ }
+ bufferSize -= count;
+ return buffer >>> bufferSize & (1 << count) - 1;
+ }
+ function skipMarkerIfEqual(value) {
+ if (data[offset + position - 1] === 0xff && data[offset + position] === value) {
+ skipBytes(1);
+ return true;
+ } else if (data[offset + position] === 0xff && data[offset + position + 1] === value) {
+ skipBytes(2);
+ return true;
+ }
+ return false;
+ }
+ function skipBytes(count) {
+ position += count;
+ }
+ function alignToByte() {
+ bufferSize = 0;
+ if (skipNextBit) {
+ position++;
+ skipNextBit = false;
+ }
+ }
+ function readCodingpasses() {
+ if (readBits(1) === 0) {
+ return 1;
+ }
+ if (readBits(1) === 0) {
+ return 2;
+ }
+ let value = readBits(2);
+ if (value < 3) {
+ return value + 3;
+ }
+ value = readBits(5);
+ if (value < 31) {
+ return value + 6;
+ }
+ value = readBits(7);
+ return value + 37;
+ }
+ const tileIndex = context.currentTile.index;
+ const tile = context.tiles[tileIndex];
+ const sopMarkerUsed = context.COD.sopMarkerUsed;
+ const ephMarkerUsed = context.COD.ephMarkerUsed;
+ const packetsIterator = tile.packetsIterator;
+ while (position < dataLength) {
+ alignToByte();
+ if (sopMarkerUsed && skipMarkerIfEqual(0x91)) {
+ skipBytes(4);
+ }
+ const packet = packetsIterator.nextPacket();
+ if (!readBits(1)) {
+ continue;
+ }
+ const layerNumber = packet.layerNumber,
+ queue = [];
+ let codeblock;
+ for (let i = 0, ii = packet.codeblocks.length; i < ii; i++) {
+ codeblock = packet.codeblocks[i];
+ let precinct = codeblock.precinct;
+ const codeblockColumn = codeblock.cbx - precinct.cbxMin;
+ const codeblockRow = codeblock.cby - precinct.cbyMin;
+ let codeblockIncluded = false;
+ let firstTimeInclusion = false;
+ let valueReady, zeroBitPlanesTree;
+ if (codeblock.included !== undefined) {
+ codeblockIncluded = !!readBits(1);
+ } else {
+ precinct = codeblock.precinct;
+ let inclusionTree;
+ if (precinct.inclusionTree !== undefined) {
+ inclusionTree = precinct.inclusionTree;
+ } else {
+ const width = precinct.cbxMax - precinct.cbxMin + 1;
+ const height = precinct.cbyMax - precinct.cbyMin + 1;
+ inclusionTree = new InclusionTree(width, height, layerNumber);
+ zeroBitPlanesTree = new TagTree(width, height);
+ precinct.inclusionTree = inclusionTree;
+ precinct.zeroBitPlanesTree = zeroBitPlanesTree;
+ for (let l = 0; l < layerNumber; l++) {
+ if (readBits(1) !== 0) {
+ throw new JpxError("Invalid tag tree");
+ }
+ }
+ }
+ if (inclusionTree.reset(codeblockColumn, codeblockRow, layerNumber)) {
+ while (true) {
+ if (readBits(1)) {
+ valueReady = !inclusionTree.nextLevel();
+ if (valueReady) {
+ codeblock.included = true;
+ codeblockIncluded = firstTimeInclusion = true;
+ break;
+ }
+ } else {
+ inclusionTree.incrementValue(layerNumber);
+ break;
+ }
+ }
+ }
+ }
+ if (!codeblockIncluded) {
+ continue;
+ }
+ if (firstTimeInclusion) {
+ zeroBitPlanesTree = precinct.zeroBitPlanesTree;
+ zeroBitPlanesTree.reset(codeblockColumn, codeblockRow);
+ while (true) {
+ if (readBits(1)) {
+ valueReady = !zeroBitPlanesTree.nextLevel();
+ if (valueReady) {
+ break;
+ }
+ } else {
+ zeroBitPlanesTree.incrementValue();
+ }
+ }
+ codeblock.zeroBitPlanes = zeroBitPlanesTree.value;
+ }
+ const codingpasses = readCodingpasses();
+ while (readBits(1)) {
+ codeblock.Lblock++;
+ }
+ const codingpassesLog2 = log2(codingpasses);
+ const bits = (codingpasses < 1 << codingpassesLog2 ? codingpassesLog2 - 1 : codingpassesLog2) + codeblock.Lblock;
+ const codedDataLength = readBits(bits);
+ queue.push({
+ codeblock,
+ codingpasses,
+ dataLength: codedDataLength
+ });
+ }
+ alignToByte();
+ if (ephMarkerUsed) {
+ skipMarkerIfEqual(0x92);
+ }
+ while (queue.length > 0) {
+ const packetItem = queue.shift();
+ codeblock = packetItem.codeblock;
+ if (codeblock.data === undefined) {
+ codeblock.data = [];
+ }
+ codeblock.data.push({
+ data,
+ start: offset + position,
+ end: offset + position + packetItem.dataLength,
+ codingpasses: packetItem.codingpasses
+ });
+ position += packetItem.dataLength;
+ }
+ }
+ return position;
+}
+function copyCoefficients(coefficients, levelWidth, levelHeight, subband, delta, mb, reversible, segmentationSymbolUsed, resetContextProbabilities) {
+ const x0 = subband.tbx0;
+ const y0 = subband.tby0;
+ const width = subband.tbx1 - subband.tbx0;
+ const codeblocks = subband.codeblocks;
+ const right = subband.type.charAt(0) === "H" ? 1 : 0;
+ const bottom = subband.type.charAt(1) === "H" ? levelWidth : 0;
+ for (let i = 0, ii = codeblocks.length; i < ii; ++i) {
+ const codeblock = codeblocks[i];
+ const blockWidth = codeblock.tbx1_ - codeblock.tbx0_;
+ const blockHeight = codeblock.tby1_ - codeblock.tby0_;
+ if (blockWidth === 0 || blockHeight === 0) {
+ continue;
+ }
+ if (codeblock.data === undefined) {
+ continue;
+ }
+ const bitModel = new BitModel(blockWidth, blockHeight, codeblock.subbandType, codeblock.zeroBitPlanes, mb);
+ let currentCodingpassType = 2;
+ const data = codeblock.data;
+ let totalLength = 0,
+ codingpasses = 0;
+ let j, jj, dataItem;
+ for (j = 0, jj = data.length; j < jj; j++) {
+ dataItem = data[j];
+ totalLength += dataItem.end - dataItem.start;
+ codingpasses += dataItem.codingpasses;
+ }
+ const encodedData = new Uint8Array(totalLength);
+ let position = 0;
+ for (j = 0, jj = data.length; j < jj; j++) {
+ dataItem = data[j];
+ const chunk = dataItem.data.subarray(dataItem.start, dataItem.end);
+ encodedData.set(chunk, position);
+ position += chunk.length;
+ }
+ const decoder = new ArithmeticDecoder(encodedData, 0, totalLength);
+ bitModel.setDecoder(decoder);
+ for (j = 0; j < codingpasses; j++) {
+ switch (currentCodingpassType) {
+ case 0:
+ bitModel.runSignificancePropagationPass();
+ break;
+ case 1:
+ bitModel.runMagnitudeRefinementPass();
+ break;
+ case 2:
+ bitModel.runCleanupPass();
+ if (segmentationSymbolUsed) {
+ bitModel.checkSegmentationSymbol();
+ }
+ break;
+ }
+ if (resetContextProbabilities) {
+ bitModel.reset();
+ }
+ currentCodingpassType = (currentCodingpassType + 1) % 3;
+ }
+ let offset = codeblock.tbx0_ - x0 + (codeblock.tby0_ - y0) * width;
+ const sign = bitModel.coefficentsSign;
+ const magnitude = bitModel.coefficentsMagnitude;
+ const bitsDecoded = bitModel.bitsDecoded;
+ const magnitudeCorrection = reversible ? 0 : 0.5;
+ let k, n, nb;
+ position = 0;
+ const interleave = subband.type !== "LL";
+ for (j = 0; j < blockHeight; j++) {
+ const row = offset / width | 0;
+ const levelOffset = 2 * row * (levelWidth - width) + right + bottom;
+ for (k = 0; k < blockWidth; k++) {
+ n = magnitude[position];
+ if (n !== 0) {
+ n = (n + magnitudeCorrection) * delta;
+ if (sign[position] !== 0) {
+ n = -n;
+ }
+ nb = bitsDecoded[position];
+ const pos = interleave ? levelOffset + (offset << 1) : offset;
+ coefficients[pos] = reversible && nb >= mb ? n : n * (1 << mb - nb);
+ }
+ offset++;
+ position++;
+ }
+ offset += width - blockWidth;
+ }
+ }
+}
+function transformTile(context, tile, c) {
+ const component = tile.components[c];
+ const codingStyleParameters = component.codingStyleParameters;
+ const quantizationParameters = component.quantizationParameters;
+ const decompositionLevelsCount = codingStyleParameters.decompositionLevelsCount;
+ const spqcds = quantizationParameters.SPqcds;
+ const scalarExpounded = quantizationParameters.scalarExpounded;
+ const guardBits = quantizationParameters.guardBits;
+ const segmentationSymbolUsed = codingStyleParameters.segmentationSymbolUsed;
+ const resetContextProbabilities = codingStyleParameters.resetContextProbabilities;
+ const precision = context.components[c].precision;
+ const reversible = codingStyleParameters.reversibleTransformation;
+ const transform = reversible ? new ReversibleTransform() : new IrreversibleTransform();
+ const subbandCoefficients = [];
+ let b = 0;
+ for (let i = 0; i <= decompositionLevelsCount; i++) {
+ const resolution = component.resolutions[i];
+ const width = resolution.trx1 - resolution.trx0;
+ const height = resolution.try1 - resolution.try0;
+ const coefficients = new Float32Array(width * height);
+ for (let j = 0, jj = resolution.subbands.length; j < jj; j++) {
+ let mu, epsilon;
+ if (!scalarExpounded) {
+ mu = spqcds[0].mu;
+ epsilon = spqcds[0].epsilon + (i > 0 ? 1 - i : 0);
+ } else {
+ mu = spqcds[b].mu;
+ epsilon = spqcds[b].epsilon;
+ b++;
+ }
+ const subband = resolution.subbands[j];
+ const gainLog2 = SubbandsGainLog2[subband.type];
+ const delta = reversible ? 1 : 2 ** (precision + gainLog2 - epsilon) * (1 + mu / 2048);
+ const mb = guardBits + epsilon - 1;
+ copyCoefficients(coefficients, width, height, subband, delta, mb, reversible, segmentationSymbolUsed, resetContextProbabilities);
+ }
+ subbandCoefficients.push({
+ width,
+ height,
+ items: coefficients
+ });
+ }
+ const result = transform.calculate(subbandCoefficients, component.tcx0, component.tcy0);
+ return {
+ left: component.tcx0,
+ top: component.tcy0,
+ width: result.width,
+ height: result.height,
+ items: result.items
+ };
+}
+function transformComponents(context) {
+ const siz = context.SIZ;
+ const components = context.components;
+ const componentsCount = siz.Csiz;
+ const resultImages = [];
+ for (let i = 0, ii = context.tiles.length; i < ii; i++) {
+ const tile = context.tiles[i];
+ const transformedTiles = [];
+ for (let c = 0; c < componentsCount; c++) {
+ transformedTiles[c] = transformTile(context, tile, c);
+ }
+ const tile0 = transformedTiles[0];
+ const out = new Uint8ClampedArray(tile0.items.length * componentsCount);
+ const result = {
+ left: tile0.left,
+ top: tile0.top,
+ width: tile0.width,
+ height: tile0.height,
+ items: out
+ };
+ let shift, offset;
+ let pos = 0,
+ j,
+ jj,
+ y0,
+ y1,
+ y2;
+ if (tile.codingStyleDefaultParameters.multipleComponentTransform) {
+ const fourComponents = componentsCount === 4;
+ const y0items = transformedTiles[0].items;
+ const y1items = transformedTiles[1].items;
+ const y2items = transformedTiles[2].items;
+ const y3items = fourComponents ? transformedTiles[3].items : null;
+ shift = components[0].precision - 8;
+ offset = (128 << shift) + 0.5;
+ const component0 = tile.components[0];
+ const alpha01 = componentsCount - 3;
+ jj = y0items.length;
+ if (!component0.codingStyleParameters.reversibleTransformation) {
+ for (j = 0; j < jj; j++, pos += alpha01) {
+ y0 = y0items[j] + offset;
+ y1 = y1items[j];
+ y2 = y2items[j];
+ out[pos++] = y0 + 1.402 * y2 >> shift;
+ out[pos++] = y0 - 0.34413 * y1 - 0.71414 * y2 >> shift;
+ out[pos++] = y0 + 1.772 * y1 >> shift;
+ }
+ } else {
+ for (j = 0; j < jj; j++, pos += alpha01) {
+ y0 = y0items[j] + offset;
+ y1 = y1items[j];
+ y2 = y2items[j];
+ const g = y0 - (y2 + y1 >> 2);
+ out[pos++] = g + y2 >> shift;
+ out[pos++] = g >> shift;
+ out[pos++] = g + y1 >> shift;
+ }
+ }
+ if (fourComponents) {
+ for (j = 0, pos = 3; j < jj; j++, pos += 4) {
+ out[pos] = y3items[j] + offset >> shift;
+ }
+ }
+ } else {
+ for (let c = 0; c < componentsCount; c++) {
+ const items = transformedTiles[c].items;
+ shift = components[c].precision - 8;
+ offset = (128 << shift) + 0.5;
+ for (pos = c, j = 0, jj = items.length; j < jj; j++) {
+ out[pos] = items[j] + offset >> shift;
+ pos += componentsCount;
+ }
+ }
+ }
+ resultImages.push(result);
+ }
+ return resultImages;
+}
+function initializeTile(context, tileIndex) {
+ const siz = context.SIZ;
+ const componentsCount = siz.Csiz;
+ const tile = context.tiles[tileIndex];
+ for (let c = 0; c < componentsCount; c++) {
+ const component = tile.components[c];
+ const qcdOrQcc = context.currentTile.QCC[c] !== undefined ? context.currentTile.QCC[c] : context.currentTile.QCD;
+ component.quantizationParameters = qcdOrQcc;
+ const codOrCoc = context.currentTile.COC[c] !== undefined ? context.currentTile.COC[c] : context.currentTile.COD;
+ component.codingStyleParameters = codOrCoc;
+ }
+ tile.codingStyleDefaultParameters = context.currentTile.COD;
+}
+class TagTree {
+ constructor(width, height) {
+ const levelsLength = log2(Math.max(width, height)) + 1;
+ this.levels = [];
+ for (let i = 0; i < levelsLength; i++) {
+ const level = {
+ width,
+ height,
+ items: []
+ };
+ this.levels.push(level);
+ width = Math.ceil(width / 2);
+ height = Math.ceil(height / 2);
+ }
+ }
+ reset(i, j) {
+ let currentLevel = 0,
+ value = 0,
+ level;
+ while (currentLevel < this.levels.length) {
+ level = this.levels[currentLevel];
+ const index = i + j * level.width;
+ if (level.items[index] !== undefined) {
+ value = level.items[index];
+ break;
+ }
+ level.index = index;
+ i >>= 1;
+ j >>= 1;
+ currentLevel++;
+ }
+ currentLevel--;
+ level = this.levels[currentLevel];
+ level.items[level.index] = value;
+ this.currentLevel = currentLevel;
+ delete this.value;
+ }
+ incrementValue() {
+ const level = this.levels[this.currentLevel];
+ level.items[level.index]++;
+ }
+ nextLevel() {
+ let currentLevel = this.currentLevel;
+ let level = this.levels[currentLevel];
+ const value = level.items[level.index];
+ currentLevel--;
+ if (currentLevel < 0) {
+ this.value = value;
+ return false;
+ }
+ this.currentLevel = currentLevel;
+ level = this.levels[currentLevel];
+ level.items[level.index] = value;
+ return true;
+ }
+}
+class InclusionTree {
+ constructor(width, height, defaultValue) {
+ const levelsLength = log2(Math.max(width, height)) + 1;
+ this.levels = [];
+ for (let i = 0; i < levelsLength; i++) {
+ const items = new Uint8Array(width * height);
+ for (let j = 0, jj = items.length; j < jj; j++) {
+ items[j] = defaultValue;
+ }
+ const level = {
+ width,
+ height,
+ items
+ };
+ this.levels.push(level);
+ width = Math.ceil(width / 2);
+ height = Math.ceil(height / 2);
+ }
+ }
+ reset(i, j, stopValue) {
+ let currentLevel = 0;
+ while (currentLevel < this.levels.length) {
+ const level = this.levels[currentLevel];
+ const index = i + j * level.width;
+ level.index = index;
+ const value = level.items[index];
+ if (value === 0xff) {
+ break;
+ }
+ if (value > stopValue) {
+ this.currentLevel = currentLevel;
+ this.propagateValues();
+ return false;
+ }
+ i >>= 1;
+ j >>= 1;
+ currentLevel++;
+ }
+ this.currentLevel = currentLevel - 1;
+ return true;
+ }
+ incrementValue(stopValue) {
+ const level = this.levels[this.currentLevel];
+ level.items[level.index] = stopValue + 1;
+ this.propagateValues();
+ }
+ propagateValues() {
+ let levelIndex = this.currentLevel;
+ let level = this.levels[levelIndex];
+ const currentValue = level.items[level.index];
+ while (--levelIndex >= 0) {
+ level = this.levels[levelIndex];
+ level.items[level.index] = currentValue;
+ }
+ }
+ nextLevel() {
+ let currentLevel = this.currentLevel;
+ let level = this.levels[currentLevel];
+ const value = level.items[level.index];
+ level.items[level.index] = 0xff;
+ currentLevel--;
+ if (currentLevel < 0) {
+ return false;
+ }
+ this.currentLevel = currentLevel;
+ level = this.levels[currentLevel];
+ level.items[level.index] = value;
+ return true;
+ }
+}
+class BitModel {
+ static UNIFORM_CONTEXT = 17;
+ static RUNLENGTH_CONTEXT = 18;
+ static LLAndLHContextsLabel = new Uint8Array([0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8]);
+ static HLContextLabel = new Uint8Array([0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8]);
+ static HHContextLabel = new Uint8Array([0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8]);
+ constructor(width, height, subband, zeroBitPlanes, mb) {
+ this.width = width;
+ this.height = height;
+ let contextLabelTable;
+ if (subband === "HH") {
+ contextLabelTable = BitModel.HHContextLabel;
+ } else if (subband === "HL") {
+ contextLabelTable = BitModel.HLContextLabel;
+ } else {
+ contextLabelTable = BitModel.LLAndLHContextsLabel;
+ }
+ this.contextLabelTable = contextLabelTable;
+ const coefficientCount = width * height;
+ this.neighborsSignificance = new Uint8Array(coefficientCount);
+ this.coefficentsSign = new Uint8Array(coefficientCount);
+ let coefficentsMagnitude;
+ if (mb > 14) {
+ coefficentsMagnitude = new Uint32Array(coefficientCount);
+ } else if (mb > 6) {
+ coefficentsMagnitude = new Uint16Array(coefficientCount);
+ } else {
+ coefficentsMagnitude = new Uint8Array(coefficientCount);
+ }
+ this.coefficentsMagnitude = coefficentsMagnitude;
+ this.processingFlags = new Uint8Array(coefficientCount);
+ const bitsDecoded = new Uint8Array(coefficientCount);
+ if (zeroBitPlanes !== 0) {
+ for (let i = 0; i < coefficientCount; i++) {
+ bitsDecoded[i] = zeroBitPlanes;
+ }
+ }
+ this.bitsDecoded = bitsDecoded;
+ this.reset();
+ }
+ setDecoder(decoder) {
+ this.decoder = decoder;
+ }
+ reset() {
+ this.contexts = new Int8Array(19);
+ this.contexts[0] = 4 << 1 | 0;
+ this.contexts[BitModel.UNIFORM_CONTEXT] = 46 << 1 | 0;
+ this.contexts[BitModel.RUNLENGTH_CONTEXT] = 3 << 1 | 0;
+ }
+ setNeighborsSignificance(row, column, index) {
+ const neighborsSignificance = this.neighborsSignificance;
+ const width = this.width,
+ height = this.height;
+ const left = column > 0;
+ const right = column + 1 < width;
+ let i;
+ if (row > 0) {
+ i = index - width;
+ if (left) {
+ neighborsSignificance[i - 1] += 0x10;
+ }
+ if (right) {
+ neighborsSignificance[i + 1] += 0x10;
+ }
+ neighborsSignificance[i] += 0x04;
+ }
+ if (row + 1 < height) {
+ i = index + width;
+ if (left) {
+ neighborsSignificance[i - 1] += 0x10;
+ }
+ if (right) {
+ neighborsSignificance[i + 1] += 0x10;
+ }
+ neighborsSignificance[i] += 0x04;
+ }
+ if (left) {
+ neighborsSignificance[index - 1] += 0x01;
+ }
+ if (right) {
+ neighborsSignificance[index + 1] += 0x01;
+ }
+ neighborsSignificance[index] |= 0x80;
+ }
+ runSignificancePropagationPass() {
+ const decoder = this.decoder;
+ const width = this.width,
+ height = this.height;
+ const coefficentsMagnitude = this.coefficentsMagnitude;
+ const coefficentsSign = this.coefficentsSign;
+ const neighborsSignificance = this.neighborsSignificance;
+ const processingFlags = this.processingFlags;
+ const contexts = this.contexts;
+ const labels = this.contextLabelTable;
+ const bitsDecoded = this.bitsDecoded;
+ const processedInverseMask = ~1;
+ const processedMask = 1;
+ const firstMagnitudeBitMask = 2;
+ for (let i0 = 0; i0 < height; i0 += 4) {
+ for (let j = 0; j < width; j++) {
+ let index = i0 * width + j;
+ for (let i1 = 0; i1 < 4; i1++, index += width) {
+ const i = i0 + i1;
+ if (i >= height) {
+ break;
+ }
+ processingFlags[index] &= processedInverseMask;
+ if (coefficentsMagnitude[index] || !neighborsSignificance[index]) {
+ continue;
+ }
+ const contextLabel = labels[neighborsSignificance[index]];
+ const decision = decoder.readBit(contexts, contextLabel);
+ if (decision) {
+ const sign = this.decodeSignBit(i, j, index);
+ coefficentsSign[index] = sign;
+ coefficentsMagnitude[index] = 1;
+ this.setNeighborsSignificance(i, j, index);
+ processingFlags[index] |= firstMagnitudeBitMask;
+ }
+ bitsDecoded[index]++;
+ processingFlags[index] |= processedMask;
+ }
+ }
+ }
+ }
+ decodeSignBit(row, column, index) {
+ const width = this.width,
+ height = this.height;
+ const coefficentsMagnitude = this.coefficentsMagnitude;
+ const coefficentsSign = this.coefficentsSign;
+ let contribution, sign0, sign1, significance1;
+ let contextLabel, decoded;
+ significance1 = column > 0 && coefficentsMagnitude[index - 1] !== 0;
+ if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) {
+ sign1 = coefficentsSign[index + 1];
+ if (significance1) {
+ sign0 = coefficentsSign[index - 1];
+ contribution = 1 - sign1 - sign0;
+ } else {
+ contribution = 1 - sign1 - sign1;
+ }
+ } else if (significance1) {
+ sign0 = coefficentsSign[index - 1];
+ contribution = 1 - sign0 - sign0;
+ } else {
+ contribution = 0;
+ }
+ const horizontalContribution = 3 * contribution;
+ significance1 = row > 0 && coefficentsMagnitude[index - width] !== 0;
+ if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) {
+ sign1 = coefficentsSign[index + width];
+ if (significance1) {
+ sign0 = coefficentsSign[index - width];
+ contribution = 1 - sign1 - sign0 + horizontalContribution;
+ } else {
+ contribution = 1 - sign1 - sign1 + horizontalContribution;
+ }
+ } else if (significance1) {
+ sign0 = coefficentsSign[index - width];
+ contribution = 1 - sign0 - sign0 + horizontalContribution;
+ } else {
+ contribution = horizontalContribution;
+ }
+ if (contribution >= 0) {
+ contextLabel = 9 + contribution;
+ decoded = this.decoder.readBit(this.contexts, contextLabel);
+ } else {
+ contextLabel = 9 - contribution;
+ decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1;
+ }
+ return decoded;
+ }
+ runMagnitudeRefinementPass() {
+ const decoder = this.decoder;
+ const width = this.width,
+ height = this.height;
+ const coefficentsMagnitude = this.coefficentsMagnitude;
+ const neighborsSignificance = this.neighborsSignificance;
+ const contexts = this.contexts;
+ const bitsDecoded = this.bitsDecoded;
+ const processingFlags = this.processingFlags;
+ const processedMask = 1;
+ const firstMagnitudeBitMask = 2;
+ const length = width * height;
+ const width4 = width * 4;
+ for (let index0 = 0, indexNext; index0 < length; index0 = indexNext) {
+ indexNext = Math.min(length, index0 + width4);
+ for (let j = 0; j < width; j++) {
+ for (let index = index0 + j; index < indexNext; index += width) {
+ if (!coefficentsMagnitude[index] || (processingFlags[index] & processedMask) !== 0) {
+ continue;
+ }
+ let contextLabel = 16;
+ if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) {
+ processingFlags[index] ^= firstMagnitudeBitMask;
+ const significance = neighborsSignificance[index] & 127;
+ contextLabel = significance === 0 ? 15 : 14;
+ }
+ const bit = decoder.readBit(contexts, contextLabel);
+ coefficentsMagnitude[index] = coefficentsMagnitude[index] << 1 | bit;
+ bitsDecoded[index]++;
+ processingFlags[index] |= processedMask;
+ }
+ }
+ }
+ }
+ runCleanupPass() {
+ const decoder = this.decoder;
+ const width = this.width,
+ height = this.height;
+ const neighborsSignificance = this.neighborsSignificance;
+ const coefficentsMagnitude = this.coefficentsMagnitude;
+ const coefficentsSign = this.coefficentsSign;
+ const contexts = this.contexts;
+ const labels = this.contextLabelTable;
+ const bitsDecoded = this.bitsDecoded;
+ const processingFlags = this.processingFlags;
+ const processedMask = 1;
+ const firstMagnitudeBitMask = 2;
+ const oneRowDown = width;
+ const twoRowsDown = width * 2;
+ const threeRowsDown = width * 3;
+ let iNext;
+ for (let i0 = 0; i0 < height; i0 = iNext) {
+ iNext = Math.min(i0 + 4, height);
+ const indexBase = i0 * width;
+ const checkAllEmpty = i0 + 3 < height;
+ for (let j = 0; j < width; j++) {
+ const index0 = indexBase + j;
+ const allEmpty = checkAllEmpty && processingFlags[index0] === 0 && processingFlags[index0 + oneRowDown] === 0 && processingFlags[index0 + twoRowsDown] === 0 && processingFlags[index0 + threeRowsDown] === 0 && neighborsSignificance[index0] === 0 && neighborsSignificance[index0 + oneRowDown] === 0 && neighborsSignificance[index0 + twoRowsDown] === 0 && neighborsSignificance[index0 + threeRowsDown] === 0;
+ let i1 = 0,
+ index = index0;
+ let i = i0,
+ sign;
+ if (allEmpty) {
+ const hasSignificantCoefficent = decoder.readBit(contexts, BitModel.RUNLENGTH_CONTEXT);
+ if (!hasSignificantCoefficent) {
+ bitsDecoded[index0]++;
+ bitsDecoded[index0 + oneRowDown]++;
+ bitsDecoded[index0 + twoRowsDown]++;
+ bitsDecoded[index0 + threeRowsDown]++;
+ continue;
+ }
+ i1 = decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT);
+ if (i1 !== 0) {
+ i = i0 + i1;
+ index += i1 * width;
+ }
+ sign = this.decodeSignBit(i, j, index);
+ coefficentsSign[index] = sign;
+ coefficentsMagnitude[index] = 1;
+ this.setNeighborsSignificance(i, j, index);
+ processingFlags[index] |= firstMagnitudeBitMask;
+ index = index0;
+ for (let i2 = i0; i2 <= i; i2++, index += width) {
+ bitsDecoded[index]++;
+ }
+ i1++;
+ }
+ for (i = i0 + i1; i < iNext; i++, index += width) {
+ if (coefficentsMagnitude[index] || (processingFlags[index] & processedMask) !== 0) {
+ continue;
+ }
+ const contextLabel = labels[neighborsSignificance[index]];
+ const decision = decoder.readBit(contexts, contextLabel);
+ if (decision === 1) {
+ sign = this.decodeSignBit(i, j, index);
+ coefficentsSign[index] = sign;
+ coefficentsMagnitude[index] = 1;
+ this.setNeighborsSignificance(i, j, index);
+ processingFlags[index] |= firstMagnitudeBitMask;
+ }
+ bitsDecoded[index]++;
+ }
+ }
+ }
+ }
+ checkSegmentationSymbol() {
+ const decoder = this.decoder;
+ const contexts = this.contexts;
+ const symbol = decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 3 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 2 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT);
+ if (symbol !== 0xa) {
+ throw new JpxError("Invalid segmentation symbol");
+ }
+ }
+}
+class Transform {
+ constructor() {
+ if (this.constructor === Transform) {
+ unreachable("Cannot initialize Transform.");
+ }
+ }
+ calculate(subbands, u0, v0) {
+ let ll = subbands[0];
+ for (let i = 1, ii = subbands.length; i < ii; i++) {
+ ll = this.iterate(ll, subbands[i], u0, v0);
+ }
+ return ll;
+ }
+ extend(buffer, offset, size) {
+ let i1 = offset - 1,
+ j1 = offset + 1;
+ let i2 = offset + size - 2,
+ j2 = offset + size;
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1--] = buffer[j1++];
+ buffer[j2++] = buffer[i2--];
+ buffer[i1] = buffer[j1];
+ buffer[j2] = buffer[i2];
+ }
+ filter(x, offset, length) {
+ unreachable("Abstract method `filter` called");
+ }
+ iterate(ll, hl_lh_hh, u0, v0) {
+ const llWidth = ll.width,
+ llHeight = ll.height;
+ let llItems = ll.items;
+ const width = hl_lh_hh.width;
+ const height = hl_lh_hh.height;
+ const items = hl_lh_hh.items;
+ let i, j, k, l, u, v;
+ for (k = 0, i = 0; i < llHeight; i++) {
+ l = i * 2 * width;
+ for (j = 0; j < llWidth; j++, k++, l += 2) {
+ items[l] = llItems[k];
+ }
+ }
+ llItems = ll.items = null;
+ const bufferPadding = 4;
+ const rowBuffer = new Float32Array(width + 2 * bufferPadding);
+ if (width === 1) {
+ if ((u0 & 1) !== 0) {
+ for (v = 0, k = 0; v < height; v++, k += width) {
+ items[k] *= 0.5;
+ }
+ }
+ } else {
+ for (v = 0, k = 0; v < height; v++, k += width) {
+ rowBuffer.set(items.subarray(k, k + width), bufferPadding);
+ this.extend(rowBuffer, bufferPadding, width);
+ this.filter(rowBuffer, bufferPadding, width);
+ items.set(rowBuffer.subarray(bufferPadding, bufferPadding + width), k);
+ }
+ }
+ let numBuffers = 16;
+ const colBuffers = [];
+ for (i = 0; i < numBuffers; i++) {
+ colBuffers.push(new Float32Array(height + 2 * bufferPadding));
+ }
+ let b,
+ currentBuffer = 0;
+ ll = bufferPadding + height;
+ if (height === 1) {
+ if ((v0 & 1) !== 0) {
+ for (u = 0; u < width; u++) {
+ items[u] *= 0.5;
+ }
+ }
+ } else {
+ for (u = 0; u < width; u++) {
+ if (currentBuffer === 0) {
+ numBuffers = Math.min(width - u, numBuffers);
+ for (k = u, l = bufferPadding; l < ll; k += width, l++) {
+ for (b = 0; b < numBuffers; b++) {
+ colBuffers[b][l] = items[k + b];
+ }
+ }
+ currentBuffer = numBuffers;
+ }
+ currentBuffer--;
+ const buffer = colBuffers[currentBuffer];
+ this.extend(buffer, bufferPadding, height);
+ this.filter(buffer, bufferPadding, height);
+ if (currentBuffer === 0) {
+ k = u - numBuffers + 1;
+ for (l = bufferPadding; l < ll; k += width, l++) {
+ for (b = 0; b < numBuffers; b++) {
+ items[k + b] = colBuffers[b][l];
+ }
+ }
+ }
+ }
+ }
+ return {
+ width,
+ height,
+ items
+ };
+ }
+}
+class IrreversibleTransform extends Transform {
+ filter(x, offset, length) {
+ const len = length >> 1;
+ offset |= 0;
+ let j, n, current, next;
+ const alpha = -1.586134342059924;
+ const beta = -0.052980118572961;
+ const gamma = 0.882911075530934;
+ const delta = 0.443506852043971;
+ const K = 1.230174104914001;
+ const K_ = 1 / K;
+ j = offset - 3;
+ for (n = len + 4; n--; j += 2) {
+ x[j] *= K_;
+ }
+ j = offset - 2;
+ current = delta * x[j - 1];
+ for (n = len + 3; n--; j += 2) {
+ next = delta * x[j + 1];
+ x[j] = K * x[j] - current - next;
+ if (n--) {
+ j += 2;
+ current = delta * x[j + 1];
+ x[j] = K * x[j] - current - next;
+ } else {
+ break;
+ }
+ }
+ j = offset - 1;
+ current = gamma * x[j - 1];
+ for (n = len + 2; n--; j += 2) {
+ next = gamma * x[j + 1];
+ x[j] -= current + next;
+ if (n--) {
+ j += 2;
+ current = gamma * x[j + 1];
+ x[j] -= current + next;
+ } else {
+ break;
+ }
+ }
+ j = offset;
+ current = beta * x[j - 1];
+ for (n = len + 1; n--; j += 2) {
+ next = beta * x[j + 1];
+ x[j] -= current + next;
+ if (n--) {
+ j += 2;
+ current = beta * x[j + 1];
+ x[j] -= current + next;
+ } else {
+ break;
+ }
+ }
+ if (len !== 0) {
+ j = offset + 1;
+ current = alpha * x[j - 1];
+ for (n = len; n--; j += 2) {
+ next = alpha * x[j + 1];
+ x[j] -= current + next;
+ if (n--) {
+ j += 2;
+ current = alpha * x[j + 1];
+ x[j] -= current + next;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+}
+class ReversibleTransform extends Transform {
+ filter(x, offset, length) {
+ const len = length >> 1;
+ offset |= 0;
+ let j, n;
+ for (j = offset, n = len + 1; n--; j += 2) {
+ x[j] -= x[j - 1] + x[j + 1] + 2 >> 2;
+ }
+ for (j = offset + 1, n = len; n--; j += 2) {
+ x[j] += x[j - 1] + x[j + 1] >> 1;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/jpx_stream.js
+
+
+
+class JpxStream extends DecodeStream {
+ constructor(stream, maybeLength, params) {
+ super(maybeLength);
+ this.stream = stream;
+ this.dict = stream.dict;
+ this.maybeLength = maybeLength;
+ this.params = params;
+ }
+ get bytes() {
+ return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
+ }
+ ensureBuffer(requested) {}
+ readBlock() {
+ if (this.eof) {
+ return;
+ }
+ const jpxImage = new JpxImage();
+ jpxImage.parse(this.bytes);
+ const width = jpxImage.width;
+ const height = jpxImage.height;
+ const componentsCount = jpxImage.componentsCount;
+ const tileCount = jpxImage.tiles.length;
+ if (tileCount === 1) {
+ this.buffer = jpxImage.tiles[0].items;
+ } else {
+ const data = new Uint8ClampedArray(width * height * componentsCount);
+ for (let k = 0; k < tileCount; k++) {
+ const tileComponents = jpxImage.tiles[k];
+ const tileWidth = tileComponents.width;
+ const tileHeight = tileComponents.height;
+ const tileLeft = tileComponents.left;
+ const tileTop = tileComponents.top;
+ const src = tileComponents.items;
+ let srcPosition = 0;
+ let dataPosition = (width * tileTop + tileLeft) * componentsCount;
+ const imgRowSize = width * componentsCount;
+ const tileRowSize = tileWidth * componentsCount;
+ for (let j = 0; j < tileHeight; j++) {
+ const rowBytes = src.subarray(srcPosition, srcPosition + tileRowSize);
+ data.set(rowBytes, dataPosition);
+ srcPosition += tileRowSize;
+ dataPosition += imgRowSize;
+ }
+ }
+ this.buffer = data;
+ }
+ this.bufferLength = this.buffer.length;
+ this.eof = true;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/lzw_stream.js
+
+class LZWStream extends DecodeStream {
+ constructor(str, maybeLength, earlyChange) {
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ this.cachedData = 0;
+ this.bitsCached = 0;
+ const maxLzwDictionarySize = 4096;
+ const lzwState = {
+ earlyChange,
+ codeLength: 9,
+ nextCode: 258,
+ dictionaryValues: new Uint8Array(maxLzwDictionarySize),
+ dictionaryLengths: new Uint16Array(maxLzwDictionarySize),
+ dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize),
+ currentSequence: new Uint8Array(maxLzwDictionarySize),
+ currentSequenceLength: 0
+ };
+ for (let i = 0; i < 256; ++i) {
+ lzwState.dictionaryValues[i] = i;
+ lzwState.dictionaryLengths[i] = 1;
+ }
+ this.lzwState = lzwState;
+ }
+ readBits(n) {
+ let bitsCached = this.bitsCached;
+ let cachedData = this.cachedData;
+ while (bitsCached < n) {
+ const c = this.str.getByte();
+ if (c === -1) {
+ this.eof = true;
+ return null;
+ }
+ cachedData = cachedData << 8 | c;
+ bitsCached += 8;
+ }
+ this.bitsCached = bitsCached -= n;
+ this.cachedData = cachedData;
+ this.lastCode = null;
+ return cachedData >>> bitsCached & (1 << n) - 1;
+ }
+ readBlock() {
+ const blockSize = 512,
+ decodedSizeDelta = blockSize;
+ let estimatedDecodedSize = blockSize * 2;
+ let i, j, q;
+ const lzwState = this.lzwState;
+ if (!lzwState) {
+ return;
+ }
+ const earlyChange = lzwState.earlyChange;
+ let nextCode = lzwState.nextCode;
+ const dictionaryValues = lzwState.dictionaryValues;
+ const dictionaryLengths = lzwState.dictionaryLengths;
+ const dictionaryPrevCodes = lzwState.dictionaryPrevCodes;
+ let codeLength = lzwState.codeLength;
+ let prevCode = lzwState.prevCode;
+ const currentSequence = lzwState.currentSequence;
+ let currentSequenceLength = lzwState.currentSequenceLength;
+ let decodedLength = 0;
+ let currentBufferLength = this.bufferLength;
+ let buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);
+ for (i = 0; i < blockSize; i++) {
+ const code = this.readBits(codeLength);
+ const hasPrev = currentSequenceLength > 0;
+ if (code < 256) {
+ currentSequence[0] = code;
+ currentSequenceLength = 1;
+ } else if (code >= 258) {
+ if (code < nextCode) {
+ currentSequenceLength = dictionaryLengths[code];
+ for (j = currentSequenceLength - 1, q = code; j >= 0; j--) {
+ currentSequence[j] = dictionaryValues[q];
+ q = dictionaryPrevCodes[q];
+ }
+ } else {
+ currentSequence[currentSequenceLength++] = currentSequence[0];
+ }
+ } else if (code === 256) {
+ codeLength = 9;
+ nextCode = 258;
+ currentSequenceLength = 0;
+ continue;
+ } else {
+ this.eof = true;
+ delete this.lzwState;
+ break;
+ }
+ if (hasPrev) {
+ dictionaryPrevCodes[nextCode] = prevCode;
+ dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1;
+ dictionaryValues[nextCode] = currentSequence[0];
+ nextCode++;
+ codeLength = nextCode + earlyChange & nextCode + earlyChange - 1 ? codeLength : Math.min(Math.log(nextCode + earlyChange) / 0.6931471805599453 + 1, 12) | 0;
+ }
+ prevCode = code;
+ decodedLength += currentSequenceLength;
+ if (estimatedDecodedSize < decodedLength) {
+ do {
+ estimatedDecodedSize += decodedSizeDelta;
+ } while (estimatedDecodedSize < decodedLength);
+ buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);
+ }
+ for (j = 0; j < currentSequenceLength; j++) {
+ buffer[currentBufferLength++] = currentSequence[j];
+ }
+ }
+ lzwState.nextCode = nextCode;
+ lzwState.codeLength = codeLength;
+ lzwState.prevCode = prevCode;
+ lzwState.currentSequenceLength = currentSequenceLength;
+ this.bufferLength = currentBufferLength;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/predictor_stream.js
+
+
+
+class PredictorStream extends DecodeStream {
+ constructor(str, maybeLength, params) {
+ super(maybeLength);
+ if (!(params instanceof Dict)) {
+ return str;
+ }
+ const predictor = this.predictor = params.get("Predictor") || 1;
+ if (predictor <= 1) {
+ return str;
+ }
+ if (predictor !== 2 && (predictor < 10 || predictor > 15)) {
+ throw new FormatError(`Unsupported predictor: ${predictor}`);
+ }
+ this.readBlock = predictor === 2 ? this.readBlockTiff : this.readBlockPng;
+ this.str = str;
+ this.dict = str.dict;
+ const colors = this.colors = params.get("Colors") || 1;
+ const bits = this.bits = params.get("BPC", "BitsPerComponent") || 8;
+ const columns = this.columns = params.get("Columns") || 1;
+ this.pixBytes = colors * bits + 7 >> 3;
+ this.rowBytes = columns * colors * bits + 7 >> 3;
+ return this;
+ }
+ readBlockTiff() {
+ const rowBytes = this.rowBytes;
+ const bufferLength = this.bufferLength;
+ const buffer = this.ensureBuffer(bufferLength + rowBytes);
+ const bits = this.bits;
+ const colors = this.colors;
+ const rawBytes = this.str.getBytes(rowBytes);
+ this.eof = !rawBytes.length;
+ if (this.eof) {
+ return;
+ }
+ let inbuf = 0,
+ outbuf = 0;
+ let inbits = 0,
+ outbits = 0;
+ let pos = bufferLength;
+ let i;
+ if (bits === 1 && colors === 1) {
+ for (i = 0; i < rowBytes; ++i) {
+ let c = rawBytes[i] ^ inbuf;
+ c ^= c >> 1;
+ c ^= c >> 2;
+ c ^= c >> 4;
+ inbuf = (c & 1) << 7;
+ buffer[pos++] = c;
+ }
+ } else if (bits === 8) {
+ for (i = 0; i < colors; ++i) {
+ buffer[pos++] = rawBytes[i];
+ }
+ for (; i < rowBytes; ++i) {
+ buffer[pos] = buffer[pos - colors] + rawBytes[i];
+ pos++;
+ }
+ } else if (bits === 16) {
+ const bytesPerPixel = colors * 2;
+ for (i = 0; i < bytesPerPixel; ++i) {
+ buffer[pos++] = rawBytes[i];
+ }
+ for (; i < rowBytes; i += 2) {
+ const sum = ((rawBytes[i] & 0xff) << 8) + (rawBytes[i + 1] & 0xff) + ((buffer[pos - bytesPerPixel] & 0xff) << 8) + (buffer[pos - bytesPerPixel + 1] & 0xff);
+ buffer[pos++] = sum >> 8 & 0xff;
+ buffer[pos++] = sum & 0xff;
+ }
+ } else {
+ const compArray = new Uint8Array(colors + 1);
+ const bitMask = (1 << bits) - 1;
+ let j = 0,
+ k = bufferLength;
+ const columns = this.columns;
+ for (i = 0; i < columns; ++i) {
+ for (let kk = 0; kk < colors; ++kk) {
+ if (inbits < bits) {
+ inbuf = inbuf << 8 | rawBytes[j++] & 0xff;
+ inbits += 8;
+ }
+ compArray[kk] = compArray[kk] + (inbuf >> inbits - bits) & bitMask;
+ inbits -= bits;
+ outbuf = outbuf << bits | compArray[kk];
+ outbits += bits;
+ if (outbits >= 8) {
+ buffer[k++] = outbuf >> outbits - 8 & 0xff;
+ outbits -= 8;
+ }
+ }
+ }
+ if (outbits > 0) {
+ buffer[k++] = (outbuf << 8 - outbits) + (inbuf & (1 << 8 - outbits) - 1);
+ }
+ }
+ this.bufferLength += rowBytes;
+ }
+ readBlockPng() {
+ const rowBytes = this.rowBytes;
+ const pixBytes = this.pixBytes;
+ const predictor = this.str.getByte();
+ const rawBytes = this.str.getBytes(rowBytes);
+ this.eof = !rawBytes.length;
+ if (this.eof) {
+ return;
+ }
+ const bufferLength = this.bufferLength;
+ const buffer = this.ensureBuffer(bufferLength + rowBytes);
+ let prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
+ if (prevRow.length === 0) {
+ prevRow = new Uint8Array(rowBytes);
+ }
+ let i,
+ j = bufferLength,
+ up,
+ c;
+ switch (predictor) {
+ case 0:
+ for (i = 0; i < rowBytes; ++i) {
+ buffer[j++] = rawBytes[i];
+ }
+ break;
+ case 1:
+ for (i = 0; i < pixBytes; ++i) {
+ buffer[j++] = rawBytes[i];
+ }
+ for (; i < rowBytes; ++i) {
+ buffer[j] = buffer[j - pixBytes] + rawBytes[i] & 0xff;
+ j++;
+ }
+ break;
+ case 2:
+ for (i = 0; i < rowBytes; ++i) {
+ buffer[j++] = prevRow[i] + rawBytes[i] & 0xff;
+ }
+ break;
+ case 3:
+ for (i = 0; i < pixBytes; ++i) {
+ buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];
+ }
+ for (; i < rowBytes; ++i) {
+ buffer[j] = (prevRow[i] + buffer[j - pixBytes] >> 1) + rawBytes[i] & 0xff;
+ j++;
+ }
+ break;
+ case 4:
+ for (i = 0; i < pixBytes; ++i) {
+ up = prevRow[i];
+ c = rawBytes[i];
+ buffer[j++] = up + c;
+ }
+ for (; i < rowBytes; ++i) {
+ up = prevRow[i];
+ const upLeft = prevRow[i - pixBytes];
+ const left = buffer[j - pixBytes];
+ const p = left + up - upLeft;
+ let pa = p - left;
+ if (pa < 0) {
+ pa = -pa;
+ }
+ let pb = p - up;
+ if (pb < 0) {
+ pb = -pb;
+ }
+ let pc = p - upLeft;
+ if (pc < 0) {
+ pc = -pc;
+ }
+ c = rawBytes[i];
+ if (pa <= pb && pa <= pc) {
+ buffer[j++] = left + c;
+ } else if (pb <= pc) {
+ buffer[j++] = up + c;
+ } else {
+ buffer[j++] = upLeft + c;
+ }
+ }
+ break;
+ default:
+ throw new FormatError(`Unsupported predictor: ${predictor}`);
+ }
+ this.bufferLength += rowBytes;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/run_length_stream.js
+
+class RunLengthStream extends DecodeStream {
+ constructor(str, maybeLength) {
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ }
+ readBlock() {
+ const repeatHeader = this.str.getBytes(2);
+ if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] === 128) {
+ this.eof = true;
+ return;
+ }
+ let buffer;
+ let bufferLength = this.bufferLength;
+ let n = repeatHeader[0];
+ if (n < 128) {
+ buffer = this.ensureBuffer(bufferLength + n + 1);
+ buffer[bufferLength++] = repeatHeader[1];
+ if (n > 0) {
+ const source = this.str.getBytes(n);
+ buffer.set(source, bufferLength);
+ bufferLength += n;
+ }
+ } else {
+ n = 257 - n;
+ const b = repeatHeader[1];
+ buffer = this.ensureBuffer(bufferLength + n + 1);
+ for (let i = 0; i < n; i++) {
+ buffer[bufferLength++] = b;
+ }
+ }
+ this.bufferLength = bufferLength;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/parser.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const MAX_LENGTH_TO_CACHE = 1000;
+function getInlineImageCacheKey(bytes) {
+ const strBuf = [],
+ ii = bytes.length;
+ let i = 0;
+ while (i < ii - 1) {
+ strBuf.push(bytes[i++] << 8 | bytes[i++]);
+ }
+ if (i < ii) {
+ strBuf.push(bytes[i]);
+ }
+ return ii + "_" + String.fromCharCode.apply(null, strBuf);
+}
+class Parser {
+ constructor({
+ lexer,
+ xref,
+ allowStreams = false,
+ recoveryMode = false
+ }) {
+ this.lexer = lexer;
+ this.xref = xref;
+ this.allowStreams = allowStreams;
+ this.recoveryMode = recoveryMode;
+ this.imageCache = Object.create(null);
+ this._imageId = 0;
+ this.refill();
+ }
+ refill() {
+ this.buf1 = this.lexer.getObj();
+ this.buf2 = this.lexer.getObj();
+ }
+ shift() {
+ if (this.buf2 instanceof Cmd && this.buf2.cmd === "ID") {
+ this.buf1 = this.buf2;
+ this.buf2 = null;
+ } else {
+ this.buf1 = this.buf2;
+ this.buf2 = this.lexer.getObj();
+ }
+ }
+ tryShift() {
+ try {
+ this.shift();
+ return true;
+ } catch (e) {
+ if (e instanceof MissingDataException) {
+ throw e;
+ }
+ return false;
+ }
+ }
+ getObj(cipherTransform = null) {
+ const buf1 = this.buf1;
+ this.shift();
+ if (buf1 instanceof Cmd) {
+ switch (buf1.cmd) {
+ case "BI":
+ return this.makeInlineImage(cipherTransform);
+ case "[":
+ const array = [];
+ while (!isCmd(this.buf1, "]") && this.buf1 !== EOF) {
+ array.push(this.getObj(cipherTransform));
+ }
+ if (this.buf1 === EOF) {
+ if (this.recoveryMode) {
+ return array;
+ }
+ throw new ParserEOFException("End of file inside array.");
+ }
+ this.shift();
+ return array;
+ case "<<":
+ const dict = new Dict(this.xref);
+ while (!isCmd(this.buf1, ">>") && this.buf1 !== EOF) {
+ if (!(this.buf1 instanceof Name)) {
+ info("Malformed dictionary: key must be a name object");
+ this.shift();
+ continue;
+ }
+ const key = this.buf1.name;
+ this.shift();
+ if (this.buf1 === EOF) {
+ break;
+ }
+ dict.set(key, this.getObj(cipherTransform));
+ }
+ if (this.buf1 === EOF) {
+ if (this.recoveryMode) {
+ return dict;
+ }
+ throw new ParserEOFException("End of file inside dictionary.");
+ }
+ if (isCmd(this.buf2, "stream")) {
+ return this.allowStreams ? this.makeStream(dict, cipherTransform) : dict;
+ }
+ this.shift();
+ return dict;
+ default:
+ return buf1;
+ }
+ }
+ if (Number.isInteger(buf1)) {
+ if (Number.isInteger(this.buf1) && isCmd(this.buf2, "R")) {
+ const ref = Ref.get(buf1, this.buf1);
+ this.shift();
+ this.shift();
+ return ref;
+ }
+ return buf1;
+ }
+ if (typeof buf1 === "string") {
+ if (cipherTransform) {
+ return cipherTransform.decryptString(buf1);
+ }
+ return buf1;
+ }
+ return buf1;
+ }
+ findDefaultInlineStreamEnd(stream) {
+ const E = 0x45,
+ I = 0x49,
+ SPACE = 0x20,
+ LF = 0xa,
+ CR = 0xd,
+ NUL = 0x0;
+ const {
+ knownCommands
+ } = this.lexer,
+ startPos = stream.pos,
+ n = 15;
+ let state = 0,
+ ch,
+ maybeEIPos;
+ while ((ch = stream.getByte()) !== -1) {
+ if (state === 0) {
+ state = ch === E ? 1 : 0;
+ } else if (state === 1) {
+ state = ch === I ? 2 : 0;
+ } else {
+ if (ch === SPACE || ch === LF || ch === CR) {
+ maybeEIPos = stream.pos;
+ const followingBytes = stream.peekBytes(n);
+ const ii = followingBytes.length;
+ if (ii === 0) {
+ break;
+ }
+ for (let i = 0; i < ii; i++) {
+ ch = followingBytes[i];
+ if (ch === NUL && followingBytes[i + 1] !== NUL) {
+ continue;
+ }
+ if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7f)) {
+ state = 0;
+ break;
+ }
+ }
+ if (state !== 2) {
+ continue;
+ }
+ if (!knownCommands) {
+ warn("findDefaultInlineStreamEnd - `lexer.knownCommands` is undefined.");
+ continue;
+ }
+ const tmpLexer = new Lexer(new Stream(followingBytes.slice()), knownCommands);
+ tmpLexer._hexStringWarn = () => {};
+ let numArgs = 0;
+ while (true) {
+ const nextObj = tmpLexer.getObj();
+ if (nextObj === EOF) {
+ state = 0;
+ break;
+ }
+ if (nextObj instanceof Cmd) {
+ const knownCommand = knownCommands[nextObj.cmd];
+ if (!knownCommand) {
+ state = 0;
+ break;
+ } else if (knownCommand.variableArgs ? numArgs <= knownCommand.numArgs : numArgs === knownCommand.numArgs) {
+ break;
+ }
+ numArgs = 0;
+ continue;
+ }
+ numArgs++;
+ }
+ if (state === 2) {
+ break;
+ }
+ } else {
+ state = 0;
+ }
+ }
+ }
+ if (ch === -1) {
+ warn("findDefaultInlineStreamEnd: " + "Reached the end of the stream without finding a valid EI marker");
+ if (maybeEIPos) {
+ warn('... trying to recover by using the last "EI" occurrence.');
+ stream.skip(-(stream.pos - maybeEIPos));
+ }
+ }
+ let endOffset = 4;
+ stream.skip(-endOffset);
+ ch = stream.peekByte();
+ stream.skip(endOffset);
+ if (!isWhiteSpace(ch)) {
+ endOffset--;
+ }
+ return stream.pos - endOffset - startPos;
+ }
+ findDCTDecodeInlineStreamEnd(stream) {
+ const startPos = stream.pos;
+ let foundEOI = false,
+ b,
+ markerLength;
+ while ((b = stream.getByte()) !== -1) {
+ if (b !== 0xff) {
+ continue;
+ }
+ switch (stream.getByte()) {
+ case 0x00:
+ break;
+ case 0xff:
+ stream.skip(-1);
+ break;
+ case 0xd9:
+ foundEOI = true;
+ break;
+ case 0xc0:
+ case 0xc1:
+ case 0xc2:
+ case 0xc3:
+ case 0xc5:
+ case 0xc6:
+ case 0xc7:
+ case 0xc9:
+ case 0xca:
+ case 0xcb:
+ case 0xcd:
+ case 0xce:
+ case 0xcf:
+ case 0xc4:
+ case 0xcc:
+ case 0xda:
+ case 0xdb:
+ case 0xdc:
+ case 0xdd:
+ case 0xde:
+ case 0xdf:
+ case 0xe0:
+ case 0xe1:
+ case 0xe2:
+ case 0xe3:
+ case 0xe4:
+ case 0xe5:
+ case 0xe6:
+ case 0xe7:
+ case 0xe8:
+ case 0xe9:
+ case 0xea:
+ case 0xeb:
+ case 0xec:
+ case 0xed:
+ case 0xee:
+ case 0xef:
+ case 0xfe:
+ markerLength = stream.getUint16();
+ if (markerLength > 2) {
+ stream.skip(markerLength - 2);
+ } else {
+ stream.skip(-2);
+ }
+ break;
+ }
+ if (foundEOI) {
+ break;
+ }
+ }
+ const length = stream.pos - startPos;
+ if (b === -1) {
+ warn("Inline DCTDecode image stream: " + "EOI marker not found, searching for /EI/ instead.");
+ stream.skip(-length);
+ return this.findDefaultInlineStreamEnd(stream);
+ }
+ this.inlineStreamSkipEI(stream);
+ return length;
+ }
+ findASCII85DecodeInlineStreamEnd(stream) {
+ const TILDE = 0x7e,
+ GT = 0x3e;
+ const startPos = stream.pos;
+ let ch;
+ while ((ch = stream.getByte()) !== -1) {
+ if (ch === TILDE) {
+ const tildePos = stream.pos;
+ ch = stream.peekByte();
+ while (isWhiteSpace(ch)) {
+ stream.skip();
+ ch = stream.peekByte();
+ }
+ if (ch === GT) {
+ stream.skip();
+ break;
+ }
+ if (stream.pos > tildePos) {
+ const maybeEI = stream.peekBytes(2);
+ if (maybeEI[0] === 0x45 && maybeEI[1] === 0x49) {
+ break;
+ }
+ }
+ }
+ }
+ const length = stream.pos - startPos;
+ if (ch === -1) {
+ warn("Inline ASCII85Decode image stream: " + "EOD marker not found, searching for /EI/ instead.");
+ stream.skip(-length);
+ return this.findDefaultInlineStreamEnd(stream);
+ }
+ this.inlineStreamSkipEI(stream);
+ return length;
+ }
+ findASCIIHexDecodeInlineStreamEnd(stream) {
+ const GT = 0x3e;
+ const startPos = stream.pos;
+ let ch;
+ while ((ch = stream.getByte()) !== -1) {
+ if (ch === GT) {
+ break;
+ }
+ }
+ const length = stream.pos - startPos;
+ if (ch === -1) {
+ warn("Inline ASCIIHexDecode image stream: " + "EOD marker not found, searching for /EI/ instead.");
+ stream.skip(-length);
+ return this.findDefaultInlineStreamEnd(stream);
+ }
+ this.inlineStreamSkipEI(stream);
+ return length;
+ }
+ inlineStreamSkipEI(stream) {
+ const E = 0x45,
+ I = 0x49;
+ let state = 0,
+ ch;
+ while ((ch = stream.getByte()) !== -1) {
+ if (state === 0) {
+ state = ch === E ? 1 : 0;
+ } else if (state === 1) {
+ state = ch === I ? 2 : 0;
+ } else if (state === 2) {
+ break;
+ }
+ }
+ }
+ makeInlineImage(cipherTransform) {
+ const lexer = this.lexer;
+ const stream = lexer.stream;
+ const dictMap = Object.create(null);
+ let dictLength;
+ while (!isCmd(this.buf1, "ID") && this.buf1 !== EOF) {
+ if (!(this.buf1 instanceof Name)) {
+ throw new FormatError("Dictionary key must be a name object");
+ }
+ const key = this.buf1.name;
+ this.shift();
+ if (this.buf1 === EOF) {
+ break;
+ }
+ dictMap[key] = this.getObj(cipherTransform);
+ }
+ if (lexer.beginInlineImagePos !== -1) {
+ dictLength = stream.pos - lexer.beginInlineImagePos;
+ }
+ const filter = this.xref.fetchIfRef(dictMap.F || dictMap.Filter);
+ let filterName;
+ if (filter instanceof Name) {
+ filterName = filter.name;
+ } else if (Array.isArray(filter)) {
+ const filterZero = this.xref.fetchIfRef(filter[0]);
+ if (filterZero instanceof Name) {
+ filterName = filterZero.name;
+ }
+ }
+ const startPos = stream.pos;
+ let length;
+ switch (filterName) {
+ case "DCT":
+ case "DCTDecode":
+ length = this.findDCTDecodeInlineStreamEnd(stream);
+ break;
+ case "A85":
+ case "ASCII85Decode":
+ length = this.findASCII85DecodeInlineStreamEnd(stream);
+ break;
+ case "AHx":
+ case "ASCIIHexDecode":
+ length = this.findASCIIHexDecodeInlineStreamEnd(stream);
+ break;
+ default:
+ length = this.findDefaultInlineStreamEnd(stream);
+ }
+ let cacheKey;
+ if (length < MAX_LENGTH_TO_CACHE && dictLength > 0) {
+ const initialStreamPos = stream.pos;
+ stream.pos = lexer.beginInlineImagePos;
+ cacheKey = getInlineImageCacheKey(stream.getBytes(dictLength + length));
+ stream.pos = initialStreamPos;
+ const cacheEntry = this.imageCache[cacheKey];
+ if (cacheEntry !== undefined) {
+ this.buf2 = Cmd.get("EI");
+ this.shift();
+ cacheEntry.reset();
+ return cacheEntry;
+ }
+ }
+ const dict = new Dict(this.xref);
+ for (const key in dictMap) {
+ dict.set(key, dictMap[key]);
+ }
+ let imageStream = stream.makeSubStream(startPos, length, dict);
+ if (cipherTransform) {
+ imageStream = cipherTransform.createStream(imageStream, length);
+ }
+ imageStream = this.filter(imageStream, dict, length);
+ imageStream.dict = dict;
+ if (cacheKey !== undefined) {
+ imageStream.cacheKey = `inline_img_${++this._imageId}`;
+ this.imageCache[cacheKey] = imageStream;
+ }
+ this.buf2 = Cmd.get("EI");
+ this.shift();
+ return imageStream;
+ }
+ _findStreamLength(startPos, signature) {
+ const {
+ stream
+ } = this.lexer;
+ stream.pos = startPos;
+ const SCAN_BLOCK_LENGTH = 2048;
+ const signatureLength = signature.length;
+ while (stream.pos < stream.end) {
+ const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
+ const scanLength = scanBytes.length - signatureLength;
+ if (scanLength <= 0) {
+ break;
+ }
+ let pos = 0;
+ while (pos < scanLength) {
+ let j = 0;
+ while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
+ j++;
+ }
+ if (j >= signatureLength) {
+ stream.pos += pos;
+ return stream.pos - startPos;
+ }
+ pos++;
+ }
+ stream.pos += scanLength;
+ }
+ return -1;
+ }
+ makeStream(dict, cipherTransform) {
+ const lexer = this.lexer;
+ let stream = lexer.stream;
+ lexer.skipToNextLine();
+ const startPos = stream.pos - 1;
+ let length = dict.get("Length");
+ if (!Number.isInteger(length)) {
+ info(`Bad length "${length && length.toString()}" in stream.`);
+ length = 0;
+ }
+ stream.pos = startPos + length;
+ lexer.nextChar();
+ if (this.tryShift() && isCmd(this.buf2, "endstream")) {
+ this.shift();
+ } else {
+ const ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]);
+ let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE);
+ if (actualLength < 0) {
+ const MAX_TRUNCATION = 1;
+ for (let i = 1; i <= MAX_TRUNCATION; i++) {
+ const end = ENDSTREAM_SIGNATURE.length - i;
+ const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end);
+ const maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE);
+ if (maybeLength >= 0) {
+ const lastByte = stream.peekBytes(end + 1)[end];
+ if (!isWhiteSpace(lastByte)) {
+ break;
+ }
+ info(`Found "${bytesToString(TRUNCATED_SIGNATURE)}" when ` + "searching for endstream command.");
+ actualLength = maybeLength;
+ break;
+ }
+ }
+ if (actualLength < 0) {
+ throw new FormatError("Missing endstream command.");
+ }
+ }
+ length = actualLength;
+ lexer.nextChar();
+ this.shift();
+ this.shift();
+ }
+ this.shift();
+ stream = stream.makeSubStream(startPos, length, dict);
+ if (cipherTransform) {
+ stream = cipherTransform.createStream(stream, length);
+ }
+ stream = this.filter(stream, dict, length);
+ stream.dict = dict;
+ return stream;
+ }
+ filter(stream, dict, length) {
+ let filter = dict.get("F", "Filter");
+ let params = dict.get("DP", "DecodeParms");
+ if (filter instanceof Name) {
+ if (Array.isArray(params)) {
+ warn("/DecodeParms should not be an Array, when /Filter is a Name.");
+ }
+ return this.makeFilter(stream, filter.name, length, params);
+ }
+ let maybeLength = length;
+ if (Array.isArray(filter)) {
+ const filterArray = filter;
+ const paramsArray = params;
+ for (let i = 0, ii = filterArray.length; i < ii; ++i) {
+ filter = this.xref.fetchIfRef(filterArray[i]);
+ if (!(filter instanceof Name)) {
+ throw new FormatError(`Bad filter name "${filter}"`);
+ }
+ params = null;
+ if (Array.isArray(paramsArray) && i in paramsArray) {
+ params = this.xref.fetchIfRef(paramsArray[i]);
+ }
+ stream = this.makeFilter(stream, filter.name, maybeLength, params);
+ maybeLength = null;
+ }
+ }
+ return stream;
+ }
+ makeFilter(stream, name, maybeLength, params) {
+ if (maybeLength === 0) {
+ warn(`Empty "${name}" stream.`);
+ return new NullStream();
+ }
+ try {
+ switch (name) {
+ case "Fl":
+ case "FlateDecode":
+ if (params) {
+ return new PredictorStream(new FlateStream(stream, maybeLength), maybeLength, params);
+ }
+ return new FlateStream(stream, maybeLength);
+ case "LZW":
+ case "LZWDecode":
+ let earlyChange = 1;
+ if (params) {
+ if (params.has("EarlyChange")) {
+ earlyChange = params.get("EarlyChange");
+ }
+ return new PredictorStream(new LZWStream(stream, maybeLength, earlyChange), maybeLength, params);
+ }
+ return new LZWStream(stream, maybeLength, earlyChange);
+ case "DCT":
+ case "DCTDecode":
+ return new JpegStream(stream, maybeLength, params);
+ case "JPX":
+ case "JPXDecode":
+ return new JpxStream(stream, maybeLength, params);
+ case "A85":
+ case "ASCII85Decode":
+ return new Ascii85Stream(stream, maybeLength);
+ case "AHx":
+ case "ASCIIHexDecode":
+ return new AsciiHexStream(stream, maybeLength);
+ case "CCF":
+ case "CCITTFaxDecode":
+ return new CCITTFaxStream(stream, maybeLength, params);
+ case "RL":
+ case "RunLengthDecode":
+ return new RunLengthStream(stream, maybeLength);
+ case "JBIG2Decode":
+ return new Jbig2Stream(stream, maybeLength, params);
+ }
+ warn(`Filter "${name}" is not supported.`);
+ return stream;
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`Invalid stream: "${ex}"`);
+ return new NullStream();
+ }
+ }
+}
+const specialChars = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+function toHexDigit(ch) {
+ if (ch >= 0x30 && ch <= 0x39) {
+ return ch & 0x0f;
+ }
+ if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
+ return (ch & 0x0f) + 9;
+ }
+ return -1;
+}
+class Lexer {
+ constructor(stream, knownCommands = null) {
+ this.stream = stream;
+ this.nextChar();
+ this.strBuf = [];
+ this.knownCommands = knownCommands;
+ this._hexStringNumWarn = 0;
+ this.beginInlineImagePos = -1;
+ }
+ nextChar() {
+ return this.currentChar = this.stream.getByte();
+ }
+ peekChar() {
+ return this.stream.peekByte();
+ }
+ getNumber() {
+ let ch = this.currentChar;
+ let eNotation = false;
+ let divideBy = 0;
+ let sign = 1;
+ if (ch === 0x2d) {
+ sign = -1;
+ ch = this.nextChar();
+ if (ch === 0x2d) {
+ ch = this.nextChar();
+ }
+ } else if (ch === 0x2b) {
+ ch = this.nextChar();
+ }
+ if (ch === 0x0a || ch === 0x0d) {
+ do {
+ ch = this.nextChar();
+ } while (ch === 0x0a || ch === 0x0d);
+ }
+ if (ch === 0x2e) {
+ divideBy = 10;
+ ch = this.nextChar();
+ }
+ if (ch < 0x30 || ch > 0x39) {
+ const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`;
+ if (isWhiteSpace(ch) || ch === -1) {
+ info(`Lexer.getNumber - "${msg}".`);
+ return 0;
+ }
+ throw new FormatError(msg);
+ }
+ let baseValue = ch - 0x30;
+ let powerValue = 0;
+ let powerValueSign = 1;
+ while ((ch = this.nextChar()) >= 0) {
+ if (ch >= 0x30 && ch <= 0x39) {
+ const currentDigit = ch - 0x30;
+ if (eNotation) {
+ powerValue = powerValue * 10 + currentDigit;
+ } else {
+ if (divideBy !== 0) {
+ divideBy *= 10;
+ }
+ baseValue = baseValue * 10 + currentDigit;
+ }
+ } else if (ch === 0x2e) {
+ if (divideBy === 0) {
+ divideBy = 1;
+ } else {
+ break;
+ }
+ } else if (ch === 0x2d) {
+ warn("Badly formatted number: minus sign in the middle");
+ } else if (ch === 0x45 || ch === 0x65) {
+ ch = this.peekChar();
+ if (ch === 0x2b || ch === 0x2d) {
+ powerValueSign = ch === 0x2d ? -1 : 1;
+ this.nextChar();
+ } else if (ch < 0x30 || ch > 0x39) {
+ break;
+ }
+ eNotation = true;
+ } else {
+ break;
+ }
+ }
+ if (divideBy !== 0) {
+ baseValue /= divideBy;
+ }
+ if (eNotation) {
+ baseValue *= 10 ** (powerValueSign * powerValue);
+ }
+ return sign * baseValue;
+ }
+ getString() {
+ let numParen = 1;
+ let done = false;
+ const strBuf = this.strBuf;
+ strBuf.length = 0;
+ let ch = this.nextChar();
+ while (true) {
+ let charBuffered = false;
+ switch (ch | 0) {
+ case -1:
+ warn("Unterminated string");
+ done = true;
+ break;
+ case 0x28:
+ ++numParen;
+ strBuf.push("(");
+ break;
+ case 0x29:
+ if (--numParen === 0) {
+ this.nextChar();
+ done = true;
+ } else {
+ strBuf.push(")");
+ }
+ break;
+ case 0x5c:
+ ch = this.nextChar();
+ switch (ch) {
+ case -1:
+ warn("Unterminated string");
+ done = true;
+ break;
+ case 0x6e:
+ strBuf.push("\n");
+ break;
+ case 0x72:
+ strBuf.push("\r");
+ break;
+ case 0x74:
+ strBuf.push("\t");
+ break;
+ case 0x62:
+ strBuf.push("\b");
+ break;
+ case 0x66:
+ strBuf.push("\f");
+ break;
+ case 0x5c:
+ case 0x28:
+ case 0x29:
+ strBuf.push(String.fromCharCode(ch));
+ break;
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ let x = ch & 0x0f;
+ ch = this.nextChar();
+ charBuffered = true;
+ if (ch >= 0x30 && ch <= 0x37) {
+ x = (x << 3) + (ch & 0x0f);
+ ch = this.nextChar();
+ if (ch >= 0x30 && ch <= 0x37) {
+ charBuffered = false;
+ x = (x << 3) + (ch & 0x0f);
+ }
+ }
+ strBuf.push(String.fromCharCode(x));
+ break;
+ case 0x0d:
+ if (this.peekChar() === 0x0a) {
+ this.nextChar();
+ }
+ break;
+ case 0x0a:
+ break;
+ default:
+ strBuf.push(String.fromCharCode(ch));
+ break;
+ }
+ break;
+ default:
+ strBuf.push(String.fromCharCode(ch));
+ break;
+ }
+ if (done) {
+ break;
+ }
+ if (!charBuffered) {
+ ch = this.nextChar();
+ }
+ }
+ return strBuf.join("");
+ }
+ getName() {
+ let ch, previousCh;
+ const strBuf = this.strBuf;
+ strBuf.length = 0;
+ while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
+ if (ch === 0x23) {
+ ch = this.nextChar();
+ if (specialChars[ch]) {
+ warn("Lexer_getName: " + "NUMBER SIGN (#) should be followed by a hexadecimal number.");
+ strBuf.push("#");
+ break;
+ }
+ const x = toHexDigit(ch);
+ if (x !== -1) {
+ previousCh = ch;
+ ch = this.nextChar();
+ const x2 = toHexDigit(ch);
+ if (x2 === -1) {
+ warn(`Lexer_getName: Illegal digit (${String.fromCharCode(ch)}) ` + "in hexadecimal number.");
+ strBuf.push("#", String.fromCharCode(previousCh));
+ if (specialChars[ch]) {
+ break;
+ }
+ strBuf.push(String.fromCharCode(ch));
+ continue;
+ }
+ strBuf.push(String.fromCharCode(x << 4 | x2));
+ } else {
+ strBuf.push("#", String.fromCharCode(ch));
+ }
+ } else {
+ strBuf.push(String.fromCharCode(ch));
+ }
+ }
+ if (strBuf.length > 127) {
+ warn(`Name token is longer than allowed by the spec: ${strBuf.length}`);
+ }
+ return Name.get(strBuf.join(""));
+ }
+ _hexStringWarn(ch) {
+ const MAX_HEX_STRING_NUM_WARN = 5;
+ if (this._hexStringNumWarn++ === MAX_HEX_STRING_NUM_WARN) {
+ warn("getHexString - ignoring additional invalid characters.");
+ return;
+ }
+ if (this._hexStringNumWarn > MAX_HEX_STRING_NUM_WARN) {
+ return;
+ }
+ warn(`getHexString - ignoring invalid character: ${ch}`);
+ }
+ getHexString() {
+ const strBuf = this.strBuf;
+ strBuf.length = 0;
+ let ch = this.currentChar;
+ let isFirstHex = true;
+ let firstDigit, secondDigit;
+ this._hexStringNumWarn = 0;
+ while (true) {
+ if (ch < 0) {
+ warn("Unterminated hex string");
+ break;
+ } else if (ch === 0x3e) {
+ this.nextChar();
+ break;
+ } else if (specialChars[ch] === 1) {
+ ch = this.nextChar();
+ continue;
+ } else {
+ if (isFirstHex) {
+ firstDigit = toHexDigit(ch);
+ if (firstDigit === -1) {
+ this._hexStringWarn(ch);
+ ch = this.nextChar();
+ continue;
+ }
+ } else {
+ secondDigit = toHexDigit(ch);
+ if (secondDigit === -1) {
+ this._hexStringWarn(ch);
+ ch = this.nextChar();
+ continue;
+ }
+ strBuf.push(String.fromCharCode(firstDigit << 4 | secondDigit));
+ }
+ isFirstHex = !isFirstHex;
+ ch = this.nextChar();
+ }
+ }
+ return strBuf.join("");
+ }
+ getObj() {
+ let comment = false;
+ let ch = this.currentChar;
+ while (true) {
+ if (ch < 0) {
+ return EOF;
+ }
+ if (comment) {
+ if (ch === 0x0a || ch === 0x0d) {
+ comment = false;
+ }
+ } else if (ch === 0x25) {
+ comment = true;
+ } else if (specialChars[ch] !== 1) {
+ break;
+ }
+ ch = this.nextChar();
+ }
+ switch (ch | 0) {
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ case 0x2b:
+ case 0x2d:
+ case 0x2e:
+ return this.getNumber();
+ case 0x28:
+ return this.getString();
+ case 0x2f:
+ return this.getName();
+ case 0x5b:
+ this.nextChar();
+ return Cmd.get("[");
+ case 0x5d:
+ this.nextChar();
+ return Cmd.get("]");
+ case 0x3c:
+ ch = this.nextChar();
+ if (ch === 0x3c) {
+ this.nextChar();
+ return Cmd.get("<<");
+ }
+ return this.getHexString();
+ case 0x3e:
+ ch = this.nextChar();
+ if (ch === 0x3e) {
+ this.nextChar();
+ return Cmd.get(">>");
+ }
+ return Cmd.get(">");
+ case 0x7b:
+ this.nextChar();
+ return Cmd.get("{");
+ case 0x7d:
+ this.nextChar();
+ return Cmd.get("}");
+ case 0x29:
+ this.nextChar();
+ throw new FormatError(`Illegal character: ${ch}`);
+ }
+ let str = String.fromCharCode(ch);
+ if (ch < 0x20 || ch > 0x7f) {
+ const nextCh = this.peekChar();
+ if (nextCh >= 0x20 && nextCh <= 0x7f) {
+ this.nextChar();
+ return Cmd.get(str);
+ }
+ }
+ const knownCommands = this.knownCommands;
+ let knownCommandFound = knownCommands?.[str] !== undefined;
+ while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
+ const possibleCommand = str + String.fromCharCode(ch);
+ if (knownCommandFound && knownCommands[possibleCommand] === undefined) {
+ break;
+ }
+ if (str.length === 128) {
+ throw new FormatError(`Command token too long: ${str.length}`);
+ }
+ str = possibleCommand;
+ knownCommandFound = knownCommands?.[str] !== undefined;
+ }
+ if (str === "true") {
+ return true;
+ }
+ if (str === "false") {
+ return false;
+ }
+ if (str === "null") {
+ return null;
+ }
+ if (str === "BI") {
+ this.beginInlineImagePos = this.stream.pos;
+ }
+ return Cmd.get(str);
+ }
+ skipToNextLine() {
+ let ch = this.currentChar;
+ while (ch >= 0) {
+ if (ch === 0x0d) {
+ ch = this.nextChar();
+ if (ch === 0x0a) {
+ this.nextChar();
+ }
+ break;
+ } else if (ch === 0x0a) {
+ this.nextChar();
+ break;
+ }
+ ch = this.nextChar();
+ }
+ }
+}
+class Linearization {
+ static create(stream) {
+ function getInt(linDict, name, allowZeroValue = false) {
+ const obj = linDict.get(name);
+ if (Number.isInteger(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) {
+ return obj;
+ }
+ throw new Error(`The "${name}" parameter in the linearization ` + "dictionary is invalid.");
+ }
+ function getHints(linDict) {
+ const hints = linDict.get("H");
+ let hintsLength;
+ if (Array.isArray(hints) && ((hintsLength = hints.length) === 2 || hintsLength === 4)) {
+ for (let index = 0; index < hintsLength; index++) {
+ const hint = hints[index];
+ if (!(Number.isInteger(hint) && hint > 0)) {
+ throw new Error(`Hint (${index}) in the linearization dictionary is invalid.`);
+ }
+ }
+ return hints;
+ }
+ throw new Error("Hint array in the linearization dictionary is invalid.");
+ }
+ const parser = new Parser({
+ lexer: new Lexer(stream),
+ xref: null
+ });
+ const obj1 = parser.getObj();
+ const obj2 = parser.getObj();
+ const obj3 = parser.getObj();
+ const linDict = parser.getObj();
+ let obj, length;
+ if (!(Number.isInteger(obj1) && Number.isInteger(obj2) && isCmd(obj3, "obj") && linDict instanceof Dict && typeof (obj = linDict.get("Linearized")) === "number" && obj > 0)) {
+ return null;
+ } else if ((length = getInt(linDict, "L")) !== stream.length) {
+ throw new Error('The "L" parameter in the linearization dictionary ' + "does not equal the stream length.");
+ }
+ return {
+ length,
+ hints: getHints(linDict),
+ objectNumberFirst: getInt(linDict, "O"),
+ endFirst: getInt(linDict, "E"),
+ numPages: getInt(linDict, "N"),
+ mainXRefEntriesOffset: getInt(linDict, "T"),
+ pageFirst: linDict.has("P") ? getInt(linDict, "P", true) : 0
+ };
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/cmap.js
+
+
+
+
+
+
+
+const BUILT_IN_CMAPS = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japan1-UCS2", "Adobe-Korea1-UCS2", "78-EUC-H", "78-EUC-V", "78-H", "78-RKSJ-H", "78-RKSJ-V", "78-V", "78ms-RKSJ-H", "78ms-RKSJ-V", "83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-RKSJ-H", "Add-RKSJ-V", "Add-V", "Adobe-CNS1-0", "Adobe-CNS1-1", "Adobe-CNS1-2", "Adobe-CNS1-3", "Adobe-CNS1-4", "Adobe-CNS1-5", "Adobe-CNS1-6", "Adobe-GB1-0", "Adobe-GB1-1", "Adobe-GB1-2", "Adobe-GB1-3", "Adobe-GB1-4", "Adobe-GB1-5", "Adobe-Japan1-0", "Adobe-Japan1-1", "Adobe-Japan1-2", "Adobe-Japan1-3", "Adobe-Japan1-4", "Adobe-Japan1-5", "Adobe-Japan1-6", "Adobe-Korea1-0", "Adobe-Korea1-1", "Adobe-Korea1-2", "B5-H", "B5-V", "B5pc-H", "B5pc-V", "CNS-EUC-H", "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "ETHK-B5-H", "ETHK-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "EUC-H", "EUC-V", "Ext-H", "Ext-RKSJ-H", "Ext-RKSJ-V", "Ext-V", "GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBK-EUC-H", "GBK-EUC-V", "GBK2K-H", "GBK2K-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBT-EUC-H", "GBT-EUC-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V", "H", "HKdla-B5-H", "HKdla-B5-V", "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", "HKm471-B5-V", "HKscs-B5-H", "HKscs-B5-V", "Hankaku", "Hiragana", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-Johab-H", "KSC-Johab-V", "KSC-V", "KSCms-UHC-H", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCms-UHC-V", "KSCpc-EUC-H", "KSCpc-EUC-V", "Katakana", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "Roman", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "UniCNS-UTF8-H", "UniCNS-UTF8-V", "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", "UniGB-UTF32-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniJIS-UCS2-H", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UCS2-V", "UniJIS-UTF16-H", "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS2004-UTF16-H", "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJISPro-UCS2-HW-V", "UniJISPro-UCS2-V", "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", "UniKS-UTF32-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "V", "WP-Symbol"];
+const MAX_MAP_RANGE = 2 ** 24 - 1;
+class CMap {
+ constructor(builtInCMap = false) {
+ this.codespaceRanges = [[], [], [], []];
+ this.numCodespaceRanges = 0;
+ this._map = [];
+ this.name = "";
+ this.vertical = false;
+ this.useCMap = null;
+ this.builtInCMap = builtInCMap;
+ }
+ addCodespaceRange(n, low, high) {
+ this.codespaceRanges[n - 1].push(low, high);
+ this.numCodespaceRanges++;
+ }
+ mapCidRange(low, high, dstLow) {
+ if (high - low > MAX_MAP_RANGE) {
+ throw new Error("mapCidRange - ignoring data above MAX_MAP_RANGE.");
+ }
+ while (low <= high) {
+ this._map[low++] = dstLow++;
+ }
+ }
+ mapBfRange(low, high, dstLow) {
+ if (high - low > MAX_MAP_RANGE) {
+ throw new Error("mapBfRange - ignoring data above MAX_MAP_RANGE.");
+ }
+ const lastByte = dstLow.length - 1;
+ while (low <= high) {
+ this._map[low++] = dstLow;
+ const nextCharCode = dstLow.charCodeAt(lastByte) + 1;
+ if (nextCharCode > 0xff) {
+ dstLow = dstLow.substring(0, lastByte - 1) + String.fromCharCode(dstLow.charCodeAt(lastByte - 1) + 1) + "\x00";
+ continue;
+ }
+ dstLow = dstLow.substring(0, lastByte) + String.fromCharCode(nextCharCode);
+ }
+ }
+ mapBfRangeToArray(low, high, array) {
+ if (high - low > MAX_MAP_RANGE) {
+ throw new Error("mapBfRangeToArray - ignoring data above MAX_MAP_RANGE.");
+ }
+ const ii = array.length;
+ let i = 0;
+ while (low <= high && i < ii) {
+ this._map[low] = array[i++];
+ ++low;
+ }
+ }
+ mapOne(src, dst) {
+ this._map[src] = dst;
+ }
+ lookup(code) {
+ return this._map[code];
+ }
+ contains(code) {
+ return this._map[code] !== undefined;
+ }
+ forEach(callback) {
+ const map = this._map;
+ const length = map.length;
+ if (length <= 0x10000) {
+ for (let i = 0; i < length; i++) {
+ if (map[i] !== undefined) {
+ callback(i, map[i]);
+ }
+ }
+ } else {
+ for (const i in map) {
+ callback(i, map[i]);
+ }
+ }
+ }
+ charCodeOf(value) {
+ const map = this._map;
+ if (map.length <= 0x10000) {
+ return map.indexOf(value);
+ }
+ for (const charCode in map) {
+ if (map[charCode] === value) {
+ return charCode | 0;
+ }
+ }
+ return -1;
+ }
+ getMap() {
+ return this._map;
+ }
+ readCharCode(str, offset, out) {
+ let c = 0;
+ const codespaceRanges = this.codespaceRanges;
+ for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {
+ c = (c << 8 | str.charCodeAt(offset + n)) >>> 0;
+ const codespaceRange = codespaceRanges[n];
+ for (let k = 0, kk = codespaceRange.length; k < kk;) {
+ const low = codespaceRange[k++];
+ const high = codespaceRange[k++];
+ if (c >= low && c <= high) {
+ out.charcode = c;
+ out.length = n + 1;
+ return;
+ }
+ }
+ }
+ out.charcode = 0;
+ out.length = 1;
+ }
+ getCharCodeLength(charCode) {
+ const codespaceRanges = this.codespaceRanges;
+ for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {
+ const codespaceRange = codespaceRanges[n];
+ for (let k = 0, kk = codespaceRange.length; k < kk;) {
+ const low = codespaceRange[k++];
+ const high = codespaceRange[k++];
+ if (charCode >= low && charCode <= high) {
+ return n + 1;
+ }
+ }
+ }
+ return 1;
+ }
+ get length() {
+ return this._map.length;
+ }
+ get isIdentityCMap() {
+ if (!(this.name === "Identity-H" || this.name === "Identity-V")) {
+ return false;
+ }
+ if (this._map.length !== 0x10000) {
+ return false;
+ }
+ for (let i = 0; i < 0x10000; i++) {
+ if (this._map[i] !== i) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+class IdentityCMap extends CMap {
+ constructor(vertical, n) {
+ super();
+ this.vertical = vertical;
+ this.addCodespaceRange(n, 0, 0xffff);
+ }
+ mapCidRange(low, high, dstLow) {
+ unreachable("should not call mapCidRange");
+ }
+ mapBfRange(low, high, dstLow) {
+ unreachable("should not call mapBfRange");
+ }
+ mapBfRangeToArray(low, high, array) {
+ unreachable("should not call mapBfRangeToArray");
+ }
+ mapOne(src, dst) {
+ unreachable("should not call mapCidOne");
+ }
+ lookup(code) {
+ return Number.isInteger(code) && code <= 0xffff ? code : undefined;
+ }
+ contains(code) {
+ return Number.isInteger(code) && code <= 0xffff;
+ }
+ forEach(callback) {
+ for (let i = 0; i <= 0xffff; i++) {
+ callback(i, i);
+ }
+ }
+ charCodeOf(value) {
+ return Number.isInteger(value) && value <= 0xffff ? value : -1;
+ }
+ getMap() {
+ const map = new Array(0x10000);
+ for (let i = 0; i <= 0xffff; i++) {
+ map[i] = i;
+ }
+ return map;
+ }
+ get length() {
+ return 0x10000;
+ }
+ get isIdentityCMap() {
+ unreachable("should not access .isIdentityCMap");
+ }
+}
+function strToInt(str) {
+ let a = 0;
+ for (let i = 0; i < str.length; i++) {
+ a = a << 8 | str.charCodeAt(i);
+ }
+ return a >>> 0;
+}
+function expectString(obj) {
+ if (typeof obj !== "string") {
+ throw new FormatError("Malformed CMap: expected string.");
+ }
+}
+function expectInt(obj) {
+ if (!Number.isInteger(obj)) {
+ throw new FormatError("Malformed CMap: expected int.");
+ }
+}
+function parseBfChar(cMap, lexer) {
+ while (true) {
+ let obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ }
+ if (isCmd(obj, "endbfchar")) {
+ return;
+ }
+ expectString(obj);
+ const src = strToInt(obj);
+ obj = lexer.getObj();
+ expectString(obj);
+ const dst = obj;
+ cMap.mapOne(src, dst);
+ }
+}
+function parseBfRange(cMap, lexer) {
+ while (true) {
+ let obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ }
+ if (isCmd(obj, "endbfrange")) {
+ return;
+ }
+ expectString(obj);
+ const low = strToInt(obj);
+ obj = lexer.getObj();
+ expectString(obj);
+ const high = strToInt(obj);
+ obj = lexer.getObj();
+ if (Number.isInteger(obj) || typeof obj === "string") {
+ const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;
+ cMap.mapBfRange(low, high, dstLow);
+ } else if (isCmd(obj, "[")) {
+ obj = lexer.getObj();
+ const array = [];
+ while (!isCmd(obj, "]") && obj !== EOF) {
+ array.push(obj);
+ obj = lexer.getObj();
+ }
+ cMap.mapBfRangeToArray(low, high, array);
+ } else {
+ break;
+ }
+ }
+ throw new FormatError("Invalid bf range.");
+}
+function parseCidChar(cMap, lexer) {
+ while (true) {
+ let obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ }
+ if (isCmd(obj, "endcidchar")) {
+ return;
+ }
+ expectString(obj);
+ const src = strToInt(obj);
+ obj = lexer.getObj();
+ expectInt(obj);
+ const dst = obj;
+ cMap.mapOne(src, dst);
+ }
+}
+function parseCidRange(cMap, lexer) {
+ while (true) {
+ let obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ }
+ if (isCmd(obj, "endcidrange")) {
+ return;
+ }
+ expectString(obj);
+ const low = strToInt(obj);
+ obj = lexer.getObj();
+ expectString(obj);
+ const high = strToInt(obj);
+ obj = lexer.getObj();
+ expectInt(obj);
+ const dstLow = obj;
+ cMap.mapCidRange(low, high, dstLow);
+ }
+}
+function parseCodespaceRange(cMap, lexer) {
+ while (true) {
+ let obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ }
+ if (isCmd(obj, "endcodespacerange")) {
+ return;
+ }
+ if (typeof obj !== "string") {
+ break;
+ }
+ const low = strToInt(obj);
+ obj = lexer.getObj();
+ if (typeof obj !== "string") {
+ break;
+ }
+ const high = strToInt(obj);
+ cMap.addCodespaceRange(obj.length, low, high);
+ }
+ throw new FormatError("Invalid codespace range.");
+}
+function parseWMode(cMap, lexer) {
+ const obj = lexer.getObj();
+ if (Number.isInteger(obj)) {
+ cMap.vertical = !!obj;
+ }
+}
+function parseCMapName(cMap, lexer) {
+ const obj = lexer.getObj();
+ if (obj instanceof Name) {
+ cMap.name = obj.name;
+ }
+}
+async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
+ let previous, embeddedUseCMap;
+ objLoop: while (true) {
+ try {
+ const obj = lexer.getObj();
+ if (obj === EOF) {
+ break;
+ } else if (obj instanceof Name) {
+ if (obj.name === "WMode") {
+ parseWMode(cMap, lexer);
+ } else if (obj.name === "CMapName") {
+ parseCMapName(cMap, lexer);
+ }
+ previous = obj;
+ } else if (obj instanceof Cmd) {
+ switch (obj.cmd) {
+ case "endcmap":
+ break objLoop;
+ case "usecmap":
+ if (previous instanceof Name) {
+ embeddedUseCMap = previous.name;
+ }
+ break;
+ case "begincodespacerange":
+ parseCodespaceRange(cMap, lexer);
+ break;
+ case "beginbfchar":
+ parseBfChar(cMap, lexer);
+ break;
+ case "begincidchar":
+ parseCidChar(cMap, lexer);
+ break;
+ case "beginbfrange":
+ parseBfRange(cMap, lexer);
+ break;
+ case "begincidrange":
+ parseCidRange(cMap, lexer);
+ break;
+ }
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Invalid cMap data: " + ex);
+ continue;
+ }
+ }
+ if (!useCMap && embeddedUseCMap) {
+ useCMap = embeddedUseCMap;
+ }
+ if (useCMap) {
+ return extendCMap(cMap, fetchBuiltInCMap, useCMap);
+ }
+ return cMap;
+}
+async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
+ cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);
+ if (cMap.numCodespaceRanges === 0) {
+ const useCodespaceRanges = cMap.useCMap.codespaceRanges;
+ for (let i = 0; i < useCodespaceRanges.length; i++) {
+ cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
+ }
+ cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
+ }
+ cMap.useCMap.forEach(function (key, value) {
+ if (!cMap.contains(key)) {
+ cMap.mapOne(key, cMap.useCMap.lookup(key));
+ }
+ });
+ return cMap;
+}
+async function createBuiltInCMap(name, fetchBuiltInCMap) {
+ if (name === "Identity-H") {
+ return new IdentityCMap(false, 2);
+ } else if (name === "Identity-V") {
+ return new IdentityCMap(true, 2);
+ }
+ if (!BUILT_IN_CMAPS.includes(name)) {
+ throw new Error("Unknown CMap name: " + name);
+ }
+ if (!fetchBuiltInCMap) {
+ throw new Error("Built-in CMap parameters are not provided.");
+ }
+ const {
+ cMapData,
+ compressionType
+ } = await fetchBuiltInCMap(name);
+ const cMap = new CMap(true);
+ if (compressionType === CMapCompressionType.BINARY) {
+ return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
+ return extendCMap(cMap, fetchBuiltInCMap, useCMap);
+ });
+ }
+ if (compressionType === CMapCompressionType.NONE) {
+ const lexer = new Lexer(new Stream(cMapData));
+ return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
+ }
+ throw new Error(`Invalid CMap "compressionType" value: ${compressionType}`);
+}
+class CMapFactory {
+ static async create({
+ encoding,
+ fetchBuiltInCMap,
+ useCMap
+ }) {
+ if (encoding instanceof Name) {
+ return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
+ } else if (encoding instanceof BaseStream) {
+ const parsedCMap = await parseCMap(new CMap(), new Lexer(encoding), fetchBuiltInCMap, useCMap);
+ if (parsedCMap.isIdentityCMap) {
+ return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
+ }
+ return parsedCMap;
+ }
+ throw new Error("Encoding required.");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/charsets.js
+const ISOAdobeCharset = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron"];
+const ExpertCharset = [".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"];
+const ExpertSubsetCharset = [".notdef", "space", "dollaroldstyle", "dollarsuperior", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior"];
+
+;// CONCATENATED MODULE: ./src/core/encodings.js
+const ExpertEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "", "", "", "isuperior", "", "", "lsuperior", "msuperior", "nsuperior", "osuperior", "", "", "rsuperior", "ssuperior", "tsuperior", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdownsmall", "centoldstyle", "Lslashsmall", "", "", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "", "Dotaccentsmall", "", "", "Macronsmall", "", "", "figuredash", "hypheninferior", "", "", "Ogoneksmall", "Ringsmall", "Cedillasmall", "", "", "", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"];
+const MacExpertEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "", "threequartersemdash", "", "questionsmall", "", "", "", "", "Ethsmall", "", "", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "", "", "", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "asuperior", "centsuperior", "", "", "", "", "Aacutesmall", "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall", "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall", "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall", "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall", "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall", "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", "", "eightsuperior", "fourinferior", "threeinferior", "sixinferior", "eightinferior", "seveninferior", "Scaronsmall", "", "centinferior", "twoinferior", "", "Dieresissmall", "", "Caronsmall", "osuperior", "fiveinferior", "", "commainferior", "periodinferior", "Yacutesmall", "", "dollarinferior", "", "", "Thornsmall", "", "nineinferior", "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall", "questiondownsmall", "oneinferior", "Lslashsmall", "", "", "", "", "", "", "Cedillasmall", "", "", "", "", "", "OEsmall", "figuredash", "hyphensuperior", "", "", "", "", "exclamdownsmall", "", "Ydieresissmall", "", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "ninesuperior", "zerosuperior", "", "esuperior", "rsuperior", "tsuperior", "", "", "isuperior", "ssuperior", "dsuperior", "", "", "", "", "", "lsuperior", "Ogoneksmall", "Brevesmall", "Macronsmall", "bsuperior", "nsuperior", "msuperior", "commasuperior", "periodsuperior", "Dotaccentsmall", "Ringsmall", "", "", "", ""];
+const MacRomanEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron"];
+const StandardEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", ""];
+const WinAnsiEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "bullet", "Euro", "bullet", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "bullet", "zcaron", "Ydieresis", "space", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"];
+const SymbolSetEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "universal", "numbersign", "existential", "percent", "ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", "plus", "comma", "minus", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "congruent", "Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "theta1", "Kappa", "Lambda", "Mu", "Nu", "Omicron", "Pi", "Theta", "Rho", "Sigma", "Tau", "Upsilon", "sigma1", "Omega", "Xi", "Psi", "Zeta", "bracketleft", "therefore", "bracketright", "perpendicular", "underscore", "radicalex", "alpha", "beta", "chi", "delta", "epsilon", "phi", "gamma", "eta", "iota", "phi1", "kappa", "lambda", "mu", "nu", "omicron", "pi", "theta", "rho", "sigma", "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta", "braceleft", "bar", "braceright", "similar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Euro", "Upsilon1", "minute", "lessequal", "fraction", "infinity", "florin", "club", "diamond", "heart", "spade", "arrowboth", "arrowleft", "arrowup", "arrowright", "arrowdown", "degree", "plusminus", "second", "greaterequal", "multiply", "proportional", "partialdiff", "bullet", "divide", "notequal", "equivalence", "approxequal", "ellipsis", "arrowvertex", "arrowhorizex", "carriagereturn", "aleph", "Ifraktur", "Rfraktur", "weierstrass", "circlemultiply", "circleplus", "emptyset", "intersection", "union", "propersuperset", "reflexsuperset", "notsubset", "propersubset", "reflexsubset", "element", "notelement", "angle", "gradient", "registerserif", "copyrightserif", "trademarkserif", "product", "radical", "dotmath", "logicalnot", "logicaland", "logicalor", "arrowdblboth", "arrowdblleft", "arrowdblup", "arrowdblright", "arrowdbldown", "lozenge", "angleleft", "registersans", "copyrightsans", "trademarksans", "summation", "parenlefttp", "parenleftex", "parenleftbt", "bracketlefttp", "bracketleftex", "bracketleftbt", "bracelefttp", "braceleftmid", "braceleftbt", "braceex", "", "angleright", "integral", "integraltp", "integralex", "integralbt", "parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp", "bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid", "bracerightbt", ""];
+const ZapfDingbatsEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", "a97", "a98", "a99", "a100", "", "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", "a206", "a86", "a87", "a88", "a95", "a96", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "a101", "a102", "a103", "a104", "a106", "a107", "a108", "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", "", "a201", "a183", "a184", "a197", "a185", "a194", "a198", "a186", "a195", "a187", "a188", "a189", "a190", "a191", ""];
+function getEncoding(encodingName) {
+ switch (encodingName) {
+ case "WinAnsiEncoding":
+ return WinAnsiEncoding;
+ case "StandardEncoding":
+ return StandardEncoding;
+ case "MacRomanEncoding":
+ return MacRomanEncoding;
+ case "SymbolSetEncoding":
+ return SymbolSetEncoding;
+ case "ZapfDingbatsEncoding":
+ return ZapfDingbatsEncoding;
+ case "ExpertEncoding":
+ return ExpertEncoding;
+ case "MacExpertEncoding":
+ return MacExpertEncoding;
+ default:
+ return null;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/cff_parser.js
+
+
+
+const MAX_SUBR_NESTING = 10;
+const CFFStandardStrings = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"];
+const NUM_STANDARD_CFF_STRINGS = 391;
+const CharstringValidationData = [null, {
+ id: "hstem",
+ min: 2,
+ stackClearing: true,
+ stem: true
+}, null, {
+ id: "vstem",
+ min: 2,
+ stackClearing: true,
+ stem: true
+}, {
+ id: "vmoveto",
+ min: 1,
+ stackClearing: true
+}, {
+ id: "rlineto",
+ min: 2,
+ resetStack: true
+}, {
+ id: "hlineto",
+ min: 1,
+ resetStack: true
+}, {
+ id: "vlineto",
+ min: 1,
+ resetStack: true
+}, {
+ id: "rrcurveto",
+ min: 6,
+ resetStack: true
+}, null, {
+ id: "callsubr",
+ min: 1,
+ undefStack: true
+}, {
+ id: "return",
+ min: 0,
+ undefStack: true
+}, null, null, {
+ id: "endchar",
+ min: 0,
+ stackClearing: true
+}, null, null, null, {
+ id: "hstemhm",
+ min: 2,
+ stackClearing: true,
+ stem: true
+}, {
+ id: "hintmask",
+ min: 0,
+ stackClearing: true
+}, {
+ id: "cntrmask",
+ min: 0,
+ stackClearing: true
+}, {
+ id: "rmoveto",
+ min: 2,
+ stackClearing: true
+}, {
+ id: "hmoveto",
+ min: 1,
+ stackClearing: true
+}, {
+ id: "vstemhm",
+ min: 2,
+ stackClearing: true,
+ stem: true
+}, {
+ id: "rcurveline",
+ min: 8,
+ resetStack: true
+}, {
+ id: "rlinecurve",
+ min: 8,
+ resetStack: true
+}, {
+ id: "vvcurveto",
+ min: 4,
+ resetStack: true
+}, {
+ id: "hhcurveto",
+ min: 4,
+ resetStack: true
+}, null, {
+ id: "callgsubr",
+ min: 1,
+ undefStack: true
+}, {
+ id: "vhcurveto",
+ min: 4,
+ resetStack: true
+}, {
+ id: "hvcurveto",
+ min: 4,
+ resetStack: true
+}];
+const CharstringValidationData12 = [null, null, null, {
+ id: "and",
+ min: 2,
+ stackDelta: -1
+}, {
+ id: "or",
+ min: 2,
+ stackDelta: -1
+}, {
+ id: "not",
+ min: 1,
+ stackDelta: 0
+}, null, null, null, {
+ id: "abs",
+ min: 1,
+ stackDelta: 0
+}, {
+ id: "add",
+ min: 2,
+ stackDelta: -1,
+ stackFn(stack, index) {
+ stack[index - 2] = stack[index - 2] + stack[index - 1];
+ }
+}, {
+ id: "sub",
+ min: 2,
+ stackDelta: -1,
+ stackFn(stack, index) {
+ stack[index - 2] = stack[index - 2] - stack[index - 1];
+ }
+}, {
+ id: "div",
+ min: 2,
+ stackDelta: -1,
+ stackFn(stack, index) {
+ stack[index - 2] = stack[index - 2] / stack[index - 1];
+ }
+}, null, {
+ id: "neg",
+ min: 1,
+ stackDelta: 0,
+ stackFn(stack, index) {
+ stack[index - 1] = -stack[index - 1];
+ }
+}, {
+ id: "eq",
+ min: 2,
+ stackDelta: -1
+}, null, null, {
+ id: "drop",
+ min: 1,
+ stackDelta: -1
+}, null, {
+ id: "put",
+ min: 2,
+ stackDelta: -2
+}, {
+ id: "get",
+ min: 1,
+ stackDelta: 0
+}, {
+ id: "ifelse",
+ min: 4,
+ stackDelta: -3
+}, {
+ id: "random",
+ min: 0,
+ stackDelta: 1
+}, {
+ id: "mul",
+ min: 2,
+ stackDelta: -1,
+ stackFn(stack, index) {
+ stack[index - 2] = stack[index - 2] * stack[index - 1];
+ }
+}, null, {
+ id: "sqrt",
+ min: 1,
+ stackDelta: 0
+}, {
+ id: "dup",
+ min: 1,
+ stackDelta: 1
+}, {
+ id: "exch",
+ min: 2,
+ stackDelta: 0
+}, {
+ id: "index",
+ min: 2,
+ stackDelta: 0
+}, {
+ id: "roll",
+ min: 3,
+ stackDelta: -2
+}, null, null, null, {
+ id: "hflex",
+ min: 7,
+ resetStack: true
+}, {
+ id: "flex",
+ min: 13,
+ resetStack: true
+}, {
+ id: "hflex1",
+ min: 9,
+ resetStack: true
+}, {
+ id: "flex1",
+ min: 11,
+ resetStack: true
+}];
+class CFFParser {
+ constructor(file, properties, seacAnalysisEnabled) {
+ this.bytes = file.getBytes();
+ this.properties = properties;
+ this.seacAnalysisEnabled = !!seacAnalysisEnabled;
+ }
+ parse() {
+ const properties = this.properties;
+ const cff = new CFF();
+ this.cff = cff;
+ const header = this.parseHeader();
+ const nameIndex = this.parseIndex(header.endPos);
+ const topDictIndex = this.parseIndex(nameIndex.endPos);
+ const stringIndex = this.parseIndex(topDictIndex.endPos);
+ const globalSubrIndex = this.parseIndex(stringIndex.endPos);
+ const topDictParsed = this.parseDict(topDictIndex.obj.get(0));
+ const topDict = this.createDict(CFFTopDict, topDictParsed, cff.strings);
+ cff.header = header.obj;
+ cff.names = this.parseNameIndex(nameIndex.obj);
+ cff.strings = this.parseStringIndex(stringIndex.obj);
+ cff.topDict = topDict;
+ cff.globalSubrIndex = globalSubrIndex.obj;
+ this.parsePrivateDict(cff.topDict);
+ cff.isCIDFont = topDict.hasName("ROS");
+ const charStringOffset = topDict.getByName("CharStrings");
+ const charStringIndex = this.parseIndex(charStringOffset).obj;
+ const fontMatrix = topDict.getByName("FontMatrix");
+ if (fontMatrix) {
+ properties.fontMatrix = fontMatrix;
+ }
+ const fontBBox = topDict.getByName("FontBBox");
+ if (fontBBox) {
+ properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
+ properties.descent = Math.min(fontBBox[1], fontBBox[3]);
+ properties.ascentScaled = true;
+ }
+ let charset, encoding;
+ if (cff.isCIDFont) {
+ const fdArrayIndex = this.parseIndex(topDict.getByName("FDArray")).obj;
+ for (let i = 0, ii = fdArrayIndex.count; i < ii; ++i) {
+ const dictRaw = fdArrayIndex.get(i);
+ const fontDict = this.createDict(CFFTopDict, this.parseDict(dictRaw), cff.strings);
+ this.parsePrivateDict(fontDict);
+ cff.fdArray.push(fontDict);
+ }
+ encoding = null;
+ charset = this.parseCharsets(topDict.getByName("charset"), charStringIndex.count, cff.strings, true);
+ cff.fdSelect = this.parseFDSelect(topDict.getByName("FDSelect"), charStringIndex.count);
+ } else {
+ charset = this.parseCharsets(topDict.getByName("charset"), charStringIndex.count, cff.strings, false);
+ encoding = this.parseEncoding(topDict.getByName("Encoding"), properties, cff.strings, charset.charset);
+ }
+ cff.charset = charset;
+ cff.encoding = encoding;
+ const charStringsAndSeacs = this.parseCharStrings({
+ charStrings: charStringIndex,
+ localSubrIndex: topDict.privateDict.subrsIndex,
+ globalSubrIndex: globalSubrIndex.obj,
+ fdSelect: cff.fdSelect,
+ fdArray: cff.fdArray,
+ privateDict: topDict.privateDict
+ });
+ cff.charStrings = charStringsAndSeacs.charStrings;
+ cff.seacs = charStringsAndSeacs.seacs;
+ cff.widths = charStringsAndSeacs.widths;
+ return cff;
+ }
+ parseHeader() {
+ let bytes = this.bytes;
+ const bytesLength = bytes.length;
+ let offset = 0;
+ while (offset < bytesLength && bytes[offset] !== 1) {
+ ++offset;
+ }
+ if (offset >= bytesLength) {
+ throw new FormatError("Invalid CFF header");
+ }
+ if (offset !== 0) {
+ info("cff data is shifted");
+ bytes = bytes.subarray(offset);
+ this.bytes = bytes;
+ }
+ const major = bytes[0];
+ const minor = bytes[1];
+ const hdrSize = bytes[2];
+ const offSize = bytes[3];
+ const header = new CFFHeader(major, minor, hdrSize, offSize);
+ return {
+ obj: header,
+ endPos: hdrSize
+ };
+ }
+ parseDict(dict) {
+ let pos = 0;
+ function parseOperand() {
+ let value = dict[pos++];
+ if (value === 30) {
+ return parseFloatOperand();
+ } else if (value === 28) {
+ value = dict[pos++];
+ value = (value << 24 | dict[pos++] << 16) >> 16;
+ return value;
+ } else if (value === 29) {
+ value = dict[pos++];
+ value = value << 8 | dict[pos++];
+ value = value << 8 | dict[pos++];
+ value = value << 8 | dict[pos++];
+ return value;
+ } else if (value >= 32 && value <= 246) {
+ return value - 139;
+ } else if (value >= 247 && value <= 250) {
+ return (value - 247) * 256 + dict[pos++] + 108;
+ } else if (value >= 251 && value <= 254) {
+ return -((value - 251) * 256) - dict[pos++] - 108;
+ }
+ warn('CFFParser_parseDict: "' + value + '" is a reserved command.');
+ return NaN;
+ }
+ function parseFloatOperand() {
+ let str = "";
+ const eof = 15;
+ const lookup = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "E", "E-", null, "-"];
+ const length = dict.length;
+ while (pos < length) {
+ const b = dict[pos++];
+ const b1 = b >> 4;
+ const b2 = b & 15;
+ if (b1 === eof) {
+ break;
+ }
+ str += lookup[b1];
+ if (b2 === eof) {
+ break;
+ }
+ str += lookup[b2];
+ }
+ return parseFloat(str);
+ }
+ let operands = [];
+ const entries = [];
+ pos = 0;
+ const end = dict.length;
+ while (pos < end) {
+ let b = dict[pos];
+ if (b <= 21) {
+ if (b === 12) {
+ b = b << 8 | dict[++pos];
+ }
+ entries.push([b, operands]);
+ operands = [];
+ ++pos;
+ } else {
+ operands.push(parseOperand());
+ }
+ }
+ return entries;
+ }
+ parseIndex(pos) {
+ const cffIndex = new CFFIndex();
+ const bytes = this.bytes;
+ const count = bytes[pos++] << 8 | bytes[pos++];
+ const offsets = [];
+ let end = pos;
+ let i, ii;
+ if (count !== 0) {
+ const offsetSize = bytes[pos++];
+ const startPos = pos + (count + 1) * offsetSize - 1;
+ for (i = 0, ii = count + 1; i < ii; ++i) {
+ let offset = 0;
+ for (let j = 0; j < offsetSize; ++j) {
+ offset <<= 8;
+ offset += bytes[pos++];
+ }
+ offsets.push(startPos + offset);
+ }
+ end = offsets[count];
+ }
+ for (i = 0, ii = offsets.length - 1; i < ii; ++i) {
+ const offsetStart = offsets[i];
+ const offsetEnd = offsets[i + 1];
+ cffIndex.add(bytes.subarray(offsetStart, offsetEnd));
+ }
+ return {
+ obj: cffIndex,
+ endPos: end
+ };
+ }
+ parseNameIndex(index) {
+ const names = [];
+ for (let i = 0, ii = index.count; i < ii; ++i) {
+ const name = index.get(i);
+ names.push(bytesToString(name));
+ }
+ return names;
+ }
+ parseStringIndex(index) {
+ const strings = new CFFStrings();
+ for (let i = 0, ii = index.count; i < ii; ++i) {
+ const data = index.get(i);
+ strings.add(bytesToString(data));
+ }
+ return strings;
+ }
+ createDict(Type, dict, strings) {
+ const cffDict = new Type(strings);
+ for (const [key, value] of dict) {
+ cffDict.setByKey(key, value);
+ }
+ return cffDict;
+ }
+ parseCharString(state, data, localSubrIndex, globalSubrIndex) {
+ if (!data || state.callDepth > MAX_SUBR_NESTING) {
+ return false;
+ }
+ let stackSize = state.stackSize;
+ const stack = state.stack;
+ let length = data.length;
+ for (let j = 0; j < length;) {
+ const value = data[j++];
+ let validationCommand = null;
+ if (value === 12) {
+ const q = data[j++];
+ if (q === 0) {
+ data[j - 2] = 139;
+ data[j - 1] = 22;
+ stackSize = 0;
+ } else {
+ validationCommand = CharstringValidationData12[q];
+ }
+ } else if (value === 28) {
+ stack[stackSize] = (data[j] << 24 | data[j + 1] << 16) >> 16;
+ j += 2;
+ stackSize++;
+ } else if (value === 14) {
+ if (stackSize >= 4) {
+ stackSize -= 4;
+ if (this.seacAnalysisEnabled) {
+ state.seac = stack.slice(stackSize, stackSize + 4);
+ return false;
+ }
+ }
+ validationCommand = CharstringValidationData[value];
+ } else if (value >= 32 && value <= 246) {
+ stack[stackSize] = value - 139;
+ stackSize++;
+ } else if (value >= 247 && value <= 254) {
+ stack[stackSize] = value < 251 ? (value - 247 << 8) + data[j] + 108 : -(value - 251 << 8) - data[j] - 108;
+ j++;
+ stackSize++;
+ } else if (value === 255) {
+ stack[stackSize] = (data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3]) / 65536;
+ j += 4;
+ stackSize++;
+ } else if (value === 19 || value === 20) {
+ state.hints += stackSize >> 1;
+ if (state.hints === 0) {
+ data.copyWithin(j - 1, j, -1);
+ j -= 1;
+ length -= 1;
+ continue;
+ }
+ j += state.hints + 7 >> 3;
+ stackSize %= 2;
+ validationCommand = CharstringValidationData[value];
+ } else if (value === 10 || value === 29) {
+ const subrsIndex = value === 10 ? localSubrIndex : globalSubrIndex;
+ if (!subrsIndex) {
+ validationCommand = CharstringValidationData[value];
+ warn("Missing subrsIndex for " + validationCommand.id);
+ return false;
+ }
+ let bias = 32768;
+ if (subrsIndex.count < 1240) {
+ bias = 107;
+ } else if (subrsIndex.count < 33900) {
+ bias = 1131;
+ }
+ const subrNumber = stack[--stackSize] + bias;
+ if (subrNumber < 0 || subrNumber >= subrsIndex.count || isNaN(subrNumber)) {
+ validationCommand = CharstringValidationData[value];
+ warn("Out of bounds subrIndex for " + validationCommand.id);
+ return false;
+ }
+ state.stackSize = stackSize;
+ state.callDepth++;
+ const valid = this.parseCharString(state, subrsIndex.get(subrNumber), localSubrIndex, globalSubrIndex);
+ if (!valid) {
+ return false;
+ }
+ state.callDepth--;
+ stackSize = state.stackSize;
+ continue;
+ } else if (value === 11) {
+ state.stackSize = stackSize;
+ return true;
+ } else if (value === 0 && j === data.length) {
+ data[j - 1] = 14;
+ validationCommand = CharstringValidationData[14];
+ } else if (value === 9) {
+ data.copyWithin(j - 1, j, -1);
+ j -= 1;
+ length -= 1;
+ continue;
+ } else {
+ validationCommand = CharstringValidationData[value];
+ }
+ if (validationCommand) {
+ if (validationCommand.stem) {
+ state.hints += stackSize >> 1;
+ if (value === 3 || value === 23) {
+ state.hasVStems = true;
+ } else if (state.hasVStems && (value === 1 || value === 18)) {
+ warn("CFF stem hints are in wrong order");
+ data[j - 1] = value === 1 ? 3 : 23;
+ }
+ }
+ if ("min" in validationCommand) {
+ if (!state.undefStack && stackSize < validationCommand.min) {
+ warn("Not enough parameters for " + validationCommand.id + "; actual: " + stackSize + ", expected: " + validationCommand.min);
+ if (stackSize === 0) {
+ data[j - 1] = 14;
+ return true;
+ }
+ return false;
+ }
+ }
+ if (state.firstStackClearing && validationCommand.stackClearing) {
+ state.firstStackClearing = false;
+ stackSize -= validationCommand.min;
+ if (stackSize >= 2 && validationCommand.stem) {
+ stackSize %= 2;
+ } else if (stackSize > 1) {
+ warn("Found too many parameters for stack-clearing command");
+ }
+ if (stackSize > 0) {
+ state.width = stack[stackSize - 1];
+ }
+ }
+ if ("stackDelta" in validationCommand) {
+ if ("stackFn" in validationCommand) {
+ validationCommand.stackFn(stack, stackSize);
+ }
+ stackSize += validationCommand.stackDelta;
+ } else if (validationCommand.stackClearing) {
+ stackSize = 0;
+ } else if (validationCommand.resetStack) {
+ stackSize = 0;
+ state.undefStack = false;
+ } else if (validationCommand.undefStack) {
+ stackSize = 0;
+ state.undefStack = true;
+ state.firstStackClearing = false;
+ }
+ }
+ }
+ if (length < data.length) {
+ data.fill(14, length);
+ }
+ state.stackSize = stackSize;
+ return true;
+ }
+ parseCharStrings({
+ charStrings,
+ localSubrIndex,
+ globalSubrIndex,
+ fdSelect,
+ fdArray,
+ privateDict
+ }) {
+ const seacs = [];
+ const widths = [];
+ const count = charStrings.count;
+ for (let i = 0; i < count; i++) {
+ const charstring = charStrings.get(i);
+ const state = {
+ callDepth: 0,
+ stackSize: 0,
+ stack: [],
+ undefStack: true,
+ hints: 0,
+ firstStackClearing: true,
+ seac: null,
+ width: null,
+ hasVStems: false
+ };
+ let valid = true;
+ let localSubrToUse = null;
+ let privateDictToUse = privateDict;
+ if (fdSelect && fdArray.length) {
+ const fdIndex = fdSelect.getFDIndex(i);
+ if (fdIndex === -1) {
+ warn("Glyph index is not in fd select.");
+ valid = false;
+ }
+ if (fdIndex >= fdArray.length) {
+ warn("Invalid fd index for glyph index.");
+ valid = false;
+ }
+ if (valid) {
+ privateDictToUse = fdArray[fdIndex].privateDict;
+ localSubrToUse = privateDictToUse.subrsIndex;
+ }
+ } else if (localSubrIndex) {
+ localSubrToUse = localSubrIndex;
+ }
+ if (valid) {
+ valid = this.parseCharString(state, charstring, localSubrToUse, globalSubrIndex);
+ }
+ if (state.width !== null) {
+ const nominalWidth = privateDictToUse.getByName("nominalWidthX");
+ widths[i] = nominalWidth + state.width;
+ } else {
+ const defaultWidth = privateDictToUse.getByName("defaultWidthX");
+ widths[i] = defaultWidth;
+ }
+ if (state.seac !== null) {
+ seacs[i] = state.seac;
+ }
+ if (!valid) {
+ charStrings.set(i, new Uint8Array([14]));
+ }
+ }
+ return {
+ charStrings,
+ seacs,
+ widths
+ };
+ }
+ emptyPrivateDictionary(parentDict) {
+ const privateDict = this.createDict(CFFPrivateDict, [], parentDict.strings);
+ parentDict.setByKey(18, [0, 0]);
+ parentDict.privateDict = privateDict;
+ }
+ parsePrivateDict(parentDict) {
+ if (!parentDict.hasName("Private")) {
+ this.emptyPrivateDictionary(parentDict);
+ return;
+ }
+ const privateOffset = parentDict.getByName("Private");
+ if (!Array.isArray(privateOffset) || privateOffset.length !== 2) {
+ parentDict.removeByName("Private");
+ return;
+ }
+ const size = privateOffset[0];
+ const offset = privateOffset[1];
+ if (size === 0 || offset >= this.bytes.length) {
+ this.emptyPrivateDictionary(parentDict);
+ return;
+ }
+ const privateDictEnd = offset + size;
+ const dictData = this.bytes.subarray(offset, privateDictEnd);
+ const dict = this.parseDict(dictData);
+ const privateDict = this.createDict(CFFPrivateDict, dict, parentDict.strings);
+ parentDict.privateDict = privateDict;
+ if (privateDict.getByName("ExpansionFactor") === 0) {
+ privateDict.setByName("ExpansionFactor", 0.06);
+ }
+ if (!privateDict.getByName("Subrs")) {
+ return;
+ }
+ const subrsOffset = privateDict.getByName("Subrs");
+ const relativeOffset = offset + subrsOffset;
+ if (subrsOffset === 0 || relativeOffset >= this.bytes.length) {
+ this.emptyPrivateDictionary(parentDict);
+ return;
+ }
+ const subrsIndex = this.parseIndex(relativeOffset);
+ privateDict.subrsIndex = subrsIndex.obj;
+ }
+ parseCharsets(pos, length, strings, cid) {
+ if (pos === 0) {
+ return new CFFCharset(true, CFFCharsetPredefinedTypes.ISO_ADOBE, ISOAdobeCharset);
+ } else if (pos === 1) {
+ return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT, ExpertCharset);
+ } else if (pos === 2) {
+ return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT_SUBSET, ExpertSubsetCharset);
+ }
+ const bytes = this.bytes;
+ const start = pos;
+ const format = bytes[pos++];
+ const charset = [cid ? 0 : ".notdef"];
+ let id, count, i;
+ length -= 1;
+ switch (format) {
+ case 0:
+ for (i = 0; i < length; i++) {
+ id = bytes[pos++] << 8 | bytes[pos++];
+ charset.push(cid ? id : strings.get(id));
+ }
+ break;
+ case 1:
+ while (charset.length <= length) {
+ id = bytes[pos++] << 8 | bytes[pos++];
+ count = bytes[pos++];
+ for (i = 0; i <= count; i++) {
+ charset.push(cid ? id++ : strings.get(id++));
+ }
+ }
+ break;
+ case 2:
+ while (charset.length <= length) {
+ id = bytes[pos++] << 8 | bytes[pos++];
+ count = bytes[pos++] << 8 | bytes[pos++];
+ for (i = 0; i <= count; i++) {
+ charset.push(cid ? id++ : strings.get(id++));
+ }
+ }
+ break;
+ default:
+ throw new FormatError("Unknown charset format");
+ }
+ const end = pos;
+ const raw = bytes.subarray(start, end);
+ return new CFFCharset(false, format, charset, raw);
+ }
+ parseEncoding(pos, properties, strings, charset) {
+ const encoding = Object.create(null);
+ const bytes = this.bytes;
+ let predefined = false;
+ let format, i, ii;
+ let raw = null;
+ function readSupplement() {
+ const supplementsCount = bytes[pos++];
+ for (i = 0; i < supplementsCount; i++) {
+ const code = bytes[pos++];
+ const sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff);
+ encoding[code] = charset.indexOf(strings.get(sid));
+ }
+ }
+ if (pos === 0 || pos === 1) {
+ predefined = true;
+ format = pos;
+ const baseEncoding = pos ? ExpertEncoding : StandardEncoding;
+ for (i = 0, ii = charset.length; i < ii; i++) {
+ const index = baseEncoding.indexOf(charset[i]);
+ if (index !== -1) {
+ encoding[index] = i;
+ }
+ }
+ } else {
+ const dataStart = pos;
+ format = bytes[pos++];
+ switch (format & 0x7f) {
+ case 0:
+ const glyphsCount = bytes[pos++];
+ for (i = 1; i <= glyphsCount; i++) {
+ encoding[bytes[pos++]] = i;
+ }
+ break;
+ case 1:
+ const rangesCount = bytes[pos++];
+ let gid = 1;
+ for (i = 0; i < rangesCount; i++) {
+ const start = bytes[pos++];
+ const left = bytes[pos++];
+ for (let j = start; j <= start + left; j++) {
+ encoding[j] = gid++;
+ }
+ }
+ break;
+ default:
+ throw new FormatError(`Unknown encoding format: ${format} in CFF`);
+ }
+ const dataEnd = pos;
+ if (format & 0x80) {
+ bytes[dataStart] &= 0x7f;
+ readSupplement();
+ }
+ raw = bytes.subarray(dataStart, dataEnd);
+ }
+ format &= 0x7f;
+ return new CFFEncoding(predefined, format, encoding, raw);
+ }
+ parseFDSelect(pos, length) {
+ const bytes = this.bytes;
+ const format = bytes[pos++];
+ const fdSelect = [];
+ let i;
+ switch (format) {
+ case 0:
+ for (i = 0; i < length; ++i) {
+ const id = bytes[pos++];
+ fdSelect.push(id);
+ }
+ break;
+ case 3:
+ const rangesCount = bytes[pos++] << 8 | bytes[pos++];
+ for (i = 0; i < rangesCount; ++i) {
+ let first = bytes[pos++] << 8 | bytes[pos++];
+ if (i === 0 && first !== 0) {
+ warn("parseFDSelect: The first range must have a first GID of 0" + " -- trying to recover.");
+ first = 0;
+ }
+ const fdIndex = bytes[pos++];
+ const next = bytes[pos] << 8 | bytes[pos + 1];
+ for (let j = first; j < next; ++j) {
+ fdSelect.push(fdIndex);
+ }
+ }
+ pos += 2;
+ break;
+ default:
+ throw new FormatError(`parseFDSelect: Unknown format "${format}".`);
+ }
+ if (fdSelect.length !== length) {
+ throw new FormatError("parseFDSelect: Invalid font data.");
+ }
+ return new CFFFDSelect(format, fdSelect);
+ }
+}
+class CFF {
+ constructor() {
+ this.header = null;
+ this.names = [];
+ this.topDict = null;
+ this.strings = new CFFStrings();
+ this.globalSubrIndex = null;
+ this.encoding = null;
+ this.charset = null;
+ this.charStrings = null;
+ this.fdArray = [];
+ this.fdSelect = null;
+ this.isCIDFont = false;
+ }
+ duplicateFirstGlyph() {
+ if (this.charStrings.count >= 65535) {
+ warn("Not enough space in charstrings to duplicate first glyph.");
+ return;
+ }
+ const glyphZero = this.charStrings.get(0);
+ this.charStrings.add(glyphZero);
+ if (this.isCIDFont) {
+ this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]);
+ }
+ }
+ hasGlyphId(id) {
+ if (id < 0 || id >= this.charStrings.count) {
+ return false;
+ }
+ const glyph = this.charStrings.get(id);
+ return glyph.length > 0;
+ }
+}
+class CFFHeader {
+ constructor(major, minor, hdrSize, offSize) {
+ this.major = major;
+ this.minor = minor;
+ this.hdrSize = hdrSize;
+ this.offSize = offSize;
+ }
+}
+class CFFStrings {
+ constructor() {
+ this.strings = [];
+ }
+ get(index) {
+ if (index >= 0 && index <= NUM_STANDARD_CFF_STRINGS - 1) {
+ return CFFStandardStrings[index];
+ }
+ if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) {
+ return this.strings[index - NUM_STANDARD_CFF_STRINGS];
+ }
+ return CFFStandardStrings[0];
+ }
+ getSID(str) {
+ let index = CFFStandardStrings.indexOf(str);
+ if (index !== -1) {
+ return index;
+ }
+ index = this.strings.indexOf(str);
+ if (index !== -1) {
+ return index + NUM_STANDARD_CFF_STRINGS;
+ }
+ return -1;
+ }
+ add(value) {
+ this.strings.push(value);
+ }
+ get count() {
+ return this.strings.length;
+ }
+}
+class CFFIndex {
+ constructor() {
+ this.objects = [];
+ this.length = 0;
+ }
+ add(data) {
+ this.length += data.length;
+ this.objects.push(data);
+ }
+ set(index, data) {
+ this.length += data.length - this.objects[index].length;
+ this.objects[index] = data;
+ }
+ get(index) {
+ return this.objects[index];
+ }
+ get count() {
+ return this.objects.length;
+ }
+}
+class CFFDict {
+ constructor(tables, strings) {
+ this.keyToNameMap = tables.keyToNameMap;
+ this.nameToKeyMap = tables.nameToKeyMap;
+ this.defaults = tables.defaults;
+ this.types = tables.types;
+ this.opcodes = tables.opcodes;
+ this.order = tables.order;
+ this.strings = strings;
+ this.values = Object.create(null);
+ }
+ setByKey(key, value) {
+ if (!(key in this.keyToNameMap)) {
+ return false;
+ }
+ if (value.length === 0) {
+ return true;
+ }
+ for (const val of value) {
+ if (isNaN(val)) {
+ warn(`Invalid CFFDict value: "${value}" for key "${key}".`);
+ return true;
+ }
+ }
+ const type = this.types[key];
+ if (type === "num" || type === "sid" || type === "offset") {
+ value = value[0];
+ }
+ this.values[key] = value;
+ return true;
+ }
+ setByName(name, value) {
+ if (!(name in this.nameToKeyMap)) {
+ throw new FormatError(`Invalid dictionary name "${name}"`);
+ }
+ this.values[this.nameToKeyMap[name]] = value;
+ }
+ hasName(name) {
+ return this.nameToKeyMap[name] in this.values;
+ }
+ getByName(name) {
+ if (!(name in this.nameToKeyMap)) {
+ throw new FormatError(`Invalid dictionary name ${name}"`);
+ }
+ const key = this.nameToKeyMap[name];
+ if (!(key in this.values)) {
+ return this.defaults[key];
+ }
+ return this.values[key];
+ }
+ removeByName(name) {
+ delete this.values[this.nameToKeyMap[name]];
+ }
+ static createTables(layout) {
+ const tables = {
+ keyToNameMap: {},
+ nameToKeyMap: {},
+ defaults: {},
+ types: {},
+ opcodes: {},
+ order: []
+ };
+ for (const entry of layout) {
+ const key = Array.isArray(entry[0]) ? (entry[0][0] << 8) + entry[0][1] : entry[0];
+ tables.keyToNameMap[key] = entry[1];
+ tables.nameToKeyMap[entry[1]] = key;
+ tables.types[key] = entry[2];
+ tables.defaults[key] = entry[3];
+ tables.opcodes[key] = Array.isArray(entry[0]) ? entry[0] : [entry[0]];
+ tables.order.push(key);
+ }
+ return tables;
+ }
+}
+const CFFTopDictLayout = [[[12, 30], "ROS", ["sid", "sid", "num"], null], [[12, 20], "SyntheticBase", "num", null], [0, "version", "sid", null], [1, "Notice", "sid", null], [[12, 0], "Copyright", "sid", null], [2, "FullName", "sid", null], [3, "FamilyName", "sid", null], [4, "Weight", "sid", null], [[12, 1], "isFixedPitch", "num", 0], [[12, 2], "ItalicAngle", "num", 0], [[12, 3], "UnderlinePosition", "num", -100], [[12, 4], "UnderlineThickness", "num", 50], [[12, 5], "PaintType", "num", 0], [[12, 6], "CharstringType", "num", 2], [[12, 7], "FontMatrix", ["num", "num", "num", "num", "num", "num"], [0.001, 0, 0, 0.001, 0, 0]], [13, "UniqueID", "num", null], [5, "FontBBox", ["num", "num", "num", "num"], [0, 0, 0, 0]], [[12, 8], "StrokeWidth", "num", 0], [14, "XUID", "array", null], [15, "charset", "offset", 0], [16, "Encoding", "offset", 0], [17, "CharStrings", "offset", 0], [18, "Private", ["offset", "offset"], null], [[12, 21], "PostScript", "sid", null], [[12, 22], "BaseFontName", "sid", null], [[12, 23], "BaseFontBlend", "delta", null], [[12, 31], "CIDFontVersion", "num", 0], [[12, 32], "CIDFontRevision", "num", 0], [[12, 33], "CIDFontType", "num", 0], [[12, 34], "CIDCount", "num", 8720], [[12, 35], "UIDBase", "num", null], [[12, 37], "FDSelect", "offset", null], [[12, 36], "FDArray", "offset", null], [[12, 38], "FontName", "sid", null]];
+class CFFTopDict extends CFFDict {
+ static get tables() {
+ return shadow(this, "tables", this.createTables(CFFTopDictLayout));
+ }
+ constructor(strings) {
+ super(CFFTopDict.tables, strings);
+ this.privateDict = null;
+ }
+}
+const CFFPrivateDictLayout = [[6, "BlueValues", "delta", null], [7, "OtherBlues", "delta", null], [8, "FamilyBlues", "delta", null], [9, "FamilyOtherBlues", "delta", null], [[12, 9], "BlueScale", "num", 0.039625], [[12, 10], "BlueShift", "num", 7], [[12, 11], "BlueFuzz", "num", 1], [10, "StdHW", "num", null], [11, "StdVW", "num", null], [[12, 12], "StemSnapH", "delta", null], [[12, 13], "StemSnapV", "delta", null], [[12, 14], "ForceBold", "num", 0], [[12, 17], "LanguageGroup", "num", 0], [[12, 18], "ExpansionFactor", "num", 0.06], [[12, 19], "initialRandomSeed", "num", 0], [20, "defaultWidthX", "num", 0], [21, "nominalWidthX", "num", 0], [19, "Subrs", "offset", null]];
+class CFFPrivateDict extends CFFDict {
+ static get tables() {
+ return shadow(this, "tables", this.createTables(CFFPrivateDictLayout));
+ }
+ constructor(strings) {
+ super(CFFPrivateDict.tables, strings);
+ this.subrsIndex = null;
+ }
+}
+const CFFCharsetPredefinedTypes = {
+ ISO_ADOBE: 0,
+ EXPERT: 1,
+ EXPERT_SUBSET: 2
+};
+class CFFCharset {
+ constructor(predefined, format, charset, raw) {
+ this.predefined = predefined;
+ this.format = format;
+ this.charset = charset;
+ this.raw = raw;
+ }
+}
+class CFFEncoding {
+ constructor(predefined, format, encoding, raw) {
+ this.predefined = predefined;
+ this.format = format;
+ this.encoding = encoding;
+ this.raw = raw;
+ }
+}
+class CFFFDSelect {
+ constructor(format, fdSelect) {
+ this.format = format;
+ this.fdSelect = fdSelect;
+ }
+ getFDIndex(glyphIndex) {
+ if (glyphIndex < 0 || glyphIndex >= this.fdSelect.length) {
+ return -1;
+ }
+ return this.fdSelect[glyphIndex];
+ }
+}
+class CFFOffsetTracker {
+ constructor() {
+ this.offsets = Object.create(null);
+ }
+ isTracking(key) {
+ return key in this.offsets;
+ }
+ track(key, location) {
+ if (key in this.offsets) {
+ throw new FormatError(`Already tracking location of ${key}`);
+ }
+ this.offsets[key] = location;
+ }
+ offset(value) {
+ for (const key in this.offsets) {
+ this.offsets[key] += value;
+ }
+ }
+ setEntryLocation(key, values, output) {
+ if (!(key in this.offsets)) {
+ throw new FormatError(`Not tracking location of ${key}`);
+ }
+ const data = output.data;
+ const dataOffset = this.offsets[key];
+ const size = 5;
+ for (let i = 0, ii = values.length; i < ii; ++i) {
+ const offset0 = i * size + dataOffset;
+ const offset1 = offset0 + 1;
+ const offset2 = offset0 + 2;
+ const offset3 = offset0 + 3;
+ const offset4 = offset0 + 4;
+ if (data[offset0] !== 0x1d || data[offset1] !== 0 || data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) {
+ throw new FormatError("writing to an offset that is not empty");
+ }
+ const value = values[i];
+ data[offset0] = 0x1d;
+ data[offset1] = value >> 24 & 0xff;
+ data[offset2] = value >> 16 & 0xff;
+ data[offset3] = value >> 8 & 0xff;
+ data[offset4] = value & 0xff;
+ }
+ }
+}
+class CFFCompiler {
+ constructor(cff) {
+ this.cff = cff;
+ }
+ compile() {
+ const cff = this.cff;
+ const output = {
+ data: [],
+ length: 0,
+ add(data) {
+ try {
+ this.data.push(...data);
+ } catch {
+ this.data = this.data.concat(data);
+ }
+ this.length = this.data.length;
+ }
+ };
+ const header = this.compileHeader(cff.header);
+ output.add(header);
+ const nameIndex = this.compileNameIndex(cff.names);
+ output.add(nameIndex);
+ if (cff.isCIDFont) {
+ if (cff.topDict.hasName("FontMatrix")) {
+ const base = cff.topDict.getByName("FontMatrix");
+ cff.topDict.removeByName("FontMatrix");
+ for (const subDict of cff.fdArray) {
+ let matrix = base.slice(0);
+ if (subDict.hasName("FontMatrix")) {
+ matrix = Util.transform(matrix, subDict.getByName("FontMatrix"));
+ }
+ subDict.setByName("FontMatrix", matrix);
+ }
+ }
+ }
+ const xuid = cff.topDict.getByName("XUID");
+ if (xuid?.length > 16) {
+ cff.topDict.removeByName("XUID");
+ }
+ cff.topDict.setByName("charset", 0);
+ let compiled = this.compileTopDicts([cff.topDict], output.length, cff.isCIDFont);
+ output.add(compiled.output);
+ const topDictTracker = compiled.trackers[0];
+ const stringIndex = this.compileStringIndex(cff.strings.strings);
+ output.add(stringIndex);
+ const globalSubrIndex = this.compileIndex(cff.globalSubrIndex);
+ output.add(globalSubrIndex);
+ if (cff.encoding && cff.topDict.hasName("Encoding")) {
+ if (cff.encoding.predefined) {
+ topDictTracker.setEntryLocation("Encoding", [cff.encoding.format], output);
+ } else {
+ const encoding = this.compileEncoding(cff.encoding);
+ topDictTracker.setEntryLocation("Encoding", [output.length], output);
+ output.add(encoding);
+ }
+ }
+ const charset = this.compileCharset(cff.charset, cff.charStrings.count, cff.strings, cff.isCIDFont);
+ topDictTracker.setEntryLocation("charset", [output.length], output);
+ output.add(charset);
+ const charStrings = this.compileCharStrings(cff.charStrings);
+ topDictTracker.setEntryLocation("CharStrings", [output.length], output);
+ output.add(charStrings);
+ if (cff.isCIDFont) {
+ topDictTracker.setEntryLocation("FDSelect", [output.length], output);
+ const fdSelect = this.compileFDSelect(cff.fdSelect);
+ output.add(fdSelect);
+ compiled = this.compileTopDicts(cff.fdArray, output.length, true);
+ topDictTracker.setEntryLocation("FDArray", [output.length], output);
+ output.add(compiled.output);
+ const fontDictTrackers = compiled.trackers;
+ this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output);
+ }
+ this.compilePrivateDicts([cff.topDict], [topDictTracker], output);
+ output.add([0]);
+ return output.data;
+ }
+ encodeNumber(value) {
+ if (Number.isInteger(value)) {
+ return this.encodeInteger(value);
+ }
+ return this.encodeFloat(value);
+ }
+ static get EncodeFloatRegExp() {
+ return shadow(this, "EncodeFloatRegExp", /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/);
+ }
+ encodeFloat(num) {
+ let value = num.toString();
+ const m = CFFCompiler.EncodeFloatRegExp.exec(value);
+ if (m) {
+ const epsilon = parseFloat("1e" + ((m[2] ? +m[2] : 0) + m[1].length));
+ value = (Math.round(num * epsilon) / epsilon).toString();
+ }
+ let nibbles = "";
+ let i, ii;
+ for (i = 0, ii = value.length; i < ii; ++i) {
+ const a = value[i];
+ if (a === "e") {
+ nibbles += value[++i] === "-" ? "c" : "b";
+ } else if (a === ".") {
+ nibbles += "a";
+ } else if (a === "-") {
+ nibbles += "e";
+ } else {
+ nibbles += a;
+ }
+ }
+ nibbles += nibbles.length & 1 ? "f" : "ff";
+ const out = [30];
+ for (i = 0, ii = nibbles.length; i < ii; i += 2) {
+ out.push(parseInt(nibbles.substring(i, i + 2), 16));
+ }
+ return out;
+ }
+ encodeInteger(value) {
+ let code;
+ if (value >= -107 && value <= 107) {
+ code = [value + 139];
+ } else if (value >= 108 && value <= 1131) {
+ value -= 108;
+ code = [(value >> 8) + 247, value & 0xff];
+ } else if (value >= -1131 && value <= -108) {
+ value = -value - 108;
+ code = [(value >> 8) + 251, value & 0xff];
+ } else if (value >= -32768 && value <= 32767) {
+ code = [0x1c, value >> 8 & 0xff, value & 0xff];
+ } else {
+ code = [0x1d, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff];
+ }
+ return code;
+ }
+ compileHeader(header) {
+ return [header.major, header.minor, 4, header.offSize];
+ }
+ compileNameIndex(names) {
+ const nameIndex = new CFFIndex();
+ for (const name of names) {
+ const length = Math.min(name.length, 127);
+ let sanitizedName = new Array(length);
+ for (let j = 0; j < length; j++) {
+ let char = name[j];
+ if (char < "!" || char > "~" || char === "[" || char === "]" || char === "(" || char === ")" || char === "{" || char === "}" || char === "<" || char === ">" || char === "/" || char === "%") {
+ char = "_";
+ }
+ sanitizedName[j] = char;
+ }
+ sanitizedName = sanitizedName.join("");
+ if (sanitizedName === "") {
+ sanitizedName = "Bad_Font_Name";
+ }
+ nameIndex.add(stringToBytes(sanitizedName));
+ }
+ return this.compileIndex(nameIndex);
+ }
+ compileTopDicts(dicts, length, removeCidKeys) {
+ const fontDictTrackers = [];
+ let fdArrayIndex = new CFFIndex();
+ for (const fontDict of dicts) {
+ if (removeCidKeys) {
+ fontDict.removeByName("CIDFontVersion");
+ fontDict.removeByName("CIDFontRevision");
+ fontDict.removeByName("CIDFontType");
+ fontDict.removeByName("CIDCount");
+ fontDict.removeByName("UIDBase");
+ }
+ const fontDictTracker = new CFFOffsetTracker();
+ const fontDictData = this.compileDict(fontDict, fontDictTracker);
+ fontDictTrackers.push(fontDictTracker);
+ fdArrayIndex.add(fontDictData);
+ fontDictTracker.offset(length);
+ }
+ fdArrayIndex = this.compileIndex(fdArrayIndex, fontDictTrackers);
+ return {
+ trackers: fontDictTrackers,
+ output: fdArrayIndex
+ };
+ }
+ compilePrivateDicts(dicts, trackers, output) {
+ for (let i = 0, ii = dicts.length; i < ii; ++i) {
+ const fontDict = dicts[i];
+ const privateDict = fontDict.privateDict;
+ if (!privateDict || !fontDict.hasName("Private")) {
+ throw new FormatError("There must be a private dictionary.");
+ }
+ const privateDictTracker = new CFFOffsetTracker();
+ const privateDictData = this.compileDict(privateDict, privateDictTracker);
+ let outputLength = output.length;
+ privateDictTracker.offset(outputLength);
+ if (!privateDictData.length) {
+ outputLength = 0;
+ }
+ trackers[i].setEntryLocation("Private", [privateDictData.length, outputLength], output);
+ output.add(privateDictData);
+ if (privateDict.subrsIndex && privateDict.hasName("Subrs")) {
+ const subrs = this.compileIndex(privateDict.subrsIndex);
+ privateDictTracker.setEntryLocation("Subrs", [privateDictData.length], output);
+ output.add(subrs);
+ }
+ }
+ }
+ compileDict(dict, offsetTracker) {
+ const out = [];
+ for (const key of dict.order) {
+ if (!(key in dict.values)) {
+ continue;
+ }
+ let values = dict.values[key];
+ let types = dict.types[key];
+ if (!Array.isArray(types)) {
+ types = [types];
+ }
+ if (!Array.isArray(values)) {
+ values = [values];
+ }
+ if (values.length === 0) {
+ continue;
+ }
+ for (let j = 0, jj = types.length; j < jj; ++j) {
+ const type = types[j];
+ const value = values[j];
+ switch (type) {
+ case "num":
+ case "sid":
+ out.push(...this.encodeNumber(value));
+ break;
+ case "offset":
+ const name = dict.keyToNameMap[key];
+ if (!offsetTracker.isTracking(name)) {
+ offsetTracker.track(name, out.length);
+ }
+ out.push(0x1d, 0, 0, 0, 0);
+ break;
+ case "array":
+ case "delta":
+ out.push(...this.encodeNumber(value));
+ for (let k = 1, kk = values.length; k < kk; ++k) {
+ out.push(...this.encodeNumber(values[k]));
+ }
+ break;
+ default:
+ throw new FormatError(`Unknown data type of ${type}`);
+ }
+ }
+ out.push(...dict.opcodes[key]);
+ }
+ return out;
+ }
+ compileStringIndex(strings) {
+ const stringIndex = new CFFIndex();
+ for (const string of strings) {
+ stringIndex.add(stringToBytes(string));
+ }
+ return this.compileIndex(stringIndex);
+ }
+ compileCharStrings(charStrings) {
+ const charStringsIndex = new CFFIndex();
+ for (let i = 0; i < charStrings.count; i++) {
+ const glyph = charStrings.get(i);
+ if (glyph.length === 0) {
+ charStringsIndex.add(new Uint8Array([0x8b, 0x0e]));
+ continue;
+ }
+ charStringsIndex.add(glyph);
+ }
+ return this.compileIndex(charStringsIndex);
+ }
+ compileCharset(charset, numGlyphs, strings, isCIDFont) {
+ let out;
+ const numGlyphsLessNotDef = numGlyphs - 1;
+ if (isCIDFont) {
+ out = new Uint8Array([2, 0, 0, numGlyphsLessNotDef >> 8 & 0xff, numGlyphsLessNotDef & 0xff]);
+ } else {
+ const length = 1 + numGlyphsLessNotDef * 2;
+ out = new Uint8Array(length);
+ out[0] = 0;
+ let charsetIndex = 0;
+ const numCharsets = charset.charset.length;
+ let warned = false;
+ for (let i = 1; i < out.length; i += 2) {
+ let sid = 0;
+ if (charsetIndex < numCharsets) {
+ const name = charset.charset[charsetIndex++];
+ sid = strings.getSID(name);
+ if (sid === -1) {
+ sid = 0;
+ if (!warned) {
+ warned = true;
+ warn(`Couldn't find ${name} in CFF strings`);
+ }
+ }
+ }
+ out[i] = sid >> 8 & 0xff;
+ out[i + 1] = sid & 0xff;
+ }
+ }
+ return this.compileTypedArray(out);
+ }
+ compileEncoding(encoding) {
+ return this.compileTypedArray(encoding.raw);
+ }
+ compileFDSelect(fdSelect) {
+ const format = fdSelect.format;
+ let out, i;
+ switch (format) {
+ case 0:
+ out = new Uint8Array(1 + fdSelect.fdSelect.length);
+ out[0] = format;
+ for (i = 0; i < fdSelect.fdSelect.length; i++) {
+ out[i + 1] = fdSelect.fdSelect[i];
+ }
+ break;
+ case 3:
+ const start = 0;
+ let lastFD = fdSelect.fdSelect[0];
+ const ranges = [format, 0, 0, start >> 8 & 0xff, start & 0xff, lastFD];
+ for (i = 1; i < fdSelect.fdSelect.length; i++) {
+ const currentFD = fdSelect.fdSelect[i];
+ if (currentFD !== lastFD) {
+ ranges.push(i >> 8 & 0xff, i & 0xff, currentFD);
+ lastFD = currentFD;
+ }
+ }
+ const numRanges = (ranges.length - 3) / 3;
+ ranges[1] = numRanges >> 8 & 0xff;
+ ranges[2] = numRanges & 0xff;
+ ranges.push(i >> 8 & 0xff, i & 0xff);
+ out = new Uint8Array(ranges);
+ break;
+ }
+ return this.compileTypedArray(out);
+ }
+ compileTypedArray(data) {
+ return Array.from(data);
+ }
+ compileIndex(index, trackers = []) {
+ const objects = index.objects;
+ const count = objects.length;
+ if (count === 0) {
+ return [0, 0];
+ }
+ const data = [count >> 8 & 0xff, count & 0xff];
+ let lastOffset = 1,
+ i;
+ for (i = 0; i < count; ++i) {
+ lastOffset += objects[i].length;
+ }
+ let offsetSize;
+ if (lastOffset < 0x100) {
+ offsetSize = 1;
+ } else if (lastOffset < 0x10000) {
+ offsetSize = 2;
+ } else if (lastOffset < 0x1000000) {
+ offsetSize = 3;
+ } else {
+ offsetSize = 4;
+ }
+ data.push(offsetSize);
+ let relativeOffset = 1;
+ for (i = 0; i < count + 1; i++) {
+ if (offsetSize === 1) {
+ data.push(relativeOffset & 0xff);
+ } else if (offsetSize === 2) {
+ data.push(relativeOffset >> 8 & 0xff, relativeOffset & 0xff);
+ } else if (offsetSize === 3) {
+ data.push(relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff);
+ } else {
+ data.push(relativeOffset >>> 24 & 0xff, relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff);
+ }
+ if (objects[i]) {
+ relativeOffset += objects[i].length;
+ }
+ }
+ for (i = 0; i < count; i++) {
+ if (trackers[i]) {
+ trackers[i].offset(data.length);
+ }
+ data.push(...objects[i]);
+ }
+ return data;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/glyphlist.js
+
+const getGlyphsUnicode = getLookupTableFactory(function (t) {
+ t.A = 0x0041;
+ t.AE = 0x00c6;
+ t.AEacute = 0x01fc;
+ t.AEmacron = 0x01e2;
+ t.AEsmall = 0xf7e6;
+ t.Aacute = 0x00c1;
+ t.Aacutesmall = 0xf7e1;
+ t.Abreve = 0x0102;
+ t.Abreveacute = 0x1eae;
+ t.Abrevecyrillic = 0x04d0;
+ t.Abrevedotbelow = 0x1eb6;
+ t.Abrevegrave = 0x1eb0;
+ t.Abrevehookabove = 0x1eb2;
+ t.Abrevetilde = 0x1eb4;
+ t.Acaron = 0x01cd;
+ t.Acircle = 0x24b6;
+ t.Acircumflex = 0x00c2;
+ t.Acircumflexacute = 0x1ea4;
+ t.Acircumflexdotbelow = 0x1eac;
+ t.Acircumflexgrave = 0x1ea6;
+ t.Acircumflexhookabove = 0x1ea8;
+ t.Acircumflexsmall = 0xf7e2;
+ t.Acircumflextilde = 0x1eaa;
+ t.Acute = 0xf6c9;
+ t.Acutesmall = 0xf7b4;
+ t.Acyrillic = 0x0410;
+ t.Adblgrave = 0x0200;
+ t.Adieresis = 0x00c4;
+ t.Adieresiscyrillic = 0x04d2;
+ t.Adieresismacron = 0x01de;
+ t.Adieresissmall = 0xf7e4;
+ t.Adotbelow = 0x1ea0;
+ t.Adotmacron = 0x01e0;
+ t.Agrave = 0x00c0;
+ t.Agravesmall = 0xf7e0;
+ t.Ahookabove = 0x1ea2;
+ t.Aiecyrillic = 0x04d4;
+ t.Ainvertedbreve = 0x0202;
+ t.Alpha = 0x0391;
+ t.Alphatonos = 0x0386;
+ t.Amacron = 0x0100;
+ t.Amonospace = 0xff21;
+ t.Aogonek = 0x0104;
+ t.Aring = 0x00c5;
+ t.Aringacute = 0x01fa;
+ t.Aringbelow = 0x1e00;
+ t.Aringsmall = 0xf7e5;
+ t.Asmall = 0xf761;
+ t.Atilde = 0x00c3;
+ t.Atildesmall = 0xf7e3;
+ t.Aybarmenian = 0x0531;
+ t.B = 0x0042;
+ t.Bcircle = 0x24b7;
+ t.Bdotaccent = 0x1e02;
+ t.Bdotbelow = 0x1e04;
+ t.Becyrillic = 0x0411;
+ t.Benarmenian = 0x0532;
+ t.Beta = 0x0392;
+ t.Bhook = 0x0181;
+ t.Blinebelow = 0x1e06;
+ t.Bmonospace = 0xff22;
+ t.Brevesmall = 0xf6f4;
+ t.Bsmall = 0xf762;
+ t.Btopbar = 0x0182;
+ t.C = 0x0043;
+ t.Caarmenian = 0x053e;
+ t.Cacute = 0x0106;
+ t.Caron = 0xf6ca;
+ t.Caronsmall = 0xf6f5;
+ t.Ccaron = 0x010c;
+ t.Ccedilla = 0x00c7;
+ t.Ccedillaacute = 0x1e08;
+ t.Ccedillasmall = 0xf7e7;
+ t.Ccircle = 0x24b8;
+ t.Ccircumflex = 0x0108;
+ t.Cdot = 0x010a;
+ t.Cdotaccent = 0x010a;
+ t.Cedillasmall = 0xf7b8;
+ t.Chaarmenian = 0x0549;
+ t.Cheabkhasiancyrillic = 0x04bc;
+ t.Checyrillic = 0x0427;
+ t.Chedescenderabkhasiancyrillic = 0x04be;
+ t.Chedescendercyrillic = 0x04b6;
+ t.Chedieresiscyrillic = 0x04f4;
+ t.Cheharmenian = 0x0543;
+ t.Chekhakassiancyrillic = 0x04cb;
+ t.Cheverticalstrokecyrillic = 0x04b8;
+ t.Chi = 0x03a7;
+ t.Chook = 0x0187;
+ t.Circumflexsmall = 0xf6f6;
+ t.Cmonospace = 0xff23;
+ t.Coarmenian = 0x0551;
+ t.Csmall = 0xf763;
+ t.D = 0x0044;
+ t.DZ = 0x01f1;
+ t.DZcaron = 0x01c4;
+ t.Daarmenian = 0x0534;
+ t.Dafrican = 0x0189;
+ t.Dcaron = 0x010e;
+ t.Dcedilla = 0x1e10;
+ t.Dcircle = 0x24b9;
+ t.Dcircumflexbelow = 0x1e12;
+ t.Dcroat = 0x0110;
+ t.Ddotaccent = 0x1e0a;
+ t.Ddotbelow = 0x1e0c;
+ t.Decyrillic = 0x0414;
+ t.Deicoptic = 0x03ee;
+ t.Delta = 0x2206;
+ t.Deltagreek = 0x0394;
+ t.Dhook = 0x018a;
+ t.Dieresis = 0xf6cb;
+ t.DieresisAcute = 0xf6cc;
+ t.DieresisGrave = 0xf6cd;
+ t.Dieresissmall = 0xf7a8;
+ t.Digammagreek = 0x03dc;
+ t.Djecyrillic = 0x0402;
+ t.Dlinebelow = 0x1e0e;
+ t.Dmonospace = 0xff24;
+ t.Dotaccentsmall = 0xf6f7;
+ t.Dslash = 0x0110;
+ t.Dsmall = 0xf764;
+ t.Dtopbar = 0x018b;
+ t.Dz = 0x01f2;
+ t.Dzcaron = 0x01c5;
+ t.Dzeabkhasiancyrillic = 0x04e0;
+ t.Dzecyrillic = 0x0405;
+ t.Dzhecyrillic = 0x040f;
+ t.E = 0x0045;
+ t.Eacute = 0x00c9;
+ t.Eacutesmall = 0xf7e9;
+ t.Ebreve = 0x0114;
+ t.Ecaron = 0x011a;
+ t.Ecedillabreve = 0x1e1c;
+ t.Echarmenian = 0x0535;
+ t.Ecircle = 0x24ba;
+ t.Ecircumflex = 0x00ca;
+ t.Ecircumflexacute = 0x1ebe;
+ t.Ecircumflexbelow = 0x1e18;
+ t.Ecircumflexdotbelow = 0x1ec6;
+ t.Ecircumflexgrave = 0x1ec0;
+ t.Ecircumflexhookabove = 0x1ec2;
+ t.Ecircumflexsmall = 0xf7ea;
+ t.Ecircumflextilde = 0x1ec4;
+ t.Ecyrillic = 0x0404;
+ t.Edblgrave = 0x0204;
+ t.Edieresis = 0x00cb;
+ t.Edieresissmall = 0xf7eb;
+ t.Edot = 0x0116;
+ t.Edotaccent = 0x0116;
+ t.Edotbelow = 0x1eb8;
+ t.Efcyrillic = 0x0424;
+ t.Egrave = 0x00c8;
+ t.Egravesmall = 0xf7e8;
+ t.Eharmenian = 0x0537;
+ t.Ehookabove = 0x1eba;
+ t.Eightroman = 0x2167;
+ t.Einvertedbreve = 0x0206;
+ t.Eiotifiedcyrillic = 0x0464;
+ t.Elcyrillic = 0x041b;
+ t.Elevenroman = 0x216a;
+ t.Emacron = 0x0112;
+ t.Emacronacute = 0x1e16;
+ t.Emacrongrave = 0x1e14;
+ t.Emcyrillic = 0x041c;
+ t.Emonospace = 0xff25;
+ t.Encyrillic = 0x041d;
+ t.Endescendercyrillic = 0x04a2;
+ t.Eng = 0x014a;
+ t.Enghecyrillic = 0x04a4;
+ t.Enhookcyrillic = 0x04c7;
+ t.Eogonek = 0x0118;
+ t.Eopen = 0x0190;
+ t.Epsilon = 0x0395;
+ t.Epsilontonos = 0x0388;
+ t.Ercyrillic = 0x0420;
+ t.Ereversed = 0x018e;
+ t.Ereversedcyrillic = 0x042d;
+ t.Escyrillic = 0x0421;
+ t.Esdescendercyrillic = 0x04aa;
+ t.Esh = 0x01a9;
+ t.Esmall = 0xf765;
+ t.Eta = 0x0397;
+ t.Etarmenian = 0x0538;
+ t.Etatonos = 0x0389;
+ t.Eth = 0x00d0;
+ t.Ethsmall = 0xf7f0;
+ t.Etilde = 0x1ebc;
+ t.Etildebelow = 0x1e1a;
+ t.Euro = 0x20ac;
+ t.Ezh = 0x01b7;
+ t.Ezhcaron = 0x01ee;
+ t.Ezhreversed = 0x01b8;
+ t.F = 0x0046;
+ t.Fcircle = 0x24bb;
+ t.Fdotaccent = 0x1e1e;
+ t.Feharmenian = 0x0556;
+ t.Feicoptic = 0x03e4;
+ t.Fhook = 0x0191;
+ t.Fitacyrillic = 0x0472;
+ t.Fiveroman = 0x2164;
+ t.Fmonospace = 0xff26;
+ t.Fourroman = 0x2163;
+ t.Fsmall = 0xf766;
+ t.G = 0x0047;
+ t.GBsquare = 0x3387;
+ t.Gacute = 0x01f4;
+ t.Gamma = 0x0393;
+ t.Gammaafrican = 0x0194;
+ t.Gangiacoptic = 0x03ea;
+ t.Gbreve = 0x011e;
+ t.Gcaron = 0x01e6;
+ t.Gcedilla = 0x0122;
+ t.Gcircle = 0x24bc;
+ t.Gcircumflex = 0x011c;
+ t.Gcommaaccent = 0x0122;
+ t.Gdot = 0x0120;
+ t.Gdotaccent = 0x0120;
+ t.Gecyrillic = 0x0413;
+ t.Ghadarmenian = 0x0542;
+ t.Ghemiddlehookcyrillic = 0x0494;
+ t.Ghestrokecyrillic = 0x0492;
+ t.Gheupturncyrillic = 0x0490;
+ t.Ghook = 0x0193;
+ t.Gimarmenian = 0x0533;
+ t.Gjecyrillic = 0x0403;
+ t.Gmacron = 0x1e20;
+ t.Gmonospace = 0xff27;
+ t.Grave = 0xf6ce;
+ t.Gravesmall = 0xf760;
+ t.Gsmall = 0xf767;
+ t.Gsmallhook = 0x029b;
+ t.Gstroke = 0x01e4;
+ t.H = 0x0048;
+ t.H18533 = 0x25cf;
+ t.H18543 = 0x25aa;
+ t.H18551 = 0x25ab;
+ t.H22073 = 0x25a1;
+ t.HPsquare = 0x33cb;
+ t.Haabkhasiancyrillic = 0x04a8;
+ t.Hadescendercyrillic = 0x04b2;
+ t.Hardsigncyrillic = 0x042a;
+ t.Hbar = 0x0126;
+ t.Hbrevebelow = 0x1e2a;
+ t.Hcedilla = 0x1e28;
+ t.Hcircle = 0x24bd;
+ t.Hcircumflex = 0x0124;
+ t.Hdieresis = 0x1e26;
+ t.Hdotaccent = 0x1e22;
+ t.Hdotbelow = 0x1e24;
+ t.Hmonospace = 0xff28;
+ t.Hoarmenian = 0x0540;
+ t.Horicoptic = 0x03e8;
+ t.Hsmall = 0xf768;
+ t.Hungarumlaut = 0xf6cf;
+ t.Hungarumlautsmall = 0xf6f8;
+ t.Hzsquare = 0x3390;
+ t.I = 0x0049;
+ t.IAcyrillic = 0x042f;
+ t.IJ = 0x0132;
+ t.IUcyrillic = 0x042e;
+ t.Iacute = 0x00cd;
+ t.Iacutesmall = 0xf7ed;
+ t.Ibreve = 0x012c;
+ t.Icaron = 0x01cf;
+ t.Icircle = 0x24be;
+ t.Icircumflex = 0x00ce;
+ t.Icircumflexsmall = 0xf7ee;
+ t.Icyrillic = 0x0406;
+ t.Idblgrave = 0x0208;
+ t.Idieresis = 0x00cf;
+ t.Idieresisacute = 0x1e2e;
+ t.Idieresiscyrillic = 0x04e4;
+ t.Idieresissmall = 0xf7ef;
+ t.Idot = 0x0130;
+ t.Idotaccent = 0x0130;
+ t.Idotbelow = 0x1eca;
+ t.Iebrevecyrillic = 0x04d6;
+ t.Iecyrillic = 0x0415;
+ t.Ifraktur = 0x2111;
+ t.Igrave = 0x00cc;
+ t.Igravesmall = 0xf7ec;
+ t.Ihookabove = 0x1ec8;
+ t.Iicyrillic = 0x0418;
+ t.Iinvertedbreve = 0x020a;
+ t.Iishortcyrillic = 0x0419;
+ t.Imacron = 0x012a;
+ t.Imacroncyrillic = 0x04e2;
+ t.Imonospace = 0xff29;
+ t.Iniarmenian = 0x053b;
+ t.Iocyrillic = 0x0401;
+ t.Iogonek = 0x012e;
+ t.Iota = 0x0399;
+ t.Iotaafrican = 0x0196;
+ t.Iotadieresis = 0x03aa;
+ t.Iotatonos = 0x038a;
+ t.Ismall = 0xf769;
+ t.Istroke = 0x0197;
+ t.Itilde = 0x0128;
+ t.Itildebelow = 0x1e2c;
+ t.Izhitsacyrillic = 0x0474;
+ t.Izhitsadblgravecyrillic = 0x0476;
+ t.J = 0x004a;
+ t.Jaarmenian = 0x0541;
+ t.Jcircle = 0x24bf;
+ t.Jcircumflex = 0x0134;
+ t.Jecyrillic = 0x0408;
+ t.Jheharmenian = 0x054b;
+ t.Jmonospace = 0xff2a;
+ t.Jsmall = 0xf76a;
+ t.K = 0x004b;
+ t.KBsquare = 0x3385;
+ t.KKsquare = 0x33cd;
+ t.Kabashkircyrillic = 0x04a0;
+ t.Kacute = 0x1e30;
+ t.Kacyrillic = 0x041a;
+ t.Kadescendercyrillic = 0x049a;
+ t.Kahookcyrillic = 0x04c3;
+ t.Kappa = 0x039a;
+ t.Kastrokecyrillic = 0x049e;
+ t.Kaverticalstrokecyrillic = 0x049c;
+ t.Kcaron = 0x01e8;
+ t.Kcedilla = 0x0136;
+ t.Kcircle = 0x24c0;
+ t.Kcommaaccent = 0x0136;
+ t.Kdotbelow = 0x1e32;
+ t.Keharmenian = 0x0554;
+ t.Kenarmenian = 0x053f;
+ t.Khacyrillic = 0x0425;
+ t.Kheicoptic = 0x03e6;
+ t.Khook = 0x0198;
+ t.Kjecyrillic = 0x040c;
+ t.Klinebelow = 0x1e34;
+ t.Kmonospace = 0xff2b;
+ t.Koppacyrillic = 0x0480;
+ t.Koppagreek = 0x03de;
+ t.Ksicyrillic = 0x046e;
+ t.Ksmall = 0xf76b;
+ t.L = 0x004c;
+ t.LJ = 0x01c7;
+ t.LL = 0xf6bf;
+ t.Lacute = 0x0139;
+ t.Lambda = 0x039b;
+ t.Lcaron = 0x013d;
+ t.Lcedilla = 0x013b;
+ t.Lcircle = 0x24c1;
+ t.Lcircumflexbelow = 0x1e3c;
+ t.Lcommaaccent = 0x013b;
+ t.Ldot = 0x013f;
+ t.Ldotaccent = 0x013f;
+ t.Ldotbelow = 0x1e36;
+ t.Ldotbelowmacron = 0x1e38;
+ t.Liwnarmenian = 0x053c;
+ t.Lj = 0x01c8;
+ t.Ljecyrillic = 0x0409;
+ t.Llinebelow = 0x1e3a;
+ t.Lmonospace = 0xff2c;
+ t.Lslash = 0x0141;
+ t.Lslashsmall = 0xf6f9;
+ t.Lsmall = 0xf76c;
+ t.M = 0x004d;
+ t.MBsquare = 0x3386;
+ t.Macron = 0xf6d0;
+ t.Macronsmall = 0xf7af;
+ t.Macute = 0x1e3e;
+ t.Mcircle = 0x24c2;
+ t.Mdotaccent = 0x1e40;
+ t.Mdotbelow = 0x1e42;
+ t.Menarmenian = 0x0544;
+ t.Mmonospace = 0xff2d;
+ t.Msmall = 0xf76d;
+ t.Mturned = 0x019c;
+ t.Mu = 0x039c;
+ t.N = 0x004e;
+ t.NJ = 0x01ca;
+ t.Nacute = 0x0143;
+ t.Ncaron = 0x0147;
+ t.Ncedilla = 0x0145;
+ t.Ncircle = 0x24c3;
+ t.Ncircumflexbelow = 0x1e4a;
+ t.Ncommaaccent = 0x0145;
+ t.Ndotaccent = 0x1e44;
+ t.Ndotbelow = 0x1e46;
+ t.Nhookleft = 0x019d;
+ t.Nineroman = 0x2168;
+ t.Nj = 0x01cb;
+ t.Njecyrillic = 0x040a;
+ t.Nlinebelow = 0x1e48;
+ t.Nmonospace = 0xff2e;
+ t.Nowarmenian = 0x0546;
+ t.Nsmall = 0xf76e;
+ t.Ntilde = 0x00d1;
+ t.Ntildesmall = 0xf7f1;
+ t.Nu = 0x039d;
+ t.O = 0x004f;
+ t.OE = 0x0152;
+ t.OEsmall = 0xf6fa;
+ t.Oacute = 0x00d3;
+ t.Oacutesmall = 0xf7f3;
+ t.Obarredcyrillic = 0x04e8;
+ t.Obarreddieresiscyrillic = 0x04ea;
+ t.Obreve = 0x014e;
+ t.Ocaron = 0x01d1;
+ t.Ocenteredtilde = 0x019f;
+ t.Ocircle = 0x24c4;
+ t.Ocircumflex = 0x00d4;
+ t.Ocircumflexacute = 0x1ed0;
+ t.Ocircumflexdotbelow = 0x1ed8;
+ t.Ocircumflexgrave = 0x1ed2;
+ t.Ocircumflexhookabove = 0x1ed4;
+ t.Ocircumflexsmall = 0xf7f4;
+ t.Ocircumflextilde = 0x1ed6;
+ t.Ocyrillic = 0x041e;
+ t.Odblacute = 0x0150;
+ t.Odblgrave = 0x020c;
+ t.Odieresis = 0x00d6;
+ t.Odieresiscyrillic = 0x04e6;
+ t.Odieresissmall = 0xf7f6;
+ t.Odotbelow = 0x1ecc;
+ t.Ogoneksmall = 0xf6fb;
+ t.Ograve = 0x00d2;
+ t.Ogravesmall = 0xf7f2;
+ t.Oharmenian = 0x0555;
+ t.Ohm = 0x2126;
+ t.Ohookabove = 0x1ece;
+ t.Ohorn = 0x01a0;
+ t.Ohornacute = 0x1eda;
+ t.Ohorndotbelow = 0x1ee2;
+ t.Ohorngrave = 0x1edc;
+ t.Ohornhookabove = 0x1ede;
+ t.Ohorntilde = 0x1ee0;
+ t.Ohungarumlaut = 0x0150;
+ t.Oi = 0x01a2;
+ t.Oinvertedbreve = 0x020e;
+ t.Omacron = 0x014c;
+ t.Omacronacute = 0x1e52;
+ t.Omacrongrave = 0x1e50;
+ t.Omega = 0x2126;
+ t.Omegacyrillic = 0x0460;
+ t.Omegagreek = 0x03a9;
+ t.Omegaroundcyrillic = 0x047a;
+ t.Omegatitlocyrillic = 0x047c;
+ t.Omegatonos = 0x038f;
+ t.Omicron = 0x039f;
+ t.Omicrontonos = 0x038c;
+ t.Omonospace = 0xff2f;
+ t.Oneroman = 0x2160;
+ t.Oogonek = 0x01ea;
+ t.Oogonekmacron = 0x01ec;
+ t.Oopen = 0x0186;
+ t.Oslash = 0x00d8;
+ t.Oslashacute = 0x01fe;
+ t.Oslashsmall = 0xf7f8;
+ t.Osmall = 0xf76f;
+ t.Ostrokeacute = 0x01fe;
+ t.Otcyrillic = 0x047e;
+ t.Otilde = 0x00d5;
+ t.Otildeacute = 0x1e4c;
+ t.Otildedieresis = 0x1e4e;
+ t.Otildesmall = 0xf7f5;
+ t.P = 0x0050;
+ t.Pacute = 0x1e54;
+ t.Pcircle = 0x24c5;
+ t.Pdotaccent = 0x1e56;
+ t.Pecyrillic = 0x041f;
+ t.Peharmenian = 0x054a;
+ t.Pemiddlehookcyrillic = 0x04a6;
+ t.Phi = 0x03a6;
+ t.Phook = 0x01a4;
+ t.Pi = 0x03a0;
+ t.Piwrarmenian = 0x0553;
+ t.Pmonospace = 0xff30;
+ t.Psi = 0x03a8;
+ t.Psicyrillic = 0x0470;
+ t.Psmall = 0xf770;
+ t.Q = 0x0051;
+ t.Qcircle = 0x24c6;
+ t.Qmonospace = 0xff31;
+ t.Qsmall = 0xf771;
+ t.R = 0x0052;
+ t.Raarmenian = 0x054c;
+ t.Racute = 0x0154;
+ t.Rcaron = 0x0158;
+ t.Rcedilla = 0x0156;
+ t.Rcircle = 0x24c7;
+ t.Rcommaaccent = 0x0156;
+ t.Rdblgrave = 0x0210;
+ t.Rdotaccent = 0x1e58;
+ t.Rdotbelow = 0x1e5a;
+ t.Rdotbelowmacron = 0x1e5c;
+ t.Reharmenian = 0x0550;
+ t.Rfraktur = 0x211c;
+ t.Rho = 0x03a1;
+ t.Ringsmall = 0xf6fc;
+ t.Rinvertedbreve = 0x0212;
+ t.Rlinebelow = 0x1e5e;
+ t.Rmonospace = 0xff32;
+ t.Rsmall = 0xf772;
+ t.Rsmallinverted = 0x0281;
+ t.Rsmallinvertedsuperior = 0x02b6;
+ t.S = 0x0053;
+ t.SF010000 = 0x250c;
+ t.SF020000 = 0x2514;
+ t.SF030000 = 0x2510;
+ t.SF040000 = 0x2518;
+ t.SF050000 = 0x253c;
+ t.SF060000 = 0x252c;
+ t.SF070000 = 0x2534;
+ t.SF080000 = 0x251c;
+ t.SF090000 = 0x2524;
+ t.SF100000 = 0x2500;
+ t.SF110000 = 0x2502;
+ t.SF190000 = 0x2561;
+ t.SF200000 = 0x2562;
+ t.SF210000 = 0x2556;
+ t.SF220000 = 0x2555;
+ t.SF230000 = 0x2563;
+ t.SF240000 = 0x2551;
+ t.SF250000 = 0x2557;
+ t.SF260000 = 0x255d;
+ t.SF270000 = 0x255c;
+ t.SF280000 = 0x255b;
+ t.SF360000 = 0x255e;
+ t.SF370000 = 0x255f;
+ t.SF380000 = 0x255a;
+ t.SF390000 = 0x2554;
+ t.SF400000 = 0x2569;
+ t.SF410000 = 0x2566;
+ t.SF420000 = 0x2560;
+ t.SF430000 = 0x2550;
+ t.SF440000 = 0x256c;
+ t.SF450000 = 0x2567;
+ t.SF460000 = 0x2568;
+ t.SF470000 = 0x2564;
+ t.SF480000 = 0x2565;
+ t.SF490000 = 0x2559;
+ t.SF500000 = 0x2558;
+ t.SF510000 = 0x2552;
+ t.SF520000 = 0x2553;
+ t.SF530000 = 0x256b;
+ t.SF540000 = 0x256a;
+ t.Sacute = 0x015a;
+ t.Sacutedotaccent = 0x1e64;
+ t.Sampigreek = 0x03e0;
+ t.Scaron = 0x0160;
+ t.Scarondotaccent = 0x1e66;
+ t.Scaronsmall = 0xf6fd;
+ t.Scedilla = 0x015e;
+ t.Schwa = 0x018f;
+ t.Schwacyrillic = 0x04d8;
+ t.Schwadieresiscyrillic = 0x04da;
+ t.Scircle = 0x24c8;
+ t.Scircumflex = 0x015c;
+ t.Scommaaccent = 0x0218;
+ t.Sdotaccent = 0x1e60;
+ t.Sdotbelow = 0x1e62;
+ t.Sdotbelowdotaccent = 0x1e68;
+ t.Seharmenian = 0x054d;
+ t.Sevenroman = 0x2166;
+ t.Shaarmenian = 0x0547;
+ t.Shacyrillic = 0x0428;
+ t.Shchacyrillic = 0x0429;
+ t.Sheicoptic = 0x03e2;
+ t.Shhacyrillic = 0x04ba;
+ t.Shimacoptic = 0x03ec;
+ t.Sigma = 0x03a3;
+ t.Sixroman = 0x2165;
+ t.Smonospace = 0xff33;
+ t.Softsigncyrillic = 0x042c;
+ t.Ssmall = 0xf773;
+ t.Stigmagreek = 0x03da;
+ t.T = 0x0054;
+ t.Tau = 0x03a4;
+ t.Tbar = 0x0166;
+ t.Tcaron = 0x0164;
+ t.Tcedilla = 0x0162;
+ t.Tcircle = 0x24c9;
+ t.Tcircumflexbelow = 0x1e70;
+ t.Tcommaaccent = 0x0162;
+ t.Tdotaccent = 0x1e6a;
+ t.Tdotbelow = 0x1e6c;
+ t.Tecyrillic = 0x0422;
+ t.Tedescendercyrillic = 0x04ac;
+ t.Tenroman = 0x2169;
+ t.Tetsecyrillic = 0x04b4;
+ t.Theta = 0x0398;
+ t.Thook = 0x01ac;
+ t.Thorn = 0x00de;
+ t.Thornsmall = 0xf7fe;
+ t.Threeroman = 0x2162;
+ t.Tildesmall = 0xf6fe;
+ t.Tiwnarmenian = 0x054f;
+ t.Tlinebelow = 0x1e6e;
+ t.Tmonospace = 0xff34;
+ t.Toarmenian = 0x0539;
+ t.Tonefive = 0x01bc;
+ t.Tonesix = 0x0184;
+ t.Tonetwo = 0x01a7;
+ t.Tretroflexhook = 0x01ae;
+ t.Tsecyrillic = 0x0426;
+ t.Tshecyrillic = 0x040b;
+ t.Tsmall = 0xf774;
+ t.Twelveroman = 0x216b;
+ t.Tworoman = 0x2161;
+ t.U = 0x0055;
+ t.Uacute = 0x00da;
+ t.Uacutesmall = 0xf7fa;
+ t.Ubreve = 0x016c;
+ t.Ucaron = 0x01d3;
+ t.Ucircle = 0x24ca;
+ t.Ucircumflex = 0x00db;
+ t.Ucircumflexbelow = 0x1e76;
+ t.Ucircumflexsmall = 0xf7fb;
+ t.Ucyrillic = 0x0423;
+ t.Udblacute = 0x0170;
+ t.Udblgrave = 0x0214;
+ t.Udieresis = 0x00dc;
+ t.Udieresisacute = 0x01d7;
+ t.Udieresisbelow = 0x1e72;
+ t.Udieresiscaron = 0x01d9;
+ t.Udieresiscyrillic = 0x04f0;
+ t.Udieresisgrave = 0x01db;
+ t.Udieresismacron = 0x01d5;
+ t.Udieresissmall = 0xf7fc;
+ t.Udotbelow = 0x1ee4;
+ t.Ugrave = 0x00d9;
+ t.Ugravesmall = 0xf7f9;
+ t.Uhookabove = 0x1ee6;
+ t.Uhorn = 0x01af;
+ t.Uhornacute = 0x1ee8;
+ t.Uhorndotbelow = 0x1ef0;
+ t.Uhorngrave = 0x1eea;
+ t.Uhornhookabove = 0x1eec;
+ t.Uhorntilde = 0x1eee;
+ t.Uhungarumlaut = 0x0170;
+ t.Uhungarumlautcyrillic = 0x04f2;
+ t.Uinvertedbreve = 0x0216;
+ t.Ukcyrillic = 0x0478;
+ t.Umacron = 0x016a;
+ t.Umacroncyrillic = 0x04ee;
+ t.Umacrondieresis = 0x1e7a;
+ t.Umonospace = 0xff35;
+ t.Uogonek = 0x0172;
+ t.Upsilon = 0x03a5;
+ t.Upsilon1 = 0x03d2;
+ t.Upsilonacutehooksymbolgreek = 0x03d3;
+ t.Upsilonafrican = 0x01b1;
+ t.Upsilondieresis = 0x03ab;
+ t.Upsilondieresishooksymbolgreek = 0x03d4;
+ t.Upsilonhooksymbol = 0x03d2;
+ t.Upsilontonos = 0x038e;
+ t.Uring = 0x016e;
+ t.Ushortcyrillic = 0x040e;
+ t.Usmall = 0xf775;
+ t.Ustraightcyrillic = 0x04ae;
+ t.Ustraightstrokecyrillic = 0x04b0;
+ t.Utilde = 0x0168;
+ t.Utildeacute = 0x1e78;
+ t.Utildebelow = 0x1e74;
+ t.V = 0x0056;
+ t.Vcircle = 0x24cb;
+ t.Vdotbelow = 0x1e7e;
+ t.Vecyrillic = 0x0412;
+ t.Vewarmenian = 0x054e;
+ t.Vhook = 0x01b2;
+ t.Vmonospace = 0xff36;
+ t.Voarmenian = 0x0548;
+ t.Vsmall = 0xf776;
+ t.Vtilde = 0x1e7c;
+ t.W = 0x0057;
+ t.Wacute = 0x1e82;
+ t.Wcircle = 0x24cc;
+ t.Wcircumflex = 0x0174;
+ t.Wdieresis = 0x1e84;
+ t.Wdotaccent = 0x1e86;
+ t.Wdotbelow = 0x1e88;
+ t.Wgrave = 0x1e80;
+ t.Wmonospace = 0xff37;
+ t.Wsmall = 0xf777;
+ t.X = 0x0058;
+ t.Xcircle = 0x24cd;
+ t.Xdieresis = 0x1e8c;
+ t.Xdotaccent = 0x1e8a;
+ t.Xeharmenian = 0x053d;
+ t.Xi = 0x039e;
+ t.Xmonospace = 0xff38;
+ t.Xsmall = 0xf778;
+ t.Y = 0x0059;
+ t.Yacute = 0x00dd;
+ t.Yacutesmall = 0xf7fd;
+ t.Yatcyrillic = 0x0462;
+ t.Ycircle = 0x24ce;
+ t.Ycircumflex = 0x0176;
+ t.Ydieresis = 0x0178;
+ t.Ydieresissmall = 0xf7ff;
+ t.Ydotaccent = 0x1e8e;
+ t.Ydotbelow = 0x1ef4;
+ t.Yericyrillic = 0x042b;
+ t.Yerudieresiscyrillic = 0x04f8;
+ t.Ygrave = 0x1ef2;
+ t.Yhook = 0x01b3;
+ t.Yhookabove = 0x1ef6;
+ t.Yiarmenian = 0x0545;
+ t.Yicyrillic = 0x0407;
+ t.Yiwnarmenian = 0x0552;
+ t.Ymonospace = 0xff39;
+ t.Ysmall = 0xf779;
+ t.Ytilde = 0x1ef8;
+ t.Yusbigcyrillic = 0x046a;
+ t.Yusbigiotifiedcyrillic = 0x046c;
+ t.Yuslittlecyrillic = 0x0466;
+ t.Yuslittleiotifiedcyrillic = 0x0468;
+ t.Z = 0x005a;
+ t.Zaarmenian = 0x0536;
+ t.Zacute = 0x0179;
+ t.Zcaron = 0x017d;
+ t.Zcaronsmall = 0xf6ff;
+ t.Zcircle = 0x24cf;
+ t.Zcircumflex = 0x1e90;
+ t.Zdot = 0x017b;
+ t.Zdotaccent = 0x017b;
+ t.Zdotbelow = 0x1e92;
+ t.Zecyrillic = 0x0417;
+ t.Zedescendercyrillic = 0x0498;
+ t.Zedieresiscyrillic = 0x04de;
+ t.Zeta = 0x0396;
+ t.Zhearmenian = 0x053a;
+ t.Zhebrevecyrillic = 0x04c1;
+ t.Zhecyrillic = 0x0416;
+ t.Zhedescendercyrillic = 0x0496;
+ t.Zhedieresiscyrillic = 0x04dc;
+ t.Zlinebelow = 0x1e94;
+ t.Zmonospace = 0xff3a;
+ t.Zsmall = 0xf77a;
+ t.Zstroke = 0x01b5;
+ t.a = 0x0061;
+ t.aabengali = 0x0986;
+ t.aacute = 0x00e1;
+ t.aadeva = 0x0906;
+ t.aagujarati = 0x0a86;
+ t.aagurmukhi = 0x0a06;
+ t.aamatragurmukhi = 0x0a3e;
+ t.aarusquare = 0x3303;
+ t.aavowelsignbengali = 0x09be;
+ t.aavowelsigndeva = 0x093e;
+ t.aavowelsigngujarati = 0x0abe;
+ t.abbreviationmarkarmenian = 0x055f;
+ t.abbreviationsigndeva = 0x0970;
+ t.abengali = 0x0985;
+ t.abopomofo = 0x311a;
+ t.abreve = 0x0103;
+ t.abreveacute = 0x1eaf;
+ t.abrevecyrillic = 0x04d1;
+ t.abrevedotbelow = 0x1eb7;
+ t.abrevegrave = 0x1eb1;
+ t.abrevehookabove = 0x1eb3;
+ t.abrevetilde = 0x1eb5;
+ t.acaron = 0x01ce;
+ t.acircle = 0x24d0;
+ t.acircumflex = 0x00e2;
+ t.acircumflexacute = 0x1ea5;
+ t.acircumflexdotbelow = 0x1ead;
+ t.acircumflexgrave = 0x1ea7;
+ t.acircumflexhookabove = 0x1ea9;
+ t.acircumflextilde = 0x1eab;
+ t.acute = 0x00b4;
+ t.acutebelowcmb = 0x0317;
+ t.acutecmb = 0x0301;
+ t.acutecomb = 0x0301;
+ t.acutedeva = 0x0954;
+ t.acutelowmod = 0x02cf;
+ t.acutetonecmb = 0x0341;
+ t.acyrillic = 0x0430;
+ t.adblgrave = 0x0201;
+ t.addakgurmukhi = 0x0a71;
+ t.adeva = 0x0905;
+ t.adieresis = 0x00e4;
+ t.adieresiscyrillic = 0x04d3;
+ t.adieresismacron = 0x01df;
+ t.adotbelow = 0x1ea1;
+ t.adotmacron = 0x01e1;
+ t.ae = 0x00e6;
+ t.aeacute = 0x01fd;
+ t.aekorean = 0x3150;
+ t.aemacron = 0x01e3;
+ t.afii00208 = 0x2015;
+ t.afii08941 = 0x20a4;
+ t.afii10017 = 0x0410;
+ t.afii10018 = 0x0411;
+ t.afii10019 = 0x0412;
+ t.afii10020 = 0x0413;
+ t.afii10021 = 0x0414;
+ t.afii10022 = 0x0415;
+ t.afii10023 = 0x0401;
+ t.afii10024 = 0x0416;
+ t.afii10025 = 0x0417;
+ t.afii10026 = 0x0418;
+ t.afii10027 = 0x0419;
+ t.afii10028 = 0x041a;
+ t.afii10029 = 0x041b;
+ t.afii10030 = 0x041c;
+ t.afii10031 = 0x041d;
+ t.afii10032 = 0x041e;
+ t.afii10033 = 0x041f;
+ t.afii10034 = 0x0420;
+ t.afii10035 = 0x0421;
+ t.afii10036 = 0x0422;
+ t.afii10037 = 0x0423;
+ t.afii10038 = 0x0424;
+ t.afii10039 = 0x0425;
+ t.afii10040 = 0x0426;
+ t.afii10041 = 0x0427;
+ t.afii10042 = 0x0428;
+ t.afii10043 = 0x0429;
+ t.afii10044 = 0x042a;
+ t.afii10045 = 0x042b;
+ t.afii10046 = 0x042c;
+ t.afii10047 = 0x042d;
+ t.afii10048 = 0x042e;
+ t.afii10049 = 0x042f;
+ t.afii10050 = 0x0490;
+ t.afii10051 = 0x0402;
+ t.afii10052 = 0x0403;
+ t.afii10053 = 0x0404;
+ t.afii10054 = 0x0405;
+ t.afii10055 = 0x0406;
+ t.afii10056 = 0x0407;
+ t.afii10057 = 0x0408;
+ t.afii10058 = 0x0409;
+ t.afii10059 = 0x040a;
+ t.afii10060 = 0x040b;
+ t.afii10061 = 0x040c;
+ t.afii10062 = 0x040e;
+ t.afii10063 = 0xf6c4;
+ t.afii10064 = 0xf6c5;
+ t.afii10065 = 0x0430;
+ t.afii10066 = 0x0431;
+ t.afii10067 = 0x0432;
+ t.afii10068 = 0x0433;
+ t.afii10069 = 0x0434;
+ t.afii10070 = 0x0435;
+ t.afii10071 = 0x0451;
+ t.afii10072 = 0x0436;
+ t.afii10073 = 0x0437;
+ t.afii10074 = 0x0438;
+ t.afii10075 = 0x0439;
+ t.afii10076 = 0x043a;
+ t.afii10077 = 0x043b;
+ t.afii10078 = 0x043c;
+ t.afii10079 = 0x043d;
+ t.afii10080 = 0x043e;
+ t.afii10081 = 0x043f;
+ t.afii10082 = 0x0440;
+ t.afii10083 = 0x0441;
+ t.afii10084 = 0x0442;
+ t.afii10085 = 0x0443;
+ t.afii10086 = 0x0444;
+ t.afii10087 = 0x0445;
+ t.afii10088 = 0x0446;
+ t.afii10089 = 0x0447;
+ t.afii10090 = 0x0448;
+ t.afii10091 = 0x0449;
+ t.afii10092 = 0x044a;
+ t.afii10093 = 0x044b;
+ t.afii10094 = 0x044c;
+ t.afii10095 = 0x044d;
+ t.afii10096 = 0x044e;
+ t.afii10097 = 0x044f;
+ t.afii10098 = 0x0491;
+ t.afii10099 = 0x0452;
+ t.afii10100 = 0x0453;
+ t.afii10101 = 0x0454;
+ t.afii10102 = 0x0455;
+ t.afii10103 = 0x0456;
+ t.afii10104 = 0x0457;
+ t.afii10105 = 0x0458;
+ t.afii10106 = 0x0459;
+ t.afii10107 = 0x045a;
+ t.afii10108 = 0x045b;
+ t.afii10109 = 0x045c;
+ t.afii10110 = 0x045e;
+ t.afii10145 = 0x040f;
+ t.afii10146 = 0x0462;
+ t.afii10147 = 0x0472;
+ t.afii10148 = 0x0474;
+ t.afii10192 = 0xf6c6;
+ t.afii10193 = 0x045f;
+ t.afii10194 = 0x0463;
+ t.afii10195 = 0x0473;
+ t.afii10196 = 0x0475;
+ t.afii10831 = 0xf6c7;
+ t.afii10832 = 0xf6c8;
+ t.afii10846 = 0x04d9;
+ t.afii299 = 0x200e;
+ t.afii300 = 0x200f;
+ t.afii301 = 0x200d;
+ t.afii57381 = 0x066a;
+ t.afii57388 = 0x060c;
+ t.afii57392 = 0x0660;
+ t.afii57393 = 0x0661;
+ t.afii57394 = 0x0662;
+ t.afii57395 = 0x0663;
+ t.afii57396 = 0x0664;
+ t.afii57397 = 0x0665;
+ t.afii57398 = 0x0666;
+ t.afii57399 = 0x0667;
+ t.afii57400 = 0x0668;
+ t.afii57401 = 0x0669;
+ t.afii57403 = 0x061b;
+ t.afii57407 = 0x061f;
+ t.afii57409 = 0x0621;
+ t.afii57410 = 0x0622;
+ t.afii57411 = 0x0623;
+ t.afii57412 = 0x0624;
+ t.afii57413 = 0x0625;
+ t.afii57414 = 0x0626;
+ t.afii57415 = 0x0627;
+ t.afii57416 = 0x0628;
+ t.afii57417 = 0x0629;
+ t.afii57418 = 0x062a;
+ t.afii57419 = 0x062b;
+ t.afii57420 = 0x062c;
+ t.afii57421 = 0x062d;
+ t.afii57422 = 0x062e;
+ t.afii57423 = 0x062f;
+ t.afii57424 = 0x0630;
+ t.afii57425 = 0x0631;
+ t.afii57426 = 0x0632;
+ t.afii57427 = 0x0633;
+ t.afii57428 = 0x0634;
+ t.afii57429 = 0x0635;
+ t.afii57430 = 0x0636;
+ t.afii57431 = 0x0637;
+ t.afii57432 = 0x0638;
+ t.afii57433 = 0x0639;
+ t.afii57434 = 0x063a;
+ t.afii57440 = 0x0640;
+ t.afii57441 = 0x0641;
+ t.afii57442 = 0x0642;
+ t.afii57443 = 0x0643;
+ t.afii57444 = 0x0644;
+ t.afii57445 = 0x0645;
+ t.afii57446 = 0x0646;
+ t.afii57448 = 0x0648;
+ t.afii57449 = 0x0649;
+ t.afii57450 = 0x064a;
+ t.afii57451 = 0x064b;
+ t.afii57452 = 0x064c;
+ t.afii57453 = 0x064d;
+ t.afii57454 = 0x064e;
+ t.afii57455 = 0x064f;
+ t.afii57456 = 0x0650;
+ t.afii57457 = 0x0651;
+ t.afii57458 = 0x0652;
+ t.afii57470 = 0x0647;
+ t.afii57505 = 0x06a4;
+ t.afii57506 = 0x067e;
+ t.afii57507 = 0x0686;
+ t.afii57508 = 0x0698;
+ t.afii57509 = 0x06af;
+ t.afii57511 = 0x0679;
+ t.afii57512 = 0x0688;
+ t.afii57513 = 0x0691;
+ t.afii57514 = 0x06ba;
+ t.afii57519 = 0x06d2;
+ t.afii57534 = 0x06d5;
+ t.afii57636 = 0x20aa;
+ t.afii57645 = 0x05be;
+ t.afii57658 = 0x05c3;
+ t.afii57664 = 0x05d0;
+ t.afii57665 = 0x05d1;
+ t.afii57666 = 0x05d2;
+ t.afii57667 = 0x05d3;
+ t.afii57668 = 0x05d4;
+ t.afii57669 = 0x05d5;
+ t.afii57670 = 0x05d6;
+ t.afii57671 = 0x05d7;
+ t.afii57672 = 0x05d8;
+ t.afii57673 = 0x05d9;
+ t.afii57674 = 0x05da;
+ t.afii57675 = 0x05db;
+ t.afii57676 = 0x05dc;
+ t.afii57677 = 0x05dd;
+ t.afii57678 = 0x05de;
+ t.afii57679 = 0x05df;
+ t.afii57680 = 0x05e0;
+ t.afii57681 = 0x05e1;
+ t.afii57682 = 0x05e2;
+ t.afii57683 = 0x05e3;
+ t.afii57684 = 0x05e4;
+ t.afii57685 = 0x05e5;
+ t.afii57686 = 0x05e6;
+ t.afii57687 = 0x05e7;
+ t.afii57688 = 0x05e8;
+ t.afii57689 = 0x05e9;
+ t.afii57690 = 0x05ea;
+ t.afii57694 = 0xfb2a;
+ t.afii57695 = 0xfb2b;
+ t.afii57700 = 0xfb4b;
+ t.afii57705 = 0xfb1f;
+ t.afii57716 = 0x05f0;
+ t.afii57717 = 0x05f1;
+ t.afii57718 = 0x05f2;
+ t.afii57723 = 0xfb35;
+ t.afii57793 = 0x05b4;
+ t.afii57794 = 0x05b5;
+ t.afii57795 = 0x05b6;
+ t.afii57796 = 0x05bb;
+ t.afii57797 = 0x05b8;
+ t.afii57798 = 0x05b7;
+ t.afii57799 = 0x05b0;
+ t.afii57800 = 0x05b2;
+ t.afii57801 = 0x05b1;
+ t.afii57802 = 0x05b3;
+ t.afii57803 = 0x05c2;
+ t.afii57804 = 0x05c1;
+ t.afii57806 = 0x05b9;
+ t.afii57807 = 0x05bc;
+ t.afii57839 = 0x05bd;
+ t.afii57841 = 0x05bf;
+ t.afii57842 = 0x05c0;
+ t.afii57929 = 0x02bc;
+ t.afii61248 = 0x2105;
+ t.afii61289 = 0x2113;
+ t.afii61352 = 0x2116;
+ t.afii61573 = 0x202c;
+ t.afii61574 = 0x202d;
+ t.afii61575 = 0x202e;
+ t.afii61664 = 0x200c;
+ t.afii63167 = 0x066d;
+ t.afii64937 = 0x02bd;
+ t.agrave = 0x00e0;
+ t.agujarati = 0x0a85;
+ t.agurmukhi = 0x0a05;
+ t.ahiragana = 0x3042;
+ t.ahookabove = 0x1ea3;
+ t.aibengali = 0x0990;
+ t.aibopomofo = 0x311e;
+ t.aideva = 0x0910;
+ t.aiecyrillic = 0x04d5;
+ t.aigujarati = 0x0a90;
+ t.aigurmukhi = 0x0a10;
+ t.aimatragurmukhi = 0x0a48;
+ t.ainarabic = 0x0639;
+ t.ainfinalarabic = 0xfeca;
+ t.aininitialarabic = 0xfecb;
+ t.ainmedialarabic = 0xfecc;
+ t.ainvertedbreve = 0x0203;
+ t.aivowelsignbengali = 0x09c8;
+ t.aivowelsigndeva = 0x0948;
+ t.aivowelsigngujarati = 0x0ac8;
+ t.akatakana = 0x30a2;
+ t.akatakanahalfwidth = 0xff71;
+ t.akorean = 0x314f;
+ t.alef = 0x05d0;
+ t.alefarabic = 0x0627;
+ t.alefdageshhebrew = 0xfb30;
+ t.aleffinalarabic = 0xfe8e;
+ t.alefhamzaabovearabic = 0x0623;
+ t.alefhamzaabovefinalarabic = 0xfe84;
+ t.alefhamzabelowarabic = 0x0625;
+ t.alefhamzabelowfinalarabic = 0xfe88;
+ t.alefhebrew = 0x05d0;
+ t.aleflamedhebrew = 0xfb4f;
+ t.alefmaddaabovearabic = 0x0622;
+ t.alefmaddaabovefinalarabic = 0xfe82;
+ t.alefmaksuraarabic = 0x0649;
+ t.alefmaksurafinalarabic = 0xfef0;
+ t.alefmaksurainitialarabic = 0xfef3;
+ t.alefmaksuramedialarabic = 0xfef4;
+ t.alefpatahhebrew = 0xfb2e;
+ t.alefqamatshebrew = 0xfb2f;
+ t.aleph = 0x2135;
+ t.allequal = 0x224c;
+ t.alpha = 0x03b1;
+ t.alphatonos = 0x03ac;
+ t.amacron = 0x0101;
+ t.amonospace = 0xff41;
+ t.ampersand = 0x0026;
+ t.ampersandmonospace = 0xff06;
+ t.ampersandsmall = 0xf726;
+ t.amsquare = 0x33c2;
+ t.anbopomofo = 0x3122;
+ t.angbopomofo = 0x3124;
+ t.angbracketleft = 0x3008;
+ t.angbracketright = 0x3009;
+ t.angkhankhuthai = 0x0e5a;
+ t.angle = 0x2220;
+ t.anglebracketleft = 0x3008;
+ t.anglebracketleftvertical = 0xfe3f;
+ t.anglebracketright = 0x3009;
+ t.anglebracketrightvertical = 0xfe40;
+ t.angleleft = 0x2329;
+ t.angleright = 0x232a;
+ t.angstrom = 0x212b;
+ t.anoteleia = 0x0387;
+ t.anudattadeva = 0x0952;
+ t.anusvarabengali = 0x0982;
+ t.anusvaradeva = 0x0902;
+ t.anusvaragujarati = 0x0a82;
+ t.aogonek = 0x0105;
+ t.apaatosquare = 0x3300;
+ t.aparen = 0x249c;
+ t.apostrophearmenian = 0x055a;
+ t.apostrophemod = 0x02bc;
+ t.apple = 0xf8ff;
+ t.approaches = 0x2250;
+ t.approxequal = 0x2248;
+ t.approxequalorimage = 0x2252;
+ t.approximatelyequal = 0x2245;
+ t.araeaekorean = 0x318e;
+ t.araeakorean = 0x318d;
+ t.arc = 0x2312;
+ t.arighthalfring = 0x1e9a;
+ t.aring = 0x00e5;
+ t.aringacute = 0x01fb;
+ t.aringbelow = 0x1e01;
+ t.arrowboth = 0x2194;
+ t.arrowdashdown = 0x21e3;
+ t.arrowdashleft = 0x21e0;
+ t.arrowdashright = 0x21e2;
+ t.arrowdashup = 0x21e1;
+ t.arrowdblboth = 0x21d4;
+ t.arrowdbldown = 0x21d3;
+ t.arrowdblleft = 0x21d0;
+ t.arrowdblright = 0x21d2;
+ t.arrowdblup = 0x21d1;
+ t.arrowdown = 0x2193;
+ t.arrowdownleft = 0x2199;
+ t.arrowdownright = 0x2198;
+ t.arrowdownwhite = 0x21e9;
+ t.arrowheaddownmod = 0x02c5;
+ t.arrowheadleftmod = 0x02c2;
+ t.arrowheadrightmod = 0x02c3;
+ t.arrowheadupmod = 0x02c4;
+ t.arrowhorizex = 0xf8e7;
+ t.arrowleft = 0x2190;
+ t.arrowleftdbl = 0x21d0;
+ t.arrowleftdblstroke = 0x21cd;
+ t.arrowleftoverright = 0x21c6;
+ t.arrowleftwhite = 0x21e6;
+ t.arrowright = 0x2192;
+ t.arrowrightdblstroke = 0x21cf;
+ t.arrowrightheavy = 0x279e;
+ t.arrowrightoverleft = 0x21c4;
+ t.arrowrightwhite = 0x21e8;
+ t.arrowtableft = 0x21e4;
+ t.arrowtabright = 0x21e5;
+ t.arrowup = 0x2191;
+ t.arrowupdn = 0x2195;
+ t.arrowupdnbse = 0x21a8;
+ t.arrowupdownbase = 0x21a8;
+ t.arrowupleft = 0x2196;
+ t.arrowupleftofdown = 0x21c5;
+ t.arrowupright = 0x2197;
+ t.arrowupwhite = 0x21e7;
+ t.arrowvertex = 0xf8e6;
+ t.asciicircum = 0x005e;
+ t.asciicircummonospace = 0xff3e;
+ t.asciitilde = 0x007e;
+ t.asciitildemonospace = 0xff5e;
+ t.ascript = 0x0251;
+ t.ascriptturned = 0x0252;
+ t.asmallhiragana = 0x3041;
+ t.asmallkatakana = 0x30a1;
+ t.asmallkatakanahalfwidth = 0xff67;
+ t.asterisk = 0x002a;
+ t.asteriskaltonearabic = 0x066d;
+ t.asteriskarabic = 0x066d;
+ t.asteriskmath = 0x2217;
+ t.asteriskmonospace = 0xff0a;
+ t.asterisksmall = 0xfe61;
+ t.asterism = 0x2042;
+ t.asuperior = 0xf6e9;
+ t.asymptoticallyequal = 0x2243;
+ t.at = 0x0040;
+ t.atilde = 0x00e3;
+ t.atmonospace = 0xff20;
+ t.atsmall = 0xfe6b;
+ t.aturned = 0x0250;
+ t.aubengali = 0x0994;
+ t.aubopomofo = 0x3120;
+ t.audeva = 0x0914;
+ t.augujarati = 0x0a94;
+ t.augurmukhi = 0x0a14;
+ t.aulengthmarkbengali = 0x09d7;
+ t.aumatragurmukhi = 0x0a4c;
+ t.auvowelsignbengali = 0x09cc;
+ t.auvowelsigndeva = 0x094c;
+ t.auvowelsigngujarati = 0x0acc;
+ t.avagrahadeva = 0x093d;
+ t.aybarmenian = 0x0561;
+ t.ayin = 0x05e2;
+ t.ayinaltonehebrew = 0xfb20;
+ t.ayinhebrew = 0x05e2;
+ t.b = 0x0062;
+ t.babengali = 0x09ac;
+ t.backslash = 0x005c;
+ t.backslashmonospace = 0xff3c;
+ t.badeva = 0x092c;
+ t.bagujarati = 0x0aac;
+ t.bagurmukhi = 0x0a2c;
+ t.bahiragana = 0x3070;
+ t.bahtthai = 0x0e3f;
+ t.bakatakana = 0x30d0;
+ t.bar = 0x007c;
+ t.barmonospace = 0xff5c;
+ t.bbopomofo = 0x3105;
+ t.bcircle = 0x24d1;
+ t.bdotaccent = 0x1e03;
+ t.bdotbelow = 0x1e05;
+ t.beamedsixteenthnotes = 0x266c;
+ t.because = 0x2235;
+ t.becyrillic = 0x0431;
+ t.beharabic = 0x0628;
+ t.behfinalarabic = 0xfe90;
+ t.behinitialarabic = 0xfe91;
+ t.behiragana = 0x3079;
+ t.behmedialarabic = 0xfe92;
+ t.behmeeminitialarabic = 0xfc9f;
+ t.behmeemisolatedarabic = 0xfc08;
+ t.behnoonfinalarabic = 0xfc6d;
+ t.bekatakana = 0x30d9;
+ t.benarmenian = 0x0562;
+ t.bet = 0x05d1;
+ t.beta = 0x03b2;
+ t.betasymbolgreek = 0x03d0;
+ t.betdagesh = 0xfb31;
+ t.betdageshhebrew = 0xfb31;
+ t.bethebrew = 0x05d1;
+ t.betrafehebrew = 0xfb4c;
+ t.bhabengali = 0x09ad;
+ t.bhadeva = 0x092d;
+ t.bhagujarati = 0x0aad;
+ t.bhagurmukhi = 0x0a2d;
+ t.bhook = 0x0253;
+ t.bihiragana = 0x3073;
+ t.bikatakana = 0x30d3;
+ t.bilabialclick = 0x0298;
+ t.bindigurmukhi = 0x0a02;
+ t.birusquare = 0x3331;
+ t.blackcircle = 0x25cf;
+ t.blackdiamond = 0x25c6;
+ t.blackdownpointingtriangle = 0x25bc;
+ t.blackleftpointingpointer = 0x25c4;
+ t.blackleftpointingtriangle = 0x25c0;
+ t.blacklenticularbracketleft = 0x3010;
+ t.blacklenticularbracketleftvertical = 0xfe3b;
+ t.blacklenticularbracketright = 0x3011;
+ t.blacklenticularbracketrightvertical = 0xfe3c;
+ t.blacklowerlefttriangle = 0x25e3;
+ t.blacklowerrighttriangle = 0x25e2;
+ t.blackrectangle = 0x25ac;
+ t.blackrightpointingpointer = 0x25ba;
+ t.blackrightpointingtriangle = 0x25b6;
+ t.blacksmallsquare = 0x25aa;
+ t.blacksmilingface = 0x263b;
+ t.blacksquare = 0x25a0;
+ t.blackstar = 0x2605;
+ t.blackupperlefttriangle = 0x25e4;
+ t.blackupperrighttriangle = 0x25e5;
+ t.blackuppointingsmalltriangle = 0x25b4;
+ t.blackuppointingtriangle = 0x25b2;
+ t.blank = 0x2423;
+ t.blinebelow = 0x1e07;
+ t.block = 0x2588;
+ t.bmonospace = 0xff42;
+ t.bobaimaithai = 0x0e1a;
+ t.bohiragana = 0x307c;
+ t.bokatakana = 0x30dc;
+ t.bparen = 0x249d;
+ t.bqsquare = 0x33c3;
+ t.braceex = 0xf8f4;
+ t.braceleft = 0x007b;
+ t.braceleftbt = 0xf8f3;
+ t.braceleftmid = 0xf8f2;
+ t.braceleftmonospace = 0xff5b;
+ t.braceleftsmall = 0xfe5b;
+ t.bracelefttp = 0xf8f1;
+ t.braceleftvertical = 0xfe37;
+ t.braceright = 0x007d;
+ t.bracerightbt = 0xf8fe;
+ t.bracerightmid = 0xf8fd;
+ t.bracerightmonospace = 0xff5d;
+ t.bracerightsmall = 0xfe5c;
+ t.bracerighttp = 0xf8fc;
+ t.bracerightvertical = 0xfe38;
+ t.bracketleft = 0x005b;
+ t.bracketleftbt = 0xf8f0;
+ t.bracketleftex = 0xf8ef;
+ t.bracketleftmonospace = 0xff3b;
+ t.bracketlefttp = 0xf8ee;
+ t.bracketright = 0x005d;
+ t.bracketrightbt = 0xf8fb;
+ t.bracketrightex = 0xf8fa;
+ t.bracketrightmonospace = 0xff3d;
+ t.bracketrighttp = 0xf8f9;
+ t.breve = 0x02d8;
+ t.brevebelowcmb = 0x032e;
+ t.brevecmb = 0x0306;
+ t.breveinvertedbelowcmb = 0x032f;
+ t.breveinvertedcmb = 0x0311;
+ t.breveinverteddoublecmb = 0x0361;
+ t.bridgebelowcmb = 0x032a;
+ t.bridgeinvertedbelowcmb = 0x033a;
+ t.brokenbar = 0x00a6;
+ t.bstroke = 0x0180;
+ t.bsuperior = 0xf6ea;
+ t.btopbar = 0x0183;
+ t.buhiragana = 0x3076;
+ t.bukatakana = 0x30d6;
+ t.bullet = 0x2022;
+ t.bulletinverse = 0x25d8;
+ t.bulletoperator = 0x2219;
+ t.bullseye = 0x25ce;
+ t.c = 0x0063;
+ t.caarmenian = 0x056e;
+ t.cabengali = 0x099a;
+ t.cacute = 0x0107;
+ t.cadeva = 0x091a;
+ t.cagujarati = 0x0a9a;
+ t.cagurmukhi = 0x0a1a;
+ t.calsquare = 0x3388;
+ t.candrabindubengali = 0x0981;
+ t.candrabinducmb = 0x0310;
+ t.candrabindudeva = 0x0901;
+ t.candrabindugujarati = 0x0a81;
+ t.capslock = 0x21ea;
+ t.careof = 0x2105;
+ t.caron = 0x02c7;
+ t.caronbelowcmb = 0x032c;
+ t.caroncmb = 0x030c;
+ t.carriagereturn = 0x21b5;
+ t.cbopomofo = 0x3118;
+ t.ccaron = 0x010d;
+ t.ccedilla = 0x00e7;
+ t.ccedillaacute = 0x1e09;
+ t.ccircle = 0x24d2;
+ t.ccircumflex = 0x0109;
+ t.ccurl = 0x0255;
+ t.cdot = 0x010b;
+ t.cdotaccent = 0x010b;
+ t.cdsquare = 0x33c5;
+ t.cedilla = 0x00b8;
+ t.cedillacmb = 0x0327;
+ t.cent = 0x00a2;
+ t.centigrade = 0x2103;
+ t.centinferior = 0xf6df;
+ t.centmonospace = 0xffe0;
+ t.centoldstyle = 0xf7a2;
+ t.centsuperior = 0xf6e0;
+ t.chaarmenian = 0x0579;
+ t.chabengali = 0x099b;
+ t.chadeva = 0x091b;
+ t.chagujarati = 0x0a9b;
+ t.chagurmukhi = 0x0a1b;
+ t.chbopomofo = 0x3114;
+ t.cheabkhasiancyrillic = 0x04bd;
+ t.checkmark = 0x2713;
+ t.checyrillic = 0x0447;
+ t.chedescenderabkhasiancyrillic = 0x04bf;
+ t.chedescendercyrillic = 0x04b7;
+ t.chedieresiscyrillic = 0x04f5;
+ t.cheharmenian = 0x0573;
+ t.chekhakassiancyrillic = 0x04cc;
+ t.cheverticalstrokecyrillic = 0x04b9;
+ t.chi = 0x03c7;
+ t.chieuchacirclekorean = 0x3277;
+ t.chieuchaparenkorean = 0x3217;
+ t.chieuchcirclekorean = 0x3269;
+ t.chieuchkorean = 0x314a;
+ t.chieuchparenkorean = 0x3209;
+ t.chochangthai = 0x0e0a;
+ t.chochanthai = 0x0e08;
+ t.chochingthai = 0x0e09;
+ t.chochoethai = 0x0e0c;
+ t.chook = 0x0188;
+ t.cieucacirclekorean = 0x3276;
+ t.cieucaparenkorean = 0x3216;
+ t.cieuccirclekorean = 0x3268;
+ t.cieuckorean = 0x3148;
+ t.cieucparenkorean = 0x3208;
+ t.cieucuparenkorean = 0x321c;
+ t.circle = 0x25cb;
+ t.circlecopyrt = 0x00a9;
+ t.circlemultiply = 0x2297;
+ t.circleot = 0x2299;
+ t.circleplus = 0x2295;
+ t.circlepostalmark = 0x3036;
+ t.circlewithlefthalfblack = 0x25d0;
+ t.circlewithrighthalfblack = 0x25d1;
+ t.circumflex = 0x02c6;
+ t.circumflexbelowcmb = 0x032d;
+ t.circumflexcmb = 0x0302;
+ t.clear = 0x2327;
+ t.clickalveolar = 0x01c2;
+ t.clickdental = 0x01c0;
+ t.clicklateral = 0x01c1;
+ t.clickretroflex = 0x01c3;
+ t.club = 0x2663;
+ t.clubsuitblack = 0x2663;
+ t.clubsuitwhite = 0x2667;
+ t.cmcubedsquare = 0x33a4;
+ t.cmonospace = 0xff43;
+ t.cmsquaredsquare = 0x33a0;
+ t.coarmenian = 0x0581;
+ t.colon = 0x003a;
+ t.colonmonetary = 0x20a1;
+ t.colonmonospace = 0xff1a;
+ t.colonsign = 0x20a1;
+ t.colonsmall = 0xfe55;
+ t.colontriangularhalfmod = 0x02d1;
+ t.colontriangularmod = 0x02d0;
+ t.comma = 0x002c;
+ t.commaabovecmb = 0x0313;
+ t.commaaboverightcmb = 0x0315;
+ t.commaaccent = 0xf6c3;
+ t.commaarabic = 0x060c;
+ t.commaarmenian = 0x055d;
+ t.commainferior = 0xf6e1;
+ t.commamonospace = 0xff0c;
+ t.commareversedabovecmb = 0x0314;
+ t.commareversedmod = 0x02bd;
+ t.commasmall = 0xfe50;
+ t.commasuperior = 0xf6e2;
+ t.commaturnedabovecmb = 0x0312;
+ t.commaturnedmod = 0x02bb;
+ t.compass = 0x263c;
+ t.congruent = 0x2245;
+ t.contourintegral = 0x222e;
+ t.control = 0x2303;
+ t.controlACK = 0x0006;
+ t.controlBEL = 0x0007;
+ t.controlBS = 0x0008;
+ t.controlCAN = 0x0018;
+ t.controlCR = 0x000d;
+ t.controlDC1 = 0x0011;
+ t.controlDC2 = 0x0012;
+ t.controlDC3 = 0x0013;
+ t.controlDC4 = 0x0014;
+ t.controlDEL = 0x007f;
+ t.controlDLE = 0x0010;
+ t.controlEM = 0x0019;
+ t.controlENQ = 0x0005;
+ t.controlEOT = 0x0004;
+ t.controlESC = 0x001b;
+ t.controlETB = 0x0017;
+ t.controlETX = 0x0003;
+ t.controlFF = 0x000c;
+ t.controlFS = 0x001c;
+ t.controlGS = 0x001d;
+ t.controlHT = 0x0009;
+ t.controlLF = 0x000a;
+ t.controlNAK = 0x0015;
+ t.controlNULL = 0x0000;
+ t.controlRS = 0x001e;
+ t.controlSI = 0x000f;
+ t.controlSO = 0x000e;
+ t.controlSOT = 0x0002;
+ t.controlSTX = 0x0001;
+ t.controlSUB = 0x001a;
+ t.controlSYN = 0x0016;
+ t.controlUS = 0x001f;
+ t.controlVT = 0x000b;
+ t.copyright = 0x00a9;
+ t.copyrightsans = 0xf8e9;
+ t.copyrightserif = 0xf6d9;
+ t.cornerbracketleft = 0x300c;
+ t.cornerbracketlefthalfwidth = 0xff62;
+ t.cornerbracketleftvertical = 0xfe41;
+ t.cornerbracketright = 0x300d;
+ t.cornerbracketrighthalfwidth = 0xff63;
+ t.cornerbracketrightvertical = 0xfe42;
+ t.corporationsquare = 0x337f;
+ t.cosquare = 0x33c7;
+ t.coverkgsquare = 0x33c6;
+ t.cparen = 0x249e;
+ t.cruzeiro = 0x20a2;
+ t.cstretched = 0x0297;
+ t.curlyand = 0x22cf;
+ t.curlyor = 0x22ce;
+ t.currency = 0x00a4;
+ t.cyrBreve = 0xf6d1;
+ t.cyrFlex = 0xf6d2;
+ t.cyrbreve = 0xf6d4;
+ t.cyrflex = 0xf6d5;
+ t.d = 0x0064;
+ t.daarmenian = 0x0564;
+ t.dabengali = 0x09a6;
+ t.dadarabic = 0x0636;
+ t.dadeva = 0x0926;
+ t.dadfinalarabic = 0xfebe;
+ t.dadinitialarabic = 0xfebf;
+ t.dadmedialarabic = 0xfec0;
+ t.dagesh = 0x05bc;
+ t.dageshhebrew = 0x05bc;
+ t.dagger = 0x2020;
+ t.daggerdbl = 0x2021;
+ t.dagujarati = 0x0aa6;
+ t.dagurmukhi = 0x0a26;
+ t.dahiragana = 0x3060;
+ t.dakatakana = 0x30c0;
+ t.dalarabic = 0x062f;
+ t.dalet = 0x05d3;
+ t.daletdagesh = 0xfb33;
+ t.daletdageshhebrew = 0xfb33;
+ t.dalethebrew = 0x05d3;
+ t.dalfinalarabic = 0xfeaa;
+ t.dammaarabic = 0x064f;
+ t.dammalowarabic = 0x064f;
+ t.dammatanaltonearabic = 0x064c;
+ t.dammatanarabic = 0x064c;
+ t.danda = 0x0964;
+ t.dargahebrew = 0x05a7;
+ t.dargalefthebrew = 0x05a7;
+ t.dasiapneumatacyrilliccmb = 0x0485;
+ t.dblGrave = 0xf6d3;
+ t.dblanglebracketleft = 0x300a;
+ t.dblanglebracketleftvertical = 0xfe3d;
+ t.dblanglebracketright = 0x300b;
+ t.dblanglebracketrightvertical = 0xfe3e;
+ t.dblarchinvertedbelowcmb = 0x032b;
+ t.dblarrowleft = 0x21d4;
+ t.dblarrowright = 0x21d2;
+ t.dbldanda = 0x0965;
+ t.dblgrave = 0xf6d6;
+ t.dblgravecmb = 0x030f;
+ t.dblintegral = 0x222c;
+ t.dbllowline = 0x2017;
+ t.dbllowlinecmb = 0x0333;
+ t.dbloverlinecmb = 0x033f;
+ t.dblprimemod = 0x02ba;
+ t.dblverticalbar = 0x2016;
+ t.dblverticallineabovecmb = 0x030e;
+ t.dbopomofo = 0x3109;
+ t.dbsquare = 0x33c8;
+ t.dcaron = 0x010f;
+ t.dcedilla = 0x1e11;
+ t.dcircle = 0x24d3;
+ t.dcircumflexbelow = 0x1e13;
+ t.dcroat = 0x0111;
+ t.ddabengali = 0x09a1;
+ t.ddadeva = 0x0921;
+ t.ddagujarati = 0x0aa1;
+ t.ddagurmukhi = 0x0a21;
+ t.ddalarabic = 0x0688;
+ t.ddalfinalarabic = 0xfb89;
+ t.dddhadeva = 0x095c;
+ t.ddhabengali = 0x09a2;
+ t.ddhadeva = 0x0922;
+ t.ddhagujarati = 0x0aa2;
+ t.ddhagurmukhi = 0x0a22;
+ t.ddotaccent = 0x1e0b;
+ t.ddotbelow = 0x1e0d;
+ t.decimalseparatorarabic = 0x066b;
+ t.decimalseparatorpersian = 0x066b;
+ t.decyrillic = 0x0434;
+ t.degree = 0x00b0;
+ t.dehihebrew = 0x05ad;
+ t.dehiragana = 0x3067;
+ t.deicoptic = 0x03ef;
+ t.dekatakana = 0x30c7;
+ t.deleteleft = 0x232b;
+ t.deleteright = 0x2326;
+ t.delta = 0x03b4;
+ t.deltaturned = 0x018d;
+ t.denominatorminusonenumeratorbengali = 0x09f8;
+ t.dezh = 0x02a4;
+ t.dhabengali = 0x09a7;
+ t.dhadeva = 0x0927;
+ t.dhagujarati = 0x0aa7;
+ t.dhagurmukhi = 0x0a27;
+ t.dhook = 0x0257;
+ t.dialytikatonos = 0x0385;
+ t.dialytikatonoscmb = 0x0344;
+ t.diamond = 0x2666;
+ t.diamondsuitwhite = 0x2662;
+ t.dieresis = 0x00a8;
+ t.dieresisacute = 0xf6d7;
+ t.dieresisbelowcmb = 0x0324;
+ t.dieresiscmb = 0x0308;
+ t.dieresisgrave = 0xf6d8;
+ t.dieresistonos = 0x0385;
+ t.dihiragana = 0x3062;
+ t.dikatakana = 0x30c2;
+ t.dittomark = 0x3003;
+ t.divide = 0x00f7;
+ t.divides = 0x2223;
+ t.divisionslash = 0x2215;
+ t.djecyrillic = 0x0452;
+ t.dkshade = 0x2593;
+ t.dlinebelow = 0x1e0f;
+ t.dlsquare = 0x3397;
+ t.dmacron = 0x0111;
+ t.dmonospace = 0xff44;
+ t.dnblock = 0x2584;
+ t.dochadathai = 0x0e0e;
+ t.dodekthai = 0x0e14;
+ t.dohiragana = 0x3069;
+ t.dokatakana = 0x30c9;
+ t.dollar = 0x0024;
+ t.dollarinferior = 0xf6e3;
+ t.dollarmonospace = 0xff04;
+ t.dollaroldstyle = 0xf724;
+ t.dollarsmall = 0xfe69;
+ t.dollarsuperior = 0xf6e4;
+ t.dong = 0x20ab;
+ t.dorusquare = 0x3326;
+ t.dotaccent = 0x02d9;
+ t.dotaccentcmb = 0x0307;
+ t.dotbelowcmb = 0x0323;
+ t.dotbelowcomb = 0x0323;
+ t.dotkatakana = 0x30fb;
+ t.dotlessi = 0x0131;
+ t.dotlessj = 0xf6be;
+ t.dotlessjstrokehook = 0x0284;
+ t.dotmath = 0x22c5;
+ t.dottedcircle = 0x25cc;
+ t.doubleyodpatah = 0xfb1f;
+ t.doubleyodpatahhebrew = 0xfb1f;
+ t.downtackbelowcmb = 0x031e;
+ t.downtackmod = 0x02d5;
+ t.dparen = 0x249f;
+ t.dsuperior = 0xf6eb;
+ t.dtail = 0x0256;
+ t.dtopbar = 0x018c;
+ t.duhiragana = 0x3065;
+ t.dukatakana = 0x30c5;
+ t.dz = 0x01f3;
+ t.dzaltone = 0x02a3;
+ t.dzcaron = 0x01c6;
+ t.dzcurl = 0x02a5;
+ t.dzeabkhasiancyrillic = 0x04e1;
+ t.dzecyrillic = 0x0455;
+ t.dzhecyrillic = 0x045f;
+ t.e = 0x0065;
+ t.eacute = 0x00e9;
+ t.earth = 0x2641;
+ t.ebengali = 0x098f;
+ t.ebopomofo = 0x311c;
+ t.ebreve = 0x0115;
+ t.ecandradeva = 0x090d;
+ t.ecandragujarati = 0x0a8d;
+ t.ecandravowelsigndeva = 0x0945;
+ t.ecandravowelsigngujarati = 0x0ac5;
+ t.ecaron = 0x011b;
+ t.ecedillabreve = 0x1e1d;
+ t.echarmenian = 0x0565;
+ t.echyiwnarmenian = 0x0587;
+ t.ecircle = 0x24d4;
+ t.ecircumflex = 0x00ea;
+ t.ecircumflexacute = 0x1ebf;
+ t.ecircumflexbelow = 0x1e19;
+ t.ecircumflexdotbelow = 0x1ec7;
+ t.ecircumflexgrave = 0x1ec1;
+ t.ecircumflexhookabove = 0x1ec3;
+ t.ecircumflextilde = 0x1ec5;
+ t.ecyrillic = 0x0454;
+ t.edblgrave = 0x0205;
+ t.edeva = 0x090f;
+ t.edieresis = 0x00eb;
+ t.edot = 0x0117;
+ t.edotaccent = 0x0117;
+ t.edotbelow = 0x1eb9;
+ t.eegurmukhi = 0x0a0f;
+ t.eematragurmukhi = 0x0a47;
+ t.efcyrillic = 0x0444;
+ t.egrave = 0x00e8;
+ t.egujarati = 0x0a8f;
+ t.eharmenian = 0x0567;
+ t.ehbopomofo = 0x311d;
+ t.ehiragana = 0x3048;
+ t.ehookabove = 0x1ebb;
+ t.eibopomofo = 0x311f;
+ t.eight = 0x0038;
+ t.eightarabic = 0x0668;
+ t.eightbengali = 0x09ee;
+ t.eightcircle = 0x2467;
+ t.eightcircleinversesansserif = 0x2791;
+ t.eightdeva = 0x096e;
+ t.eighteencircle = 0x2471;
+ t.eighteenparen = 0x2485;
+ t.eighteenperiod = 0x2499;
+ t.eightgujarati = 0x0aee;
+ t.eightgurmukhi = 0x0a6e;
+ t.eighthackarabic = 0x0668;
+ t.eighthangzhou = 0x3028;
+ t.eighthnotebeamed = 0x266b;
+ t.eightideographicparen = 0x3227;
+ t.eightinferior = 0x2088;
+ t.eightmonospace = 0xff18;
+ t.eightoldstyle = 0xf738;
+ t.eightparen = 0x247b;
+ t.eightperiod = 0x248f;
+ t.eightpersian = 0x06f8;
+ t.eightroman = 0x2177;
+ t.eightsuperior = 0x2078;
+ t.eightthai = 0x0e58;
+ t.einvertedbreve = 0x0207;
+ t.eiotifiedcyrillic = 0x0465;
+ t.ekatakana = 0x30a8;
+ t.ekatakanahalfwidth = 0xff74;
+ t.ekonkargurmukhi = 0x0a74;
+ t.ekorean = 0x3154;
+ t.elcyrillic = 0x043b;
+ t.element = 0x2208;
+ t.elevencircle = 0x246a;
+ t.elevenparen = 0x247e;
+ t.elevenperiod = 0x2492;
+ t.elevenroman = 0x217a;
+ t.ellipsis = 0x2026;
+ t.ellipsisvertical = 0x22ee;
+ t.emacron = 0x0113;
+ t.emacronacute = 0x1e17;
+ t.emacrongrave = 0x1e15;
+ t.emcyrillic = 0x043c;
+ t.emdash = 0x2014;
+ t.emdashvertical = 0xfe31;
+ t.emonospace = 0xff45;
+ t.emphasismarkarmenian = 0x055b;
+ t.emptyset = 0x2205;
+ t.enbopomofo = 0x3123;
+ t.encyrillic = 0x043d;
+ t.endash = 0x2013;
+ t.endashvertical = 0xfe32;
+ t.endescendercyrillic = 0x04a3;
+ t.eng = 0x014b;
+ t.engbopomofo = 0x3125;
+ t.enghecyrillic = 0x04a5;
+ t.enhookcyrillic = 0x04c8;
+ t.enspace = 0x2002;
+ t.eogonek = 0x0119;
+ t.eokorean = 0x3153;
+ t.eopen = 0x025b;
+ t.eopenclosed = 0x029a;
+ t.eopenreversed = 0x025c;
+ t.eopenreversedclosed = 0x025e;
+ t.eopenreversedhook = 0x025d;
+ t.eparen = 0x24a0;
+ t.epsilon = 0x03b5;
+ t.epsilontonos = 0x03ad;
+ t.equal = 0x003d;
+ t.equalmonospace = 0xff1d;
+ t.equalsmall = 0xfe66;
+ t.equalsuperior = 0x207c;
+ t.equivalence = 0x2261;
+ t.erbopomofo = 0x3126;
+ t.ercyrillic = 0x0440;
+ t.ereversed = 0x0258;
+ t.ereversedcyrillic = 0x044d;
+ t.escyrillic = 0x0441;
+ t.esdescendercyrillic = 0x04ab;
+ t.esh = 0x0283;
+ t.eshcurl = 0x0286;
+ t.eshortdeva = 0x090e;
+ t.eshortvowelsigndeva = 0x0946;
+ t.eshreversedloop = 0x01aa;
+ t.eshsquatreversed = 0x0285;
+ t.esmallhiragana = 0x3047;
+ t.esmallkatakana = 0x30a7;
+ t.esmallkatakanahalfwidth = 0xff6a;
+ t.estimated = 0x212e;
+ t.esuperior = 0xf6ec;
+ t.eta = 0x03b7;
+ t.etarmenian = 0x0568;
+ t.etatonos = 0x03ae;
+ t.eth = 0x00f0;
+ t.etilde = 0x1ebd;
+ t.etildebelow = 0x1e1b;
+ t.etnahtafoukhhebrew = 0x0591;
+ t.etnahtafoukhlefthebrew = 0x0591;
+ t.etnahtahebrew = 0x0591;
+ t.etnahtalefthebrew = 0x0591;
+ t.eturned = 0x01dd;
+ t.eukorean = 0x3161;
+ t.euro = 0x20ac;
+ t.evowelsignbengali = 0x09c7;
+ t.evowelsigndeva = 0x0947;
+ t.evowelsigngujarati = 0x0ac7;
+ t.exclam = 0x0021;
+ t.exclamarmenian = 0x055c;
+ t.exclamdbl = 0x203c;
+ t.exclamdown = 0x00a1;
+ t.exclamdownsmall = 0xf7a1;
+ t.exclammonospace = 0xff01;
+ t.exclamsmall = 0xf721;
+ t.existential = 0x2203;
+ t.ezh = 0x0292;
+ t.ezhcaron = 0x01ef;
+ t.ezhcurl = 0x0293;
+ t.ezhreversed = 0x01b9;
+ t.ezhtail = 0x01ba;
+ t.f = 0x0066;
+ t.fadeva = 0x095e;
+ t.fagurmukhi = 0x0a5e;
+ t.fahrenheit = 0x2109;
+ t.fathaarabic = 0x064e;
+ t.fathalowarabic = 0x064e;
+ t.fathatanarabic = 0x064b;
+ t.fbopomofo = 0x3108;
+ t.fcircle = 0x24d5;
+ t.fdotaccent = 0x1e1f;
+ t.feharabic = 0x0641;
+ t.feharmenian = 0x0586;
+ t.fehfinalarabic = 0xfed2;
+ t.fehinitialarabic = 0xfed3;
+ t.fehmedialarabic = 0xfed4;
+ t.feicoptic = 0x03e5;
+ t.female = 0x2640;
+ t.ff = 0xfb00;
+ t.f_f = 0xfb00;
+ t.ffi = 0xfb03;
+ t.f_f_i = 0xfb03;
+ t.ffl = 0xfb04;
+ t.f_f_l = 0xfb04;
+ t.fi = 0xfb01;
+ t.f_i = 0xfb01;
+ t.fifteencircle = 0x246e;
+ t.fifteenparen = 0x2482;
+ t.fifteenperiod = 0x2496;
+ t.figuredash = 0x2012;
+ t.filledbox = 0x25a0;
+ t.filledrect = 0x25ac;
+ t.finalkaf = 0x05da;
+ t.finalkafdagesh = 0xfb3a;
+ t.finalkafdageshhebrew = 0xfb3a;
+ t.finalkafhebrew = 0x05da;
+ t.finalmem = 0x05dd;
+ t.finalmemhebrew = 0x05dd;
+ t.finalnun = 0x05df;
+ t.finalnunhebrew = 0x05df;
+ t.finalpe = 0x05e3;
+ t.finalpehebrew = 0x05e3;
+ t.finaltsadi = 0x05e5;
+ t.finaltsadihebrew = 0x05e5;
+ t.firsttonechinese = 0x02c9;
+ t.fisheye = 0x25c9;
+ t.fitacyrillic = 0x0473;
+ t.five = 0x0035;
+ t.fivearabic = 0x0665;
+ t.fivebengali = 0x09eb;
+ t.fivecircle = 0x2464;
+ t.fivecircleinversesansserif = 0x278e;
+ t.fivedeva = 0x096b;
+ t.fiveeighths = 0x215d;
+ t.fivegujarati = 0x0aeb;
+ t.fivegurmukhi = 0x0a6b;
+ t.fivehackarabic = 0x0665;
+ t.fivehangzhou = 0x3025;
+ t.fiveideographicparen = 0x3224;
+ t.fiveinferior = 0x2085;
+ t.fivemonospace = 0xff15;
+ t.fiveoldstyle = 0xf735;
+ t.fiveparen = 0x2478;
+ t.fiveperiod = 0x248c;
+ t.fivepersian = 0x06f5;
+ t.fiveroman = 0x2174;
+ t.fivesuperior = 0x2075;
+ t.fivethai = 0x0e55;
+ t.fl = 0xfb02;
+ t.f_l = 0xfb02;
+ t.florin = 0x0192;
+ t.fmonospace = 0xff46;
+ t.fmsquare = 0x3399;
+ t.fofanthai = 0x0e1f;
+ t.fofathai = 0x0e1d;
+ t.fongmanthai = 0x0e4f;
+ t.forall = 0x2200;
+ t.four = 0x0034;
+ t.fourarabic = 0x0664;
+ t.fourbengali = 0x09ea;
+ t.fourcircle = 0x2463;
+ t.fourcircleinversesansserif = 0x278d;
+ t.fourdeva = 0x096a;
+ t.fourgujarati = 0x0aea;
+ t.fourgurmukhi = 0x0a6a;
+ t.fourhackarabic = 0x0664;
+ t.fourhangzhou = 0x3024;
+ t.fourideographicparen = 0x3223;
+ t.fourinferior = 0x2084;
+ t.fourmonospace = 0xff14;
+ t.fournumeratorbengali = 0x09f7;
+ t.fouroldstyle = 0xf734;
+ t.fourparen = 0x2477;
+ t.fourperiod = 0x248b;
+ t.fourpersian = 0x06f4;
+ t.fourroman = 0x2173;
+ t.foursuperior = 0x2074;
+ t.fourteencircle = 0x246d;
+ t.fourteenparen = 0x2481;
+ t.fourteenperiod = 0x2495;
+ t.fourthai = 0x0e54;
+ t.fourthtonechinese = 0x02cb;
+ t.fparen = 0x24a1;
+ t.fraction = 0x2044;
+ t.franc = 0x20a3;
+ t.g = 0x0067;
+ t.gabengali = 0x0997;
+ t.gacute = 0x01f5;
+ t.gadeva = 0x0917;
+ t.gafarabic = 0x06af;
+ t.gaffinalarabic = 0xfb93;
+ t.gafinitialarabic = 0xfb94;
+ t.gafmedialarabic = 0xfb95;
+ t.gagujarati = 0x0a97;
+ t.gagurmukhi = 0x0a17;
+ t.gahiragana = 0x304c;
+ t.gakatakana = 0x30ac;
+ t.gamma = 0x03b3;
+ t.gammalatinsmall = 0x0263;
+ t.gammasuperior = 0x02e0;
+ t.gangiacoptic = 0x03eb;
+ t.gbopomofo = 0x310d;
+ t.gbreve = 0x011f;
+ t.gcaron = 0x01e7;
+ t.gcedilla = 0x0123;
+ t.gcircle = 0x24d6;
+ t.gcircumflex = 0x011d;
+ t.gcommaaccent = 0x0123;
+ t.gdot = 0x0121;
+ t.gdotaccent = 0x0121;
+ t.gecyrillic = 0x0433;
+ t.gehiragana = 0x3052;
+ t.gekatakana = 0x30b2;
+ t.geometricallyequal = 0x2251;
+ t.gereshaccenthebrew = 0x059c;
+ t.gereshhebrew = 0x05f3;
+ t.gereshmuqdamhebrew = 0x059d;
+ t.germandbls = 0x00df;
+ t.gershayimaccenthebrew = 0x059e;
+ t.gershayimhebrew = 0x05f4;
+ t.getamark = 0x3013;
+ t.ghabengali = 0x0998;
+ t.ghadarmenian = 0x0572;
+ t.ghadeva = 0x0918;
+ t.ghagujarati = 0x0a98;
+ t.ghagurmukhi = 0x0a18;
+ t.ghainarabic = 0x063a;
+ t.ghainfinalarabic = 0xfece;
+ t.ghaininitialarabic = 0xfecf;
+ t.ghainmedialarabic = 0xfed0;
+ t.ghemiddlehookcyrillic = 0x0495;
+ t.ghestrokecyrillic = 0x0493;
+ t.gheupturncyrillic = 0x0491;
+ t.ghhadeva = 0x095a;
+ t.ghhagurmukhi = 0x0a5a;
+ t.ghook = 0x0260;
+ t.ghzsquare = 0x3393;
+ t.gihiragana = 0x304e;
+ t.gikatakana = 0x30ae;
+ t.gimarmenian = 0x0563;
+ t.gimel = 0x05d2;
+ t.gimeldagesh = 0xfb32;
+ t.gimeldageshhebrew = 0xfb32;
+ t.gimelhebrew = 0x05d2;
+ t.gjecyrillic = 0x0453;
+ t.glottalinvertedstroke = 0x01be;
+ t.glottalstop = 0x0294;
+ t.glottalstopinverted = 0x0296;
+ t.glottalstopmod = 0x02c0;
+ t.glottalstopreversed = 0x0295;
+ t.glottalstopreversedmod = 0x02c1;
+ t.glottalstopreversedsuperior = 0x02e4;
+ t.glottalstopstroke = 0x02a1;
+ t.glottalstopstrokereversed = 0x02a2;
+ t.gmacron = 0x1e21;
+ t.gmonospace = 0xff47;
+ t.gohiragana = 0x3054;
+ t.gokatakana = 0x30b4;
+ t.gparen = 0x24a2;
+ t.gpasquare = 0x33ac;
+ t.gradient = 0x2207;
+ t.grave = 0x0060;
+ t.gravebelowcmb = 0x0316;
+ t.gravecmb = 0x0300;
+ t.gravecomb = 0x0300;
+ t.gravedeva = 0x0953;
+ t.gravelowmod = 0x02ce;
+ t.gravemonospace = 0xff40;
+ t.gravetonecmb = 0x0340;
+ t.greater = 0x003e;
+ t.greaterequal = 0x2265;
+ t.greaterequalorless = 0x22db;
+ t.greatermonospace = 0xff1e;
+ t.greaterorequivalent = 0x2273;
+ t.greaterorless = 0x2277;
+ t.greateroverequal = 0x2267;
+ t.greatersmall = 0xfe65;
+ t.gscript = 0x0261;
+ t.gstroke = 0x01e5;
+ t.guhiragana = 0x3050;
+ t.guillemotleft = 0x00ab;
+ t.guillemotright = 0x00bb;
+ t.guilsinglleft = 0x2039;
+ t.guilsinglright = 0x203a;
+ t.gukatakana = 0x30b0;
+ t.guramusquare = 0x3318;
+ t.gysquare = 0x33c9;
+ t.h = 0x0068;
+ t.haabkhasiancyrillic = 0x04a9;
+ t.haaltonearabic = 0x06c1;
+ t.habengali = 0x09b9;
+ t.hadescendercyrillic = 0x04b3;
+ t.hadeva = 0x0939;
+ t.hagujarati = 0x0ab9;
+ t.hagurmukhi = 0x0a39;
+ t.haharabic = 0x062d;
+ t.hahfinalarabic = 0xfea2;
+ t.hahinitialarabic = 0xfea3;
+ t.hahiragana = 0x306f;
+ t.hahmedialarabic = 0xfea4;
+ t.haitusquare = 0x332a;
+ t.hakatakana = 0x30cf;
+ t.hakatakanahalfwidth = 0xff8a;
+ t.halantgurmukhi = 0x0a4d;
+ t.hamzaarabic = 0x0621;
+ t.hamzalowarabic = 0x0621;
+ t.hangulfiller = 0x3164;
+ t.hardsigncyrillic = 0x044a;
+ t.harpoonleftbarbup = 0x21bc;
+ t.harpoonrightbarbup = 0x21c0;
+ t.hasquare = 0x33ca;
+ t.hatafpatah = 0x05b2;
+ t.hatafpatah16 = 0x05b2;
+ t.hatafpatah23 = 0x05b2;
+ t.hatafpatah2f = 0x05b2;
+ t.hatafpatahhebrew = 0x05b2;
+ t.hatafpatahnarrowhebrew = 0x05b2;
+ t.hatafpatahquarterhebrew = 0x05b2;
+ t.hatafpatahwidehebrew = 0x05b2;
+ t.hatafqamats = 0x05b3;
+ t.hatafqamats1b = 0x05b3;
+ t.hatafqamats28 = 0x05b3;
+ t.hatafqamats34 = 0x05b3;
+ t.hatafqamatshebrew = 0x05b3;
+ t.hatafqamatsnarrowhebrew = 0x05b3;
+ t.hatafqamatsquarterhebrew = 0x05b3;
+ t.hatafqamatswidehebrew = 0x05b3;
+ t.hatafsegol = 0x05b1;
+ t.hatafsegol17 = 0x05b1;
+ t.hatafsegol24 = 0x05b1;
+ t.hatafsegol30 = 0x05b1;
+ t.hatafsegolhebrew = 0x05b1;
+ t.hatafsegolnarrowhebrew = 0x05b1;
+ t.hatafsegolquarterhebrew = 0x05b1;
+ t.hatafsegolwidehebrew = 0x05b1;
+ t.hbar = 0x0127;
+ t.hbopomofo = 0x310f;
+ t.hbrevebelow = 0x1e2b;
+ t.hcedilla = 0x1e29;
+ t.hcircle = 0x24d7;
+ t.hcircumflex = 0x0125;
+ t.hdieresis = 0x1e27;
+ t.hdotaccent = 0x1e23;
+ t.hdotbelow = 0x1e25;
+ t.he = 0x05d4;
+ t.heart = 0x2665;
+ t.heartsuitblack = 0x2665;
+ t.heartsuitwhite = 0x2661;
+ t.hedagesh = 0xfb34;
+ t.hedageshhebrew = 0xfb34;
+ t.hehaltonearabic = 0x06c1;
+ t.heharabic = 0x0647;
+ t.hehebrew = 0x05d4;
+ t.hehfinalaltonearabic = 0xfba7;
+ t.hehfinalalttwoarabic = 0xfeea;
+ t.hehfinalarabic = 0xfeea;
+ t.hehhamzaabovefinalarabic = 0xfba5;
+ t.hehhamzaaboveisolatedarabic = 0xfba4;
+ t.hehinitialaltonearabic = 0xfba8;
+ t.hehinitialarabic = 0xfeeb;
+ t.hehiragana = 0x3078;
+ t.hehmedialaltonearabic = 0xfba9;
+ t.hehmedialarabic = 0xfeec;
+ t.heiseierasquare = 0x337b;
+ t.hekatakana = 0x30d8;
+ t.hekatakanahalfwidth = 0xff8d;
+ t.hekutaarusquare = 0x3336;
+ t.henghook = 0x0267;
+ t.herutusquare = 0x3339;
+ t.het = 0x05d7;
+ t.hethebrew = 0x05d7;
+ t.hhook = 0x0266;
+ t.hhooksuperior = 0x02b1;
+ t.hieuhacirclekorean = 0x327b;
+ t.hieuhaparenkorean = 0x321b;
+ t.hieuhcirclekorean = 0x326d;
+ t.hieuhkorean = 0x314e;
+ t.hieuhparenkorean = 0x320d;
+ t.hihiragana = 0x3072;
+ t.hikatakana = 0x30d2;
+ t.hikatakanahalfwidth = 0xff8b;
+ t.hiriq = 0x05b4;
+ t.hiriq14 = 0x05b4;
+ t.hiriq21 = 0x05b4;
+ t.hiriq2d = 0x05b4;
+ t.hiriqhebrew = 0x05b4;
+ t.hiriqnarrowhebrew = 0x05b4;
+ t.hiriqquarterhebrew = 0x05b4;
+ t.hiriqwidehebrew = 0x05b4;
+ t.hlinebelow = 0x1e96;
+ t.hmonospace = 0xff48;
+ t.hoarmenian = 0x0570;
+ t.hohipthai = 0x0e2b;
+ t.hohiragana = 0x307b;
+ t.hokatakana = 0x30db;
+ t.hokatakanahalfwidth = 0xff8e;
+ t.holam = 0x05b9;
+ t.holam19 = 0x05b9;
+ t.holam26 = 0x05b9;
+ t.holam32 = 0x05b9;
+ t.holamhebrew = 0x05b9;
+ t.holamnarrowhebrew = 0x05b9;
+ t.holamquarterhebrew = 0x05b9;
+ t.holamwidehebrew = 0x05b9;
+ t.honokhukthai = 0x0e2e;
+ t.hookabovecomb = 0x0309;
+ t.hookcmb = 0x0309;
+ t.hookpalatalizedbelowcmb = 0x0321;
+ t.hookretroflexbelowcmb = 0x0322;
+ t.hoonsquare = 0x3342;
+ t.horicoptic = 0x03e9;
+ t.horizontalbar = 0x2015;
+ t.horncmb = 0x031b;
+ t.hotsprings = 0x2668;
+ t.house = 0x2302;
+ t.hparen = 0x24a3;
+ t.hsuperior = 0x02b0;
+ t.hturned = 0x0265;
+ t.huhiragana = 0x3075;
+ t.huiitosquare = 0x3333;
+ t.hukatakana = 0x30d5;
+ t.hukatakanahalfwidth = 0xff8c;
+ t.hungarumlaut = 0x02dd;
+ t.hungarumlautcmb = 0x030b;
+ t.hv = 0x0195;
+ t.hyphen = 0x002d;
+ t.hypheninferior = 0xf6e5;
+ t.hyphenmonospace = 0xff0d;
+ t.hyphensmall = 0xfe63;
+ t.hyphensuperior = 0xf6e6;
+ t.hyphentwo = 0x2010;
+ t.i = 0x0069;
+ t.iacute = 0x00ed;
+ t.iacyrillic = 0x044f;
+ t.ibengali = 0x0987;
+ t.ibopomofo = 0x3127;
+ t.ibreve = 0x012d;
+ t.icaron = 0x01d0;
+ t.icircle = 0x24d8;
+ t.icircumflex = 0x00ee;
+ t.icyrillic = 0x0456;
+ t.idblgrave = 0x0209;
+ t.ideographearthcircle = 0x328f;
+ t.ideographfirecircle = 0x328b;
+ t.ideographicallianceparen = 0x323f;
+ t.ideographiccallparen = 0x323a;
+ t.ideographiccentrecircle = 0x32a5;
+ t.ideographicclose = 0x3006;
+ t.ideographiccomma = 0x3001;
+ t.ideographiccommaleft = 0xff64;
+ t.ideographiccongratulationparen = 0x3237;
+ t.ideographiccorrectcircle = 0x32a3;
+ t.ideographicearthparen = 0x322f;
+ t.ideographicenterpriseparen = 0x323d;
+ t.ideographicexcellentcircle = 0x329d;
+ t.ideographicfestivalparen = 0x3240;
+ t.ideographicfinancialcircle = 0x3296;
+ t.ideographicfinancialparen = 0x3236;
+ t.ideographicfireparen = 0x322b;
+ t.ideographichaveparen = 0x3232;
+ t.ideographichighcircle = 0x32a4;
+ t.ideographiciterationmark = 0x3005;
+ t.ideographiclaborcircle = 0x3298;
+ t.ideographiclaborparen = 0x3238;
+ t.ideographicleftcircle = 0x32a7;
+ t.ideographiclowcircle = 0x32a6;
+ t.ideographicmedicinecircle = 0x32a9;
+ t.ideographicmetalparen = 0x322e;
+ t.ideographicmoonparen = 0x322a;
+ t.ideographicnameparen = 0x3234;
+ t.ideographicperiod = 0x3002;
+ t.ideographicprintcircle = 0x329e;
+ t.ideographicreachparen = 0x3243;
+ t.ideographicrepresentparen = 0x3239;
+ t.ideographicresourceparen = 0x323e;
+ t.ideographicrightcircle = 0x32a8;
+ t.ideographicsecretcircle = 0x3299;
+ t.ideographicselfparen = 0x3242;
+ t.ideographicsocietyparen = 0x3233;
+ t.ideographicspace = 0x3000;
+ t.ideographicspecialparen = 0x3235;
+ t.ideographicstockparen = 0x3231;
+ t.ideographicstudyparen = 0x323b;
+ t.ideographicsunparen = 0x3230;
+ t.ideographicsuperviseparen = 0x323c;
+ t.ideographicwaterparen = 0x322c;
+ t.ideographicwoodparen = 0x322d;
+ t.ideographiczero = 0x3007;
+ t.ideographmetalcircle = 0x328e;
+ t.ideographmooncircle = 0x328a;
+ t.ideographnamecircle = 0x3294;
+ t.ideographsuncircle = 0x3290;
+ t.ideographwatercircle = 0x328c;
+ t.ideographwoodcircle = 0x328d;
+ t.ideva = 0x0907;
+ t.idieresis = 0x00ef;
+ t.idieresisacute = 0x1e2f;
+ t.idieresiscyrillic = 0x04e5;
+ t.idotbelow = 0x1ecb;
+ t.iebrevecyrillic = 0x04d7;
+ t.iecyrillic = 0x0435;
+ t.ieungacirclekorean = 0x3275;
+ t.ieungaparenkorean = 0x3215;
+ t.ieungcirclekorean = 0x3267;
+ t.ieungkorean = 0x3147;
+ t.ieungparenkorean = 0x3207;
+ t.igrave = 0x00ec;
+ t.igujarati = 0x0a87;
+ t.igurmukhi = 0x0a07;
+ t.ihiragana = 0x3044;
+ t.ihookabove = 0x1ec9;
+ t.iibengali = 0x0988;
+ t.iicyrillic = 0x0438;
+ t.iideva = 0x0908;
+ t.iigujarati = 0x0a88;
+ t.iigurmukhi = 0x0a08;
+ t.iimatragurmukhi = 0x0a40;
+ t.iinvertedbreve = 0x020b;
+ t.iishortcyrillic = 0x0439;
+ t.iivowelsignbengali = 0x09c0;
+ t.iivowelsigndeva = 0x0940;
+ t.iivowelsigngujarati = 0x0ac0;
+ t.ij = 0x0133;
+ t.ikatakana = 0x30a4;
+ t.ikatakanahalfwidth = 0xff72;
+ t.ikorean = 0x3163;
+ t.ilde = 0x02dc;
+ t.iluyhebrew = 0x05ac;
+ t.imacron = 0x012b;
+ t.imacroncyrillic = 0x04e3;
+ t.imageorapproximatelyequal = 0x2253;
+ t.imatragurmukhi = 0x0a3f;
+ t.imonospace = 0xff49;
+ t.increment = 0x2206;
+ t.infinity = 0x221e;
+ t.iniarmenian = 0x056b;
+ t.integral = 0x222b;
+ t.integralbottom = 0x2321;
+ t.integralbt = 0x2321;
+ t.integralex = 0xf8f5;
+ t.integraltop = 0x2320;
+ t.integraltp = 0x2320;
+ t.intersection = 0x2229;
+ t.intisquare = 0x3305;
+ t.invbullet = 0x25d8;
+ t.invcircle = 0x25d9;
+ t.invsmileface = 0x263b;
+ t.iocyrillic = 0x0451;
+ t.iogonek = 0x012f;
+ t.iota = 0x03b9;
+ t.iotadieresis = 0x03ca;
+ t.iotadieresistonos = 0x0390;
+ t.iotalatin = 0x0269;
+ t.iotatonos = 0x03af;
+ t.iparen = 0x24a4;
+ t.irigurmukhi = 0x0a72;
+ t.ismallhiragana = 0x3043;
+ t.ismallkatakana = 0x30a3;
+ t.ismallkatakanahalfwidth = 0xff68;
+ t.issharbengali = 0x09fa;
+ t.istroke = 0x0268;
+ t.isuperior = 0xf6ed;
+ t.iterationhiragana = 0x309d;
+ t.iterationkatakana = 0x30fd;
+ t.itilde = 0x0129;
+ t.itildebelow = 0x1e2d;
+ t.iubopomofo = 0x3129;
+ t.iucyrillic = 0x044e;
+ t.ivowelsignbengali = 0x09bf;
+ t.ivowelsigndeva = 0x093f;
+ t.ivowelsigngujarati = 0x0abf;
+ t.izhitsacyrillic = 0x0475;
+ t.izhitsadblgravecyrillic = 0x0477;
+ t.j = 0x006a;
+ t.jaarmenian = 0x0571;
+ t.jabengali = 0x099c;
+ t.jadeva = 0x091c;
+ t.jagujarati = 0x0a9c;
+ t.jagurmukhi = 0x0a1c;
+ t.jbopomofo = 0x3110;
+ t.jcaron = 0x01f0;
+ t.jcircle = 0x24d9;
+ t.jcircumflex = 0x0135;
+ t.jcrossedtail = 0x029d;
+ t.jdotlessstroke = 0x025f;
+ t.jecyrillic = 0x0458;
+ t.jeemarabic = 0x062c;
+ t.jeemfinalarabic = 0xfe9e;
+ t.jeeminitialarabic = 0xfe9f;
+ t.jeemmedialarabic = 0xfea0;
+ t.jeharabic = 0x0698;
+ t.jehfinalarabic = 0xfb8b;
+ t.jhabengali = 0x099d;
+ t.jhadeva = 0x091d;
+ t.jhagujarati = 0x0a9d;
+ t.jhagurmukhi = 0x0a1d;
+ t.jheharmenian = 0x057b;
+ t.jis = 0x3004;
+ t.jmonospace = 0xff4a;
+ t.jparen = 0x24a5;
+ t.jsuperior = 0x02b2;
+ t.k = 0x006b;
+ t.kabashkircyrillic = 0x04a1;
+ t.kabengali = 0x0995;
+ t.kacute = 0x1e31;
+ t.kacyrillic = 0x043a;
+ t.kadescendercyrillic = 0x049b;
+ t.kadeva = 0x0915;
+ t.kaf = 0x05db;
+ t.kafarabic = 0x0643;
+ t.kafdagesh = 0xfb3b;
+ t.kafdageshhebrew = 0xfb3b;
+ t.kaffinalarabic = 0xfeda;
+ t.kafhebrew = 0x05db;
+ t.kafinitialarabic = 0xfedb;
+ t.kafmedialarabic = 0xfedc;
+ t.kafrafehebrew = 0xfb4d;
+ t.kagujarati = 0x0a95;
+ t.kagurmukhi = 0x0a15;
+ t.kahiragana = 0x304b;
+ t.kahookcyrillic = 0x04c4;
+ t.kakatakana = 0x30ab;
+ t.kakatakanahalfwidth = 0xff76;
+ t.kappa = 0x03ba;
+ t.kappasymbolgreek = 0x03f0;
+ t.kapyeounmieumkorean = 0x3171;
+ t.kapyeounphieuphkorean = 0x3184;
+ t.kapyeounpieupkorean = 0x3178;
+ t.kapyeounssangpieupkorean = 0x3179;
+ t.karoriisquare = 0x330d;
+ t.kashidaautoarabic = 0x0640;
+ t.kashidaautonosidebearingarabic = 0x0640;
+ t.kasmallkatakana = 0x30f5;
+ t.kasquare = 0x3384;
+ t.kasraarabic = 0x0650;
+ t.kasratanarabic = 0x064d;
+ t.kastrokecyrillic = 0x049f;
+ t.katahiraprolongmarkhalfwidth = 0xff70;
+ t.kaverticalstrokecyrillic = 0x049d;
+ t.kbopomofo = 0x310e;
+ t.kcalsquare = 0x3389;
+ t.kcaron = 0x01e9;
+ t.kcedilla = 0x0137;
+ t.kcircle = 0x24da;
+ t.kcommaaccent = 0x0137;
+ t.kdotbelow = 0x1e33;
+ t.keharmenian = 0x0584;
+ t.kehiragana = 0x3051;
+ t.kekatakana = 0x30b1;
+ t.kekatakanahalfwidth = 0xff79;
+ t.kenarmenian = 0x056f;
+ t.kesmallkatakana = 0x30f6;
+ t.kgreenlandic = 0x0138;
+ t.khabengali = 0x0996;
+ t.khacyrillic = 0x0445;
+ t.khadeva = 0x0916;
+ t.khagujarati = 0x0a96;
+ t.khagurmukhi = 0x0a16;
+ t.khaharabic = 0x062e;
+ t.khahfinalarabic = 0xfea6;
+ t.khahinitialarabic = 0xfea7;
+ t.khahmedialarabic = 0xfea8;
+ t.kheicoptic = 0x03e7;
+ t.khhadeva = 0x0959;
+ t.khhagurmukhi = 0x0a59;
+ t.khieukhacirclekorean = 0x3278;
+ t.khieukhaparenkorean = 0x3218;
+ t.khieukhcirclekorean = 0x326a;
+ t.khieukhkorean = 0x314b;
+ t.khieukhparenkorean = 0x320a;
+ t.khokhaithai = 0x0e02;
+ t.khokhonthai = 0x0e05;
+ t.khokhuatthai = 0x0e03;
+ t.khokhwaithai = 0x0e04;
+ t.khomutthai = 0x0e5b;
+ t.khook = 0x0199;
+ t.khorakhangthai = 0x0e06;
+ t.khzsquare = 0x3391;
+ t.kihiragana = 0x304d;
+ t.kikatakana = 0x30ad;
+ t.kikatakanahalfwidth = 0xff77;
+ t.kiroguramusquare = 0x3315;
+ t.kiromeetorusquare = 0x3316;
+ t.kirosquare = 0x3314;
+ t.kiyeokacirclekorean = 0x326e;
+ t.kiyeokaparenkorean = 0x320e;
+ t.kiyeokcirclekorean = 0x3260;
+ t.kiyeokkorean = 0x3131;
+ t.kiyeokparenkorean = 0x3200;
+ t.kiyeoksioskorean = 0x3133;
+ t.kjecyrillic = 0x045c;
+ t.klinebelow = 0x1e35;
+ t.klsquare = 0x3398;
+ t.kmcubedsquare = 0x33a6;
+ t.kmonospace = 0xff4b;
+ t.kmsquaredsquare = 0x33a2;
+ t.kohiragana = 0x3053;
+ t.kohmsquare = 0x33c0;
+ t.kokaithai = 0x0e01;
+ t.kokatakana = 0x30b3;
+ t.kokatakanahalfwidth = 0xff7a;
+ t.kooposquare = 0x331e;
+ t.koppacyrillic = 0x0481;
+ t.koreanstandardsymbol = 0x327f;
+ t.koroniscmb = 0x0343;
+ t.kparen = 0x24a6;
+ t.kpasquare = 0x33aa;
+ t.ksicyrillic = 0x046f;
+ t.ktsquare = 0x33cf;
+ t.kturned = 0x029e;
+ t.kuhiragana = 0x304f;
+ t.kukatakana = 0x30af;
+ t.kukatakanahalfwidth = 0xff78;
+ t.kvsquare = 0x33b8;
+ t.kwsquare = 0x33be;
+ t.l = 0x006c;
+ t.labengali = 0x09b2;
+ t.lacute = 0x013a;
+ t.ladeva = 0x0932;
+ t.lagujarati = 0x0ab2;
+ t.lagurmukhi = 0x0a32;
+ t.lakkhangyaothai = 0x0e45;
+ t.lamaleffinalarabic = 0xfefc;
+ t.lamalefhamzaabovefinalarabic = 0xfef8;
+ t.lamalefhamzaaboveisolatedarabic = 0xfef7;
+ t.lamalefhamzabelowfinalarabic = 0xfefa;
+ t.lamalefhamzabelowisolatedarabic = 0xfef9;
+ t.lamalefisolatedarabic = 0xfefb;
+ t.lamalefmaddaabovefinalarabic = 0xfef6;
+ t.lamalefmaddaaboveisolatedarabic = 0xfef5;
+ t.lamarabic = 0x0644;
+ t.lambda = 0x03bb;
+ t.lambdastroke = 0x019b;
+ t.lamed = 0x05dc;
+ t.lameddagesh = 0xfb3c;
+ t.lameddageshhebrew = 0xfb3c;
+ t.lamedhebrew = 0x05dc;
+ t.lamfinalarabic = 0xfede;
+ t.lamhahinitialarabic = 0xfcca;
+ t.laminitialarabic = 0xfedf;
+ t.lamjeeminitialarabic = 0xfcc9;
+ t.lamkhahinitialarabic = 0xfccb;
+ t.lamlamhehisolatedarabic = 0xfdf2;
+ t.lammedialarabic = 0xfee0;
+ t.lammeemhahinitialarabic = 0xfd88;
+ t.lammeeminitialarabic = 0xfccc;
+ t.largecircle = 0x25ef;
+ t.lbar = 0x019a;
+ t.lbelt = 0x026c;
+ t.lbopomofo = 0x310c;
+ t.lcaron = 0x013e;
+ t.lcedilla = 0x013c;
+ t.lcircle = 0x24db;
+ t.lcircumflexbelow = 0x1e3d;
+ t.lcommaaccent = 0x013c;
+ t.ldot = 0x0140;
+ t.ldotaccent = 0x0140;
+ t.ldotbelow = 0x1e37;
+ t.ldotbelowmacron = 0x1e39;
+ t.leftangleabovecmb = 0x031a;
+ t.lefttackbelowcmb = 0x0318;
+ t.less = 0x003c;
+ t.lessequal = 0x2264;
+ t.lessequalorgreater = 0x22da;
+ t.lessmonospace = 0xff1c;
+ t.lessorequivalent = 0x2272;
+ t.lessorgreater = 0x2276;
+ t.lessoverequal = 0x2266;
+ t.lesssmall = 0xfe64;
+ t.lezh = 0x026e;
+ t.lfblock = 0x258c;
+ t.lhookretroflex = 0x026d;
+ t.lira = 0x20a4;
+ t.liwnarmenian = 0x056c;
+ t.lj = 0x01c9;
+ t.ljecyrillic = 0x0459;
+ t.ll = 0xf6c0;
+ t.lladeva = 0x0933;
+ t.llagujarati = 0x0ab3;
+ t.llinebelow = 0x1e3b;
+ t.llladeva = 0x0934;
+ t.llvocalicbengali = 0x09e1;
+ t.llvocalicdeva = 0x0961;
+ t.llvocalicvowelsignbengali = 0x09e3;
+ t.llvocalicvowelsigndeva = 0x0963;
+ t.lmiddletilde = 0x026b;
+ t.lmonospace = 0xff4c;
+ t.lmsquare = 0x33d0;
+ t.lochulathai = 0x0e2c;
+ t.logicaland = 0x2227;
+ t.logicalnot = 0x00ac;
+ t.logicalnotreversed = 0x2310;
+ t.logicalor = 0x2228;
+ t.lolingthai = 0x0e25;
+ t.longs = 0x017f;
+ t.lowlinecenterline = 0xfe4e;
+ t.lowlinecmb = 0x0332;
+ t.lowlinedashed = 0xfe4d;
+ t.lozenge = 0x25ca;
+ t.lparen = 0x24a7;
+ t.lslash = 0x0142;
+ t.lsquare = 0x2113;
+ t.lsuperior = 0xf6ee;
+ t.ltshade = 0x2591;
+ t.luthai = 0x0e26;
+ t.lvocalicbengali = 0x098c;
+ t.lvocalicdeva = 0x090c;
+ t.lvocalicvowelsignbengali = 0x09e2;
+ t.lvocalicvowelsigndeva = 0x0962;
+ t.lxsquare = 0x33d3;
+ t.m = 0x006d;
+ t.mabengali = 0x09ae;
+ t.macron = 0x00af;
+ t.macronbelowcmb = 0x0331;
+ t.macroncmb = 0x0304;
+ t.macronlowmod = 0x02cd;
+ t.macronmonospace = 0xffe3;
+ t.macute = 0x1e3f;
+ t.madeva = 0x092e;
+ t.magujarati = 0x0aae;
+ t.magurmukhi = 0x0a2e;
+ t.mahapakhhebrew = 0x05a4;
+ t.mahapakhlefthebrew = 0x05a4;
+ t.mahiragana = 0x307e;
+ t.maichattawalowleftthai = 0xf895;
+ t.maichattawalowrightthai = 0xf894;
+ t.maichattawathai = 0x0e4b;
+ t.maichattawaupperleftthai = 0xf893;
+ t.maieklowleftthai = 0xf88c;
+ t.maieklowrightthai = 0xf88b;
+ t.maiekthai = 0x0e48;
+ t.maiekupperleftthai = 0xf88a;
+ t.maihanakatleftthai = 0xf884;
+ t.maihanakatthai = 0x0e31;
+ t.maitaikhuleftthai = 0xf889;
+ t.maitaikhuthai = 0x0e47;
+ t.maitholowleftthai = 0xf88f;
+ t.maitholowrightthai = 0xf88e;
+ t.maithothai = 0x0e49;
+ t.maithoupperleftthai = 0xf88d;
+ t.maitrilowleftthai = 0xf892;
+ t.maitrilowrightthai = 0xf891;
+ t.maitrithai = 0x0e4a;
+ t.maitriupperleftthai = 0xf890;
+ t.maiyamokthai = 0x0e46;
+ t.makatakana = 0x30de;
+ t.makatakanahalfwidth = 0xff8f;
+ t.male = 0x2642;
+ t.mansyonsquare = 0x3347;
+ t.maqafhebrew = 0x05be;
+ t.mars = 0x2642;
+ t.masoracirclehebrew = 0x05af;
+ t.masquare = 0x3383;
+ t.mbopomofo = 0x3107;
+ t.mbsquare = 0x33d4;
+ t.mcircle = 0x24dc;
+ t.mcubedsquare = 0x33a5;
+ t.mdotaccent = 0x1e41;
+ t.mdotbelow = 0x1e43;
+ t.meemarabic = 0x0645;
+ t.meemfinalarabic = 0xfee2;
+ t.meeminitialarabic = 0xfee3;
+ t.meemmedialarabic = 0xfee4;
+ t.meemmeeminitialarabic = 0xfcd1;
+ t.meemmeemisolatedarabic = 0xfc48;
+ t.meetorusquare = 0x334d;
+ t.mehiragana = 0x3081;
+ t.meizierasquare = 0x337e;
+ t.mekatakana = 0x30e1;
+ t.mekatakanahalfwidth = 0xff92;
+ t.mem = 0x05de;
+ t.memdagesh = 0xfb3e;
+ t.memdageshhebrew = 0xfb3e;
+ t.memhebrew = 0x05de;
+ t.menarmenian = 0x0574;
+ t.merkhahebrew = 0x05a5;
+ t.merkhakefulahebrew = 0x05a6;
+ t.merkhakefulalefthebrew = 0x05a6;
+ t.merkhalefthebrew = 0x05a5;
+ t.mhook = 0x0271;
+ t.mhzsquare = 0x3392;
+ t.middledotkatakanahalfwidth = 0xff65;
+ t.middot = 0x00b7;
+ t.mieumacirclekorean = 0x3272;
+ t.mieumaparenkorean = 0x3212;
+ t.mieumcirclekorean = 0x3264;
+ t.mieumkorean = 0x3141;
+ t.mieumpansioskorean = 0x3170;
+ t.mieumparenkorean = 0x3204;
+ t.mieumpieupkorean = 0x316e;
+ t.mieumsioskorean = 0x316f;
+ t.mihiragana = 0x307f;
+ t.mikatakana = 0x30df;
+ t.mikatakanahalfwidth = 0xff90;
+ t.minus = 0x2212;
+ t.minusbelowcmb = 0x0320;
+ t.minuscircle = 0x2296;
+ t.minusmod = 0x02d7;
+ t.minusplus = 0x2213;
+ t.minute = 0x2032;
+ t.miribaarusquare = 0x334a;
+ t.mirisquare = 0x3349;
+ t.mlonglegturned = 0x0270;
+ t.mlsquare = 0x3396;
+ t.mmcubedsquare = 0x33a3;
+ t.mmonospace = 0xff4d;
+ t.mmsquaredsquare = 0x339f;
+ t.mohiragana = 0x3082;
+ t.mohmsquare = 0x33c1;
+ t.mokatakana = 0x30e2;
+ t.mokatakanahalfwidth = 0xff93;
+ t.molsquare = 0x33d6;
+ t.momathai = 0x0e21;
+ t.moverssquare = 0x33a7;
+ t.moverssquaredsquare = 0x33a8;
+ t.mparen = 0x24a8;
+ t.mpasquare = 0x33ab;
+ t.mssquare = 0x33b3;
+ t.msuperior = 0xf6ef;
+ t.mturned = 0x026f;
+ t.mu = 0x00b5;
+ t.mu1 = 0x00b5;
+ t.muasquare = 0x3382;
+ t.muchgreater = 0x226b;
+ t.muchless = 0x226a;
+ t.mufsquare = 0x338c;
+ t.mugreek = 0x03bc;
+ t.mugsquare = 0x338d;
+ t.muhiragana = 0x3080;
+ t.mukatakana = 0x30e0;
+ t.mukatakanahalfwidth = 0xff91;
+ t.mulsquare = 0x3395;
+ t.multiply = 0x00d7;
+ t.mumsquare = 0x339b;
+ t.munahhebrew = 0x05a3;
+ t.munahlefthebrew = 0x05a3;
+ t.musicalnote = 0x266a;
+ t.musicalnotedbl = 0x266b;
+ t.musicflatsign = 0x266d;
+ t.musicsharpsign = 0x266f;
+ t.mussquare = 0x33b2;
+ t.muvsquare = 0x33b6;
+ t.muwsquare = 0x33bc;
+ t.mvmegasquare = 0x33b9;
+ t.mvsquare = 0x33b7;
+ t.mwmegasquare = 0x33bf;
+ t.mwsquare = 0x33bd;
+ t.n = 0x006e;
+ t.nabengali = 0x09a8;
+ t.nabla = 0x2207;
+ t.nacute = 0x0144;
+ t.nadeva = 0x0928;
+ t.nagujarati = 0x0aa8;
+ t.nagurmukhi = 0x0a28;
+ t.nahiragana = 0x306a;
+ t.nakatakana = 0x30ca;
+ t.nakatakanahalfwidth = 0xff85;
+ t.napostrophe = 0x0149;
+ t.nasquare = 0x3381;
+ t.nbopomofo = 0x310b;
+ t.nbspace = 0x00a0;
+ t.ncaron = 0x0148;
+ t.ncedilla = 0x0146;
+ t.ncircle = 0x24dd;
+ t.ncircumflexbelow = 0x1e4b;
+ t.ncommaaccent = 0x0146;
+ t.ndotaccent = 0x1e45;
+ t.ndotbelow = 0x1e47;
+ t.nehiragana = 0x306d;
+ t.nekatakana = 0x30cd;
+ t.nekatakanahalfwidth = 0xff88;
+ t.newsheqelsign = 0x20aa;
+ t.nfsquare = 0x338b;
+ t.ngabengali = 0x0999;
+ t.ngadeva = 0x0919;
+ t.ngagujarati = 0x0a99;
+ t.ngagurmukhi = 0x0a19;
+ t.ngonguthai = 0x0e07;
+ t.nhiragana = 0x3093;
+ t.nhookleft = 0x0272;
+ t.nhookretroflex = 0x0273;
+ t.nieunacirclekorean = 0x326f;
+ t.nieunaparenkorean = 0x320f;
+ t.nieuncieuckorean = 0x3135;
+ t.nieuncirclekorean = 0x3261;
+ t.nieunhieuhkorean = 0x3136;
+ t.nieunkorean = 0x3134;
+ t.nieunpansioskorean = 0x3168;
+ t.nieunparenkorean = 0x3201;
+ t.nieunsioskorean = 0x3167;
+ t.nieuntikeutkorean = 0x3166;
+ t.nihiragana = 0x306b;
+ t.nikatakana = 0x30cb;
+ t.nikatakanahalfwidth = 0xff86;
+ t.nikhahitleftthai = 0xf899;
+ t.nikhahitthai = 0x0e4d;
+ t.nine = 0x0039;
+ t.ninearabic = 0x0669;
+ t.ninebengali = 0x09ef;
+ t.ninecircle = 0x2468;
+ t.ninecircleinversesansserif = 0x2792;
+ t.ninedeva = 0x096f;
+ t.ninegujarati = 0x0aef;
+ t.ninegurmukhi = 0x0a6f;
+ t.ninehackarabic = 0x0669;
+ t.ninehangzhou = 0x3029;
+ t.nineideographicparen = 0x3228;
+ t.nineinferior = 0x2089;
+ t.ninemonospace = 0xff19;
+ t.nineoldstyle = 0xf739;
+ t.nineparen = 0x247c;
+ t.nineperiod = 0x2490;
+ t.ninepersian = 0x06f9;
+ t.nineroman = 0x2178;
+ t.ninesuperior = 0x2079;
+ t.nineteencircle = 0x2472;
+ t.nineteenparen = 0x2486;
+ t.nineteenperiod = 0x249a;
+ t.ninethai = 0x0e59;
+ t.nj = 0x01cc;
+ t.njecyrillic = 0x045a;
+ t.nkatakana = 0x30f3;
+ t.nkatakanahalfwidth = 0xff9d;
+ t.nlegrightlong = 0x019e;
+ t.nlinebelow = 0x1e49;
+ t.nmonospace = 0xff4e;
+ t.nmsquare = 0x339a;
+ t.nnabengali = 0x09a3;
+ t.nnadeva = 0x0923;
+ t.nnagujarati = 0x0aa3;
+ t.nnagurmukhi = 0x0a23;
+ t.nnnadeva = 0x0929;
+ t.nohiragana = 0x306e;
+ t.nokatakana = 0x30ce;
+ t.nokatakanahalfwidth = 0xff89;
+ t.nonbreakingspace = 0x00a0;
+ t.nonenthai = 0x0e13;
+ t.nonuthai = 0x0e19;
+ t.noonarabic = 0x0646;
+ t.noonfinalarabic = 0xfee6;
+ t.noonghunnaarabic = 0x06ba;
+ t.noonghunnafinalarabic = 0xfb9f;
+ t.nooninitialarabic = 0xfee7;
+ t.noonjeeminitialarabic = 0xfcd2;
+ t.noonjeemisolatedarabic = 0xfc4b;
+ t.noonmedialarabic = 0xfee8;
+ t.noonmeeminitialarabic = 0xfcd5;
+ t.noonmeemisolatedarabic = 0xfc4e;
+ t.noonnoonfinalarabic = 0xfc8d;
+ t.notcontains = 0x220c;
+ t.notelement = 0x2209;
+ t.notelementof = 0x2209;
+ t.notequal = 0x2260;
+ t.notgreater = 0x226f;
+ t.notgreaternorequal = 0x2271;
+ t.notgreaternorless = 0x2279;
+ t.notidentical = 0x2262;
+ t.notless = 0x226e;
+ t.notlessnorequal = 0x2270;
+ t.notparallel = 0x2226;
+ t.notprecedes = 0x2280;
+ t.notsubset = 0x2284;
+ t.notsucceeds = 0x2281;
+ t.notsuperset = 0x2285;
+ t.nowarmenian = 0x0576;
+ t.nparen = 0x24a9;
+ t.nssquare = 0x33b1;
+ t.nsuperior = 0x207f;
+ t.ntilde = 0x00f1;
+ t.nu = 0x03bd;
+ t.nuhiragana = 0x306c;
+ t.nukatakana = 0x30cc;
+ t.nukatakanahalfwidth = 0xff87;
+ t.nuktabengali = 0x09bc;
+ t.nuktadeva = 0x093c;
+ t.nuktagujarati = 0x0abc;
+ t.nuktagurmukhi = 0x0a3c;
+ t.numbersign = 0x0023;
+ t.numbersignmonospace = 0xff03;
+ t.numbersignsmall = 0xfe5f;
+ t.numeralsigngreek = 0x0374;
+ t.numeralsignlowergreek = 0x0375;
+ t.numero = 0x2116;
+ t.nun = 0x05e0;
+ t.nundagesh = 0xfb40;
+ t.nundageshhebrew = 0xfb40;
+ t.nunhebrew = 0x05e0;
+ t.nvsquare = 0x33b5;
+ t.nwsquare = 0x33bb;
+ t.nyabengali = 0x099e;
+ t.nyadeva = 0x091e;
+ t.nyagujarati = 0x0a9e;
+ t.nyagurmukhi = 0x0a1e;
+ t.o = 0x006f;
+ t.oacute = 0x00f3;
+ t.oangthai = 0x0e2d;
+ t.obarred = 0x0275;
+ t.obarredcyrillic = 0x04e9;
+ t.obarreddieresiscyrillic = 0x04eb;
+ t.obengali = 0x0993;
+ t.obopomofo = 0x311b;
+ t.obreve = 0x014f;
+ t.ocandradeva = 0x0911;
+ t.ocandragujarati = 0x0a91;
+ t.ocandravowelsigndeva = 0x0949;
+ t.ocandravowelsigngujarati = 0x0ac9;
+ t.ocaron = 0x01d2;
+ t.ocircle = 0x24de;
+ t.ocircumflex = 0x00f4;
+ t.ocircumflexacute = 0x1ed1;
+ t.ocircumflexdotbelow = 0x1ed9;
+ t.ocircumflexgrave = 0x1ed3;
+ t.ocircumflexhookabove = 0x1ed5;
+ t.ocircumflextilde = 0x1ed7;
+ t.ocyrillic = 0x043e;
+ t.odblacute = 0x0151;
+ t.odblgrave = 0x020d;
+ t.odeva = 0x0913;
+ t.odieresis = 0x00f6;
+ t.odieresiscyrillic = 0x04e7;
+ t.odotbelow = 0x1ecd;
+ t.oe = 0x0153;
+ t.oekorean = 0x315a;
+ t.ogonek = 0x02db;
+ t.ogonekcmb = 0x0328;
+ t.ograve = 0x00f2;
+ t.ogujarati = 0x0a93;
+ t.oharmenian = 0x0585;
+ t.ohiragana = 0x304a;
+ t.ohookabove = 0x1ecf;
+ t.ohorn = 0x01a1;
+ t.ohornacute = 0x1edb;
+ t.ohorndotbelow = 0x1ee3;
+ t.ohorngrave = 0x1edd;
+ t.ohornhookabove = 0x1edf;
+ t.ohorntilde = 0x1ee1;
+ t.ohungarumlaut = 0x0151;
+ t.oi = 0x01a3;
+ t.oinvertedbreve = 0x020f;
+ t.okatakana = 0x30aa;
+ t.okatakanahalfwidth = 0xff75;
+ t.okorean = 0x3157;
+ t.olehebrew = 0x05ab;
+ t.omacron = 0x014d;
+ t.omacronacute = 0x1e53;
+ t.omacrongrave = 0x1e51;
+ t.omdeva = 0x0950;
+ t.omega = 0x03c9;
+ t.omega1 = 0x03d6;
+ t.omegacyrillic = 0x0461;
+ t.omegalatinclosed = 0x0277;
+ t.omegaroundcyrillic = 0x047b;
+ t.omegatitlocyrillic = 0x047d;
+ t.omegatonos = 0x03ce;
+ t.omgujarati = 0x0ad0;
+ t.omicron = 0x03bf;
+ t.omicrontonos = 0x03cc;
+ t.omonospace = 0xff4f;
+ t.one = 0x0031;
+ t.onearabic = 0x0661;
+ t.onebengali = 0x09e7;
+ t.onecircle = 0x2460;
+ t.onecircleinversesansserif = 0x278a;
+ t.onedeva = 0x0967;
+ t.onedotenleader = 0x2024;
+ t.oneeighth = 0x215b;
+ t.onefitted = 0xf6dc;
+ t.onegujarati = 0x0ae7;
+ t.onegurmukhi = 0x0a67;
+ t.onehackarabic = 0x0661;
+ t.onehalf = 0x00bd;
+ t.onehangzhou = 0x3021;
+ t.oneideographicparen = 0x3220;
+ t.oneinferior = 0x2081;
+ t.onemonospace = 0xff11;
+ t.onenumeratorbengali = 0x09f4;
+ t.oneoldstyle = 0xf731;
+ t.oneparen = 0x2474;
+ t.oneperiod = 0x2488;
+ t.onepersian = 0x06f1;
+ t.onequarter = 0x00bc;
+ t.oneroman = 0x2170;
+ t.onesuperior = 0x00b9;
+ t.onethai = 0x0e51;
+ t.onethird = 0x2153;
+ t.oogonek = 0x01eb;
+ t.oogonekmacron = 0x01ed;
+ t.oogurmukhi = 0x0a13;
+ t.oomatragurmukhi = 0x0a4b;
+ t.oopen = 0x0254;
+ t.oparen = 0x24aa;
+ t.openbullet = 0x25e6;
+ t.option = 0x2325;
+ t.ordfeminine = 0x00aa;
+ t.ordmasculine = 0x00ba;
+ t.orthogonal = 0x221f;
+ t.oshortdeva = 0x0912;
+ t.oshortvowelsigndeva = 0x094a;
+ t.oslash = 0x00f8;
+ t.oslashacute = 0x01ff;
+ t.osmallhiragana = 0x3049;
+ t.osmallkatakana = 0x30a9;
+ t.osmallkatakanahalfwidth = 0xff6b;
+ t.ostrokeacute = 0x01ff;
+ t.osuperior = 0xf6f0;
+ t.otcyrillic = 0x047f;
+ t.otilde = 0x00f5;
+ t.otildeacute = 0x1e4d;
+ t.otildedieresis = 0x1e4f;
+ t.oubopomofo = 0x3121;
+ t.overline = 0x203e;
+ t.overlinecenterline = 0xfe4a;
+ t.overlinecmb = 0x0305;
+ t.overlinedashed = 0xfe49;
+ t.overlinedblwavy = 0xfe4c;
+ t.overlinewavy = 0xfe4b;
+ t.overscore = 0x00af;
+ t.ovowelsignbengali = 0x09cb;
+ t.ovowelsigndeva = 0x094b;
+ t.ovowelsigngujarati = 0x0acb;
+ t.p = 0x0070;
+ t.paampssquare = 0x3380;
+ t.paasentosquare = 0x332b;
+ t.pabengali = 0x09aa;
+ t.pacute = 0x1e55;
+ t.padeva = 0x092a;
+ t.pagedown = 0x21df;
+ t.pageup = 0x21de;
+ t.pagujarati = 0x0aaa;
+ t.pagurmukhi = 0x0a2a;
+ t.pahiragana = 0x3071;
+ t.paiyannoithai = 0x0e2f;
+ t.pakatakana = 0x30d1;
+ t.palatalizationcyrilliccmb = 0x0484;
+ t.palochkacyrillic = 0x04c0;
+ t.pansioskorean = 0x317f;
+ t.paragraph = 0x00b6;
+ t.parallel = 0x2225;
+ t.parenleft = 0x0028;
+ t.parenleftaltonearabic = 0xfd3e;
+ t.parenleftbt = 0xf8ed;
+ t.parenleftex = 0xf8ec;
+ t.parenleftinferior = 0x208d;
+ t.parenleftmonospace = 0xff08;
+ t.parenleftsmall = 0xfe59;
+ t.parenleftsuperior = 0x207d;
+ t.parenlefttp = 0xf8eb;
+ t.parenleftvertical = 0xfe35;
+ t.parenright = 0x0029;
+ t.parenrightaltonearabic = 0xfd3f;
+ t.parenrightbt = 0xf8f8;
+ t.parenrightex = 0xf8f7;
+ t.parenrightinferior = 0x208e;
+ t.parenrightmonospace = 0xff09;
+ t.parenrightsmall = 0xfe5a;
+ t.parenrightsuperior = 0x207e;
+ t.parenrighttp = 0xf8f6;
+ t.parenrightvertical = 0xfe36;
+ t.partialdiff = 0x2202;
+ t.paseqhebrew = 0x05c0;
+ t.pashtahebrew = 0x0599;
+ t.pasquare = 0x33a9;
+ t.patah = 0x05b7;
+ t.patah11 = 0x05b7;
+ t.patah1d = 0x05b7;
+ t.patah2a = 0x05b7;
+ t.patahhebrew = 0x05b7;
+ t.patahnarrowhebrew = 0x05b7;
+ t.patahquarterhebrew = 0x05b7;
+ t.patahwidehebrew = 0x05b7;
+ t.pazerhebrew = 0x05a1;
+ t.pbopomofo = 0x3106;
+ t.pcircle = 0x24df;
+ t.pdotaccent = 0x1e57;
+ t.pe = 0x05e4;
+ t.pecyrillic = 0x043f;
+ t.pedagesh = 0xfb44;
+ t.pedageshhebrew = 0xfb44;
+ t.peezisquare = 0x333b;
+ t.pefinaldageshhebrew = 0xfb43;
+ t.peharabic = 0x067e;
+ t.peharmenian = 0x057a;
+ t.pehebrew = 0x05e4;
+ t.pehfinalarabic = 0xfb57;
+ t.pehinitialarabic = 0xfb58;
+ t.pehiragana = 0x307a;
+ t.pehmedialarabic = 0xfb59;
+ t.pekatakana = 0x30da;
+ t.pemiddlehookcyrillic = 0x04a7;
+ t.perafehebrew = 0xfb4e;
+ t.percent = 0x0025;
+ t.percentarabic = 0x066a;
+ t.percentmonospace = 0xff05;
+ t.percentsmall = 0xfe6a;
+ t.period = 0x002e;
+ t.periodarmenian = 0x0589;
+ t.periodcentered = 0x00b7;
+ t.periodhalfwidth = 0xff61;
+ t.periodinferior = 0xf6e7;
+ t.periodmonospace = 0xff0e;
+ t.periodsmall = 0xfe52;
+ t.periodsuperior = 0xf6e8;
+ t.perispomenigreekcmb = 0x0342;
+ t.perpendicular = 0x22a5;
+ t.perthousand = 0x2030;
+ t.peseta = 0x20a7;
+ t.pfsquare = 0x338a;
+ t.phabengali = 0x09ab;
+ t.phadeva = 0x092b;
+ t.phagujarati = 0x0aab;
+ t.phagurmukhi = 0x0a2b;
+ t.phi = 0x03c6;
+ t.phi1 = 0x03d5;
+ t.phieuphacirclekorean = 0x327a;
+ t.phieuphaparenkorean = 0x321a;
+ t.phieuphcirclekorean = 0x326c;
+ t.phieuphkorean = 0x314d;
+ t.phieuphparenkorean = 0x320c;
+ t.philatin = 0x0278;
+ t.phinthuthai = 0x0e3a;
+ t.phisymbolgreek = 0x03d5;
+ t.phook = 0x01a5;
+ t.phophanthai = 0x0e1e;
+ t.phophungthai = 0x0e1c;
+ t.phosamphaothai = 0x0e20;
+ t.pi = 0x03c0;
+ t.pieupacirclekorean = 0x3273;
+ t.pieupaparenkorean = 0x3213;
+ t.pieupcieuckorean = 0x3176;
+ t.pieupcirclekorean = 0x3265;
+ t.pieupkiyeokkorean = 0x3172;
+ t.pieupkorean = 0x3142;
+ t.pieupparenkorean = 0x3205;
+ t.pieupsioskiyeokkorean = 0x3174;
+ t.pieupsioskorean = 0x3144;
+ t.pieupsiostikeutkorean = 0x3175;
+ t.pieupthieuthkorean = 0x3177;
+ t.pieuptikeutkorean = 0x3173;
+ t.pihiragana = 0x3074;
+ t.pikatakana = 0x30d4;
+ t.pisymbolgreek = 0x03d6;
+ t.piwrarmenian = 0x0583;
+ t.planckover2pi = 0x210f;
+ t.planckover2pi1 = 0x210f;
+ t.plus = 0x002b;
+ t.plusbelowcmb = 0x031f;
+ t.pluscircle = 0x2295;
+ t.plusminus = 0x00b1;
+ t.plusmod = 0x02d6;
+ t.plusmonospace = 0xff0b;
+ t.plussmall = 0xfe62;
+ t.plussuperior = 0x207a;
+ t.pmonospace = 0xff50;
+ t.pmsquare = 0x33d8;
+ t.pohiragana = 0x307d;
+ t.pointingindexdownwhite = 0x261f;
+ t.pointingindexleftwhite = 0x261c;
+ t.pointingindexrightwhite = 0x261e;
+ t.pointingindexupwhite = 0x261d;
+ t.pokatakana = 0x30dd;
+ t.poplathai = 0x0e1b;
+ t.postalmark = 0x3012;
+ t.postalmarkface = 0x3020;
+ t.pparen = 0x24ab;
+ t.precedes = 0x227a;
+ t.prescription = 0x211e;
+ t.primemod = 0x02b9;
+ t.primereversed = 0x2035;
+ t.product = 0x220f;
+ t.projective = 0x2305;
+ t.prolongedkana = 0x30fc;
+ t.propellor = 0x2318;
+ t.propersubset = 0x2282;
+ t.propersuperset = 0x2283;
+ t.proportion = 0x2237;
+ t.proportional = 0x221d;
+ t.psi = 0x03c8;
+ t.psicyrillic = 0x0471;
+ t.psilipneumatacyrilliccmb = 0x0486;
+ t.pssquare = 0x33b0;
+ t.puhiragana = 0x3077;
+ t.pukatakana = 0x30d7;
+ t.pvsquare = 0x33b4;
+ t.pwsquare = 0x33ba;
+ t.q = 0x0071;
+ t.qadeva = 0x0958;
+ t.qadmahebrew = 0x05a8;
+ t.qafarabic = 0x0642;
+ t.qaffinalarabic = 0xfed6;
+ t.qafinitialarabic = 0xfed7;
+ t.qafmedialarabic = 0xfed8;
+ t.qamats = 0x05b8;
+ t.qamats10 = 0x05b8;
+ t.qamats1a = 0x05b8;
+ t.qamats1c = 0x05b8;
+ t.qamats27 = 0x05b8;
+ t.qamats29 = 0x05b8;
+ t.qamats33 = 0x05b8;
+ t.qamatsde = 0x05b8;
+ t.qamatshebrew = 0x05b8;
+ t.qamatsnarrowhebrew = 0x05b8;
+ t.qamatsqatanhebrew = 0x05b8;
+ t.qamatsqatannarrowhebrew = 0x05b8;
+ t.qamatsqatanquarterhebrew = 0x05b8;
+ t.qamatsqatanwidehebrew = 0x05b8;
+ t.qamatsquarterhebrew = 0x05b8;
+ t.qamatswidehebrew = 0x05b8;
+ t.qarneyparahebrew = 0x059f;
+ t.qbopomofo = 0x3111;
+ t.qcircle = 0x24e0;
+ t.qhook = 0x02a0;
+ t.qmonospace = 0xff51;
+ t.qof = 0x05e7;
+ t.qofdagesh = 0xfb47;
+ t.qofdageshhebrew = 0xfb47;
+ t.qofhebrew = 0x05e7;
+ t.qparen = 0x24ac;
+ t.quarternote = 0x2669;
+ t.qubuts = 0x05bb;
+ t.qubuts18 = 0x05bb;
+ t.qubuts25 = 0x05bb;
+ t.qubuts31 = 0x05bb;
+ t.qubutshebrew = 0x05bb;
+ t.qubutsnarrowhebrew = 0x05bb;
+ t.qubutsquarterhebrew = 0x05bb;
+ t.qubutswidehebrew = 0x05bb;
+ t.question = 0x003f;
+ t.questionarabic = 0x061f;
+ t.questionarmenian = 0x055e;
+ t.questiondown = 0x00bf;
+ t.questiondownsmall = 0xf7bf;
+ t.questiongreek = 0x037e;
+ t.questionmonospace = 0xff1f;
+ t.questionsmall = 0xf73f;
+ t.quotedbl = 0x0022;
+ t.quotedblbase = 0x201e;
+ t.quotedblleft = 0x201c;
+ t.quotedblmonospace = 0xff02;
+ t.quotedblprime = 0x301e;
+ t.quotedblprimereversed = 0x301d;
+ t.quotedblright = 0x201d;
+ t.quoteleft = 0x2018;
+ t.quoteleftreversed = 0x201b;
+ t.quotereversed = 0x201b;
+ t.quoteright = 0x2019;
+ t.quoterightn = 0x0149;
+ t.quotesinglbase = 0x201a;
+ t.quotesingle = 0x0027;
+ t.quotesinglemonospace = 0xff07;
+ t.r = 0x0072;
+ t.raarmenian = 0x057c;
+ t.rabengali = 0x09b0;
+ t.racute = 0x0155;
+ t.radeva = 0x0930;
+ t.radical = 0x221a;
+ t.radicalex = 0xf8e5;
+ t.radoverssquare = 0x33ae;
+ t.radoverssquaredsquare = 0x33af;
+ t.radsquare = 0x33ad;
+ t.rafe = 0x05bf;
+ t.rafehebrew = 0x05bf;
+ t.ragujarati = 0x0ab0;
+ t.ragurmukhi = 0x0a30;
+ t.rahiragana = 0x3089;
+ t.rakatakana = 0x30e9;
+ t.rakatakanahalfwidth = 0xff97;
+ t.ralowerdiagonalbengali = 0x09f1;
+ t.ramiddlediagonalbengali = 0x09f0;
+ t.ramshorn = 0x0264;
+ t.ratio = 0x2236;
+ t.rbopomofo = 0x3116;
+ t.rcaron = 0x0159;
+ t.rcedilla = 0x0157;
+ t.rcircle = 0x24e1;
+ t.rcommaaccent = 0x0157;
+ t.rdblgrave = 0x0211;
+ t.rdotaccent = 0x1e59;
+ t.rdotbelow = 0x1e5b;
+ t.rdotbelowmacron = 0x1e5d;
+ t.referencemark = 0x203b;
+ t.reflexsubset = 0x2286;
+ t.reflexsuperset = 0x2287;
+ t.registered = 0x00ae;
+ t.registersans = 0xf8e8;
+ t.registerserif = 0xf6da;
+ t.reharabic = 0x0631;
+ t.reharmenian = 0x0580;
+ t.rehfinalarabic = 0xfeae;
+ t.rehiragana = 0x308c;
+ t.rekatakana = 0x30ec;
+ t.rekatakanahalfwidth = 0xff9a;
+ t.resh = 0x05e8;
+ t.reshdageshhebrew = 0xfb48;
+ t.reshhebrew = 0x05e8;
+ t.reversedtilde = 0x223d;
+ t.reviahebrew = 0x0597;
+ t.reviamugrashhebrew = 0x0597;
+ t.revlogicalnot = 0x2310;
+ t.rfishhook = 0x027e;
+ t.rfishhookreversed = 0x027f;
+ t.rhabengali = 0x09dd;
+ t.rhadeva = 0x095d;
+ t.rho = 0x03c1;
+ t.rhook = 0x027d;
+ t.rhookturned = 0x027b;
+ t.rhookturnedsuperior = 0x02b5;
+ t.rhosymbolgreek = 0x03f1;
+ t.rhotichookmod = 0x02de;
+ t.rieulacirclekorean = 0x3271;
+ t.rieulaparenkorean = 0x3211;
+ t.rieulcirclekorean = 0x3263;
+ t.rieulhieuhkorean = 0x3140;
+ t.rieulkiyeokkorean = 0x313a;
+ t.rieulkiyeoksioskorean = 0x3169;
+ t.rieulkorean = 0x3139;
+ t.rieulmieumkorean = 0x313b;
+ t.rieulpansioskorean = 0x316c;
+ t.rieulparenkorean = 0x3203;
+ t.rieulphieuphkorean = 0x313f;
+ t.rieulpieupkorean = 0x313c;
+ t.rieulpieupsioskorean = 0x316b;
+ t.rieulsioskorean = 0x313d;
+ t.rieulthieuthkorean = 0x313e;
+ t.rieultikeutkorean = 0x316a;
+ t.rieulyeorinhieuhkorean = 0x316d;
+ t.rightangle = 0x221f;
+ t.righttackbelowcmb = 0x0319;
+ t.righttriangle = 0x22bf;
+ t.rihiragana = 0x308a;
+ t.rikatakana = 0x30ea;
+ t.rikatakanahalfwidth = 0xff98;
+ t.ring = 0x02da;
+ t.ringbelowcmb = 0x0325;
+ t.ringcmb = 0x030a;
+ t.ringhalfleft = 0x02bf;
+ t.ringhalfleftarmenian = 0x0559;
+ t.ringhalfleftbelowcmb = 0x031c;
+ t.ringhalfleftcentered = 0x02d3;
+ t.ringhalfright = 0x02be;
+ t.ringhalfrightbelowcmb = 0x0339;
+ t.ringhalfrightcentered = 0x02d2;
+ t.rinvertedbreve = 0x0213;
+ t.rittorusquare = 0x3351;
+ t.rlinebelow = 0x1e5f;
+ t.rlongleg = 0x027c;
+ t.rlonglegturned = 0x027a;
+ t.rmonospace = 0xff52;
+ t.rohiragana = 0x308d;
+ t.rokatakana = 0x30ed;
+ t.rokatakanahalfwidth = 0xff9b;
+ t.roruathai = 0x0e23;
+ t.rparen = 0x24ad;
+ t.rrabengali = 0x09dc;
+ t.rradeva = 0x0931;
+ t.rragurmukhi = 0x0a5c;
+ t.rreharabic = 0x0691;
+ t.rrehfinalarabic = 0xfb8d;
+ t.rrvocalicbengali = 0x09e0;
+ t.rrvocalicdeva = 0x0960;
+ t.rrvocalicgujarati = 0x0ae0;
+ t.rrvocalicvowelsignbengali = 0x09c4;
+ t.rrvocalicvowelsigndeva = 0x0944;
+ t.rrvocalicvowelsigngujarati = 0x0ac4;
+ t.rsuperior = 0xf6f1;
+ t.rtblock = 0x2590;
+ t.rturned = 0x0279;
+ t.rturnedsuperior = 0x02b4;
+ t.ruhiragana = 0x308b;
+ t.rukatakana = 0x30eb;
+ t.rukatakanahalfwidth = 0xff99;
+ t.rupeemarkbengali = 0x09f2;
+ t.rupeesignbengali = 0x09f3;
+ t.rupiah = 0xf6dd;
+ t.ruthai = 0x0e24;
+ t.rvocalicbengali = 0x098b;
+ t.rvocalicdeva = 0x090b;
+ t.rvocalicgujarati = 0x0a8b;
+ t.rvocalicvowelsignbengali = 0x09c3;
+ t.rvocalicvowelsigndeva = 0x0943;
+ t.rvocalicvowelsigngujarati = 0x0ac3;
+ t.s = 0x0073;
+ t.sabengali = 0x09b8;
+ t.sacute = 0x015b;
+ t.sacutedotaccent = 0x1e65;
+ t.sadarabic = 0x0635;
+ t.sadeva = 0x0938;
+ t.sadfinalarabic = 0xfeba;
+ t.sadinitialarabic = 0xfebb;
+ t.sadmedialarabic = 0xfebc;
+ t.sagujarati = 0x0ab8;
+ t.sagurmukhi = 0x0a38;
+ t.sahiragana = 0x3055;
+ t.sakatakana = 0x30b5;
+ t.sakatakanahalfwidth = 0xff7b;
+ t.sallallahoualayhewasallamarabic = 0xfdfa;
+ t.samekh = 0x05e1;
+ t.samekhdagesh = 0xfb41;
+ t.samekhdageshhebrew = 0xfb41;
+ t.samekhhebrew = 0x05e1;
+ t.saraaathai = 0x0e32;
+ t.saraaethai = 0x0e41;
+ t.saraaimaimalaithai = 0x0e44;
+ t.saraaimaimuanthai = 0x0e43;
+ t.saraamthai = 0x0e33;
+ t.saraathai = 0x0e30;
+ t.saraethai = 0x0e40;
+ t.saraiileftthai = 0xf886;
+ t.saraiithai = 0x0e35;
+ t.saraileftthai = 0xf885;
+ t.saraithai = 0x0e34;
+ t.saraothai = 0x0e42;
+ t.saraueeleftthai = 0xf888;
+ t.saraueethai = 0x0e37;
+ t.saraueleftthai = 0xf887;
+ t.sarauethai = 0x0e36;
+ t.sarauthai = 0x0e38;
+ t.sarauuthai = 0x0e39;
+ t.sbopomofo = 0x3119;
+ t.scaron = 0x0161;
+ t.scarondotaccent = 0x1e67;
+ t.scedilla = 0x015f;
+ t.schwa = 0x0259;
+ t.schwacyrillic = 0x04d9;
+ t.schwadieresiscyrillic = 0x04db;
+ t.schwahook = 0x025a;
+ t.scircle = 0x24e2;
+ t.scircumflex = 0x015d;
+ t.scommaaccent = 0x0219;
+ t.sdotaccent = 0x1e61;
+ t.sdotbelow = 0x1e63;
+ t.sdotbelowdotaccent = 0x1e69;
+ t.seagullbelowcmb = 0x033c;
+ t.second = 0x2033;
+ t.secondtonechinese = 0x02ca;
+ t.section = 0x00a7;
+ t.seenarabic = 0x0633;
+ t.seenfinalarabic = 0xfeb2;
+ t.seeninitialarabic = 0xfeb3;
+ t.seenmedialarabic = 0xfeb4;
+ t.segol = 0x05b6;
+ t.segol13 = 0x05b6;
+ t.segol1f = 0x05b6;
+ t.segol2c = 0x05b6;
+ t.segolhebrew = 0x05b6;
+ t.segolnarrowhebrew = 0x05b6;
+ t.segolquarterhebrew = 0x05b6;
+ t.segoltahebrew = 0x0592;
+ t.segolwidehebrew = 0x05b6;
+ t.seharmenian = 0x057d;
+ t.sehiragana = 0x305b;
+ t.sekatakana = 0x30bb;
+ t.sekatakanahalfwidth = 0xff7e;
+ t.semicolon = 0x003b;
+ t.semicolonarabic = 0x061b;
+ t.semicolonmonospace = 0xff1b;
+ t.semicolonsmall = 0xfe54;
+ t.semivoicedmarkkana = 0x309c;
+ t.semivoicedmarkkanahalfwidth = 0xff9f;
+ t.sentisquare = 0x3322;
+ t.sentosquare = 0x3323;
+ t.seven = 0x0037;
+ t.sevenarabic = 0x0667;
+ t.sevenbengali = 0x09ed;
+ t.sevencircle = 0x2466;
+ t.sevencircleinversesansserif = 0x2790;
+ t.sevendeva = 0x096d;
+ t.seveneighths = 0x215e;
+ t.sevengujarati = 0x0aed;
+ t.sevengurmukhi = 0x0a6d;
+ t.sevenhackarabic = 0x0667;
+ t.sevenhangzhou = 0x3027;
+ t.sevenideographicparen = 0x3226;
+ t.seveninferior = 0x2087;
+ t.sevenmonospace = 0xff17;
+ t.sevenoldstyle = 0xf737;
+ t.sevenparen = 0x247a;
+ t.sevenperiod = 0x248e;
+ t.sevenpersian = 0x06f7;
+ t.sevenroman = 0x2176;
+ t.sevensuperior = 0x2077;
+ t.seventeencircle = 0x2470;
+ t.seventeenparen = 0x2484;
+ t.seventeenperiod = 0x2498;
+ t.seventhai = 0x0e57;
+ t.sfthyphen = 0x00ad;
+ t.shaarmenian = 0x0577;
+ t.shabengali = 0x09b6;
+ t.shacyrillic = 0x0448;
+ t.shaddaarabic = 0x0651;
+ t.shaddadammaarabic = 0xfc61;
+ t.shaddadammatanarabic = 0xfc5e;
+ t.shaddafathaarabic = 0xfc60;
+ t.shaddakasraarabic = 0xfc62;
+ t.shaddakasratanarabic = 0xfc5f;
+ t.shade = 0x2592;
+ t.shadedark = 0x2593;
+ t.shadelight = 0x2591;
+ t.shademedium = 0x2592;
+ t.shadeva = 0x0936;
+ t.shagujarati = 0x0ab6;
+ t.shagurmukhi = 0x0a36;
+ t.shalshelethebrew = 0x0593;
+ t.shbopomofo = 0x3115;
+ t.shchacyrillic = 0x0449;
+ t.sheenarabic = 0x0634;
+ t.sheenfinalarabic = 0xfeb6;
+ t.sheeninitialarabic = 0xfeb7;
+ t.sheenmedialarabic = 0xfeb8;
+ t.sheicoptic = 0x03e3;
+ t.sheqel = 0x20aa;
+ t.sheqelhebrew = 0x20aa;
+ t.sheva = 0x05b0;
+ t.sheva115 = 0x05b0;
+ t.sheva15 = 0x05b0;
+ t.sheva22 = 0x05b0;
+ t.sheva2e = 0x05b0;
+ t.shevahebrew = 0x05b0;
+ t.shevanarrowhebrew = 0x05b0;
+ t.shevaquarterhebrew = 0x05b0;
+ t.shevawidehebrew = 0x05b0;
+ t.shhacyrillic = 0x04bb;
+ t.shimacoptic = 0x03ed;
+ t.shin = 0x05e9;
+ t.shindagesh = 0xfb49;
+ t.shindageshhebrew = 0xfb49;
+ t.shindageshshindot = 0xfb2c;
+ t.shindageshshindothebrew = 0xfb2c;
+ t.shindageshsindot = 0xfb2d;
+ t.shindageshsindothebrew = 0xfb2d;
+ t.shindothebrew = 0x05c1;
+ t.shinhebrew = 0x05e9;
+ t.shinshindot = 0xfb2a;
+ t.shinshindothebrew = 0xfb2a;
+ t.shinsindot = 0xfb2b;
+ t.shinsindothebrew = 0xfb2b;
+ t.shook = 0x0282;
+ t.sigma = 0x03c3;
+ t.sigma1 = 0x03c2;
+ t.sigmafinal = 0x03c2;
+ t.sigmalunatesymbolgreek = 0x03f2;
+ t.sihiragana = 0x3057;
+ t.sikatakana = 0x30b7;
+ t.sikatakanahalfwidth = 0xff7c;
+ t.siluqhebrew = 0x05bd;
+ t.siluqlefthebrew = 0x05bd;
+ t.similar = 0x223c;
+ t.sindothebrew = 0x05c2;
+ t.siosacirclekorean = 0x3274;
+ t.siosaparenkorean = 0x3214;
+ t.sioscieuckorean = 0x317e;
+ t.sioscirclekorean = 0x3266;
+ t.sioskiyeokkorean = 0x317a;
+ t.sioskorean = 0x3145;
+ t.siosnieunkorean = 0x317b;
+ t.siosparenkorean = 0x3206;
+ t.siospieupkorean = 0x317d;
+ t.siostikeutkorean = 0x317c;
+ t.six = 0x0036;
+ t.sixarabic = 0x0666;
+ t.sixbengali = 0x09ec;
+ t.sixcircle = 0x2465;
+ t.sixcircleinversesansserif = 0x278f;
+ t.sixdeva = 0x096c;
+ t.sixgujarati = 0x0aec;
+ t.sixgurmukhi = 0x0a6c;
+ t.sixhackarabic = 0x0666;
+ t.sixhangzhou = 0x3026;
+ t.sixideographicparen = 0x3225;
+ t.sixinferior = 0x2086;
+ t.sixmonospace = 0xff16;
+ t.sixoldstyle = 0xf736;
+ t.sixparen = 0x2479;
+ t.sixperiod = 0x248d;
+ t.sixpersian = 0x06f6;
+ t.sixroman = 0x2175;
+ t.sixsuperior = 0x2076;
+ t.sixteencircle = 0x246f;
+ t.sixteencurrencydenominatorbengali = 0x09f9;
+ t.sixteenparen = 0x2483;
+ t.sixteenperiod = 0x2497;
+ t.sixthai = 0x0e56;
+ t.slash = 0x002f;
+ t.slashmonospace = 0xff0f;
+ t.slong = 0x017f;
+ t.slongdotaccent = 0x1e9b;
+ t.smileface = 0x263a;
+ t.smonospace = 0xff53;
+ t.sofpasuqhebrew = 0x05c3;
+ t.softhyphen = 0x00ad;
+ t.softsigncyrillic = 0x044c;
+ t.sohiragana = 0x305d;
+ t.sokatakana = 0x30bd;
+ t.sokatakanahalfwidth = 0xff7f;
+ t.soliduslongoverlaycmb = 0x0338;
+ t.solidusshortoverlaycmb = 0x0337;
+ t.sorusithai = 0x0e29;
+ t.sosalathai = 0x0e28;
+ t.sosothai = 0x0e0b;
+ t.sosuathai = 0x0e2a;
+ t.space = 0x0020;
+ t.spacehackarabic = 0x0020;
+ t.spade = 0x2660;
+ t.spadesuitblack = 0x2660;
+ t.spadesuitwhite = 0x2664;
+ t.sparen = 0x24ae;
+ t.squarebelowcmb = 0x033b;
+ t.squarecc = 0x33c4;
+ t.squarecm = 0x339d;
+ t.squarediagonalcrosshatchfill = 0x25a9;
+ t.squarehorizontalfill = 0x25a4;
+ t.squarekg = 0x338f;
+ t.squarekm = 0x339e;
+ t.squarekmcapital = 0x33ce;
+ t.squareln = 0x33d1;
+ t.squarelog = 0x33d2;
+ t.squaremg = 0x338e;
+ t.squaremil = 0x33d5;
+ t.squaremm = 0x339c;
+ t.squaremsquared = 0x33a1;
+ t.squareorthogonalcrosshatchfill = 0x25a6;
+ t.squareupperlefttolowerrightfill = 0x25a7;
+ t.squareupperrighttolowerleftfill = 0x25a8;
+ t.squareverticalfill = 0x25a5;
+ t.squarewhitewithsmallblack = 0x25a3;
+ t.srsquare = 0x33db;
+ t.ssabengali = 0x09b7;
+ t.ssadeva = 0x0937;
+ t.ssagujarati = 0x0ab7;
+ t.ssangcieuckorean = 0x3149;
+ t.ssanghieuhkorean = 0x3185;
+ t.ssangieungkorean = 0x3180;
+ t.ssangkiyeokkorean = 0x3132;
+ t.ssangnieunkorean = 0x3165;
+ t.ssangpieupkorean = 0x3143;
+ t.ssangsioskorean = 0x3146;
+ t.ssangtikeutkorean = 0x3138;
+ t.ssuperior = 0xf6f2;
+ t.sterling = 0x00a3;
+ t.sterlingmonospace = 0xffe1;
+ t.strokelongoverlaycmb = 0x0336;
+ t.strokeshortoverlaycmb = 0x0335;
+ t.subset = 0x2282;
+ t.subsetnotequal = 0x228a;
+ t.subsetorequal = 0x2286;
+ t.succeeds = 0x227b;
+ t.suchthat = 0x220b;
+ t.suhiragana = 0x3059;
+ t.sukatakana = 0x30b9;
+ t.sukatakanahalfwidth = 0xff7d;
+ t.sukunarabic = 0x0652;
+ t.summation = 0x2211;
+ t.sun = 0x263c;
+ t.superset = 0x2283;
+ t.supersetnotequal = 0x228b;
+ t.supersetorequal = 0x2287;
+ t.svsquare = 0x33dc;
+ t.syouwaerasquare = 0x337c;
+ t.t = 0x0074;
+ t.tabengali = 0x09a4;
+ t.tackdown = 0x22a4;
+ t.tackleft = 0x22a3;
+ t.tadeva = 0x0924;
+ t.tagujarati = 0x0aa4;
+ t.tagurmukhi = 0x0a24;
+ t.taharabic = 0x0637;
+ t.tahfinalarabic = 0xfec2;
+ t.tahinitialarabic = 0xfec3;
+ t.tahiragana = 0x305f;
+ t.tahmedialarabic = 0xfec4;
+ t.taisyouerasquare = 0x337d;
+ t.takatakana = 0x30bf;
+ t.takatakanahalfwidth = 0xff80;
+ t.tatweelarabic = 0x0640;
+ t.tau = 0x03c4;
+ t.tav = 0x05ea;
+ t.tavdages = 0xfb4a;
+ t.tavdagesh = 0xfb4a;
+ t.tavdageshhebrew = 0xfb4a;
+ t.tavhebrew = 0x05ea;
+ t.tbar = 0x0167;
+ t.tbopomofo = 0x310a;
+ t.tcaron = 0x0165;
+ t.tccurl = 0x02a8;
+ t.tcedilla = 0x0163;
+ t.tcheharabic = 0x0686;
+ t.tchehfinalarabic = 0xfb7b;
+ t.tchehinitialarabic = 0xfb7c;
+ t.tchehmedialarabic = 0xfb7d;
+ t.tcircle = 0x24e3;
+ t.tcircumflexbelow = 0x1e71;
+ t.tcommaaccent = 0x0163;
+ t.tdieresis = 0x1e97;
+ t.tdotaccent = 0x1e6b;
+ t.tdotbelow = 0x1e6d;
+ t.tecyrillic = 0x0442;
+ t.tedescendercyrillic = 0x04ad;
+ t.teharabic = 0x062a;
+ t.tehfinalarabic = 0xfe96;
+ t.tehhahinitialarabic = 0xfca2;
+ t.tehhahisolatedarabic = 0xfc0c;
+ t.tehinitialarabic = 0xfe97;
+ t.tehiragana = 0x3066;
+ t.tehjeeminitialarabic = 0xfca1;
+ t.tehjeemisolatedarabic = 0xfc0b;
+ t.tehmarbutaarabic = 0x0629;
+ t.tehmarbutafinalarabic = 0xfe94;
+ t.tehmedialarabic = 0xfe98;
+ t.tehmeeminitialarabic = 0xfca4;
+ t.tehmeemisolatedarabic = 0xfc0e;
+ t.tehnoonfinalarabic = 0xfc73;
+ t.tekatakana = 0x30c6;
+ t.tekatakanahalfwidth = 0xff83;
+ t.telephone = 0x2121;
+ t.telephoneblack = 0x260e;
+ t.telishagedolahebrew = 0x05a0;
+ t.telishaqetanahebrew = 0x05a9;
+ t.tencircle = 0x2469;
+ t.tenideographicparen = 0x3229;
+ t.tenparen = 0x247d;
+ t.tenperiod = 0x2491;
+ t.tenroman = 0x2179;
+ t.tesh = 0x02a7;
+ t.tet = 0x05d8;
+ t.tetdagesh = 0xfb38;
+ t.tetdageshhebrew = 0xfb38;
+ t.tethebrew = 0x05d8;
+ t.tetsecyrillic = 0x04b5;
+ t.tevirhebrew = 0x059b;
+ t.tevirlefthebrew = 0x059b;
+ t.thabengali = 0x09a5;
+ t.thadeva = 0x0925;
+ t.thagujarati = 0x0aa5;
+ t.thagurmukhi = 0x0a25;
+ t.thalarabic = 0x0630;
+ t.thalfinalarabic = 0xfeac;
+ t.thanthakhatlowleftthai = 0xf898;
+ t.thanthakhatlowrightthai = 0xf897;
+ t.thanthakhatthai = 0x0e4c;
+ t.thanthakhatupperleftthai = 0xf896;
+ t.theharabic = 0x062b;
+ t.thehfinalarabic = 0xfe9a;
+ t.thehinitialarabic = 0xfe9b;
+ t.thehmedialarabic = 0xfe9c;
+ t.thereexists = 0x2203;
+ t.therefore = 0x2234;
+ t.theta = 0x03b8;
+ t.theta1 = 0x03d1;
+ t.thetasymbolgreek = 0x03d1;
+ t.thieuthacirclekorean = 0x3279;
+ t.thieuthaparenkorean = 0x3219;
+ t.thieuthcirclekorean = 0x326b;
+ t.thieuthkorean = 0x314c;
+ t.thieuthparenkorean = 0x320b;
+ t.thirteencircle = 0x246c;
+ t.thirteenparen = 0x2480;
+ t.thirteenperiod = 0x2494;
+ t.thonangmonthothai = 0x0e11;
+ t.thook = 0x01ad;
+ t.thophuthaothai = 0x0e12;
+ t.thorn = 0x00fe;
+ t.thothahanthai = 0x0e17;
+ t.thothanthai = 0x0e10;
+ t.thothongthai = 0x0e18;
+ t.thothungthai = 0x0e16;
+ t.thousandcyrillic = 0x0482;
+ t.thousandsseparatorarabic = 0x066c;
+ t.thousandsseparatorpersian = 0x066c;
+ t.three = 0x0033;
+ t.threearabic = 0x0663;
+ t.threebengali = 0x09e9;
+ t.threecircle = 0x2462;
+ t.threecircleinversesansserif = 0x278c;
+ t.threedeva = 0x0969;
+ t.threeeighths = 0x215c;
+ t.threegujarati = 0x0ae9;
+ t.threegurmukhi = 0x0a69;
+ t.threehackarabic = 0x0663;
+ t.threehangzhou = 0x3023;
+ t.threeideographicparen = 0x3222;
+ t.threeinferior = 0x2083;
+ t.threemonospace = 0xff13;
+ t.threenumeratorbengali = 0x09f6;
+ t.threeoldstyle = 0xf733;
+ t.threeparen = 0x2476;
+ t.threeperiod = 0x248a;
+ t.threepersian = 0x06f3;
+ t.threequarters = 0x00be;
+ t.threequartersemdash = 0xf6de;
+ t.threeroman = 0x2172;
+ t.threesuperior = 0x00b3;
+ t.threethai = 0x0e53;
+ t.thzsquare = 0x3394;
+ t.tihiragana = 0x3061;
+ t.tikatakana = 0x30c1;
+ t.tikatakanahalfwidth = 0xff81;
+ t.tikeutacirclekorean = 0x3270;
+ t.tikeutaparenkorean = 0x3210;
+ t.tikeutcirclekorean = 0x3262;
+ t.tikeutkorean = 0x3137;
+ t.tikeutparenkorean = 0x3202;
+ t.tilde = 0x02dc;
+ t.tildebelowcmb = 0x0330;
+ t.tildecmb = 0x0303;
+ t.tildecomb = 0x0303;
+ t.tildedoublecmb = 0x0360;
+ t.tildeoperator = 0x223c;
+ t.tildeoverlaycmb = 0x0334;
+ t.tildeverticalcmb = 0x033e;
+ t.timescircle = 0x2297;
+ t.tipehahebrew = 0x0596;
+ t.tipehalefthebrew = 0x0596;
+ t.tippigurmukhi = 0x0a70;
+ t.titlocyrilliccmb = 0x0483;
+ t.tiwnarmenian = 0x057f;
+ t.tlinebelow = 0x1e6f;
+ t.tmonospace = 0xff54;
+ t.toarmenian = 0x0569;
+ t.tohiragana = 0x3068;
+ t.tokatakana = 0x30c8;
+ t.tokatakanahalfwidth = 0xff84;
+ t.tonebarextrahighmod = 0x02e5;
+ t.tonebarextralowmod = 0x02e9;
+ t.tonebarhighmod = 0x02e6;
+ t.tonebarlowmod = 0x02e8;
+ t.tonebarmidmod = 0x02e7;
+ t.tonefive = 0x01bd;
+ t.tonesix = 0x0185;
+ t.tonetwo = 0x01a8;
+ t.tonos = 0x0384;
+ t.tonsquare = 0x3327;
+ t.topatakthai = 0x0e0f;
+ t.tortoiseshellbracketleft = 0x3014;
+ t.tortoiseshellbracketleftsmall = 0xfe5d;
+ t.tortoiseshellbracketleftvertical = 0xfe39;
+ t.tortoiseshellbracketright = 0x3015;
+ t.tortoiseshellbracketrightsmall = 0xfe5e;
+ t.tortoiseshellbracketrightvertical = 0xfe3a;
+ t.totaothai = 0x0e15;
+ t.tpalatalhook = 0x01ab;
+ t.tparen = 0x24af;
+ t.trademark = 0x2122;
+ t.trademarksans = 0xf8ea;
+ t.trademarkserif = 0xf6db;
+ t.tretroflexhook = 0x0288;
+ t.triagdn = 0x25bc;
+ t.triaglf = 0x25c4;
+ t.triagrt = 0x25ba;
+ t.triagup = 0x25b2;
+ t.ts = 0x02a6;
+ t.tsadi = 0x05e6;
+ t.tsadidagesh = 0xfb46;
+ t.tsadidageshhebrew = 0xfb46;
+ t.tsadihebrew = 0x05e6;
+ t.tsecyrillic = 0x0446;
+ t.tsere = 0x05b5;
+ t.tsere12 = 0x05b5;
+ t.tsere1e = 0x05b5;
+ t.tsere2b = 0x05b5;
+ t.tserehebrew = 0x05b5;
+ t.tserenarrowhebrew = 0x05b5;
+ t.tserequarterhebrew = 0x05b5;
+ t.tserewidehebrew = 0x05b5;
+ t.tshecyrillic = 0x045b;
+ t.tsuperior = 0xf6f3;
+ t.ttabengali = 0x099f;
+ t.ttadeva = 0x091f;
+ t.ttagujarati = 0x0a9f;
+ t.ttagurmukhi = 0x0a1f;
+ t.tteharabic = 0x0679;
+ t.ttehfinalarabic = 0xfb67;
+ t.ttehinitialarabic = 0xfb68;
+ t.ttehmedialarabic = 0xfb69;
+ t.tthabengali = 0x09a0;
+ t.tthadeva = 0x0920;
+ t.tthagujarati = 0x0aa0;
+ t.tthagurmukhi = 0x0a20;
+ t.tturned = 0x0287;
+ t.tuhiragana = 0x3064;
+ t.tukatakana = 0x30c4;
+ t.tukatakanahalfwidth = 0xff82;
+ t.tusmallhiragana = 0x3063;
+ t.tusmallkatakana = 0x30c3;
+ t.tusmallkatakanahalfwidth = 0xff6f;
+ t.twelvecircle = 0x246b;
+ t.twelveparen = 0x247f;
+ t.twelveperiod = 0x2493;
+ t.twelveroman = 0x217b;
+ t.twentycircle = 0x2473;
+ t.twentyhangzhou = 0x5344;
+ t.twentyparen = 0x2487;
+ t.twentyperiod = 0x249b;
+ t.two = 0x0032;
+ t.twoarabic = 0x0662;
+ t.twobengali = 0x09e8;
+ t.twocircle = 0x2461;
+ t.twocircleinversesansserif = 0x278b;
+ t.twodeva = 0x0968;
+ t.twodotenleader = 0x2025;
+ t.twodotleader = 0x2025;
+ t.twodotleadervertical = 0xfe30;
+ t.twogujarati = 0x0ae8;
+ t.twogurmukhi = 0x0a68;
+ t.twohackarabic = 0x0662;
+ t.twohangzhou = 0x3022;
+ t.twoideographicparen = 0x3221;
+ t.twoinferior = 0x2082;
+ t.twomonospace = 0xff12;
+ t.twonumeratorbengali = 0x09f5;
+ t.twooldstyle = 0xf732;
+ t.twoparen = 0x2475;
+ t.twoperiod = 0x2489;
+ t.twopersian = 0x06f2;
+ t.tworoman = 0x2171;
+ t.twostroke = 0x01bb;
+ t.twosuperior = 0x00b2;
+ t.twothai = 0x0e52;
+ t.twothirds = 0x2154;
+ t.u = 0x0075;
+ t.uacute = 0x00fa;
+ t.ubar = 0x0289;
+ t.ubengali = 0x0989;
+ t.ubopomofo = 0x3128;
+ t.ubreve = 0x016d;
+ t.ucaron = 0x01d4;
+ t.ucircle = 0x24e4;
+ t.ucircumflex = 0x00fb;
+ t.ucircumflexbelow = 0x1e77;
+ t.ucyrillic = 0x0443;
+ t.udattadeva = 0x0951;
+ t.udblacute = 0x0171;
+ t.udblgrave = 0x0215;
+ t.udeva = 0x0909;
+ t.udieresis = 0x00fc;
+ t.udieresisacute = 0x01d8;
+ t.udieresisbelow = 0x1e73;
+ t.udieresiscaron = 0x01da;
+ t.udieresiscyrillic = 0x04f1;
+ t.udieresisgrave = 0x01dc;
+ t.udieresismacron = 0x01d6;
+ t.udotbelow = 0x1ee5;
+ t.ugrave = 0x00f9;
+ t.ugujarati = 0x0a89;
+ t.ugurmukhi = 0x0a09;
+ t.uhiragana = 0x3046;
+ t.uhookabove = 0x1ee7;
+ t.uhorn = 0x01b0;
+ t.uhornacute = 0x1ee9;
+ t.uhorndotbelow = 0x1ef1;
+ t.uhorngrave = 0x1eeb;
+ t.uhornhookabove = 0x1eed;
+ t.uhorntilde = 0x1eef;
+ t.uhungarumlaut = 0x0171;
+ t.uhungarumlautcyrillic = 0x04f3;
+ t.uinvertedbreve = 0x0217;
+ t.ukatakana = 0x30a6;
+ t.ukatakanahalfwidth = 0xff73;
+ t.ukcyrillic = 0x0479;
+ t.ukorean = 0x315c;
+ t.umacron = 0x016b;
+ t.umacroncyrillic = 0x04ef;
+ t.umacrondieresis = 0x1e7b;
+ t.umatragurmukhi = 0x0a41;
+ t.umonospace = 0xff55;
+ t.underscore = 0x005f;
+ t.underscoredbl = 0x2017;
+ t.underscoremonospace = 0xff3f;
+ t.underscorevertical = 0xfe33;
+ t.underscorewavy = 0xfe4f;
+ t.union = 0x222a;
+ t.universal = 0x2200;
+ t.uogonek = 0x0173;
+ t.uparen = 0x24b0;
+ t.upblock = 0x2580;
+ t.upperdothebrew = 0x05c4;
+ t.upsilon = 0x03c5;
+ t.upsilondieresis = 0x03cb;
+ t.upsilondieresistonos = 0x03b0;
+ t.upsilonlatin = 0x028a;
+ t.upsilontonos = 0x03cd;
+ t.uptackbelowcmb = 0x031d;
+ t.uptackmod = 0x02d4;
+ t.uragurmukhi = 0x0a73;
+ t.uring = 0x016f;
+ t.ushortcyrillic = 0x045e;
+ t.usmallhiragana = 0x3045;
+ t.usmallkatakana = 0x30a5;
+ t.usmallkatakanahalfwidth = 0xff69;
+ t.ustraightcyrillic = 0x04af;
+ t.ustraightstrokecyrillic = 0x04b1;
+ t.utilde = 0x0169;
+ t.utildeacute = 0x1e79;
+ t.utildebelow = 0x1e75;
+ t.uubengali = 0x098a;
+ t.uudeva = 0x090a;
+ t.uugujarati = 0x0a8a;
+ t.uugurmukhi = 0x0a0a;
+ t.uumatragurmukhi = 0x0a42;
+ t.uuvowelsignbengali = 0x09c2;
+ t.uuvowelsigndeva = 0x0942;
+ t.uuvowelsigngujarati = 0x0ac2;
+ t.uvowelsignbengali = 0x09c1;
+ t.uvowelsigndeva = 0x0941;
+ t.uvowelsigngujarati = 0x0ac1;
+ t.v = 0x0076;
+ t.vadeva = 0x0935;
+ t.vagujarati = 0x0ab5;
+ t.vagurmukhi = 0x0a35;
+ t.vakatakana = 0x30f7;
+ t.vav = 0x05d5;
+ t.vavdagesh = 0xfb35;
+ t.vavdagesh65 = 0xfb35;
+ t.vavdageshhebrew = 0xfb35;
+ t.vavhebrew = 0x05d5;
+ t.vavholam = 0xfb4b;
+ t.vavholamhebrew = 0xfb4b;
+ t.vavvavhebrew = 0x05f0;
+ t.vavyodhebrew = 0x05f1;
+ t.vcircle = 0x24e5;
+ t.vdotbelow = 0x1e7f;
+ t.vecyrillic = 0x0432;
+ t.veharabic = 0x06a4;
+ t.vehfinalarabic = 0xfb6b;
+ t.vehinitialarabic = 0xfb6c;
+ t.vehmedialarabic = 0xfb6d;
+ t.vekatakana = 0x30f9;
+ t.venus = 0x2640;
+ t.verticalbar = 0x007c;
+ t.verticallineabovecmb = 0x030d;
+ t.verticallinebelowcmb = 0x0329;
+ t.verticallinelowmod = 0x02cc;
+ t.verticallinemod = 0x02c8;
+ t.vewarmenian = 0x057e;
+ t.vhook = 0x028b;
+ t.vikatakana = 0x30f8;
+ t.viramabengali = 0x09cd;
+ t.viramadeva = 0x094d;
+ t.viramagujarati = 0x0acd;
+ t.visargabengali = 0x0983;
+ t.visargadeva = 0x0903;
+ t.visargagujarati = 0x0a83;
+ t.vmonospace = 0xff56;
+ t.voarmenian = 0x0578;
+ t.voicediterationhiragana = 0x309e;
+ t.voicediterationkatakana = 0x30fe;
+ t.voicedmarkkana = 0x309b;
+ t.voicedmarkkanahalfwidth = 0xff9e;
+ t.vokatakana = 0x30fa;
+ t.vparen = 0x24b1;
+ t.vtilde = 0x1e7d;
+ t.vturned = 0x028c;
+ t.vuhiragana = 0x3094;
+ t.vukatakana = 0x30f4;
+ t.w = 0x0077;
+ t.wacute = 0x1e83;
+ t.waekorean = 0x3159;
+ t.wahiragana = 0x308f;
+ t.wakatakana = 0x30ef;
+ t.wakatakanahalfwidth = 0xff9c;
+ t.wakorean = 0x3158;
+ t.wasmallhiragana = 0x308e;
+ t.wasmallkatakana = 0x30ee;
+ t.wattosquare = 0x3357;
+ t.wavedash = 0x301c;
+ t.wavyunderscorevertical = 0xfe34;
+ t.wawarabic = 0x0648;
+ t.wawfinalarabic = 0xfeee;
+ t.wawhamzaabovearabic = 0x0624;
+ t.wawhamzaabovefinalarabic = 0xfe86;
+ t.wbsquare = 0x33dd;
+ t.wcircle = 0x24e6;
+ t.wcircumflex = 0x0175;
+ t.wdieresis = 0x1e85;
+ t.wdotaccent = 0x1e87;
+ t.wdotbelow = 0x1e89;
+ t.wehiragana = 0x3091;
+ t.weierstrass = 0x2118;
+ t.wekatakana = 0x30f1;
+ t.wekorean = 0x315e;
+ t.weokorean = 0x315d;
+ t.wgrave = 0x1e81;
+ t.whitebullet = 0x25e6;
+ t.whitecircle = 0x25cb;
+ t.whitecircleinverse = 0x25d9;
+ t.whitecornerbracketleft = 0x300e;
+ t.whitecornerbracketleftvertical = 0xfe43;
+ t.whitecornerbracketright = 0x300f;
+ t.whitecornerbracketrightvertical = 0xfe44;
+ t.whitediamond = 0x25c7;
+ t.whitediamondcontainingblacksmalldiamond = 0x25c8;
+ t.whitedownpointingsmalltriangle = 0x25bf;
+ t.whitedownpointingtriangle = 0x25bd;
+ t.whiteleftpointingsmalltriangle = 0x25c3;
+ t.whiteleftpointingtriangle = 0x25c1;
+ t.whitelenticularbracketleft = 0x3016;
+ t.whitelenticularbracketright = 0x3017;
+ t.whiterightpointingsmalltriangle = 0x25b9;
+ t.whiterightpointingtriangle = 0x25b7;
+ t.whitesmallsquare = 0x25ab;
+ t.whitesmilingface = 0x263a;
+ t.whitesquare = 0x25a1;
+ t.whitestar = 0x2606;
+ t.whitetelephone = 0x260f;
+ t.whitetortoiseshellbracketleft = 0x3018;
+ t.whitetortoiseshellbracketright = 0x3019;
+ t.whiteuppointingsmalltriangle = 0x25b5;
+ t.whiteuppointingtriangle = 0x25b3;
+ t.wihiragana = 0x3090;
+ t.wikatakana = 0x30f0;
+ t.wikorean = 0x315f;
+ t.wmonospace = 0xff57;
+ t.wohiragana = 0x3092;
+ t.wokatakana = 0x30f2;
+ t.wokatakanahalfwidth = 0xff66;
+ t.won = 0x20a9;
+ t.wonmonospace = 0xffe6;
+ t.wowaenthai = 0x0e27;
+ t.wparen = 0x24b2;
+ t.wring = 0x1e98;
+ t.wsuperior = 0x02b7;
+ t.wturned = 0x028d;
+ t.wynn = 0x01bf;
+ t.x = 0x0078;
+ t.xabovecmb = 0x033d;
+ t.xbopomofo = 0x3112;
+ t.xcircle = 0x24e7;
+ t.xdieresis = 0x1e8d;
+ t.xdotaccent = 0x1e8b;
+ t.xeharmenian = 0x056d;
+ t.xi = 0x03be;
+ t.xmonospace = 0xff58;
+ t.xparen = 0x24b3;
+ t.xsuperior = 0x02e3;
+ t.y = 0x0079;
+ t.yaadosquare = 0x334e;
+ t.yabengali = 0x09af;
+ t.yacute = 0x00fd;
+ t.yadeva = 0x092f;
+ t.yaekorean = 0x3152;
+ t.yagujarati = 0x0aaf;
+ t.yagurmukhi = 0x0a2f;
+ t.yahiragana = 0x3084;
+ t.yakatakana = 0x30e4;
+ t.yakatakanahalfwidth = 0xff94;
+ t.yakorean = 0x3151;
+ t.yamakkanthai = 0x0e4e;
+ t.yasmallhiragana = 0x3083;
+ t.yasmallkatakana = 0x30e3;
+ t.yasmallkatakanahalfwidth = 0xff6c;
+ t.yatcyrillic = 0x0463;
+ t.ycircle = 0x24e8;
+ t.ycircumflex = 0x0177;
+ t.ydieresis = 0x00ff;
+ t.ydotaccent = 0x1e8f;
+ t.ydotbelow = 0x1ef5;
+ t.yeharabic = 0x064a;
+ t.yehbarreearabic = 0x06d2;
+ t.yehbarreefinalarabic = 0xfbaf;
+ t.yehfinalarabic = 0xfef2;
+ t.yehhamzaabovearabic = 0x0626;
+ t.yehhamzaabovefinalarabic = 0xfe8a;
+ t.yehhamzaaboveinitialarabic = 0xfe8b;
+ t.yehhamzaabovemedialarabic = 0xfe8c;
+ t.yehinitialarabic = 0xfef3;
+ t.yehmedialarabic = 0xfef4;
+ t.yehmeeminitialarabic = 0xfcdd;
+ t.yehmeemisolatedarabic = 0xfc58;
+ t.yehnoonfinalarabic = 0xfc94;
+ t.yehthreedotsbelowarabic = 0x06d1;
+ t.yekorean = 0x3156;
+ t.yen = 0x00a5;
+ t.yenmonospace = 0xffe5;
+ t.yeokorean = 0x3155;
+ t.yeorinhieuhkorean = 0x3186;
+ t.yerahbenyomohebrew = 0x05aa;
+ t.yerahbenyomolefthebrew = 0x05aa;
+ t.yericyrillic = 0x044b;
+ t.yerudieresiscyrillic = 0x04f9;
+ t.yesieungkorean = 0x3181;
+ t.yesieungpansioskorean = 0x3183;
+ t.yesieungsioskorean = 0x3182;
+ t.yetivhebrew = 0x059a;
+ t.ygrave = 0x1ef3;
+ t.yhook = 0x01b4;
+ t.yhookabove = 0x1ef7;
+ t.yiarmenian = 0x0575;
+ t.yicyrillic = 0x0457;
+ t.yikorean = 0x3162;
+ t.yinyang = 0x262f;
+ t.yiwnarmenian = 0x0582;
+ t.ymonospace = 0xff59;
+ t.yod = 0x05d9;
+ t.yoddagesh = 0xfb39;
+ t.yoddageshhebrew = 0xfb39;
+ t.yodhebrew = 0x05d9;
+ t.yodyodhebrew = 0x05f2;
+ t.yodyodpatahhebrew = 0xfb1f;
+ t.yohiragana = 0x3088;
+ t.yoikorean = 0x3189;
+ t.yokatakana = 0x30e8;
+ t.yokatakanahalfwidth = 0xff96;
+ t.yokorean = 0x315b;
+ t.yosmallhiragana = 0x3087;
+ t.yosmallkatakana = 0x30e7;
+ t.yosmallkatakanahalfwidth = 0xff6e;
+ t.yotgreek = 0x03f3;
+ t.yoyaekorean = 0x3188;
+ t.yoyakorean = 0x3187;
+ t.yoyakthai = 0x0e22;
+ t.yoyingthai = 0x0e0d;
+ t.yparen = 0x24b4;
+ t.ypogegrammeni = 0x037a;
+ t.ypogegrammenigreekcmb = 0x0345;
+ t.yr = 0x01a6;
+ t.yring = 0x1e99;
+ t.ysuperior = 0x02b8;
+ t.ytilde = 0x1ef9;
+ t.yturned = 0x028e;
+ t.yuhiragana = 0x3086;
+ t.yuikorean = 0x318c;
+ t.yukatakana = 0x30e6;
+ t.yukatakanahalfwidth = 0xff95;
+ t.yukorean = 0x3160;
+ t.yusbigcyrillic = 0x046b;
+ t.yusbigiotifiedcyrillic = 0x046d;
+ t.yuslittlecyrillic = 0x0467;
+ t.yuslittleiotifiedcyrillic = 0x0469;
+ t.yusmallhiragana = 0x3085;
+ t.yusmallkatakana = 0x30e5;
+ t.yusmallkatakanahalfwidth = 0xff6d;
+ t.yuyekorean = 0x318b;
+ t.yuyeokorean = 0x318a;
+ t.yyabengali = 0x09df;
+ t.yyadeva = 0x095f;
+ t.z = 0x007a;
+ t.zaarmenian = 0x0566;
+ t.zacute = 0x017a;
+ t.zadeva = 0x095b;
+ t.zagurmukhi = 0x0a5b;
+ t.zaharabic = 0x0638;
+ t.zahfinalarabic = 0xfec6;
+ t.zahinitialarabic = 0xfec7;
+ t.zahiragana = 0x3056;
+ t.zahmedialarabic = 0xfec8;
+ t.zainarabic = 0x0632;
+ t.zainfinalarabic = 0xfeb0;
+ t.zakatakana = 0x30b6;
+ t.zaqefgadolhebrew = 0x0595;
+ t.zaqefqatanhebrew = 0x0594;
+ t.zarqahebrew = 0x0598;
+ t.zayin = 0x05d6;
+ t.zayindagesh = 0xfb36;
+ t.zayindageshhebrew = 0xfb36;
+ t.zayinhebrew = 0x05d6;
+ t.zbopomofo = 0x3117;
+ t.zcaron = 0x017e;
+ t.zcircle = 0x24e9;
+ t.zcircumflex = 0x1e91;
+ t.zcurl = 0x0291;
+ t.zdot = 0x017c;
+ t.zdotaccent = 0x017c;
+ t.zdotbelow = 0x1e93;
+ t.zecyrillic = 0x0437;
+ t.zedescendercyrillic = 0x0499;
+ t.zedieresiscyrillic = 0x04df;
+ t.zehiragana = 0x305c;
+ t.zekatakana = 0x30bc;
+ t.zero = 0x0030;
+ t.zeroarabic = 0x0660;
+ t.zerobengali = 0x09e6;
+ t.zerodeva = 0x0966;
+ t.zerogujarati = 0x0ae6;
+ t.zerogurmukhi = 0x0a66;
+ t.zerohackarabic = 0x0660;
+ t.zeroinferior = 0x2080;
+ t.zeromonospace = 0xff10;
+ t.zerooldstyle = 0xf730;
+ t.zeropersian = 0x06f0;
+ t.zerosuperior = 0x2070;
+ t.zerothai = 0x0e50;
+ t.zerowidthjoiner = 0xfeff;
+ t.zerowidthnonjoiner = 0x200c;
+ t.zerowidthspace = 0x200b;
+ t.zeta = 0x03b6;
+ t.zhbopomofo = 0x3113;
+ t.zhearmenian = 0x056a;
+ t.zhebrevecyrillic = 0x04c2;
+ t.zhecyrillic = 0x0436;
+ t.zhedescendercyrillic = 0x0497;
+ t.zhedieresiscyrillic = 0x04dd;
+ t.zihiragana = 0x3058;
+ t.zikatakana = 0x30b8;
+ t.zinorhebrew = 0x05ae;
+ t.zlinebelow = 0x1e95;
+ t.zmonospace = 0xff5a;
+ t.zohiragana = 0x305e;
+ t.zokatakana = 0x30be;
+ t.zparen = 0x24b5;
+ t.zretroflexhook = 0x0290;
+ t.zstroke = 0x01b6;
+ t.zuhiragana = 0x305a;
+ t.zukatakana = 0x30ba;
+ t[".notdef"] = 0x0000;
+ t.angbracketleftbig = 0x2329;
+ t.angbracketleftBig = 0x2329;
+ t.angbracketleftbigg = 0x2329;
+ t.angbracketleftBigg = 0x2329;
+ t.angbracketrightBig = 0x232a;
+ t.angbracketrightbig = 0x232a;
+ t.angbracketrightBigg = 0x232a;
+ t.angbracketrightbigg = 0x232a;
+ t.arrowhookleft = 0x21aa;
+ t.arrowhookright = 0x21a9;
+ t.arrowlefttophalf = 0x21bc;
+ t.arrowleftbothalf = 0x21bd;
+ t.arrownortheast = 0x2197;
+ t.arrownorthwest = 0x2196;
+ t.arrowrighttophalf = 0x21c0;
+ t.arrowrightbothalf = 0x21c1;
+ t.arrowsoutheast = 0x2198;
+ t.arrowsouthwest = 0x2199;
+ t.backslashbig = 0x2216;
+ t.backslashBig = 0x2216;
+ t.backslashBigg = 0x2216;
+ t.backslashbigg = 0x2216;
+ t.bardbl = 0x2016;
+ t.bracehtipdownleft = 0xfe37;
+ t.bracehtipdownright = 0xfe37;
+ t.bracehtipupleft = 0xfe38;
+ t.bracehtipupright = 0xfe38;
+ t.braceleftBig = 0x007b;
+ t.braceleftbig = 0x007b;
+ t.braceleftbigg = 0x007b;
+ t.braceleftBigg = 0x007b;
+ t.bracerightBig = 0x007d;
+ t.bracerightbig = 0x007d;
+ t.bracerightbigg = 0x007d;
+ t.bracerightBigg = 0x007d;
+ t.bracketleftbig = 0x005b;
+ t.bracketleftBig = 0x005b;
+ t.bracketleftbigg = 0x005b;
+ t.bracketleftBigg = 0x005b;
+ t.bracketrightBig = 0x005d;
+ t.bracketrightbig = 0x005d;
+ t.bracketrightbigg = 0x005d;
+ t.bracketrightBigg = 0x005d;
+ t.ceilingleftbig = 0x2308;
+ t.ceilingleftBig = 0x2308;
+ t.ceilingleftBigg = 0x2308;
+ t.ceilingleftbigg = 0x2308;
+ t.ceilingrightbig = 0x2309;
+ t.ceilingrightBig = 0x2309;
+ t.ceilingrightbigg = 0x2309;
+ t.ceilingrightBigg = 0x2309;
+ t.circledotdisplay = 0x2299;
+ t.circledottext = 0x2299;
+ t.circlemultiplydisplay = 0x2297;
+ t.circlemultiplytext = 0x2297;
+ t.circleplusdisplay = 0x2295;
+ t.circleplustext = 0x2295;
+ t.contintegraldisplay = 0x222e;
+ t.contintegraltext = 0x222e;
+ t.coproductdisplay = 0x2210;
+ t.coproducttext = 0x2210;
+ t.floorleftBig = 0x230a;
+ t.floorleftbig = 0x230a;
+ t.floorleftbigg = 0x230a;
+ t.floorleftBigg = 0x230a;
+ t.floorrightbig = 0x230b;
+ t.floorrightBig = 0x230b;
+ t.floorrightBigg = 0x230b;
+ t.floorrightbigg = 0x230b;
+ t.hatwide = 0x0302;
+ t.hatwider = 0x0302;
+ t.hatwidest = 0x0302;
+ t.intercal = 0x1d40;
+ t.integraldisplay = 0x222b;
+ t.integraltext = 0x222b;
+ t.intersectiondisplay = 0x22c2;
+ t.intersectiontext = 0x22c2;
+ t.logicalanddisplay = 0x2227;
+ t.logicalandtext = 0x2227;
+ t.logicalordisplay = 0x2228;
+ t.logicalortext = 0x2228;
+ t.parenleftBig = 0x0028;
+ t.parenleftbig = 0x0028;
+ t.parenleftBigg = 0x0028;
+ t.parenleftbigg = 0x0028;
+ t.parenrightBig = 0x0029;
+ t.parenrightbig = 0x0029;
+ t.parenrightBigg = 0x0029;
+ t.parenrightbigg = 0x0029;
+ t.prime = 0x2032;
+ t.productdisplay = 0x220f;
+ t.producttext = 0x220f;
+ t.radicalbig = 0x221a;
+ t.radicalBig = 0x221a;
+ t.radicalBigg = 0x221a;
+ t.radicalbigg = 0x221a;
+ t.radicalbt = 0x221a;
+ t.radicaltp = 0x221a;
+ t.radicalvertex = 0x221a;
+ t.slashbig = 0x002f;
+ t.slashBig = 0x002f;
+ t.slashBigg = 0x002f;
+ t.slashbigg = 0x002f;
+ t.summationdisplay = 0x2211;
+ t.summationtext = 0x2211;
+ t.tildewide = 0x02dc;
+ t.tildewider = 0x02dc;
+ t.tildewidest = 0x02dc;
+ t.uniondisplay = 0x22c3;
+ t.unionmultidisplay = 0x228e;
+ t.unionmultitext = 0x228e;
+ t.unionsqdisplay = 0x2294;
+ t.unionsqtext = 0x2294;
+ t.uniontext = 0x22c3;
+ t.vextenddouble = 0x2225;
+ t.vextendsingle = 0x2223;
+});
+const getDingbatsGlyphsUnicode = getLookupTableFactory(function (t) {
+ t.space = 0x0020;
+ t.a1 = 0x2701;
+ t.a2 = 0x2702;
+ t.a202 = 0x2703;
+ t.a3 = 0x2704;
+ t.a4 = 0x260e;
+ t.a5 = 0x2706;
+ t.a119 = 0x2707;
+ t.a118 = 0x2708;
+ t.a117 = 0x2709;
+ t.a11 = 0x261b;
+ t.a12 = 0x261e;
+ t.a13 = 0x270c;
+ t.a14 = 0x270d;
+ t.a15 = 0x270e;
+ t.a16 = 0x270f;
+ t.a105 = 0x2710;
+ t.a17 = 0x2711;
+ t.a18 = 0x2712;
+ t.a19 = 0x2713;
+ t.a20 = 0x2714;
+ t.a21 = 0x2715;
+ t.a22 = 0x2716;
+ t.a23 = 0x2717;
+ t.a24 = 0x2718;
+ t.a25 = 0x2719;
+ t.a26 = 0x271a;
+ t.a27 = 0x271b;
+ t.a28 = 0x271c;
+ t.a6 = 0x271d;
+ t.a7 = 0x271e;
+ t.a8 = 0x271f;
+ t.a9 = 0x2720;
+ t.a10 = 0x2721;
+ t.a29 = 0x2722;
+ t.a30 = 0x2723;
+ t.a31 = 0x2724;
+ t.a32 = 0x2725;
+ t.a33 = 0x2726;
+ t.a34 = 0x2727;
+ t.a35 = 0x2605;
+ t.a36 = 0x2729;
+ t.a37 = 0x272a;
+ t.a38 = 0x272b;
+ t.a39 = 0x272c;
+ t.a40 = 0x272d;
+ t.a41 = 0x272e;
+ t.a42 = 0x272f;
+ t.a43 = 0x2730;
+ t.a44 = 0x2731;
+ t.a45 = 0x2732;
+ t.a46 = 0x2733;
+ t.a47 = 0x2734;
+ t.a48 = 0x2735;
+ t.a49 = 0x2736;
+ t.a50 = 0x2737;
+ t.a51 = 0x2738;
+ t.a52 = 0x2739;
+ t.a53 = 0x273a;
+ t.a54 = 0x273b;
+ t.a55 = 0x273c;
+ t.a56 = 0x273d;
+ t.a57 = 0x273e;
+ t.a58 = 0x273f;
+ t.a59 = 0x2740;
+ t.a60 = 0x2741;
+ t.a61 = 0x2742;
+ t.a62 = 0x2743;
+ t.a63 = 0x2744;
+ t.a64 = 0x2745;
+ t.a65 = 0x2746;
+ t.a66 = 0x2747;
+ t.a67 = 0x2748;
+ t.a68 = 0x2749;
+ t.a69 = 0x274a;
+ t.a70 = 0x274b;
+ t.a71 = 0x25cf;
+ t.a72 = 0x274d;
+ t.a73 = 0x25a0;
+ t.a74 = 0x274f;
+ t.a203 = 0x2750;
+ t.a75 = 0x2751;
+ t.a204 = 0x2752;
+ t.a76 = 0x25b2;
+ t.a77 = 0x25bc;
+ t.a78 = 0x25c6;
+ t.a79 = 0x2756;
+ t.a81 = 0x25d7;
+ t.a82 = 0x2758;
+ t.a83 = 0x2759;
+ t.a84 = 0x275a;
+ t.a97 = 0x275b;
+ t.a98 = 0x275c;
+ t.a99 = 0x275d;
+ t.a100 = 0x275e;
+ t.a101 = 0x2761;
+ t.a102 = 0x2762;
+ t.a103 = 0x2763;
+ t.a104 = 0x2764;
+ t.a106 = 0x2765;
+ t.a107 = 0x2766;
+ t.a108 = 0x2767;
+ t.a112 = 0x2663;
+ t.a111 = 0x2666;
+ t.a110 = 0x2665;
+ t.a109 = 0x2660;
+ t.a120 = 0x2460;
+ t.a121 = 0x2461;
+ t.a122 = 0x2462;
+ t.a123 = 0x2463;
+ t.a124 = 0x2464;
+ t.a125 = 0x2465;
+ t.a126 = 0x2466;
+ t.a127 = 0x2467;
+ t.a128 = 0x2468;
+ t.a129 = 0x2469;
+ t.a130 = 0x2776;
+ t.a131 = 0x2777;
+ t.a132 = 0x2778;
+ t.a133 = 0x2779;
+ t.a134 = 0x277a;
+ t.a135 = 0x277b;
+ t.a136 = 0x277c;
+ t.a137 = 0x277d;
+ t.a138 = 0x277e;
+ t.a139 = 0x277f;
+ t.a140 = 0x2780;
+ t.a141 = 0x2781;
+ t.a142 = 0x2782;
+ t.a143 = 0x2783;
+ t.a144 = 0x2784;
+ t.a145 = 0x2785;
+ t.a146 = 0x2786;
+ t.a147 = 0x2787;
+ t.a148 = 0x2788;
+ t.a149 = 0x2789;
+ t.a150 = 0x278a;
+ t.a151 = 0x278b;
+ t.a152 = 0x278c;
+ t.a153 = 0x278d;
+ t.a154 = 0x278e;
+ t.a155 = 0x278f;
+ t.a156 = 0x2790;
+ t.a157 = 0x2791;
+ t.a158 = 0x2792;
+ t.a159 = 0x2793;
+ t.a160 = 0x2794;
+ t.a161 = 0x2192;
+ t.a163 = 0x2194;
+ t.a164 = 0x2195;
+ t.a196 = 0x2798;
+ t.a165 = 0x2799;
+ t.a192 = 0x279a;
+ t.a166 = 0x279b;
+ t.a167 = 0x279c;
+ t.a168 = 0x279d;
+ t.a169 = 0x279e;
+ t.a170 = 0x279f;
+ t.a171 = 0x27a0;
+ t.a172 = 0x27a1;
+ t.a173 = 0x27a2;
+ t.a162 = 0x27a3;
+ t.a174 = 0x27a4;
+ t.a175 = 0x27a5;
+ t.a176 = 0x27a6;
+ t.a177 = 0x27a7;
+ t.a178 = 0x27a8;
+ t.a179 = 0x27a9;
+ t.a193 = 0x27aa;
+ t.a180 = 0x27ab;
+ t.a199 = 0x27ac;
+ t.a181 = 0x27ad;
+ t.a200 = 0x27ae;
+ t.a182 = 0x27af;
+ t.a201 = 0x27b1;
+ t.a183 = 0x27b2;
+ t.a184 = 0x27b3;
+ t.a197 = 0x27b4;
+ t.a185 = 0x27b5;
+ t.a194 = 0x27b6;
+ t.a198 = 0x27b7;
+ t.a186 = 0x27b8;
+ t.a195 = 0x27b9;
+ t.a187 = 0x27ba;
+ t.a188 = 0x27bb;
+ t.a189 = 0x27bc;
+ t.a190 = 0x27bd;
+ t.a191 = 0x27be;
+ t.a89 = 0x2768;
+ t.a90 = 0x2769;
+ t.a93 = 0x276a;
+ t.a94 = 0x276b;
+ t.a91 = 0x276c;
+ t.a92 = 0x276d;
+ t.a205 = 0x276e;
+ t.a85 = 0x276f;
+ t.a206 = 0x2770;
+ t.a86 = 0x2771;
+ t.a87 = 0x2772;
+ t.a88 = 0x2773;
+ t.a95 = 0x2774;
+ t.a96 = 0x2775;
+ t[".notdef"] = 0x0000;
+});
+
+;// CONCATENATED MODULE: ./src/core/unicode.js
+
+const getSpecialPUASymbols = getLookupTableFactory(function (t) {
+ t[63721] = 0x00a9;
+ t[63193] = 0x00a9;
+ t[63720] = 0x00ae;
+ t[63194] = 0x00ae;
+ t[63722] = 0x2122;
+ t[63195] = 0x2122;
+ t[63729] = 0x23a7;
+ t[63730] = 0x23a8;
+ t[63731] = 0x23a9;
+ t[63740] = 0x23ab;
+ t[63741] = 0x23ac;
+ t[63742] = 0x23ad;
+ t[63726] = 0x23a1;
+ t[63727] = 0x23a2;
+ t[63728] = 0x23a3;
+ t[63737] = 0x23a4;
+ t[63738] = 0x23a5;
+ t[63739] = 0x23a6;
+ t[63723] = 0x239b;
+ t[63724] = 0x239c;
+ t[63725] = 0x239d;
+ t[63734] = 0x239e;
+ t[63735] = 0x239f;
+ t[63736] = 0x23a0;
+});
+function mapSpecialUnicodeValues(code) {
+ if (code >= 0xfff0 && code <= 0xffff) {
+ return 0;
+ } else if (code >= 0xf600 && code <= 0xf8ff) {
+ return getSpecialPUASymbols()[code] || code;
+ } else if (code === 0x00ad) {
+ return 0x002d;
+ }
+ return code;
+}
+function getUnicodeForGlyph(name, glyphsUnicodeMap) {
+ let unicode = glyphsUnicodeMap[name];
+ if (unicode !== undefined) {
+ return unicode;
+ }
+ if (!name) {
+ return -1;
+ }
+ if (name[0] === "u") {
+ const nameLen = name.length;
+ let hexStr;
+ if (nameLen === 7 && name[1] === "n" && name[2] === "i") {
+ hexStr = name.substring(3);
+ } else if (nameLen >= 5 && nameLen <= 7) {
+ hexStr = name.substring(1);
+ } else {
+ return -1;
+ }
+ if (hexStr === hexStr.toUpperCase()) {
+ unicode = parseInt(hexStr, 16);
+ if (unicode >= 0) {
+ return unicode;
+ }
+ }
+ }
+ return -1;
+}
+const UnicodeRanges = [[0x0000, 0x007f], [0x0080, 0x00ff], [0x0100, 0x017f], [0x0180, 0x024f], [0x0250, 0x02af, 0x1d00, 0x1d7f, 0x1d80, 0x1dbf], [0x02b0, 0x02ff, 0xa700, 0xa71f], [0x0300, 0x036f, 0x1dc0, 0x1dff], [0x0370, 0x03ff], [0x2c80, 0x2cff], [0x0400, 0x04ff, 0x0500, 0x052f, 0x2de0, 0x2dff, 0xa640, 0xa69f], [0x0530, 0x058f], [0x0590, 0x05ff], [0xa500, 0xa63f], [0x0600, 0x06ff, 0x0750, 0x077f], [0x07c0, 0x07ff], [0x0900, 0x097f], [0x0980, 0x09ff], [0x0a00, 0x0a7f], [0x0a80, 0x0aff], [0x0b00, 0x0b7f], [0x0b80, 0x0bff], [0x0c00, 0x0c7f], [0x0c80, 0x0cff], [0x0d00, 0x0d7f], [0x0e00, 0x0e7f], [0x0e80, 0x0eff], [0x10a0, 0x10ff, 0x2d00, 0x2d2f], [0x1b00, 0x1b7f], [0x1100, 0x11ff], [0x1e00, 0x1eff, 0x2c60, 0x2c7f, 0xa720, 0xa7ff], [0x1f00, 0x1fff], [0x2000, 0x206f, 0x2e00, 0x2e7f], [0x2070, 0x209f], [0x20a0, 0x20cf], [0x20d0, 0x20ff], [0x2100, 0x214f], [0x2150, 0x218f], [0x2190, 0x21ff, 0x27f0, 0x27ff, 0x2900, 0x297f, 0x2b00, 0x2bff], [0x2200, 0x22ff, 0x2a00, 0x2aff, 0x27c0, 0x27ef, 0x2980, 0x29ff], [0x2300, 0x23ff], [0x2400, 0x243f], [0x2440, 0x245f], [0x2460, 0x24ff], [0x2500, 0x257f], [0x2580, 0x259f], [0x25a0, 0x25ff], [0x2600, 0x26ff], [0x2700, 0x27bf], [0x3000, 0x303f], [0x3040, 0x309f], [0x30a0, 0x30ff, 0x31f0, 0x31ff], [0x3100, 0x312f, 0x31a0, 0x31bf], [0x3130, 0x318f], [0xa840, 0xa87f], [0x3200, 0x32ff], [0x3300, 0x33ff], [0xac00, 0xd7af], [0xd800, 0xdfff], [0x10900, 0x1091f], [0x4e00, 0x9fff, 0x2e80, 0x2eff, 0x2f00, 0x2fdf, 0x2ff0, 0x2fff, 0x3400, 0x4dbf, 0x20000, 0x2a6df, 0x3190, 0x319f], [0xe000, 0xf8ff], [0x31c0, 0x31ef, 0xf900, 0xfaff, 0x2f800, 0x2fa1f], [0xfb00, 0xfb4f], [0xfb50, 0xfdff], [0xfe20, 0xfe2f], [0xfe10, 0xfe1f], [0xfe50, 0xfe6f], [0xfe70, 0xfeff], [0xff00, 0xffef], [0xfff0, 0xffff], [0x0f00, 0x0fff], [0x0700, 0x074f], [0x0780, 0x07bf], [0x0d80, 0x0dff], [0x1000, 0x109f], [0x1200, 0x137f, 0x1380, 0x139f, 0x2d80, 0x2ddf], [0x13a0, 0x13ff], [0x1400, 0x167f], [0x1680, 0x169f], [0x16a0, 0x16ff], [0x1780, 0x17ff], [0x1800, 0x18af], [0x2800, 0x28ff], [0xa000, 0xa48f], [0x1700, 0x171f, 0x1720, 0x173f, 0x1740, 0x175f, 0x1760, 0x177f], [0x10300, 0x1032f], [0x10330, 0x1034f], [0x10400, 0x1044f], [0x1d000, 0x1d0ff, 0x1d100, 0x1d1ff, 0x1d200, 0x1d24f], [0x1d400, 0x1d7ff], [0xff000, 0xffffd], [0xfe00, 0xfe0f, 0xe0100, 0xe01ef], [0xe0000, 0xe007f], [0x1900, 0x194f], [0x1950, 0x197f], [0x1980, 0x19df], [0x1a00, 0x1a1f], [0x2c00, 0x2c5f], [0x2d30, 0x2d7f], [0x4dc0, 0x4dff], [0xa800, 0xa82f], [0x10000, 0x1007f, 0x10080, 0x100ff, 0x10100, 0x1013f], [0x10140, 0x1018f], [0x10380, 0x1039f], [0x103a0, 0x103df], [0x10450, 0x1047f], [0x10480, 0x104af], [0x10800, 0x1083f], [0x10a00, 0x10a5f], [0x1d300, 0x1d35f], [0x12000, 0x123ff, 0x12400, 0x1247f], [0x1d360, 0x1d37f], [0x1b80, 0x1bbf], [0x1c00, 0x1c4f], [0x1c50, 0x1c7f], [0xa880, 0xa8df], [0xa900, 0xa92f], [0xa930, 0xa95f], [0xaa00, 0xaa5f], [0x10190, 0x101cf], [0x101d0, 0x101ff], [0x102a0, 0x102df, 0x10280, 0x1029f, 0x10920, 0x1093f], [0x1f030, 0x1f09f, 0x1f000, 0x1f02f]];
+function getUnicodeRangeFor(value, lastPosition = -1) {
+ if (lastPosition !== -1) {
+ const range = UnicodeRanges[lastPosition];
+ for (let i = 0, ii = range.length; i < ii; i += 2) {
+ if (value >= range[i] && value <= range[i + 1]) {
+ return lastPosition;
+ }
+ }
+ }
+ for (let i = 0, ii = UnicodeRanges.length; i < ii; i++) {
+ const range = UnicodeRanges[i];
+ for (let j = 0, jj = range.length; j < jj; j += 2) {
+ if (value >= range[j] && value <= range[j + 1]) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+const SpecialCharRegExp = new RegExp("^(\\s)|(\\p{Mn})|(\\p{Cf})$", "u");
+const CategoryCache = new Map();
+function getCharUnicodeCategory(char) {
+ const cachedCategory = CategoryCache.get(char);
+ if (cachedCategory) {
+ return cachedCategory;
+ }
+ const groups = char.match(SpecialCharRegExp);
+ const category = {
+ isWhitespace: !!groups?.[1],
+ isZeroWidthDiacritic: !!groups?.[2],
+ isInvisibleFormatMark: !!groups?.[3]
+ };
+ CategoryCache.set(char, category);
+ return category;
+}
+function clearUnicodeCaches() {
+ CategoryCache.clear();
+}
+
+;// CONCATENATED MODULE: ./src/core/fonts_utils.js
+
+
+
+
+const SEAC_ANALYSIS_ENABLED = true;
+const FontFlags = {
+ FixedPitch: 1,
+ Serif: 2,
+ Symbolic: 4,
+ Script: 8,
+ Nonsymbolic: 32,
+ Italic: 64,
+ AllCap: 65536,
+ SmallCap: 131072,
+ ForceBold: 262144
+};
+const MacStandardGlyphOrdering = [".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat"];
+function recoverGlyphName(name, glyphsUnicodeMap) {
+ if (glyphsUnicodeMap[name] !== undefined) {
+ return name;
+ }
+ const unicode = getUnicodeForGlyph(name, glyphsUnicodeMap);
+ if (unicode !== -1) {
+ for (const key in glyphsUnicodeMap) {
+ if (glyphsUnicodeMap[key] === unicode) {
+ return key;
+ }
+ }
+ }
+ info("Unable to recover a standard glyph name for: " + name);
+ return name;
+}
+function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
+ const charCodeToGlyphId = Object.create(null);
+ let glyphId, charCode, baseEncoding;
+ const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
+ if (properties.isInternalFont) {
+ baseEncoding = builtInEncoding;
+ for (charCode = 0; charCode < baseEncoding.length; charCode++) {
+ glyphId = glyphNames.indexOf(baseEncoding[charCode]);
+ charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;
+ }
+ } else if (properties.baseEncodingName) {
+ baseEncoding = getEncoding(properties.baseEncodingName);
+ for (charCode = 0; charCode < baseEncoding.length; charCode++) {
+ glyphId = glyphNames.indexOf(baseEncoding[charCode]);
+ charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;
+ }
+ } else if (isSymbolicFont) {
+ for (charCode in builtInEncoding) {
+ charCodeToGlyphId[charCode] = builtInEncoding[charCode];
+ }
+ } else {
+ baseEncoding = StandardEncoding;
+ for (charCode = 0; charCode < baseEncoding.length; charCode++) {
+ glyphId = glyphNames.indexOf(baseEncoding[charCode]);
+ charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;
+ }
+ }
+ const differences = properties.differences;
+ let glyphsUnicodeMap;
+ if (differences) {
+ for (charCode in differences) {
+ const glyphName = differences[charCode];
+ glyphId = glyphNames.indexOf(glyphName);
+ if (glyphId === -1) {
+ if (!glyphsUnicodeMap) {
+ glyphsUnicodeMap = getGlyphsUnicode();
+ }
+ const standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);
+ if (standardGlyphName !== glyphName) {
+ glyphId = glyphNames.indexOf(standardGlyphName);
+ }
+ }
+ charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0;
+ }
+ }
+ return charCodeToGlyphId;
+}
+function normalizeFontName(name) {
+ return name.replaceAll(/[,_]/g, "-").replaceAll(/\s/g, "");
+}
+
+;// CONCATENATED MODULE: ./src/core/standard_fonts.js
+
+
+const getStdFontMap = getLookupTableFactory(function (t) {
+ t["Times-Roman"] = "Times-Roman";
+ t.Helvetica = "Helvetica";
+ t.Courier = "Courier";
+ t.Symbol = "Symbol";
+ t["Times-Bold"] = "Times-Bold";
+ t["Helvetica-Bold"] = "Helvetica-Bold";
+ t["Courier-Bold"] = "Courier-Bold";
+ t.ZapfDingbats = "ZapfDingbats";
+ t["Times-Italic"] = "Times-Italic";
+ t["Helvetica-Oblique"] = "Helvetica-Oblique";
+ t["Courier-Oblique"] = "Courier-Oblique";
+ t["Times-BoldItalic"] = "Times-BoldItalic";
+ t["Helvetica-BoldOblique"] = "Helvetica-BoldOblique";
+ t["Courier-BoldOblique"] = "Courier-BoldOblique";
+ t.ArialNarrow = "Helvetica";
+ t["ArialNarrow-Bold"] = "Helvetica-Bold";
+ t["ArialNarrow-BoldItalic"] = "Helvetica-BoldOblique";
+ t["ArialNarrow-Italic"] = "Helvetica-Oblique";
+ t.ArialBlack = "Helvetica";
+ t["ArialBlack-Bold"] = "Helvetica-Bold";
+ t["ArialBlack-BoldItalic"] = "Helvetica-BoldOblique";
+ t["ArialBlack-Italic"] = "Helvetica-Oblique";
+ t["Arial-Black"] = "Helvetica";
+ t["Arial-Black-Bold"] = "Helvetica-Bold";
+ t["Arial-Black-BoldItalic"] = "Helvetica-BoldOblique";
+ t["Arial-Black-Italic"] = "Helvetica-Oblique";
+ t.Arial = "Helvetica";
+ t["Arial-Bold"] = "Helvetica-Bold";
+ t["Arial-BoldItalic"] = "Helvetica-BoldOblique";
+ t["Arial-Italic"] = "Helvetica-Oblique";
+ t.ArialMT = "Helvetica";
+ t["Arial-BoldItalicMT"] = "Helvetica-BoldOblique";
+ t["Arial-BoldMT"] = "Helvetica-Bold";
+ t["Arial-ItalicMT"] = "Helvetica-Oblique";
+ t["Arial-BoldItalicMT-BoldItalic"] = "Helvetica-BoldOblique";
+ t["Arial-BoldMT-Bold"] = "Helvetica-Bold";
+ t["Arial-ItalicMT-Italic"] = "Helvetica-Oblique";
+ t.ArialUnicodeMS = "Helvetica";
+ t["ArialUnicodeMS-Bold"] = "Helvetica-Bold";
+ t["ArialUnicodeMS-BoldItalic"] = "Helvetica-BoldOblique";
+ t["ArialUnicodeMS-Italic"] = "Helvetica-Oblique";
+ t["Courier-BoldItalic"] = "Courier-BoldOblique";
+ t["Courier-Italic"] = "Courier-Oblique";
+ t.CourierNew = "Courier";
+ t["CourierNew-Bold"] = "Courier-Bold";
+ t["CourierNew-BoldItalic"] = "Courier-BoldOblique";
+ t["CourierNew-Italic"] = "Courier-Oblique";
+ t["CourierNewPS-BoldItalicMT"] = "Courier-BoldOblique";
+ t["CourierNewPS-BoldMT"] = "Courier-Bold";
+ t["CourierNewPS-ItalicMT"] = "Courier-Oblique";
+ t.CourierNewPSMT = "Courier";
+ t["Helvetica-BoldItalic"] = "Helvetica-BoldOblique";
+ t["Helvetica-Italic"] = "Helvetica-Oblique";
+ t["Symbol-Bold"] = "Symbol";
+ t["Symbol-BoldItalic"] = "Symbol";
+ t["Symbol-Italic"] = "Symbol";
+ t.TimesNewRoman = "Times-Roman";
+ t["TimesNewRoman-Bold"] = "Times-Bold";
+ t["TimesNewRoman-BoldItalic"] = "Times-BoldItalic";
+ t["TimesNewRoman-Italic"] = "Times-Italic";
+ t.TimesNewRomanPS = "Times-Roman";
+ t["TimesNewRomanPS-Bold"] = "Times-Bold";
+ t["TimesNewRomanPS-BoldItalic"] = "Times-BoldItalic";
+ t["TimesNewRomanPS-BoldItalicMT"] = "Times-BoldItalic";
+ t["TimesNewRomanPS-BoldMT"] = "Times-Bold";
+ t["TimesNewRomanPS-Italic"] = "Times-Italic";
+ t["TimesNewRomanPS-ItalicMT"] = "Times-Italic";
+ t.TimesNewRomanPSMT = "Times-Roman";
+ t["TimesNewRomanPSMT-Bold"] = "Times-Bold";
+ t["TimesNewRomanPSMT-BoldItalic"] = "Times-BoldItalic";
+ t["TimesNewRomanPSMT-Italic"] = "Times-Italic";
+});
+const getFontNameToFileMap = getLookupTableFactory(function (t) {
+ t.Courier = "FoxitFixed.pfb";
+ t["Courier-Bold"] = "FoxitFixedBold.pfb";
+ t["Courier-BoldOblique"] = "FoxitFixedBoldItalic.pfb";
+ t["Courier-Oblique"] = "FoxitFixedItalic.pfb";
+ t.Helvetica = "LiberationSans-Regular.ttf";
+ t["Helvetica-Bold"] = "LiberationSans-Bold.ttf";
+ t["Helvetica-BoldOblique"] = "LiberationSans-BoldItalic.ttf";
+ t["Helvetica-Oblique"] = "LiberationSans-Italic.ttf";
+ t["Times-Roman"] = "FoxitSerif.pfb";
+ t["Times-Bold"] = "FoxitSerifBold.pfb";
+ t["Times-BoldItalic"] = "FoxitSerifBoldItalic.pfb";
+ t["Times-Italic"] = "FoxitSerifItalic.pfb";
+ t.Symbol = "FoxitSymbol.pfb";
+ t.ZapfDingbats = "FoxitDingbats.pfb";
+ t["LiberationSans-Regular"] = "LiberationSans-Regular.ttf";
+ t["LiberationSans-Bold"] = "LiberationSans-Bold.ttf";
+ t["LiberationSans-Italic"] = "LiberationSans-Italic.ttf";
+ t["LiberationSans-BoldItalic"] = "LiberationSans-BoldItalic.ttf";
+});
+const getNonStdFontMap = getLookupTableFactory(function (t) {
+ t.Calibri = "Helvetica";
+ t["Calibri-Bold"] = "Helvetica-Bold";
+ t["Calibri-BoldItalic"] = "Helvetica-BoldOblique";
+ t["Calibri-Italic"] = "Helvetica-Oblique";
+ t.CenturyGothic = "Helvetica";
+ t["CenturyGothic-Bold"] = "Helvetica-Bold";
+ t["CenturyGothic-BoldItalic"] = "Helvetica-BoldOblique";
+ t["CenturyGothic-Italic"] = "Helvetica-Oblique";
+ t.ComicSansMS = "Comic Sans MS";
+ t["ComicSansMS-Bold"] = "Comic Sans MS-Bold";
+ t["ComicSansMS-BoldItalic"] = "Comic Sans MS-BoldItalic";
+ t["ComicSansMS-Italic"] = "Comic Sans MS-Italic";
+ t.Impact = "Helvetica";
+ t["ItcSymbol-Bold"] = "Helvetica-Bold";
+ t["ItcSymbol-BoldItalic"] = "Helvetica-BoldOblique";
+ t["ItcSymbol-Book"] = "Helvetica";
+ t["ItcSymbol-BookItalic"] = "Helvetica-Oblique";
+ t["ItcSymbol-Medium"] = "Helvetica";
+ t["ItcSymbol-MediumItalic"] = "Helvetica-Oblique";
+ t.LucidaConsole = "Courier";
+ t["LucidaConsole-Bold"] = "Courier-Bold";
+ t["LucidaConsole-BoldItalic"] = "Courier-BoldOblique";
+ t["LucidaConsole-Italic"] = "Courier-Oblique";
+ t["LucidaSans-Demi"] = "Helvetica-Bold";
+ t["MS-Gothic"] = "MS Gothic";
+ t["MS-Gothic-Bold"] = "MS Gothic-Bold";
+ t["MS-Gothic-BoldItalic"] = "MS Gothic-BoldItalic";
+ t["MS-Gothic-Italic"] = "MS Gothic-Italic";
+ t["MS-Mincho"] = "MS Mincho";
+ t["MS-Mincho-Bold"] = "MS Mincho-Bold";
+ t["MS-Mincho-BoldItalic"] = "MS Mincho-BoldItalic";
+ t["MS-Mincho-Italic"] = "MS Mincho-Italic";
+ t["MS-PGothic"] = "MS PGothic";
+ t["MS-PGothic-Bold"] = "MS PGothic-Bold";
+ t["MS-PGothic-BoldItalic"] = "MS PGothic-BoldItalic";
+ t["MS-PGothic-Italic"] = "MS PGothic-Italic";
+ t["MS-PMincho"] = "MS PMincho";
+ t["MS-PMincho-Bold"] = "MS PMincho-Bold";
+ t["MS-PMincho-BoldItalic"] = "MS PMincho-BoldItalic";
+ t["MS-PMincho-Italic"] = "MS PMincho-Italic";
+ t.NuptialScript = "Times-Italic";
+ t.SegoeUISymbol = "Helvetica";
+});
+const getSerifFonts = getLookupTableFactory(function (t) {
+ t["Adobe Jenson"] = true;
+ t["Adobe Text"] = true;
+ t.Albertus = true;
+ t.Aldus = true;
+ t.Alexandria = true;
+ t.Algerian = true;
+ t["American Typewriter"] = true;
+ t.Antiqua = true;
+ t.Apex = true;
+ t.Arno = true;
+ t.Aster = true;
+ t.Aurora = true;
+ t.Baskerville = true;
+ t.Bell = true;
+ t.Bembo = true;
+ t["Bembo Schoolbook"] = true;
+ t.Benguiat = true;
+ t["Berkeley Old Style"] = true;
+ t["Bernhard Modern"] = true;
+ t["Berthold City"] = true;
+ t.Bodoni = true;
+ t["Bauer Bodoni"] = true;
+ t["Book Antiqua"] = true;
+ t.Bookman = true;
+ t["Bordeaux Roman"] = true;
+ t["Californian FB"] = true;
+ t.Calisto = true;
+ t.Calvert = true;
+ t.Capitals = true;
+ t.Cambria = true;
+ t.Cartier = true;
+ t.Caslon = true;
+ t.Catull = true;
+ t.Centaur = true;
+ t["Century Old Style"] = true;
+ t["Century Schoolbook"] = true;
+ t.Chaparral = true;
+ t["Charis SIL"] = true;
+ t.Cheltenham = true;
+ t["Cholla Slab"] = true;
+ t.Clarendon = true;
+ t.Clearface = true;
+ t.Cochin = true;
+ t.Colonna = true;
+ t["Computer Modern"] = true;
+ t["Concrete Roman"] = true;
+ t.Constantia = true;
+ t["Cooper Black"] = true;
+ t.Corona = true;
+ t.Ecotype = true;
+ t.Egyptienne = true;
+ t.Elephant = true;
+ t.Excelsior = true;
+ t.Fairfield = true;
+ t["FF Scala"] = true;
+ t.Folkard = true;
+ t.Footlight = true;
+ t.FreeSerif = true;
+ t["Friz Quadrata"] = true;
+ t.Garamond = true;
+ t.Gentium = true;
+ t.Georgia = true;
+ t.Gloucester = true;
+ t["Goudy Old Style"] = true;
+ t["Goudy Schoolbook"] = true;
+ t["Goudy Pro Font"] = true;
+ t.Granjon = true;
+ t["Guardian Egyptian"] = true;
+ t.Heather = true;
+ t.Hercules = true;
+ t["High Tower Text"] = true;
+ t.Hiroshige = true;
+ t["Hoefler Text"] = true;
+ t["Humana Serif"] = true;
+ t.Imprint = true;
+ t["Ionic No. 5"] = true;
+ t.Janson = true;
+ t.Joanna = true;
+ t.Korinna = true;
+ t.Lexicon = true;
+ t.LiberationSerif = true;
+ t["Liberation Serif"] = true;
+ t["Linux Libertine"] = true;
+ t.Literaturnaya = true;
+ t.Lucida = true;
+ t["Lucida Bright"] = true;
+ t.Melior = true;
+ t.Memphis = true;
+ t.Miller = true;
+ t.Minion = true;
+ t.Modern = true;
+ t["Mona Lisa"] = true;
+ t["Mrs Eaves"] = true;
+ t["MS Serif"] = true;
+ t["Museo Slab"] = true;
+ t["New York"] = true;
+ t["Nimbus Roman"] = true;
+ t["NPS Rawlinson Roadway"] = true;
+ t.NuptialScript = true;
+ t.Palatino = true;
+ t.Perpetua = true;
+ t.Plantin = true;
+ t["Plantin Schoolbook"] = true;
+ t.Playbill = true;
+ t["Poor Richard"] = true;
+ t["Rawlinson Roadway"] = true;
+ t.Renault = true;
+ t.Requiem = true;
+ t.Rockwell = true;
+ t.Roman = true;
+ t["Rotis Serif"] = true;
+ t.Sabon = true;
+ t.Scala = true;
+ t.Seagull = true;
+ t.Sistina = true;
+ t.Souvenir = true;
+ t.STIX = true;
+ t["Stone Informal"] = true;
+ t["Stone Serif"] = true;
+ t.Sylfaen = true;
+ t.Times = true;
+ t.Trajan = true;
+ t["Trinité"] = true;
+ t["Trump Mediaeval"] = true;
+ t.Utopia = true;
+ t["Vale Type"] = true;
+ t["Bitstream Vera"] = true;
+ t["Vera Serif"] = true;
+ t.Versailles = true;
+ t.Wanted = true;
+ t.Weiss = true;
+ t["Wide Latin"] = true;
+ t.Windsor = true;
+ t.XITS = true;
+});
+const getSymbolsFonts = getLookupTableFactory(function (t) {
+ t.Dingbats = true;
+ t.Symbol = true;
+ t.ZapfDingbats = true;
+ t.Wingdings = true;
+ t["Wingdings-Bold"] = true;
+ t["Wingdings-Regular"] = true;
+});
+const getGlyphMapForStandardFonts = getLookupTableFactory(function (t) {
+ t[2] = 10;
+ t[3] = 32;
+ t[4] = 33;
+ t[5] = 34;
+ t[6] = 35;
+ t[7] = 36;
+ t[8] = 37;
+ t[9] = 38;
+ t[10] = 39;
+ t[11] = 40;
+ t[12] = 41;
+ t[13] = 42;
+ t[14] = 43;
+ t[15] = 44;
+ t[16] = 45;
+ t[17] = 46;
+ t[18] = 47;
+ t[19] = 48;
+ t[20] = 49;
+ t[21] = 50;
+ t[22] = 51;
+ t[23] = 52;
+ t[24] = 53;
+ t[25] = 54;
+ t[26] = 55;
+ t[27] = 56;
+ t[28] = 57;
+ t[29] = 58;
+ t[30] = 894;
+ t[31] = 60;
+ t[32] = 61;
+ t[33] = 62;
+ t[34] = 63;
+ t[35] = 64;
+ t[36] = 65;
+ t[37] = 66;
+ t[38] = 67;
+ t[39] = 68;
+ t[40] = 69;
+ t[41] = 70;
+ t[42] = 71;
+ t[43] = 72;
+ t[44] = 73;
+ t[45] = 74;
+ t[46] = 75;
+ t[47] = 76;
+ t[48] = 77;
+ t[49] = 78;
+ t[50] = 79;
+ t[51] = 80;
+ t[52] = 81;
+ t[53] = 82;
+ t[54] = 83;
+ t[55] = 84;
+ t[56] = 85;
+ t[57] = 86;
+ t[58] = 87;
+ t[59] = 88;
+ t[60] = 89;
+ t[61] = 90;
+ t[62] = 91;
+ t[63] = 92;
+ t[64] = 93;
+ t[65] = 94;
+ t[66] = 95;
+ t[67] = 96;
+ t[68] = 97;
+ t[69] = 98;
+ t[70] = 99;
+ t[71] = 100;
+ t[72] = 101;
+ t[73] = 102;
+ t[74] = 103;
+ t[75] = 104;
+ t[76] = 105;
+ t[77] = 106;
+ t[78] = 107;
+ t[79] = 108;
+ t[80] = 109;
+ t[81] = 110;
+ t[82] = 111;
+ t[83] = 112;
+ t[84] = 113;
+ t[85] = 114;
+ t[86] = 115;
+ t[87] = 116;
+ t[88] = 117;
+ t[89] = 118;
+ t[90] = 119;
+ t[91] = 120;
+ t[92] = 121;
+ t[93] = 122;
+ t[94] = 123;
+ t[95] = 124;
+ t[96] = 125;
+ t[97] = 126;
+ t[98] = 196;
+ t[99] = 197;
+ t[100] = 199;
+ t[101] = 201;
+ t[102] = 209;
+ t[103] = 214;
+ t[104] = 220;
+ t[105] = 225;
+ t[106] = 224;
+ t[107] = 226;
+ t[108] = 228;
+ t[109] = 227;
+ t[110] = 229;
+ t[111] = 231;
+ t[112] = 233;
+ t[113] = 232;
+ t[114] = 234;
+ t[115] = 235;
+ t[116] = 237;
+ t[117] = 236;
+ t[118] = 238;
+ t[119] = 239;
+ t[120] = 241;
+ t[121] = 243;
+ t[122] = 242;
+ t[123] = 244;
+ t[124] = 246;
+ t[125] = 245;
+ t[126] = 250;
+ t[127] = 249;
+ t[128] = 251;
+ t[129] = 252;
+ t[130] = 8224;
+ t[131] = 176;
+ t[132] = 162;
+ t[133] = 163;
+ t[134] = 167;
+ t[135] = 8226;
+ t[136] = 182;
+ t[137] = 223;
+ t[138] = 174;
+ t[139] = 169;
+ t[140] = 8482;
+ t[141] = 180;
+ t[142] = 168;
+ t[143] = 8800;
+ t[144] = 198;
+ t[145] = 216;
+ t[146] = 8734;
+ t[147] = 177;
+ t[148] = 8804;
+ t[149] = 8805;
+ t[150] = 165;
+ t[151] = 181;
+ t[152] = 8706;
+ t[153] = 8721;
+ t[154] = 8719;
+ t[156] = 8747;
+ t[157] = 170;
+ t[158] = 186;
+ t[159] = 8486;
+ t[160] = 230;
+ t[161] = 248;
+ t[162] = 191;
+ t[163] = 161;
+ t[164] = 172;
+ t[165] = 8730;
+ t[166] = 402;
+ t[167] = 8776;
+ t[168] = 8710;
+ t[169] = 171;
+ t[170] = 187;
+ t[171] = 8230;
+ t[179] = 8220;
+ t[180] = 8221;
+ t[181] = 8216;
+ t[182] = 8217;
+ t[200] = 193;
+ t[203] = 205;
+ t[207] = 211;
+ t[210] = 218;
+ t[223] = 711;
+ t[224] = 321;
+ t[225] = 322;
+ t[226] = 352;
+ t[227] = 353;
+ t[228] = 381;
+ t[229] = 382;
+ t[233] = 221;
+ t[234] = 253;
+ t[252] = 263;
+ t[253] = 268;
+ t[254] = 269;
+ t[258] = 258;
+ t[260] = 260;
+ t[261] = 261;
+ t[265] = 280;
+ t[266] = 281;
+ t[267] = 282;
+ t[268] = 283;
+ t[269] = 313;
+ t[275] = 323;
+ t[276] = 324;
+ t[278] = 328;
+ t[283] = 344;
+ t[284] = 345;
+ t[285] = 346;
+ t[286] = 347;
+ t[292] = 367;
+ t[295] = 377;
+ t[296] = 378;
+ t[298] = 380;
+ t[305] = 963;
+ t[306] = 964;
+ t[307] = 966;
+ t[308] = 8215;
+ t[309] = 8252;
+ t[310] = 8319;
+ t[311] = 8359;
+ t[312] = 8592;
+ t[313] = 8593;
+ t[337] = 9552;
+ t[493] = 1039;
+ t[494] = 1040;
+ t[672] = 1488;
+ t[673] = 1489;
+ t[674] = 1490;
+ t[675] = 1491;
+ t[676] = 1492;
+ t[677] = 1493;
+ t[678] = 1494;
+ t[679] = 1495;
+ t[680] = 1496;
+ t[681] = 1497;
+ t[682] = 1498;
+ t[683] = 1499;
+ t[684] = 1500;
+ t[685] = 1501;
+ t[686] = 1502;
+ t[687] = 1503;
+ t[688] = 1504;
+ t[689] = 1505;
+ t[690] = 1506;
+ t[691] = 1507;
+ t[692] = 1508;
+ t[693] = 1509;
+ t[694] = 1510;
+ t[695] = 1511;
+ t[696] = 1512;
+ t[697] = 1513;
+ t[698] = 1514;
+ t[705] = 1524;
+ t[706] = 8362;
+ t[710] = 64288;
+ t[711] = 64298;
+ t[759] = 1617;
+ t[761] = 1776;
+ t[763] = 1778;
+ t[775] = 1652;
+ t[777] = 1764;
+ t[778] = 1780;
+ t[779] = 1781;
+ t[780] = 1782;
+ t[782] = 771;
+ t[783] = 64726;
+ t[786] = 8363;
+ t[788] = 8532;
+ t[790] = 768;
+ t[791] = 769;
+ t[792] = 768;
+ t[795] = 803;
+ t[797] = 64336;
+ t[798] = 64337;
+ t[799] = 64342;
+ t[800] = 64343;
+ t[801] = 64344;
+ t[802] = 64345;
+ t[803] = 64362;
+ t[804] = 64363;
+ t[805] = 64364;
+ t[2424] = 7821;
+ t[2425] = 7822;
+ t[2426] = 7823;
+ t[2427] = 7824;
+ t[2428] = 7825;
+ t[2429] = 7826;
+ t[2430] = 7827;
+ t[2433] = 7682;
+ t[2678] = 8045;
+ t[2679] = 8046;
+ t[2830] = 1552;
+ t[2838] = 686;
+ t[2840] = 751;
+ t[2842] = 753;
+ t[2843] = 754;
+ t[2844] = 755;
+ t[2846] = 757;
+ t[2856] = 767;
+ t[2857] = 848;
+ t[2858] = 849;
+ t[2862] = 853;
+ t[2863] = 854;
+ t[2864] = 855;
+ t[2865] = 861;
+ t[2866] = 862;
+ t[2906] = 7460;
+ t[2908] = 7462;
+ t[2909] = 7463;
+ t[2910] = 7464;
+ t[2912] = 7466;
+ t[2913] = 7467;
+ t[2914] = 7468;
+ t[2916] = 7470;
+ t[2917] = 7471;
+ t[2918] = 7472;
+ t[2920] = 7474;
+ t[2921] = 7475;
+ t[2922] = 7476;
+ t[2924] = 7478;
+ t[2925] = 7479;
+ t[2926] = 7480;
+ t[2928] = 7482;
+ t[2929] = 7483;
+ t[2930] = 7484;
+ t[2932] = 7486;
+ t[2933] = 7487;
+ t[2934] = 7488;
+ t[2936] = 7490;
+ t[2937] = 7491;
+ t[2938] = 7492;
+ t[2940] = 7494;
+ t[2941] = 7495;
+ t[2942] = 7496;
+ t[2944] = 7498;
+ t[2946] = 7500;
+ t[2948] = 7502;
+ t[2950] = 7504;
+ t[2951] = 7505;
+ t[2952] = 7506;
+ t[2954] = 7508;
+ t[2955] = 7509;
+ t[2956] = 7510;
+ t[2958] = 7512;
+ t[2959] = 7513;
+ t[2960] = 7514;
+ t[2962] = 7516;
+ t[2963] = 7517;
+ t[2964] = 7518;
+ t[2966] = 7520;
+ t[2967] = 7521;
+ t[2968] = 7522;
+ t[2970] = 7524;
+ t[2971] = 7525;
+ t[2972] = 7526;
+ t[2974] = 7528;
+ t[2975] = 7529;
+ t[2976] = 7530;
+ t[2978] = 1537;
+ t[2979] = 1538;
+ t[2980] = 1539;
+ t[2982] = 1549;
+ t[2983] = 1551;
+ t[2984] = 1552;
+ t[2986] = 1554;
+ t[2987] = 1555;
+ t[2988] = 1556;
+ t[2990] = 1623;
+ t[2991] = 1624;
+ t[2995] = 1775;
+ t[2999] = 1791;
+ t[3002] = 64290;
+ t[3003] = 64291;
+ t[3004] = 64292;
+ t[3006] = 64294;
+ t[3007] = 64295;
+ t[3008] = 64296;
+ t[3011] = 1900;
+ t[3014] = 8223;
+ t[3015] = 8244;
+ t[3017] = 7532;
+ t[3018] = 7533;
+ t[3019] = 7534;
+ t[3075] = 7590;
+ t[3076] = 7591;
+ t[3079] = 7594;
+ t[3080] = 7595;
+ t[3083] = 7598;
+ t[3084] = 7599;
+ t[3087] = 7602;
+ t[3088] = 7603;
+ t[3091] = 7606;
+ t[3092] = 7607;
+ t[3095] = 7610;
+ t[3096] = 7611;
+ t[3099] = 7614;
+ t[3100] = 7615;
+ t[3103] = 7618;
+ t[3104] = 7619;
+ t[3107] = 8337;
+ t[3108] = 8338;
+ t[3116] = 1884;
+ t[3119] = 1885;
+ t[3120] = 1885;
+ t[3123] = 1886;
+ t[3124] = 1886;
+ t[3127] = 1887;
+ t[3128] = 1887;
+ t[3131] = 1888;
+ t[3132] = 1888;
+ t[3135] = 1889;
+ t[3136] = 1889;
+ t[3139] = 1890;
+ t[3140] = 1890;
+ t[3143] = 1891;
+ t[3144] = 1891;
+ t[3147] = 1892;
+ t[3148] = 1892;
+ t[3153] = 580;
+ t[3154] = 581;
+ t[3157] = 584;
+ t[3158] = 585;
+ t[3161] = 588;
+ t[3162] = 589;
+ t[3165] = 891;
+ t[3166] = 892;
+ t[3169] = 1274;
+ t[3170] = 1275;
+ t[3173] = 1278;
+ t[3174] = 1279;
+ t[3181] = 7622;
+ t[3182] = 7623;
+ t[3282] = 11799;
+ t[3316] = 578;
+ t[3379] = 42785;
+ t[3393] = 1159;
+ t[3416] = 8377;
+});
+const getSupplementalGlyphMapForArialBlack = getLookupTableFactory(function (t) {
+ t[227] = 322;
+ t[264] = 261;
+ t[291] = 346;
+});
+const getSupplementalGlyphMapForCalibri = getLookupTableFactory(function (t) {
+ t[1] = 32;
+ t[4] = 65;
+ t[5] = 192;
+ t[6] = 193;
+ t[9] = 196;
+ t[17] = 66;
+ t[18] = 67;
+ t[21] = 268;
+ t[24] = 68;
+ t[28] = 69;
+ t[29] = 200;
+ t[30] = 201;
+ t[32] = 282;
+ t[38] = 70;
+ t[39] = 71;
+ t[44] = 72;
+ t[47] = 73;
+ t[48] = 204;
+ t[49] = 205;
+ t[58] = 74;
+ t[60] = 75;
+ t[62] = 76;
+ t[68] = 77;
+ t[69] = 78;
+ t[75] = 79;
+ t[76] = 210;
+ t[80] = 214;
+ t[87] = 80;
+ t[89] = 81;
+ t[90] = 82;
+ t[92] = 344;
+ t[94] = 83;
+ t[97] = 352;
+ t[100] = 84;
+ t[104] = 85;
+ t[109] = 220;
+ t[115] = 86;
+ t[116] = 87;
+ t[121] = 88;
+ t[122] = 89;
+ t[124] = 221;
+ t[127] = 90;
+ t[129] = 381;
+ t[258] = 97;
+ t[259] = 224;
+ t[260] = 225;
+ t[263] = 228;
+ t[268] = 261;
+ t[271] = 98;
+ t[272] = 99;
+ t[273] = 263;
+ t[275] = 269;
+ t[282] = 100;
+ t[286] = 101;
+ t[287] = 232;
+ t[288] = 233;
+ t[290] = 283;
+ t[295] = 281;
+ t[296] = 102;
+ t[336] = 103;
+ t[346] = 104;
+ t[349] = 105;
+ t[350] = 236;
+ t[351] = 237;
+ t[361] = 106;
+ t[364] = 107;
+ t[367] = 108;
+ t[371] = 322;
+ t[373] = 109;
+ t[374] = 110;
+ t[381] = 111;
+ t[382] = 242;
+ t[383] = 243;
+ t[386] = 246;
+ t[393] = 112;
+ t[395] = 113;
+ t[396] = 114;
+ t[398] = 345;
+ t[400] = 115;
+ t[401] = 347;
+ t[403] = 353;
+ t[410] = 116;
+ t[437] = 117;
+ t[442] = 252;
+ t[448] = 118;
+ t[449] = 119;
+ t[454] = 120;
+ t[455] = 121;
+ t[457] = 253;
+ t[460] = 122;
+ t[462] = 382;
+ t[463] = 380;
+ t[853] = 44;
+ t[855] = 58;
+ t[856] = 46;
+ t[876] = 47;
+ t[878] = 45;
+ t[882] = 45;
+ t[894] = 40;
+ t[895] = 41;
+ t[896] = 91;
+ t[897] = 93;
+ t[923] = 64;
+ t[1004] = 48;
+ t[1005] = 49;
+ t[1006] = 50;
+ t[1007] = 51;
+ t[1008] = 52;
+ t[1009] = 53;
+ t[1010] = 54;
+ t[1011] = 55;
+ t[1012] = 56;
+ t[1013] = 57;
+ t[1081] = 37;
+ t[1085] = 43;
+ t[1086] = 45;
+});
+function getStandardFontName(name) {
+ const fontName = normalizeFontName(name);
+ const stdFontMap = getStdFontMap();
+ return stdFontMap[fontName];
+}
+function isKnownFontName(name) {
+ const fontName = normalizeFontName(name);
+ return !!(getStdFontMap()[fontName] || getNonStdFontMap()[fontName] || getSerifFonts()[fontName] || getSymbolsFonts()[fontName]);
+}
+
+;// CONCATENATED MODULE: ./src/core/to_unicode_map.js
+
+class ToUnicodeMap {
+ constructor(cmap = []) {
+ this._map = cmap;
+ }
+ get length() {
+ return this._map.length;
+ }
+ forEach(callback) {
+ for (const charCode in this._map) {
+ callback(charCode, this._map[charCode].charCodeAt(0));
+ }
+ }
+ has(i) {
+ return this._map[i] !== undefined;
+ }
+ get(i) {
+ return this._map[i];
+ }
+ charCodeOf(value) {
+ const map = this._map;
+ if (map.length <= 0x10000) {
+ return map.indexOf(value);
+ }
+ for (const charCode in map) {
+ if (map[charCode] === value) {
+ return charCode | 0;
+ }
+ }
+ return -1;
+ }
+ amend(map) {
+ for (const charCode in map) {
+ this._map[charCode] = map[charCode];
+ }
+ }
+}
+class IdentityToUnicodeMap {
+ constructor(firstChar, lastChar) {
+ this.firstChar = firstChar;
+ this.lastChar = lastChar;
+ }
+ get length() {
+ return this.lastChar + 1 - this.firstChar;
+ }
+ forEach(callback) {
+ for (let i = this.firstChar, ii = this.lastChar; i <= ii; i++) {
+ callback(i, i);
+ }
+ }
+ has(i) {
+ return this.firstChar <= i && i <= this.lastChar;
+ }
+ get(i) {
+ if (this.firstChar <= i && i <= this.lastChar) {
+ return String.fromCharCode(i);
+ }
+ return undefined;
+ }
+ charCodeOf(v) {
+ return Number.isInteger(v) && v >= this.firstChar && v <= this.lastChar ? v : -1;
+ }
+ amend(map) {
+ unreachable("Should not call amend()");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/cff_font.js
+
+
+
+class CFFFont {
+ constructor(file, properties) {
+ this.properties = properties;
+ const parser = new CFFParser(file, properties, SEAC_ANALYSIS_ENABLED);
+ this.cff = parser.parse();
+ this.cff.duplicateFirstGlyph();
+ const compiler = new CFFCompiler(this.cff);
+ this.seacs = this.cff.seacs;
+ try {
+ this.data = compiler.compile();
+ } catch {
+ warn("Failed to compile font " + properties.loadedName);
+ this.data = file;
+ }
+ this._createBuiltInEncoding();
+ }
+ get numGlyphs() {
+ return this.cff.charStrings.count;
+ }
+ getCharset() {
+ return this.cff.charset.charset;
+ }
+ getGlyphMapping() {
+ const cff = this.cff;
+ const properties = this.properties;
+ const {
+ cidToGidMap,
+ cMap
+ } = properties;
+ const charsets = cff.charset.charset;
+ let charCodeToGlyphId;
+ let glyphId;
+ if (properties.composite) {
+ let invCidToGidMap;
+ if (cidToGidMap?.length > 0) {
+ invCidToGidMap = Object.create(null);
+ for (let i = 0, ii = cidToGidMap.length; i < ii; i++) {
+ const gid = cidToGidMap[i];
+ if (gid !== undefined) {
+ invCidToGidMap[gid] = i;
+ }
+ }
+ }
+ charCodeToGlyphId = Object.create(null);
+ let charCode;
+ if (cff.isCIDFont) {
+ for (glyphId = 0; glyphId < charsets.length; glyphId++) {
+ const cid = charsets[glyphId];
+ charCode = cMap.charCodeOf(cid);
+ if (invCidToGidMap?.[charCode] !== undefined) {
+ charCode = invCidToGidMap[charCode];
+ }
+ charCodeToGlyphId[charCode] = glyphId;
+ }
+ } else {
+ for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) {
+ charCode = cMap.charCodeOf(glyphId);
+ charCodeToGlyphId[charCode] = glyphId;
+ }
+ }
+ return charCodeToGlyphId;
+ }
+ let encoding = cff.encoding ? cff.encoding.encoding : null;
+ if (properties.isInternalFont) {
+ encoding = properties.defaultEncoding;
+ }
+ charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);
+ return charCodeToGlyphId;
+ }
+ hasGlyphId(id) {
+ return this.cff.hasGlyphId(id);
+ }
+ _createBuiltInEncoding() {
+ const {
+ charset,
+ encoding
+ } = this.cff;
+ if (!charset || !encoding) {
+ return;
+ }
+ const charsets = charset.charset,
+ encodings = encoding.encoding;
+ const map = [];
+ for (const charCode in encodings) {
+ const glyphId = encodings[charCode];
+ if (glyphId >= 0) {
+ const glyphName = charsets[glyphId];
+ if (glyphName) {
+ map[charCode] = glyphName;
+ }
+ }
+ }
+ if (map.length > 0) {
+ this.properties.builtInEncoding = map;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/font_renderer.js
+
+
+
+
+
+function getUint32(data, offset) {
+ return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
+}
+function getUint16(data, offset) {
+ return data[offset] << 8 | data[offset + 1];
+}
+function getInt16(data, offset) {
+ return (data[offset] << 24 | data[offset + 1] << 16) >> 16;
+}
+function getInt8(data, offset) {
+ return data[offset] << 24 >> 24;
+}
+function getFloat214(data, offset) {
+ return getInt16(data, offset) / 16384;
+}
+function getSubroutineBias(subrs) {
+ const numSubrs = subrs.length;
+ let bias = 32768;
+ if (numSubrs < 1240) {
+ bias = 107;
+ } else if (numSubrs < 33900) {
+ bias = 1131;
+ }
+ return bias;
+}
+function parseCmap(data, start, end) {
+ const offset = getUint16(data, start + 2) === 1 ? getUint32(data, start + 8) : getUint32(data, start + 16);
+ const format = getUint16(data, start + offset);
+ let ranges, p, i;
+ if (format === 4) {
+ getUint16(data, start + offset + 2);
+ const segCount = getUint16(data, start + offset + 6) >> 1;
+ p = start + offset + 14;
+ ranges = [];
+ for (i = 0; i < segCount; i++, p += 2) {
+ ranges[i] = {
+ end: getUint16(data, p)
+ };
+ }
+ p += 2;
+ for (i = 0; i < segCount; i++, p += 2) {
+ ranges[i].start = getUint16(data, p);
+ }
+ for (i = 0; i < segCount; i++, p += 2) {
+ ranges[i].idDelta = getUint16(data, p);
+ }
+ for (i = 0; i < segCount; i++, p += 2) {
+ let idOffset = getUint16(data, p);
+ if (idOffset === 0) {
+ continue;
+ }
+ ranges[i].ids = [];
+ for (let j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {
+ ranges[i].ids[j] = getUint16(data, p + idOffset);
+ idOffset += 2;
+ }
+ }
+ return ranges;
+ } else if (format === 12) {
+ const groups = getUint32(data, start + offset + 12);
+ p = start + offset + 16;
+ ranges = [];
+ for (i = 0; i < groups; i++) {
+ start = getUint32(data, p);
+ ranges.push({
+ start,
+ end: getUint32(data, p + 4),
+ idDelta: getUint32(data, p + 8) - start
+ });
+ p += 12;
+ }
+ return ranges;
+ }
+ throw new FormatError(`unsupported cmap: ${format}`);
+}
+function parseCff(data, start, end, seacAnalysisEnabled) {
+ const properties = {};
+ const parser = new CFFParser(new Stream(data, start, end - start), properties, seacAnalysisEnabled);
+ const cff = parser.parse();
+ return {
+ glyphs: cff.charStrings.objects,
+ subrs: cff.topDict.privateDict?.subrsIndex?.objects,
+ gsubrs: cff.globalSubrIndex?.objects,
+ isCFFCIDFont: cff.isCIDFont,
+ fdSelect: cff.fdSelect,
+ fdArray: cff.fdArray
+ };
+}
+function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
+ let itemSize, itemDecode;
+ if (isGlyphLocationsLong) {
+ itemSize = 4;
+ itemDecode = getUint32;
+ } else {
+ itemSize = 2;
+ itemDecode = (data, offset) => 2 * getUint16(data, offset);
+ }
+ const glyphs = [];
+ let startOffset = itemDecode(loca, 0);
+ for (let j = itemSize; j < loca.length; j += itemSize) {
+ const endOffset = itemDecode(loca, j);
+ glyphs.push(glyf.subarray(startOffset, endOffset));
+ startOffset = endOffset;
+ }
+ return glyphs;
+}
+function lookupCmap(ranges, unicode) {
+ const code = unicode.codePointAt(0);
+ let gid = 0,
+ l = 0,
+ r = ranges.length - 1;
+ while (l < r) {
+ const c = l + r + 1 >> 1;
+ if (code < ranges[c].start) {
+ r = c - 1;
+ } else {
+ l = c;
+ }
+ }
+ if (ranges[l].start <= code && code <= ranges[l].end) {
+ gid = ranges[l].idDelta + (ranges[l].ids ? ranges[l].ids[code - ranges[l].start] : code) & 0xffff;
+ }
+ return {
+ charCode: code,
+ glyphId: gid
+ };
+}
+function compileGlyf(code, cmds, font) {
+ function moveTo(x, y) {
+ cmds.push({
+ cmd: "moveTo",
+ args: [x, y]
+ });
+ }
+ function lineTo(x, y) {
+ cmds.push({
+ cmd: "lineTo",
+ args: [x, y]
+ });
+ }
+ function quadraticCurveTo(xa, ya, x, y) {
+ cmds.push({
+ cmd: "quadraticCurveTo",
+ args: [xa, ya, x, y]
+ });
+ }
+ let i = 0;
+ const numberOfContours = getInt16(code, i);
+ let flags;
+ let x = 0,
+ y = 0;
+ i += 10;
+ if (numberOfContours < 0) {
+ do {
+ flags = getUint16(code, i);
+ const glyphIndex = getUint16(code, i + 2);
+ i += 4;
+ let arg1, arg2;
+ if (flags & 0x01) {
+ if (flags & 0x02) {
+ arg1 = getInt16(code, i);
+ arg2 = getInt16(code, i + 2);
+ } else {
+ arg1 = getUint16(code, i);
+ arg2 = getUint16(code, i + 2);
+ }
+ i += 4;
+ } else if (flags & 0x02) {
+ arg1 = getInt8(code, i++);
+ arg2 = getInt8(code, i++);
+ } else {
+ arg1 = code[i++];
+ arg2 = code[i++];
+ }
+ if (flags & 0x02) {
+ x = arg1;
+ y = arg2;
+ } else {
+ x = 0;
+ y = 0;
+ }
+ let scaleX = 1,
+ scaleY = 1,
+ scale01 = 0,
+ scale10 = 0;
+ if (flags & 0x08) {
+ scaleX = scaleY = getFloat214(code, i);
+ i += 2;
+ } else if (flags & 0x40) {
+ scaleX = getFloat214(code, i);
+ scaleY = getFloat214(code, i + 2);
+ i += 4;
+ } else if (flags & 0x80) {
+ scaleX = getFloat214(code, i);
+ scale01 = getFloat214(code, i + 2);
+ scale10 = getFloat214(code, i + 4);
+ scaleY = getFloat214(code, i + 6);
+ i += 8;
+ }
+ const subglyph = font.glyphs[glyphIndex];
+ if (subglyph) {
+ cmds.push({
+ cmd: "save"
+ }, {
+ cmd: "transform",
+ args: [scaleX, scale01, scale10, scaleY, x, y]
+ });
+ if (!(flags & 0x02)) {}
+ compileGlyf(subglyph, cmds, font);
+ cmds.push({
+ cmd: "restore"
+ });
+ }
+ } while (flags & 0x20);
+ } else {
+ const endPtsOfContours = [];
+ let j, jj;
+ for (j = 0; j < numberOfContours; j++) {
+ endPtsOfContours.push(getUint16(code, i));
+ i += 2;
+ }
+ const instructionLength = getUint16(code, i);
+ i += 2 + instructionLength;
+ const numberOfPoints = endPtsOfContours.at(-1) + 1;
+ const points = [];
+ while (points.length < numberOfPoints) {
+ flags = code[i++];
+ let repeat = 1;
+ if (flags & 0x08) {
+ repeat += code[i++];
+ }
+ while (repeat-- > 0) {
+ points.push({
+ flags
+ });
+ }
+ }
+ for (j = 0; j < numberOfPoints; j++) {
+ switch (points[j].flags & 0x12) {
+ case 0x00:
+ x += getInt16(code, i);
+ i += 2;
+ break;
+ case 0x02:
+ x -= code[i++];
+ break;
+ case 0x12:
+ x += code[i++];
+ break;
+ }
+ points[j].x = x;
+ }
+ for (j = 0; j < numberOfPoints; j++) {
+ switch (points[j].flags & 0x24) {
+ case 0x00:
+ y += getInt16(code, i);
+ i += 2;
+ break;
+ case 0x04:
+ y -= code[i++];
+ break;
+ case 0x24:
+ y += code[i++];
+ break;
+ }
+ points[j].y = y;
+ }
+ let startPoint = 0;
+ for (i = 0; i < numberOfContours; i++) {
+ const endPoint = endPtsOfContours[i];
+ const contour = points.slice(startPoint, endPoint + 1);
+ if (contour[0].flags & 1) {
+ contour.push(contour[0]);
+ } else if (contour.at(-1).flags & 1) {
+ contour.unshift(contour.at(-1));
+ } else {
+ const p = {
+ flags: 1,
+ x: (contour[0].x + contour.at(-1).x) / 2,
+ y: (contour[0].y + contour.at(-1).y) / 2
+ };
+ contour.unshift(p);
+ contour.push(p);
+ }
+ moveTo(contour[0].x, contour[0].y);
+ for (j = 1, jj = contour.length; j < jj; j++) {
+ if (contour[j].flags & 1) {
+ lineTo(contour[j].x, contour[j].y);
+ } else if (contour[j + 1].flags & 1) {
+ quadraticCurveTo(contour[j].x, contour[j].y, contour[j + 1].x, contour[j + 1].y);
+ j++;
+ } else {
+ quadraticCurveTo(contour[j].x, contour[j].y, (contour[j].x + contour[j + 1].x) / 2, (contour[j].y + contour[j + 1].y) / 2);
+ }
+ }
+ startPoint = endPoint + 1;
+ }
+ }
+}
+function compileCharString(charStringCode, cmds, font, glyphId) {
+ function moveTo(x, y) {
+ cmds.push({
+ cmd: "moveTo",
+ args: [x, y]
+ });
+ }
+ function lineTo(x, y) {
+ cmds.push({
+ cmd: "lineTo",
+ args: [x, y]
+ });
+ }
+ function bezierCurveTo(x1, y1, x2, y2, x, y) {
+ cmds.push({
+ cmd: "bezierCurveTo",
+ args: [x1, y1, x2, y2, x, y]
+ });
+ }
+ const stack = [];
+ let x = 0,
+ y = 0;
+ let stems = 0;
+ function parse(code) {
+ let i = 0;
+ while (i < code.length) {
+ let stackClean = false;
+ let v = code[i++];
+ let xa, xb, ya, yb, y1, y2, y3, n, subrCode;
+ switch (v) {
+ case 1:
+ stems += stack.length >> 1;
+ stackClean = true;
+ break;
+ case 3:
+ stems += stack.length >> 1;
+ stackClean = true;
+ break;
+ case 4:
+ y += stack.pop();
+ moveTo(x, y);
+ stackClean = true;
+ break;
+ case 5:
+ while (stack.length > 0) {
+ x += stack.shift();
+ y += stack.shift();
+ lineTo(x, y);
+ }
+ break;
+ case 6:
+ while (stack.length > 0) {
+ x += stack.shift();
+ lineTo(x, y);
+ if (stack.length === 0) {
+ break;
+ }
+ y += stack.shift();
+ lineTo(x, y);
+ }
+ break;
+ case 7:
+ while (stack.length > 0) {
+ y += stack.shift();
+ lineTo(x, y);
+ if (stack.length === 0) {
+ break;
+ }
+ x += stack.shift();
+ lineTo(x, y);
+ }
+ break;
+ case 8:
+ while (stack.length > 0) {
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ break;
+ case 10:
+ n = stack.pop();
+ subrCode = null;
+ if (font.isCFFCIDFont) {
+ const fdIndex = font.fdSelect.getFDIndex(glyphId);
+ if (fdIndex >= 0 && fdIndex < font.fdArray.length) {
+ const fontDict = font.fdArray[fdIndex];
+ let subrs;
+ if (fontDict.privateDict?.subrsIndex) {
+ subrs = fontDict.privateDict.subrsIndex.objects;
+ }
+ if (subrs) {
+ n += getSubroutineBias(subrs);
+ subrCode = subrs[n];
+ }
+ } else {
+ warn("Invalid fd index for glyph index.");
+ }
+ } else {
+ subrCode = font.subrs[n + font.subrsBias];
+ }
+ if (subrCode) {
+ parse(subrCode);
+ }
+ break;
+ case 11:
+ return;
+ case 12:
+ v = code[i++];
+ switch (v) {
+ case 34:
+ xa = x + stack.shift();
+ xb = xa + stack.shift();
+ y1 = y + stack.shift();
+ x = xb + stack.shift();
+ bezierCurveTo(xa, y, xb, y1, x, y1);
+ xa = x + stack.shift();
+ xb = xa + stack.shift();
+ x = xb + stack.shift();
+ bezierCurveTo(xa, y1, xb, y, x, y);
+ break;
+ case 35:
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ stack.pop();
+ break;
+ case 36:
+ xa = x + stack.shift();
+ y1 = y + stack.shift();
+ xb = xa + stack.shift();
+ y2 = y1 + stack.shift();
+ x = xb + stack.shift();
+ bezierCurveTo(xa, y1, xb, y2, x, y2);
+ xa = x + stack.shift();
+ xb = xa + stack.shift();
+ y3 = y2 + stack.shift();
+ x = xb + stack.shift();
+ bezierCurveTo(xa, y2, xb, y3, x, y);
+ break;
+ case 37:
+ const x0 = x,
+ y0 = y;
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb;
+ y = yb;
+ if (Math.abs(x - x0) > Math.abs(y - y0)) {
+ x += stack.shift();
+ } else {
+ y += stack.shift();
+ }
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ break;
+ default:
+ throw new FormatError(`unknown operator: 12 ${v}`);
+ }
+ break;
+ case 14:
+ if (stack.length >= 4) {
+ const achar = stack.pop();
+ const bchar = stack.pop();
+ y = stack.pop();
+ x = stack.pop();
+ cmds.push({
+ cmd: "save"
+ }, {
+ cmd: "translate",
+ args: [x, y]
+ });
+ let cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]]));
+ compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);
+ cmds.push({
+ cmd: "restore"
+ });
+ cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[bchar]]));
+ compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);
+ }
+ return;
+ case 18:
+ stems += stack.length >> 1;
+ stackClean = true;
+ break;
+ case 19:
+ stems += stack.length >> 1;
+ i += stems + 7 >> 3;
+ stackClean = true;
+ break;
+ case 20:
+ stems += stack.length >> 1;
+ i += stems + 7 >> 3;
+ stackClean = true;
+ break;
+ case 21:
+ y += stack.pop();
+ x += stack.pop();
+ moveTo(x, y);
+ stackClean = true;
+ break;
+ case 22:
+ x += stack.pop();
+ moveTo(x, y);
+ stackClean = true;
+ break;
+ case 23:
+ stems += stack.length >> 1;
+ stackClean = true;
+ break;
+ case 24:
+ while (stack.length > 2) {
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ x += stack.shift();
+ y += stack.shift();
+ lineTo(x, y);
+ break;
+ case 25:
+ while (stack.length > 6) {
+ x += stack.shift();
+ y += stack.shift();
+ lineTo(x, y);
+ }
+ xa = x + stack.shift();
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ break;
+ case 26:
+ if (stack.length % 2) {
+ x += stack.shift();
+ }
+ while (stack.length > 0) {
+ xa = x;
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb;
+ y = yb + stack.shift();
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ break;
+ case 27:
+ if (stack.length % 2) {
+ y += stack.shift();
+ }
+ while (stack.length > 0) {
+ xa = x + stack.shift();
+ ya = y;
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb;
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ break;
+ case 28:
+ stack.push((code[i] << 24 | code[i + 1] << 16) >> 16);
+ i += 2;
+ break;
+ case 29:
+ n = stack.pop() + font.gsubrsBias;
+ subrCode = font.gsubrs[n];
+ if (subrCode) {
+ parse(subrCode);
+ }
+ break;
+ case 30:
+ while (stack.length > 0) {
+ xa = x;
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + (stack.length === 1 ? stack.shift() : 0);
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ if (stack.length === 0) {
+ break;
+ }
+ xa = x + stack.shift();
+ ya = y;
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ y = yb + stack.shift();
+ x = xb + (stack.length === 1 ? stack.shift() : 0);
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ break;
+ case 31:
+ while (stack.length > 0) {
+ xa = x + stack.shift();
+ ya = y;
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ y = yb + stack.shift();
+ x = xb + (stack.length === 1 ? stack.shift() : 0);
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ if (stack.length === 0) {
+ break;
+ }
+ xa = x;
+ ya = y + stack.shift();
+ xb = xa + stack.shift();
+ yb = ya + stack.shift();
+ x = xb + stack.shift();
+ y = yb + (stack.length === 1 ? stack.shift() : 0);
+ bezierCurveTo(xa, ya, xb, yb, x, y);
+ }
+ break;
+ default:
+ if (v < 32) {
+ throw new FormatError(`unknown operator: ${v}`);
+ }
+ if (v < 247) {
+ stack.push(v - 139);
+ } else if (v < 251) {
+ stack.push((v - 247) * 256 + code[i++] + 108);
+ } else if (v < 255) {
+ stack.push(-(v - 251) * 256 - code[i++] - 108);
+ } else {
+ stack.push((code[i] << 24 | code[i + 1] << 16 | code[i + 2] << 8 | code[i + 3]) / 65536);
+ i += 4;
+ }
+ break;
+ }
+ if (stackClean) {
+ stack.length = 0;
+ }
+ }
+ }
+ parse(charStringCode);
+}
+const NOOP = [];
+class CompiledFont {
+ constructor(fontMatrix) {
+ if (this.constructor === CompiledFont) {
+ unreachable("Cannot initialize CompiledFont.");
+ }
+ this.fontMatrix = fontMatrix;
+ this.compiledGlyphs = Object.create(null);
+ this.compiledCharCodeToGlyphId = Object.create(null);
+ }
+ getPathJs(unicode) {
+ const {
+ charCode,
+ glyphId
+ } = lookupCmap(this.cmap, unicode);
+ let fn = this.compiledGlyphs[glyphId];
+ if (!fn) {
+ try {
+ fn = this.compileGlyph(this.glyphs[glyphId], glyphId);
+ this.compiledGlyphs[glyphId] = fn;
+ } catch (ex) {
+ this.compiledGlyphs[glyphId] = NOOP;
+ if (this.compiledCharCodeToGlyphId[charCode] === undefined) {
+ this.compiledCharCodeToGlyphId[charCode] = glyphId;
+ }
+ throw ex;
+ }
+ }
+ if (this.compiledCharCodeToGlyphId[charCode] === undefined) {
+ this.compiledCharCodeToGlyphId[charCode] = glyphId;
+ }
+ return fn;
+ }
+ compileGlyph(code, glyphId) {
+ if (!code || code.length === 0 || code[0] === 14) {
+ return NOOP;
+ }
+ let fontMatrix = this.fontMatrix;
+ if (this.isCFFCIDFont) {
+ const fdIndex = this.fdSelect.getFDIndex(glyphId);
+ if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
+ const fontDict = this.fdArray[fdIndex];
+ fontMatrix = fontDict.getByName("FontMatrix") || FONT_IDENTITY_MATRIX;
+ } else {
+ warn("Invalid fd index for glyph index.");
+ }
+ }
+ const cmds = [{
+ cmd: "save"
+ }, {
+ cmd: "transform",
+ args: fontMatrix.slice()
+ }, {
+ cmd: "scale",
+ args: ["size", "-size"]
+ }];
+ this.compileGlyphImpl(code, cmds, glyphId);
+ cmds.push({
+ cmd: "restore"
+ });
+ return cmds;
+ }
+ compileGlyphImpl() {
+ unreachable("Children classes should implement this.");
+ }
+ hasBuiltPath(unicode) {
+ const {
+ charCode,
+ glyphId
+ } = lookupCmap(this.cmap, unicode);
+ return this.compiledGlyphs[glyphId] !== undefined && this.compiledCharCodeToGlyphId[charCode] !== undefined;
+ }
+}
+class TrueTypeCompiled extends CompiledFont {
+ constructor(glyphs, cmap, fontMatrix) {
+ super(fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0]);
+ this.glyphs = glyphs;
+ this.cmap = cmap;
+ }
+ compileGlyphImpl(code, cmds) {
+ compileGlyf(code, cmds, this);
+ }
+}
+class Type2Compiled extends CompiledFont {
+ constructor(cffInfo, cmap, fontMatrix, glyphNameMap) {
+ super(fontMatrix || [0.001, 0, 0, 0.001, 0, 0]);
+ this.glyphs = cffInfo.glyphs;
+ this.gsubrs = cffInfo.gsubrs || [];
+ this.subrs = cffInfo.subrs || [];
+ this.cmap = cmap;
+ this.glyphNameMap = glyphNameMap || getGlyphsUnicode();
+ this.gsubrsBias = getSubroutineBias(this.gsubrs);
+ this.subrsBias = getSubroutineBias(this.subrs);
+ this.isCFFCIDFont = cffInfo.isCFFCIDFont;
+ this.fdSelect = cffInfo.fdSelect;
+ this.fdArray = cffInfo.fdArray;
+ }
+ compileGlyphImpl(code, cmds, glyphId) {
+ compileCharString(code, cmds, this, glyphId);
+ }
+}
+class FontRendererFactory {
+ static create(font, seacAnalysisEnabled) {
+ const data = new Uint8Array(font.data);
+ let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
+ const numTables = getUint16(data, 4);
+ for (let i = 0, p = 12; i < numTables; i++, p += 16) {
+ const tag = bytesToString(data.subarray(p, p + 4));
+ const offset = getUint32(data, p + 8);
+ const length = getUint32(data, p + 12);
+ switch (tag) {
+ case "cmap":
+ cmap = parseCmap(data, offset, offset + length);
+ break;
+ case "glyf":
+ glyf = data.subarray(offset, offset + length);
+ break;
+ case "loca":
+ loca = data.subarray(offset, offset + length);
+ break;
+ case "head":
+ unitsPerEm = getUint16(data, offset + 18);
+ indexToLocFormat = getUint16(data, offset + 50);
+ break;
+ case "CFF ":
+ cff = parseCff(data, offset, offset + length, seacAnalysisEnabled);
+ break;
+ }
+ }
+ if (glyf) {
+ const fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
+ return new TrueTypeCompiled(parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);
+ }
+ return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/metrics.js
+
+const getMetrics = getLookupTableFactory(function (t) {
+ t.Courier = 600;
+ t["Courier-Bold"] = 600;
+ t["Courier-BoldOblique"] = 600;
+ t["Courier-Oblique"] = 600;
+ t.Helvetica = getLookupTableFactory(function (t) {
+ t.space = 278;
+ t.exclam = 278;
+ t.quotedbl = 355;
+ t.numbersign = 556;
+ t.dollar = 556;
+ t.percent = 889;
+ t.ampersand = 667;
+ t.quoteright = 222;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 389;
+ t.plus = 584;
+ t.comma = 278;
+ t.hyphen = 333;
+ t.period = 278;
+ t.slash = 278;
+ t.zero = 556;
+ t.one = 556;
+ t.two = 556;
+ t.three = 556;
+ t.four = 556;
+ t.five = 556;
+ t.six = 556;
+ t.seven = 556;
+ t.eight = 556;
+ t.nine = 556;
+ t.colon = 278;
+ t.semicolon = 278;
+ t.less = 584;
+ t.equal = 584;
+ t.greater = 584;
+ t.question = 556;
+ t.at = 1015;
+ t.A = 667;
+ t.B = 667;
+ t.C = 722;
+ t.D = 722;
+ t.E = 667;
+ t.F = 611;
+ t.G = 778;
+ t.H = 722;
+ t.I = 278;
+ t.J = 500;
+ t.K = 667;
+ t.L = 556;
+ t.M = 833;
+ t.N = 722;
+ t.O = 778;
+ t.P = 667;
+ t.Q = 778;
+ t.R = 722;
+ t.S = 667;
+ t.T = 611;
+ t.U = 722;
+ t.V = 667;
+ t.W = 944;
+ t.X = 667;
+ t.Y = 667;
+ t.Z = 611;
+ t.bracketleft = 278;
+ t.backslash = 278;
+ t.bracketright = 278;
+ t.asciicircum = 469;
+ t.underscore = 556;
+ t.quoteleft = 222;
+ t.a = 556;
+ t.b = 556;
+ t.c = 500;
+ t.d = 556;
+ t.e = 556;
+ t.f = 278;
+ t.g = 556;
+ t.h = 556;
+ t.i = 222;
+ t.j = 222;
+ t.k = 500;
+ t.l = 222;
+ t.m = 833;
+ t.n = 556;
+ t.o = 556;
+ t.p = 556;
+ t.q = 556;
+ t.r = 333;
+ t.s = 500;
+ t.t = 278;
+ t.u = 556;
+ t.v = 500;
+ t.w = 722;
+ t.x = 500;
+ t.y = 500;
+ t.z = 500;
+ t.braceleft = 334;
+ t.bar = 260;
+ t.braceright = 334;
+ t.asciitilde = 584;
+ t.exclamdown = 333;
+ t.cent = 556;
+ t.sterling = 556;
+ t.fraction = 167;
+ t.yen = 556;
+ t.florin = 556;
+ t.section = 556;
+ t.currency = 556;
+ t.quotesingle = 191;
+ t.quotedblleft = 333;
+ t.guillemotleft = 556;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 500;
+ t.fl = 500;
+ t.endash = 556;
+ t.dagger = 556;
+ t.daggerdbl = 556;
+ t.periodcentered = 278;
+ t.paragraph = 537;
+ t.bullet = 350;
+ t.quotesinglbase = 222;
+ t.quotedblbase = 333;
+ t.quotedblright = 333;
+ t.guillemotright = 556;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 611;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 1000;
+ t.ordfeminine = 370;
+ t.Lslash = 556;
+ t.Oslash = 778;
+ t.OE = 1000;
+ t.ordmasculine = 365;
+ t.ae = 889;
+ t.dotlessi = 278;
+ t.lslash = 222;
+ t.oslash = 611;
+ t.oe = 944;
+ t.germandbls = 611;
+ t.Idieresis = 278;
+ t.eacute = 556;
+ t.abreve = 556;
+ t.uhungarumlaut = 556;
+ t.ecaron = 556;
+ t.Ydieresis = 667;
+ t.divide = 584;
+ t.Yacute = 667;
+ t.Acircumflex = 667;
+ t.aacute = 556;
+ t.Ucircumflex = 722;
+ t.yacute = 500;
+ t.scommaaccent = 500;
+ t.ecircumflex = 556;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 556;
+ t.Uacute = 722;
+ t.uogonek = 556;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 737;
+ t.Emacron = 667;
+ t.ccaron = 500;
+ t.aring = 556;
+ t.Ncommaaccent = 722;
+ t.lacute = 222;
+ t.agrave = 556;
+ t.Tcommaaccent = 611;
+ t.Cacute = 722;
+ t.atilde = 556;
+ t.Edotaccent = 667;
+ t.scaron = 500;
+ t.scedilla = 500;
+ t.iacute = 278;
+ t.lozenge = 471;
+ t.Rcaron = 722;
+ t.Gcommaaccent = 778;
+ t.ucircumflex = 556;
+ t.acircumflex = 556;
+ t.Amacron = 667;
+ t.rcaron = 333;
+ t.ccedilla = 500;
+ t.Zdotaccent = 611;
+ t.Thorn = 667;
+ t.Omacron = 778;
+ t.Racute = 722;
+ t.Sacute = 667;
+ t.dcaron = 643;
+ t.Umacron = 722;
+ t.uring = 556;
+ t.threesuperior = 333;
+ t.Ograve = 778;
+ t.Agrave = 667;
+ t.Abreve = 667;
+ t.multiply = 584;
+ t.uacute = 556;
+ t.Tcaron = 611;
+ t.partialdiff = 476;
+ t.ydieresis = 500;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 556;
+ t.edieresis = 556;
+ t.cacute = 500;
+ t.nacute = 556;
+ t.umacron = 556;
+ t.Ncaron = 722;
+ t.Iacute = 278;
+ t.plusminus = 584;
+ t.brokenbar = 260;
+ t.registered = 737;
+ t.Gbreve = 778;
+ t.Idotaccent = 278;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 333;
+ t.omacron = 556;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 722;
+ t.lcommaaccent = 222;
+ t.tcaron = 317;
+ t.eogonek = 556;
+ t.Uogonek = 722;
+ t.Aacute = 667;
+ t.Adieresis = 667;
+ t.egrave = 556;
+ t.zacute = 500;
+ t.iogonek = 222;
+ t.Oacute = 778;
+ t.oacute = 556;
+ t.amacron = 556;
+ t.sacute = 500;
+ t.idieresis = 278;
+ t.Ocircumflex = 778;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 556;
+ t.twosuperior = 333;
+ t.Odieresis = 778;
+ t.mu = 556;
+ t.igrave = 278;
+ t.ohungarumlaut = 556;
+ t.Eogonek = 667;
+ t.dcroat = 556;
+ t.threequarters = 834;
+ t.Scedilla = 667;
+ t.lcaron = 299;
+ t.Kcommaaccent = 667;
+ t.Lacute = 556;
+ t.trademark = 1000;
+ t.edotaccent = 556;
+ t.Igrave = 278;
+ t.Imacron = 278;
+ t.Lcaron = 556;
+ t.onehalf = 834;
+ t.lessequal = 549;
+ t.ocircumflex = 556;
+ t.ntilde = 556;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 556;
+ t.gbreve = 556;
+ t.onequarter = 834;
+ t.Scaron = 667;
+ t.Scommaaccent = 667;
+ t.Ohungarumlaut = 778;
+ t.degree = 400;
+ t.ograve = 556;
+ t.Ccaron = 722;
+ t.ugrave = 556;
+ t.radical = 453;
+ t.Dcaron = 722;
+ t.rcommaaccent = 333;
+ t.Ntilde = 722;
+ t.otilde = 556;
+ t.Rcommaaccent = 722;
+ t.Lcommaaccent = 556;
+ t.Atilde = 667;
+ t.Aogonek = 667;
+ t.Aring = 667;
+ t.Otilde = 778;
+ t.zdotaccent = 500;
+ t.Ecaron = 667;
+ t.Iogonek = 278;
+ t.kcommaaccent = 500;
+ t.minus = 584;
+ t.Icircumflex = 278;
+ t.ncaron = 556;
+ t.tcommaaccent = 278;
+ t.logicalnot = 584;
+ t.odieresis = 556;
+ t.udieresis = 556;
+ t.notequal = 549;
+ t.gcommaaccent = 556;
+ t.eth = 556;
+ t.zcaron = 500;
+ t.ncommaaccent = 556;
+ t.onesuperior = 333;
+ t.imacron = 278;
+ t.Euro = 556;
+ });
+ t["Helvetica-Bold"] = getLookupTableFactory(function (t) {
+ t.space = 278;
+ t.exclam = 333;
+ t.quotedbl = 474;
+ t.numbersign = 556;
+ t.dollar = 556;
+ t.percent = 889;
+ t.ampersand = 722;
+ t.quoteright = 278;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 389;
+ t.plus = 584;
+ t.comma = 278;
+ t.hyphen = 333;
+ t.period = 278;
+ t.slash = 278;
+ t.zero = 556;
+ t.one = 556;
+ t.two = 556;
+ t.three = 556;
+ t.four = 556;
+ t.five = 556;
+ t.six = 556;
+ t.seven = 556;
+ t.eight = 556;
+ t.nine = 556;
+ t.colon = 333;
+ t.semicolon = 333;
+ t.less = 584;
+ t.equal = 584;
+ t.greater = 584;
+ t.question = 611;
+ t.at = 975;
+ t.A = 722;
+ t.B = 722;
+ t.C = 722;
+ t.D = 722;
+ t.E = 667;
+ t.F = 611;
+ t.G = 778;
+ t.H = 722;
+ t.I = 278;
+ t.J = 556;
+ t.K = 722;
+ t.L = 611;
+ t.M = 833;
+ t.N = 722;
+ t.O = 778;
+ t.P = 667;
+ t.Q = 778;
+ t.R = 722;
+ t.S = 667;
+ t.T = 611;
+ t.U = 722;
+ t.V = 667;
+ t.W = 944;
+ t.X = 667;
+ t.Y = 667;
+ t.Z = 611;
+ t.bracketleft = 333;
+ t.backslash = 278;
+ t.bracketright = 333;
+ t.asciicircum = 584;
+ t.underscore = 556;
+ t.quoteleft = 278;
+ t.a = 556;
+ t.b = 611;
+ t.c = 556;
+ t.d = 611;
+ t.e = 556;
+ t.f = 333;
+ t.g = 611;
+ t.h = 611;
+ t.i = 278;
+ t.j = 278;
+ t.k = 556;
+ t.l = 278;
+ t.m = 889;
+ t.n = 611;
+ t.o = 611;
+ t.p = 611;
+ t.q = 611;
+ t.r = 389;
+ t.s = 556;
+ t.t = 333;
+ t.u = 611;
+ t.v = 556;
+ t.w = 778;
+ t.x = 556;
+ t.y = 556;
+ t.z = 500;
+ t.braceleft = 389;
+ t.bar = 280;
+ t.braceright = 389;
+ t.asciitilde = 584;
+ t.exclamdown = 333;
+ t.cent = 556;
+ t.sterling = 556;
+ t.fraction = 167;
+ t.yen = 556;
+ t.florin = 556;
+ t.section = 556;
+ t.currency = 556;
+ t.quotesingle = 238;
+ t.quotedblleft = 500;
+ t.guillemotleft = 556;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 611;
+ t.fl = 611;
+ t.endash = 556;
+ t.dagger = 556;
+ t.daggerdbl = 556;
+ t.periodcentered = 278;
+ t.paragraph = 556;
+ t.bullet = 350;
+ t.quotesinglbase = 278;
+ t.quotedblbase = 500;
+ t.quotedblright = 500;
+ t.guillemotright = 556;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 611;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 1000;
+ t.ordfeminine = 370;
+ t.Lslash = 611;
+ t.Oslash = 778;
+ t.OE = 1000;
+ t.ordmasculine = 365;
+ t.ae = 889;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 611;
+ t.oe = 944;
+ t.germandbls = 611;
+ t.Idieresis = 278;
+ t.eacute = 556;
+ t.abreve = 556;
+ t.uhungarumlaut = 611;
+ t.ecaron = 556;
+ t.Ydieresis = 667;
+ t.divide = 584;
+ t.Yacute = 667;
+ t.Acircumflex = 722;
+ t.aacute = 556;
+ t.Ucircumflex = 722;
+ t.yacute = 556;
+ t.scommaaccent = 556;
+ t.ecircumflex = 556;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 556;
+ t.Uacute = 722;
+ t.uogonek = 611;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 737;
+ t.Emacron = 667;
+ t.ccaron = 556;
+ t.aring = 556;
+ t.Ncommaaccent = 722;
+ t.lacute = 278;
+ t.agrave = 556;
+ t.Tcommaaccent = 611;
+ t.Cacute = 722;
+ t.atilde = 556;
+ t.Edotaccent = 667;
+ t.scaron = 556;
+ t.scedilla = 556;
+ t.iacute = 278;
+ t.lozenge = 494;
+ t.Rcaron = 722;
+ t.Gcommaaccent = 778;
+ t.ucircumflex = 611;
+ t.acircumflex = 556;
+ t.Amacron = 722;
+ t.rcaron = 389;
+ t.ccedilla = 556;
+ t.Zdotaccent = 611;
+ t.Thorn = 667;
+ t.Omacron = 778;
+ t.Racute = 722;
+ t.Sacute = 667;
+ t.dcaron = 743;
+ t.Umacron = 722;
+ t.uring = 611;
+ t.threesuperior = 333;
+ t.Ograve = 778;
+ t.Agrave = 722;
+ t.Abreve = 722;
+ t.multiply = 584;
+ t.uacute = 611;
+ t.Tcaron = 611;
+ t.partialdiff = 494;
+ t.ydieresis = 556;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 556;
+ t.edieresis = 556;
+ t.cacute = 556;
+ t.nacute = 611;
+ t.umacron = 611;
+ t.Ncaron = 722;
+ t.Iacute = 278;
+ t.plusminus = 584;
+ t.brokenbar = 280;
+ t.registered = 737;
+ t.Gbreve = 778;
+ t.Idotaccent = 278;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 389;
+ t.omacron = 611;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 722;
+ t.lcommaaccent = 278;
+ t.tcaron = 389;
+ t.eogonek = 556;
+ t.Uogonek = 722;
+ t.Aacute = 722;
+ t.Adieresis = 722;
+ t.egrave = 556;
+ t.zacute = 500;
+ t.iogonek = 278;
+ t.Oacute = 778;
+ t.oacute = 611;
+ t.amacron = 556;
+ t.sacute = 556;
+ t.idieresis = 278;
+ t.Ocircumflex = 778;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 611;
+ t.twosuperior = 333;
+ t.Odieresis = 778;
+ t.mu = 611;
+ t.igrave = 278;
+ t.ohungarumlaut = 611;
+ t.Eogonek = 667;
+ t.dcroat = 611;
+ t.threequarters = 834;
+ t.Scedilla = 667;
+ t.lcaron = 400;
+ t.Kcommaaccent = 722;
+ t.Lacute = 611;
+ t.trademark = 1000;
+ t.edotaccent = 556;
+ t.Igrave = 278;
+ t.Imacron = 278;
+ t.Lcaron = 611;
+ t.onehalf = 834;
+ t.lessequal = 549;
+ t.ocircumflex = 611;
+ t.ntilde = 611;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 556;
+ t.gbreve = 611;
+ t.onequarter = 834;
+ t.Scaron = 667;
+ t.Scommaaccent = 667;
+ t.Ohungarumlaut = 778;
+ t.degree = 400;
+ t.ograve = 611;
+ t.Ccaron = 722;
+ t.ugrave = 611;
+ t.radical = 549;
+ t.Dcaron = 722;
+ t.rcommaaccent = 389;
+ t.Ntilde = 722;
+ t.otilde = 611;
+ t.Rcommaaccent = 722;
+ t.Lcommaaccent = 611;
+ t.Atilde = 722;
+ t.Aogonek = 722;
+ t.Aring = 722;
+ t.Otilde = 778;
+ t.zdotaccent = 500;
+ t.Ecaron = 667;
+ t.Iogonek = 278;
+ t.kcommaaccent = 556;
+ t.minus = 584;
+ t.Icircumflex = 278;
+ t.ncaron = 611;
+ t.tcommaaccent = 333;
+ t.logicalnot = 584;
+ t.odieresis = 611;
+ t.udieresis = 611;
+ t.notequal = 549;
+ t.gcommaaccent = 611;
+ t.eth = 611;
+ t.zcaron = 500;
+ t.ncommaaccent = 611;
+ t.onesuperior = 333;
+ t.imacron = 278;
+ t.Euro = 556;
+ });
+ t["Helvetica-BoldOblique"] = getLookupTableFactory(function (t) {
+ t.space = 278;
+ t.exclam = 333;
+ t.quotedbl = 474;
+ t.numbersign = 556;
+ t.dollar = 556;
+ t.percent = 889;
+ t.ampersand = 722;
+ t.quoteright = 278;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 389;
+ t.plus = 584;
+ t.comma = 278;
+ t.hyphen = 333;
+ t.period = 278;
+ t.slash = 278;
+ t.zero = 556;
+ t.one = 556;
+ t.two = 556;
+ t.three = 556;
+ t.four = 556;
+ t.five = 556;
+ t.six = 556;
+ t.seven = 556;
+ t.eight = 556;
+ t.nine = 556;
+ t.colon = 333;
+ t.semicolon = 333;
+ t.less = 584;
+ t.equal = 584;
+ t.greater = 584;
+ t.question = 611;
+ t.at = 975;
+ t.A = 722;
+ t.B = 722;
+ t.C = 722;
+ t.D = 722;
+ t.E = 667;
+ t.F = 611;
+ t.G = 778;
+ t.H = 722;
+ t.I = 278;
+ t.J = 556;
+ t.K = 722;
+ t.L = 611;
+ t.M = 833;
+ t.N = 722;
+ t.O = 778;
+ t.P = 667;
+ t.Q = 778;
+ t.R = 722;
+ t.S = 667;
+ t.T = 611;
+ t.U = 722;
+ t.V = 667;
+ t.W = 944;
+ t.X = 667;
+ t.Y = 667;
+ t.Z = 611;
+ t.bracketleft = 333;
+ t.backslash = 278;
+ t.bracketright = 333;
+ t.asciicircum = 584;
+ t.underscore = 556;
+ t.quoteleft = 278;
+ t.a = 556;
+ t.b = 611;
+ t.c = 556;
+ t.d = 611;
+ t.e = 556;
+ t.f = 333;
+ t.g = 611;
+ t.h = 611;
+ t.i = 278;
+ t.j = 278;
+ t.k = 556;
+ t.l = 278;
+ t.m = 889;
+ t.n = 611;
+ t.o = 611;
+ t.p = 611;
+ t.q = 611;
+ t.r = 389;
+ t.s = 556;
+ t.t = 333;
+ t.u = 611;
+ t.v = 556;
+ t.w = 778;
+ t.x = 556;
+ t.y = 556;
+ t.z = 500;
+ t.braceleft = 389;
+ t.bar = 280;
+ t.braceright = 389;
+ t.asciitilde = 584;
+ t.exclamdown = 333;
+ t.cent = 556;
+ t.sterling = 556;
+ t.fraction = 167;
+ t.yen = 556;
+ t.florin = 556;
+ t.section = 556;
+ t.currency = 556;
+ t.quotesingle = 238;
+ t.quotedblleft = 500;
+ t.guillemotleft = 556;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 611;
+ t.fl = 611;
+ t.endash = 556;
+ t.dagger = 556;
+ t.daggerdbl = 556;
+ t.periodcentered = 278;
+ t.paragraph = 556;
+ t.bullet = 350;
+ t.quotesinglbase = 278;
+ t.quotedblbase = 500;
+ t.quotedblright = 500;
+ t.guillemotright = 556;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 611;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 1000;
+ t.ordfeminine = 370;
+ t.Lslash = 611;
+ t.Oslash = 778;
+ t.OE = 1000;
+ t.ordmasculine = 365;
+ t.ae = 889;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 611;
+ t.oe = 944;
+ t.germandbls = 611;
+ t.Idieresis = 278;
+ t.eacute = 556;
+ t.abreve = 556;
+ t.uhungarumlaut = 611;
+ t.ecaron = 556;
+ t.Ydieresis = 667;
+ t.divide = 584;
+ t.Yacute = 667;
+ t.Acircumflex = 722;
+ t.aacute = 556;
+ t.Ucircumflex = 722;
+ t.yacute = 556;
+ t.scommaaccent = 556;
+ t.ecircumflex = 556;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 556;
+ t.Uacute = 722;
+ t.uogonek = 611;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 737;
+ t.Emacron = 667;
+ t.ccaron = 556;
+ t.aring = 556;
+ t.Ncommaaccent = 722;
+ t.lacute = 278;
+ t.agrave = 556;
+ t.Tcommaaccent = 611;
+ t.Cacute = 722;
+ t.atilde = 556;
+ t.Edotaccent = 667;
+ t.scaron = 556;
+ t.scedilla = 556;
+ t.iacute = 278;
+ t.lozenge = 494;
+ t.Rcaron = 722;
+ t.Gcommaaccent = 778;
+ t.ucircumflex = 611;
+ t.acircumflex = 556;
+ t.Amacron = 722;
+ t.rcaron = 389;
+ t.ccedilla = 556;
+ t.Zdotaccent = 611;
+ t.Thorn = 667;
+ t.Omacron = 778;
+ t.Racute = 722;
+ t.Sacute = 667;
+ t.dcaron = 743;
+ t.Umacron = 722;
+ t.uring = 611;
+ t.threesuperior = 333;
+ t.Ograve = 778;
+ t.Agrave = 722;
+ t.Abreve = 722;
+ t.multiply = 584;
+ t.uacute = 611;
+ t.Tcaron = 611;
+ t.partialdiff = 494;
+ t.ydieresis = 556;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 556;
+ t.edieresis = 556;
+ t.cacute = 556;
+ t.nacute = 611;
+ t.umacron = 611;
+ t.Ncaron = 722;
+ t.Iacute = 278;
+ t.plusminus = 584;
+ t.brokenbar = 280;
+ t.registered = 737;
+ t.Gbreve = 778;
+ t.Idotaccent = 278;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 389;
+ t.omacron = 611;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 722;
+ t.lcommaaccent = 278;
+ t.tcaron = 389;
+ t.eogonek = 556;
+ t.Uogonek = 722;
+ t.Aacute = 722;
+ t.Adieresis = 722;
+ t.egrave = 556;
+ t.zacute = 500;
+ t.iogonek = 278;
+ t.Oacute = 778;
+ t.oacute = 611;
+ t.amacron = 556;
+ t.sacute = 556;
+ t.idieresis = 278;
+ t.Ocircumflex = 778;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 611;
+ t.twosuperior = 333;
+ t.Odieresis = 778;
+ t.mu = 611;
+ t.igrave = 278;
+ t.ohungarumlaut = 611;
+ t.Eogonek = 667;
+ t.dcroat = 611;
+ t.threequarters = 834;
+ t.Scedilla = 667;
+ t.lcaron = 400;
+ t.Kcommaaccent = 722;
+ t.Lacute = 611;
+ t.trademark = 1000;
+ t.edotaccent = 556;
+ t.Igrave = 278;
+ t.Imacron = 278;
+ t.Lcaron = 611;
+ t.onehalf = 834;
+ t.lessequal = 549;
+ t.ocircumflex = 611;
+ t.ntilde = 611;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 556;
+ t.gbreve = 611;
+ t.onequarter = 834;
+ t.Scaron = 667;
+ t.Scommaaccent = 667;
+ t.Ohungarumlaut = 778;
+ t.degree = 400;
+ t.ograve = 611;
+ t.Ccaron = 722;
+ t.ugrave = 611;
+ t.radical = 549;
+ t.Dcaron = 722;
+ t.rcommaaccent = 389;
+ t.Ntilde = 722;
+ t.otilde = 611;
+ t.Rcommaaccent = 722;
+ t.Lcommaaccent = 611;
+ t.Atilde = 722;
+ t.Aogonek = 722;
+ t.Aring = 722;
+ t.Otilde = 778;
+ t.zdotaccent = 500;
+ t.Ecaron = 667;
+ t.Iogonek = 278;
+ t.kcommaaccent = 556;
+ t.minus = 584;
+ t.Icircumflex = 278;
+ t.ncaron = 611;
+ t.tcommaaccent = 333;
+ t.logicalnot = 584;
+ t.odieresis = 611;
+ t.udieresis = 611;
+ t.notequal = 549;
+ t.gcommaaccent = 611;
+ t.eth = 611;
+ t.zcaron = 500;
+ t.ncommaaccent = 611;
+ t.onesuperior = 333;
+ t.imacron = 278;
+ t.Euro = 556;
+ });
+ t["Helvetica-Oblique"] = getLookupTableFactory(function (t) {
+ t.space = 278;
+ t.exclam = 278;
+ t.quotedbl = 355;
+ t.numbersign = 556;
+ t.dollar = 556;
+ t.percent = 889;
+ t.ampersand = 667;
+ t.quoteright = 222;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 389;
+ t.plus = 584;
+ t.comma = 278;
+ t.hyphen = 333;
+ t.period = 278;
+ t.slash = 278;
+ t.zero = 556;
+ t.one = 556;
+ t.two = 556;
+ t.three = 556;
+ t.four = 556;
+ t.five = 556;
+ t.six = 556;
+ t.seven = 556;
+ t.eight = 556;
+ t.nine = 556;
+ t.colon = 278;
+ t.semicolon = 278;
+ t.less = 584;
+ t.equal = 584;
+ t.greater = 584;
+ t.question = 556;
+ t.at = 1015;
+ t.A = 667;
+ t.B = 667;
+ t.C = 722;
+ t.D = 722;
+ t.E = 667;
+ t.F = 611;
+ t.G = 778;
+ t.H = 722;
+ t.I = 278;
+ t.J = 500;
+ t.K = 667;
+ t.L = 556;
+ t.M = 833;
+ t.N = 722;
+ t.O = 778;
+ t.P = 667;
+ t.Q = 778;
+ t.R = 722;
+ t.S = 667;
+ t.T = 611;
+ t.U = 722;
+ t.V = 667;
+ t.W = 944;
+ t.X = 667;
+ t.Y = 667;
+ t.Z = 611;
+ t.bracketleft = 278;
+ t.backslash = 278;
+ t.bracketright = 278;
+ t.asciicircum = 469;
+ t.underscore = 556;
+ t.quoteleft = 222;
+ t.a = 556;
+ t.b = 556;
+ t.c = 500;
+ t.d = 556;
+ t.e = 556;
+ t.f = 278;
+ t.g = 556;
+ t.h = 556;
+ t.i = 222;
+ t.j = 222;
+ t.k = 500;
+ t.l = 222;
+ t.m = 833;
+ t.n = 556;
+ t.o = 556;
+ t.p = 556;
+ t.q = 556;
+ t.r = 333;
+ t.s = 500;
+ t.t = 278;
+ t.u = 556;
+ t.v = 500;
+ t.w = 722;
+ t.x = 500;
+ t.y = 500;
+ t.z = 500;
+ t.braceleft = 334;
+ t.bar = 260;
+ t.braceright = 334;
+ t.asciitilde = 584;
+ t.exclamdown = 333;
+ t.cent = 556;
+ t.sterling = 556;
+ t.fraction = 167;
+ t.yen = 556;
+ t.florin = 556;
+ t.section = 556;
+ t.currency = 556;
+ t.quotesingle = 191;
+ t.quotedblleft = 333;
+ t.guillemotleft = 556;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 500;
+ t.fl = 500;
+ t.endash = 556;
+ t.dagger = 556;
+ t.daggerdbl = 556;
+ t.periodcentered = 278;
+ t.paragraph = 537;
+ t.bullet = 350;
+ t.quotesinglbase = 222;
+ t.quotedblbase = 333;
+ t.quotedblright = 333;
+ t.guillemotright = 556;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 611;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 1000;
+ t.ordfeminine = 370;
+ t.Lslash = 556;
+ t.Oslash = 778;
+ t.OE = 1000;
+ t.ordmasculine = 365;
+ t.ae = 889;
+ t.dotlessi = 278;
+ t.lslash = 222;
+ t.oslash = 611;
+ t.oe = 944;
+ t.germandbls = 611;
+ t.Idieresis = 278;
+ t.eacute = 556;
+ t.abreve = 556;
+ t.uhungarumlaut = 556;
+ t.ecaron = 556;
+ t.Ydieresis = 667;
+ t.divide = 584;
+ t.Yacute = 667;
+ t.Acircumflex = 667;
+ t.aacute = 556;
+ t.Ucircumflex = 722;
+ t.yacute = 500;
+ t.scommaaccent = 500;
+ t.ecircumflex = 556;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 556;
+ t.Uacute = 722;
+ t.uogonek = 556;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 737;
+ t.Emacron = 667;
+ t.ccaron = 500;
+ t.aring = 556;
+ t.Ncommaaccent = 722;
+ t.lacute = 222;
+ t.agrave = 556;
+ t.Tcommaaccent = 611;
+ t.Cacute = 722;
+ t.atilde = 556;
+ t.Edotaccent = 667;
+ t.scaron = 500;
+ t.scedilla = 500;
+ t.iacute = 278;
+ t.lozenge = 471;
+ t.Rcaron = 722;
+ t.Gcommaaccent = 778;
+ t.ucircumflex = 556;
+ t.acircumflex = 556;
+ t.Amacron = 667;
+ t.rcaron = 333;
+ t.ccedilla = 500;
+ t.Zdotaccent = 611;
+ t.Thorn = 667;
+ t.Omacron = 778;
+ t.Racute = 722;
+ t.Sacute = 667;
+ t.dcaron = 643;
+ t.Umacron = 722;
+ t.uring = 556;
+ t.threesuperior = 333;
+ t.Ograve = 778;
+ t.Agrave = 667;
+ t.Abreve = 667;
+ t.multiply = 584;
+ t.uacute = 556;
+ t.Tcaron = 611;
+ t.partialdiff = 476;
+ t.ydieresis = 500;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 556;
+ t.edieresis = 556;
+ t.cacute = 500;
+ t.nacute = 556;
+ t.umacron = 556;
+ t.Ncaron = 722;
+ t.Iacute = 278;
+ t.plusminus = 584;
+ t.brokenbar = 260;
+ t.registered = 737;
+ t.Gbreve = 778;
+ t.Idotaccent = 278;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 333;
+ t.omacron = 556;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 722;
+ t.lcommaaccent = 222;
+ t.tcaron = 317;
+ t.eogonek = 556;
+ t.Uogonek = 722;
+ t.Aacute = 667;
+ t.Adieresis = 667;
+ t.egrave = 556;
+ t.zacute = 500;
+ t.iogonek = 222;
+ t.Oacute = 778;
+ t.oacute = 556;
+ t.amacron = 556;
+ t.sacute = 500;
+ t.idieresis = 278;
+ t.Ocircumflex = 778;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 556;
+ t.twosuperior = 333;
+ t.Odieresis = 778;
+ t.mu = 556;
+ t.igrave = 278;
+ t.ohungarumlaut = 556;
+ t.Eogonek = 667;
+ t.dcroat = 556;
+ t.threequarters = 834;
+ t.Scedilla = 667;
+ t.lcaron = 299;
+ t.Kcommaaccent = 667;
+ t.Lacute = 556;
+ t.trademark = 1000;
+ t.edotaccent = 556;
+ t.Igrave = 278;
+ t.Imacron = 278;
+ t.Lcaron = 556;
+ t.onehalf = 834;
+ t.lessequal = 549;
+ t.ocircumflex = 556;
+ t.ntilde = 556;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 556;
+ t.gbreve = 556;
+ t.onequarter = 834;
+ t.Scaron = 667;
+ t.Scommaaccent = 667;
+ t.Ohungarumlaut = 778;
+ t.degree = 400;
+ t.ograve = 556;
+ t.Ccaron = 722;
+ t.ugrave = 556;
+ t.radical = 453;
+ t.Dcaron = 722;
+ t.rcommaaccent = 333;
+ t.Ntilde = 722;
+ t.otilde = 556;
+ t.Rcommaaccent = 722;
+ t.Lcommaaccent = 556;
+ t.Atilde = 667;
+ t.Aogonek = 667;
+ t.Aring = 667;
+ t.Otilde = 778;
+ t.zdotaccent = 500;
+ t.Ecaron = 667;
+ t.Iogonek = 278;
+ t.kcommaaccent = 500;
+ t.minus = 584;
+ t.Icircumflex = 278;
+ t.ncaron = 556;
+ t.tcommaaccent = 278;
+ t.logicalnot = 584;
+ t.odieresis = 556;
+ t.udieresis = 556;
+ t.notequal = 549;
+ t.gcommaaccent = 556;
+ t.eth = 556;
+ t.zcaron = 500;
+ t.ncommaaccent = 556;
+ t.onesuperior = 333;
+ t.imacron = 278;
+ t.Euro = 556;
+ });
+ t.Symbol = getLookupTableFactory(function (t) {
+ t.space = 250;
+ t.exclam = 333;
+ t.universal = 713;
+ t.numbersign = 500;
+ t.existential = 549;
+ t.percent = 833;
+ t.ampersand = 778;
+ t.suchthat = 439;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asteriskmath = 500;
+ t.plus = 549;
+ t.comma = 250;
+ t.minus = 549;
+ t.period = 250;
+ t.slash = 278;
+ t.zero = 500;
+ t.one = 500;
+ t.two = 500;
+ t.three = 500;
+ t.four = 500;
+ t.five = 500;
+ t.six = 500;
+ t.seven = 500;
+ t.eight = 500;
+ t.nine = 500;
+ t.colon = 278;
+ t.semicolon = 278;
+ t.less = 549;
+ t.equal = 549;
+ t.greater = 549;
+ t.question = 444;
+ t.congruent = 549;
+ t.Alpha = 722;
+ t.Beta = 667;
+ t.Chi = 722;
+ t.Delta = 612;
+ t.Epsilon = 611;
+ t.Phi = 763;
+ t.Gamma = 603;
+ t.Eta = 722;
+ t.Iota = 333;
+ t.theta1 = 631;
+ t.Kappa = 722;
+ t.Lambda = 686;
+ t.Mu = 889;
+ t.Nu = 722;
+ t.Omicron = 722;
+ t.Pi = 768;
+ t.Theta = 741;
+ t.Rho = 556;
+ t.Sigma = 592;
+ t.Tau = 611;
+ t.Upsilon = 690;
+ t.sigma1 = 439;
+ t.Omega = 768;
+ t.Xi = 645;
+ t.Psi = 795;
+ t.Zeta = 611;
+ t.bracketleft = 333;
+ t.therefore = 863;
+ t.bracketright = 333;
+ t.perpendicular = 658;
+ t.underscore = 500;
+ t.radicalex = 500;
+ t.alpha = 631;
+ t.beta = 549;
+ t.chi = 549;
+ t.delta = 494;
+ t.epsilon = 439;
+ t.phi = 521;
+ t.gamma = 411;
+ t.eta = 603;
+ t.iota = 329;
+ t.phi1 = 603;
+ t.kappa = 549;
+ t.lambda = 549;
+ t.mu = 576;
+ t.nu = 521;
+ t.omicron = 549;
+ t.pi = 549;
+ t.theta = 521;
+ t.rho = 549;
+ t.sigma = 603;
+ t.tau = 439;
+ t.upsilon = 576;
+ t.omega1 = 713;
+ t.omega = 686;
+ t.xi = 493;
+ t.psi = 686;
+ t.zeta = 494;
+ t.braceleft = 480;
+ t.bar = 200;
+ t.braceright = 480;
+ t.similar = 549;
+ t.Euro = 750;
+ t.Upsilon1 = 620;
+ t.minute = 247;
+ t.lessequal = 549;
+ t.fraction = 167;
+ t.infinity = 713;
+ t.florin = 500;
+ t.club = 753;
+ t.diamond = 753;
+ t.heart = 753;
+ t.spade = 753;
+ t.arrowboth = 1042;
+ t.arrowleft = 987;
+ t.arrowup = 603;
+ t.arrowright = 987;
+ t.arrowdown = 603;
+ t.degree = 400;
+ t.plusminus = 549;
+ t.second = 411;
+ t.greaterequal = 549;
+ t.multiply = 549;
+ t.proportional = 713;
+ t.partialdiff = 494;
+ t.bullet = 460;
+ t.divide = 549;
+ t.notequal = 549;
+ t.equivalence = 549;
+ t.approxequal = 549;
+ t.ellipsis = 1000;
+ t.arrowvertex = 603;
+ t.arrowhorizex = 1000;
+ t.carriagereturn = 658;
+ t.aleph = 823;
+ t.Ifraktur = 686;
+ t.Rfraktur = 795;
+ t.weierstrass = 987;
+ t.circlemultiply = 768;
+ t.circleplus = 768;
+ t.emptyset = 823;
+ t.intersection = 768;
+ t.union = 768;
+ t.propersuperset = 713;
+ t.reflexsuperset = 713;
+ t.notsubset = 713;
+ t.propersubset = 713;
+ t.reflexsubset = 713;
+ t.element = 713;
+ t.notelement = 713;
+ t.angle = 768;
+ t.gradient = 713;
+ t.registerserif = 790;
+ t.copyrightserif = 790;
+ t.trademarkserif = 890;
+ t.product = 823;
+ t.radical = 549;
+ t.dotmath = 250;
+ t.logicalnot = 713;
+ t.logicaland = 603;
+ t.logicalor = 603;
+ t.arrowdblboth = 1042;
+ t.arrowdblleft = 987;
+ t.arrowdblup = 603;
+ t.arrowdblright = 987;
+ t.arrowdbldown = 603;
+ t.lozenge = 494;
+ t.angleleft = 329;
+ t.registersans = 790;
+ t.copyrightsans = 790;
+ t.trademarksans = 786;
+ t.summation = 713;
+ t.parenlefttp = 384;
+ t.parenleftex = 384;
+ t.parenleftbt = 384;
+ t.bracketlefttp = 384;
+ t.bracketleftex = 384;
+ t.bracketleftbt = 384;
+ t.bracelefttp = 494;
+ t.braceleftmid = 494;
+ t.braceleftbt = 494;
+ t.braceex = 494;
+ t.angleright = 329;
+ t.integral = 274;
+ t.integraltp = 686;
+ t.integralex = 686;
+ t.integralbt = 686;
+ t.parenrighttp = 384;
+ t.parenrightex = 384;
+ t.parenrightbt = 384;
+ t.bracketrighttp = 384;
+ t.bracketrightex = 384;
+ t.bracketrightbt = 384;
+ t.bracerighttp = 494;
+ t.bracerightmid = 494;
+ t.bracerightbt = 494;
+ t.apple = 790;
+ });
+ t["Times-Roman"] = getLookupTableFactory(function (t) {
+ t.space = 250;
+ t.exclam = 333;
+ t.quotedbl = 408;
+ t.numbersign = 500;
+ t.dollar = 500;
+ t.percent = 833;
+ t.ampersand = 778;
+ t.quoteright = 333;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 500;
+ t.plus = 564;
+ t.comma = 250;
+ t.hyphen = 333;
+ t.period = 250;
+ t.slash = 278;
+ t.zero = 500;
+ t.one = 500;
+ t.two = 500;
+ t.three = 500;
+ t.four = 500;
+ t.five = 500;
+ t.six = 500;
+ t.seven = 500;
+ t.eight = 500;
+ t.nine = 500;
+ t.colon = 278;
+ t.semicolon = 278;
+ t.less = 564;
+ t.equal = 564;
+ t.greater = 564;
+ t.question = 444;
+ t.at = 921;
+ t.A = 722;
+ t.B = 667;
+ t.C = 667;
+ t.D = 722;
+ t.E = 611;
+ t.F = 556;
+ t.G = 722;
+ t.H = 722;
+ t.I = 333;
+ t.J = 389;
+ t.K = 722;
+ t.L = 611;
+ t.M = 889;
+ t.N = 722;
+ t.O = 722;
+ t.P = 556;
+ t.Q = 722;
+ t.R = 667;
+ t.S = 556;
+ t.T = 611;
+ t.U = 722;
+ t.V = 722;
+ t.W = 944;
+ t.X = 722;
+ t.Y = 722;
+ t.Z = 611;
+ t.bracketleft = 333;
+ t.backslash = 278;
+ t.bracketright = 333;
+ t.asciicircum = 469;
+ t.underscore = 500;
+ t.quoteleft = 333;
+ t.a = 444;
+ t.b = 500;
+ t.c = 444;
+ t.d = 500;
+ t.e = 444;
+ t.f = 333;
+ t.g = 500;
+ t.h = 500;
+ t.i = 278;
+ t.j = 278;
+ t.k = 500;
+ t.l = 278;
+ t.m = 778;
+ t.n = 500;
+ t.o = 500;
+ t.p = 500;
+ t.q = 500;
+ t.r = 333;
+ t.s = 389;
+ t.t = 278;
+ t.u = 500;
+ t.v = 500;
+ t.w = 722;
+ t.x = 500;
+ t.y = 500;
+ t.z = 444;
+ t.braceleft = 480;
+ t.bar = 200;
+ t.braceright = 480;
+ t.asciitilde = 541;
+ t.exclamdown = 333;
+ t.cent = 500;
+ t.sterling = 500;
+ t.fraction = 167;
+ t.yen = 500;
+ t.florin = 500;
+ t.section = 500;
+ t.currency = 500;
+ t.quotesingle = 180;
+ t.quotedblleft = 444;
+ t.guillemotleft = 500;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 556;
+ t.fl = 556;
+ t.endash = 500;
+ t.dagger = 500;
+ t.daggerdbl = 500;
+ t.periodcentered = 250;
+ t.paragraph = 453;
+ t.bullet = 350;
+ t.quotesinglbase = 333;
+ t.quotedblbase = 444;
+ t.quotedblright = 444;
+ t.guillemotright = 500;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 444;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 889;
+ t.ordfeminine = 276;
+ t.Lslash = 611;
+ t.Oslash = 722;
+ t.OE = 889;
+ t.ordmasculine = 310;
+ t.ae = 667;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 500;
+ t.oe = 722;
+ t.germandbls = 500;
+ t.Idieresis = 333;
+ t.eacute = 444;
+ t.abreve = 444;
+ t.uhungarumlaut = 500;
+ t.ecaron = 444;
+ t.Ydieresis = 722;
+ t.divide = 564;
+ t.Yacute = 722;
+ t.Acircumflex = 722;
+ t.aacute = 444;
+ t.Ucircumflex = 722;
+ t.yacute = 500;
+ t.scommaaccent = 389;
+ t.ecircumflex = 444;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 444;
+ t.Uacute = 722;
+ t.uogonek = 500;
+ t.Edieresis = 611;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 760;
+ t.Emacron = 611;
+ t.ccaron = 444;
+ t.aring = 444;
+ t.Ncommaaccent = 722;
+ t.lacute = 278;
+ t.agrave = 444;
+ t.Tcommaaccent = 611;
+ t.Cacute = 667;
+ t.atilde = 444;
+ t.Edotaccent = 611;
+ t.scaron = 389;
+ t.scedilla = 389;
+ t.iacute = 278;
+ t.lozenge = 471;
+ t.Rcaron = 667;
+ t.Gcommaaccent = 722;
+ t.ucircumflex = 500;
+ t.acircumflex = 444;
+ t.Amacron = 722;
+ t.rcaron = 333;
+ t.ccedilla = 444;
+ t.Zdotaccent = 611;
+ t.Thorn = 556;
+ t.Omacron = 722;
+ t.Racute = 667;
+ t.Sacute = 556;
+ t.dcaron = 588;
+ t.Umacron = 722;
+ t.uring = 500;
+ t.threesuperior = 300;
+ t.Ograve = 722;
+ t.Agrave = 722;
+ t.Abreve = 722;
+ t.multiply = 564;
+ t.uacute = 500;
+ t.Tcaron = 611;
+ t.partialdiff = 476;
+ t.ydieresis = 500;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 611;
+ t.adieresis = 444;
+ t.edieresis = 444;
+ t.cacute = 444;
+ t.nacute = 500;
+ t.umacron = 500;
+ t.Ncaron = 722;
+ t.Iacute = 333;
+ t.plusminus = 564;
+ t.brokenbar = 200;
+ t.registered = 760;
+ t.Gbreve = 722;
+ t.Idotaccent = 333;
+ t.summation = 600;
+ t.Egrave = 611;
+ t.racute = 333;
+ t.omacron = 500;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 667;
+ t.lcommaaccent = 278;
+ t.tcaron = 326;
+ t.eogonek = 444;
+ t.Uogonek = 722;
+ t.Aacute = 722;
+ t.Adieresis = 722;
+ t.egrave = 444;
+ t.zacute = 444;
+ t.iogonek = 278;
+ t.Oacute = 722;
+ t.oacute = 500;
+ t.amacron = 444;
+ t.sacute = 389;
+ t.idieresis = 278;
+ t.Ocircumflex = 722;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 500;
+ t.twosuperior = 300;
+ t.Odieresis = 722;
+ t.mu = 500;
+ t.igrave = 278;
+ t.ohungarumlaut = 500;
+ t.Eogonek = 611;
+ t.dcroat = 500;
+ t.threequarters = 750;
+ t.Scedilla = 556;
+ t.lcaron = 344;
+ t.Kcommaaccent = 722;
+ t.Lacute = 611;
+ t.trademark = 980;
+ t.edotaccent = 444;
+ t.Igrave = 333;
+ t.Imacron = 333;
+ t.Lcaron = 611;
+ t.onehalf = 750;
+ t.lessequal = 549;
+ t.ocircumflex = 500;
+ t.ntilde = 500;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 611;
+ t.emacron = 444;
+ t.gbreve = 500;
+ t.onequarter = 750;
+ t.Scaron = 556;
+ t.Scommaaccent = 556;
+ t.Ohungarumlaut = 722;
+ t.degree = 400;
+ t.ograve = 500;
+ t.Ccaron = 667;
+ t.ugrave = 500;
+ t.radical = 453;
+ t.Dcaron = 722;
+ t.rcommaaccent = 333;
+ t.Ntilde = 722;
+ t.otilde = 500;
+ t.Rcommaaccent = 667;
+ t.Lcommaaccent = 611;
+ t.Atilde = 722;
+ t.Aogonek = 722;
+ t.Aring = 722;
+ t.Otilde = 722;
+ t.zdotaccent = 444;
+ t.Ecaron = 611;
+ t.Iogonek = 333;
+ t.kcommaaccent = 500;
+ t.minus = 564;
+ t.Icircumflex = 333;
+ t.ncaron = 500;
+ t.tcommaaccent = 278;
+ t.logicalnot = 564;
+ t.odieresis = 500;
+ t.udieresis = 500;
+ t.notequal = 549;
+ t.gcommaaccent = 500;
+ t.eth = 500;
+ t.zcaron = 444;
+ t.ncommaaccent = 500;
+ t.onesuperior = 300;
+ t.imacron = 278;
+ t.Euro = 500;
+ });
+ t["Times-Bold"] = getLookupTableFactory(function (t) {
+ t.space = 250;
+ t.exclam = 333;
+ t.quotedbl = 555;
+ t.numbersign = 500;
+ t.dollar = 500;
+ t.percent = 1000;
+ t.ampersand = 833;
+ t.quoteright = 333;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 500;
+ t.plus = 570;
+ t.comma = 250;
+ t.hyphen = 333;
+ t.period = 250;
+ t.slash = 278;
+ t.zero = 500;
+ t.one = 500;
+ t.two = 500;
+ t.three = 500;
+ t.four = 500;
+ t.five = 500;
+ t.six = 500;
+ t.seven = 500;
+ t.eight = 500;
+ t.nine = 500;
+ t.colon = 333;
+ t.semicolon = 333;
+ t.less = 570;
+ t.equal = 570;
+ t.greater = 570;
+ t.question = 500;
+ t.at = 930;
+ t.A = 722;
+ t.B = 667;
+ t.C = 722;
+ t.D = 722;
+ t.E = 667;
+ t.F = 611;
+ t.G = 778;
+ t.H = 778;
+ t.I = 389;
+ t.J = 500;
+ t.K = 778;
+ t.L = 667;
+ t.M = 944;
+ t.N = 722;
+ t.O = 778;
+ t.P = 611;
+ t.Q = 778;
+ t.R = 722;
+ t.S = 556;
+ t.T = 667;
+ t.U = 722;
+ t.V = 722;
+ t.W = 1000;
+ t.X = 722;
+ t.Y = 722;
+ t.Z = 667;
+ t.bracketleft = 333;
+ t.backslash = 278;
+ t.bracketright = 333;
+ t.asciicircum = 581;
+ t.underscore = 500;
+ t.quoteleft = 333;
+ t.a = 500;
+ t.b = 556;
+ t.c = 444;
+ t.d = 556;
+ t.e = 444;
+ t.f = 333;
+ t.g = 500;
+ t.h = 556;
+ t.i = 278;
+ t.j = 333;
+ t.k = 556;
+ t.l = 278;
+ t.m = 833;
+ t.n = 556;
+ t.o = 500;
+ t.p = 556;
+ t.q = 556;
+ t.r = 444;
+ t.s = 389;
+ t.t = 333;
+ t.u = 556;
+ t.v = 500;
+ t.w = 722;
+ t.x = 500;
+ t.y = 500;
+ t.z = 444;
+ t.braceleft = 394;
+ t.bar = 220;
+ t.braceright = 394;
+ t.asciitilde = 520;
+ t.exclamdown = 333;
+ t.cent = 500;
+ t.sterling = 500;
+ t.fraction = 167;
+ t.yen = 500;
+ t.florin = 500;
+ t.section = 500;
+ t.currency = 500;
+ t.quotesingle = 278;
+ t.quotedblleft = 500;
+ t.guillemotleft = 500;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 556;
+ t.fl = 556;
+ t.endash = 500;
+ t.dagger = 500;
+ t.daggerdbl = 500;
+ t.periodcentered = 250;
+ t.paragraph = 540;
+ t.bullet = 350;
+ t.quotesinglbase = 333;
+ t.quotedblbase = 500;
+ t.quotedblright = 500;
+ t.guillemotright = 500;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 500;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 1000;
+ t.ordfeminine = 300;
+ t.Lslash = 667;
+ t.Oslash = 778;
+ t.OE = 1000;
+ t.ordmasculine = 330;
+ t.ae = 722;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 500;
+ t.oe = 722;
+ t.germandbls = 556;
+ t.Idieresis = 389;
+ t.eacute = 444;
+ t.abreve = 500;
+ t.uhungarumlaut = 556;
+ t.ecaron = 444;
+ t.Ydieresis = 722;
+ t.divide = 570;
+ t.Yacute = 722;
+ t.Acircumflex = 722;
+ t.aacute = 500;
+ t.Ucircumflex = 722;
+ t.yacute = 500;
+ t.scommaaccent = 389;
+ t.ecircumflex = 444;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 500;
+ t.Uacute = 722;
+ t.uogonek = 556;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 747;
+ t.Emacron = 667;
+ t.ccaron = 444;
+ t.aring = 500;
+ t.Ncommaaccent = 722;
+ t.lacute = 278;
+ t.agrave = 500;
+ t.Tcommaaccent = 667;
+ t.Cacute = 722;
+ t.atilde = 500;
+ t.Edotaccent = 667;
+ t.scaron = 389;
+ t.scedilla = 389;
+ t.iacute = 278;
+ t.lozenge = 494;
+ t.Rcaron = 722;
+ t.Gcommaaccent = 778;
+ t.ucircumflex = 556;
+ t.acircumflex = 500;
+ t.Amacron = 722;
+ t.rcaron = 444;
+ t.ccedilla = 444;
+ t.Zdotaccent = 667;
+ t.Thorn = 611;
+ t.Omacron = 778;
+ t.Racute = 722;
+ t.Sacute = 556;
+ t.dcaron = 672;
+ t.Umacron = 722;
+ t.uring = 556;
+ t.threesuperior = 300;
+ t.Ograve = 778;
+ t.Agrave = 722;
+ t.Abreve = 722;
+ t.multiply = 570;
+ t.uacute = 556;
+ t.Tcaron = 667;
+ t.partialdiff = 494;
+ t.ydieresis = 500;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 500;
+ t.edieresis = 444;
+ t.cacute = 444;
+ t.nacute = 556;
+ t.umacron = 556;
+ t.Ncaron = 722;
+ t.Iacute = 389;
+ t.plusminus = 570;
+ t.brokenbar = 220;
+ t.registered = 747;
+ t.Gbreve = 778;
+ t.Idotaccent = 389;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 444;
+ t.omacron = 500;
+ t.Zacute = 667;
+ t.Zcaron = 667;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 722;
+ t.lcommaaccent = 278;
+ t.tcaron = 416;
+ t.eogonek = 444;
+ t.Uogonek = 722;
+ t.Aacute = 722;
+ t.Adieresis = 722;
+ t.egrave = 444;
+ t.zacute = 444;
+ t.iogonek = 278;
+ t.Oacute = 778;
+ t.oacute = 500;
+ t.amacron = 500;
+ t.sacute = 389;
+ t.idieresis = 278;
+ t.Ocircumflex = 778;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 556;
+ t.twosuperior = 300;
+ t.Odieresis = 778;
+ t.mu = 556;
+ t.igrave = 278;
+ t.ohungarumlaut = 500;
+ t.Eogonek = 667;
+ t.dcroat = 556;
+ t.threequarters = 750;
+ t.Scedilla = 556;
+ t.lcaron = 394;
+ t.Kcommaaccent = 778;
+ t.Lacute = 667;
+ t.trademark = 1000;
+ t.edotaccent = 444;
+ t.Igrave = 389;
+ t.Imacron = 389;
+ t.Lcaron = 667;
+ t.onehalf = 750;
+ t.lessequal = 549;
+ t.ocircumflex = 500;
+ t.ntilde = 556;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 444;
+ t.gbreve = 500;
+ t.onequarter = 750;
+ t.Scaron = 556;
+ t.Scommaaccent = 556;
+ t.Ohungarumlaut = 778;
+ t.degree = 400;
+ t.ograve = 500;
+ t.Ccaron = 722;
+ t.ugrave = 556;
+ t.radical = 549;
+ t.Dcaron = 722;
+ t.rcommaaccent = 444;
+ t.Ntilde = 722;
+ t.otilde = 500;
+ t.Rcommaaccent = 722;
+ t.Lcommaaccent = 667;
+ t.Atilde = 722;
+ t.Aogonek = 722;
+ t.Aring = 722;
+ t.Otilde = 778;
+ t.zdotaccent = 444;
+ t.Ecaron = 667;
+ t.Iogonek = 389;
+ t.kcommaaccent = 556;
+ t.minus = 570;
+ t.Icircumflex = 389;
+ t.ncaron = 556;
+ t.tcommaaccent = 333;
+ t.logicalnot = 570;
+ t.odieresis = 500;
+ t.udieresis = 556;
+ t.notequal = 549;
+ t.gcommaaccent = 500;
+ t.eth = 500;
+ t.zcaron = 444;
+ t.ncommaaccent = 556;
+ t.onesuperior = 300;
+ t.imacron = 278;
+ t.Euro = 500;
+ });
+ t["Times-BoldItalic"] = getLookupTableFactory(function (t) {
+ t.space = 250;
+ t.exclam = 389;
+ t.quotedbl = 555;
+ t.numbersign = 500;
+ t.dollar = 500;
+ t.percent = 833;
+ t.ampersand = 778;
+ t.quoteright = 333;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 500;
+ t.plus = 570;
+ t.comma = 250;
+ t.hyphen = 333;
+ t.period = 250;
+ t.slash = 278;
+ t.zero = 500;
+ t.one = 500;
+ t.two = 500;
+ t.three = 500;
+ t.four = 500;
+ t.five = 500;
+ t.six = 500;
+ t.seven = 500;
+ t.eight = 500;
+ t.nine = 500;
+ t.colon = 333;
+ t.semicolon = 333;
+ t.less = 570;
+ t.equal = 570;
+ t.greater = 570;
+ t.question = 500;
+ t.at = 832;
+ t.A = 667;
+ t.B = 667;
+ t.C = 667;
+ t.D = 722;
+ t.E = 667;
+ t.F = 667;
+ t.G = 722;
+ t.H = 778;
+ t.I = 389;
+ t.J = 500;
+ t.K = 667;
+ t.L = 611;
+ t.M = 889;
+ t.N = 722;
+ t.O = 722;
+ t.P = 611;
+ t.Q = 722;
+ t.R = 667;
+ t.S = 556;
+ t.T = 611;
+ t.U = 722;
+ t.V = 667;
+ t.W = 889;
+ t.X = 667;
+ t.Y = 611;
+ t.Z = 611;
+ t.bracketleft = 333;
+ t.backslash = 278;
+ t.bracketright = 333;
+ t.asciicircum = 570;
+ t.underscore = 500;
+ t.quoteleft = 333;
+ t.a = 500;
+ t.b = 500;
+ t.c = 444;
+ t.d = 500;
+ t.e = 444;
+ t.f = 333;
+ t.g = 500;
+ t.h = 556;
+ t.i = 278;
+ t.j = 278;
+ t.k = 500;
+ t.l = 278;
+ t.m = 778;
+ t.n = 556;
+ t.o = 500;
+ t.p = 500;
+ t.q = 500;
+ t.r = 389;
+ t.s = 389;
+ t.t = 278;
+ t.u = 556;
+ t.v = 444;
+ t.w = 667;
+ t.x = 500;
+ t.y = 444;
+ t.z = 389;
+ t.braceleft = 348;
+ t.bar = 220;
+ t.braceright = 348;
+ t.asciitilde = 570;
+ t.exclamdown = 389;
+ t.cent = 500;
+ t.sterling = 500;
+ t.fraction = 167;
+ t.yen = 500;
+ t.florin = 500;
+ t.section = 500;
+ t.currency = 500;
+ t.quotesingle = 278;
+ t.quotedblleft = 500;
+ t.guillemotleft = 500;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 556;
+ t.fl = 556;
+ t.endash = 500;
+ t.dagger = 500;
+ t.daggerdbl = 500;
+ t.periodcentered = 250;
+ t.paragraph = 500;
+ t.bullet = 350;
+ t.quotesinglbase = 333;
+ t.quotedblbase = 500;
+ t.quotedblright = 500;
+ t.guillemotright = 500;
+ t.ellipsis = 1000;
+ t.perthousand = 1000;
+ t.questiondown = 500;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 1000;
+ t.AE = 944;
+ t.ordfeminine = 266;
+ t.Lslash = 611;
+ t.Oslash = 722;
+ t.OE = 944;
+ t.ordmasculine = 300;
+ t.ae = 722;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 500;
+ t.oe = 722;
+ t.germandbls = 500;
+ t.Idieresis = 389;
+ t.eacute = 444;
+ t.abreve = 500;
+ t.uhungarumlaut = 556;
+ t.ecaron = 444;
+ t.Ydieresis = 611;
+ t.divide = 570;
+ t.Yacute = 611;
+ t.Acircumflex = 667;
+ t.aacute = 500;
+ t.Ucircumflex = 722;
+ t.yacute = 444;
+ t.scommaaccent = 389;
+ t.ecircumflex = 444;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 500;
+ t.Uacute = 722;
+ t.uogonek = 556;
+ t.Edieresis = 667;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 747;
+ t.Emacron = 667;
+ t.ccaron = 444;
+ t.aring = 500;
+ t.Ncommaaccent = 722;
+ t.lacute = 278;
+ t.agrave = 500;
+ t.Tcommaaccent = 611;
+ t.Cacute = 667;
+ t.atilde = 500;
+ t.Edotaccent = 667;
+ t.scaron = 389;
+ t.scedilla = 389;
+ t.iacute = 278;
+ t.lozenge = 494;
+ t.Rcaron = 667;
+ t.Gcommaaccent = 722;
+ t.ucircumflex = 556;
+ t.acircumflex = 500;
+ t.Amacron = 667;
+ t.rcaron = 389;
+ t.ccedilla = 444;
+ t.Zdotaccent = 611;
+ t.Thorn = 611;
+ t.Omacron = 722;
+ t.Racute = 667;
+ t.Sacute = 556;
+ t.dcaron = 608;
+ t.Umacron = 722;
+ t.uring = 556;
+ t.threesuperior = 300;
+ t.Ograve = 722;
+ t.Agrave = 667;
+ t.Abreve = 667;
+ t.multiply = 570;
+ t.uacute = 556;
+ t.Tcaron = 611;
+ t.partialdiff = 494;
+ t.ydieresis = 444;
+ t.Nacute = 722;
+ t.icircumflex = 278;
+ t.Ecircumflex = 667;
+ t.adieresis = 500;
+ t.edieresis = 444;
+ t.cacute = 444;
+ t.nacute = 556;
+ t.umacron = 556;
+ t.Ncaron = 722;
+ t.Iacute = 389;
+ t.plusminus = 570;
+ t.brokenbar = 220;
+ t.registered = 747;
+ t.Gbreve = 722;
+ t.Idotaccent = 389;
+ t.summation = 600;
+ t.Egrave = 667;
+ t.racute = 389;
+ t.omacron = 500;
+ t.Zacute = 611;
+ t.Zcaron = 611;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 667;
+ t.lcommaaccent = 278;
+ t.tcaron = 366;
+ t.eogonek = 444;
+ t.Uogonek = 722;
+ t.Aacute = 667;
+ t.Adieresis = 667;
+ t.egrave = 444;
+ t.zacute = 389;
+ t.iogonek = 278;
+ t.Oacute = 722;
+ t.oacute = 500;
+ t.amacron = 500;
+ t.sacute = 389;
+ t.idieresis = 278;
+ t.Ocircumflex = 722;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 500;
+ t.twosuperior = 300;
+ t.Odieresis = 722;
+ t.mu = 576;
+ t.igrave = 278;
+ t.ohungarumlaut = 500;
+ t.Eogonek = 667;
+ t.dcroat = 500;
+ t.threequarters = 750;
+ t.Scedilla = 556;
+ t.lcaron = 382;
+ t.Kcommaaccent = 667;
+ t.Lacute = 611;
+ t.trademark = 1000;
+ t.edotaccent = 444;
+ t.Igrave = 389;
+ t.Imacron = 389;
+ t.Lcaron = 611;
+ t.onehalf = 750;
+ t.lessequal = 549;
+ t.ocircumflex = 500;
+ t.ntilde = 556;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 667;
+ t.emacron = 444;
+ t.gbreve = 500;
+ t.onequarter = 750;
+ t.Scaron = 556;
+ t.Scommaaccent = 556;
+ t.Ohungarumlaut = 722;
+ t.degree = 400;
+ t.ograve = 500;
+ t.Ccaron = 667;
+ t.ugrave = 556;
+ t.radical = 549;
+ t.Dcaron = 722;
+ t.rcommaaccent = 389;
+ t.Ntilde = 722;
+ t.otilde = 500;
+ t.Rcommaaccent = 667;
+ t.Lcommaaccent = 611;
+ t.Atilde = 667;
+ t.Aogonek = 667;
+ t.Aring = 667;
+ t.Otilde = 722;
+ t.zdotaccent = 389;
+ t.Ecaron = 667;
+ t.Iogonek = 389;
+ t.kcommaaccent = 500;
+ t.minus = 606;
+ t.Icircumflex = 389;
+ t.ncaron = 556;
+ t.tcommaaccent = 278;
+ t.logicalnot = 606;
+ t.odieresis = 500;
+ t.udieresis = 556;
+ t.notequal = 549;
+ t.gcommaaccent = 500;
+ t.eth = 500;
+ t.zcaron = 389;
+ t.ncommaaccent = 556;
+ t.onesuperior = 300;
+ t.imacron = 278;
+ t.Euro = 500;
+ });
+ t["Times-Italic"] = getLookupTableFactory(function (t) {
+ t.space = 250;
+ t.exclam = 333;
+ t.quotedbl = 420;
+ t.numbersign = 500;
+ t.dollar = 500;
+ t.percent = 833;
+ t.ampersand = 778;
+ t.quoteright = 333;
+ t.parenleft = 333;
+ t.parenright = 333;
+ t.asterisk = 500;
+ t.plus = 675;
+ t.comma = 250;
+ t.hyphen = 333;
+ t.period = 250;
+ t.slash = 278;
+ t.zero = 500;
+ t.one = 500;
+ t.two = 500;
+ t.three = 500;
+ t.four = 500;
+ t.five = 500;
+ t.six = 500;
+ t.seven = 500;
+ t.eight = 500;
+ t.nine = 500;
+ t.colon = 333;
+ t.semicolon = 333;
+ t.less = 675;
+ t.equal = 675;
+ t.greater = 675;
+ t.question = 500;
+ t.at = 920;
+ t.A = 611;
+ t.B = 611;
+ t.C = 667;
+ t.D = 722;
+ t.E = 611;
+ t.F = 611;
+ t.G = 722;
+ t.H = 722;
+ t.I = 333;
+ t.J = 444;
+ t.K = 667;
+ t.L = 556;
+ t.M = 833;
+ t.N = 667;
+ t.O = 722;
+ t.P = 611;
+ t.Q = 722;
+ t.R = 611;
+ t.S = 500;
+ t.T = 556;
+ t.U = 722;
+ t.V = 611;
+ t.W = 833;
+ t.X = 611;
+ t.Y = 556;
+ t.Z = 556;
+ t.bracketleft = 389;
+ t.backslash = 278;
+ t.bracketright = 389;
+ t.asciicircum = 422;
+ t.underscore = 500;
+ t.quoteleft = 333;
+ t.a = 500;
+ t.b = 500;
+ t.c = 444;
+ t.d = 500;
+ t.e = 444;
+ t.f = 278;
+ t.g = 500;
+ t.h = 500;
+ t.i = 278;
+ t.j = 278;
+ t.k = 444;
+ t.l = 278;
+ t.m = 722;
+ t.n = 500;
+ t.o = 500;
+ t.p = 500;
+ t.q = 500;
+ t.r = 389;
+ t.s = 389;
+ t.t = 278;
+ t.u = 500;
+ t.v = 444;
+ t.w = 667;
+ t.x = 444;
+ t.y = 444;
+ t.z = 389;
+ t.braceleft = 400;
+ t.bar = 275;
+ t.braceright = 400;
+ t.asciitilde = 541;
+ t.exclamdown = 389;
+ t.cent = 500;
+ t.sterling = 500;
+ t.fraction = 167;
+ t.yen = 500;
+ t.florin = 500;
+ t.section = 500;
+ t.currency = 500;
+ t.quotesingle = 214;
+ t.quotedblleft = 556;
+ t.guillemotleft = 500;
+ t.guilsinglleft = 333;
+ t.guilsinglright = 333;
+ t.fi = 500;
+ t.fl = 500;
+ t.endash = 500;
+ t.dagger = 500;
+ t.daggerdbl = 500;
+ t.periodcentered = 250;
+ t.paragraph = 523;
+ t.bullet = 350;
+ t.quotesinglbase = 333;
+ t.quotedblbase = 556;
+ t.quotedblright = 556;
+ t.guillemotright = 500;
+ t.ellipsis = 889;
+ t.perthousand = 1000;
+ t.questiondown = 500;
+ t.grave = 333;
+ t.acute = 333;
+ t.circumflex = 333;
+ t.tilde = 333;
+ t.macron = 333;
+ t.breve = 333;
+ t.dotaccent = 333;
+ t.dieresis = 333;
+ t.ring = 333;
+ t.cedilla = 333;
+ t.hungarumlaut = 333;
+ t.ogonek = 333;
+ t.caron = 333;
+ t.emdash = 889;
+ t.AE = 889;
+ t.ordfeminine = 276;
+ t.Lslash = 556;
+ t.Oslash = 722;
+ t.OE = 944;
+ t.ordmasculine = 310;
+ t.ae = 667;
+ t.dotlessi = 278;
+ t.lslash = 278;
+ t.oslash = 500;
+ t.oe = 667;
+ t.germandbls = 500;
+ t.Idieresis = 333;
+ t.eacute = 444;
+ t.abreve = 500;
+ t.uhungarumlaut = 500;
+ t.ecaron = 444;
+ t.Ydieresis = 556;
+ t.divide = 675;
+ t.Yacute = 556;
+ t.Acircumflex = 611;
+ t.aacute = 500;
+ t.Ucircumflex = 722;
+ t.yacute = 444;
+ t.scommaaccent = 389;
+ t.ecircumflex = 444;
+ t.Uring = 722;
+ t.Udieresis = 722;
+ t.aogonek = 500;
+ t.Uacute = 722;
+ t.uogonek = 500;
+ t.Edieresis = 611;
+ t.Dcroat = 722;
+ t.commaaccent = 250;
+ t.copyright = 760;
+ t.Emacron = 611;
+ t.ccaron = 444;
+ t.aring = 500;
+ t.Ncommaaccent = 667;
+ t.lacute = 278;
+ t.agrave = 500;
+ t.Tcommaaccent = 556;
+ t.Cacute = 667;
+ t.atilde = 500;
+ t.Edotaccent = 611;
+ t.scaron = 389;
+ t.scedilla = 389;
+ t.iacute = 278;
+ t.lozenge = 471;
+ t.Rcaron = 611;
+ t.Gcommaaccent = 722;
+ t.ucircumflex = 500;
+ t.acircumflex = 500;
+ t.Amacron = 611;
+ t.rcaron = 389;
+ t.ccedilla = 444;
+ t.Zdotaccent = 556;
+ t.Thorn = 611;
+ t.Omacron = 722;
+ t.Racute = 611;
+ t.Sacute = 500;
+ t.dcaron = 544;
+ t.Umacron = 722;
+ t.uring = 500;
+ t.threesuperior = 300;
+ t.Ograve = 722;
+ t.Agrave = 611;
+ t.Abreve = 611;
+ t.multiply = 675;
+ t.uacute = 500;
+ t.Tcaron = 556;
+ t.partialdiff = 476;
+ t.ydieresis = 444;
+ t.Nacute = 667;
+ t.icircumflex = 278;
+ t.Ecircumflex = 611;
+ t.adieresis = 500;
+ t.edieresis = 444;
+ t.cacute = 444;
+ t.nacute = 500;
+ t.umacron = 500;
+ t.Ncaron = 667;
+ t.Iacute = 333;
+ t.plusminus = 675;
+ t.brokenbar = 275;
+ t.registered = 760;
+ t.Gbreve = 722;
+ t.Idotaccent = 333;
+ t.summation = 600;
+ t.Egrave = 611;
+ t.racute = 389;
+ t.omacron = 500;
+ t.Zacute = 556;
+ t.Zcaron = 556;
+ t.greaterequal = 549;
+ t.Eth = 722;
+ t.Ccedilla = 667;
+ t.lcommaaccent = 278;
+ t.tcaron = 300;
+ t.eogonek = 444;
+ t.Uogonek = 722;
+ t.Aacute = 611;
+ t.Adieresis = 611;
+ t.egrave = 444;
+ t.zacute = 389;
+ t.iogonek = 278;
+ t.Oacute = 722;
+ t.oacute = 500;
+ t.amacron = 500;
+ t.sacute = 389;
+ t.idieresis = 278;
+ t.Ocircumflex = 722;
+ t.Ugrave = 722;
+ t.Delta = 612;
+ t.thorn = 500;
+ t.twosuperior = 300;
+ t.Odieresis = 722;
+ t.mu = 500;
+ t.igrave = 278;
+ t.ohungarumlaut = 500;
+ t.Eogonek = 611;
+ t.dcroat = 500;
+ t.threequarters = 750;
+ t.Scedilla = 500;
+ t.lcaron = 300;
+ t.Kcommaaccent = 667;
+ t.Lacute = 556;
+ t.trademark = 980;
+ t.edotaccent = 444;
+ t.Igrave = 333;
+ t.Imacron = 333;
+ t.Lcaron = 611;
+ t.onehalf = 750;
+ t.lessequal = 549;
+ t.ocircumflex = 500;
+ t.ntilde = 500;
+ t.Uhungarumlaut = 722;
+ t.Eacute = 611;
+ t.emacron = 444;
+ t.gbreve = 500;
+ t.onequarter = 750;
+ t.Scaron = 500;
+ t.Scommaaccent = 500;
+ t.Ohungarumlaut = 722;
+ t.degree = 400;
+ t.ograve = 500;
+ t.Ccaron = 667;
+ t.ugrave = 500;
+ t.radical = 453;
+ t.Dcaron = 722;
+ t.rcommaaccent = 389;
+ t.Ntilde = 667;
+ t.otilde = 500;
+ t.Rcommaaccent = 611;
+ t.Lcommaaccent = 556;
+ t.Atilde = 611;
+ t.Aogonek = 611;
+ t.Aring = 611;
+ t.Otilde = 722;
+ t.zdotaccent = 389;
+ t.Ecaron = 611;
+ t.Iogonek = 333;
+ t.kcommaaccent = 444;
+ t.minus = 675;
+ t.Icircumflex = 333;
+ t.ncaron = 500;
+ t.tcommaaccent = 278;
+ t.logicalnot = 675;
+ t.odieresis = 500;
+ t.udieresis = 500;
+ t.notequal = 549;
+ t.gcommaaccent = 500;
+ t.eth = 500;
+ t.zcaron = 389;
+ t.ncommaaccent = 500;
+ t.onesuperior = 300;
+ t.imacron = 278;
+ t.Euro = 500;
+ });
+ t.ZapfDingbats = getLookupTableFactory(function (t) {
+ t.space = 278;
+ t.a1 = 974;
+ t.a2 = 961;
+ t.a202 = 974;
+ t.a3 = 980;
+ t.a4 = 719;
+ t.a5 = 789;
+ t.a119 = 790;
+ t.a118 = 791;
+ t.a117 = 690;
+ t.a11 = 960;
+ t.a12 = 939;
+ t.a13 = 549;
+ t.a14 = 855;
+ t.a15 = 911;
+ t.a16 = 933;
+ t.a105 = 911;
+ t.a17 = 945;
+ t.a18 = 974;
+ t.a19 = 755;
+ t.a20 = 846;
+ t.a21 = 762;
+ t.a22 = 761;
+ t.a23 = 571;
+ t.a24 = 677;
+ t.a25 = 763;
+ t.a26 = 760;
+ t.a27 = 759;
+ t.a28 = 754;
+ t.a6 = 494;
+ t.a7 = 552;
+ t.a8 = 537;
+ t.a9 = 577;
+ t.a10 = 692;
+ t.a29 = 786;
+ t.a30 = 788;
+ t.a31 = 788;
+ t.a32 = 790;
+ t.a33 = 793;
+ t.a34 = 794;
+ t.a35 = 816;
+ t.a36 = 823;
+ t.a37 = 789;
+ t.a38 = 841;
+ t.a39 = 823;
+ t.a40 = 833;
+ t.a41 = 816;
+ t.a42 = 831;
+ t.a43 = 923;
+ t.a44 = 744;
+ t.a45 = 723;
+ t.a46 = 749;
+ t.a47 = 790;
+ t.a48 = 792;
+ t.a49 = 695;
+ t.a50 = 776;
+ t.a51 = 768;
+ t.a52 = 792;
+ t.a53 = 759;
+ t.a54 = 707;
+ t.a55 = 708;
+ t.a56 = 682;
+ t.a57 = 701;
+ t.a58 = 826;
+ t.a59 = 815;
+ t.a60 = 789;
+ t.a61 = 789;
+ t.a62 = 707;
+ t.a63 = 687;
+ t.a64 = 696;
+ t.a65 = 689;
+ t.a66 = 786;
+ t.a67 = 787;
+ t.a68 = 713;
+ t.a69 = 791;
+ t.a70 = 785;
+ t.a71 = 791;
+ t.a72 = 873;
+ t.a73 = 761;
+ t.a74 = 762;
+ t.a203 = 762;
+ t.a75 = 759;
+ t.a204 = 759;
+ t.a76 = 892;
+ t.a77 = 892;
+ t.a78 = 788;
+ t.a79 = 784;
+ t.a81 = 438;
+ t.a82 = 138;
+ t.a83 = 277;
+ t.a84 = 415;
+ t.a97 = 392;
+ t.a98 = 392;
+ t.a99 = 668;
+ t.a100 = 668;
+ t.a89 = 390;
+ t.a90 = 390;
+ t.a93 = 317;
+ t.a94 = 317;
+ t.a91 = 276;
+ t.a92 = 276;
+ t.a205 = 509;
+ t.a85 = 509;
+ t.a206 = 410;
+ t.a86 = 410;
+ t.a87 = 234;
+ t.a88 = 234;
+ t.a95 = 334;
+ t.a96 = 334;
+ t.a101 = 732;
+ t.a102 = 544;
+ t.a103 = 544;
+ t.a104 = 910;
+ t.a106 = 667;
+ t.a107 = 760;
+ t.a108 = 760;
+ t.a112 = 776;
+ t.a111 = 595;
+ t.a110 = 694;
+ t.a109 = 626;
+ t.a120 = 788;
+ t.a121 = 788;
+ t.a122 = 788;
+ t.a123 = 788;
+ t.a124 = 788;
+ t.a125 = 788;
+ t.a126 = 788;
+ t.a127 = 788;
+ t.a128 = 788;
+ t.a129 = 788;
+ t.a130 = 788;
+ t.a131 = 788;
+ t.a132 = 788;
+ t.a133 = 788;
+ t.a134 = 788;
+ t.a135 = 788;
+ t.a136 = 788;
+ t.a137 = 788;
+ t.a138 = 788;
+ t.a139 = 788;
+ t.a140 = 788;
+ t.a141 = 788;
+ t.a142 = 788;
+ t.a143 = 788;
+ t.a144 = 788;
+ t.a145 = 788;
+ t.a146 = 788;
+ t.a147 = 788;
+ t.a148 = 788;
+ t.a149 = 788;
+ t.a150 = 788;
+ t.a151 = 788;
+ t.a152 = 788;
+ t.a153 = 788;
+ t.a154 = 788;
+ t.a155 = 788;
+ t.a156 = 788;
+ t.a157 = 788;
+ t.a158 = 788;
+ t.a159 = 788;
+ t.a160 = 894;
+ t.a161 = 838;
+ t.a163 = 1016;
+ t.a164 = 458;
+ t.a196 = 748;
+ t.a165 = 924;
+ t.a192 = 748;
+ t.a166 = 918;
+ t.a167 = 927;
+ t.a168 = 928;
+ t.a169 = 928;
+ t.a170 = 834;
+ t.a171 = 873;
+ t.a172 = 828;
+ t.a173 = 924;
+ t.a162 = 924;
+ t.a174 = 917;
+ t.a175 = 930;
+ t.a176 = 931;
+ t.a177 = 463;
+ t.a178 = 883;
+ t.a179 = 836;
+ t.a193 = 836;
+ t.a180 = 867;
+ t.a199 = 867;
+ t.a181 = 696;
+ t.a200 = 696;
+ t.a182 = 874;
+ t.a201 = 874;
+ t.a183 = 760;
+ t.a184 = 946;
+ t.a197 = 771;
+ t.a185 = 865;
+ t.a194 = 771;
+ t.a198 = 888;
+ t.a186 = 967;
+ t.a195 = 888;
+ t.a187 = 831;
+ t.a188 = 873;
+ t.a189 = 927;
+ t.a190 = 970;
+ t.a191 = 918;
+ });
+});
+const getFontBasicMetrics = getLookupTableFactory(function (t) {
+ t.Courier = {
+ ascent: 629,
+ descent: -157,
+ capHeight: 562,
+ xHeight: -426
+ };
+ t["Courier-Bold"] = {
+ ascent: 629,
+ descent: -157,
+ capHeight: 562,
+ xHeight: 439
+ };
+ t["Courier-Oblique"] = {
+ ascent: 629,
+ descent: -157,
+ capHeight: 562,
+ xHeight: 426
+ };
+ t["Courier-BoldOblique"] = {
+ ascent: 629,
+ descent: -157,
+ capHeight: 562,
+ xHeight: 426
+ };
+ t.Helvetica = {
+ ascent: 718,
+ descent: -207,
+ capHeight: 718,
+ xHeight: 523
+ };
+ t["Helvetica-Bold"] = {
+ ascent: 718,
+ descent: -207,
+ capHeight: 718,
+ xHeight: 532
+ };
+ t["Helvetica-Oblique"] = {
+ ascent: 718,
+ descent: -207,
+ capHeight: 718,
+ xHeight: 523
+ };
+ t["Helvetica-BoldOblique"] = {
+ ascent: 718,
+ descent: -207,
+ capHeight: 718,
+ xHeight: 532
+ };
+ t["Times-Roman"] = {
+ ascent: 683,
+ descent: -217,
+ capHeight: 662,
+ xHeight: 450
+ };
+ t["Times-Bold"] = {
+ ascent: 683,
+ descent: -217,
+ capHeight: 676,
+ xHeight: 461
+ };
+ t["Times-Italic"] = {
+ ascent: 683,
+ descent: -217,
+ capHeight: 653,
+ xHeight: 441
+ };
+ t["Times-BoldItalic"] = {
+ ascent: 683,
+ descent: -217,
+ capHeight: 669,
+ xHeight: 462
+ };
+ t.Symbol = {
+ ascent: Math.NaN,
+ descent: Math.NaN,
+ capHeight: Math.NaN,
+ xHeight: Math.NaN
+ };
+ t.ZapfDingbats = {
+ ascent: Math.NaN,
+ descent: Math.NaN,
+ capHeight: Math.NaN,
+ xHeight: Math.NaN
+ };
+});
+
+;// CONCATENATED MODULE: ./src/core/glyf.js
+const ON_CURVE_POINT = 1 << 0;
+const X_SHORT_VECTOR = 1 << 1;
+const Y_SHORT_VECTOR = 1 << 2;
+const REPEAT_FLAG = 1 << 3;
+const X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR = 1 << 4;
+const Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR = 1 << 5;
+const OVERLAP_SIMPLE = 1 << 6;
+const ARG_1_AND_2_ARE_WORDS = 1 << 0;
+const ARGS_ARE_XY_VALUES = 1 << 1;
+const WE_HAVE_A_SCALE = 1 << 3;
+const MORE_COMPONENTS = 1 << 5;
+const WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
+const WE_HAVE_A_TWO_BY_TWO = 1 << 7;
+const WE_HAVE_INSTRUCTIONS = 1 << 8;
+class GlyfTable {
+ constructor({
+ glyfTable,
+ isGlyphLocationsLong,
+ locaTable,
+ numGlyphs
+ }) {
+ this.glyphs = [];
+ const loca = new DataView(locaTable.buffer, locaTable.byteOffset, locaTable.byteLength);
+ const glyf = new DataView(glyfTable.buffer, glyfTable.byteOffset, glyfTable.byteLength);
+ const offsetSize = isGlyphLocationsLong ? 4 : 2;
+ let prev = isGlyphLocationsLong ? loca.getUint32(0) : 2 * loca.getUint16(0);
+ let pos = 0;
+ for (let i = 0; i < numGlyphs; i++) {
+ pos += offsetSize;
+ const next = isGlyphLocationsLong ? loca.getUint32(pos) : 2 * loca.getUint16(pos);
+ if (next === prev) {
+ this.glyphs.push(new Glyph({}));
+ continue;
+ }
+ const glyph = Glyph.parse(prev, glyf);
+ this.glyphs.push(glyph);
+ prev = next;
+ }
+ }
+ getSize() {
+ return this.glyphs.reduce((a, g) => {
+ const size = g.getSize();
+ return a + (size + 3 & ~3);
+ }, 0);
+ }
+ write() {
+ const totalSize = this.getSize();
+ const glyfTable = new DataView(new ArrayBuffer(totalSize));
+ const isLocationLong = totalSize > 0x1fffe;
+ const offsetSize = isLocationLong ? 4 : 2;
+ const locaTable = new DataView(new ArrayBuffer((this.glyphs.length + 1) * offsetSize));
+ if (isLocationLong) {
+ locaTable.setUint32(0, 0);
+ } else {
+ locaTable.setUint16(0, 0);
+ }
+ let pos = 0;
+ let locaIndex = 0;
+ for (const glyph of this.glyphs) {
+ pos += glyph.write(pos, glyfTable);
+ pos = pos + 3 & ~3;
+ locaIndex += offsetSize;
+ if (isLocationLong) {
+ locaTable.setUint32(locaIndex, pos);
+ } else {
+ locaTable.setUint16(locaIndex, pos >> 1);
+ }
+ }
+ return {
+ isLocationLong,
+ loca: new Uint8Array(locaTable.buffer),
+ glyf: new Uint8Array(glyfTable.buffer)
+ };
+ }
+ scale(factors) {
+ for (let i = 0, ii = this.glyphs.length; i < ii; i++) {
+ this.glyphs[i].scale(factors[i]);
+ }
+ }
+}
+class Glyph {
+ constructor({
+ header = null,
+ simple = null,
+ composites = null
+ }) {
+ this.header = header;
+ this.simple = simple;
+ this.composites = composites;
+ }
+ static parse(pos, glyf) {
+ const [read, header] = GlyphHeader.parse(pos, glyf);
+ pos += read;
+ if (header.numberOfContours < 0) {
+ const composites = [];
+ while (true) {
+ const [n, composite] = CompositeGlyph.parse(pos, glyf);
+ pos += n;
+ composites.push(composite);
+ if (!(composite.flags & MORE_COMPONENTS)) {
+ break;
+ }
+ }
+ return new Glyph({
+ header,
+ composites
+ });
+ }
+ const simple = SimpleGlyph.parse(pos, glyf, header.numberOfContours);
+ return new Glyph({
+ header,
+ simple
+ });
+ }
+ getSize() {
+ if (!this.header) {
+ return 0;
+ }
+ const size = this.simple ? this.simple.getSize() : this.composites.reduce((a, c) => a + c.getSize(), 0);
+ return this.header.getSize() + size;
+ }
+ write(pos, buf) {
+ if (!this.header) {
+ return 0;
+ }
+ const spos = pos;
+ pos += this.header.write(pos, buf);
+ if (this.simple) {
+ pos += this.simple.write(pos, buf);
+ } else {
+ for (const composite of this.composites) {
+ pos += composite.write(pos, buf);
+ }
+ }
+ return pos - spos;
+ }
+ scale(factor) {
+ if (!this.header) {
+ return;
+ }
+ const xMiddle = (this.header.xMin + this.header.xMax) / 2;
+ this.header.scale(xMiddle, factor);
+ if (this.simple) {
+ this.simple.scale(xMiddle, factor);
+ } else {
+ for (const composite of this.composites) {
+ composite.scale(xMiddle, factor);
+ }
+ }
+ }
+}
+class GlyphHeader {
+ constructor({
+ numberOfContours,
+ xMin,
+ yMin,
+ xMax,
+ yMax
+ }) {
+ this.numberOfContours = numberOfContours;
+ this.xMin = xMin;
+ this.yMin = yMin;
+ this.xMax = xMax;
+ this.yMax = yMax;
+ }
+ static parse(pos, glyf) {
+ return [10, new GlyphHeader({
+ numberOfContours: glyf.getInt16(pos),
+ xMin: glyf.getInt16(pos + 2),
+ yMin: glyf.getInt16(pos + 4),
+ xMax: glyf.getInt16(pos + 6),
+ yMax: glyf.getInt16(pos + 8)
+ })];
+ }
+ getSize() {
+ return 10;
+ }
+ write(pos, buf) {
+ buf.setInt16(pos, this.numberOfContours);
+ buf.setInt16(pos + 2, this.xMin);
+ buf.setInt16(pos + 4, this.yMin);
+ buf.setInt16(pos + 6, this.xMax);
+ buf.setInt16(pos + 8, this.yMax);
+ return 10;
+ }
+ scale(x, factor) {
+ this.xMin = Math.round(x + (this.xMin - x) * factor);
+ this.xMax = Math.round(x + (this.xMax - x) * factor);
+ }
+}
+class Contour {
+ constructor({
+ flags,
+ xCoordinates,
+ yCoordinates
+ }) {
+ this.xCoordinates = xCoordinates;
+ this.yCoordinates = yCoordinates;
+ this.flags = flags;
+ }
+}
+class SimpleGlyph {
+ constructor({
+ contours,
+ instructions
+ }) {
+ this.contours = contours;
+ this.instructions = instructions;
+ }
+ static parse(pos, glyf, numberOfContours) {
+ const endPtsOfContours = [];
+ for (let i = 0; i < numberOfContours; i++) {
+ const endPt = glyf.getUint16(pos);
+ pos += 2;
+ endPtsOfContours.push(endPt);
+ }
+ const numberOfPt = endPtsOfContours[numberOfContours - 1] + 1;
+ const instructionLength = glyf.getUint16(pos);
+ pos += 2;
+ const instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength);
+ pos += instructionLength;
+ const flags = [];
+ for (let i = 0; i < numberOfPt; pos++, i++) {
+ let flag = glyf.getUint8(pos);
+ flags.push(flag);
+ if (flag & REPEAT_FLAG) {
+ const count = glyf.getUint8(++pos);
+ flag ^= REPEAT_FLAG;
+ for (let m = 0; m < count; m++) {
+ flags.push(flag);
+ }
+ i += count;
+ }
+ }
+ const allXCoordinates = [];
+ let xCoordinates = [];
+ let yCoordinates = [];
+ let pointFlags = [];
+ const contours = [];
+ let endPtsOfContoursIndex = 0;
+ let lastCoordinate = 0;
+ for (let i = 0; i < numberOfPt; i++) {
+ const flag = flags[i];
+ if (flag & X_SHORT_VECTOR) {
+ const x = glyf.getUint8(pos++);
+ lastCoordinate += flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR ? x : -x;
+ xCoordinates.push(lastCoordinate);
+ } else if (flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR) {
+ xCoordinates.push(lastCoordinate);
+ } else {
+ lastCoordinate += glyf.getInt16(pos);
+ pos += 2;
+ xCoordinates.push(lastCoordinate);
+ }
+ if (endPtsOfContours[endPtsOfContoursIndex] === i) {
+ endPtsOfContoursIndex++;
+ allXCoordinates.push(xCoordinates);
+ xCoordinates = [];
+ }
+ }
+ lastCoordinate = 0;
+ endPtsOfContoursIndex = 0;
+ for (let i = 0; i < numberOfPt; i++) {
+ const flag = flags[i];
+ if (flag & Y_SHORT_VECTOR) {
+ const y = glyf.getUint8(pos++);
+ lastCoordinate += flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR ? y : -y;
+ yCoordinates.push(lastCoordinate);
+ } else if (flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR) {
+ yCoordinates.push(lastCoordinate);
+ } else {
+ lastCoordinate += glyf.getInt16(pos);
+ pos += 2;
+ yCoordinates.push(lastCoordinate);
+ }
+ pointFlags.push(flag & ON_CURVE_POINT | flag & OVERLAP_SIMPLE);
+ if (endPtsOfContours[endPtsOfContoursIndex] === i) {
+ xCoordinates = allXCoordinates[endPtsOfContoursIndex];
+ endPtsOfContoursIndex++;
+ contours.push(new Contour({
+ flags: pointFlags,
+ xCoordinates,
+ yCoordinates
+ }));
+ yCoordinates = [];
+ pointFlags = [];
+ }
+ }
+ return new SimpleGlyph({
+ contours,
+ instructions
+ });
+ }
+ getSize() {
+ let size = this.contours.length * 2 + 2 + this.instructions.length;
+ let lastX = 0;
+ let lastY = 0;
+ for (const contour of this.contours) {
+ size += contour.flags.length;
+ for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {
+ const x = contour.xCoordinates[i];
+ const y = contour.yCoordinates[i];
+ let abs = Math.abs(x - lastX);
+ if (abs > 255) {
+ size += 2;
+ } else if (abs > 0) {
+ size += 1;
+ }
+ lastX = x;
+ abs = Math.abs(y - lastY);
+ if (abs > 255) {
+ size += 2;
+ } else if (abs > 0) {
+ size += 1;
+ }
+ lastY = y;
+ }
+ }
+ return size;
+ }
+ write(pos, buf) {
+ const spos = pos;
+ const xCoordinates = [];
+ const yCoordinates = [];
+ const flags = [];
+ let lastX = 0;
+ let lastY = 0;
+ for (const contour of this.contours) {
+ for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {
+ let flag = contour.flags[i];
+ const x = contour.xCoordinates[i];
+ let delta = x - lastX;
+ if (delta === 0) {
+ flag |= X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR;
+ xCoordinates.push(0);
+ } else {
+ const abs = Math.abs(delta);
+ if (abs <= 255) {
+ flag |= delta >= 0 ? X_SHORT_VECTOR | X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR : X_SHORT_VECTOR;
+ xCoordinates.push(abs);
+ } else {
+ xCoordinates.push(delta);
+ }
+ }
+ lastX = x;
+ const y = contour.yCoordinates[i];
+ delta = y - lastY;
+ if (delta === 0) {
+ flag |= Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR;
+ yCoordinates.push(0);
+ } else {
+ const abs = Math.abs(delta);
+ if (abs <= 255) {
+ flag |= delta >= 0 ? Y_SHORT_VECTOR | Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR : Y_SHORT_VECTOR;
+ yCoordinates.push(abs);
+ } else {
+ yCoordinates.push(delta);
+ }
+ }
+ lastY = y;
+ flags.push(flag);
+ }
+ buf.setUint16(pos, xCoordinates.length - 1);
+ pos += 2;
+ }
+ buf.setUint16(pos, this.instructions.length);
+ pos += 2;
+ if (this.instructions.length) {
+ new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos);
+ pos += this.instructions.length;
+ }
+ for (const flag of flags) {
+ buf.setUint8(pos++, flag);
+ }
+ for (let i = 0, ii = xCoordinates.length; i < ii; i++) {
+ const x = xCoordinates[i];
+ const flag = flags[i];
+ if (flag & X_SHORT_VECTOR) {
+ buf.setUint8(pos++, x);
+ } else if (!(flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR)) {
+ buf.setInt16(pos, x);
+ pos += 2;
+ }
+ }
+ for (let i = 0, ii = yCoordinates.length; i < ii; i++) {
+ const y = yCoordinates[i];
+ const flag = flags[i];
+ if (flag & Y_SHORT_VECTOR) {
+ buf.setUint8(pos++, y);
+ } else if (!(flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR)) {
+ buf.setInt16(pos, y);
+ pos += 2;
+ }
+ }
+ return pos - spos;
+ }
+ scale(x, factor) {
+ for (const contour of this.contours) {
+ if (contour.xCoordinates.length === 0) {
+ continue;
+ }
+ for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) {
+ contour.xCoordinates[i] = Math.round(x + (contour.xCoordinates[i] - x) * factor);
+ }
+ }
+ }
+}
+class CompositeGlyph {
+ constructor({
+ flags,
+ glyphIndex,
+ argument1,
+ argument2,
+ transf,
+ instructions
+ }) {
+ this.flags = flags;
+ this.glyphIndex = glyphIndex;
+ this.argument1 = argument1;
+ this.argument2 = argument2;
+ this.transf = transf;
+ this.instructions = instructions;
+ }
+ static parse(pos, glyf) {
+ const spos = pos;
+ const transf = [];
+ let flags = glyf.getUint16(pos);
+ const glyphIndex = glyf.getUint16(pos + 2);
+ pos += 4;
+ let argument1, argument2;
+ if (flags & ARG_1_AND_2_ARE_WORDS) {
+ if (flags & ARGS_ARE_XY_VALUES) {
+ argument1 = glyf.getInt16(pos);
+ argument2 = glyf.getInt16(pos + 2);
+ } else {
+ argument1 = glyf.getUint16(pos);
+ argument2 = glyf.getUint16(pos + 2);
+ }
+ pos += 4;
+ flags ^= ARG_1_AND_2_ARE_WORDS;
+ } else {
+ if (flags & ARGS_ARE_XY_VALUES) {
+ argument1 = glyf.getInt8(pos);
+ argument2 = glyf.getInt8(pos + 1);
+ } else {
+ argument1 = glyf.getUint8(pos);
+ argument2 = glyf.getUint8(pos + 1);
+ }
+ pos += 2;
+ }
+ if (flags & WE_HAVE_A_SCALE) {
+ transf.push(glyf.getUint16(pos));
+ pos += 2;
+ } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+ transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2));
+ pos += 4;
+ } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
+ transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2), glyf.getUint16(pos + 4), glyf.getUint16(pos + 6));
+ pos += 8;
+ }
+ let instructions = null;
+ if (flags & WE_HAVE_INSTRUCTIONS) {
+ const instructionLength = glyf.getUint16(pos);
+ pos += 2;
+ instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength);
+ pos += instructionLength;
+ }
+ return [pos - spos, new CompositeGlyph({
+ flags,
+ glyphIndex,
+ argument1,
+ argument2,
+ transf,
+ instructions
+ })];
+ }
+ getSize() {
+ let size = 2 + 2 + this.transf.length * 2;
+ if (this.flags & WE_HAVE_INSTRUCTIONS) {
+ size += 2 + this.instructions.length;
+ }
+ size += 2;
+ if (this.flags & 2) {
+ if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) {
+ size += 2;
+ }
+ } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) {
+ size += 2;
+ }
+ return size;
+ }
+ write(pos, buf) {
+ const spos = pos;
+ if (this.flags & ARGS_ARE_XY_VALUES) {
+ if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) {
+ this.flags |= ARG_1_AND_2_ARE_WORDS;
+ }
+ } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) {
+ this.flags |= ARG_1_AND_2_ARE_WORDS;
+ }
+ buf.setUint16(pos, this.flags);
+ buf.setUint16(pos + 2, this.glyphIndex);
+ pos += 4;
+ if (this.flags & ARG_1_AND_2_ARE_WORDS) {
+ if (this.flags & ARGS_ARE_XY_VALUES) {
+ buf.setInt16(pos, this.argument1);
+ buf.setInt16(pos + 2, this.argument2);
+ } else {
+ buf.setUint16(pos, this.argument1);
+ buf.setUint16(pos + 2, this.argument2);
+ }
+ pos += 4;
+ } else {
+ buf.setUint8(pos, this.argument1);
+ buf.setUint8(pos + 1, this.argument2);
+ pos += 2;
+ }
+ if (this.flags & WE_HAVE_INSTRUCTIONS) {
+ buf.setUint16(pos, this.instructions.length);
+ pos += 2;
+ if (this.instructions.length) {
+ new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos);
+ pos += this.instructions.length;
+ }
+ }
+ return pos - spos;
+ }
+ scale(x, factor) {}
+}
+
+;// CONCATENATED MODULE: ./src/core/opentype_file_builder.js
+
+
+function writeInt16(dest, offset, num) {
+ dest[offset] = num >> 8 & 0xff;
+ dest[offset + 1] = num & 0xff;
+}
+function writeInt32(dest, offset, num) {
+ dest[offset] = num >> 24 & 0xff;
+ dest[offset + 1] = num >> 16 & 0xff;
+ dest[offset + 2] = num >> 8 & 0xff;
+ dest[offset + 3] = num & 0xff;
+}
+function writeData(dest, offset, data) {
+ if (data instanceof Uint8Array) {
+ dest.set(data, offset);
+ } else if (typeof data === "string") {
+ for (let i = 0, ii = data.length; i < ii; i++) {
+ dest[offset++] = data.charCodeAt(i) & 0xff;
+ }
+ } else {
+ for (const num of data) {
+ dest[offset++] = num & 0xff;
+ }
+ }
+}
+const OTF_HEADER_SIZE = 12;
+const OTF_TABLE_ENTRY_SIZE = 16;
+class OpenTypeFileBuilder {
+ constructor(sfnt) {
+ this.sfnt = sfnt;
+ this.tables = Object.create(null);
+ }
+ static getSearchParams(entriesCount, entrySize) {
+ let maxPower2 = 1,
+ log2 = 0;
+ while ((maxPower2 ^ entriesCount) > maxPower2) {
+ maxPower2 <<= 1;
+ log2++;
+ }
+ const searchRange = maxPower2 * entrySize;
+ return {
+ range: searchRange,
+ entry: log2,
+ rangeShift: entrySize * entriesCount - searchRange
+ };
+ }
+ toArray() {
+ let sfnt = this.sfnt;
+ const tables = this.tables;
+ const tablesNames = Object.keys(tables);
+ tablesNames.sort();
+ const numTables = tablesNames.length;
+ let i, j, jj, table, tableName;
+ let offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE;
+ const tableOffsets = [offset];
+ for (i = 0; i < numTables; i++) {
+ table = tables[tablesNames[i]];
+ const paddedLength = (table.length + 3 & ~3) >>> 0;
+ offset += paddedLength;
+ tableOffsets.push(offset);
+ }
+ const file = new Uint8Array(offset);
+ for (i = 0; i < numTables; i++) {
+ table = tables[tablesNames[i]];
+ writeData(file, tableOffsets[i], table);
+ }
+ if (sfnt === "true") {
+ sfnt = string32(0x00010000);
+ }
+ file[0] = sfnt.charCodeAt(0) & 0xff;
+ file[1] = sfnt.charCodeAt(1) & 0xff;
+ file[2] = sfnt.charCodeAt(2) & 0xff;
+ file[3] = sfnt.charCodeAt(3) & 0xff;
+ writeInt16(file, 4, numTables);
+ const searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16);
+ writeInt16(file, 6, searchParams.range);
+ writeInt16(file, 8, searchParams.entry);
+ writeInt16(file, 10, searchParams.rangeShift);
+ offset = OTF_HEADER_SIZE;
+ for (i = 0; i < numTables; i++) {
+ tableName = tablesNames[i];
+ file[offset] = tableName.charCodeAt(0) & 0xff;
+ file[offset + 1] = tableName.charCodeAt(1) & 0xff;
+ file[offset + 2] = tableName.charCodeAt(2) & 0xff;
+ file[offset + 3] = tableName.charCodeAt(3) & 0xff;
+ let checksum = 0;
+ for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) {
+ const quad = readUint32(file, j);
+ checksum = checksum + quad >>> 0;
+ }
+ writeInt32(file, offset + 4, checksum);
+ writeInt32(file, offset + 8, tableOffsets[i]);
+ writeInt32(file, offset + 12, tables[tableName].length);
+ offset += OTF_TABLE_ENTRY_SIZE;
+ }
+ return file;
+ }
+ addTable(tag, data) {
+ if (tag in this.tables) {
+ throw new Error("Table " + tag + " already exists");
+ }
+ this.tables[tag] = data;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/type1_parser.js
+
+
+
+
+const HINTING_ENABLED = false;
+const COMMAND_MAP = {
+ hstem: [1],
+ vstem: [3],
+ vmoveto: [4],
+ rlineto: [5],
+ hlineto: [6],
+ vlineto: [7],
+ rrcurveto: [8],
+ callsubr: [10],
+ flex: [12, 35],
+ drop: [12, 18],
+ endchar: [14],
+ rmoveto: [21],
+ hmoveto: [22],
+ vhcurveto: [30],
+ hvcurveto: [31]
+};
+class Type1CharString {
+ constructor() {
+ this.width = 0;
+ this.lsb = 0;
+ this.flexing = false;
+ this.output = [];
+ this.stack = [];
+ }
+ convert(encoded, subrs, seacAnalysisEnabled) {
+ const count = encoded.length;
+ let error = false;
+ let wx, sbx, subrNumber;
+ for (let i = 0; i < count; i++) {
+ let value = encoded[i];
+ if (value < 32) {
+ if (value === 12) {
+ value = (value << 8) + encoded[++i];
+ }
+ switch (value) {
+ case 1:
+ if (!HINTING_ENABLED) {
+ this.stack = [];
+ break;
+ }
+ error = this.executeCommand(2, COMMAND_MAP.hstem);
+ break;
+ case 3:
+ if (!HINTING_ENABLED) {
+ this.stack = [];
+ break;
+ }
+ error = this.executeCommand(2, COMMAND_MAP.vstem);
+ break;
+ case 4:
+ if (this.flexing) {
+ if (this.stack.length < 1) {
+ error = true;
+ break;
+ }
+ const dy = this.stack.pop();
+ this.stack.push(0, dy);
+ break;
+ }
+ error = this.executeCommand(1, COMMAND_MAP.vmoveto);
+ break;
+ case 5:
+ error = this.executeCommand(2, COMMAND_MAP.rlineto);
+ break;
+ case 6:
+ error = this.executeCommand(1, COMMAND_MAP.hlineto);
+ break;
+ case 7:
+ error = this.executeCommand(1, COMMAND_MAP.vlineto);
+ break;
+ case 8:
+ error = this.executeCommand(6, COMMAND_MAP.rrcurveto);
+ break;
+ case 9:
+ this.stack = [];
+ break;
+ case 10:
+ if (this.stack.length < 1) {
+ error = true;
+ break;
+ }
+ subrNumber = this.stack.pop();
+ if (!subrs[subrNumber]) {
+ error = true;
+ break;
+ }
+ error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);
+ break;
+ case 11:
+ return error;
+ case 13:
+ if (this.stack.length < 2) {
+ error = true;
+ break;
+ }
+ wx = this.stack.pop();
+ sbx = this.stack.pop();
+ this.lsb = sbx;
+ this.width = wx;
+ this.stack.push(wx, sbx);
+ error = this.executeCommand(2, COMMAND_MAP.hmoveto);
+ break;
+ case 14:
+ this.output.push(COMMAND_MAP.endchar[0]);
+ break;
+ case 21:
+ if (this.flexing) {
+ break;
+ }
+ error = this.executeCommand(2, COMMAND_MAP.rmoveto);
+ break;
+ case 22:
+ if (this.flexing) {
+ this.stack.push(0);
+ break;
+ }
+ error = this.executeCommand(1, COMMAND_MAP.hmoveto);
+ break;
+ case 30:
+ error = this.executeCommand(4, COMMAND_MAP.vhcurveto);
+ break;
+ case 31:
+ error = this.executeCommand(4, COMMAND_MAP.hvcurveto);
+ break;
+ case (12 << 8) + 0:
+ this.stack = [];
+ break;
+ case (12 << 8) + 1:
+ if (!HINTING_ENABLED) {
+ this.stack = [];
+ break;
+ }
+ error = this.executeCommand(2, COMMAND_MAP.vstem);
+ break;
+ case (12 << 8) + 2:
+ if (!HINTING_ENABLED) {
+ this.stack = [];
+ break;
+ }
+ error = this.executeCommand(2, COMMAND_MAP.hstem);
+ break;
+ case (12 << 8) + 6:
+ if (seacAnalysisEnabled) {
+ const asb = this.stack.at(-5);
+ this.seac = this.stack.splice(-4, 4);
+ this.seac[0] += this.lsb - asb;
+ error = this.executeCommand(0, COMMAND_MAP.endchar);
+ } else {
+ error = this.executeCommand(4, COMMAND_MAP.endchar);
+ }
+ break;
+ case (12 << 8) + 7:
+ if (this.stack.length < 4) {
+ error = true;
+ break;
+ }
+ this.stack.pop();
+ wx = this.stack.pop();
+ const sby = this.stack.pop();
+ sbx = this.stack.pop();
+ this.lsb = sbx;
+ this.width = wx;
+ this.stack.push(wx, sbx, sby);
+ error = this.executeCommand(3, COMMAND_MAP.rmoveto);
+ break;
+ case (12 << 8) + 12:
+ if (this.stack.length < 2) {
+ error = true;
+ break;
+ }
+ const num2 = this.stack.pop();
+ const num1 = this.stack.pop();
+ this.stack.push(num1 / num2);
+ break;
+ case (12 << 8) + 16:
+ if (this.stack.length < 2) {
+ error = true;
+ break;
+ }
+ subrNumber = this.stack.pop();
+ const numArgs = this.stack.pop();
+ if (subrNumber === 0 && numArgs === 3) {
+ const flexArgs = this.stack.splice(-17, 17);
+ this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]);
+ error = this.executeCommand(13, COMMAND_MAP.flex, true);
+ this.flexing = false;
+ this.stack.push(flexArgs[15], flexArgs[16]);
+ } else if (subrNumber === 1 && numArgs === 0) {
+ this.flexing = true;
+ }
+ break;
+ case (12 << 8) + 17:
+ break;
+ case (12 << 8) + 33:
+ this.stack = [];
+ break;
+ default:
+ warn('Unknown type 1 charstring command of "' + value + '"');
+ break;
+ }
+ if (error) {
+ break;
+ }
+ continue;
+ } else if (value <= 246) {
+ value -= 139;
+ } else if (value <= 250) {
+ value = (value - 247) * 256 + encoded[++i] + 108;
+ } else if (value <= 254) {
+ value = -((value - 251) * 256) - encoded[++i] - 108;
+ } else {
+ value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
+ }
+ this.stack.push(value);
+ }
+ return error;
+ }
+ executeCommand(howManyArgs, command, keepStack) {
+ const stackLength = this.stack.length;
+ if (howManyArgs > stackLength) {
+ return true;
+ }
+ const start = stackLength - howManyArgs;
+ for (let i = start; i < stackLength; i++) {
+ let value = this.stack[i];
+ if (Number.isInteger(value)) {
+ this.output.push(28, value >> 8 & 0xff, value & 0xff);
+ } else {
+ value = 65536 * value | 0;
+ this.output.push(255, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
+ }
+ }
+ this.output.push(...command);
+ if (keepStack) {
+ this.stack.splice(start, howManyArgs);
+ } else {
+ this.stack.length = 0;
+ }
+ return false;
+ }
+}
+const EEXEC_ENCRYPT_KEY = 55665;
+const CHAR_STRS_ENCRYPT_KEY = 4330;
+function isHexDigit(code) {
+ return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;
+}
+function decrypt(data, key, discardNumber) {
+ if (discardNumber >= data.length) {
+ return new Uint8Array(0);
+ }
+ const c1 = 52845,
+ c2 = 22719;
+ let r = key | 0,
+ i,
+ j;
+ for (i = 0; i < discardNumber; i++) {
+ r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;
+ }
+ const count = data.length - discardNumber;
+ const decrypted = new Uint8Array(count);
+ for (i = discardNumber, j = 0; j < count; i++, j++) {
+ const value = data[i];
+ decrypted[j] = value ^ r >> 8;
+ r = (value + r) * c1 + c2 & (1 << 16) - 1;
+ }
+ return decrypted;
+}
+function decryptAscii(data, key, discardNumber) {
+ const c1 = 52845,
+ c2 = 22719;
+ let r = key | 0;
+ const count = data.length,
+ maybeLength = count >>> 1;
+ const decrypted = new Uint8Array(maybeLength);
+ let i, j;
+ for (i = 0, j = 0; i < count; i++) {
+ const digit1 = data[i];
+ if (!isHexDigit(digit1)) {
+ continue;
+ }
+ i++;
+ let digit2;
+ while (i < count && !isHexDigit(digit2 = data[i])) {
+ i++;
+ }
+ if (i < count) {
+ const value = parseInt(String.fromCharCode(digit1, digit2), 16);
+ decrypted[j++] = value ^ r >> 8;
+ r = (value + r) * c1 + c2 & (1 << 16) - 1;
+ }
+ }
+ return decrypted.slice(discardNumber, j);
+}
+function isSpecial(c) {
+ return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29;
+}
+class Type1Parser {
+ constructor(stream, encrypted, seacAnalysisEnabled) {
+ if (encrypted) {
+ const data = stream.getBytes();
+ const isBinary = !((isHexDigit(data[0]) || isWhiteSpace(data[0])) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]) && isHexDigit(data[4]) && isHexDigit(data[5]) && isHexDigit(data[6]) && isHexDigit(data[7]));
+ stream = new Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));
+ }
+ this.seacAnalysisEnabled = !!seacAnalysisEnabled;
+ this.stream = stream;
+ this.nextChar();
+ }
+ readNumberArray() {
+ this.getToken();
+ const array = [];
+ while (true) {
+ const token = this.getToken();
+ if (token === null || token === "]" || token === "}") {
+ break;
+ }
+ array.push(parseFloat(token || 0));
+ }
+ return array;
+ }
+ readNumber() {
+ const token = this.getToken();
+ return parseFloat(token || 0);
+ }
+ readInt() {
+ const token = this.getToken();
+ return parseInt(token || 0, 10) | 0;
+ }
+ readBoolean() {
+ const token = this.getToken();
+ return token === "true" ? 1 : 0;
+ }
+ nextChar() {
+ return this.currentChar = this.stream.getByte();
+ }
+ prevChar() {
+ this.stream.skip(-2);
+ return this.currentChar = this.stream.getByte();
+ }
+ getToken() {
+ let comment = false;
+ let ch = this.currentChar;
+ while (true) {
+ if (ch === -1) {
+ return null;
+ }
+ if (comment) {
+ if (ch === 0x0a || ch === 0x0d) {
+ comment = false;
+ }
+ } else if (ch === 0x25) {
+ comment = true;
+ } else if (!isWhiteSpace(ch)) {
+ break;
+ }
+ ch = this.nextChar();
+ }
+ if (isSpecial(ch)) {
+ this.nextChar();
+ return String.fromCharCode(ch);
+ }
+ let token = "";
+ do {
+ token += String.fromCharCode(ch);
+ ch = this.nextChar();
+ } while (ch >= 0 && !isWhiteSpace(ch) && !isSpecial(ch));
+ return token;
+ }
+ readCharStrings(bytes, lenIV) {
+ if (lenIV === -1) {
+ return bytes;
+ }
+ return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
+ }
+ extractFontProgram(properties) {
+ const stream = this.stream;
+ const subrs = [],
+ charstrings = [];
+ const privateData = Object.create(null);
+ privateData.lenIV = 4;
+ const program = {
+ subrs: [],
+ charstrings: [],
+ properties: {
+ privateData
+ }
+ };
+ let token, length, data, lenIV;
+ while ((token = this.getToken()) !== null) {
+ if (token !== "/") {
+ continue;
+ }
+ token = this.getToken();
+ switch (token) {
+ case "CharStrings":
+ this.getToken();
+ this.getToken();
+ this.getToken();
+ this.getToken();
+ while (true) {
+ token = this.getToken();
+ if (token === null || token === "end") {
+ break;
+ }
+ if (token !== "/") {
+ continue;
+ }
+ const glyph = this.getToken();
+ length = this.readInt();
+ this.getToken();
+ data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
+ lenIV = program.properties.privateData.lenIV;
+ const encoded = this.readCharStrings(data, lenIV);
+ this.nextChar();
+ token = this.getToken();
+ if (token === "noaccess") {
+ this.getToken();
+ } else if (token === "/") {
+ this.prevChar();
+ }
+ charstrings.push({
+ glyph,
+ encoded
+ });
+ }
+ break;
+ case "Subrs":
+ this.readInt();
+ this.getToken();
+ while (this.getToken() === "dup") {
+ const index = this.readInt();
+ length = this.readInt();
+ this.getToken();
+ data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
+ lenIV = program.properties.privateData.lenIV;
+ const encoded = this.readCharStrings(data, lenIV);
+ this.nextChar();
+ token = this.getToken();
+ if (token === "noaccess") {
+ this.getToken();
+ }
+ subrs[index] = encoded;
+ }
+ break;
+ case "BlueValues":
+ case "OtherBlues":
+ case "FamilyBlues":
+ case "FamilyOtherBlues":
+ const blueArray = this.readNumberArray();
+ if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {
+ program.properties.privateData[token] = blueArray;
+ }
+ break;
+ case "StemSnapH":
+ case "StemSnapV":
+ program.properties.privateData[token] = this.readNumberArray();
+ break;
+ case "StdHW":
+ case "StdVW":
+ program.properties.privateData[token] = this.readNumberArray()[0];
+ break;
+ case "BlueShift":
+ case "lenIV":
+ case "BlueFuzz":
+ case "BlueScale":
+ case "LanguageGroup":
+ program.properties.privateData[token] = this.readNumber();
+ break;
+ case "ExpansionFactor":
+ program.properties.privateData[token] = this.readNumber() || 0.06;
+ break;
+ case "ForceBold":
+ program.properties.privateData[token] = this.readBoolean();
+ break;
+ }
+ }
+ for (const {
+ encoded,
+ glyph
+ } of charstrings) {
+ const charString = new Type1CharString();
+ const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
+ let output = charString.output;
+ if (error) {
+ output = [14];
+ }
+ const charStringObject = {
+ glyphName: glyph,
+ charstring: output,
+ width: charString.width,
+ lsb: charString.lsb,
+ seac: charString.seac
+ };
+ if (glyph === ".notdef") {
+ program.charstrings.unshift(charStringObject);
+ } else {
+ program.charstrings.push(charStringObject);
+ }
+ if (properties.builtInEncoding) {
+ const index = properties.builtInEncoding.indexOf(glyph);
+ if (index > -1 && properties.widths[index] === undefined && index >= properties.firstChar && index <= properties.lastChar) {
+ properties.widths[index] = charString.width;
+ }
+ }
+ }
+ return program;
+ }
+ extractFontHeader(properties) {
+ let token;
+ while ((token = this.getToken()) !== null) {
+ if (token !== "/") {
+ continue;
+ }
+ token = this.getToken();
+ switch (token) {
+ case "FontMatrix":
+ const matrix = this.readNumberArray();
+ properties.fontMatrix = matrix;
+ break;
+ case "Encoding":
+ const encodingArg = this.getToken();
+ let encoding;
+ if (!/^\d+$/.test(encodingArg)) {
+ encoding = getEncoding(encodingArg);
+ } else {
+ encoding = [];
+ const size = parseInt(encodingArg, 10) | 0;
+ this.getToken();
+ for (let j = 0; j < size; j++) {
+ token = this.getToken();
+ while (token !== "dup" && token !== "def") {
+ token = this.getToken();
+ if (token === null) {
+ return;
+ }
+ }
+ if (token === "def") {
+ break;
+ }
+ const index = this.readInt();
+ this.getToken();
+ const glyph = this.getToken();
+ encoding[index] = glyph;
+ this.getToken();
+ }
+ }
+ properties.builtInEncoding = encoding;
+ break;
+ case "FontBBox":
+ const fontBBox = this.readNumberArray();
+ properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
+ properties.descent = Math.min(fontBBox[1], fontBBox[3]);
+ properties.ascentScaled = true;
+ break;
+ }
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/type1_font.js
+
+
+
+
+
+
+function findBlock(streamBytes, signature, startIndex) {
+ const streamBytesLength = streamBytes.length;
+ const signatureLength = signature.length;
+ const scanLength = streamBytesLength - signatureLength;
+ let i = startIndex,
+ found = false;
+ while (i < scanLength) {
+ let j = 0;
+ while (j < signatureLength && streamBytes[i + j] === signature[j]) {
+ j++;
+ }
+ if (j >= signatureLength) {
+ i += j;
+ while (i < streamBytesLength && isWhiteSpace(streamBytes[i])) {
+ i++;
+ }
+ found = true;
+ break;
+ }
+ i++;
+ }
+ return {
+ found,
+ length: i
+ };
+}
+function getHeaderBlock(stream, suggestedLength) {
+ const EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];
+ const streamStartPos = stream.pos;
+ let headerBytes, headerBytesLength, block;
+ try {
+ headerBytes = stream.getBytes(suggestedLength);
+ headerBytesLength = headerBytes.length;
+ } catch {}
+ if (headerBytesLength === suggestedLength) {
+ block = findBlock(headerBytes, EEXEC_SIGNATURE, suggestedLength - 2 * EEXEC_SIGNATURE.length);
+ if (block.found && block.length === suggestedLength) {
+ return {
+ stream: new Stream(headerBytes),
+ length: suggestedLength
+ };
+ }
+ }
+ warn('Invalid "Length1" property in Type1 font -- trying to recover.');
+ stream.pos = streamStartPos;
+ const SCAN_BLOCK_LENGTH = 2048;
+ let actualLength;
+ while (true) {
+ const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
+ block = findBlock(scanBytes, EEXEC_SIGNATURE, 0);
+ if (block.length === 0) {
+ break;
+ }
+ stream.pos += block.length;
+ if (block.found) {
+ actualLength = stream.pos - streamStartPos;
+ break;
+ }
+ }
+ stream.pos = streamStartPos;
+ if (actualLength) {
+ return {
+ stream: new Stream(stream.getBytes(actualLength)),
+ length: actualLength
+ };
+ }
+ warn('Unable to recover "Length1" property in Type1 font -- using as is.');
+ return {
+ stream: new Stream(stream.getBytes(suggestedLength)),
+ length: suggestedLength
+ };
+}
+function getEexecBlock(stream, suggestedLength) {
+ const eexecBytes = stream.getBytes();
+ if (eexecBytes.length === 0) {
+ throw new FormatError("getEexecBlock - no font program found.");
+ }
+ return {
+ stream: new Stream(eexecBytes),
+ length: eexecBytes.length
+ };
+}
+class Type1Font {
+ constructor(name, file, properties) {
+ const PFB_HEADER_SIZE = 6;
+ let headerBlockLength = properties.length1;
+ let eexecBlockLength = properties.length2;
+ let pfbHeader = file.peekBytes(PFB_HEADER_SIZE);
+ const pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01;
+ if (pfbHeaderPresent) {
+ file.skip(PFB_HEADER_SIZE);
+ headerBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];
+ }
+ const headerBlock = getHeaderBlock(file, headerBlockLength);
+ const headerBlockParser = new Type1Parser(headerBlock.stream, false, SEAC_ANALYSIS_ENABLED);
+ headerBlockParser.extractFontHeader(properties);
+ if (pfbHeaderPresent) {
+ pfbHeader = file.getBytes(PFB_HEADER_SIZE);
+ eexecBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2];
+ }
+ const eexecBlock = getEexecBlock(file, eexecBlockLength);
+ const eexecBlockParser = new Type1Parser(eexecBlock.stream, true, SEAC_ANALYSIS_ENABLED);
+ const data = eexecBlockParser.extractFontProgram(properties);
+ for (const key in data.properties) {
+ properties[key] = data.properties[key];
+ }
+ const charstrings = data.charstrings;
+ const type2Charstrings = this.getType2Charstrings(charstrings);
+ const subrs = this.getType2Subrs(data.subrs);
+ this.charstrings = charstrings;
+ this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties);
+ this.seacs = this.getSeacs(data.charstrings);
+ }
+ get numGlyphs() {
+ return this.charstrings.length + 1;
+ }
+ getCharset() {
+ const charset = [".notdef"];
+ for (const {
+ glyphName
+ } of this.charstrings) {
+ charset.push(glyphName);
+ }
+ return charset;
+ }
+ getGlyphMapping(properties) {
+ const charstrings = this.charstrings;
+ if (properties.composite) {
+ const charCodeToGlyphId = Object.create(null);
+ for (let glyphId = 0, charstringsLen = charstrings.length; glyphId < charstringsLen; glyphId++) {
+ const charCode = properties.cMap.charCodeOf(glyphId);
+ charCodeToGlyphId[charCode] = glyphId + 1;
+ }
+ return charCodeToGlyphId;
+ }
+ const glyphNames = [".notdef"];
+ let builtInEncoding, glyphId;
+ for (glyphId = 0; glyphId < charstrings.length; glyphId++) {
+ glyphNames.push(charstrings[glyphId].glyphName);
+ }
+ const encoding = properties.builtInEncoding;
+ if (encoding) {
+ builtInEncoding = Object.create(null);
+ for (const charCode in encoding) {
+ glyphId = glyphNames.indexOf(encoding[charCode]);
+ if (glyphId >= 0) {
+ builtInEncoding[charCode] = glyphId;
+ }
+ }
+ }
+ return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
+ }
+ hasGlyphId(id) {
+ if (id < 0 || id >= this.numGlyphs) {
+ return false;
+ }
+ if (id === 0) {
+ return true;
+ }
+ const glyph = this.charstrings[id - 1];
+ return glyph.charstring.length > 0;
+ }
+ getSeacs(charstrings) {
+ const seacMap = [];
+ for (let i = 0, ii = charstrings.length; i < ii; i++) {
+ const charstring = charstrings[i];
+ if (charstring.seac) {
+ seacMap[i + 1] = charstring.seac;
+ }
+ }
+ return seacMap;
+ }
+ getType2Charstrings(type1Charstrings) {
+ const type2Charstrings = [];
+ for (const type1Charstring of type1Charstrings) {
+ type2Charstrings.push(type1Charstring.charstring);
+ }
+ return type2Charstrings;
+ }
+ getType2Subrs(type1Subrs) {
+ let bias = 0;
+ const count = type1Subrs.length;
+ if (count < 1133) {
+ bias = 107;
+ } else if (count < 33769) {
+ bias = 1131;
+ } else {
+ bias = 32768;
+ }
+ const type2Subrs = [];
+ let i;
+ for (i = 0; i < bias; i++) {
+ type2Subrs.push([0x0b]);
+ }
+ for (i = 0; i < count; i++) {
+ type2Subrs.push(type1Subrs[i]);
+ }
+ return type2Subrs;
+ }
+ wrap(name, glyphs, charstrings, subrs, properties) {
+ const cff = new CFF();
+ cff.header = new CFFHeader(1, 0, 4, 4);
+ cff.names = [name];
+ const topDict = new CFFTopDict();
+ topDict.setByName("version", 391);
+ topDict.setByName("Notice", 392);
+ topDict.setByName("FullName", 393);
+ topDict.setByName("FamilyName", 394);
+ topDict.setByName("Weight", 395);
+ topDict.setByName("Encoding", null);
+ topDict.setByName("FontMatrix", properties.fontMatrix);
+ topDict.setByName("FontBBox", properties.bbox);
+ topDict.setByName("charset", null);
+ topDict.setByName("CharStrings", null);
+ topDict.setByName("Private", null);
+ cff.topDict = topDict;
+ const strings = new CFFStrings();
+ strings.add("Version 0.11");
+ strings.add("See original notice");
+ strings.add(name);
+ strings.add(name);
+ strings.add("Medium");
+ cff.strings = strings;
+ cff.globalSubrIndex = new CFFIndex();
+ const count = glyphs.length;
+ const charsetArray = [".notdef"];
+ let i, ii;
+ for (i = 0; i < count; i++) {
+ const glyphName = charstrings[i].glyphName;
+ const index = CFFStandardStrings.indexOf(glyphName);
+ if (index === -1) {
+ strings.add(glyphName);
+ }
+ charsetArray.push(glyphName);
+ }
+ cff.charset = new CFFCharset(false, 0, charsetArray);
+ const charStringsIndex = new CFFIndex();
+ charStringsIndex.add([0x8b, 0x0e]);
+ for (i = 0; i < count; i++) {
+ charStringsIndex.add(glyphs[i]);
+ }
+ cff.charStrings = charStringsIndex;
+ const privateDict = new CFFPrivateDict();
+ privateDict.setByName("Subrs", null);
+ const fields = ["BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StemSnapH", "StemSnapV", "BlueShift", "BlueFuzz", "BlueScale", "LanguageGroup", "ExpansionFactor", "ForceBold", "StdHW", "StdVW"];
+ for (i = 0, ii = fields.length; i < ii; i++) {
+ const field = fields[i];
+ if (!(field in properties.privateData)) {
+ continue;
+ }
+ const value = properties.privateData[field];
+ if (Array.isArray(value)) {
+ for (let j = value.length - 1; j > 0; j--) {
+ value[j] -= value[j - 1];
+ }
+ }
+ privateDict.setByName(field, value);
+ }
+ cff.topDict.privateDict = privateDict;
+ const subrIndex = new CFFIndex();
+ for (i = 0, ii = subrs.length; i < ii; i++) {
+ subrIndex.add(subrs[i]);
+ }
+ privateDict.subrsIndex = subrIndex;
+ const compiler = new CFFCompiler(cff);
+ return compiler.compile();
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/fonts.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const PRIVATE_USE_AREAS = [[0xe000, 0xf8ff], [0x100000, 0x10fffd]];
+const PDF_GLYPH_SPACE_UNITS = 1000;
+const EXPORT_DATA_PROPERTIES = ["ascent", "bbox", "black", "bold", "charProcOperatorList", "composite", "cssFontInfo", "data", "defaultVMetrics", "defaultWidth", "descent", "fallbackName", "fontMatrix", "isInvalidPDFjsFont", "isType3Font", "italic", "loadedName", "mimetype", "missingFile", "name", "remeasure", "subtype", "systemFontInfo", "type", "vertical"];
+const EXPORT_DATA_EXTRA_PROPERTIES = ["cMap", "defaultEncoding", "differences", "isMonospace", "isSerifFont", "isSymbolicFont", "seacMap", "toFontChar", "toUnicode", "vmetrics", "widths"];
+function adjustWidths(properties) {
+ if (!properties.fontMatrix) {
+ return;
+ }
+ if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) {
+ return;
+ }
+ const scale = 0.001 / properties.fontMatrix[0];
+ const glyphsWidths = properties.widths;
+ for (const glyph in glyphsWidths) {
+ glyphsWidths[glyph] *= scale;
+ }
+ properties.defaultWidth *= scale;
+}
+function adjustTrueTypeToUnicode(properties, isSymbolicFont, nameRecords) {
+ if (properties.isInternalFont) {
+ return;
+ }
+ if (properties.hasIncludedToUnicodeMap) {
+ return;
+ }
+ if (properties.hasEncoding) {
+ return;
+ }
+ if (properties.toUnicode instanceof IdentityToUnicodeMap) {
+ return;
+ }
+ if (!isSymbolicFont) {
+ return;
+ }
+ if (nameRecords.length === 0) {
+ return;
+ }
+ if (properties.defaultEncoding === WinAnsiEncoding) {
+ return;
+ }
+ for (const r of nameRecords) {
+ if (!isWinNameRecord(r)) {
+ return;
+ }
+ }
+ const encoding = WinAnsiEncoding;
+ const toUnicode = [],
+ glyphsUnicodeMap = getGlyphsUnicode();
+ for (const charCode in encoding) {
+ const glyphName = encoding[charCode];
+ if (glyphName === "") {
+ continue;
+ }
+ const unicode = glyphsUnicodeMap[glyphName];
+ if (unicode === undefined) {
+ continue;
+ }
+ toUnicode[charCode] = String.fromCharCode(unicode);
+ }
+ if (toUnicode.length > 0) {
+ properties.toUnicode.amend(toUnicode);
+ }
+}
+function adjustType1ToUnicode(properties, builtInEncoding) {
+ if (properties.isInternalFont) {
+ return;
+ }
+ if (properties.hasIncludedToUnicodeMap) {
+ return;
+ }
+ if (builtInEncoding === properties.defaultEncoding) {
+ return;
+ }
+ if (properties.toUnicode instanceof IdentityToUnicodeMap) {
+ return;
+ }
+ const toUnicode = [],
+ glyphsUnicodeMap = getGlyphsUnicode();
+ for (const charCode in builtInEncoding) {
+ if (properties.hasEncoding) {
+ if (properties.baseEncodingName || properties.differences[charCode] !== undefined) {
+ continue;
+ }
+ }
+ const glyphName = builtInEncoding[charCode];
+ const unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);
+ if (unicode !== -1) {
+ toUnicode[charCode] = String.fromCharCode(unicode);
+ }
+ }
+ if (toUnicode.length > 0) {
+ properties.toUnicode.amend(toUnicode);
+ }
+}
+function amendFallbackToUnicode(properties) {
+ if (!properties.fallbackToUnicode) {
+ return;
+ }
+ if (properties.toUnicode instanceof IdentityToUnicodeMap) {
+ return;
+ }
+ const toUnicode = [];
+ for (const charCode in properties.fallbackToUnicode) {
+ if (properties.toUnicode.has(charCode)) {
+ continue;
+ }
+ toUnicode[charCode] = properties.fallbackToUnicode[charCode];
+ }
+ if (toUnicode.length > 0) {
+ properties.toUnicode.amend(toUnicode);
+ }
+}
+class fonts_Glyph {
+ constructor(originalCharCode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont) {
+ this.originalCharCode = originalCharCode;
+ this.fontChar = fontChar;
+ this.unicode = unicode;
+ this.accent = accent;
+ this.width = width;
+ this.vmetric = vmetric;
+ this.operatorListId = operatorListId;
+ this.isSpace = isSpace;
+ this.isInFont = isInFont;
+ }
+ get category() {
+ return shadow(this, "category", getCharUnicodeCategory(this.unicode), true);
+ }
+}
+function int16(b0, b1) {
+ return (b0 << 8) + b1;
+}
+function writeSignedInt16(bytes, index, value) {
+ bytes[index + 1] = value;
+ bytes[index] = value >>> 8;
+}
+function signedInt16(b0, b1) {
+ const value = (b0 << 8) + b1;
+ return value & 1 << 15 ? value - 0x10000 : value;
+}
+function writeUint32(bytes, index, value) {
+ bytes[index + 3] = value & 0xff;
+ bytes[index + 2] = value >>> 8;
+ bytes[index + 1] = value >>> 16;
+ bytes[index] = value >>> 24;
+}
+function int32(b0, b1, b2, b3) {
+ return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
+}
+function string16(value) {
+ return String.fromCharCode(value >> 8 & 0xff, value & 0xff);
+}
+function safeString16(value) {
+ if (value > 0x7fff) {
+ value = 0x7fff;
+ } else if (value < -0x8000) {
+ value = -0x8000;
+ }
+ return String.fromCharCode(value >> 8 & 0xff, value & 0xff);
+}
+function isTrueTypeFile(file) {
+ const header = file.peekBytes(4);
+ return readUint32(header, 0) === 0x00010000 || bytesToString(header) === "true";
+}
+function isTrueTypeCollectionFile(file) {
+ const header = file.peekBytes(4);
+ return bytesToString(header) === "ttcf";
+}
+function isOpenTypeFile(file) {
+ const header = file.peekBytes(4);
+ return bytesToString(header) === "OTTO";
+}
+function isType1File(file) {
+ const header = file.peekBytes(2);
+ if (header[0] === 0x25 && header[1] === 0x21) {
+ return true;
+ }
+ if (header[0] === 0x80 && header[1] === 0x01) {
+ return true;
+ }
+ return false;
+}
+function isCFFFile(file) {
+ const header = file.peekBytes(4);
+ if (header[0] >= 1 && header[3] >= 1 && header[3] <= 4) {
+ return true;
+ }
+ return false;
+}
+function getFontFileType(file, {
+ type,
+ subtype,
+ composite
+}) {
+ let fileType, fileSubtype;
+ if (isTrueTypeFile(file) || isTrueTypeCollectionFile(file)) {
+ fileType = composite ? "CIDFontType2" : "TrueType";
+ } else if (isOpenTypeFile(file)) {
+ fileType = composite ? "CIDFontType2" : "OpenType";
+ } else if (isType1File(file)) {
+ if (composite) {
+ fileType = "CIDFontType0";
+ } else {
+ fileType = type === "MMType1" ? "MMType1" : "Type1";
+ }
+ } else if (isCFFFile(file)) {
+ if (composite) {
+ fileType = "CIDFontType0";
+ fileSubtype = "CIDFontType0C";
+ } else {
+ fileType = type === "MMType1" ? "MMType1" : "Type1";
+ fileSubtype = "Type1C";
+ }
+ } else {
+ warn("getFontFileType: Unable to detect correct font file Type/Subtype.");
+ fileType = type;
+ fileSubtype = subtype;
+ }
+ return [fileType, fileSubtype];
+}
+function applyStandardFontGlyphMap(map, glyphMap) {
+ for (const charCode in glyphMap) {
+ map[+charCode] = glyphMap[charCode];
+ }
+}
+function buildToFontChar(encoding, glyphsUnicodeMap, differences) {
+ const toFontChar = [];
+ let unicode;
+ for (let i = 0, ii = encoding.length; i < ii; i++) {
+ unicode = getUnicodeForGlyph(encoding[i], glyphsUnicodeMap);
+ if (unicode !== -1) {
+ toFontChar[i] = unicode;
+ }
+ }
+ for (const charCode in differences) {
+ unicode = getUnicodeForGlyph(differences[charCode], glyphsUnicodeMap);
+ if (unicode !== -1) {
+ toFontChar[+charCode] = unicode;
+ }
+ }
+ return toFontChar;
+}
+function isMacNameRecord(r) {
+ return r.platform === 1 && r.encoding === 0 && r.language === 0;
+}
+function isWinNameRecord(r) {
+ return r.platform === 3 && r.encoding === 1 && r.language === 0x409;
+}
+function convertCidString(charCode, cid, shouldThrow = false) {
+ switch (cid.length) {
+ case 1:
+ return cid.charCodeAt(0);
+ case 2:
+ return cid.charCodeAt(0) << 8 | cid.charCodeAt(1);
+ }
+ const msg = `Unsupported CID string (charCode ${charCode}): "${cid}".`;
+ if (shouldThrow) {
+ throw new FormatError(msg);
+ }
+ warn(msg);
+ return cid;
+}
+function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUnicode) {
+ const newMap = Object.create(null);
+ const toUnicodeExtraMap = new Map();
+ const toFontChar = [];
+ const usedGlyphIds = new Set();
+ let privateUseAreaIndex = 0;
+ const privateUseOffetStart = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
+ let nextAvailableFontCharCode = privateUseOffetStart;
+ let privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
+ const isInPrivateArea = code => PRIVATE_USE_AREAS[0][0] <= code && code <= PRIVATE_USE_AREAS[0][1] || PRIVATE_USE_AREAS[1][0] <= code && code <= PRIVATE_USE_AREAS[1][1];
+ for (let originalCharCode in charCodeToGlyphId) {
+ originalCharCode |= 0;
+ let glyphId = charCodeToGlyphId[originalCharCode];
+ if (!hasGlyph(glyphId)) {
+ continue;
+ }
+ if (nextAvailableFontCharCode > privateUseOffetEnd) {
+ privateUseAreaIndex++;
+ if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) {
+ warn("Ran out of space in font private use area.");
+ break;
+ }
+ nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
+ privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
+ }
+ const fontCharCode = nextAvailableFontCharCode++;
+ if (glyphId === 0) {
+ glyphId = newGlyphZeroId;
+ }
+ let unicode = toUnicode.get(originalCharCode);
+ if (typeof unicode === "string") {
+ unicode = unicode.codePointAt(0);
+ }
+ if (unicode && !isInPrivateArea(unicode) && !usedGlyphIds.has(glyphId)) {
+ toUnicodeExtraMap.set(unicode, glyphId);
+ usedGlyphIds.add(glyphId);
+ }
+ newMap[fontCharCode] = glyphId;
+ toFontChar[originalCharCode] = fontCharCode;
+ }
+ return {
+ toFontChar,
+ charCodeToGlyphId: newMap,
+ toUnicodeExtraMap,
+ nextAvailableFontCharCode
+ };
+}
+function getRanges(glyphs, toUnicodeExtraMap, numGlyphs) {
+ const codes = [];
+ for (const charCode in glyphs) {
+ if (glyphs[charCode] >= numGlyphs) {
+ continue;
+ }
+ codes.push({
+ fontCharCode: charCode | 0,
+ glyphId: glyphs[charCode]
+ });
+ }
+ if (toUnicodeExtraMap) {
+ for (const [unicode, glyphId] of toUnicodeExtraMap) {
+ if (glyphId >= numGlyphs) {
+ continue;
+ }
+ codes.push({
+ fontCharCode: unicode,
+ glyphId
+ });
+ }
+ }
+ if (codes.length === 0) {
+ codes.push({
+ fontCharCode: 0,
+ glyphId: 0
+ });
+ }
+ codes.sort(function fontGetRangesSort(a, b) {
+ return a.fontCharCode - b.fontCharCode;
+ });
+ const ranges = [];
+ const length = codes.length;
+ for (let n = 0; n < length;) {
+ const start = codes[n].fontCharCode;
+ const codeIndices = [codes[n].glyphId];
+ ++n;
+ let end = start;
+ while (n < length && end + 1 === codes[n].fontCharCode) {
+ codeIndices.push(codes[n].glyphId);
+ ++end;
+ ++n;
+ if (end === 0xffff) {
+ break;
+ }
+ }
+ ranges.push([start, end, codeIndices]);
+ }
+ return ranges;
+}
+function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
+ const ranges = getRanges(glyphs, toUnicodeExtraMap, numGlyphs);
+ const numTables = ranges.at(-1)[1] > 0xffff ? 2 : 1;
+ let cmap = "\x00\x00" + string16(numTables) + "\x00\x03" + "\x00\x01" + string32(4 + numTables * 8);
+ let i, ii, j, jj;
+ for (i = ranges.length - 1; i >= 0; --i) {
+ if (ranges[i][0] <= 0xffff) {
+ break;
+ }
+ }
+ const bmpLength = i + 1;
+ if (ranges[i][0] < 0xffff && ranges[i][1] === 0xffff) {
+ ranges[i][1] = 0xfffe;
+ }
+ const trailingRangesCount = ranges[i][1] < 0xffff ? 1 : 0;
+ const segCount = bmpLength + trailingRangesCount;
+ const searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);
+ let startCount = "";
+ let endCount = "";
+ let idDeltas = "";
+ let idRangeOffsets = "";
+ let glyphsIds = "";
+ let bias = 0;
+ let range, start, end, codes;
+ for (i = 0, ii = bmpLength; i < ii; i++) {
+ range = ranges[i];
+ start = range[0];
+ end = range[1];
+ startCount += string16(start);
+ endCount += string16(end);
+ codes = range[2];
+ let contiguous = true;
+ for (j = 1, jj = codes.length; j < jj; ++j) {
+ if (codes[j] !== codes[j - 1] + 1) {
+ contiguous = false;
+ break;
+ }
+ }
+ if (!contiguous) {
+ const offset = (segCount - i) * 2 + bias * 2;
+ bias += end - start + 1;
+ idDeltas += string16(0);
+ idRangeOffsets += string16(offset);
+ for (j = 0, jj = codes.length; j < jj; ++j) {
+ glyphsIds += string16(codes[j]);
+ }
+ } else {
+ const startCode = codes[0];
+ idDeltas += string16(startCode - start & 0xffff);
+ idRangeOffsets += string16(0);
+ }
+ }
+ if (trailingRangesCount > 0) {
+ endCount += "\xFF\xFF";
+ startCount += "\xFF\xFF";
+ idDeltas += "\x00\x01";
+ idRangeOffsets += "\x00\x00";
+ }
+ const format314 = "\x00\x00" + string16(2 * segCount) + string16(searchParams.range) + string16(searchParams.entry) + string16(searchParams.rangeShift) + endCount + "\x00\x00" + startCount + idDeltas + idRangeOffsets + glyphsIds;
+ let format31012 = "";
+ let header31012 = "";
+ if (numTables > 1) {
+ cmap += "\x00\x03" + "\x00\x0A" + string32(4 + numTables * 8 + 4 + format314.length);
+ format31012 = "";
+ for (i = 0, ii = ranges.length; i < ii; i++) {
+ range = ranges[i];
+ start = range[0];
+ codes = range[2];
+ let code = codes[0];
+ for (j = 1, jj = codes.length; j < jj; ++j) {
+ if (codes[j] !== codes[j - 1] + 1) {
+ end = range[0] + j - 1;
+ format31012 += string32(start) + string32(end) + string32(code);
+ start = end + 1;
+ code = codes[j];
+ }
+ }
+ format31012 += string32(start) + string32(range[1]) + string32(code);
+ }
+ header31012 = "\x00\x0C" + "\x00\x00" + string32(format31012.length + 16) + "\x00\x00\x00\x00" + string32(format31012.length / 12);
+ }
+ return cmap + "\x00\x04" + string16(format314.length + 4) + format314 + header31012 + format31012;
+}
+function validateOS2Table(os2, file) {
+ file.pos = (file.start || 0) + os2.offset;
+ const version = file.getUint16();
+ file.skip(60);
+ const selection = file.getUint16();
+ if (version < 4 && selection & 0x0300) {
+ return false;
+ }
+ const firstChar = file.getUint16();
+ const lastChar = file.getUint16();
+ if (firstChar > lastChar) {
+ return false;
+ }
+ file.skip(6);
+ const usWinAscent = file.getUint16();
+ if (usWinAscent === 0) {
+ return false;
+ }
+ os2.data[8] = os2.data[9] = 0;
+ return true;
+}
+function createOS2Table(properties, charstrings, override) {
+ override ||= {
+ unitsPerEm: 0,
+ yMax: 0,
+ yMin: 0,
+ ascent: 0,
+ descent: 0
+ };
+ let ulUnicodeRange1 = 0;
+ let ulUnicodeRange2 = 0;
+ let ulUnicodeRange3 = 0;
+ let ulUnicodeRange4 = 0;
+ let firstCharIndex = null;
+ let lastCharIndex = 0;
+ let position = -1;
+ if (charstrings) {
+ for (let code in charstrings) {
+ code |= 0;
+ if (firstCharIndex > code || !firstCharIndex) {
+ firstCharIndex = code;
+ }
+ if (lastCharIndex < code) {
+ lastCharIndex = code;
+ }
+ position = getUnicodeRangeFor(code, position);
+ if (position < 32) {
+ ulUnicodeRange1 |= 1 << position;
+ } else if (position < 64) {
+ ulUnicodeRange2 |= 1 << position - 32;
+ } else if (position < 96) {
+ ulUnicodeRange3 |= 1 << position - 64;
+ } else if (position < 123) {
+ ulUnicodeRange4 |= 1 << position - 96;
+ } else {
+ throw new FormatError("Unicode ranges Bits > 123 are reserved for internal usage");
+ }
+ }
+ if (lastCharIndex > 0xffff) {
+ lastCharIndex = 0xffff;
+ }
+ } else {
+ firstCharIndex = 0;
+ lastCharIndex = 255;
+ }
+ const bbox = properties.bbox || [0, 0, 0, 0];
+ const unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];
+ const scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS;
+ const typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3]));
+ let typoDescent = override.descent || Math.round(scale * (properties.descent || bbox[1]));
+ if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) {
+ typoDescent = -typoDescent;
+ }
+ const winAscent = override.yMax || typoAscent;
+ const winDescent = -override.yMin || -typoDescent;
+ return "\x00\x03" + "\x02\x24" + "\x01\xF4" + "\x00\x05" + "\x00\x00" + "\x02\x8A" + "\x02\xBB" + "\x00\x00" + "\x00\x8C" + "\x02\x8A" + "\x02\xBB" + "\x00\x00" + "\x01\xDF" + "\x00\x31" + "\x01\x02" + "\x00\x00" + "\x00\x00\x06" + String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + "\x00\x00\x00\x00\x00\x00" + string32(ulUnicodeRange1) + string32(ulUnicodeRange2) + string32(ulUnicodeRange3) + string32(ulUnicodeRange4) + "\x2A\x32\x31\x2A" + string16(properties.italicAngle ? 1 : 0) + string16(firstCharIndex || properties.firstChar) + string16(lastCharIndex || properties.lastChar) + string16(typoAscent) + string16(typoDescent) + "\x00\x64" + string16(winAscent) + string16(winDescent) + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + string16(properties.xHeight) + string16(properties.capHeight) + string16(0) + string16(firstCharIndex || properties.firstChar) + "\x00\x03";
+}
+function createPostTable(properties) {
+ const angle = Math.floor(properties.italicAngle * 2 ** 16);
+ return "\x00\x03\x00\x00" + string32(angle) + "\x00\x00" + "\x00\x00" + string32(properties.fixedPitch ? 1 : 0) + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00";
+}
+function createPostscriptName(name) {
+ return name.replaceAll(/[^\x21-\x7E]|[[\](){}<>/%]/g, "").slice(0, 63);
+}
+function createNameTable(name, proto) {
+ if (!proto) {
+ proto = [[], []];
+ }
+ const strings = [proto[0][0] || "Original licence", proto[0][1] || name, proto[0][2] || "Unknown", proto[0][3] || "uniqueID", proto[0][4] || name, proto[0][5] || "Version 0.11", proto[0][6] || createPostscriptName(name), proto[0][7] || "Unknown", proto[0][8] || "Unknown", proto[0][9] || "Unknown"];
+ const stringsUnicode = [];
+ let i, ii, j, jj, str;
+ for (i = 0, ii = strings.length; i < ii; i++) {
+ str = proto[1][i] || strings[i];
+ const strBufUnicode = [];
+ for (j = 0, jj = str.length; j < jj; j++) {
+ strBufUnicode.push(string16(str.charCodeAt(j)));
+ }
+ stringsUnicode.push(strBufUnicode.join(""));
+ }
+ const names = [strings, stringsUnicode];
+ const platforms = ["\x00\x01", "\x00\x03"];
+ const encodings = ["\x00\x00", "\x00\x01"];
+ const languages = ["\x00\x00", "\x04\x09"];
+ const namesRecordCount = strings.length * platforms.length;
+ let nameTable = "\x00\x00" + string16(namesRecordCount) + string16(namesRecordCount * 12 + 6);
+ let strOffset = 0;
+ for (i = 0, ii = platforms.length; i < ii; i++) {
+ const strs = names[i];
+ for (j = 0, jj = strs.length; j < jj; j++) {
+ str = strs[j];
+ const nameRecord = platforms[i] + encodings[i] + languages[i] + string16(j) + string16(str.length) + string16(strOffset);
+ nameTable += nameRecord;
+ strOffset += str.length;
+ }
+ }
+ nameTable += strings.join("") + stringsUnicode.join("");
+ return nameTable;
+}
+class Font {
+ constructor(name, file, properties) {
+ this.name = name;
+ this.psName = null;
+ this.mimetype = null;
+ this.disableFontFace = false;
+ this.loadedName = properties.loadedName;
+ this.isType3Font = properties.isType3Font;
+ this.missingFile = false;
+ this.cssFontInfo = properties.cssFontInfo;
+ this._charsCache = Object.create(null);
+ this._glyphCache = Object.create(null);
+ let isSerifFont = !!(properties.flags & FontFlags.Serif);
+ if (!isSerifFont && !properties.isSimulatedFlags) {
+ const baseName = name.replaceAll(/[,_]/g, "-").split("-")[0],
+ serifFonts = getSerifFonts();
+ for (const namePart of baseName.split("+")) {
+ if (serifFonts[namePart]) {
+ isSerifFont = true;
+ break;
+ }
+ }
+ }
+ this.isSerifFont = isSerifFont;
+ this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
+ this.isMonospace = !!(properties.flags & FontFlags.FixedPitch);
+ let {
+ type,
+ subtype
+ } = properties;
+ this.type = type;
+ this.subtype = subtype;
+ this.systemFontInfo = properties.systemFontInfo;
+ const matches = name.match(/^InvalidPDFjsFont_(.*)_\d+$/);
+ this.isInvalidPDFjsFont = !!matches;
+ if (this.isInvalidPDFjsFont) {
+ this.fallbackName = matches[1];
+ } else if (this.isMonospace) {
+ this.fallbackName = "monospace";
+ } else if (this.isSerifFont) {
+ this.fallbackName = "serif";
+ } else {
+ this.fallbackName = "sans-serif";
+ }
+ if (this.systemFontInfo?.guessFallback) {
+ this.systemFontInfo.guessFallback = false;
+ this.systemFontInfo.css += `,${this.fallbackName}`;
+ }
+ this.differences = properties.differences;
+ this.widths = properties.widths;
+ this.defaultWidth = properties.defaultWidth;
+ this.composite = properties.composite;
+ this.cMap = properties.cMap;
+ this.capHeight = properties.capHeight / PDF_GLYPH_SPACE_UNITS;
+ this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS;
+ this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS;
+ this.lineHeight = this.ascent - this.descent;
+ this.fontMatrix = properties.fontMatrix;
+ this.bbox = properties.bbox;
+ this.defaultEncoding = properties.defaultEncoding;
+ this.toUnicode = properties.toUnicode;
+ this.toFontChar = [];
+ if (properties.type === "Type3") {
+ for (let charCode = 0; charCode < 256; charCode++) {
+ this.toFontChar[charCode] = this.differences[charCode] || properties.defaultEncoding[charCode];
+ }
+ return;
+ }
+ this.cidEncoding = properties.cidEncoding || "";
+ this.vertical = !!properties.vertical;
+ if (this.vertical) {
+ this.vmetrics = properties.vmetrics;
+ this.defaultVMetrics = properties.defaultVMetrics;
+ }
+ if (!file || file.isEmpty) {
+ if (file) {
+ warn('Font file is empty in "' + name + '" (' + this.loadedName + ")");
+ }
+ this.fallbackToSystemFont(properties);
+ return;
+ }
+ [type, subtype] = getFontFileType(file, properties);
+ if (type !== this.type || subtype !== this.subtype) {
+ info("Inconsistent font file Type/SubType, expected: " + `${this.type}/${this.subtype} but found: ${type}/${subtype}.`);
+ }
+ let data;
+ try {
+ switch (type) {
+ case "MMType1":
+ info("MMType1 font (" + name + "), falling back to Type1.");
+ case "Type1":
+ case "CIDFontType0":
+ this.mimetype = "font/opentype";
+ const cff = subtype === "Type1C" || subtype === "CIDFontType0C" ? new CFFFont(file, properties) : new Type1Font(name, file, properties);
+ adjustWidths(properties);
+ data = this.convert(name, cff, properties);
+ break;
+ case "OpenType":
+ case "TrueType":
+ case "CIDFontType2":
+ this.mimetype = "font/opentype";
+ data = this.checkAndRepair(name, file, properties);
+ if (this.isOpenType) {
+ adjustWidths(properties);
+ type = "OpenType";
+ }
+ break;
+ default:
+ throw new FormatError(`Font ${type} is not supported`);
+ }
+ } catch (e) {
+ warn(e);
+ this.fallbackToSystemFont(properties);
+ return;
+ }
+ amendFallbackToUnicode(properties);
+ this.data = data;
+ this.type = type;
+ this.subtype = subtype;
+ this.fontMatrix = properties.fontMatrix;
+ this.widths = properties.widths;
+ this.defaultWidth = properties.defaultWidth;
+ this.toUnicode = properties.toUnicode;
+ this.seacMap = properties.seacMap;
+ }
+ get renderer() {
+ const renderer = FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED);
+ return shadow(this, "renderer", renderer);
+ }
+ exportData(extraProperties = false) {
+ const exportDataProperties = extraProperties ? [...EXPORT_DATA_PROPERTIES, ...EXPORT_DATA_EXTRA_PROPERTIES] : EXPORT_DATA_PROPERTIES;
+ const data = Object.create(null);
+ let property, value;
+ for (property of exportDataProperties) {
+ value = this[property];
+ if (value !== undefined) {
+ data[property] = value;
+ }
+ }
+ return data;
+ }
+ fallbackToSystemFont(properties) {
+ this.missingFile = true;
+ const {
+ name,
+ type
+ } = this;
+ let fontName = normalizeFontName(name);
+ const stdFontMap = getStdFontMap(),
+ nonStdFontMap = getNonStdFontMap();
+ const isStandardFont = !!stdFontMap[fontName];
+ const isMappedToStandardFont = !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]);
+ fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName;
+ const fontBasicMetricsMap = getFontBasicMetrics();
+ const metrics = fontBasicMetricsMap[fontName];
+ if (metrics) {
+ if (isNaN(this.ascent)) {
+ this.ascent = metrics.ascent / PDF_GLYPH_SPACE_UNITS;
+ }
+ if (isNaN(this.descent)) {
+ this.descent = metrics.descent / PDF_GLYPH_SPACE_UNITS;
+ }
+ if (isNaN(this.capHeight)) {
+ this.capHeight = metrics.capHeight / PDF_GLYPH_SPACE_UNITS;
+ }
+ }
+ this.bold = /bold/gi.test(fontName);
+ this.italic = /oblique|italic/gi.test(fontName);
+ this.black = /Black/g.test(name);
+ const isNarrow = /Narrow/g.test(name);
+ this.remeasure = (!isStandardFont || isNarrow) && Object.keys(this.widths).length > 0;
+ if ((isStandardFont || isMappedToStandardFont) && type === "CIDFontType2" && this.cidEncoding.startsWith("Identity-")) {
+ const cidToGidMap = properties.cidToGidMap;
+ const map = [];
+ applyStandardFontGlyphMap(map, getGlyphMapForStandardFonts());
+ if (/Arial-?Black/i.test(name)) {
+ applyStandardFontGlyphMap(map, getSupplementalGlyphMapForArialBlack());
+ } else if (/Calibri/i.test(name)) {
+ applyStandardFontGlyphMap(map, getSupplementalGlyphMapForCalibri());
+ }
+ if (cidToGidMap) {
+ for (const charCode in map) {
+ const cid = map[charCode];
+ if (cidToGidMap[cid] !== undefined) {
+ map[+charCode] = cidToGidMap[cid];
+ }
+ }
+ if (cidToGidMap.length !== this.toUnicode.length && properties.hasIncludedToUnicodeMap && this.toUnicode instanceof IdentityToUnicodeMap) {
+ this.toUnicode.forEach(function (charCode, unicodeCharCode) {
+ const cid = map[charCode];
+ if (cidToGidMap[cid] === undefined) {
+ map[+charCode] = unicodeCharCode;
+ }
+ });
+ }
+ }
+ if (!(this.toUnicode instanceof IdentityToUnicodeMap)) {
+ this.toUnicode.forEach(function (charCode, unicodeCharCode) {
+ map[+charCode] = unicodeCharCode;
+ });
+ }
+ this.toFontChar = map;
+ this.toUnicode = new ToUnicodeMap(map);
+ } else if (/Symbol/i.test(fontName)) {
+ this.toFontChar = buildToFontChar(SymbolSetEncoding, getGlyphsUnicode(), this.differences);
+ } else if (/Dingbats/i.test(fontName)) {
+ this.toFontChar = buildToFontChar(ZapfDingbatsEncoding, getDingbatsGlyphsUnicode(), this.differences);
+ } else if (isStandardFont) {
+ const map = buildToFontChar(this.defaultEncoding, getGlyphsUnicode(), this.differences);
+ if (type === "CIDFontType2" && !this.cidEncoding.startsWith("Identity-") && !(this.toUnicode instanceof IdentityToUnicodeMap)) {
+ this.toUnicode.forEach(function (charCode, unicodeCharCode) {
+ map[+charCode] = unicodeCharCode;
+ });
+ }
+ this.toFontChar = map;
+ } else {
+ const glyphsUnicodeMap = getGlyphsUnicode();
+ const map = [];
+ this.toUnicode.forEach((charCode, unicodeCharCode) => {
+ if (!this.composite) {
+ const glyphName = this.differences[charCode] || this.defaultEncoding[charCode];
+ const unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);
+ if (unicode !== -1) {
+ unicodeCharCode = unicode;
+ }
+ }
+ map[+charCode] = unicodeCharCode;
+ });
+ if (this.composite && this.toUnicode instanceof IdentityToUnicodeMap) {
+ if (/Tahoma|Verdana/i.test(name)) {
+ applyStandardFontGlyphMap(map, getGlyphMapForStandardFonts());
+ }
+ }
+ this.toFontChar = map;
+ }
+ amendFallbackToUnicode(properties);
+ this.loadedName = fontName.split("-")[0];
+ }
+ checkAndRepair(name, font, properties) {
+ const VALID_TABLES = ["OS/2", "cmap", "head", "hhea", "hmtx", "maxp", "name", "post", "loca", "glyf", "fpgm", "prep", "cvt ", "CFF "];
+ function readTables(file, numTables) {
+ const tables = Object.create(null);
+ tables["OS/2"] = null;
+ tables.cmap = null;
+ tables.head = null;
+ tables.hhea = null;
+ tables.hmtx = null;
+ tables.maxp = null;
+ tables.name = null;
+ tables.post = null;
+ for (let i = 0; i < numTables; i++) {
+ const table = readTableEntry(file);
+ if (!VALID_TABLES.includes(table.tag)) {
+ continue;
+ }
+ if (table.length === 0) {
+ continue;
+ }
+ tables[table.tag] = table;
+ }
+ return tables;
+ }
+ function readTableEntry(file) {
+ const tag = file.getString(4);
+ const checksum = file.getInt32() >>> 0;
+ const offset = file.getInt32() >>> 0;
+ const length = file.getInt32() >>> 0;
+ const previousPosition = file.pos;
+ file.pos = file.start || 0;
+ file.skip(offset);
+ const data = file.getBytes(length);
+ file.pos = previousPosition;
+ if (tag === "head") {
+ data[8] = data[9] = data[10] = data[11] = 0;
+ data[17] |= 0x20;
+ }
+ return {
+ tag,
+ checksum,
+ length,
+ offset,
+ data
+ };
+ }
+ function readOpenTypeHeader(ttf) {
+ return {
+ version: ttf.getString(4),
+ numTables: ttf.getUint16(),
+ searchRange: ttf.getUint16(),
+ entrySelector: ttf.getUint16(),
+ rangeShift: ttf.getUint16()
+ };
+ }
+ function readTrueTypeCollectionHeader(ttc) {
+ const ttcTag = ttc.getString(4);
+ assert(ttcTag === "ttcf", "Must be a TrueType Collection font.");
+ const majorVersion = ttc.getUint16();
+ const minorVersion = ttc.getUint16();
+ const numFonts = ttc.getInt32() >>> 0;
+ const offsetTable = [];
+ for (let i = 0; i < numFonts; i++) {
+ offsetTable.push(ttc.getInt32() >>> 0);
+ }
+ const header = {
+ ttcTag,
+ majorVersion,
+ minorVersion,
+ numFonts,
+ offsetTable
+ };
+ switch (majorVersion) {
+ case 1:
+ return header;
+ case 2:
+ header.dsigTag = ttc.getInt32() >>> 0;
+ header.dsigLength = ttc.getInt32() >>> 0;
+ header.dsigOffset = ttc.getInt32() >>> 0;
+ return header;
+ }
+ throw new FormatError(`Invalid TrueType Collection majorVersion: ${majorVersion}.`);
+ }
+ function readTrueTypeCollectionData(ttc, fontName) {
+ const {
+ numFonts,
+ offsetTable
+ } = readTrueTypeCollectionHeader(ttc);
+ const fontNameParts = fontName.split("+");
+ let fallbackData;
+ for (let i = 0; i < numFonts; i++) {
+ ttc.pos = (ttc.start || 0) + offsetTable[i];
+ const potentialHeader = readOpenTypeHeader(ttc);
+ const potentialTables = readTables(ttc, potentialHeader.numTables);
+ if (!potentialTables.name) {
+ throw new FormatError('TrueType Collection font must contain a "name" table.');
+ }
+ const [nameTable] = readNameTable(potentialTables.name);
+ for (let j = 0, jj = nameTable.length; j < jj; j++) {
+ for (let k = 0, kk = nameTable[j].length; k < kk; k++) {
+ const nameEntry = nameTable[j][k]?.replaceAll(/\s/g, "");
+ if (!nameEntry) {
+ continue;
+ }
+ if (nameEntry === fontName) {
+ return {
+ header: potentialHeader,
+ tables: potentialTables
+ };
+ }
+ if (fontNameParts.length < 2) {
+ continue;
+ }
+ for (const part of fontNameParts) {
+ if (nameEntry === part) {
+ fallbackData = {
+ name: part,
+ header: potentialHeader,
+ tables: potentialTables
+ };
+ }
+ }
+ }
+ }
+ }
+ if (fallbackData) {
+ warn(`TrueType Collection does not contain "${fontName}" font, ` + `falling back to "${fallbackData.name}" font instead.`);
+ return {
+ header: fallbackData.header,
+ tables: fallbackData.tables
+ };
+ }
+ throw new FormatError(`TrueType Collection does not contain "${fontName}" font.`);
+ }
+ function readCmapTable(cmap, file, isSymbolicFont, hasEncoding) {
+ if (!cmap) {
+ warn("No cmap table available.");
+ return {
+ platformId: -1,
+ encodingId: -1,
+ mappings: [],
+ hasShortCmap: false
+ };
+ }
+ let segment;
+ let start = (file.start || 0) + cmap.offset;
+ file.pos = start;
+ file.skip(2);
+ const numTables = file.getUint16();
+ let potentialTable;
+ let canBreak = false;
+ for (let i = 0; i < numTables; i++) {
+ const platformId = file.getUint16();
+ const encodingId = file.getUint16();
+ const offset = file.getInt32() >>> 0;
+ let useTable = false;
+ if (potentialTable?.platformId === platformId && potentialTable?.encodingId === encodingId) {
+ continue;
+ }
+ if (platformId === 0 && (encodingId === 0 || encodingId === 1 || encodingId === 3)) {
+ useTable = true;
+ } else if (platformId === 1 && encodingId === 0) {
+ useTable = true;
+ } else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) {
+ useTable = true;
+ if (!isSymbolicFont) {
+ canBreak = true;
+ }
+ } else if (isSymbolicFont && platformId === 3 && encodingId === 0) {
+ useTable = true;
+ let correctlySorted = true;
+ if (i < numTables - 1) {
+ const nextBytes = file.peekBytes(2),
+ nextPlatformId = int16(nextBytes[0], nextBytes[1]);
+ if (nextPlatformId < platformId) {
+ correctlySorted = false;
+ }
+ }
+ if (correctlySorted) {
+ canBreak = true;
+ }
+ }
+ if (useTable) {
+ potentialTable = {
+ platformId,
+ encodingId,
+ offset
+ };
+ }
+ if (canBreak) {
+ break;
+ }
+ }
+ if (potentialTable) {
+ file.pos = start + potentialTable.offset;
+ }
+ if (!potentialTable || file.peekByte() === -1) {
+ warn("Could not find a preferred cmap table.");
+ return {
+ platformId: -1,
+ encodingId: -1,
+ mappings: [],
+ hasShortCmap: false
+ };
+ }
+ const format = file.getUint16();
+ let hasShortCmap = false;
+ const mappings = [];
+ let j, glyphId;
+ if (format === 0) {
+ file.skip(2 + 2);
+ for (j = 0; j < 256; j++) {
+ const index = file.getByte();
+ if (!index) {
+ continue;
+ }
+ mappings.push({
+ charCode: j,
+ glyphId: index
+ });
+ }
+ hasShortCmap = true;
+ } else if (format === 2) {
+ file.skip(2 + 2);
+ const subHeaderKeys = [];
+ let maxSubHeaderKey = 0;
+ for (let i = 0; i < 256; i++) {
+ const subHeaderKey = file.getUint16() >> 3;
+ subHeaderKeys.push(subHeaderKey);
+ maxSubHeaderKey = Math.max(subHeaderKey, maxSubHeaderKey);
+ }
+ const subHeaders = [];
+ for (let i = 0; i <= maxSubHeaderKey; i++) {
+ subHeaders.push({
+ firstCode: file.getUint16(),
+ entryCount: file.getUint16(),
+ idDelta: signedInt16(file.getByte(), file.getByte()),
+ idRangePos: file.pos + file.getUint16()
+ });
+ }
+ for (let i = 0; i < 256; i++) {
+ if (subHeaderKeys[i] === 0) {
+ file.pos = subHeaders[0].idRangePos + 2 * i;
+ glyphId = file.getUint16();
+ mappings.push({
+ charCode: i,
+ glyphId
+ });
+ } else {
+ const s = subHeaders[subHeaderKeys[i]];
+ for (j = 0; j < s.entryCount; j++) {
+ const charCode = (i << 8) + j + s.firstCode;
+ file.pos = s.idRangePos + 2 * j;
+ glyphId = file.getUint16();
+ if (glyphId !== 0) {
+ glyphId = (glyphId + s.idDelta) % 65536;
+ }
+ mappings.push({
+ charCode,
+ glyphId
+ });
+ }
+ }
+ }
+ } else if (format === 4) {
+ file.skip(2 + 2);
+ const segCount = file.getUint16() >> 1;
+ file.skip(6);
+ const segments = [];
+ let segIndex;
+ for (segIndex = 0; segIndex < segCount; segIndex++) {
+ segments.push({
+ end: file.getUint16()
+ });
+ }
+ file.skip(2);
+ for (segIndex = 0; segIndex < segCount; segIndex++) {
+ segments[segIndex].start = file.getUint16();
+ }
+ for (segIndex = 0; segIndex < segCount; segIndex++) {
+ segments[segIndex].delta = file.getUint16();
+ }
+ let offsetsCount = 0,
+ offsetIndex;
+ for (segIndex = 0; segIndex < segCount; segIndex++) {
+ segment = segments[segIndex];
+ const rangeOffset = file.getUint16();
+ if (!rangeOffset) {
+ segment.offsetIndex = -1;
+ continue;
+ }
+ offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);
+ segment.offsetIndex = offsetIndex;
+ offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1);
+ }
+ const offsets = [];
+ for (j = 0; j < offsetsCount; j++) {
+ offsets.push(file.getUint16());
+ }
+ for (segIndex = 0; segIndex < segCount; segIndex++) {
+ segment = segments[segIndex];
+ start = segment.start;
+ const end = segment.end;
+ const delta = segment.delta;
+ offsetIndex = segment.offsetIndex;
+ for (j = start; j <= end; j++) {
+ if (j === 0xffff) {
+ continue;
+ }
+ glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];
+ glyphId = glyphId + delta & 0xffff;
+ mappings.push({
+ charCode: j,
+ glyphId
+ });
+ }
+ }
+ } else if (format === 6) {
+ file.skip(2 + 2);
+ const firstCode = file.getUint16();
+ const entryCount = file.getUint16();
+ for (j = 0; j < entryCount; j++) {
+ glyphId = file.getUint16();
+ const charCode = firstCode + j;
+ mappings.push({
+ charCode,
+ glyphId
+ });
+ }
+ } else if (format === 12) {
+ file.skip(2 + 4 + 4);
+ const nGroups = file.getInt32() >>> 0;
+ for (j = 0; j < nGroups; j++) {
+ const startCharCode = file.getInt32() >>> 0;
+ const endCharCode = file.getInt32() >>> 0;
+ let glyphCode = file.getInt32() >>> 0;
+ for (let charCode = startCharCode; charCode <= endCharCode; charCode++) {
+ mappings.push({
+ charCode,
+ glyphId: glyphCode++
+ });
+ }
+ }
+ } else {
+ warn("cmap table has unsupported format: " + format);
+ return {
+ platformId: -1,
+ encodingId: -1,
+ mappings: [],
+ hasShortCmap: false
+ };
+ }
+ mappings.sort(function (a, b) {
+ return a.charCode - b.charCode;
+ });
+ for (let i = 1; i < mappings.length; i++) {
+ if (mappings[i - 1].charCode === mappings[i].charCode) {
+ mappings.splice(i, 1);
+ i--;
+ }
+ }
+ return {
+ platformId: potentialTable.platformId,
+ encodingId: potentialTable.encodingId,
+ mappings,
+ hasShortCmap
+ };
+ }
+ function sanitizeMetrics(file, header, metrics, headTable, numGlyphs, dupFirstEntry) {
+ if (!header) {
+ if (metrics) {
+ metrics.data = null;
+ }
+ return;
+ }
+ file.pos = (file.start || 0) + header.offset;
+ file.pos += 4;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ file.pos += 2;
+ const caretOffset = file.getUint16();
+ file.pos += 8;
+ file.pos += 2;
+ let numOfMetrics = file.getUint16();
+ if (caretOffset !== 0) {
+ const macStyle = int16(headTable.data[44], headTable.data[45]);
+ if (!(macStyle & 2)) {
+ header.data[22] = 0;
+ header.data[23] = 0;
+ }
+ }
+ if (numOfMetrics > numGlyphs) {
+ info(`The numOfMetrics (${numOfMetrics}) should not be ` + `greater than the numGlyphs (${numGlyphs}).`);
+ numOfMetrics = numGlyphs;
+ header.data[34] = (numOfMetrics & 0xff00) >> 8;
+ header.data[35] = numOfMetrics & 0x00ff;
+ }
+ const numOfSidebearings = numGlyphs - numOfMetrics;
+ const numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1);
+ if (numMissing > 0) {
+ const entries = new Uint8Array(metrics.length + numMissing * 2);
+ entries.set(metrics.data);
+ if (dupFirstEntry) {
+ entries[metrics.length] = metrics.data[2];
+ entries[metrics.length + 1] = metrics.data[3];
+ }
+ metrics.data = entries;
+ }
+ }
+ function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) {
+ const glyphProfile = {
+ length: 0,
+ sizeOfInstructions: 0
+ };
+ if (sourceStart < 0 || sourceStart >= source.length || sourceEnd > source.length || sourceEnd - sourceStart <= 12) {
+ return glyphProfile;
+ }
+ const glyf = source.subarray(sourceStart, sourceEnd);
+ const xMin = signedInt16(glyf[2], glyf[3]);
+ const yMin = signedInt16(glyf[4], glyf[5]);
+ const xMax = signedInt16(glyf[6], glyf[7]);
+ const yMax = signedInt16(glyf[8], glyf[9]);
+ if (xMin > xMax) {
+ writeSignedInt16(glyf, 2, xMax);
+ writeSignedInt16(glyf, 6, xMin);
+ }
+ if (yMin > yMax) {
+ writeSignedInt16(glyf, 4, yMax);
+ writeSignedInt16(glyf, 8, yMin);
+ }
+ const contoursCount = signedInt16(glyf[0], glyf[1]);
+ if (contoursCount < 0) {
+ if (contoursCount < -1) {
+ return glyphProfile;
+ }
+ dest.set(glyf, destStart);
+ glyphProfile.length = glyf.length;
+ return glyphProfile;
+ }
+ let i,
+ j = 10,
+ flagsCount = 0;
+ for (i = 0; i < contoursCount; i++) {
+ const endPoint = glyf[j] << 8 | glyf[j + 1];
+ flagsCount = endPoint + 1;
+ j += 2;
+ }
+ const instructionsStart = j;
+ const instructionsLength = glyf[j] << 8 | glyf[j + 1];
+ glyphProfile.sizeOfInstructions = instructionsLength;
+ j += 2 + instructionsLength;
+ const instructionsEnd = j;
+ let coordinatesLength = 0;
+ for (i = 0; i < flagsCount; i++) {
+ const flag = glyf[j++];
+ if (flag & 0xc0) {
+ glyf[j - 1] = flag & 0x3f;
+ }
+ let xLength = 2;
+ if (flag & 2) {
+ xLength = 1;
+ } else if (flag & 16) {
+ xLength = 0;
+ }
+ let yLength = 2;
+ if (flag & 4) {
+ yLength = 1;
+ } else if (flag & 32) {
+ yLength = 0;
+ }
+ const xyLength = xLength + yLength;
+ coordinatesLength += xyLength;
+ if (flag & 8) {
+ const repeat = glyf[j++];
+ if (repeat === 0) {
+ glyf[j - 1] ^= 8;
+ }
+ i += repeat;
+ coordinatesLength += repeat * xyLength;
+ }
+ }
+ if (coordinatesLength === 0) {
+ return glyphProfile;
+ }
+ let glyphDataLength = j + coordinatesLength;
+ if (glyphDataLength > glyf.length) {
+ return glyphProfile;
+ }
+ if (!hintsValid && instructionsLength > 0) {
+ dest.set(glyf.subarray(0, instructionsStart), destStart);
+ dest.set([0, 0], destStart + instructionsStart);
+ dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2);
+ glyphDataLength -= instructionsLength;
+ if (glyf.length - glyphDataLength > 3) {
+ glyphDataLength = glyphDataLength + 3 & ~3;
+ }
+ glyphProfile.length = glyphDataLength;
+ return glyphProfile;
+ }
+ if (glyf.length - glyphDataLength > 3) {
+ glyphDataLength = glyphDataLength + 3 & ~3;
+ dest.set(glyf.subarray(0, glyphDataLength), destStart);
+ glyphProfile.length = glyphDataLength;
+ return glyphProfile;
+ }
+ dest.set(glyf, destStart);
+ glyphProfile.length = glyf.length;
+ return glyphProfile;
+ }
+ function sanitizeHead(head, numGlyphs, locaLength) {
+ const data = head.data;
+ const version = int32(data[0], data[1], data[2], data[3]);
+ if (version >> 16 !== 1) {
+ info("Attempting to fix invalid version in head table: " + version);
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 0;
+ data[3] = 0;
+ }
+ const indexToLocFormat = int16(data[50], data[51]);
+ if (indexToLocFormat < 0 || indexToLocFormat > 1) {
+ info("Attempting to fix invalid indexToLocFormat in head table: " + indexToLocFormat);
+ const numGlyphsPlusOne = numGlyphs + 1;
+ if (locaLength === numGlyphsPlusOne << 1) {
+ data[50] = 0;
+ data[51] = 0;
+ } else if (locaLength === numGlyphsPlusOne << 2) {
+ data[50] = 0;
+ data[51] = 1;
+ } else {
+ throw new FormatError("Could not fix indexToLocFormat: " + indexToLocFormat);
+ }
+ }
+ }
+ function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) {
+ let itemSize, itemDecode, itemEncode;
+ if (isGlyphLocationsLong) {
+ itemSize = 4;
+ itemDecode = function fontItemDecodeLong(data, offset) {
+ return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
+ };
+ itemEncode = function fontItemEncodeLong(data, offset, value) {
+ data[offset] = value >>> 24 & 0xff;
+ data[offset + 1] = value >> 16 & 0xff;
+ data[offset + 2] = value >> 8 & 0xff;
+ data[offset + 3] = value & 0xff;
+ };
+ } else {
+ itemSize = 2;
+ itemDecode = function fontItemDecode(data, offset) {
+ return data[offset] << 9 | data[offset + 1] << 1;
+ };
+ itemEncode = function fontItemEncode(data, offset, value) {
+ data[offset] = value >> 9 & 0xff;
+ data[offset + 1] = value >> 1 & 0xff;
+ };
+ }
+ const numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs;
+ const locaDataSize = itemSize * (1 + numGlyphsOut);
+ const locaData = new Uint8Array(locaDataSize);
+ locaData.set(loca.data.subarray(0, locaDataSize));
+ loca.data = locaData;
+ const oldGlyfData = glyf.data;
+ const oldGlyfDataLength = oldGlyfData.length;
+ const newGlyfData = new Uint8Array(oldGlyfDataLength);
+ let i, j;
+ const locaEntries = [];
+ for (i = 0, j = 0; i < numGlyphs + 1; i++, j += itemSize) {
+ let offset = itemDecode(locaData, j);
+ if (offset > oldGlyfDataLength) {
+ offset = oldGlyfDataLength;
+ }
+ locaEntries.push({
+ index: i,
+ offset,
+ endOffset: 0
+ });
+ }
+ locaEntries.sort((a, b) => {
+ return a.offset - b.offset;
+ });
+ for (i = 0; i < numGlyphs; i++) {
+ locaEntries[i].endOffset = locaEntries[i + 1].offset;
+ }
+ locaEntries.sort((a, b) => {
+ return a.index - b.index;
+ });
+ for (i = 0; i < numGlyphs; i++) {
+ const {
+ offset,
+ endOffset
+ } = locaEntries[i];
+ if (offset !== 0 || endOffset !== 0) {
+ break;
+ }
+ const nextOffset = locaEntries[i + 1].offset;
+ if (nextOffset === 0) {
+ continue;
+ }
+ locaEntries[i].endOffset = nextOffset;
+ break;
+ }
+ const missingGlyphs = Object.create(null);
+ let writeOffset = 0;
+ itemEncode(locaData, 0, writeOffset);
+ for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
+ const glyphProfile = sanitizeGlyph(oldGlyfData, locaEntries[i].offset, locaEntries[i].endOffset, newGlyfData, writeOffset, hintsValid);
+ const newLength = glyphProfile.length;
+ if (newLength === 0) {
+ missingGlyphs[i] = true;
+ }
+ if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) {
+ maxSizeOfInstructions = glyphProfile.sizeOfInstructions;
+ }
+ writeOffset += newLength;
+ itemEncode(locaData, j, writeOffset);
+ }
+ if (writeOffset === 0) {
+ const simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);
+ for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) {
+ itemEncode(locaData, j, simpleGlyph.length);
+ }
+ glyf.data = simpleGlyph;
+ } else if (dupFirstEntry) {
+ const firstEntryLength = itemDecode(locaData, itemSize);
+ if (newGlyfData.length > firstEntryLength + writeOffset) {
+ glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);
+ } else {
+ glyf.data = new Uint8Array(firstEntryLength + writeOffset);
+ glyf.data.set(newGlyfData.subarray(0, writeOffset));
+ }
+ glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);
+ itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength);
+ } else {
+ glyf.data = newGlyfData.subarray(0, writeOffset);
+ }
+ return {
+ missingGlyphs,
+ maxSizeOfInstructions
+ };
+ }
+ function readPostScriptTable(post, propertiesObj, maxpNumGlyphs) {
+ const start = (font.start || 0) + post.offset;
+ font.pos = start;
+ const length = post.length,
+ end = start + length;
+ const version = font.getInt32();
+ font.skip(28);
+ let glyphNames;
+ let valid = true;
+ let i;
+ switch (version) {
+ case 0x00010000:
+ glyphNames = MacStandardGlyphOrdering;
+ break;
+ case 0x00020000:
+ const numGlyphs = font.getUint16();
+ if (numGlyphs !== maxpNumGlyphs) {
+ valid = false;
+ break;
+ }
+ const glyphNameIndexes = [];
+ for (i = 0; i < numGlyphs; ++i) {
+ const index = font.getUint16();
+ if (index >= 32768) {
+ valid = false;
+ break;
+ }
+ glyphNameIndexes.push(index);
+ }
+ if (!valid) {
+ break;
+ }
+ const customNames = [],
+ strBuf = [];
+ while (font.pos < end) {
+ const stringLength = font.getByte();
+ strBuf.length = stringLength;
+ for (i = 0; i < stringLength; ++i) {
+ strBuf[i] = String.fromCharCode(font.getByte());
+ }
+ customNames.push(strBuf.join(""));
+ }
+ glyphNames = [];
+ for (i = 0; i < numGlyphs; ++i) {
+ const j = glyphNameIndexes[i];
+ if (j < 258) {
+ glyphNames.push(MacStandardGlyphOrdering[j]);
+ continue;
+ }
+ glyphNames.push(customNames[j - 258]);
+ }
+ break;
+ case 0x00030000:
+ break;
+ default:
+ warn("Unknown/unsupported post table version " + version);
+ valid = false;
+ if (propertiesObj.defaultEncoding) {
+ glyphNames = propertiesObj.defaultEncoding;
+ }
+ break;
+ }
+ propertiesObj.glyphNames = glyphNames;
+ return valid;
+ }
+ function readNameTable(nameTable) {
+ const start = (font.start || 0) + nameTable.offset;
+ font.pos = start;
+ const names = [[], []],
+ records = [];
+ const length = nameTable.length,
+ end = start + length;
+ const format = font.getUint16();
+ const FORMAT_0_HEADER_LENGTH = 6;
+ if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {
+ return [names, records];
+ }
+ const numRecords = font.getUint16();
+ const stringsStart = font.getUint16();
+ const NAME_RECORD_LENGTH = 12;
+ let i, ii;
+ for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {
+ const r = {
+ platform: font.getUint16(),
+ encoding: font.getUint16(),
+ language: font.getUint16(),
+ name: font.getUint16(),
+ length: font.getUint16(),
+ offset: font.getUint16()
+ };
+ if (isMacNameRecord(r) || isWinNameRecord(r)) {
+ records.push(r);
+ }
+ }
+ for (i = 0, ii = records.length; i < ii; i++) {
+ const record = records[i];
+ if (record.length <= 0) {
+ continue;
+ }
+ const pos = start + stringsStart + record.offset;
+ if (pos + record.length > end) {
+ continue;
+ }
+ font.pos = pos;
+ const nameIndex = record.name;
+ if (record.encoding) {
+ let str = "";
+ for (let j = 0, jj = record.length; j < jj; j += 2) {
+ str += String.fromCharCode(font.getUint16());
+ }
+ names[1][nameIndex] = str;
+ } else {
+ names[0][nameIndex] = font.getString(record.length);
+ }
+ }
+ return [names, records];
+ }
+ const TTOpsStackDeltas = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2];
+ function sanitizeTTProgram(table, ttContext) {
+ let data = table.data;
+ let i = 0,
+ j,
+ n,
+ b,
+ funcId,
+ pc,
+ lastEndf = 0,
+ lastDeff = 0;
+ const stack = [];
+ const callstack = [];
+ const functionsCalled = [];
+ let tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions;
+ let inFDEF = false,
+ ifLevel = 0,
+ inELSE = 0;
+ for (let ii = data.length; i < ii;) {
+ const op = data[i++];
+ if (op === 0x40) {
+ n = data[i++];
+ if (inFDEF || inELSE) {
+ i += n;
+ } else {
+ for (j = 0; j < n; j++) {
+ stack.push(data[i++]);
+ }
+ }
+ } else if (op === 0x41) {
+ n = data[i++];
+ if (inFDEF || inELSE) {
+ i += n * 2;
+ } else {
+ for (j = 0; j < n; j++) {
+ b = data[i++];
+ stack.push(b << 8 | data[i++]);
+ }
+ }
+ } else if ((op & 0xf8) === 0xb0) {
+ n = op - 0xb0 + 1;
+ if (inFDEF || inELSE) {
+ i += n;
+ } else {
+ for (j = 0; j < n; j++) {
+ stack.push(data[i++]);
+ }
+ }
+ } else if ((op & 0xf8) === 0xb8) {
+ n = op - 0xb8 + 1;
+ if (inFDEF || inELSE) {
+ i += n * 2;
+ } else {
+ for (j = 0; j < n; j++) {
+ b = data[i++];
+ stack.push(b << 8 | data[i++]);
+ }
+ }
+ } else if (op === 0x2b && !tooComplexToFollowFunctions) {
+ if (!inFDEF && !inELSE) {
+ funcId = stack.at(-1);
+ if (isNaN(funcId)) {
+ info("TT: CALL empty stack (or invalid entry).");
+ } else {
+ ttContext.functionsUsed[funcId] = true;
+ if (funcId in ttContext.functionsStackDeltas) {
+ const newStackLength = stack.length + ttContext.functionsStackDeltas[funcId];
+ if (newStackLength < 0) {
+ warn("TT: CALL invalid functions stack delta.");
+ ttContext.hintsValid = false;
+ return;
+ }
+ stack.length = newStackLength;
+ } else if (funcId in ttContext.functionsDefined && !functionsCalled.includes(funcId)) {
+ callstack.push({
+ data,
+ i,
+ stackTop: stack.length - 1
+ });
+ functionsCalled.push(funcId);
+ pc = ttContext.functionsDefined[funcId];
+ if (!pc) {
+ warn("TT: CALL non-existent function");
+ ttContext.hintsValid = false;
+ return;
+ }
+ data = pc.data;
+ i = pc.i;
+ }
+ }
+ }
+ } else if (op === 0x2c && !tooComplexToFollowFunctions) {
+ if (inFDEF || inELSE) {
+ warn("TT: nested FDEFs not allowed");
+ tooComplexToFollowFunctions = true;
+ }
+ inFDEF = true;
+ lastDeff = i;
+ funcId = stack.pop();
+ ttContext.functionsDefined[funcId] = {
+ data,
+ i
+ };
+ } else if (op === 0x2d) {
+ if (inFDEF) {
+ inFDEF = false;
+ lastEndf = i;
+ } else {
+ pc = callstack.pop();
+ if (!pc) {
+ warn("TT: ENDF bad stack");
+ ttContext.hintsValid = false;
+ return;
+ }
+ funcId = functionsCalled.pop();
+ data = pc.data;
+ i = pc.i;
+ ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop;
+ }
+ } else if (op === 0x89) {
+ if (inFDEF || inELSE) {
+ warn("TT: nested IDEFs not allowed");
+ tooComplexToFollowFunctions = true;
+ }
+ inFDEF = true;
+ lastDeff = i;
+ } else if (op === 0x58) {
+ ++ifLevel;
+ } else if (op === 0x1b) {
+ inELSE = ifLevel;
+ } else if (op === 0x59) {
+ if (inELSE === ifLevel) {
+ inELSE = 0;
+ }
+ --ifLevel;
+ } else if (op === 0x1c) {
+ if (!inFDEF && !inELSE) {
+ const offset = stack.at(-1);
+ if (offset > 0) {
+ i += offset - 1;
+ }
+ }
+ }
+ if (!inFDEF && !inELSE) {
+ let stackDelta = 0;
+ if (op <= 0x8e) {
+ stackDelta = TTOpsStackDeltas[op];
+ } else if (op >= 0xc0 && op <= 0xdf) {
+ stackDelta = -1;
+ } else if (op >= 0xe0) {
+ stackDelta = -2;
+ }
+ if (op >= 0x71 && op <= 0x75) {
+ n = stack.pop();
+ if (!isNaN(n)) {
+ stackDelta = -n * 2;
+ }
+ }
+ while (stackDelta < 0 && stack.length > 0) {
+ stack.pop();
+ stackDelta++;
+ }
+ while (stackDelta > 0) {
+ stack.push(NaN);
+ stackDelta--;
+ }
+ }
+ }
+ ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;
+ const content = [data];
+ if (i > data.length) {
+ content.push(new Uint8Array(i - data.length));
+ }
+ if (lastDeff > lastEndf) {
+ warn("TT: complementing a missing function tail");
+ content.push(new Uint8Array([0x22, 0x2d]));
+ }
+ foldTTTable(table, content);
+ }
+ function checkInvalidFunctions(ttContext, maxFunctionDefs) {
+ if (ttContext.tooComplexToFollowFunctions) {
+ return;
+ }
+ if (ttContext.functionsDefined.length > maxFunctionDefs) {
+ warn("TT: more functions defined than expected");
+ ttContext.hintsValid = false;
+ return;
+ }
+ for (let j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {
+ if (j > maxFunctionDefs) {
+ warn("TT: invalid function id: " + j);
+ ttContext.hintsValid = false;
+ return;
+ }
+ if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) {
+ warn("TT: undefined function: " + j);
+ ttContext.hintsValid = false;
+ return;
+ }
+ }
+ }
+ function foldTTTable(table, content) {
+ if (content.length > 1) {
+ let newLength = 0;
+ let j, jj;
+ for (j = 0, jj = content.length; j < jj; j++) {
+ newLength += content[j].length;
+ }
+ newLength = newLength + 3 & ~3;
+ const result = new Uint8Array(newLength);
+ let pos = 0;
+ for (j = 0, jj = content.length; j < jj; j++) {
+ result.set(content[j], pos);
+ pos += content[j].length;
+ }
+ table.data = result;
+ table.length = newLength;
+ }
+ }
+ function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) {
+ const ttContext = {
+ functionsDefined: [],
+ functionsUsed: [],
+ functionsStackDeltas: [],
+ tooComplexToFollowFunctions: false,
+ hintsValid: true
+ };
+ if (fpgm) {
+ sanitizeTTProgram(fpgm, ttContext);
+ }
+ if (prep) {
+ sanitizeTTProgram(prep, ttContext);
+ }
+ if (fpgm) {
+ checkInvalidFunctions(ttContext, maxFunctionDefs);
+ }
+ if (cvt && cvt.length & 1) {
+ const cvtData = new Uint8Array(cvt.length + 1);
+ cvtData.set(cvt.data);
+ cvt.data = cvtData;
+ }
+ return ttContext.hintsValid;
+ }
+ font = new Stream(new Uint8Array(font.getBytes()));
+ let header, tables;
+ if (isTrueTypeCollectionFile(font)) {
+ const ttcData = readTrueTypeCollectionData(font, this.name);
+ header = ttcData.header;
+ tables = ttcData.tables;
+ } else {
+ header = readOpenTypeHeader(font);
+ tables = readTables(font, header.numTables);
+ }
+ let cff, cffFile;
+ const isTrueType = !tables["CFF "];
+ if (!isTrueType) {
+ const isComposite = properties.composite && (properties.cidToGidMap?.length > 0 || !(properties.cMap instanceof IdentityCMap));
+ if (header.version === "OTTO" && !isComposite || !tables.head || !tables.hhea || !tables.maxp || !tables.post) {
+ cffFile = new Stream(tables["CFF "].data);
+ cff = new CFFFont(cffFile, properties);
+ adjustWidths(properties);
+ return this.convert(name, cff, properties);
+ }
+ delete tables.glyf;
+ delete tables.loca;
+ delete tables.fpgm;
+ delete tables.prep;
+ delete tables["cvt "];
+ this.isOpenType = true;
+ } else {
+ if (!tables.loca) {
+ throw new FormatError('Required "loca" table is not found');
+ }
+ if (!tables.glyf) {
+ warn('Required "glyf" table is not found -- trying to recover.');
+ tables.glyf = {
+ tag: "glyf",
+ data: new Uint8Array(0)
+ };
+ }
+ this.isOpenType = false;
+ }
+ if (!tables.maxp) {
+ throw new FormatError('Required "maxp" table is not found');
+ }
+ font.pos = (font.start || 0) + tables.maxp.offset;
+ let version = font.getInt32();
+ const numGlyphs = font.getUint16();
+ if (version !== 0x00010000 && version !== 0x00005000) {
+ if (tables.maxp.length === 6) {
+ version = 0x0005000;
+ } else if (tables.maxp.length >= 32) {
+ version = 0x00010000;
+ } else {
+ throw new FormatError(`"maxp" table has a wrong version number`);
+ }
+ writeUint32(tables.maxp.data, 0, version);
+ }
+ if (properties.scaleFactors?.length === numGlyphs && isTrueType) {
+ const {
+ scaleFactors
+ } = properties;
+ const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]);
+ const glyphs = new GlyfTable({
+ glyfTable: tables.glyf.data,
+ isGlyphLocationsLong,
+ locaTable: tables.loca.data,
+ numGlyphs
+ });
+ glyphs.scale(scaleFactors);
+ const {
+ glyf,
+ loca,
+ isLocationLong
+ } = glyphs.write();
+ tables.glyf.data = glyf;
+ tables.loca.data = loca;
+ if (isLocationLong !== !!isGlyphLocationsLong) {
+ tables.head.data[50] = 0;
+ tables.head.data[51] = isLocationLong ? 1 : 0;
+ }
+ const metrics = tables.hmtx.data;
+ for (let i = 0; i < numGlyphs; i++) {
+ const j = 4 * i;
+ const advanceWidth = Math.round(scaleFactors[i] * int16(metrics[j], metrics[j + 1]));
+ metrics[j] = advanceWidth >> 8 & 0xff;
+ metrics[j + 1] = advanceWidth & 0xff;
+ const lsb = Math.round(scaleFactors[i] * signedInt16(metrics[j + 2], metrics[j + 3]));
+ writeSignedInt16(metrics, j + 2, lsb);
+ }
+ }
+ let numGlyphsOut = numGlyphs + 1;
+ let dupFirstEntry = true;
+ if (numGlyphsOut > 0xffff) {
+ dupFirstEntry = false;
+ numGlyphsOut = numGlyphs;
+ warn("Not enough space in glyfs to duplicate first glyph.");
+ }
+ let maxFunctionDefs = 0;
+ let maxSizeOfInstructions = 0;
+ if (version >= 0x00010000 && tables.maxp.length >= 32) {
+ font.pos += 8;
+ const maxZones = font.getUint16();
+ if (maxZones > 2) {
+ tables.maxp.data[14] = 0;
+ tables.maxp.data[15] = 2;
+ }
+ font.pos += 4;
+ maxFunctionDefs = font.getUint16();
+ font.pos += 4;
+ maxSizeOfInstructions = font.getUint16();
+ }
+ tables.maxp.data[4] = numGlyphsOut >> 8;
+ tables.maxp.data[5] = numGlyphsOut & 255;
+ const hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep, tables["cvt "], maxFunctionDefs);
+ if (!hintsValid) {
+ delete tables.fpgm;
+ delete tables.prep;
+ delete tables["cvt "];
+ }
+ sanitizeMetrics(font, tables.hhea, tables.hmtx, tables.head, numGlyphsOut, dupFirstEntry);
+ if (!tables.head) {
+ throw new FormatError('Required "head" table is not found');
+ }
+ sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0);
+ let missingGlyphs = Object.create(null);
+ if (isTrueType) {
+ const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]);
+ const glyphsInfo = sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions);
+ missingGlyphs = glyphsInfo.missingGlyphs;
+ if (version >= 0x00010000 && tables.maxp.length >= 32) {
+ tables.maxp.data[26] = glyphsInfo.maxSizeOfInstructions >> 8;
+ tables.maxp.data[27] = glyphsInfo.maxSizeOfInstructions & 255;
+ }
+ }
+ if (!tables.hhea) {
+ throw new FormatError('Required "hhea" table is not found');
+ }
+ if (tables.hhea.data[10] === 0 && tables.hhea.data[11] === 0) {
+ tables.hhea.data[10] = 0xff;
+ tables.hhea.data[11] = 0xff;
+ }
+ const metricsOverride = {
+ unitsPerEm: int16(tables.head.data[18], tables.head.data[19]),
+ yMax: signedInt16(tables.head.data[42], tables.head.data[43]),
+ yMin: signedInt16(tables.head.data[38], tables.head.data[39]),
+ ascent: signedInt16(tables.hhea.data[4], tables.hhea.data[5]),
+ descent: signedInt16(tables.hhea.data[6], tables.hhea.data[7]),
+ lineGap: signedInt16(tables.hhea.data[8], tables.hhea.data[9])
+ };
+ this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;
+ this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;
+ this.lineGap = metricsOverride.lineGap / metricsOverride.unitsPerEm;
+ if (this.cssFontInfo?.lineHeight) {
+ this.lineHeight = this.cssFontInfo.metrics.lineHeight;
+ this.lineGap = this.cssFontInfo.metrics.lineGap;
+ } else {
+ this.lineHeight = this.ascent - this.descent + this.lineGap;
+ }
+ if (tables.post) {
+ readPostScriptTable(tables.post, properties, numGlyphs);
+ }
+ tables.post = {
+ tag: "post",
+ data: createPostTable(properties)
+ };
+ const charCodeToGlyphId = [];
+ function hasGlyph(glyphId) {
+ return !missingGlyphs[glyphId];
+ }
+ if (properties.composite) {
+ const cidToGidMap = properties.cidToGidMap || [];
+ const isCidToGidMapEmpty = cidToGidMap.length === 0;
+ properties.cMap.forEach(function (charCode, cid) {
+ if (typeof cid === "string") {
+ cid = convertCidString(charCode, cid, true);
+ }
+ if (cid > 0xffff) {
+ throw new FormatError("Max size of CID is 65,535");
+ }
+ let glyphId = -1;
+ if (isCidToGidMapEmpty) {
+ glyphId = cid;
+ } else if (cidToGidMap[cid] !== undefined) {
+ glyphId = cidToGidMap[cid];
+ }
+ if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {
+ charCodeToGlyphId[charCode] = glyphId;
+ }
+ });
+ } else {
+ const cmapTable = readCmapTable(tables.cmap, font, this.isSymbolicFont, properties.hasEncoding);
+ const cmapPlatformId = cmapTable.platformId;
+ const cmapEncodingId = cmapTable.encodingId;
+ const cmapMappings = cmapTable.mappings;
+ let baseEncoding = [],
+ forcePostTable = false;
+ if (properties.hasEncoding && (properties.baseEncodingName === "MacRomanEncoding" || properties.baseEncodingName === "WinAnsiEncoding")) {
+ baseEncoding = getEncoding(properties.baseEncodingName);
+ }
+ if (properties.hasEncoding && !this.isSymbolicFont && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0)) {
+ const glyphsUnicodeMap = getGlyphsUnicode();
+ for (let charCode = 0; charCode < 256; charCode++) {
+ let glyphName;
+ if (this.differences[charCode] !== undefined) {
+ glyphName = this.differences[charCode];
+ } else if (baseEncoding.length && baseEncoding[charCode] !== "") {
+ glyphName = baseEncoding[charCode];
+ } else {
+ glyphName = StandardEncoding[charCode];
+ }
+ if (!glyphName) {
+ continue;
+ }
+ const standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);
+ let unicodeOrCharCode;
+ if (cmapPlatformId === 3 && cmapEncodingId === 1) {
+ unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName];
+ } else if (cmapPlatformId === 1 && cmapEncodingId === 0) {
+ unicodeOrCharCode = MacRomanEncoding.indexOf(standardGlyphName);
+ }
+ if (unicodeOrCharCode === undefined) {
+ if (!properties.glyphNames && properties.hasIncludedToUnicodeMap && !(this.toUnicode instanceof IdentityToUnicodeMap)) {
+ const unicode = this.toUnicode.get(charCode);
+ if (unicode) {
+ unicodeOrCharCode = unicode.codePointAt(0);
+ }
+ }
+ if (unicodeOrCharCode === undefined) {
+ continue;
+ }
+ }
+ for (const mapping of cmapMappings) {
+ if (mapping.charCode !== unicodeOrCharCode) {
+ continue;
+ }
+ charCodeToGlyphId[charCode] = mapping.glyphId;
+ break;
+ }
+ }
+ } else if (cmapPlatformId === 0) {
+ for (const mapping of cmapMappings) {
+ charCodeToGlyphId[mapping.charCode] = mapping.glyphId;
+ }
+ forcePostTable = true;
+ } else {
+ for (const mapping of cmapMappings) {
+ let charCode = mapping.charCode;
+ if (cmapPlatformId === 3 && charCode >= 0xf000 && charCode <= 0xf0ff) {
+ charCode &= 0xff;
+ }
+ charCodeToGlyphId[charCode] = mapping.glyphId;
+ }
+ }
+ if (properties.glyphNames && (baseEncoding.length || this.differences.length)) {
+ for (let i = 0; i < 256; ++i) {
+ if (!forcePostTable && charCodeToGlyphId[i] !== undefined) {
+ continue;
+ }
+ const glyphName = this.differences[i] || baseEncoding[i];
+ if (!glyphName) {
+ continue;
+ }
+ const glyphId = properties.glyphNames.indexOf(glyphName);
+ if (glyphId > 0 && hasGlyph(glyphId)) {
+ charCodeToGlyphId[i] = glyphId;
+ }
+ }
+ }
+ }
+ if (charCodeToGlyphId.length === 0) {
+ charCodeToGlyphId[0] = 0;
+ }
+ let glyphZeroId = numGlyphsOut - 1;
+ if (!dupFirstEntry) {
+ glyphZeroId = 0;
+ }
+ if (!properties.cssFontInfo) {
+ const newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId, this.toUnicode);
+ this.toFontChar = newMapping.toFontChar;
+ tables.cmap = {
+ tag: "cmap",
+ data: createCmapTable(newMapping.charCodeToGlyphId, newMapping.toUnicodeExtraMap, numGlyphsOut)
+ };
+ if (!tables["OS/2"] || !validateOS2Table(tables["OS/2"], font)) {
+ tables["OS/2"] = {
+ tag: "OS/2",
+ data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)
+ };
+ }
+ }
+ if (!isTrueType) {
+ try {
+ cffFile = new Stream(tables["CFF "].data);
+ const parser = new CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);
+ cff = parser.parse();
+ cff.duplicateFirstGlyph();
+ const compiler = new CFFCompiler(cff);
+ tables["CFF "].data = compiler.compile();
+ } catch {
+ warn("Failed to compile font " + properties.loadedName);
+ }
+ }
+ if (!tables.name) {
+ tables.name = {
+ tag: "name",
+ data: createNameTable(this.name)
+ };
+ } else {
+ const [namePrototype, nameRecords] = readNameTable(tables.name);
+ tables.name.data = createNameTable(name, namePrototype);
+ this.psName = namePrototype[0][6] || null;
+ if (!properties.composite) {
+ adjustTrueTypeToUnicode(properties, this.isSymbolicFont, nameRecords);
+ }
+ }
+ const builder = new OpenTypeFileBuilder(header.version);
+ for (const tableTag in tables) {
+ builder.addTable(tableTag, tables[tableTag].data);
+ }
+ return builder.toArray();
+ }
+ convert(fontName, font, properties) {
+ properties.fixedPitch = false;
+ if (properties.builtInEncoding) {
+ adjustType1ToUnicode(properties, properties.builtInEncoding);
+ }
+ let glyphZeroId = 1;
+ if (font instanceof CFFFont) {
+ glyphZeroId = font.numGlyphs - 1;
+ }
+ const mapping = font.getGlyphMapping(properties);
+ let newMapping = null;
+ let newCharCodeToGlyphId = mapping;
+ let toUnicodeExtraMap = null;
+ if (!properties.cssFontInfo) {
+ newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId, this.toUnicode);
+ this.toFontChar = newMapping.toFontChar;
+ newCharCodeToGlyphId = newMapping.charCodeToGlyphId;
+ toUnicodeExtraMap = newMapping.toUnicodeExtraMap;
+ }
+ const numGlyphs = font.numGlyphs;
+ function getCharCodes(charCodeToGlyphId, glyphId) {
+ let charCodes = null;
+ for (const charCode in charCodeToGlyphId) {
+ if (glyphId === charCodeToGlyphId[charCode]) {
+ (charCodes ||= []).push(charCode | 0);
+ }
+ }
+ return charCodes;
+ }
+ function createCharCode(charCodeToGlyphId, glyphId) {
+ for (const charCode in charCodeToGlyphId) {
+ if (glyphId === charCodeToGlyphId[charCode]) {
+ return charCode | 0;
+ }
+ }
+ newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = glyphId;
+ return newMapping.nextAvailableFontCharCode++;
+ }
+ const seacs = font.seacs;
+ if (newMapping && SEAC_ANALYSIS_ENABLED && seacs?.length) {
+ const matrix = properties.fontMatrix || FONT_IDENTITY_MATRIX;
+ const charset = font.getCharset();
+ const seacMap = Object.create(null);
+ for (let glyphId in seacs) {
+ glyphId |= 0;
+ const seac = seacs[glyphId];
+ const baseGlyphName = StandardEncoding[seac[2]];
+ const accentGlyphName = StandardEncoding[seac[3]];
+ const baseGlyphId = charset.indexOf(baseGlyphName);
+ const accentGlyphId = charset.indexOf(accentGlyphName);
+ if (baseGlyphId < 0 || accentGlyphId < 0) {
+ continue;
+ }
+ const accentOffset = {
+ x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4],
+ y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5]
+ };
+ const charCodes = getCharCodes(mapping, glyphId);
+ if (!charCodes) {
+ continue;
+ }
+ for (const charCode of charCodes) {
+ const charCodeToGlyphId = newMapping.charCodeToGlyphId;
+ const baseFontCharCode = createCharCode(charCodeToGlyphId, baseGlyphId);
+ const accentFontCharCode = createCharCode(charCodeToGlyphId, accentGlyphId);
+ seacMap[charCode] = {
+ baseFontCharCode,
+ accentFontCharCode,
+ accentOffset
+ };
+ }
+ }
+ properties.seacMap = seacMap;
+ }
+ const unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];
+ const builder = new OpenTypeFileBuilder("\x4F\x54\x54\x4F");
+ builder.addTable("CFF ", font.data);
+ builder.addTable("OS/2", createOS2Table(properties, newCharCodeToGlyphId));
+ builder.addTable("cmap", createCmapTable(newCharCodeToGlyphId, toUnicodeExtraMap, numGlyphs));
+ builder.addTable("head", "\x00\x01\x00\x00" + "\x00\x00\x10\x00" + "\x00\x00\x00\x00" + "\x5F\x0F\x3C\xF5" + "\x00\x00" + safeString16(unitsPerEm) + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00" + safeString16(properties.descent) + "\x0F\xFF" + safeString16(properties.ascent) + string16(properties.italicAngle ? 2 : 0) + "\x00\x11" + "\x00\x00" + "\x00\x00" + "\x00\x00");
+ builder.addTable("hhea", "\x00\x01\x00\x00" + safeString16(properties.ascent) + safeString16(properties.descent) + "\x00\x00" + "\xFF\xFF" + "\x00\x00" + "\x00\x00" + "\x00\x00" + safeString16(properties.capHeight) + safeString16(Math.tan(properties.italicAngle) * properties.xHeight) + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + string16(numGlyphs));
+ builder.addTable("hmtx", function fontFieldsHmtx() {
+ const charstrings = font.charstrings;
+ const cffWidths = font.cff ? font.cff.widths : null;
+ let hmtx = "\x00\x00\x00\x00";
+ for (let i = 1, ii = numGlyphs; i < ii; i++) {
+ let width = 0;
+ if (charstrings) {
+ const charstring = charstrings[i - 1];
+ width = "width" in charstring ? charstring.width : 0;
+ } else if (cffWidths) {
+ width = Math.ceil(cffWidths[i] || 0);
+ }
+ hmtx += string16(width) + string16(0);
+ }
+ return hmtx;
+ }());
+ builder.addTable("maxp", "\x00\x00\x50\x00" + string16(numGlyphs));
+ builder.addTable("name", createNameTable(fontName));
+ builder.addTable("post", createPostTable(properties));
+ return builder.toArray();
+ }
+ get spaceWidth() {
+ const possibleSpaceReplacements = ["space", "minus", "one", "i", "I"];
+ let width;
+ for (const glyphName of possibleSpaceReplacements) {
+ if (glyphName in this.widths) {
+ width = this.widths[glyphName];
+ break;
+ }
+ const glyphsUnicodeMap = getGlyphsUnicode();
+ const glyphUnicode = glyphsUnicodeMap[glyphName];
+ let charcode = 0;
+ if (this.composite && this.cMap.contains(glyphUnicode)) {
+ charcode = this.cMap.lookup(glyphUnicode);
+ if (typeof charcode === "string") {
+ charcode = convertCidString(glyphUnicode, charcode);
+ }
+ }
+ if (!charcode && this.toUnicode) {
+ charcode = this.toUnicode.charCodeOf(glyphUnicode);
+ }
+ if (charcode <= 0) {
+ charcode = glyphUnicode;
+ }
+ width = this.widths[charcode];
+ if (width) {
+ break;
+ }
+ }
+ return shadow(this, "spaceWidth", width || this.defaultWidth);
+ }
+ _charToGlyph(charcode, isSpace = false) {
+ let glyph = this._glyphCache[charcode];
+ if (glyph?.isSpace === isSpace) {
+ return glyph;
+ }
+ let fontCharCode, width, operatorListId;
+ let widthCode = charcode;
+ if (this.cMap?.contains(charcode)) {
+ widthCode = this.cMap.lookup(charcode);
+ if (typeof widthCode === "string") {
+ widthCode = convertCidString(charcode, widthCode);
+ }
+ }
+ width = this.widths[widthCode];
+ if (typeof width !== "number") {
+ width = this.defaultWidth;
+ }
+ const vmetric = this.vmetrics?.[widthCode];
+ let unicode = this.toUnicode.get(charcode) || charcode;
+ if (typeof unicode === "number") {
+ unicode = String.fromCharCode(unicode);
+ }
+ let isInFont = this.toFontChar[charcode] !== undefined;
+ fontCharCode = this.toFontChar[charcode] || charcode;
+ if (this.missingFile) {
+ const glyphName = this.differences[charcode] || this.defaultEncoding[charcode];
+ if ((glyphName === ".notdef" || glyphName === "") && this.type === "Type1") {
+ fontCharCode = 0x20;
+ }
+ fontCharCode = mapSpecialUnicodeValues(fontCharCode);
+ }
+ if (this.isType3Font) {
+ operatorListId = fontCharCode;
+ }
+ let accent = null;
+ if (this.seacMap?.[charcode]) {
+ isInFont = true;
+ const seac = this.seacMap[charcode];
+ fontCharCode = seac.baseFontCharCode;
+ accent = {
+ fontChar: String.fromCodePoint(seac.accentFontCharCode),
+ offset: seac.accentOffset
+ };
+ }
+ let fontChar = "";
+ if (typeof fontCharCode === "number") {
+ if (fontCharCode <= 0x10ffff) {
+ fontChar = String.fromCodePoint(fontCharCode);
+ } else {
+ warn(`charToGlyph - invalid fontCharCode: ${fontCharCode}`);
+ }
+ }
+ glyph = new fonts_Glyph(charcode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont);
+ return this._glyphCache[charcode] = glyph;
+ }
+ charsToGlyphs(chars) {
+ let glyphs = this._charsCache[chars];
+ if (glyphs) {
+ return glyphs;
+ }
+ glyphs = [];
+ if (this.cMap) {
+ const c = Object.create(null),
+ ii = chars.length;
+ let i = 0;
+ while (i < ii) {
+ this.cMap.readCharCode(chars, i, c);
+ const {
+ charcode,
+ length
+ } = c;
+ i += length;
+ const glyph = this._charToGlyph(charcode, length === 1 && chars.charCodeAt(i - 1) === 0x20);
+ glyphs.push(glyph);
+ }
+ } else {
+ for (let i = 0, ii = chars.length; i < ii; ++i) {
+ const charcode = chars.charCodeAt(i);
+ const glyph = this._charToGlyph(charcode, charcode === 0x20);
+ glyphs.push(glyph);
+ }
+ }
+ return this._charsCache[chars] = glyphs;
+ }
+ getCharPositions(chars) {
+ const positions = [];
+ if (this.cMap) {
+ const c = Object.create(null);
+ let i = 0;
+ while (i < chars.length) {
+ this.cMap.readCharCode(chars, i, c);
+ const length = c.length;
+ positions.push([i, i + length]);
+ i += length;
+ }
+ } else {
+ for (let i = 0, ii = chars.length; i < ii; ++i) {
+ positions.push([i, i + 1]);
+ }
+ }
+ return positions;
+ }
+ get glyphCacheValues() {
+ return Object.values(this._glyphCache);
+ }
+ encodeString(str) {
+ const buffers = [];
+ const currentBuf = [];
+ const hasCurrentBufErrors = () => buffers.length % 2 === 1;
+ const getCharCode = this.toUnicode instanceof IdentityToUnicodeMap ? unicode => this.toUnicode.charCodeOf(unicode) : unicode => this.toUnicode.charCodeOf(String.fromCodePoint(unicode));
+ for (let i = 0, ii = str.length; i < ii; i++) {
+ const unicode = str.codePointAt(i);
+ if (unicode > 0xd7ff && (unicode < 0xe000 || unicode > 0xfffd)) {
+ i++;
+ }
+ if (this.toUnicode) {
+ const charCode = getCharCode(unicode);
+ if (charCode !== -1) {
+ if (hasCurrentBufErrors()) {
+ buffers.push(currentBuf.join(""));
+ currentBuf.length = 0;
+ }
+ const charCodeLength = this.cMap ? this.cMap.getCharCodeLength(charCode) : 1;
+ for (let j = charCodeLength - 1; j >= 0; j--) {
+ currentBuf.push(String.fromCharCode(charCode >> 8 * j & 0xff));
+ }
+ continue;
+ }
+ }
+ if (!hasCurrentBufErrors()) {
+ buffers.push(currentBuf.join(""));
+ currentBuf.length = 0;
+ }
+ currentBuf.push(String.fromCodePoint(unicode));
+ }
+ buffers.push(currentBuf.join(""));
+ return buffers;
+ }
+}
+class ErrorFont {
+ constructor(error) {
+ this.error = error;
+ this.loadedName = "g_font_error";
+ this.missingFile = true;
+ }
+ charsToGlyphs() {
+ return [];
+ }
+ encodeString(chars) {
+ return [chars];
+ }
+ exportData(extraProperties = false) {
+ return {
+ error: this.error
+ };
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/pattern.js
+
+
+
+
+const ShadingType = {
+ FUNCTION_BASED: 1,
+ AXIAL: 2,
+ RADIAL: 3,
+ FREE_FORM_MESH: 4,
+ LATTICE_FORM_MESH: 5,
+ COONS_PATCH_MESH: 6,
+ TENSOR_PATCH_MESH: 7
+};
+class Pattern {
+ constructor() {
+ unreachable("Cannot initialize Pattern.");
+ }
+ static parseShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache) {
+ const dict = shading instanceof BaseStream ? shading.dict : shading;
+ const type = dict.get("ShadingType");
+ try {
+ switch (type) {
+ case ShadingType.AXIAL:
+ case ShadingType.RADIAL:
+ return new RadialAxialShading(dict, xref, res, pdfFunctionFactory, localColorSpaceCache);
+ case ShadingType.FREE_FORM_MESH:
+ case ShadingType.LATTICE_FORM_MESH:
+ case ShadingType.COONS_PATCH_MESH:
+ case ShadingType.TENSOR_PATCH_MESH:
+ return new MeshShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache);
+ default:
+ throw new FormatError("Unsupported ShadingType: " + type);
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(ex);
+ return new DummyShading();
+ }
+ }
+}
+class BaseShading {
+ static SMALL_NUMBER = 1e-6;
+ constructor() {
+ if (this.constructor === BaseShading) {
+ unreachable("Cannot initialize BaseShading.");
+ }
+ }
+ getIR() {
+ unreachable("Abstract method `getIR` called.");
+ }
+}
+class RadialAxialShading extends BaseShading {
+ constructor(dict, xref, resources, pdfFunctionFactory, localColorSpaceCache) {
+ super();
+ this.coordsArr = dict.getArray("Coords");
+ this.shadingType = dict.get("ShadingType");
+ const cs = ColorSpace.parse({
+ cs: dict.getRaw("CS") || dict.getRaw("ColorSpace"),
+ xref,
+ resources,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ const bbox = dict.getArray("BBox");
+ this.bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;
+ let t0 = 0.0,
+ t1 = 1.0;
+ if (dict.has("Domain")) {
+ const domainArr = dict.getArray("Domain");
+ t0 = domainArr[0];
+ t1 = domainArr[1];
+ }
+ let extendStart = false,
+ extendEnd = false;
+ if (dict.has("Extend")) {
+ const extendArr = dict.getArray("Extend");
+ extendStart = extendArr[0];
+ extendEnd = extendArr[1];
+ }
+ if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) {
+ const [x1, y1, r1, x2, y2, r2] = this.coordsArr;
+ const distance = Math.hypot(x1 - x2, y1 - y2);
+ if (r1 <= r2 + distance && r2 <= r1 + distance) {
+ warn("Unsupported radial gradient.");
+ }
+ }
+ this.extendStart = extendStart;
+ this.extendEnd = extendEnd;
+ const fnObj = dict.getRaw("Function");
+ const fn = pdfFunctionFactory.createFromArray(fnObj);
+ const NUMBER_OF_SAMPLES = 840;
+ const step = (t1 - t0) / NUMBER_OF_SAMPLES;
+ const colorStops = this.colorStops = [];
+ if (t0 >= t1 || step <= 0) {
+ info("Bad shading domain.");
+ return;
+ }
+ const color = new Float32Array(cs.numComps),
+ ratio = new Float32Array(1);
+ let rgbColor;
+ let iBase = 0;
+ ratio[0] = t0;
+ fn(ratio, 0, color, 0);
+ let rgbBase = cs.getRgb(color, 0);
+ const cssColorBase = Util.makeHexColor(rgbBase[0], rgbBase[1], rgbBase[2]);
+ colorStops.push([0, cssColorBase]);
+ let iPrev = 1;
+ ratio[0] = t0 + step;
+ fn(ratio, 0, color, 0);
+ let rgbPrev = cs.getRgb(color, 0);
+ let maxSlopeR = rgbPrev[0] - rgbBase[0] + 1;
+ let maxSlopeG = rgbPrev[1] - rgbBase[1] + 1;
+ let maxSlopeB = rgbPrev[2] - rgbBase[2] + 1;
+ let minSlopeR = rgbPrev[0] - rgbBase[0] - 1;
+ let minSlopeG = rgbPrev[1] - rgbBase[1] - 1;
+ let minSlopeB = rgbPrev[2] - rgbBase[2] - 1;
+ for (let i = 2; i < NUMBER_OF_SAMPLES; i++) {
+ ratio[0] = t0 + i * step;
+ fn(ratio, 0, color, 0);
+ rgbColor = cs.getRgb(color, 0);
+ const run = i - iBase;
+ maxSlopeR = Math.min(maxSlopeR, (rgbColor[0] - rgbBase[0] + 1) / run);
+ maxSlopeG = Math.min(maxSlopeG, (rgbColor[1] - rgbBase[1] + 1) / run);
+ maxSlopeB = Math.min(maxSlopeB, (rgbColor[2] - rgbBase[2] + 1) / run);
+ minSlopeR = Math.max(minSlopeR, (rgbColor[0] - rgbBase[0] - 1) / run);
+ minSlopeG = Math.max(minSlopeG, (rgbColor[1] - rgbBase[1] - 1) / run);
+ minSlopeB = Math.max(minSlopeB, (rgbColor[2] - rgbBase[2] - 1) / run);
+ const slopesExist = minSlopeR <= maxSlopeR && minSlopeG <= maxSlopeG && minSlopeB <= maxSlopeB;
+ if (!slopesExist) {
+ const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);
+ colorStops.push([iPrev / NUMBER_OF_SAMPLES, cssColor]);
+ maxSlopeR = rgbColor[0] - rgbPrev[0] + 1;
+ maxSlopeG = rgbColor[1] - rgbPrev[1] + 1;
+ maxSlopeB = rgbColor[2] - rgbPrev[2] + 1;
+ minSlopeR = rgbColor[0] - rgbPrev[0] - 1;
+ minSlopeG = rgbColor[1] - rgbPrev[1] - 1;
+ minSlopeB = rgbColor[2] - rgbPrev[2] - 1;
+ iBase = iPrev;
+ rgbBase = rgbPrev;
+ }
+ iPrev = i;
+ rgbPrev = rgbColor;
+ }
+ const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);
+ colorStops.push([1, cssColor]);
+ let background = "transparent";
+ if (dict.has("Background")) {
+ rgbColor = cs.getRgb(dict.get("Background"), 0);
+ background = Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]);
+ }
+ if (!extendStart) {
+ colorStops.unshift([0, background]);
+ colorStops[1][0] += BaseShading.SMALL_NUMBER;
+ }
+ if (!extendEnd) {
+ colorStops.at(-1)[0] -= BaseShading.SMALL_NUMBER;
+ colorStops.push([1, background]);
+ }
+ this.colorStops = colorStops;
+ }
+ getIR() {
+ const coordsArr = this.coordsArr;
+ const shadingType = this.shadingType;
+ let type, p0, p1, r0, r1;
+ if (shadingType === ShadingType.AXIAL) {
+ p0 = [coordsArr[0], coordsArr[1]];
+ p1 = [coordsArr[2], coordsArr[3]];
+ r0 = null;
+ r1 = null;
+ type = "axial";
+ } else if (shadingType === ShadingType.RADIAL) {
+ p0 = [coordsArr[0], coordsArr[1]];
+ p1 = [coordsArr[3], coordsArr[4]];
+ r0 = coordsArr[2];
+ r1 = coordsArr[5];
+ type = "radial";
+ } else {
+ unreachable(`getPattern type unknown: ${shadingType}`);
+ }
+ return ["RadialAxial", type, this.bbox, this.colorStops, p0, p1, r0, r1];
+ }
+}
+class MeshStreamReader {
+ constructor(stream, context) {
+ this.stream = stream;
+ this.context = context;
+ this.buffer = 0;
+ this.bufferLength = 0;
+ const numComps = context.numComps;
+ this.tmpCompsBuf = new Float32Array(numComps);
+ const csNumComps = context.colorSpace.numComps;
+ this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf;
+ }
+ get hasData() {
+ if (this.stream.end) {
+ return this.stream.pos < this.stream.end;
+ }
+ if (this.bufferLength > 0) {
+ return true;
+ }
+ const nextByte = this.stream.getByte();
+ if (nextByte < 0) {
+ return false;
+ }
+ this.buffer = nextByte;
+ this.bufferLength = 8;
+ return true;
+ }
+ readBits(n) {
+ let buffer = this.buffer;
+ let bufferLength = this.bufferLength;
+ if (n === 32) {
+ if (bufferLength === 0) {
+ return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0;
+ }
+ buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte();
+ const nextByte = this.stream.getByte();
+ this.buffer = nextByte & (1 << bufferLength) - 1;
+ return (buffer << 8 - bufferLength | (nextByte & 0xff) >> bufferLength) >>> 0;
+ }
+ if (n === 8 && bufferLength === 0) {
+ return this.stream.getByte();
+ }
+ while (bufferLength < n) {
+ buffer = buffer << 8 | this.stream.getByte();
+ bufferLength += 8;
+ }
+ bufferLength -= n;
+ this.bufferLength = bufferLength;
+ this.buffer = buffer & (1 << bufferLength) - 1;
+ return buffer >> bufferLength;
+ }
+ align() {
+ this.buffer = 0;
+ this.bufferLength = 0;
+ }
+ readFlag() {
+ return this.readBits(this.context.bitsPerFlag);
+ }
+ readCoordinate() {
+ const bitsPerCoordinate = this.context.bitsPerCoordinate;
+ const xi = this.readBits(bitsPerCoordinate);
+ const yi = this.readBits(bitsPerCoordinate);
+ const decode = this.context.decode;
+ const scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10;
+ return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]];
+ }
+ readComponents() {
+ const numComps = this.context.numComps;
+ const bitsPerComponent = this.context.bitsPerComponent;
+ const scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;
+ const decode = this.context.decode;
+ const components = this.tmpCompsBuf;
+ for (let i = 0, j = 4; i < numComps; i++, j += 2) {
+ const ci = this.readBits(bitsPerComponent);
+ components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j];
+ }
+ const color = this.tmpCsCompsBuf;
+ if (this.context.colorFn) {
+ this.context.colorFn(components, 0, color, 0);
+ }
+ return this.context.colorSpace.getRgb(color, 0);
+ }
+}
+let bCache = Object.create(null);
+function buildB(count) {
+ const lut = [];
+ for (let i = 0; i <= count; i++) {
+ const t = i / count,
+ t_ = 1 - t;
+ lut.push(new Float32Array([t_ ** 3, 3 * t * t_ ** 2, 3 * t ** 2 * t_, t ** 3]));
+ }
+ return lut;
+}
+function getB(count) {
+ return bCache[count] ||= buildB(count);
+}
+function clearPatternCaches() {
+ bCache = Object.create(null);
+}
+class MeshShading extends BaseShading {
+ static MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
+ static MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
+ static TRIANGLE_DENSITY = 20;
+ constructor(stream, xref, resources, pdfFunctionFactory, localColorSpaceCache) {
+ super();
+ if (!(stream instanceof BaseStream)) {
+ throw new FormatError("Mesh data is not a stream");
+ }
+ const dict = stream.dict;
+ this.shadingType = dict.get("ShadingType");
+ const bbox = dict.getArray("BBox");
+ this.bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;
+ const cs = ColorSpace.parse({
+ cs: dict.getRaw("CS") || dict.getRaw("ColorSpace"),
+ xref,
+ resources,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ this.background = dict.has("Background") ? cs.getRgb(dict.get("Background"), 0) : null;
+ const fnObj = dict.getRaw("Function");
+ const fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;
+ this.coords = [];
+ this.colors = [];
+ this.figures = [];
+ const decodeContext = {
+ bitsPerCoordinate: dict.get("BitsPerCoordinate"),
+ bitsPerComponent: dict.get("BitsPerComponent"),
+ bitsPerFlag: dict.get("BitsPerFlag"),
+ decode: dict.getArray("Decode"),
+ colorFn: fn,
+ colorSpace: cs,
+ numComps: fn ? 1 : cs.numComps
+ };
+ const reader = new MeshStreamReader(stream, decodeContext);
+ let patchMesh = false;
+ switch (this.shadingType) {
+ case ShadingType.FREE_FORM_MESH:
+ this._decodeType4Shading(reader);
+ break;
+ case ShadingType.LATTICE_FORM_MESH:
+ const verticesPerRow = dict.get("VerticesPerRow") | 0;
+ if (verticesPerRow < 2) {
+ throw new FormatError("Invalid VerticesPerRow");
+ }
+ this._decodeType5Shading(reader, verticesPerRow);
+ break;
+ case ShadingType.COONS_PATCH_MESH:
+ this._decodeType6Shading(reader);
+ patchMesh = true;
+ break;
+ case ShadingType.TENSOR_PATCH_MESH:
+ this._decodeType7Shading(reader);
+ patchMesh = true;
+ break;
+ default:
+ unreachable("Unsupported mesh type.");
+ break;
+ }
+ if (patchMesh) {
+ this._updateBounds();
+ for (let i = 0, ii = this.figures.length; i < ii; i++) {
+ this._buildFigureFromPatch(i);
+ }
+ }
+ this._updateBounds();
+ this._packData();
+ }
+ _decodeType4Shading(reader) {
+ const coords = this.coords;
+ const colors = this.colors;
+ const operators = [];
+ const ps = [];
+ let verticesLeft = 0;
+ while (reader.hasData) {
+ const f = reader.readFlag();
+ const coord = reader.readCoordinate();
+ const color = reader.readComponents();
+ if (verticesLeft === 0) {
+ if (!(0 <= f && f <= 2)) {
+ throw new FormatError("Unknown type4 flag");
+ }
+ switch (f) {
+ case 0:
+ verticesLeft = 3;
+ break;
+ case 1:
+ ps.push(ps.at(-2), ps.at(-1));
+ verticesLeft = 1;
+ break;
+ case 2:
+ ps.push(ps.at(-3), ps.at(-1));
+ verticesLeft = 1;
+ break;
+ }
+ operators.push(f);
+ }
+ ps.push(coords.length);
+ coords.push(coord);
+ colors.push(color);
+ verticesLeft--;
+ reader.align();
+ }
+ this.figures.push({
+ type: "triangles",
+ coords: new Int32Array(ps),
+ colors: new Int32Array(ps)
+ });
+ }
+ _decodeType5Shading(reader, verticesPerRow) {
+ const coords = this.coords;
+ const colors = this.colors;
+ const ps = [];
+ while (reader.hasData) {
+ const coord = reader.readCoordinate();
+ const color = reader.readComponents();
+ ps.push(coords.length);
+ coords.push(coord);
+ colors.push(color);
+ }
+ this.figures.push({
+ type: "lattice",
+ coords: new Int32Array(ps),
+ colors: new Int32Array(ps),
+ verticesPerRow
+ });
+ }
+ _decodeType6Shading(reader) {
+ const coords = this.coords;
+ const colors = this.colors;
+ const ps = new Int32Array(16);
+ const cs = new Int32Array(4);
+ while (reader.hasData) {
+ const f = reader.readFlag();
+ if (!(0 <= f && f <= 3)) {
+ throw new FormatError("Unknown type6 flag");
+ }
+ const pi = coords.length;
+ for (let i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
+ coords.push(reader.readCoordinate());
+ }
+ const ci = colors.length;
+ for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
+ colors.push(reader.readComponents());
+ }
+ let tmp1, tmp2, tmp3, tmp4;
+ switch (f) {
+ case 0:
+ ps[12] = pi + 3;
+ ps[13] = pi + 4;
+ ps[14] = pi + 5;
+ ps[15] = pi + 6;
+ ps[8] = pi + 2;
+ ps[11] = pi + 7;
+ ps[4] = pi + 1;
+ ps[7] = pi + 8;
+ ps[0] = pi;
+ ps[1] = pi + 11;
+ ps[2] = pi + 10;
+ ps[3] = pi + 9;
+ cs[2] = ci + 1;
+ cs[3] = ci + 2;
+ cs[0] = ci;
+ cs[1] = ci + 3;
+ break;
+ case 1:
+ tmp1 = ps[12];
+ tmp2 = ps[13];
+ tmp3 = ps[14];
+ tmp4 = ps[15];
+ ps[12] = tmp4;
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = tmp3;
+ ps[11] = pi + 3;
+ ps[4] = tmp2;
+ ps[7] = pi + 4;
+ ps[0] = tmp1;
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ tmp1 = cs[2];
+ tmp2 = cs[3];
+ cs[2] = tmp2;
+ cs[3] = ci;
+ cs[0] = tmp1;
+ cs[1] = ci + 1;
+ break;
+ case 2:
+ tmp1 = ps[15];
+ tmp2 = ps[11];
+ ps[12] = ps[3];
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = ps[7];
+ ps[11] = pi + 3;
+ ps[4] = tmp2;
+ ps[7] = pi + 4;
+ ps[0] = tmp1;
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ tmp1 = cs[3];
+ cs[2] = cs[1];
+ cs[3] = ci;
+ cs[0] = tmp1;
+ cs[1] = ci + 1;
+ break;
+ case 3:
+ ps[12] = ps[0];
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = ps[1];
+ ps[11] = pi + 3;
+ ps[4] = ps[2];
+ ps[7] = pi + 4;
+ ps[0] = ps[3];
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ cs[2] = cs[0];
+ cs[3] = ci;
+ cs[0] = cs[1];
+ cs[1] = ci + 1;
+ break;
+ }
+ ps[5] = coords.length;
+ coords.push([(-4 * coords[ps[0]][0] - coords[ps[15]][0] + 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, (-4 * coords[ps[0]][1] - coords[ps[15]][1] + 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9]);
+ ps[6] = coords.length;
+ coords.push([(-4 * coords[ps[3]][0] - coords[ps[12]][0] + 6 * (coords[ps[2]][0] + coords[ps[7]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9, (-4 * coords[ps[3]][1] - coords[ps[12]][1] + 6 * (coords[ps[2]][1] + coords[ps[7]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9]);
+ ps[9] = coords.length;
+ coords.push([(-4 * coords[ps[12]][0] - coords[ps[3]][0] + 6 * (coords[ps[8]][0] + coords[ps[13]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9, (-4 * coords[ps[12]][1] - coords[ps[3]][1] + 6 * (coords[ps[8]][1] + coords[ps[13]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9]);
+ ps[10] = coords.length;
+ coords.push([(-4 * coords[ps[15]][0] - coords[ps[0]][0] + 6 * (coords[ps[11]][0] + coords[ps[14]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9, (-4 * coords[ps[15]][1] - coords[ps[0]][1] + 6 * (coords[ps[11]][1] + coords[ps[14]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9]);
+ this.figures.push({
+ type: "patch",
+ coords: new Int32Array(ps),
+ colors: new Int32Array(cs)
+ });
+ }
+ }
+ _decodeType7Shading(reader) {
+ const coords = this.coords;
+ const colors = this.colors;
+ const ps = new Int32Array(16);
+ const cs = new Int32Array(4);
+ while (reader.hasData) {
+ const f = reader.readFlag();
+ if (!(0 <= f && f <= 3)) {
+ throw new FormatError("Unknown type7 flag");
+ }
+ const pi = coords.length;
+ for (let i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
+ coords.push(reader.readCoordinate());
+ }
+ const ci = colors.length;
+ for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
+ colors.push(reader.readComponents());
+ }
+ let tmp1, tmp2, tmp3, tmp4;
+ switch (f) {
+ case 0:
+ ps[12] = pi + 3;
+ ps[13] = pi + 4;
+ ps[14] = pi + 5;
+ ps[15] = pi + 6;
+ ps[8] = pi + 2;
+ ps[9] = pi + 13;
+ ps[10] = pi + 14;
+ ps[11] = pi + 7;
+ ps[4] = pi + 1;
+ ps[5] = pi + 12;
+ ps[6] = pi + 15;
+ ps[7] = pi + 8;
+ ps[0] = pi;
+ ps[1] = pi + 11;
+ ps[2] = pi + 10;
+ ps[3] = pi + 9;
+ cs[2] = ci + 1;
+ cs[3] = ci + 2;
+ cs[0] = ci;
+ cs[1] = ci + 3;
+ break;
+ case 1:
+ tmp1 = ps[12];
+ tmp2 = ps[13];
+ tmp3 = ps[14];
+ tmp4 = ps[15];
+ ps[12] = tmp4;
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = tmp3;
+ ps[9] = pi + 9;
+ ps[10] = pi + 10;
+ ps[11] = pi + 3;
+ ps[4] = tmp2;
+ ps[5] = pi + 8;
+ ps[6] = pi + 11;
+ ps[7] = pi + 4;
+ ps[0] = tmp1;
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ tmp1 = cs[2];
+ tmp2 = cs[3];
+ cs[2] = tmp2;
+ cs[3] = ci;
+ cs[0] = tmp1;
+ cs[1] = ci + 1;
+ break;
+ case 2:
+ tmp1 = ps[15];
+ tmp2 = ps[11];
+ ps[12] = ps[3];
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = ps[7];
+ ps[9] = pi + 9;
+ ps[10] = pi + 10;
+ ps[11] = pi + 3;
+ ps[4] = tmp2;
+ ps[5] = pi + 8;
+ ps[6] = pi + 11;
+ ps[7] = pi + 4;
+ ps[0] = tmp1;
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ tmp1 = cs[3];
+ cs[2] = cs[1];
+ cs[3] = ci;
+ cs[0] = tmp1;
+ cs[1] = ci + 1;
+ break;
+ case 3:
+ ps[12] = ps[0];
+ ps[13] = pi + 0;
+ ps[14] = pi + 1;
+ ps[15] = pi + 2;
+ ps[8] = ps[1];
+ ps[9] = pi + 9;
+ ps[10] = pi + 10;
+ ps[11] = pi + 3;
+ ps[4] = ps[2];
+ ps[5] = pi + 8;
+ ps[6] = pi + 11;
+ ps[7] = pi + 4;
+ ps[0] = ps[3];
+ ps[1] = pi + 7;
+ ps[2] = pi + 6;
+ ps[3] = pi + 5;
+ cs[2] = cs[0];
+ cs[3] = ci;
+ cs[0] = cs[1];
+ cs[1] = ci + 1;
+ break;
+ }
+ this.figures.push({
+ type: "patch",
+ coords: new Int32Array(ps),
+ colors: new Int32Array(cs)
+ });
+ }
+ }
+ _buildFigureFromPatch(index) {
+ const figure = this.figures[index];
+ assert(figure.type === "patch", "Unexpected patch mesh figure");
+ const coords = this.coords,
+ colors = this.colors;
+ const pi = figure.coords;
+ const ci = figure.colors;
+ const figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
+ const figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
+ const figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
+ const figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
+ let splitXBy = Math.ceil((figureMaxX - figureMinX) * MeshShading.TRIANGLE_DENSITY / (this.bounds[2] - this.bounds[0]));
+ splitXBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy));
+ let splitYBy = Math.ceil((figureMaxY - figureMinY) * MeshShading.TRIANGLE_DENSITY / (this.bounds[3] - this.bounds[1]));
+ splitYBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy));
+ const verticesPerRow = splitXBy + 1;
+ const figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);
+ const figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);
+ let k = 0;
+ const cl = new Uint8Array(3),
+ cr = new Uint8Array(3);
+ const c0 = colors[ci[0]],
+ c1 = colors[ci[1]],
+ c2 = colors[ci[2]],
+ c3 = colors[ci[3]];
+ const bRow = getB(splitYBy),
+ bCol = getB(splitXBy);
+ for (let row = 0; row <= splitYBy; row++) {
+ cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0;
+ cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0;
+ cl[2] = (c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy | 0;
+ cr[0] = (c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy | 0;
+ cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0;
+ cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0;
+ for (let col = 0; col <= splitXBy; col++, k++) {
+ if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) {
+ continue;
+ }
+ let x = 0,
+ y = 0;
+ let q = 0;
+ for (let i = 0; i <= 3; i++) {
+ for (let j = 0; j <= 3; j++, q++) {
+ const m = bRow[row][i] * bCol[col][j];
+ x += coords[pi[q]][0] * m;
+ y += coords[pi[q]][1] * m;
+ }
+ }
+ figureCoords[k] = coords.length;
+ coords.push([x, y]);
+ figureColors[k] = colors.length;
+ const newColor = new Uint8Array(3);
+ newColor[0] = (cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy | 0;
+ newColor[1] = (cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy | 0;
+ newColor[2] = (cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy | 0;
+ colors.push(newColor);
+ }
+ }
+ figureCoords[0] = pi[0];
+ figureColors[0] = ci[0];
+ figureCoords[splitXBy] = pi[3];
+ figureColors[splitXBy] = ci[1];
+ figureCoords[verticesPerRow * splitYBy] = pi[12];
+ figureColors[verticesPerRow * splitYBy] = ci[2];
+ figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15];
+ figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3];
+ this.figures[index] = {
+ type: "lattice",
+ coords: figureCoords,
+ colors: figureColors,
+ verticesPerRow
+ };
+ }
+ _updateBounds() {
+ let minX = this.coords[0][0],
+ minY = this.coords[0][1],
+ maxX = minX,
+ maxY = minY;
+ for (let i = 1, ii = this.coords.length; i < ii; i++) {
+ const x = this.coords[i][0],
+ y = this.coords[i][1];
+ minX = minX > x ? x : minX;
+ minY = minY > y ? y : minY;
+ maxX = maxX < x ? x : maxX;
+ maxY = maxY < y ? y : maxY;
+ }
+ this.bounds = [minX, minY, maxX, maxY];
+ }
+ _packData() {
+ let i, ii, j, jj;
+ const coords = this.coords;
+ const coordsPacked = new Float32Array(coords.length * 2);
+ for (i = 0, j = 0, ii = coords.length; i < ii; i++) {
+ const xy = coords[i];
+ coordsPacked[j++] = xy[0];
+ coordsPacked[j++] = xy[1];
+ }
+ this.coords = coordsPacked;
+ const colors = this.colors;
+ const colorsPacked = new Uint8Array(colors.length * 3);
+ for (i = 0, j = 0, ii = colors.length; i < ii; i++) {
+ const c = colors[i];
+ colorsPacked[j++] = c[0];
+ colorsPacked[j++] = c[1];
+ colorsPacked[j++] = c[2];
+ }
+ this.colors = colorsPacked;
+ const figures = this.figures;
+ for (i = 0, ii = figures.length; i < ii; i++) {
+ const figure = figures[i],
+ ps = figure.coords,
+ cs = figure.colors;
+ for (j = 0, jj = ps.length; j < jj; j++) {
+ ps[j] *= 2;
+ cs[j] *= 3;
+ }
+ }
+ }
+ getIR() {
+ return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.bbox, this.background];
+ }
+}
+class DummyShading extends BaseShading {
+ getIR() {
+ return ["Dummy"];
+ }
+}
+function getTilingPatternIR(operatorList, dict, color) {
+ const matrix = dict.getArray("Matrix");
+ const bbox = Util.normalizeRect(dict.getArray("BBox"));
+ const xstep = dict.get("XStep");
+ const ystep = dict.get("YStep");
+ const paintType = dict.get("PaintType");
+ const tilingType = dict.get("TilingType");
+ if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) {
+ throw new FormatError(`Invalid getTilingPatternIR /BBox array: [${bbox}].`);
+ }
+ return ["TilingPattern", color, operatorList, matrix, bbox, xstep, ystep, paintType, tilingType];
+}
+
+;// CONCATENATED MODULE: ./src/core/calibri_factors.js
+const CalibriBoldFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.54657, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.73293, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.9121, 0.86943, 0.79795, 0.88198, 0.77958, 0.70864, 0.81055, 0.90399, 0.88653, 0.96017, 0.82577, 0.77892, 0.78257, 0.97507, 1.54657, 0.97507, 0.85284, 0.89552, 0.90176, 0.88762, 0.8785, 0.75241, 0.8785, 0.90518, 0.95015, 0.77618, 0.8785, 0.88401, 0.91916, 0.86304, 0.88401, 0.91488, 0.8785, 0.8801, 0.8785, 0.8785, 0.91343, 0.7173, 1.04106, 0.8785, 0.85075, 0.95794, 0.82616, 0.85162, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.12401, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.73293, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.9121, 0.86943, 0.86943, 0.86943, 0.86943, 0.86943, 0.85284, 0.87508, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.8715, 0.75241, 0.90518, 0.90518, 0.90518, 0.90518, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.8785, 0.8801, 0.8801, 0.8801, 0.8801, 0.8801, 0.90747, 0.89049, 0.8785, 0.8785, 0.8785, 0.8785, 0.85162, 0.8785, 0.85162, 0.83908, 0.88762, 0.83908, 0.88762, 0.83908, 0.88762, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.87289, 0.83016, 0.88506, 0.93125, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.81921, 0.77618, 0.81921, 0.77618, 0.81921, 0.77618, 1, 1, 0.87356, 0.8785, 0.91075, 0.89608, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76229, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.79468, 0.91926, 0.88175, 0.70823, 0.94903, 0.9121, 0.8785, 1, 1, 0.9121, 0.8785, 0.87802, 0.88656, 0.8785, 0.86943, 0.8801, 0.86943, 0.8801, 0.86943, 0.8801, 0.87402, 0.89291, 0.77958, 0.91343, 1, 1, 0.77958, 0.91343, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.96017, 0.95794, 0.77892, 0.85162, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.88762, 0.77539, 0.8715, 0.87508, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70674, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.06303, 0.83908, 0.80352, 0.57184, 0.6965, 0.56289, 0.82001, 0.56029, 0.81235, 1.02988, 0.83908, 0.7762, 0.68156, 0.80367, 0.73133, 0.78257, 0.87356, 0.86943, 0.95958, 0.75727, 0.89019, 1.04924, 0.9121, 0.7648, 0.86943, 0.87356, 0.79795, 0.78275, 0.81055, 0.77892, 0.9762, 0.82577, 0.99819, 0.84896, 0.95958, 0.77892, 0.96108, 1.01407, 0.89049, 1.02988, 0.94211, 0.96108, 0.8936, 0.84021, 0.87842, 0.96399, 0.79109, 0.89049, 1.00813, 1.02988, 0.86077, 0.87445, 0.92099, 0.84723, 0.86513, 0.8801, 0.75638, 0.85714, 0.78216, 0.79586, 0.87965, 0.94211, 0.97747, 0.78287, 0.97926, 0.84971, 1.02988, 0.94211, 0.8801, 0.94211, 0.84971, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90264, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90518, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90548, 1, 1, 1, 1, 1, 1, 0.96017, 0.95794, 0.96017, 0.95794, 0.96017, 0.95794, 0.77892, 0.85162, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.92794, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71143, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.93835, 0.83406, 0.91133, 0.84107, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90527, 1.81055, 0.90527, 1.81055, 1.31006, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const CalibriBoldMetrics = {
+ lineHeight: 1.2207,
+ lineGap: 0.2207
+};
+const CalibriBoldItalicFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.56239, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.71805, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.90872, 0.85938, 0.79795, 0.87068, 0.77958, 0.69766, 0.81055, 0.90399, 0.88653, 0.96068, 0.82577, 0.77892, 0.78257, 0.97507, 1.529, 0.97507, 0.85284, 0.89552, 0.90176, 0.94908, 0.86411, 0.74012, 0.86411, 0.88323, 0.95015, 0.86411, 0.86331, 0.88401, 0.91916, 0.86304, 0.88401, 0.9039, 0.86331, 0.86331, 0.86411, 0.86411, 0.90464, 0.70852, 1.04106, 0.86331, 0.84372, 0.95794, 0.82616, 0.84548, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.19129, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.71805, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.90872, 0.85938, 0.85938, 0.85938, 0.85938, 0.85938, 0.85284, 0.87068, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.85887, 0.74012, 0.88323, 0.88323, 0.88323, 0.88323, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.90747, 0.89049, 0.86331, 0.86331, 0.86331, 0.86331, 0.84548, 0.86411, 0.84548, 0.83908, 0.94908, 0.83908, 0.94908, 0.83908, 0.94908, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.87289, 0.79538, 0.88506, 0.92726, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.81921, 0.86411, 0.81921, 0.86411, 0.81921, 0.86411, 1, 1, 0.87356, 0.86331, 0.91075, 0.8777, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76467, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.77312, 0.91926, 0.88175, 0.70823, 0.94903, 0.90872, 0.86331, 1, 1, 0.90872, 0.86331, 0.86906, 0.88116, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.87402, 0.86549, 0.77958, 0.90464, 1, 1, 0.77958, 0.90464, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.96068, 0.95794, 0.77892, 0.84548, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.94908, 0.77539, 0.85887, 0.87068, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70088, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.48387, 0.83908, 0.80352, 0.57118, 0.6965, 0.56347, 0.79179, 0.55853, 0.80346, 1.02988, 0.83908, 0.7762, 0.67174, 0.86036, 0.73133, 0.78257, 0.87356, 0.86441, 0.95958, 0.75727, 0.89019, 1.04924, 0.90872, 0.74889, 0.85938, 0.87891, 0.79795, 0.7957, 0.81055, 0.77892, 0.97447, 0.82577, 0.97466, 0.87179, 0.95958, 0.77892, 0.94252, 0.95612, 0.8753, 1.02988, 0.92733, 0.94252, 0.87411, 0.84021, 0.8728, 0.95612, 0.74081, 0.8753, 1.02189, 1.02988, 0.84814, 0.87445, 0.91822, 0.84723, 0.85668, 0.86331, 0.81344, 0.87581, 0.76422, 0.82046, 0.96057, 0.92733, 0.99375, 0.78022, 0.95452, 0.86015, 1.02988, 0.92733, 0.86331, 0.92733, 0.86015, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90631, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88323, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85174, 1, 1, 1, 1, 1, 1, 0.96068, 0.95794, 0.96068, 0.95794, 0.96068, 0.95794, 0.77892, 0.84548, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.89807, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71094, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.92972, 0.83406, 0.91133, 0.83326, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90616, 1.81055, 0.90527, 1.81055, 1.3107, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const CalibriBoldItalicMetrics = {
+ lineHeight: 1.2207,
+ lineGap: 0.2207
+};
+const CalibriItalicFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39543, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.72346, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89249, 0.84118, 0.77452, 0.85374, 0.75186, 0.67789, 0.79776, 0.88844, 0.85066, 0.94309, 0.77818, 0.7306, 0.76659, 1.10369, 1.38313, 1.10369, 1.06139, 0.89552, 0.8739, 0.9245, 0.9245, 0.83203, 0.9245, 0.85865, 1.09842, 0.9245, 0.9245, 1.03297, 1.07692, 0.90918, 1.03297, 0.94959, 0.9245, 0.92274, 0.9245, 0.9245, 1.02933, 0.77832, 1.20562, 0.9245, 0.8916, 0.98986, 0.86621, 0.89453, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.16359, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.72346, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89249, 0.84118, 0.84118, 0.84118, 0.84118, 0.84118, 0.85284, 0.84557, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.84843, 0.83203, 0.85865, 0.85865, 0.85865, 0.85865, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.9245, 0.92274, 0.92274, 0.92274, 0.92274, 0.92274, 0.90747, 0.86651, 0.9245, 0.9245, 0.9245, 0.9245, 0.89453, 0.9245, 0.89453, 0.8675, 0.9245, 0.8675, 0.9245, 0.8675, 0.9245, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.85193, 0.8875, 0.86477, 0.99034, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.81105, 0.9245, 0.81105, 0.9245, 0.81105, 0.9245, 1, 1, 0.86275, 0.9245, 0.90872, 0.93591, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77896, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.9375, 0.98156, 0.93407, 0.77261, 1.11429, 0.89249, 0.9245, 1, 1, 0.89249, 0.9245, 0.92534, 0.86698, 0.9245, 0.84118, 0.92274, 0.84118, 0.92274, 0.84118, 0.92274, 0.8667, 0.86291, 0.75186, 1.02933, 1, 1, 0.75186, 1.02933, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 1, 1, 0.79776, 0.97655, 0.79776, 1.23023, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.94309, 0.98986, 0.7306, 0.89453, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.9245, 0.76318, 0.84843, 0.84557, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67009, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.8675, 0.90861, 0.6192, 0.7363, 0.64824, 0.82411, 0.56321, 0.85696, 1.23516, 0.8675, 0.81552, 0.7286, 0.84134, 0.73206, 0.76659, 0.86275, 0.84369, 0.90685, 0.77892, 0.85871, 1.02638, 0.89249, 0.75828, 0.84118, 0.85984, 0.77452, 0.76466, 0.79776, 0.7306, 0.90782, 0.77818, 0.903, 0.87291, 0.90685, 0.7306, 0.99058, 1.03667, 0.94635, 1.23516, 0.9849, 0.99058, 0.92393, 0.8916, 0.942, 1.03667, 0.75026, 0.94635, 1.0297, 1.23516, 0.90918, 0.94048, 0.98217, 0.89746, 0.84153, 0.92274, 0.82507, 0.88832, 0.84438, 0.88178, 1.03525, 0.9849, 1.00225, 0.78086, 0.97248, 0.89404, 1.23516, 0.9849, 0.92274, 0.9849, 0.89404, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89693, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85865, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90933, 1, 1, 1, 1, 1, 1, 0.94309, 0.98986, 0.94309, 0.98986, 0.94309, 0.98986, 0.7306, 0.89453, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.68994, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.97858, 0.82616, 0.91133, 0.83437, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90572, 1.81055, 0.90749, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85284, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const CalibriItalicMetrics = {
+ lineHeight: 1.2207,
+ lineGap: 0.2207
+};
+const CalibriRegularFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39016, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.73834, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89385, 0.85122, 0.77452, 0.86503, 0.75186, 0.68887, 0.79776, 0.88844, 0.85066, 0.94258, 0.77818, 0.7306, 0.76659, 1.10369, 1.39016, 1.10369, 1.06139, 0.89552, 0.8739, 0.86128, 0.94469, 0.8457, 0.94469, 0.89464, 1.09842, 0.84636, 0.94469, 1.03297, 1.07692, 0.90918, 1.03297, 0.95897, 0.94469, 0.9482, 0.94469, 0.94469, 1.04692, 0.78223, 1.20562, 0.94469, 0.90332, 0.98986, 0.86621, 0.90527, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.08707, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.73834, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89385, 0.85122, 0.85122, 0.85122, 0.85122, 0.85122, 0.85284, 0.85311, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.8693, 0.8457, 0.89464, 0.89464, 0.89464, 0.89464, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.94469, 0.9482, 0.9482, 0.9482, 0.9482, 0.9482, 0.90747, 0.86651, 0.94469, 0.94469, 0.94469, 0.94469, 0.90527, 0.94469, 0.90527, 0.8675, 0.86128, 0.8675, 0.86128, 0.8675, 0.86128, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.85193, 0.92454, 0.86477, 0.9921, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.81105, 0.84636, 0.81105, 0.84636, 0.81105, 0.84636, 1, 1, 0.86275, 0.94469, 0.90872, 0.95786, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77741, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.90452, 0.98156, 1.11842, 0.77261, 1.11429, 0.89385, 0.94469, 1, 1, 0.89385, 0.94469, 0.95877, 0.86901, 0.94469, 0.85122, 0.9482, 0.85122, 0.9482, 0.85122, 0.9482, 0.8667, 0.90016, 0.75186, 1.04692, 1, 1, 0.75186, 1.04692, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 1, 1, 0.79776, 0.92188, 0.79776, 1.23023, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.94258, 0.98986, 0.7306, 0.90527, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.86128, 0.76318, 0.8693, 0.85311, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67742, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.86686, 0.90861, 0.62267, 0.74359, 0.65649, 0.85498, 0.56963, 0.88254, 1.23516, 0.8675, 0.81552, 0.75443, 0.84503, 0.73206, 0.76659, 0.86275, 0.85122, 0.90685, 0.77892, 0.85746, 1.02638, 0.89385, 0.75657, 0.85122, 0.86275, 0.77452, 0.74171, 0.79776, 0.7306, 0.95165, 0.77818, 0.89772, 0.88831, 0.90685, 0.7306, 0.98142, 1.02191, 0.96576, 1.23516, 0.99018, 0.98142, 0.9236, 0.89258, 0.94035, 1.02191, 0.78848, 0.96576, 0.9561, 1.23516, 0.90918, 0.92578, 0.95424, 0.89746, 0.83969, 0.9482, 0.80113, 0.89442, 0.85208, 0.86155, 0.98022, 0.99018, 1.00452, 0.81209, 0.99247, 0.89181, 1.23516, 0.99018, 0.9482, 0.99018, 0.89181, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88844, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89464, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96766, 1, 1, 1, 1, 1, 1, 0.94258, 0.98986, 0.94258, 0.98986, 0.94258, 0.98986, 0.7306, 0.90527, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.69043, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.99331, 0.82616, 0.91133, 0.84286, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90527, 1.81055, 0.90527, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1.07185, 0.99413, 0.96334, 1.08065, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const CalibriRegularMetrics = {
+ lineHeight: 1.2207,
+ lineGap: 0.2207
+};
+
+;// CONCATENATED MODULE: ./src/core/helvetica_factors.js
+const HelveticaBoldFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.03374, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.00042, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.03828, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00034, 0.99977, 1, 0.99997, 1.00026, 1.00078, 1.00036, 0.99973, 1.00013, 1.0006, 0.99977, 0.99977, 0.99988, 0.85148, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 1.00069, 1.00022, 0.99977, 1.00001, 0.99984, 1.00026, 1.00001, 1.00024, 1.00001, 0.9999, 1, 1.0006, 1.00001, 1.00041, 0.99962, 1.00026, 1.0006, 0.99995, 1.00041, 0.99942, 0.99973, 0.99927, 1.00082, 0.99902, 1.00026, 1.00087, 1.0006, 1.00069, 0.99973, 0.99867, 0.99973, 0.9993, 1.00026, 1.00049, 1.00056, 1, 0.99988, 0.99935, 0.99995, 0.99954, 1.00055, 0.99945, 1.00032, 1.0006, 0.99995, 1.00026, 0.99995, 1.00032, 1.00001, 1.00008, 0.99971, 1.00019, 0.9994, 1.00001, 1.0006, 1.00044, 0.99973, 1.00023, 1.00047, 1, 0.99942, 0.99561, 0.99989, 1.00035, 0.99977, 1.00035, 0.99977, 1.00019, 0.99944, 1.00001, 1.00021, 0.99926, 1.00035, 1.00035, 0.99942, 1.00048, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.99989, 1.00057, 1.00001, 0.99936, 1.00052, 1.00012, 0.99996, 1.00043, 1, 1.00035, 0.9994, 0.99976, 1.00035, 0.99973, 1.00052, 1.00041, 1.00119, 1.00037, 0.99973, 1.00002, 0.99986, 1.00041, 1.00041, 0.99902, 0.9996, 1.00034, 0.99999, 1.00026, 0.99999, 1.00026, 0.99973, 1.00052, 0.99973, 1, 0.99973, 1.00041, 1.00075, 0.9994, 1.0003, 0.99999, 1, 1.00041, 0.99955, 1, 0.99915, 0.99973, 0.99973, 1.00026, 1.00119, 0.99955, 0.99973, 1.0006, 0.99911, 1.0006, 1.00026, 0.99972, 1.00026, 0.99902, 1.00041, 0.99973, 0.99999, 1, 1, 1.00038, 1.0005, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 1.00047, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const HelveticaBoldMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+const HelveticaBoldItalicFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.0044, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99971, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.01011, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99977, 1, 1, 1.00026, 0.99969, 0.99972, 0.99981, 0.9998, 1.0006, 0.99977, 0.99977, 1.00022, 0.91155, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 0.99966, 1.00022, 1.00032, 1.00001, 0.99944, 1.00026, 1.00001, 0.99968, 1.00001, 1.00047, 1, 1.0006, 1.00001, 0.99981, 1.00101, 1.00026, 1.0006, 0.99948, 0.99981, 1.00064, 0.99973, 0.99942, 1.00101, 1.00061, 1.00026, 1.00069, 1.0006, 1.00014, 0.99973, 1.01322, 0.99973, 1.00065, 1.00026, 1.00012, 0.99923, 1, 1.00064, 1.00076, 0.99948, 1.00055, 1.00063, 1.00007, 0.99943, 1.0006, 0.99948, 1.00026, 0.99948, 0.99943, 1.00001, 1.00001, 1.00029, 1.00038, 1.00035, 1.00001, 1.0006, 1.0006, 0.99973, 0.99978, 1.00001, 1.00057, 0.99989, 0.99967, 0.99964, 0.99967, 0.99977, 0.99999, 0.99977, 1.00038, 0.99977, 1.00001, 0.99973, 1.00066, 0.99967, 0.99967, 1.00041, 0.99998, 0.99999, 0.99977, 1.00022, 0.99967, 1.00001, 0.99977, 1.00026, 0.99964, 1.00031, 1.00001, 0.99999, 0.99999, 1, 1.00023, 1, 1, 0.99999, 1.00035, 1.00001, 0.99999, 0.99973, 0.99977, 0.99999, 1.00058, 0.99973, 0.99973, 0.99955, 0.9995, 1.00026, 1.00026, 1.00032, 0.99989, 1.00034, 0.99999, 1.00026, 1.00026, 1.00026, 0.99973, 0.45998, 0.99973, 1.00026, 0.99973, 1.00001, 0.99999, 0.99982, 0.99994, 0.99996, 1, 1.00042, 1.00044, 1.00029, 1.00023, 0.99973, 0.99973, 1.00026, 0.99949, 1.00002, 0.99973, 1.0006, 1.0006, 1.0006, 0.99975, 1.00026, 1.00026, 1.00032, 0.98685, 0.99973, 1.00026, 1, 1, 0.99966, 1.00044, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1, 0.99973, 0.99971, 0.99978, 1, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00098, 1, 1, 1, 1.00049, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const HelveticaBoldItalicMetrics = {
+ lineHeight: 1.35,
+ lineGap: 0.2
+};
+const HelveticaItalicFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.0288, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 0.99946, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.06311, 0.99973, 1.00024, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00041, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.89547, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00001, 1, 1.00054, 0.99977, 1.00084, 1.00007, 0.99973, 1.00013, 0.99924, 1.00001, 1.00001, 0.99945, 0.91221, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00001, 0.99999, 0.99977, 0.99933, 1.00022, 1.00054, 1.00001, 1.00065, 1.00026, 1.00001, 1.0001, 1.00001, 1.00052, 1, 1.0006, 1.00001, 0.99945, 0.99897, 0.99968, 0.99924, 1.00036, 0.99945, 0.99949, 1, 1.0006, 0.99897, 0.99918, 0.99968, 0.99911, 0.99924, 1, 0.99962, 1.01487, 1, 1.0005, 0.99973, 1.00012, 1.00043, 1, 0.99995, 0.99994, 1.00036, 0.99947, 1.00019, 1.00063, 1.00025, 0.99924, 1.00036, 0.99973, 1.00036, 1.00025, 1.00001, 1.00001, 1.00027, 1.0001, 1.00068, 1.00001, 1.0006, 1.0006, 1, 1.00008, 0.99957, 0.99972, 0.9994, 0.99954, 0.99975, 1.00051, 1.00001, 1.00019, 1.00001, 1.0001, 0.99986, 1.00001, 1.00001, 1.00038, 0.99954, 0.99954, 0.9994, 1.00066, 0.99999, 0.99977, 1.00022, 1.00054, 1.00001, 0.99977, 1.00026, 0.99975, 1.0001, 1.00001, 0.99993, 0.9995, 0.99955, 1.00016, 0.99978, 0.99974, 1.00019, 1.00022, 0.99955, 1.00053, 0.99973, 1.00089, 1.00005, 0.99967, 1.00048, 0.99973, 1.00002, 1.00034, 0.99973, 0.99973, 0.99964, 1.00006, 1.00066, 0.99947, 0.99973, 0.98894, 0.99973, 1, 0.44898, 1, 0.99946, 1, 1.00039, 1.00082, 0.99991, 0.99991, 0.99985, 1.00022, 1.00023, 1.00061, 1.00006, 0.99966, 0.99973, 0.99973, 0.99973, 1.00019, 1.0008, 1, 0.99924, 0.99924, 0.99924, 0.99983, 1.00044, 0.99973, 0.99964, 0.98332, 1, 0.99973, 1, 1, 0.99962, 0.99895, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 1.00423, 0.99925, 0.99999, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00049, 1, 1.00245, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 1.00003, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const HelveticaItalicMetrics = {
+ lineHeight: 1.35,
+ lineGap: 0.2
+};
+const HelveticaRegularFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.04596, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 1.00019, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.02572, 0.99973, 1.00005, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99999, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.84533, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99928, 1, 0.99977, 1.00013, 1.00055, 0.99947, 0.99945, 0.99941, 0.99924, 1.00001, 1.00001, 1.0004, 0.91621, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00005, 0.99999, 0.99977, 1.00015, 1.00022, 0.99977, 1.00001, 0.99973, 1.00026, 1.00001, 1.00019, 1.00001, 0.99946, 1, 1.0006, 1.00001, 0.99978, 1.00045, 0.99973, 0.99924, 1.00023, 0.99978, 0.99966, 1, 1.00065, 1.00045, 1.00019, 0.99973, 0.99973, 0.99924, 1, 1, 0.96499, 1, 1.00055, 0.99973, 1.00008, 1.00027, 1, 0.9997, 0.99995, 1.00023, 0.99933, 1.00019, 1.00015, 1.00031, 0.99924, 1.00023, 0.99973, 1.00023, 1.00031, 1.00001, 0.99928, 1.00029, 1.00092, 1.00035, 1.00001, 1.0006, 1.0006, 1, 0.99988, 0.99975, 1, 1.00082, 0.99561, 0.9996, 1.00035, 1.00001, 0.99962, 1.00001, 1.00092, 0.99964, 1.00001, 0.99963, 0.99999, 1.00035, 1.00035, 1.00082, 0.99962, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.9996, 0.99967, 1.00001, 1.00034, 1.00074, 1.00054, 1.00053, 1.00063, 0.99971, 0.99962, 1.00035, 0.99975, 0.99977, 0.99973, 1.00043, 0.99953, 1.0007, 0.99915, 0.99973, 1.00008, 0.99892, 1.00073, 1.00073, 1.00114, 0.99915, 1.00073, 0.99955, 0.99973, 1.00092, 0.99973, 1, 0.99998, 1, 1.0003, 1, 1.00043, 1.00001, 0.99969, 1.0003, 1, 1.00035, 1.00001, 0.9995, 1, 1.00092, 0.99973, 0.99973, 0.99973, 1.0007, 0.9995, 1, 0.99924, 1.0006, 0.99924, 0.99972, 1.00062, 0.99973, 1.00114, 1.00073, 1, 0.99955, 1, 1, 1.00047, 0.99968, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 0.99925, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const HelveticaRegularMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+
+;// CONCATENATED MODULE: ./src/core/liberationsans_widths.js
+const LiberationSansBoldWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 719, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 785, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 385, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 465, 722, 333, 853, 906, 474, 825, 927, 838, 278, 722, 722, 601, 719, 667, 611, 722, 778, 278, 722, 667, 833, 722, 644, 778, 722, 667, 600, 611, 667, 821, 667, 809, 802, 278, 667, 615, 451, 611, 278, 582, 615, 610, 556, 606, 475, 460, 611, 541, 278, 558, 556, 612, 556, 445, 611, 766, 619, 520, 684, 446, 582, 715, 576, 753, 845, 278, 582, 611, 582, 845, 667, 669, 885, 567, 711, 667, 278, 276, 556, 1094, 1062, 875, 610, 722, 622, 719, 722, 719, 722, 567, 712, 667, 904, 626, 719, 719, 610, 702, 833, 722, 778, 719, 667, 722, 611, 622, 854, 667, 730, 703, 1005, 1019, 870, 979, 719, 711, 1031, 719, 556, 618, 615, 417, 635, 556, 709, 497, 615, 615, 500, 635, 740, 604, 611, 604, 611, 556, 490, 556, 875, 556, 615, 581, 833, 844, 729, 854, 615, 552, 854, 583, 556, 556, 611, 417, 552, 556, 278, 281, 278, 969, 906, 611, 500, 615, 556, 604, 778, 611, 487, 447, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1094, 556, 885, 489, 1115, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333];
+const LiberationSansBoldMapping = [-1, -1, -1, 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, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
+const LiberationSansBoldItalicWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 740, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 782, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 396, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 722, 333, 854, 906, 473, 844, 930, 847, 278, 722, 722, 610, 671, 667, 611, 722, 778, 278, 722, 667, 833, 722, 657, 778, 718, 667, 590, 611, 667, 822, 667, 829, 781, 278, 667, 620, 479, 611, 278, 591, 620, 621, 556, 610, 479, 492, 611, 558, 278, 566, 556, 603, 556, 450, 611, 712, 605, 532, 664, 409, 591, 704, 578, 773, 834, 278, 591, 611, 591, 834, 667, 667, 886, 614, 719, 667, 278, 278, 556, 1094, 1042, 854, 622, 719, 677, 719, 722, 708, 722, 614, 722, 667, 927, 643, 719, 719, 615, 687, 833, 722, 778, 719, 667, 722, 611, 677, 781, 667, 729, 708, 979, 989, 854, 1000, 708, 719, 1042, 729, 556, 619, 604, 534, 618, 556, 736, 510, 611, 611, 507, 622, 740, 604, 611, 611, 611, 556, 889, 556, 885, 556, 646, 583, 889, 935, 707, 854, 594, 552, 865, 589, 556, 556, 611, 469, 563, 556, 278, 278, 278, 969, 906, 611, 507, 619, 556, 611, 778, 611, 575, 467, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1104, 556, 885, 516, 1146, 1000, 768, 600, 834, 834, 834, 834, 999, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333];
+const LiberationSansBoldItalicMapping = [-1, -1, -1, 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, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
+const LiberationSansItalicWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 625, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 733, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 281, 556, 400, 556, 222, 722, 556, 722, 556, 722, 556, 615, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 354, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 789, 846, 389, 794, 865, 775, 222, 667, 667, 570, 671, 667, 611, 722, 778, 278, 667, 667, 833, 722, 648, 778, 725, 667, 600, 611, 667, 837, 667, 831, 761, 278, 667, 570, 439, 555, 222, 550, 570, 571, 500, 556, 439, 463, 555, 542, 222, 500, 492, 548, 500, 447, 556, 670, 573, 486, 603, 374, 550, 652, 546, 728, 779, 222, 550, 556, 550, 779, 667, 667, 843, 544, 708, 667, 278, 278, 500, 1066, 982, 844, 589, 715, 639, 724, 667, 651, 667, 544, 704, 667, 917, 614, 715, 715, 589, 686, 833, 722, 778, 725, 667, 722, 611, 639, 795, 667, 727, 673, 920, 923, 805, 886, 651, 694, 1022, 682, 556, 562, 522, 493, 553, 556, 688, 465, 556, 556, 472, 564, 686, 550, 556, 556, 556, 500, 833, 500, 835, 500, 572, 518, 830, 851, 621, 736, 526, 492, 752, 534, 556, 556, 556, 378, 496, 500, 222, 222, 222, 910, 828, 556, 472, 565, 500, 556, 778, 556, 492, 339, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1083, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 998, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 584, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285];
+const LiberationSansItalicMapping = [-1, -1, -1, 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, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
+const LiberationSansRegularWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 615, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 735, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 292, 556, 334, 556, 222, 722, 556, 722, 556, 722, 556, 604, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 375, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 784, 838, 384, 774, 855, 752, 222, 667, 667, 551, 668, 667, 611, 722, 778, 278, 667, 668, 833, 722, 650, 778, 722, 667, 618, 611, 667, 798, 667, 835, 748, 278, 667, 578, 446, 556, 222, 547, 578, 575, 500, 557, 446, 441, 556, 556, 222, 500, 500, 576, 500, 448, 556, 690, 569, 482, 617, 395, 547, 648, 525, 713, 781, 222, 547, 556, 547, 781, 667, 667, 865, 542, 719, 667, 278, 278, 500, 1057, 1010, 854, 583, 722, 635, 719, 667, 656, 667, 542, 677, 667, 923, 604, 719, 719, 583, 656, 833, 722, 778, 719, 667, 722, 611, 635, 760, 667, 740, 667, 917, 938, 792, 885, 656, 719, 1010, 722, 556, 573, 531, 365, 583, 556, 669, 458, 559, 559, 438, 583, 688, 552, 556, 542, 556, 500, 458, 500, 823, 500, 573, 521, 802, 823, 625, 719, 521, 510, 750, 542, 556, 556, 556, 365, 510, 500, 222, 278, 222, 906, 812, 556, 438, 559, 500, 552, 778, 556, 489, 411, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1073, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285];
+const LiberationSansRegularMapping = [-1, -1, -1, 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, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
+
+;// CONCATENATED MODULE: ./src/core/myriadpro_factors.js
+const MyriadProBoldFactors = [1.36898, 1, 1, 0.72706, 0.80479, 0.83734, 0.98894, 0.99793, 0.9897, 0.93884, 0.86209, 0.94292, 0.94292, 1.16661, 1.02058, 0.93582, 0.96694, 0.93582, 1.19137, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.72851, 0.78966, 0.90838, 0.83637, 0.82391, 0.96376, 0.80061, 0.86275, 0.8768, 0.95407, 1.0258, 0.73901, 0.85022, 0.83655, 1.0156, 0.95546, 0.92179, 0.87107, 0.92179, 0.82114, 0.8096, 0.89713, 0.94438, 0.95353, 0.94083, 0.91905, 0.90406, 0.9446, 0.94292, 1.18777, 0.94292, 1.02058, 0.89903, 0.90088, 0.94938, 0.97898, 0.81093, 0.97571, 0.94938, 1.024, 0.9577, 0.95933, 0.98621, 1.0474, 0.97455, 0.98981, 0.9672, 0.95933, 0.9446, 0.97898, 0.97407, 0.97646, 0.78036, 1.10208, 0.95442, 0.95298, 0.97579, 0.9332, 0.94039, 0.938, 0.80687, 1.01149, 0.80687, 1.02058, 0.80479, 0.99793, 0.99793, 0.99793, 0.99793, 1.01149, 1.00872, 0.90088, 0.91882, 1.0213, 0.8361, 1.02058, 0.62295, 0.54324, 0.89022, 1.08595, 1, 1, 0.90088, 1, 0.97455, 0.93582, 0.90088, 1, 1.05686, 0.8361, 0.99642, 0.99642, 0.99642, 0.72851, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.868, 0.82391, 0.80061, 0.80061, 0.80061, 0.80061, 1.0258, 1.0258, 1.0258, 1.0258, 0.97484, 0.95546, 0.92179, 0.92179, 0.92179, 0.92179, 0.92179, 1.02058, 0.92179, 0.94438, 0.94438, 0.94438, 0.94438, 0.90406, 0.86958, 0.98225, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.9031, 0.81093, 0.94938, 0.94938, 0.94938, 0.94938, 0.98621, 0.98621, 0.98621, 0.98621, 0.93969, 0.95933, 0.9446, 0.9446, 0.9446, 0.9446, 0.9446, 1.08595, 0.9446, 0.95442, 0.95442, 0.95442, 0.95442, 0.94039, 0.97898, 0.94039, 0.90838, 0.94938, 0.90838, 0.94938, 0.90838, 0.94938, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.96376, 0.84313, 0.97484, 0.97571, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.8768, 0.9577, 0.8768, 0.9577, 0.8768, 0.9577, 1, 1, 0.95407, 0.95933, 0.97069, 0.95933, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 0.887, 1.01591, 0.73901, 1.0474, 1, 1, 0.97455, 0.83655, 0.98981, 1, 1, 0.83655, 0.73977, 0.83655, 0.73903, 0.84638, 1.033, 0.95546, 0.95933, 1, 1, 0.95546, 0.95933, 0.8271, 0.95417, 0.95933, 0.92179, 0.9446, 0.92179, 0.9446, 0.92179, 0.9446, 0.936, 0.91964, 0.82114, 0.97646, 1, 1, 0.82114, 0.97646, 0.8096, 0.78036, 0.8096, 0.78036, 1, 1, 0.8096, 0.78036, 1, 1, 0.89713, 0.77452, 0.89713, 1.10208, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94083, 0.97579, 0.90406, 0.94039, 0.90406, 0.9446, 0.938, 0.9446, 0.938, 0.9446, 0.938, 1, 0.99793, 0.90838, 0.94938, 0.868, 0.9031, 0.92179, 0.9446, 1, 1, 0.89713, 1.10208, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90989, 0.9358, 0.91945, 0.83181, 0.75261, 0.87992, 0.82976, 0.96034, 0.83689, 0.97268, 1.0078, 0.90838, 0.83637, 0.8019, 0.90157, 0.80061, 0.9446, 0.95407, 0.92436, 1.0258, 0.85022, 0.97153, 1.0156, 0.95546, 0.89192, 0.92179, 0.92361, 0.87107, 0.96318, 0.89713, 0.93704, 0.95638, 0.91905, 0.91709, 0.92796, 1.0258, 0.93704, 0.94836, 1.0373, 0.95933, 1.0078, 0.95871, 0.94836, 0.96174, 0.92601, 0.9498, 0.98607, 0.95776, 0.95933, 1.05453, 1.0078, 0.98275, 0.9314, 0.95617, 0.91701, 1.05993, 0.9446, 0.78367, 0.9553, 1, 0.86832, 1.0128, 0.95871, 0.99394, 0.87548, 0.96361, 0.86774, 1.0078, 0.95871, 0.9446, 0.95871, 0.86774, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.94083, 0.97579, 0.94083, 0.97579, 0.94083, 0.97579, 0.90406, 0.94039, 0.96694, 1, 0.89903, 1, 1, 1, 0.93582, 0.93582, 0.93582, 1, 0.908, 0.908, 0.918, 0.94219, 0.94219, 0.96544, 1, 1.285, 1, 1, 0.81079, 0.81079, 1, 1, 0.74854, 1, 1, 1, 1, 0.99793, 1, 1, 1, 0.65, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.17173, 1, 0.80535, 0.76169, 1.02058, 1.0732, 1.05486, 1, 1, 1.30692, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.16161, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const MyriadProBoldMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+const MyriadProBoldItalicFactors = [1.36898, 1, 1, 0.66227, 0.80779, 0.81625, 0.97276, 0.97276, 0.97733, 0.92222, 0.83266, 0.94292, 0.94292, 1.16148, 1.02058, 0.93582, 0.96694, 0.93582, 1.17337, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.71541, 0.76813, 0.85576, 0.80591, 0.80729, 0.94299, 0.77512, 0.83655, 0.86523, 0.92222, 0.98621, 0.71743, 0.81698, 0.79726, 0.98558, 0.92222, 0.90637, 0.83809, 0.90637, 0.80729, 0.76463, 0.86275, 0.90699, 0.91605, 0.9154, 0.85308, 0.85458, 0.90531, 0.94292, 1.21296, 0.94292, 1.02058, 0.89903, 1.18616, 0.99613, 0.91677, 0.78216, 0.91677, 0.90083, 0.98796, 0.9135, 0.92168, 0.95381, 0.98981, 0.95298, 0.95381, 0.93459, 0.92168, 0.91513, 0.92004, 0.91677, 0.95077, 0.748, 1.04502, 0.91677, 0.92061, 0.94236, 0.89544, 0.89364, 0.9, 0.80687, 0.8578, 0.80687, 1.02058, 0.80779, 0.97276, 0.97276, 0.97276, 0.97276, 0.8578, 0.99973, 1.18616, 0.91339, 1.08074, 0.82891, 1.02058, 0.55509, 0.71526, 0.89022, 1.08595, 1, 1, 1.18616, 1, 0.96736, 0.93582, 1.18616, 1, 1.04864, 0.82711, 0.99043, 0.99043, 0.99043, 0.71541, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.845, 0.80729, 0.77512, 0.77512, 0.77512, 0.77512, 0.98621, 0.98621, 0.98621, 0.98621, 0.95961, 0.92222, 0.90637, 0.90637, 0.90637, 0.90637, 0.90637, 1.02058, 0.90251, 0.90699, 0.90699, 0.90699, 0.90699, 0.85458, 0.83659, 0.94951, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.85811, 0.78216, 0.90083, 0.90083, 0.90083, 0.90083, 0.95381, 0.95381, 0.95381, 0.95381, 0.9135, 0.92168, 0.91513, 0.91513, 0.91513, 0.91513, 0.91513, 1.08595, 0.91677, 0.91677, 0.91677, 0.91677, 0.91677, 0.89364, 0.92332, 0.89364, 0.85576, 0.99613, 0.85576, 0.99613, 0.85576, 0.99613, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.94299, 0.76783, 0.95961, 0.91677, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.86523, 0.9135, 0.86523, 0.9135, 0.86523, 0.9135, 1, 1, 0.92222, 0.92168, 0.92222, 0.92168, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.86036, 0.97096, 0.71743, 0.98981, 1, 1, 0.95298, 0.79726, 0.95381, 1, 1, 0.79726, 0.6894, 0.79726, 0.74321, 0.81691, 1.0006, 0.92222, 0.92168, 1, 1, 0.92222, 0.92168, 0.79464, 0.92098, 0.92168, 0.90637, 0.91513, 0.90637, 0.91513, 0.90637, 0.91513, 0.909, 0.87514, 0.80729, 0.95077, 1, 1, 0.80729, 0.95077, 0.76463, 0.748, 0.76463, 0.748, 1, 1, 0.76463, 0.748, 1, 1, 0.86275, 0.72651, 0.86275, 1.04502, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.9154, 0.94236, 0.85458, 0.89364, 0.85458, 0.90531, 0.9, 0.90531, 0.9, 0.90531, 0.9, 1, 0.97276, 0.85576, 0.99613, 0.845, 0.85811, 0.90251, 0.91677, 1, 1, 0.86275, 1.04502, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.00899, 1.30628, 0.85576, 0.80178, 0.66862, 0.7927, 0.69323, 0.88127, 0.72459, 0.89711, 0.95381, 0.85576, 0.80591, 0.7805, 0.94729, 0.77512, 0.90531, 0.92222, 0.90637, 0.98621, 0.81698, 0.92655, 0.98558, 0.92222, 0.85359, 0.90637, 0.90976, 0.83809, 0.94523, 0.86275, 0.83509, 0.93157, 0.85308, 0.83392, 0.92346, 0.98621, 0.83509, 0.92886, 0.91324, 0.92168, 0.95381, 0.90646, 0.92886, 0.90557, 0.86847, 0.90276, 0.91324, 0.86842, 0.92168, 0.99531, 0.95381, 0.9224, 0.85408, 0.92699, 0.86847, 1.0051, 0.91513, 0.80487, 0.93481, 1, 0.88159, 1.05214, 0.90646, 0.97355, 0.81539, 0.89398, 0.85923, 0.95381, 0.90646, 0.91513, 0.90646, 0.85923, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9154, 0.94236, 0.9154, 0.94236, 0.9154, 0.94236, 0.85458, 0.89364, 0.96694, 1, 0.89903, 1, 1, 1, 0.91782, 0.91782, 0.91782, 1, 0.896, 0.896, 0.896, 0.9332, 0.9332, 0.95973, 1, 1.26, 1, 1, 0.80479, 0.80178, 1, 1, 0.85633, 1, 1, 1, 1, 0.97276, 1, 1, 1, 0.698, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.14542, 1, 0.79199, 0.78694, 1.02058, 1.03493, 1.05486, 1, 1, 1.23026, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.20006, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const MyriadProBoldItalicMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+const MyriadProItalicFactors = [1.36898, 1, 1, 0.65507, 0.84943, 0.85639, 0.88465, 0.88465, 0.86936, 0.88307, 0.86948, 0.85283, 0.85283, 1.06383, 1.02058, 0.75945, 0.9219, 0.75945, 1.17337, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.75945, 0.75945, 1.02058, 1.02058, 1.02058, 0.69046, 0.70926, 0.85158, 0.77812, 0.76852, 0.89591, 0.70466, 0.76125, 0.80094, 0.86822, 0.83864, 0.728, 0.77212, 0.79475, 0.93637, 0.87514, 0.8588, 0.76013, 0.8588, 0.72421, 0.69866, 0.77598, 0.85991, 0.80811, 0.87832, 0.78112, 0.77512, 0.8562, 1.0222, 1.18417, 1.0222, 1.27014, 0.89903, 1.15012, 0.93859, 0.94399, 0.846, 0.94399, 0.81453, 1.0186, 0.94219, 0.96017, 1.03075, 1.02175, 0.912, 1.03075, 0.96998, 0.96017, 0.93859, 0.94399, 0.94399, 0.95493, 0.746, 1.12658, 0.94578, 0.91, 0.979, 0.882, 0.882, 0.83, 0.85034, 0.83537, 0.85034, 1.02058, 0.70869, 0.88465, 0.88465, 0.88465, 0.88465, 0.83537, 0.90083, 1.15012, 0.9161, 0.94565, 0.73541, 1.02058, 0.53609, 0.69353, 0.79519, 1.08595, 1, 1, 1.15012, 1, 0.91974, 0.75945, 1.15012, 1, 0.9446, 0.73361, 0.9005, 0.9005, 0.9005, 0.62864, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.773, 0.76852, 0.70466, 0.70466, 0.70466, 0.70466, 0.83864, 0.83864, 0.83864, 0.83864, 0.90561, 0.87514, 0.8588, 0.8588, 0.8588, 0.8588, 0.8588, 1.02058, 0.85751, 0.85991, 0.85991, 0.85991, 0.85991, 0.77512, 0.76013, 0.88075, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.8075, 0.846, 0.81453, 0.81453, 0.81453, 0.81453, 0.82424, 0.82424, 0.82424, 0.82424, 0.9278, 0.96017, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 1.08595, 0.8562, 0.94578, 0.94578, 0.94578, 0.94578, 0.882, 0.94578, 0.882, 0.85158, 0.93859, 0.85158, 0.93859, 0.85158, 0.93859, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.89591, 0.8544, 0.90561, 0.94399, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.80094, 0.94219, 0.80094, 0.94219, 0.80094, 0.94219, 1, 1, 0.86822, 0.96017, 0.86822, 0.96017, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 1.03075, 0.83864, 0.82424, 0.81402, 1.02738, 0.728, 1.02175, 1, 1, 0.912, 0.79475, 1.03075, 1, 1, 0.79475, 0.83911, 0.79475, 0.66266, 0.80553, 1.06676, 0.87514, 0.96017, 1, 1, 0.87514, 0.96017, 0.86865, 0.87396, 0.96017, 0.8588, 0.93859, 0.8588, 0.93859, 0.8588, 0.93859, 0.867, 0.84759, 0.72421, 0.95493, 1, 1, 0.72421, 0.95493, 0.69866, 0.746, 0.69866, 0.746, 1, 1, 0.69866, 0.746, 1, 1, 0.77598, 0.88417, 0.77598, 1.12658, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.87832, 0.979, 0.77512, 0.882, 0.77512, 0.8562, 0.83, 0.8562, 0.83, 0.8562, 0.83, 1, 0.88465, 0.85158, 0.93859, 0.773, 0.8075, 0.85751, 0.8562, 1, 1, 0.77598, 1.12658, 1.15012, 1.15012, 1.15012, 1.15012, 1.15012, 1.15313, 1.15012, 1.15012, 1.15012, 1.08106, 1.03901, 0.85158, 0.77025, 0.62264, 0.7646, 0.65351, 0.86026, 0.69461, 0.89947, 1.03075, 0.85158, 0.77812, 0.76449, 0.88836, 0.70466, 0.8562, 0.86822, 0.8588, 0.83864, 0.77212, 0.85308, 0.93637, 0.87514, 0.82352, 0.8588, 0.85701, 0.76013, 0.89058, 0.77598, 0.8156, 0.82565, 0.78112, 0.77899, 0.89386, 0.83864, 0.8156, 0.9486, 0.92388, 0.96186, 1.03075, 0.91123, 0.9486, 0.93298, 0.878, 0.93942, 0.92388, 0.84596, 0.96186, 0.95119, 1.03075, 0.922, 0.88787, 0.95829, 0.88, 0.93559, 0.93859, 0.78815, 0.93758, 1, 0.89217, 1.03737, 0.91123, 0.93969, 0.77487, 0.85769, 0.86799, 1.03075, 0.91123, 0.93859, 0.91123, 0.86799, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87832, 0.979, 0.87832, 0.979, 0.87832, 0.979, 0.77512, 0.882, 0.9219, 1, 0.89903, 1, 1, 1, 0.87321, 0.87321, 0.87321, 1, 1.027, 1.027, 1.027, 0.86847, 0.86847, 0.79121, 1, 1.124, 1, 1, 0.73572, 0.73572, 1, 1, 0.85034, 1, 1, 1, 1, 0.88465, 1, 1, 1, 0.669, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04828, 1, 0.74948, 0.75187, 1.02058, 0.98391, 1.02119, 1, 1, 1.06233, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05233, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const MyriadProItalicMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+const MyriadProRegularFactors = [1.36898, 1, 1, 0.76305, 0.82784, 0.94935, 0.89364, 0.92241, 0.89073, 0.90706, 0.98472, 0.85283, 0.85283, 1.0664, 1.02058, 0.74505, 0.9219, 0.74505, 1.23456, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.74505, 0.74505, 1.02058, 1.02058, 1.02058, 0.73002, 0.72601, 0.91755, 0.8126, 0.80314, 0.92222, 0.73764, 0.79726, 0.83051, 0.90284, 0.86023, 0.74, 0.8126, 0.84869, 0.96518, 0.91115, 0.8858, 0.79761, 0.8858, 0.74498, 0.73914, 0.81363, 0.89591, 0.83659, 0.89633, 0.85608, 0.8111, 0.90531, 1.0222, 1.22736, 1.0222, 1.27014, 0.89903, 0.90088, 0.86667, 1.0231, 0.896, 1.01411, 0.90083, 1.05099, 1.00512, 0.99793, 1.05326, 1.09377, 0.938, 1.06226, 1.00119, 0.99793, 0.98714, 1.0231, 1.01231, 0.98196, 0.792, 1.19137, 0.99074, 0.962, 1.01915, 0.926, 0.942, 0.856, 0.85034, 0.92006, 0.85034, 1.02058, 0.69067, 0.92241, 0.92241, 0.92241, 0.92241, 0.92006, 0.9332, 0.90088, 0.91882, 0.93484, 0.75339, 1.02058, 0.56866, 0.54324, 0.79519, 1.08595, 1, 1, 0.90088, 1, 0.95325, 0.74505, 0.90088, 1, 0.97198, 0.75339, 0.91009, 0.91009, 0.91009, 0.66466, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.788, 0.80314, 0.73764, 0.73764, 0.73764, 0.73764, 0.86023, 0.86023, 0.86023, 0.86023, 0.92915, 0.91115, 0.8858, 0.8858, 0.8858, 0.8858, 0.8858, 1.02058, 0.8858, 0.89591, 0.89591, 0.89591, 0.89591, 0.8111, 0.79611, 0.89713, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86936, 0.896, 0.90083, 0.90083, 0.90083, 0.90083, 0.84224, 0.84224, 0.84224, 0.84224, 0.97276, 0.99793, 0.98714, 0.98714, 0.98714, 0.98714, 0.98714, 1.08595, 0.89876, 0.99074, 0.99074, 0.99074, 0.99074, 0.942, 1.0231, 0.942, 0.91755, 0.86667, 0.91755, 0.86667, 0.91755, 0.86667, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.92222, 0.93372, 0.92915, 1.01411, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.83051, 1.00512, 0.83051, 1.00512, 0.83051, 1.00512, 1, 1, 0.90284, 0.99793, 0.90976, 0.99793, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 1.05326, 0.86023, 0.84224, 0.82873, 1.07469, 0.74, 1.09377, 1, 1, 0.938, 0.84869, 1.06226, 1, 1, 0.84869, 0.83704, 0.84869, 0.81441, 0.85588, 1.08927, 0.91115, 0.99793, 1, 1, 0.91115, 0.99793, 0.91887, 0.90991, 0.99793, 0.8858, 0.98714, 0.8858, 0.98714, 0.8858, 0.98714, 0.894, 0.91434, 0.74498, 0.98196, 1, 1, 0.74498, 0.98196, 0.73914, 0.792, 0.73914, 0.792, 1, 1, 0.73914, 0.792, 1, 1, 0.81363, 0.904, 0.81363, 1.19137, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89633, 1.01915, 0.8111, 0.942, 0.8111, 0.90531, 0.856, 0.90531, 0.856, 0.90531, 0.856, 1, 0.92241, 0.91755, 0.86667, 0.788, 0.86936, 0.8858, 0.89876, 1, 1, 0.81363, 1.19137, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90388, 1.03901, 0.92138, 0.78105, 0.7154, 0.86169, 0.80513, 0.94007, 0.82528, 0.98612, 1.06226, 0.91755, 0.8126, 0.81884, 0.92819, 0.73764, 0.90531, 0.90284, 0.8858, 0.86023, 0.8126, 0.91172, 0.96518, 0.91115, 0.83089, 0.8858, 0.87791, 0.79761, 0.89297, 0.81363, 0.88157, 0.89992, 0.85608, 0.81992, 0.94307, 0.86023, 0.88157, 0.95308, 0.98699, 0.99793, 1.06226, 0.95817, 0.95308, 0.97358, 0.928, 0.98088, 0.98699, 0.92761, 0.99793, 0.96017, 1.06226, 0.986, 0.944, 0.95978, 0.938, 0.96705, 0.98714, 0.80442, 0.98972, 1, 0.89762, 1.04552, 0.95817, 0.99007, 0.87064, 0.91879, 0.88888, 1.06226, 0.95817, 0.98714, 0.95817, 0.88888, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89633, 1.01915, 0.89633, 1.01915, 0.89633, 1.01915, 0.8111, 0.942, 0.9219, 1, 0.89903, 1, 1, 1, 0.93173, 0.93173, 0.93173, 1, 1.06304, 1.06304, 1.06904, 0.89903, 0.89903, 0.80549, 1, 1.156, 1, 1, 0.76575, 0.76575, 1, 1, 0.72458, 1, 1, 1, 1, 0.92241, 1, 1, 1, 0.619, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.07257, 1, 0.74705, 0.71119, 1.02058, 1.024, 1.02119, 1, 1, 1.1536, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05638, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const MyriadProRegularMetrics = {
+ lineHeight: 1.2,
+ lineGap: 0.2
+};
+
+;// CONCATENATED MODULE: ./src/core/segoeui_factors.js
+const SegoeuiBoldFactors = [1.76738, 1, 1, 0.99297, 0.9824, 1.04016, 1.06497, 1.03424, 0.97529, 1.17647, 1.23203, 1.1085, 1.1085, 1.16939, 1.2107, 0.9754, 1.21408, 0.9754, 1.59578, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 0.81378, 0.81378, 1.2107, 1.2107, 1.2107, 0.71703, 0.97847, 0.97363, 0.88776, 0.8641, 1.02096, 0.79795, 0.85132, 0.914, 1.06085, 1.1406, 0.8007, 0.89858, 0.83693, 1.14889, 1.09398, 0.97489, 0.92094, 0.97489, 0.90399, 0.84041, 0.95923, 1.00135, 1, 1.06467, 0.98243, 0.90996, 0.99361, 1.1085, 1.56942, 1.1085, 1.2107, 0.74627, 0.94282, 0.96752, 1.01519, 0.86304, 1.01359, 0.97278, 1.15103, 1.01359, 0.98561, 1.02285, 1.02285, 1.00527, 1.02285, 1.0302, 0.99041, 1.0008, 1.01519, 1.01359, 1.02258, 0.79104, 1.16862, 0.99041, 0.97454, 1.02511, 0.99298, 0.96752, 0.95801, 0.94856, 1.16579, 0.94856, 1.2107, 0.9824, 1.03424, 1.03424, 1, 1.03424, 1.16579, 0.8727, 1.3871, 1.18622, 1.10818, 1.04478, 1.2107, 1.18622, 0.75155, 0.94994, 1.28826, 1.21408, 1.21408, 0.91056, 1, 0.91572, 0.9754, 0.64663, 1.18328, 1.24866, 1.04478, 1.14169, 1.15749, 1.17389, 0.71703, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.93506, 0.8641, 0.79795, 0.79795, 0.79795, 0.79795, 1.1406, 1.1406, 1.1406, 1.1406, 1.02096, 1.09398, 0.97426, 0.97426, 0.97426, 0.97426, 0.97426, 1.2107, 0.97489, 1.00135, 1.00135, 1.00135, 1.00135, 0.90996, 0.92094, 1.02798, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.93136, 0.86304, 0.97278, 0.97278, 0.97278, 0.97278, 1.02285, 1.02285, 1.02285, 1.02285, 0.97122, 0.99041, 1, 1, 1, 1, 1, 1.28826, 1.0008, 0.99041, 0.99041, 0.99041, 0.99041, 0.96752, 1.01519, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 1.02096, 1.03057, 1.02096, 1.03517, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.914, 1.01359, 0.914, 1.01359, 0.914, 1.01359, 1, 1, 1.06085, 0.98561, 1.06085, 1.00879, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 0.97138, 1.08692, 0.8007, 1.02285, 1, 1, 1.00527, 0.83693, 1.02285, 1, 1, 0.83693, 0.9455, 0.83693, 0.90418, 0.83693, 1.13005, 1.09398, 0.99041, 1, 1, 1.09398, 0.99041, 0.96692, 1.09251, 0.99041, 0.97489, 1.0008, 0.97489, 1.0008, 0.97489, 1.0008, 0.93994, 0.97931, 0.90399, 1.02258, 1, 1, 0.90399, 1.02258, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 1, 1, 0.95923, 1.07034, 0.95923, 1.16862, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.06467, 1.02511, 0.90996, 0.96752, 0.90996, 0.99361, 0.95801, 0.99361, 0.95801, 0.99361, 0.95801, 1.07733, 1.03424, 0.97363, 0.96752, 0.93506, 0.93136, 0.97489, 1.0008, 1, 1, 0.95923, 1.16862, 1.15103, 1.15103, 1.01173, 1.03959, 0.75953, 0.81378, 0.79912, 1.15103, 1.21994, 0.95161, 0.87815, 1.01149, 0.81525, 0.7676, 0.98167, 1.01134, 1.02546, 0.84097, 1.03089, 1.18102, 0.97363, 0.88776, 0.85134, 0.97826, 0.79795, 0.99361, 1.06085, 0.97489, 1.1406, 0.89858, 1.0388, 1.14889, 1.09398, 0.86039, 0.97489, 1.0595, 0.92094, 0.94793, 0.95923, 0.90996, 0.99346, 0.98243, 1.02112, 0.95493, 1.1406, 0.90996, 1.03574, 1.02597, 1.0008, 1.18102, 1.06628, 1.03574, 1.0192, 1.01932, 1.00886, 0.97531, 1.0106, 1.0008, 1.13189, 1.18102, 1.02277, 0.98683, 1.0016, 0.99561, 1.07237, 1.0008, 0.90434, 0.99921, 0.93803, 0.8965, 1.23085, 1.06628, 1.04983, 0.96268, 1.0499, 0.98439, 1.18102, 1.06628, 1.0008, 1.06628, 0.98439, 0.79795, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09466, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.97278, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.02065, 1, 1, 1, 1, 1, 1, 1.06467, 1.02511, 1.06467, 1.02511, 1.06467, 1.02511, 0.90996, 0.96752, 1, 1.21408, 0.89903, 1, 1, 0.75155, 1.04394, 1.04394, 1.04394, 1.04394, 0.98633, 0.98633, 0.98633, 0.73047, 0.73047, 1.20642, 0.91211, 1.25635, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.12454, 0.93503, 1.03424, 1.19687, 1.03424, 1, 1, 1, 0.771, 1, 1, 1.15749, 1.15749, 1.15749, 1.10948, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.16897, 1, 0.96085, 0.90137, 1.2107, 1.18416, 1.13973, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21172, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18874, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.09193, 1.09193, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const SegoeuiBoldMetrics = {
+ lineHeight: 1.33008,
+ lineGap: 0
+};
+const SegoeuiBoldItalicFactors = [1.76738, 1, 1, 0.98946, 1.03959, 1.04016, 1.02809, 1.036, 0.97639, 1.10953, 1.23203, 1.11144, 1.11144, 1.16939, 1.21237, 0.9754, 1.21261, 0.9754, 1.59754, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 0.81378, 0.81378, 1.21237, 1.21237, 1.21237, 0.73541, 0.97847, 0.97363, 0.89723, 0.87897, 1.0426, 0.79429, 0.85292, 0.91149, 1.05815, 1.1406, 0.79631, 0.90128, 0.83853, 1.04396, 1.10615, 0.97552, 0.94436, 0.97552, 0.88641, 0.80527, 0.96083, 1.00135, 1, 1.06777, 0.9817, 0.91142, 0.99361, 1.11144, 1.57293, 1.11144, 1.21237, 0.74627, 1.31818, 1.06585, 0.97042, 0.83055, 0.97042, 0.93503, 1.1261, 0.97042, 0.97922, 1.14236, 0.94552, 1.01054, 1.14236, 1.02471, 0.97922, 0.94165, 0.97042, 0.97042, 1.0276, 0.78929, 1.1261, 0.97922, 0.95874, 1.02197, 0.98507, 0.96752, 0.97168, 0.95107, 1.16579, 0.95107, 1.21237, 1.03959, 1.036, 1.036, 1, 1.036, 1.16579, 0.87357, 1.31818, 1.18754, 1.26781, 1.05356, 1.21237, 1.18622, 0.79487, 0.94994, 1.29004, 1.24047, 1.24047, 1.31818, 1, 0.91484, 0.9754, 1.31818, 1.1349, 1.24866, 1.05356, 1.13934, 1.15574, 1.17389, 0.73541, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.94385, 0.87897, 0.79429, 0.79429, 0.79429, 0.79429, 1.1406, 1.1406, 1.1406, 1.1406, 1.0426, 1.10615, 0.97552, 0.97552, 0.97552, 0.97552, 0.97552, 1.21237, 0.97552, 1.00135, 1.00135, 1.00135, 1.00135, 0.91142, 0.94436, 0.98721, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 0.96705, 0.83055, 0.93503, 0.93503, 0.93503, 0.93503, 1.14236, 1.14236, 1.14236, 1.14236, 0.93125, 0.97922, 0.94165, 0.94165, 0.94165, 0.94165, 0.94165, 1.29004, 0.94165, 0.97922, 0.97922, 0.97922, 0.97922, 0.96752, 0.97042, 0.96752, 0.97363, 1.06585, 0.97363, 1.06585, 0.97363, 1.06585, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 1.0426, 1.0033, 1.0426, 0.97042, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.91149, 0.97042, 0.91149, 0.97042, 0.91149, 0.97042, 1, 1, 1.05815, 0.97922, 1.05815, 0.97922, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 0.97441, 1.04302, 0.79631, 1.01582, 1, 1, 1.01054, 0.83853, 1.14236, 1, 1, 0.83853, 1.09125, 0.83853, 0.90418, 0.83853, 1.19508, 1.10615, 0.97922, 1, 1, 1.10615, 0.97922, 1.01034, 1.10466, 0.97922, 0.97552, 0.94165, 0.97552, 0.94165, 0.97552, 0.94165, 0.91602, 0.91981, 0.88641, 1.0276, 1, 1, 0.88641, 1.0276, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 1, 1, 0.96083, 1.05403, 0.95923, 1.16862, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.06777, 1.02197, 0.91142, 0.96752, 0.91142, 0.99361, 0.97168, 0.99361, 0.97168, 0.99361, 0.97168, 1.23199, 1.036, 0.97363, 1.06585, 0.94385, 0.96705, 0.97552, 0.94165, 1, 1, 0.96083, 1.1261, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 0.95161, 1.27126, 1.00811, 0.83284, 0.77702, 0.99137, 0.95253, 1.0347, 0.86142, 1.07205, 1.14236, 0.97363, 0.89723, 0.86869, 1.09818, 0.79429, 0.99361, 1.05815, 0.97552, 1.1406, 0.90128, 1.06662, 1.04396, 1.10615, 0.84918, 0.97552, 1.04694, 0.94436, 0.98015, 0.96083, 0.91142, 1.00356, 0.9817, 1.01945, 0.98999, 1.1406, 0.91142, 1.04961, 0.9898, 1.00639, 1.14236, 1.07514, 1.04961, 0.99607, 1.02897, 1.008, 0.9898, 0.95134, 1.00639, 1.11121, 1.14236, 1.00518, 0.97981, 1.02186, 1, 1.08578, 0.94165, 0.99314, 0.98387, 0.93028, 0.93377, 1.35125, 1.07514, 1.10687, 0.93491, 1.04232, 1.00351, 1.14236, 1.07514, 0.94165, 1.07514, 1.00351, 0.79429, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09097, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.93503, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96609, 1, 1, 1, 1, 1, 1, 1.06777, 1.02197, 1.06777, 1.02197, 1.06777, 1.02197, 0.91142, 0.96752, 1, 1.21261, 0.89903, 1, 1, 0.75155, 1.04745, 1.04745, 1.04745, 1.04394, 0.98633, 0.98633, 0.98633, 0.72959, 0.72959, 1.20502, 0.91406, 1.26514, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.09125, 0.93327, 1.03336, 1.16541, 1.036, 1, 1, 1, 0.771, 1, 1, 1.15574, 1.15574, 1.15574, 1.15574, 0.86364, 0.94434, 0.86279, 0.94434, 0.86224, 1, 1, 1.16798, 1, 0.96085, 0.90068, 1.21237, 1.18416, 1.13904, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21339, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18775, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.13269, 1.13269, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const SegoeuiBoldItalicMetrics = {
+ lineHeight: 1.33008,
+ lineGap: 0
+};
+const SegoeuiItalicFactors = [1.76738, 1, 1, 0.98946, 1.14763, 1.05365, 1.06234, 0.96927, 0.92586, 1.15373, 1.18414, 0.91349, 0.91349, 1.07403, 1.17308, 0.78383, 1.20088, 0.78383, 1.42531, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78383, 0.78383, 1.17308, 1.17308, 1.17308, 0.77349, 0.94565, 0.94729, 0.85944, 0.88506, 0.9858, 0.74817, 0.80016, 0.88449, 0.98039, 0.95782, 0.69238, 0.89898, 0.83231, 0.98183, 1.03989, 0.96924, 0.86237, 0.96924, 0.80595, 0.74524, 0.86091, 0.95402, 0.94143, 0.98448, 0.8858, 0.83089, 0.93285, 1.0949, 1.39016, 1.0949, 1.45994, 0.74627, 1.04839, 0.97454, 0.97454, 0.87207, 0.97454, 0.87533, 1.06151, 0.97454, 1.00176, 1.16484, 1.08132, 0.98047, 1.16484, 1.02989, 1.01054, 0.96225, 0.97454, 0.97454, 1.06598, 0.79004, 1.16344, 1.00351, 0.94629, 0.9973, 0.91016, 0.96777, 0.9043, 0.91082, 0.92481, 0.91082, 1.17308, 0.95748, 0.96927, 0.96927, 1, 0.96927, 0.92481, 0.80597, 1.04839, 1.23393, 1.1781, 0.9245, 1.17308, 1.20808, 0.63218, 0.94261, 1.24822, 1.09971, 1.09971, 1.04839, 1, 0.85273, 0.78032, 1.04839, 1.09971, 1.22326, 0.9245, 1.09836, 1.13525, 1.15222, 0.70424, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.85498, 0.88506, 0.74817, 0.74817, 0.74817, 0.74817, 0.95782, 0.95782, 0.95782, 0.95782, 0.9858, 1.03989, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.17308, 0.96924, 0.95402, 0.95402, 0.95402, 0.95402, 0.83089, 0.86237, 0.88409, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.92916, 0.87207, 0.87533, 0.87533, 0.87533, 0.87533, 0.93146, 0.93146, 0.93146, 0.93146, 0.93854, 1.01054, 0.96225, 0.96225, 0.96225, 0.96225, 0.96225, 1.24822, 0.8761, 1.00351, 1.00351, 1.00351, 1.00351, 0.96777, 0.97454, 0.96777, 0.94729, 0.97454, 0.94729, 0.97454, 0.94729, 0.97454, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.9858, 0.95391, 0.9858, 0.97454, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.88449, 0.97454, 0.88449, 0.97454, 0.88449, 0.97454, 1, 1, 0.98039, 1.00176, 0.98039, 1.00176, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 1.16484, 0.95782, 0.93146, 0.84421, 1.12761, 0.69238, 1.08132, 1, 1, 0.98047, 0.83231, 1.16484, 1, 1, 0.84723, 1.04861, 0.84723, 0.78755, 0.83231, 1.23736, 1.03989, 1.01054, 1, 1, 1.03989, 1.01054, 0.9857, 1.03849, 1.01054, 0.96924, 0.96225, 0.96924, 0.96225, 0.96924, 0.96225, 0.92383, 0.90171, 0.80595, 1.06598, 1, 1, 0.80595, 1.06598, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 1, 1, 0.86091, 1.02759, 0.85771, 1.16344, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.98448, 0.9973, 0.83089, 0.96777, 0.83089, 0.93285, 0.9043, 0.93285, 0.9043, 0.93285, 0.9043, 1.31868, 0.96927, 0.94729, 0.97454, 0.85498, 0.92916, 0.96924, 0.8761, 1, 1, 0.86091, 1.16344, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 0.81965, 0.81965, 0.94729, 0.78032, 0.71022, 0.90883, 0.84171, 0.99877, 0.77596, 1.05734, 1.2, 0.94729, 0.85944, 0.82791, 0.9607, 0.74817, 0.93285, 0.98039, 0.96924, 0.95782, 0.89898, 0.98316, 0.98183, 1.03989, 0.78614, 0.96924, 0.97642, 0.86237, 0.86075, 0.86091, 0.83089, 0.90082, 0.8858, 0.97296, 1.01284, 0.95782, 0.83089, 1.0976, 1.04, 1.03342, 1.2, 1.0675, 1.0976, 0.98205, 1.03809, 1.05097, 1.04, 0.95364, 1.03342, 1.05401, 1.2, 1.02148, 1.0119, 1.04724, 1.0127, 1.02732, 0.96225, 0.8965, 0.97783, 0.93574, 0.94818, 1.30679, 1.0675, 1.11826, 0.99821, 1.0557, 1.0326, 1.2, 1.0675, 0.96225, 1.0675, 1.0326, 0.74817, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03754, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87533, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.98705, 1, 1, 1, 1, 1, 1, 0.98448, 0.9973, 0.98448, 0.9973, 0.98448, 0.9973, 0.83089, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 0.94945, 0.94945, 0.94945, 0.94945, 1.12317, 1.12317, 1.12317, 0.67603, 0.67603, 1.15621, 0.73584, 1.21191, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87709, 0.96927, 1.01473, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.09836, 1.09836, 1.09836, 1.01522, 0.86321, 0.94434, 0.8649, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86438, 1.17308, 1.18416, 1.14589, 0.69825, 0.97622, 1.96791, 1.24822, 1.24822, 1.17308, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.17984, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10742, 1.10742, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const SegoeuiItalicMetrics = {
+ lineHeight: 1.33008,
+ lineGap: 0
+};
+const SegoeuiRegularFactors = [1.76738, 1, 1, 0.98594, 1.02285, 1.10454, 1.06234, 0.96927, 0.92037, 1.19985, 1.2046, 0.90616, 0.90616, 1.07152, 1.1714, 0.78032, 1.20088, 0.78032, 1.40246, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78032, 0.78032, 1.1714, 1.1714, 1.1714, 0.80597, 0.94084, 0.96706, 0.85944, 0.85734, 0.97093, 0.75842, 0.79936, 0.88198, 0.9831, 0.95782, 0.71387, 0.86969, 0.84636, 1.07796, 1.03584, 0.96924, 0.83968, 0.96924, 0.82826, 0.79649, 0.85771, 0.95132, 0.93119, 0.98965, 0.88433, 0.8287, 0.93365, 1.08612, 1.3638, 1.08612, 1.45786, 0.74627, 0.80499, 0.91484, 1.05707, 0.92383, 1.05882, 0.9403, 1.12654, 1.05882, 1.01756, 1.09011, 1.09011, 0.99414, 1.09011, 1.034, 1.01756, 1.05356, 1.05707, 1.05882, 1.04399, 0.84863, 1.21968, 1.01756, 0.95801, 1.00068, 0.91797, 0.96777, 0.9043, 0.90351, 0.92105, 0.90351, 1.1714, 0.85337, 0.96927, 0.96927, 0.99912, 0.96927, 0.92105, 0.80597, 1.2434, 1.20808, 1.05937, 0.90957, 1.1714, 1.20808, 0.75155, 0.94261, 1.24644, 1.09971, 1.09971, 0.84751, 1, 0.85273, 0.78032, 0.61584, 1.05425, 1.17914, 0.90957, 1.08665, 1.11593, 1.14169, 0.73381, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.86035, 0.85734, 0.75842, 0.75842, 0.75842, 0.75842, 0.95782, 0.95782, 0.95782, 0.95782, 0.97093, 1.03584, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.1714, 0.96924, 0.95132, 0.95132, 0.95132, 0.95132, 0.8287, 0.83968, 0.89049, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.93575, 0.92383, 0.9403, 0.9403, 0.9403, 0.9403, 0.8717, 0.8717, 0.8717, 0.8717, 1.00527, 1.01756, 1.05356, 1.05356, 1.05356, 1.05356, 1.05356, 1.24644, 0.95923, 1.01756, 1.01756, 1.01756, 1.01756, 0.96777, 1.05707, 0.96777, 0.96706, 0.91484, 0.96706, 0.91484, 0.96706, 0.91484, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.97093, 1.0969, 0.97093, 1.05882, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.88198, 1.05882, 0.88198, 1.05882, 0.88198, 1.05882, 1, 1, 0.9831, 1.01756, 0.9831, 1.01756, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 1.09011, 0.95782, 0.8717, 0.84784, 1.11551, 0.71387, 1.09011, 1, 1, 0.99414, 0.84636, 1.09011, 1, 1, 0.84636, 1.0536, 0.84636, 0.94298, 0.84636, 1.23297, 1.03584, 1.01756, 1, 1, 1.03584, 1.01756, 1.00323, 1.03444, 1.01756, 0.96924, 1.05356, 0.96924, 1.05356, 0.96924, 1.05356, 0.93066, 0.98293, 0.82826, 1.04399, 1, 1, 0.82826, 1.04399, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 1, 1, 0.85771, 1.17318, 0.85771, 1.21968, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.98965, 1.00068, 0.8287, 0.96777, 0.8287, 0.93365, 0.9043, 0.93365, 0.9043, 0.93365, 0.9043, 1.08571, 0.96927, 0.96706, 0.91484, 0.86035, 0.93575, 0.96924, 0.95923, 1, 1, 0.85771, 1.21968, 1.11437, 1.11437, 0.93109, 0.91202, 0.60411, 0.84164, 0.55572, 1.01173, 0.97361, 0.81818, 0.81818, 0.96635, 0.78032, 0.72727, 0.92366, 0.98601, 1.03405, 0.77968, 1.09799, 1.2, 0.96706, 0.85944, 0.85638, 0.96491, 0.75842, 0.93365, 0.9831, 0.96924, 0.95782, 0.86969, 0.94152, 1.07796, 1.03584, 0.78437, 0.96924, 0.98715, 0.83968, 0.83491, 0.85771, 0.8287, 0.94492, 0.88433, 0.9287, 1.0098, 0.95782, 0.8287, 1.0625, 0.98248, 1.03424, 1.2, 1.01071, 1.0625, 0.95246, 1.03809, 1.04912, 0.98248, 1.00221, 1.03424, 1.05443, 1.2, 1.04785, 0.99609, 1.00169, 1.05176, 0.99346, 1.05356, 0.9087, 1.03004, 0.95542, 0.93117, 1.23362, 1.01071, 1.07831, 1.02512, 1.05205, 1.03502, 1.2, 1.01071, 1.05356, 1.01071, 1.03502, 0.75842, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03719, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9403, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04021, 1, 1, 1, 1, 1, 1, 0.98965, 1.00068, 0.98965, 1.00068, 0.98965, 1.00068, 0.8287, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 1.03077, 1.03077, 1.03077, 1.03077, 1.13196, 1.13196, 1.13196, 0.67428, 0.67428, 1.16039, 0.73291, 1.20996, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87796, 0.96927, 1.01518, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.10539, 1.10539, 1.11358, 1.06967, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86507, 1.1714, 1.18416, 1.14589, 0.69825, 0.97622, 1.9697, 1.24822, 1.24822, 1.17238, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18083, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10938, 1.10938, 1, 1, 1, 1.05425, 1.09971, 1.09971, 1.09971, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+const SegoeuiRegularMetrics = {
+ lineHeight: 1.33008,
+ lineGap: 0
+};
+
+;// CONCATENATED MODULE: ./src/core/xfa_fonts.js
+
+
+
+
+
+
+
+
+const getXFAFontMap = getLookupTableFactory(function (t) {
+ t["MyriadPro-Regular"] = t["PdfJS-Fallback-Regular"] = {
+ name: "LiberationSans-Regular",
+ factors: MyriadProRegularFactors,
+ baseWidths: LiberationSansRegularWidths,
+ baseMapping: LiberationSansRegularMapping,
+ metrics: MyriadProRegularMetrics
+ };
+ t["MyriadPro-Bold"] = t["PdfJS-Fallback-Bold"] = {
+ name: "LiberationSans-Bold",
+ factors: MyriadProBoldFactors,
+ baseWidths: LiberationSansBoldWidths,
+ baseMapping: LiberationSansBoldMapping,
+ metrics: MyriadProBoldMetrics
+ };
+ t["MyriadPro-It"] = t["MyriadPro-Italic"] = t["PdfJS-Fallback-Italic"] = {
+ name: "LiberationSans-Italic",
+ factors: MyriadProItalicFactors,
+ baseWidths: LiberationSansItalicWidths,
+ baseMapping: LiberationSansItalicMapping,
+ metrics: MyriadProItalicMetrics
+ };
+ t["MyriadPro-BoldIt"] = t["MyriadPro-BoldItalic"] = t["PdfJS-Fallback-BoldItalic"] = {
+ name: "LiberationSans-BoldItalic",
+ factors: MyriadProBoldItalicFactors,
+ baseWidths: LiberationSansBoldItalicWidths,
+ baseMapping: LiberationSansBoldItalicMapping,
+ metrics: MyriadProBoldItalicMetrics
+ };
+ t.ArialMT = t.Arial = t["Arial-Regular"] = {
+ name: "LiberationSans-Regular",
+ baseWidths: LiberationSansRegularWidths,
+ baseMapping: LiberationSansRegularMapping
+ };
+ t["Arial-BoldMT"] = t["Arial-Bold"] = {
+ name: "LiberationSans-Bold",
+ baseWidths: LiberationSansBoldWidths,
+ baseMapping: LiberationSansBoldMapping
+ };
+ t["Arial-ItalicMT"] = t["Arial-Italic"] = {
+ name: "LiberationSans-Italic",
+ baseWidths: LiberationSansItalicWidths,
+ baseMapping: LiberationSansItalicMapping
+ };
+ t["Arial-BoldItalicMT"] = t["Arial-BoldItalic"] = {
+ name: "LiberationSans-BoldItalic",
+ baseWidths: LiberationSansBoldItalicWidths,
+ baseMapping: LiberationSansBoldItalicMapping
+ };
+ t["Calibri-Regular"] = {
+ name: "LiberationSans-Regular",
+ factors: CalibriRegularFactors,
+ baseWidths: LiberationSansRegularWidths,
+ baseMapping: LiberationSansRegularMapping,
+ metrics: CalibriRegularMetrics
+ };
+ t["Calibri-Bold"] = {
+ name: "LiberationSans-Bold",
+ factors: CalibriBoldFactors,
+ baseWidths: LiberationSansBoldWidths,
+ baseMapping: LiberationSansBoldMapping,
+ metrics: CalibriBoldMetrics
+ };
+ t["Calibri-Italic"] = {
+ name: "LiberationSans-Italic",
+ factors: CalibriItalicFactors,
+ baseWidths: LiberationSansItalicWidths,
+ baseMapping: LiberationSansItalicMapping,
+ metrics: CalibriItalicMetrics
+ };
+ t["Calibri-BoldItalic"] = {
+ name: "LiberationSans-BoldItalic",
+ factors: CalibriBoldItalicFactors,
+ baseWidths: LiberationSansBoldItalicWidths,
+ baseMapping: LiberationSansBoldItalicMapping,
+ metrics: CalibriBoldItalicMetrics
+ };
+ t["Segoeui-Regular"] = {
+ name: "LiberationSans-Regular",
+ factors: SegoeuiRegularFactors,
+ baseWidths: LiberationSansRegularWidths,
+ baseMapping: LiberationSansRegularMapping,
+ metrics: SegoeuiRegularMetrics
+ };
+ t["Segoeui-Bold"] = {
+ name: "LiberationSans-Bold",
+ factors: SegoeuiBoldFactors,
+ baseWidths: LiberationSansBoldWidths,
+ baseMapping: LiberationSansBoldMapping,
+ metrics: SegoeuiBoldMetrics
+ };
+ t["Segoeui-Italic"] = {
+ name: "LiberationSans-Italic",
+ factors: SegoeuiItalicFactors,
+ baseWidths: LiberationSansItalicWidths,
+ baseMapping: LiberationSansItalicMapping,
+ metrics: SegoeuiItalicMetrics
+ };
+ t["Segoeui-BoldItalic"] = {
+ name: "LiberationSans-BoldItalic",
+ factors: SegoeuiBoldItalicFactors,
+ baseWidths: LiberationSansBoldItalicWidths,
+ baseMapping: LiberationSansBoldItalicMapping,
+ metrics: SegoeuiBoldItalicMetrics
+ };
+ t["Helvetica-Regular"] = t.Helvetica = {
+ name: "LiberationSans-Regular",
+ factors: HelveticaRegularFactors,
+ baseWidths: LiberationSansRegularWidths,
+ baseMapping: LiberationSansRegularMapping,
+ metrics: HelveticaRegularMetrics
+ };
+ t["Helvetica-Bold"] = {
+ name: "LiberationSans-Bold",
+ factors: HelveticaBoldFactors,
+ baseWidths: LiberationSansBoldWidths,
+ baseMapping: LiberationSansBoldMapping,
+ metrics: HelveticaBoldMetrics
+ };
+ t["Helvetica-Italic"] = {
+ name: "LiberationSans-Italic",
+ factors: HelveticaItalicFactors,
+ baseWidths: LiberationSansItalicWidths,
+ baseMapping: LiberationSansItalicMapping,
+ metrics: HelveticaItalicMetrics
+ };
+ t["Helvetica-BoldItalic"] = {
+ name: "LiberationSans-BoldItalic",
+ factors: HelveticaBoldItalicFactors,
+ baseWidths: LiberationSansBoldItalicWidths,
+ baseMapping: LiberationSansBoldItalicMapping,
+ metrics: HelveticaBoldItalicMetrics
+ };
+});
+function getXfaFontName(name) {
+ const fontName = normalizeFontName(name);
+ const fontMap = getXFAFontMap();
+ return fontMap[fontName];
+}
+function getXfaFontWidths(name) {
+ const info = getXfaFontName(name);
+ if (!info) {
+ return null;
+ }
+ const {
+ baseWidths,
+ baseMapping,
+ factors
+ } = info;
+ const rescaledBaseWidths = !factors ? baseWidths : baseWidths.map((w, i) => w * factors[i]);
+ let currentCode = -2;
+ let currentArray;
+ const newWidths = [];
+ for (const [unicode, glyphIndex] of baseMapping.map((charUnicode, index) => [charUnicode, index]).sort(([unicode1], [unicode2]) => unicode1 - unicode2)) {
+ if (unicode === -1) {
+ continue;
+ }
+ if (unicode === currentCode + 1) {
+ currentArray.push(rescaledBaseWidths[glyphIndex]);
+ currentCode += 1;
+ } else {
+ currentCode = unicode;
+ currentArray = [rescaledBaseWidths[glyphIndex]];
+ newWidths.push(unicode, currentArray);
+ }
+ }
+ return newWidths;
+}
+function getXfaFontDict(name) {
+ const widths = getXfaFontWidths(name);
+ const dict = new Dict(null);
+ dict.set("BaseFont", Name.get(name));
+ dict.set("Type", Name.get("Font"));
+ dict.set("Subtype", Name.get("CIDFontType2"));
+ dict.set("Encoding", Name.get("Identity-H"));
+ dict.set("CIDToGIDMap", Name.get("Identity"));
+ dict.set("W", widths);
+ dict.set("FirstChar", widths[0]);
+ dict.set("LastChar", widths.at(-2) + widths.at(-1).length - 1);
+ const descriptor = new Dict(null);
+ dict.set("FontDescriptor", descriptor);
+ const systemInfo = new Dict(null);
+ systemInfo.set("Ordering", "Identity");
+ systemInfo.set("Registry", "Adobe");
+ systemInfo.set("Supplement", 0);
+ dict.set("CIDSystemInfo", systemInfo);
+ return dict;
+}
+
+;// CONCATENATED MODULE: ./src/core/ps_parser.js
+
+
+
+class PostScriptParser {
+ constructor(lexer) {
+ this.lexer = lexer;
+ this.operators = [];
+ this.token = null;
+ this.prev = null;
+ }
+ nextToken() {
+ this.prev = this.token;
+ this.token = this.lexer.getToken();
+ }
+ accept(type) {
+ if (this.token.type === type) {
+ this.nextToken();
+ return true;
+ }
+ return false;
+ }
+ expect(type) {
+ if (this.accept(type)) {
+ return true;
+ }
+ throw new FormatError(`Unexpected symbol: found ${this.token.type} expected ${type}.`);
+ }
+ parse() {
+ this.nextToken();
+ this.expect(PostScriptTokenTypes.LBRACE);
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ return this.operators;
+ }
+ parseBlock() {
+ while (true) {
+ if (this.accept(PostScriptTokenTypes.NUMBER)) {
+ this.operators.push(this.prev.value);
+ } else if (this.accept(PostScriptTokenTypes.OPERATOR)) {
+ this.operators.push(this.prev.value);
+ } else if (this.accept(PostScriptTokenTypes.LBRACE)) {
+ this.parseCondition();
+ } else {
+ return;
+ }
+ }
+ }
+ parseCondition() {
+ const conditionLocation = this.operators.length;
+ this.operators.push(null, null);
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ if (this.accept(PostScriptTokenTypes.IF)) {
+ this.operators[conditionLocation] = this.operators.length;
+ this.operators[conditionLocation + 1] = "jz";
+ } else if (this.accept(PostScriptTokenTypes.LBRACE)) {
+ const jumpLocation = this.operators.length;
+ this.operators.push(null, null);
+ const endOfTrue = this.operators.length;
+ this.parseBlock();
+ this.expect(PostScriptTokenTypes.RBRACE);
+ this.expect(PostScriptTokenTypes.IFELSE);
+ this.operators[jumpLocation] = this.operators.length;
+ this.operators[jumpLocation + 1] = "j";
+ this.operators[conditionLocation] = endOfTrue;
+ this.operators[conditionLocation + 1] = "jz";
+ } else {
+ throw new FormatError("PS Function: error parsing conditional.");
+ }
+ }
+}
+const PostScriptTokenTypes = {
+ LBRACE: 0,
+ RBRACE: 1,
+ NUMBER: 2,
+ OPERATOR: 3,
+ IF: 4,
+ IFELSE: 5
+};
+class PostScriptToken {
+ static get opCache() {
+ return shadow(this, "opCache", Object.create(null));
+ }
+ constructor(type, value) {
+ this.type = type;
+ this.value = value;
+ }
+ static getOperator(op) {
+ return PostScriptToken.opCache[op] ||= new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);
+ }
+ static get LBRACE() {
+ return shadow(this, "LBRACE", new PostScriptToken(PostScriptTokenTypes.LBRACE, "{"));
+ }
+ static get RBRACE() {
+ return shadow(this, "RBRACE", new PostScriptToken(PostScriptTokenTypes.RBRACE, "}"));
+ }
+ static get IF() {
+ return shadow(this, "IF", new PostScriptToken(PostScriptTokenTypes.IF, "IF"));
+ }
+ static get IFELSE() {
+ return shadow(this, "IFELSE", new PostScriptToken(PostScriptTokenTypes.IFELSE, "IFELSE"));
+ }
+}
+class PostScriptLexer {
+ constructor(stream) {
+ this.stream = stream;
+ this.nextChar();
+ this.strBuf = [];
+ }
+ nextChar() {
+ return this.currentChar = this.stream.getByte();
+ }
+ getToken() {
+ let comment = false;
+ let ch = this.currentChar;
+ while (true) {
+ if (ch < 0) {
+ return EOF;
+ }
+ if (comment) {
+ if (ch === 0x0a || ch === 0x0d) {
+ comment = false;
+ }
+ } else if (ch === 0x25) {
+ comment = true;
+ } else if (!isWhiteSpace(ch)) {
+ break;
+ }
+ ch = this.nextChar();
+ }
+ switch (ch | 0) {
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ case 0x2b:
+ case 0x2d:
+ case 0x2e:
+ return new PostScriptToken(PostScriptTokenTypes.NUMBER, this.getNumber());
+ case 0x7b:
+ this.nextChar();
+ return PostScriptToken.LBRACE;
+ case 0x7d:
+ this.nextChar();
+ return PostScriptToken.RBRACE;
+ }
+ const strBuf = this.strBuf;
+ strBuf.length = 0;
+ strBuf[0] = String.fromCharCode(ch);
+ while ((ch = this.nextChar()) >= 0 && (ch >= 0x41 && ch <= 0x5a || ch >= 0x61 && ch <= 0x7a)) {
+ strBuf.push(String.fromCharCode(ch));
+ }
+ const str = strBuf.join("");
+ switch (str.toLowerCase()) {
+ case "if":
+ return PostScriptToken.IF;
+ case "ifelse":
+ return PostScriptToken.IFELSE;
+ default:
+ return PostScriptToken.getOperator(str);
+ }
+ }
+ getNumber() {
+ let ch = this.currentChar;
+ const strBuf = this.strBuf;
+ strBuf.length = 0;
+ strBuf[0] = String.fromCharCode(ch);
+ while ((ch = this.nextChar()) >= 0) {
+ if (ch >= 0x30 && ch <= 0x39 || ch === 0x2d || ch === 0x2e) {
+ strBuf.push(String.fromCharCode(ch));
+ } else {
+ break;
+ }
+ }
+ const value = parseFloat(strBuf.join(""));
+ if (isNaN(value)) {
+ throw new FormatError(`Invalid floating point number: ${value}`);
+ }
+ return value;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/image_utils.js
+
+
+class BaseLocalCache {
+ constructor(options) {
+ if (this.constructor === BaseLocalCache) {
+ unreachable("Cannot initialize BaseLocalCache.");
+ }
+ this._onlyRefs = options?.onlyRefs === true;
+ if (!this._onlyRefs) {
+ this._nameRefMap = new Map();
+ this._imageMap = new Map();
+ }
+ this._imageCache = new RefSetCache();
+ }
+ getByName(name) {
+ if (this._onlyRefs) {
+ unreachable("Should not call `getByName` method.");
+ }
+ const ref = this._nameRefMap.get(name);
+ if (ref) {
+ return this.getByRef(ref);
+ }
+ return this._imageMap.get(name) || null;
+ }
+ getByRef(ref) {
+ return this._imageCache.get(ref) || null;
+ }
+ set(name, ref, data) {
+ unreachable("Abstract method `set` called.");
+ }
+}
+class LocalImageCache extends BaseLocalCache {
+ set(name, ref = null, data) {
+ if (typeof name !== "string") {
+ throw new Error('LocalImageCache.set - expected "name" argument.');
+ }
+ if (ref) {
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ this._nameRefMap.set(name, ref);
+ this._imageCache.put(ref, data);
+ return;
+ }
+ if (this._imageMap.has(name)) {
+ return;
+ }
+ this._imageMap.set(name, data);
+ }
+}
+class LocalColorSpaceCache extends BaseLocalCache {
+ set(name = null, ref = null, data) {
+ if (typeof name !== "string" && !ref) {
+ throw new Error('LocalColorSpaceCache.set - expected "name" and/or "ref" argument.');
+ }
+ if (ref) {
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ if (name !== null) {
+ this._nameRefMap.set(name, ref);
+ }
+ this._imageCache.put(ref, data);
+ return;
+ }
+ if (this._imageMap.has(name)) {
+ return;
+ }
+ this._imageMap.set(name, data);
+ }
+}
+class LocalFunctionCache extends BaseLocalCache {
+ constructor(options) {
+ super({
+ onlyRefs: true
+ });
+ }
+ set(name = null, ref, data) {
+ if (!ref) {
+ throw new Error('LocalFunctionCache.set - expected "ref" argument.');
+ }
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ this._imageCache.put(ref, data);
+ }
+}
+class LocalGStateCache extends BaseLocalCache {
+ set(name, ref = null, data) {
+ if (typeof name !== "string") {
+ throw new Error('LocalGStateCache.set - expected "name" argument.');
+ }
+ if (ref) {
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ this._nameRefMap.set(name, ref);
+ this._imageCache.put(ref, data);
+ return;
+ }
+ if (this._imageMap.has(name)) {
+ return;
+ }
+ this._imageMap.set(name, data);
+ }
+}
+class LocalTilingPatternCache extends BaseLocalCache {
+ constructor(options) {
+ super({
+ onlyRefs: true
+ });
+ }
+ set(name = null, ref, data) {
+ if (!ref) {
+ throw new Error('LocalTilingPatternCache.set - expected "ref" argument.');
+ }
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ this._imageCache.put(ref, data);
+ }
+}
+class RegionalImageCache extends BaseLocalCache {
+ constructor(options) {
+ super({
+ onlyRefs: true
+ });
+ }
+ set(name = null, ref, data) {
+ if (!ref) {
+ throw new Error('RegionalImageCache.set - expected "ref" argument.');
+ }
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ this._imageCache.put(ref, data);
+ }
+}
+class GlobalImageCache {
+ static NUM_PAGES_THRESHOLD = 2;
+ static MIN_IMAGES_TO_CACHE = 10;
+ static MAX_BYTE_SIZE = 5 * MAX_IMAGE_SIZE_TO_CACHE;
+ constructor() {
+ this._refCache = new RefSetCache();
+ this._imageCache = new RefSetCache();
+ }
+ get _byteSize() {
+ let byteSize = 0;
+ for (const imageData of this._imageCache) {
+ byteSize += imageData.byteSize;
+ }
+ return byteSize;
+ }
+ get _cacheLimitReached() {
+ if (this._imageCache.size < GlobalImageCache.MIN_IMAGES_TO_CACHE) {
+ return false;
+ }
+ if (this._byteSize < GlobalImageCache.MAX_BYTE_SIZE) {
+ return false;
+ }
+ return true;
+ }
+ shouldCache(ref, pageIndex) {
+ let pageIndexSet = this._refCache.get(ref);
+ if (!pageIndexSet) {
+ pageIndexSet = new Set();
+ this._refCache.put(ref, pageIndexSet);
+ }
+ pageIndexSet.add(pageIndex);
+ if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) {
+ return false;
+ }
+ if (!this._imageCache.has(ref) && this._cacheLimitReached) {
+ return false;
+ }
+ return true;
+ }
+ addByteSize(ref, byteSize) {
+ const imageData = this._imageCache.get(ref);
+ if (!imageData) {
+ return;
+ }
+ if (imageData.byteSize) {
+ return;
+ }
+ imageData.byteSize = byteSize;
+ }
+ getData(ref, pageIndex) {
+ const pageIndexSet = this._refCache.get(ref);
+ if (!pageIndexSet) {
+ return null;
+ }
+ if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) {
+ return null;
+ }
+ const imageData = this._imageCache.get(ref);
+ if (!imageData) {
+ return null;
+ }
+ pageIndexSet.add(pageIndex);
+ return imageData;
+ }
+ setData(ref, data) {
+ if (!this._refCache.has(ref)) {
+ throw new Error('GlobalImageCache.setData - expected "shouldCache" to have been called.');
+ }
+ if (this._imageCache.has(ref)) {
+ return;
+ }
+ if (this._cacheLimitReached) {
+ warn("GlobalImageCache.setData - cache limit reached.");
+ return;
+ }
+ this._imageCache.put(ref, data);
+ }
+ clear(onlyData = false) {
+ if (!onlyData) {
+ this._refCache.clear();
+ }
+ this._imageCache.clear();
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/function.js
+
+
+
+
+
+class PDFFunctionFactory {
+ constructor({
+ xref,
+ isEvalSupported = true
+ }) {
+ this.xref = xref;
+ this.isEvalSupported = isEvalSupported !== false;
+ }
+ create(fn) {
+ const cachedFunction = this.getCached(fn);
+ if (cachedFunction) {
+ return cachedFunction;
+ }
+ const parsedFunction = PDFFunction.parse({
+ xref: this.xref,
+ isEvalSupported: this.isEvalSupported,
+ fn: fn instanceof Ref ? this.xref.fetch(fn) : fn
+ });
+ this._cache(fn, parsedFunction);
+ return parsedFunction;
+ }
+ createFromArray(fnObj) {
+ const cachedFunction = this.getCached(fnObj);
+ if (cachedFunction) {
+ return cachedFunction;
+ }
+ const parsedFunction = PDFFunction.parseArray({
+ xref: this.xref,
+ isEvalSupported: this.isEvalSupported,
+ fnObj: fnObj instanceof Ref ? this.xref.fetch(fnObj) : fnObj
+ });
+ this._cache(fnObj, parsedFunction);
+ return parsedFunction;
+ }
+ getCached(cacheKey) {
+ let fnRef;
+ if (cacheKey instanceof Ref) {
+ fnRef = cacheKey;
+ } else if (cacheKey instanceof Dict) {
+ fnRef = cacheKey.objId;
+ } else if (cacheKey instanceof BaseStream) {
+ fnRef = cacheKey.dict?.objId;
+ }
+ if (fnRef) {
+ const localFunction = this._localFunctionCache.getByRef(fnRef);
+ if (localFunction) {
+ return localFunction;
+ }
+ }
+ return null;
+ }
+ _cache(cacheKey, parsedFunction) {
+ if (!parsedFunction) {
+ throw new Error('PDFFunctionFactory._cache - expected "parsedFunction" argument.');
+ }
+ let fnRef;
+ if (cacheKey instanceof Ref) {
+ fnRef = cacheKey;
+ } else if (cacheKey instanceof Dict) {
+ fnRef = cacheKey.objId;
+ } else if (cacheKey instanceof BaseStream) {
+ fnRef = cacheKey.dict?.objId;
+ }
+ if (fnRef) {
+ this._localFunctionCache.set(null, fnRef, parsedFunction);
+ }
+ }
+ get _localFunctionCache() {
+ return shadow(this, "_localFunctionCache", new LocalFunctionCache());
+ }
+}
+function toNumberArray(arr) {
+ if (!Array.isArray(arr)) {
+ return null;
+ }
+ const length = arr.length;
+ for (let i = 0; i < length; i++) {
+ if (typeof arr[i] !== "number") {
+ const result = new Array(length);
+ for (let j = 0; j < length; j++) {
+ result[j] = +arr[j];
+ }
+ return result;
+ }
+ }
+ return arr;
+}
+class PDFFunction {
+ static getSampleArray(size, outputSize, bps, stream) {
+ let i, ii;
+ let length = 1;
+ for (i = 0, ii = size.length; i < ii; i++) {
+ length *= size[i];
+ }
+ length *= outputSize;
+ const array = new Array(length);
+ let codeSize = 0;
+ let codeBuf = 0;
+ const sampleMul = 1.0 / (2.0 ** bps - 1);
+ const strBytes = stream.getBytes((length * bps + 7) / 8);
+ let strIdx = 0;
+ for (i = 0; i < length; i++) {
+ while (codeSize < bps) {
+ codeBuf <<= 8;
+ codeBuf |= strBytes[strIdx++];
+ codeSize += 8;
+ }
+ codeSize -= bps;
+ array[i] = (codeBuf >> codeSize) * sampleMul;
+ codeBuf &= (1 << codeSize) - 1;
+ }
+ return array;
+ }
+ static parse({
+ xref,
+ isEvalSupported,
+ fn
+ }) {
+ const dict = fn.dict || fn;
+ const typeNum = dict.get("FunctionType");
+ switch (typeNum) {
+ case 0:
+ return this.constructSampled({
+ xref,
+ isEvalSupported,
+ fn,
+ dict
+ });
+ case 1:
+ break;
+ case 2:
+ return this.constructInterpolated({
+ xref,
+ isEvalSupported,
+ dict
+ });
+ case 3:
+ return this.constructStiched({
+ xref,
+ isEvalSupported,
+ dict
+ });
+ case 4:
+ return this.constructPostScript({
+ xref,
+ isEvalSupported,
+ fn,
+ dict
+ });
+ }
+ throw new FormatError("Unknown type of function");
+ }
+ static parseArray({
+ xref,
+ isEvalSupported,
+ fnObj
+ }) {
+ if (!Array.isArray(fnObj)) {
+ return this.parse({
+ xref,
+ isEvalSupported,
+ fn: fnObj
+ });
+ }
+ const fnArray = [];
+ for (const fn of fnObj) {
+ fnArray.push(this.parse({
+ xref,
+ isEvalSupported,
+ fn: xref.fetchIfRef(fn)
+ }));
+ }
+ return function (src, srcOffset, dest, destOffset) {
+ for (let i = 0, ii = fnArray.length; i < ii; i++) {
+ fnArray[i](src, srcOffset, dest, destOffset + i);
+ }
+ };
+ }
+ static constructSampled({
+ xref,
+ isEvalSupported,
+ fn,
+ dict
+ }) {
+ function toMultiArray(arr) {
+ const inputLength = arr.length;
+ const out = [];
+ let index = 0;
+ for (let i = 0; i < inputLength; i += 2) {
+ out[index++] = [arr[i], arr[i + 1]];
+ }
+ return out;
+ }
+ function interpolate(x, xmin, xmax, ymin, ymax) {
+ return ymin + (x - xmin) * ((ymax - ymin) / (xmax - xmin));
+ }
+ let domain = toNumberArray(dict.getArray("Domain"));
+ let range = toNumberArray(dict.getArray("Range"));
+ if (!domain || !range) {
+ throw new FormatError("No domain or range");
+ }
+ const inputSize = domain.length / 2;
+ const outputSize = range.length / 2;
+ domain = toMultiArray(domain);
+ range = toMultiArray(range);
+ const size = toNumberArray(dict.getArray("Size"));
+ const bps = dict.get("BitsPerSample");
+ const order = dict.get("Order") || 1;
+ if (order !== 1) {
+ info("No support for cubic spline interpolation: " + order);
+ }
+ let encode = toNumberArray(dict.getArray("Encode"));
+ if (!encode) {
+ encode = [];
+ for (let i = 0; i < inputSize; ++i) {
+ encode.push([0, size[i] - 1]);
+ }
+ } else {
+ encode = toMultiArray(encode);
+ }
+ let decode = toNumberArray(dict.getArray("Decode"));
+ decode = !decode ? range : toMultiArray(decode);
+ const samples = this.getSampleArray(size, outputSize, bps, fn);
+ return function constructSampledFn(src, srcOffset, dest, destOffset) {
+ const cubeVertices = 1 << inputSize;
+ const cubeN = new Float64Array(cubeVertices);
+ const cubeVertex = new Uint32Array(cubeVertices);
+ let i, j;
+ for (j = 0; j < cubeVertices; j++) {
+ cubeN[j] = 1;
+ }
+ let k = outputSize,
+ pos = 1;
+ for (i = 0; i < inputSize; ++i) {
+ const domain_2i = domain[i][0];
+ const domain_2i_1 = domain[i][1];
+ const xi = Math.min(Math.max(src[srcOffset + i], domain_2i), domain_2i_1);
+ let e = interpolate(xi, domain_2i, domain_2i_1, encode[i][0], encode[i][1]);
+ const size_i = size[i];
+ e = Math.min(Math.max(e, 0), size_i - 1);
+ const e0 = e < size_i - 1 ? Math.floor(e) : e - 1;
+ const n0 = e0 + 1 - e;
+ const n1 = e - e0;
+ const offset0 = e0 * k;
+ const offset1 = offset0 + k;
+ for (j = 0; j < cubeVertices; j++) {
+ if (j & pos) {
+ cubeN[j] *= n1;
+ cubeVertex[j] += offset1;
+ } else {
+ cubeN[j] *= n0;
+ cubeVertex[j] += offset0;
+ }
+ }
+ k *= size_i;
+ pos <<= 1;
+ }
+ for (j = 0; j < outputSize; ++j) {
+ let rj = 0;
+ for (i = 0; i < cubeVertices; i++) {
+ rj += samples[cubeVertex[i] + j] * cubeN[i];
+ }
+ rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
+ dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
+ }
+ };
+ }
+ static constructInterpolated({
+ xref,
+ isEvalSupported,
+ dict
+ }) {
+ const c0 = toNumberArray(dict.getArray("C0")) || [0];
+ const c1 = toNumberArray(dict.getArray("C1")) || [1];
+ const n = dict.get("N");
+ const diff = [];
+ for (let i = 0, ii = c0.length; i < ii; ++i) {
+ diff.push(c1[i] - c0[i]);
+ }
+ const length = diff.length;
+ return function constructInterpolatedFn(src, srcOffset, dest, destOffset) {
+ const x = n === 1 ? src[srcOffset] : src[srcOffset] ** n;
+ for (let j = 0; j < length; ++j) {
+ dest[destOffset + j] = c0[j] + x * diff[j];
+ }
+ };
+ }
+ static constructStiched({
+ xref,
+ isEvalSupported,
+ dict
+ }) {
+ const domain = toNumberArray(dict.getArray("Domain"));
+ if (!domain) {
+ throw new FormatError("No domain");
+ }
+ const inputSize = domain.length / 2;
+ if (inputSize !== 1) {
+ throw new FormatError("Bad domain for stiched function");
+ }
+ const fns = [];
+ for (const fn of dict.get("Functions")) {
+ fns.push(this.parse({
+ xref,
+ isEvalSupported,
+ fn: xref.fetchIfRef(fn)
+ }));
+ }
+ const bounds = toNumberArray(dict.getArray("Bounds"));
+ const encode = toNumberArray(dict.getArray("Encode"));
+ const tmpBuf = new Float32Array(1);
+ return function constructStichedFn(src, srcOffset, dest, destOffset) {
+ const clip = function constructStichedFromIRClip(v, min, max) {
+ if (v > max) {
+ v = max;
+ } else if (v < min) {
+ v = min;
+ }
+ return v;
+ };
+ const v = clip(src[srcOffset], domain[0], domain[1]);
+ const length = bounds.length;
+ let i;
+ for (i = 0; i < length; ++i) {
+ if (v < bounds[i]) {
+ break;
+ }
+ }
+ let dmin = domain[0];
+ if (i > 0) {
+ dmin = bounds[i - 1];
+ }
+ let dmax = domain[1];
+ if (i < bounds.length) {
+ dmax = bounds[i];
+ }
+ const rmin = encode[2 * i];
+ const rmax = encode[2 * i + 1];
+ tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);
+ fns[i](tmpBuf, 0, dest, destOffset);
+ };
+ }
+ static constructPostScript({
+ xref,
+ isEvalSupported,
+ fn,
+ dict
+ }) {
+ const domain = toNumberArray(dict.getArray("Domain"));
+ const range = toNumberArray(dict.getArray("Range"));
+ if (!domain) {
+ throw new FormatError("No domain.");
+ }
+ if (!range) {
+ throw new FormatError("No range.");
+ }
+ const lexer = new PostScriptLexer(fn);
+ const parser = new PostScriptParser(lexer);
+ const code = parser.parse();
+ if (isEvalSupported && FeatureTest.isEvalSupported) {
+ const compiled = new PostScriptCompiler().compile(code, domain, range);
+ if (compiled) {
+ return new Function("src", "srcOffset", "dest", "destOffset", compiled);
+ }
+ }
+ info("Unable to compile PS function");
+ const numOutputs = range.length >> 1;
+ const numInputs = domain.length >> 1;
+ const evaluator = new PostScriptEvaluator(code);
+ const cache = Object.create(null);
+ const MAX_CACHE_SIZE = 2048 * 4;
+ let cache_available = MAX_CACHE_SIZE;
+ const tmpBuf = new Float32Array(numInputs);
+ return function constructPostScriptFn(src, srcOffset, dest, destOffset) {
+ let i, value;
+ let key = "";
+ const input = tmpBuf;
+ for (i = 0; i < numInputs; i++) {
+ value = src[srcOffset + i];
+ input[i] = value;
+ key += value + "_";
+ }
+ const cachedValue = cache[key];
+ if (cachedValue !== undefined) {
+ dest.set(cachedValue, destOffset);
+ return;
+ }
+ const output = new Float32Array(numOutputs);
+ const stack = evaluator.execute(input);
+ const stackIndex = stack.length - numOutputs;
+ for (i = 0; i < numOutputs; i++) {
+ value = stack[stackIndex + i];
+ let bound = range[i * 2];
+ if (value < bound) {
+ value = bound;
+ } else {
+ bound = range[i * 2 + 1];
+ if (value > bound) {
+ value = bound;
+ }
+ }
+ output[i] = value;
+ }
+ if (cache_available > 0) {
+ cache_available--;
+ cache[key] = output;
+ }
+ dest.set(output, destOffset);
+ };
+ }
+}
+function isPDFFunction(v) {
+ let fnDict;
+ if (v instanceof Dict) {
+ fnDict = v;
+ } else if (v instanceof BaseStream) {
+ fnDict = v.dict;
+ } else {
+ return false;
+ }
+ return fnDict.has("FunctionType");
+}
+class PostScriptStack {
+ static MAX_STACK_SIZE = 100;
+ constructor(initialStack) {
+ this.stack = initialStack ? Array.from(initialStack) : [];
+ }
+ push(value) {
+ if (this.stack.length >= PostScriptStack.MAX_STACK_SIZE) {
+ throw new Error("PostScript function stack overflow.");
+ }
+ this.stack.push(value);
+ }
+ pop() {
+ if (this.stack.length <= 0) {
+ throw new Error("PostScript function stack underflow.");
+ }
+ return this.stack.pop();
+ }
+ copy(n) {
+ if (this.stack.length + n >= PostScriptStack.MAX_STACK_SIZE) {
+ throw new Error("PostScript function stack overflow.");
+ }
+ const stack = this.stack;
+ for (let i = stack.length - n, j = n - 1; j >= 0; j--, i++) {
+ stack.push(stack[i]);
+ }
+ }
+ index(n) {
+ this.push(this.stack[this.stack.length - n - 1]);
+ }
+ roll(n, p) {
+ const stack = this.stack;
+ const l = stack.length - n;
+ const r = stack.length - 1;
+ const c = l + (p - Math.floor(p / n) * n);
+ for (let i = l, j = r; i < j; i++, j--) {
+ const t = stack[i];
+ stack[i] = stack[j];
+ stack[j] = t;
+ }
+ for (let i = l, j = c - 1; i < j; i++, j--) {
+ const t = stack[i];
+ stack[i] = stack[j];
+ stack[j] = t;
+ }
+ for (let i = c, j = r; i < j; i++, j--) {
+ const t = stack[i];
+ stack[i] = stack[j];
+ stack[j] = t;
+ }
+ }
+}
+class PostScriptEvaluator {
+ constructor(operators) {
+ this.operators = operators;
+ }
+ execute(initialStack) {
+ const stack = new PostScriptStack(initialStack);
+ let counter = 0;
+ const operators = this.operators;
+ const length = operators.length;
+ let operator, a, b;
+ while (counter < length) {
+ operator = operators[counter++];
+ if (typeof operator === "number") {
+ stack.push(operator);
+ continue;
+ }
+ switch (operator) {
+ case "jz":
+ b = stack.pop();
+ a = stack.pop();
+ if (!a) {
+ counter = b;
+ }
+ break;
+ case "j":
+ a = stack.pop();
+ counter = a;
+ break;
+ case "abs":
+ a = stack.pop();
+ stack.push(Math.abs(a));
+ break;
+ case "add":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a + b);
+ break;
+ case "and":
+ b = stack.pop();
+ a = stack.pop();
+ if (typeof a === "boolean" && typeof b === "boolean") {
+ stack.push(a && b);
+ } else {
+ stack.push(a & b);
+ }
+ break;
+ case "atan":
+ b = stack.pop();
+ a = stack.pop();
+ a = Math.atan2(a, b) / Math.PI * 180;
+ if (a < 0) {
+ a += 360;
+ }
+ stack.push(a);
+ break;
+ case "bitshift":
+ b = stack.pop();
+ a = stack.pop();
+ if (a > 0) {
+ stack.push(a << b);
+ } else {
+ stack.push(a >> b);
+ }
+ break;
+ case "ceiling":
+ a = stack.pop();
+ stack.push(Math.ceil(a));
+ break;
+ case "copy":
+ a = stack.pop();
+ stack.copy(a);
+ break;
+ case "cos":
+ a = stack.pop();
+ stack.push(Math.cos(a % 360 / 180 * Math.PI));
+ break;
+ case "cvi":
+ a = stack.pop() | 0;
+ stack.push(a);
+ break;
+ case "cvr":
+ break;
+ case "div":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a / b);
+ break;
+ case "dup":
+ stack.copy(1);
+ break;
+ case "eq":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a === b);
+ break;
+ case "exch":
+ stack.roll(2, 1);
+ break;
+ case "exp":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a ** b);
+ break;
+ case "false":
+ stack.push(false);
+ break;
+ case "floor":
+ a = stack.pop();
+ stack.push(Math.floor(a));
+ break;
+ case "ge":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a >= b);
+ break;
+ case "gt":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a > b);
+ break;
+ case "idiv":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a / b | 0);
+ break;
+ case "index":
+ a = stack.pop();
+ stack.index(a);
+ break;
+ case "le":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a <= b);
+ break;
+ case "ln":
+ a = stack.pop();
+ stack.push(Math.log(a));
+ break;
+ case "log":
+ a = stack.pop();
+ stack.push(Math.log10(a));
+ break;
+ case "lt":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a < b);
+ break;
+ case "mod":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a % b);
+ break;
+ case "mul":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a * b);
+ break;
+ case "ne":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a !== b);
+ break;
+ case "neg":
+ a = stack.pop();
+ stack.push(-a);
+ break;
+ case "not":
+ a = stack.pop();
+ if (typeof a === "boolean") {
+ stack.push(!a);
+ } else {
+ stack.push(~a);
+ }
+ break;
+ case "or":
+ b = stack.pop();
+ a = stack.pop();
+ if (typeof a === "boolean" && typeof b === "boolean") {
+ stack.push(a || b);
+ } else {
+ stack.push(a | b);
+ }
+ break;
+ case "pop":
+ stack.pop();
+ break;
+ case "roll":
+ b = stack.pop();
+ a = stack.pop();
+ stack.roll(a, b);
+ break;
+ case "round":
+ a = stack.pop();
+ stack.push(Math.round(a));
+ break;
+ case "sin":
+ a = stack.pop();
+ stack.push(Math.sin(a % 360 / 180 * Math.PI));
+ break;
+ case "sqrt":
+ a = stack.pop();
+ stack.push(Math.sqrt(a));
+ break;
+ case "sub":
+ b = stack.pop();
+ a = stack.pop();
+ stack.push(a - b);
+ break;
+ case "true":
+ stack.push(true);
+ break;
+ case "truncate":
+ a = stack.pop();
+ a = a < 0 ? Math.ceil(a) : Math.floor(a);
+ stack.push(a);
+ break;
+ case "xor":
+ b = stack.pop();
+ a = stack.pop();
+ if (typeof a === "boolean" && typeof b === "boolean") {
+ stack.push(a !== b);
+ } else {
+ stack.push(a ^ b);
+ }
+ break;
+ default:
+ throw new FormatError(`Unknown operator ${operator}`);
+ }
+ }
+ return stack.stack;
+ }
+}
+class AstNode {
+ constructor(type) {
+ this.type = type;
+ }
+ visit(visitor) {
+ unreachable("abstract method");
+ }
+}
+class AstArgument extends AstNode {
+ constructor(index, min, max) {
+ super("args");
+ this.index = index;
+ this.min = min;
+ this.max = max;
+ }
+ visit(visitor) {
+ visitor.visitArgument(this);
+ }
+}
+class AstLiteral extends AstNode {
+ constructor(number) {
+ super("literal");
+ this.number = number;
+ this.min = number;
+ this.max = number;
+ }
+ visit(visitor) {
+ visitor.visitLiteral(this);
+ }
+}
+class AstBinaryOperation extends AstNode {
+ constructor(op, arg1, arg2, min, max) {
+ super("binary");
+ this.op = op;
+ this.arg1 = arg1;
+ this.arg2 = arg2;
+ this.min = min;
+ this.max = max;
+ }
+ visit(visitor) {
+ visitor.visitBinaryOperation(this);
+ }
+}
+class AstMin extends AstNode {
+ constructor(arg, max) {
+ super("max");
+ this.arg = arg;
+ this.min = arg.min;
+ this.max = max;
+ }
+ visit(visitor) {
+ visitor.visitMin(this);
+ }
+}
+class AstVariable extends AstNode {
+ constructor(index, min, max) {
+ super("var");
+ this.index = index;
+ this.min = min;
+ this.max = max;
+ }
+ visit(visitor) {
+ visitor.visitVariable(this);
+ }
+}
+class AstVariableDefinition extends AstNode {
+ constructor(variable, arg) {
+ super("definition");
+ this.variable = variable;
+ this.arg = arg;
+ }
+ visit(visitor) {
+ visitor.visitVariableDefinition(this);
+ }
+}
+class ExpressionBuilderVisitor {
+ constructor() {
+ this.parts = [];
+ }
+ visitArgument(arg) {
+ this.parts.push("Math.max(", arg.min, ", Math.min(", arg.max, ", src[srcOffset + ", arg.index, "]))");
+ }
+ visitVariable(variable) {
+ this.parts.push("v", variable.index);
+ }
+ visitLiteral(literal) {
+ this.parts.push(literal.number);
+ }
+ visitBinaryOperation(operation) {
+ this.parts.push("(");
+ operation.arg1.visit(this);
+ this.parts.push(" ", operation.op, " ");
+ operation.arg2.visit(this);
+ this.parts.push(")");
+ }
+ visitVariableDefinition(definition) {
+ this.parts.push("var ");
+ definition.variable.visit(this);
+ this.parts.push(" = ");
+ definition.arg.visit(this);
+ this.parts.push(";");
+ }
+ visitMin(max) {
+ this.parts.push("Math.min(");
+ max.arg.visit(this);
+ this.parts.push(", ", max.max, ")");
+ }
+ toString() {
+ return this.parts.join("");
+ }
+}
+function buildAddOperation(num1, num2) {
+ if (num2.type === "literal" && num2.number === 0) {
+ return num1;
+ }
+ if (num1.type === "literal" && num1.number === 0) {
+ return num2;
+ }
+ if (num2.type === "literal" && num1.type === "literal") {
+ return new AstLiteral(num1.number + num2.number);
+ }
+ return new AstBinaryOperation("+", num1, num2, num1.min + num2.min, num1.max + num2.max);
+}
+function buildMulOperation(num1, num2) {
+ if (num2.type === "literal") {
+ if (num2.number === 0) {
+ return new AstLiteral(0);
+ } else if (num2.number === 1) {
+ return num1;
+ } else if (num1.type === "literal") {
+ return new AstLiteral(num1.number * num2.number);
+ }
+ }
+ if (num1.type === "literal") {
+ if (num1.number === 0) {
+ return new AstLiteral(0);
+ } else if (num1.number === 1) {
+ return num2;
+ }
+ }
+ const min = Math.min(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
+ const max = Math.max(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
+ return new AstBinaryOperation("*", num1, num2, min, max);
+}
+function buildSubOperation(num1, num2) {
+ if (num2.type === "literal") {
+ if (num2.number === 0) {
+ return num1;
+ } else if (num1.type === "literal") {
+ return new AstLiteral(num1.number - num2.number);
+ }
+ }
+ if (num2.type === "binary" && num2.op === "-" && num1.type === "literal" && num1.number === 1 && num2.arg1.type === "literal" && num2.arg1.number === 1) {
+ return num2.arg2;
+ }
+ return new AstBinaryOperation("-", num1, num2, num1.min - num2.max, num1.max - num2.min);
+}
+function buildMinOperation(num1, max) {
+ if (num1.min >= max) {
+ return new AstLiteral(max);
+ } else if (num1.max <= max) {
+ return num1;
+ }
+ return new AstMin(num1, max);
+}
+class PostScriptCompiler {
+ compile(code, domain, range) {
+ const stack = [];
+ const instructions = [];
+ const inputSize = domain.length >> 1,
+ outputSize = range.length >> 1;
+ let lastRegister = 0;
+ let n, j;
+ let num1, num2, ast1, ast2, tmpVar, item;
+ for (let i = 0; i < inputSize; i++) {
+ stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1]));
+ }
+ for (let i = 0, ii = code.length; i < ii; i++) {
+ item = code[i];
+ if (typeof item === "number") {
+ stack.push(new AstLiteral(item));
+ continue;
+ }
+ switch (item) {
+ case "add":
+ if (stack.length < 2) {
+ return null;
+ }
+ num2 = stack.pop();
+ num1 = stack.pop();
+ stack.push(buildAddOperation(num1, num2));
+ break;
+ case "cvr":
+ if (stack.length < 1) {
+ return null;
+ }
+ break;
+ case "mul":
+ if (stack.length < 2) {
+ return null;
+ }
+ num2 = stack.pop();
+ num1 = stack.pop();
+ stack.push(buildMulOperation(num1, num2));
+ break;
+ case "sub":
+ if (stack.length < 2) {
+ return null;
+ }
+ num2 = stack.pop();
+ num1 = stack.pop();
+ stack.push(buildSubOperation(num1, num2));
+ break;
+ case "exch":
+ if (stack.length < 2) {
+ return null;
+ }
+ ast1 = stack.pop();
+ ast2 = stack.pop();
+ stack.push(ast1, ast2);
+ break;
+ case "pop":
+ if (stack.length < 1) {
+ return null;
+ }
+ stack.pop();
+ break;
+ case "index":
+ if (stack.length < 1) {
+ return null;
+ }
+ num1 = stack.pop();
+ if (num1.type !== "literal") {
+ return null;
+ }
+ n = num1.number;
+ if (n < 0 || !Number.isInteger(n) || stack.length < n) {
+ return null;
+ }
+ ast1 = stack[stack.length - n - 1];
+ if (ast1.type === "literal" || ast1.type === "var") {
+ stack.push(ast1);
+ break;
+ }
+ tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
+ stack[stack.length - n - 1] = tmpVar;
+ stack.push(tmpVar);
+ instructions.push(new AstVariableDefinition(tmpVar, ast1));
+ break;
+ case "dup":
+ if (stack.length < 1) {
+ return null;
+ }
+ if (typeof code[i + 1] === "number" && code[i + 2] === "gt" && code[i + 3] === i + 7 && code[i + 4] === "jz" && code[i + 5] === "pop" && code[i + 6] === code[i + 1]) {
+ num1 = stack.pop();
+ stack.push(buildMinOperation(num1, code[i + 1]));
+ i += 6;
+ break;
+ }
+ ast1 = stack.at(-1);
+ if (ast1.type === "literal" || ast1.type === "var") {
+ stack.push(ast1);
+ break;
+ }
+ tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
+ stack[stack.length - 1] = tmpVar;
+ stack.push(tmpVar);
+ instructions.push(new AstVariableDefinition(tmpVar, ast1));
+ break;
+ case "roll":
+ if (stack.length < 2) {
+ return null;
+ }
+ num2 = stack.pop();
+ num1 = stack.pop();
+ if (num2.type !== "literal" || num1.type !== "literal") {
+ return null;
+ }
+ j = num2.number;
+ n = num1.number;
+ if (n <= 0 || !Number.isInteger(n) || !Number.isInteger(j) || stack.length < n) {
+ return null;
+ }
+ j = (j % n + n) % n;
+ if (j === 0) {
+ break;
+ }
+ stack.push(...stack.splice(stack.length - n, n - j));
+ break;
+ default:
+ return null;
+ }
+ }
+ if (stack.length !== outputSize) {
+ return null;
+ }
+ const result = [];
+ for (const instruction of instructions) {
+ const statementBuilder = new ExpressionBuilderVisitor();
+ instruction.visit(statementBuilder);
+ result.push(statementBuilder.toString());
+ }
+ for (let i = 0, ii = stack.length; i < ii; i++) {
+ const expr = stack[i],
+ statementBuilder = new ExpressionBuilderVisitor();
+ expr.visit(statementBuilder);
+ const min = range[i * 2],
+ max = range[i * 2 + 1];
+ const out = [statementBuilder.toString()];
+ if (min > expr.min) {
+ out.unshift("Math.max(", min, ", ");
+ out.push(")");
+ }
+ if (max < expr.max) {
+ out.unshift("Math.min(", max, ", ");
+ out.push(")");
+ }
+ out.unshift("dest[destOffset + ", i, "] = ");
+ out.push(";");
+ result.push(out.join(""));
+ }
+ return result.join("\n");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/bidi.js
+
+const baseTypes = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "ON", "ON", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "ON", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "ON", "ET", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "L", "ON", "ON", "BN", "ON", "ON", "ET", "ET", "EN", "EN", "ON", "L", "ON", "ON", "ON", "EN", "L", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L"];
+const arabicTypes = ["AN", "AN", "AN", "AN", "AN", "AN", "ON", "ON", "AL", "ET", "ET", "AL", "CS", "AL", "ON", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "ON", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL"];
+function isOdd(i) {
+ return (i & 1) !== 0;
+}
+function isEven(i) {
+ return (i & 1) === 0;
+}
+function findUnequal(arr, start, value) {
+ let j, jj;
+ for (j = start, jj = arr.length; j < jj; ++j) {
+ if (arr[j] !== value) {
+ return j;
+ }
+ }
+ return j;
+}
+function setValues(arr, start, end, value) {
+ for (let j = start; j < end; ++j) {
+ arr[j] = value;
+ }
+}
+function reverseValues(arr, start, end) {
+ for (let i = start, j = end - 1; i < j; ++i, --j) {
+ const temp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = temp;
+ }
+}
+function createBidiText(str, isLTR, vertical = false) {
+ let dir = "ltr";
+ if (vertical) {
+ dir = "ttb";
+ } else if (!isLTR) {
+ dir = "rtl";
+ }
+ return {
+ str,
+ dir
+ };
+}
+const chars = [];
+const types = [];
+function bidi(str, startLevel = -1, vertical = false) {
+ let isLTR = true;
+ const strLength = str.length;
+ if (strLength === 0 || vertical) {
+ return createBidiText(str, isLTR, vertical);
+ }
+ chars.length = strLength;
+ types.length = strLength;
+ let numBidi = 0;
+ let i, ii;
+ for (i = 0; i < strLength; ++i) {
+ chars[i] = str.charAt(i);
+ const charCode = str.charCodeAt(i);
+ let charType = "L";
+ if (charCode <= 0x00ff) {
+ charType = baseTypes[charCode];
+ } else if (0x0590 <= charCode && charCode <= 0x05f4) {
+ charType = "R";
+ } else if (0x0600 <= charCode && charCode <= 0x06ff) {
+ charType = arabicTypes[charCode & 0xff];
+ if (!charType) {
+ warn("Bidi: invalid Unicode character " + charCode.toString(16));
+ }
+ } else if (0x0700 <= charCode && charCode <= 0x08ac || 0xfb50 <= charCode && charCode <= 0xfdff || 0xfe70 <= charCode && charCode <= 0xfeff) {
+ charType = "AL";
+ }
+ if (charType === "R" || charType === "AL" || charType === "AN") {
+ numBidi++;
+ }
+ types[i] = charType;
+ }
+ if (numBidi === 0) {
+ isLTR = true;
+ return createBidiText(str, isLTR);
+ }
+ if (startLevel === -1) {
+ if (numBidi / strLength < 0.3 && strLength > 4) {
+ isLTR = true;
+ startLevel = 0;
+ } else {
+ isLTR = false;
+ startLevel = 1;
+ }
+ }
+ const levels = [];
+ for (i = 0; i < strLength; ++i) {
+ levels[i] = startLevel;
+ }
+ const e = isOdd(startLevel) ? "R" : "L";
+ const sor = e;
+ const eor = sor;
+ let lastType = sor;
+ for (i = 0; i < strLength; ++i) {
+ if (types[i] === "NSM") {
+ types[i] = lastType;
+ } else {
+ lastType = types[i];
+ }
+ }
+ lastType = sor;
+ let t;
+ for (i = 0; i < strLength; ++i) {
+ t = types[i];
+ if (t === "EN") {
+ types[i] = lastType === "AL" ? "AN" : "EN";
+ } else if (t === "R" || t === "L" || t === "AL") {
+ lastType = t;
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ t = types[i];
+ if (t === "AL") {
+ types[i] = "R";
+ }
+ }
+ for (i = 1; i < strLength - 1; ++i) {
+ if (types[i] === "ES" && types[i - 1] === "EN" && types[i + 1] === "EN") {
+ types[i] = "EN";
+ }
+ if (types[i] === "CS" && (types[i - 1] === "EN" || types[i - 1] === "AN") && types[i + 1] === types[i - 1]) {
+ types[i] = types[i - 1];
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ if (types[i] === "EN") {
+ for (let j = i - 1; j >= 0; --j) {
+ if (types[j] !== "ET") {
+ break;
+ }
+ types[j] = "EN";
+ }
+ for (let j = i + 1; j < strLength; ++j) {
+ if (types[j] !== "ET") {
+ break;
+ }
+ types[j] = "EN";
+ }
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ t = types[i];
+ if (t === "WS" || t === "ES" || t === "ET" || t === "CS") {
+ types[i] = "ON";
+ }
+ }
+ lastType = sor;
+ for (i = 0; i < strLength; ++i) {
+ t = types[i];
+ if (t === "EN") {
+ types[i] = lastType === "L" ? "L" : "EN";
+ } else if (t === "R" || t === "L") {
+ lastType = t;
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ if (types[i] === "ON") {
+ const end = findUnequal(types, i + 1, "ON");
+ let before = sor;
+ if (i > 0) {
+ before = types[i - 1];
+ }
+ let after = eor;
+ if (end + 1 < strLength) {
+ after = types[end + 1];
+ }
+ if (before !== "L") {
+ before = "R";
+ }
+ if (after !== "L") {
+ after = "R";
+ }
+ if (before === after) {
+ setValues(types, i, end, before);
+ }
+ i = end - 1;
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ if (types[i] === "ON") {
+ types[i] = e;
+ }
+ }
+ for (i = 0; i < strLength; ++i) {
+ t = types[i];
+ if (isEven(levels[i])) {
+ if (t === "R") {
+ levels[i] += 1;
+ } else if (t === "AN" || t === "EN") {
+ levels[i] += 2;
+ }
+ } else if (t === "L" || t === "AN" || t === "EN") {
+ levels[i] += 1;
+ }
+ }
+ let highestLevel = -1;
+ let lowestOddLevel = 99;
+ let level;
+ for (i = 0, ii = levels.length; i < ii; ++i) {
+ level = levels[i];
+ if (highestLevel < level) {
+ highestLevel = level;
+ }
+ if (lowestOddLevel > level && isOdd(level)) {
+ lowestOddLevel = level;
+ }
+ }
+ for (level = highestLevel; level >= lowestOddLevel; --level) {
+ let start = -1;
+ for (i = 0, ii = levels.length; i < ii; ++i) {
+ if (levels[i] < level) {
+ if (start >= 0) {
+ reverseValues(chars, start, i);
+ start = -1;
+ }
+ } else if (start < 0) {
+ start = i;
+ }
+ }
+ if (start >= 0) {
+ reverseValues(chars, start, levels.length);
+ }
+ }
+ for (i = 0, ii = chars.length; i < ii; ++i) {
+ const ch = chars[i];
+ if (ch === "<" || ch === ">") {
+ chars[i] = "";
+ }
+ }
+ return createBidiText(chars.join(""), isLTR);
+}
+
+;// CONCATENATED MODULE: ./src/core/font_substitutions.js
+
+
+const NORMAL = {
+ style: "normal",
+ weight: "normal"
+};
+const BOLD = {
+ style: "normal",
+ weight: "bold"
+};
+const ITALIC = {
+ style: "italic",
+ weight: "normal"
+};
+const BOLDITALIC = {
+ style: "italic",
+ weight: "bold"
+};
+const substitutionMap = new Map([["Times-Roman", {
+ local: ["Times New Roman", "Times-Roman", "Times", "Liberation Serif", "Nimbus Roman", "Nimbus Roman L", "Tinos", "Thorndale", "TeX Gyre Termes", "FreeSerif", "DejaVu Serif", "Bitstream Vera Serif", "Ubuntu"],
+ style: NORMAL,
+ ultimate: "serif"
+}], ["Times-Bold", {
+ alias: "Times-Roman",
+ style: BOLD,
+ ultimate: "serif"
+}], ["Times-Italic", {
+ alias: "Times-Roman",
+ style: ITALIC,
+ ultimate: "serif"
+}], ["Times-BoldItalic", {
+ alias: "Times-Roman",
+ style: BOLDITALIC,
+ ultimate: "serif"
+}], ["Helvetica", {
+ local: ["Helvetica", "Helvetica Neue", "Arial", "Arial Nova", "Liberation Sans", "Arimo", "Nimbus Sans", "Nimbus Sans L", "A030", "TeX Gyre Heros", "FreeSans", "DejaVu Sans", "Albany", "Bitstream Vera Sans", "Arial Unicode MS", "Microsoft Sans Serif", "Apple Symbols", "Cantarell"],
+ path: "LiberationSans-Regular.ttf",
+ style: NORMAL,
+ ultimate: "sans-serif"
+}], ["Helvetica-Bold", {
+ alias: "Helvetica",
+ path: "LiberationSans-Bold.ttf",
+ style: BOLD,
+ ultimate: "sans-serif"
+}], ["Helvetica-Oblique", {
+ alias: "Helvetica",
+ path: "LiberationSans-Italic.ttf",
+ style: ITALIC,
+ ultimate: "sans-serif"
+}], ["Helvetica-BoldOblique", {
+ alias: "Helvetica",
+ path: "LiberationSans-BoldItalic.ttf",
+ style: BOLDITALIC,
+ ultimate: "sans-serif"
+}], ["Courier", {
+ local: ["Courier", "Courier New", "Liberation Mono", "Nimbus Mono", "Nimbus Mono L", "Cousine", "Cumberland", "TeX Gyre Cursor", "FreeMono"],
+ style: NORMAL,
+ ultimate: "monospace"
+}], ["Courier-Bold", {
+ alias: "Courier",
+ style: BOLD,
+ ultimate: "monospace"
+}], ["Courier-Oblique", {
+ alias: "Courier",
+ style: ITALIC,
+ ultimate: "monospace"
+}], ["Courier-BoldOblique", {
+ alias: "Courier",
+ style: BOLDITALIC,
+ ultimate: "monospace"
+}], ["ArialBlack", {
+ local: ["Arial Black"],
+ style: {
+ style: "normal",
+ weight: "900"
+ },
+ fallback: "Helvetica-Bold"
+}], ["ArialBlack-Bold", {
+ alias: "ArialBlack"
+}], ["ArialBlack-Italic", {
+ alias: "ArialBlack",
+ style: {
+ style: "italic",
+ weight: "900"
+ },
+ fallback: "Helvetica-BoldOblique"
+}], ["ArialBlack-BoldItalic", {
+ alias: "ArialBlack-Italic"
+}], ["ArialNarrow", {
+ local: ["Arial Narrow", "Liberation Sans Narrow", "Helvetica Condensed", "Nimbus Sans Narrow", "TeX Gyre Heros Cn"],
+ style: NORMAL,
+ fallback: "Helvetica"
+}], ["ArialNarrow-Bold", {
+ alias: "ArialNarrow",
+ style: BOLD,
+ fallback: "Helvetica-Bold"
+}], ["ArialNarrow-Italic", {
+ alias: "ArialNarrow",
+ style: ITALIC,
+ fallback: "Helvetica-Oblique"
+}], ["ArialNarrow-BoldItalic", {
+ alias: "ArialNarrow",
+ style: BOLDITALIC,
+ fallback: "Helvetica-BoldOblique"
+}], ["Calibri", {
+ local: ["Calibri", "Carlito"],
+ style: NORMAL,
+ fallback: "Helvetica"
+}], ["Calibri-Bold", {
+ alias: "Calibri",
+ style: BOLD,
+ fallback: "Helvetica-Bold"
+}], ["Calibri-Italic", {
+ alias: "Calibri",
+ style: ITALIC,
+ fallback: "Helvetica-Oblique"
+}], ["Calibri-BoldItalic", {
+ alias: "Calibri",
+ style: BOLDITALIC,
+ fallback: "Helvetica-BoldOblique"
+}], ["Wingdings", {
+ local: ["Wingdings", "URW Dingbats"],
+ style: NORMAL
+}], ["Wingdings-Regular", {
+ alias: "Wingdings"
+}], ["Wingdings-Bold", {
+ alias: "Wingdings"
+}]]);
+const fontAliases = new Map([["Arial-Black", "ArialBlack"]]);
+function getStyleToAppend(style) {
+ switch (style) {
+ case BOLD:
+ return "Bold";
+ case ITALIC:
+ return "Italic";
+ case BOLDITALIC:
+ return "Bold Italic";
+ default:
+ if (style?.weight === "bold") {
+ return "Bold";
+ }
+ if (style?.style === "italic") {
+ return "Italic";
+ }
+ }
+ return "";
+}
+function generateFont({
+ alias,
+ local,
+ path,
+ fallback,
+ style,
+ ultimate
+}, src, localFontPath, useFallback = true, usePath = true, append = "") {
+ const result = {
+ style: null,
+ ultimate: null
+ };
+ if (local) {
+ const extra = append ? ` ${append}` : "";
+ for (const name of local) {
+ src.push(`local(${name}${extra})`);
+ }
+ }
+ if (alias) {
+ const substitution = substitutionMap.get(alias);
+ const aliasAppend = append || getStyleToAppend(style);
+ Object.assign(result, generateFont(substitution, src, localFontPath, useFallback && !fallback, usePath && !path, aliasAppend));
+ }
+ if (style) {
+ result.style = style;
+ }
+ if (ultimate) {
+ result.ultimate = ultimate;
+ }
+ if (useFallback && fallback) {
+ const fallbackInfo = substitutionMap.get(fallback);
+ const {
+ ultimate: fallbackUltimate
+ } = generateFont(fallbackInfo, src, localFontPath, useFallback, usePath && !path, append);
+ result.ultimate ||= fallbackUltimate;
+ }
+ if (usePath && path && localFontPath) {
+ src.push(`url(${localFontPath}${path})`);
+ }
+ return result;
+}
+function getFontSubstitution(systemFontCache, idFactory, localFontPath, baseFontName, standardFontName) {
+ if (baseFontName.startsWith("InvalidPDFjsFont_")) {
+ return null;
+ }
+ baseFontName = normalizeFontName(baseFontName);
+ const key = baseFontName;
+ let substitutionInfo = systemFontCache.get(key);
+ if (substitutionInfo) {
+ return substitutionInfo;
+ }
+ let substitution = substitutionMap.get(baseFontName);
+ if (!substitution) {
+ for (const [alias, subst] of fontAliases) {
+ if (baseFontName.startsWith(alias)) {
+ baseFontName = `${subst}${baseFontName.substring(alias.length)}`;
+ substitution = substitutionMap.get(baseFontName);
+ break;
+ }
+ }
+ }
+ let mustAddBaseFont = false;
+ if (!substitution) {
+ substitution = substitutionMap.get(standardFontName);
+ mustAddBaseFont = true;
+ }
+ const loadedName = `${idFactory.getDocId()}_s${idFactory.createFontId()}`;
+ if (!substitution) {
+ if (!validateFontName(baseFontName)) {
+ systemFontCache.set(key, null);
+ return null;
+ }
+ const bold = /bold/gi.test(baseFontName);
+ const italic = /oblique|italic/gi.test(baseFontName);
+ const style = bold && italic && BOLDITALIC || bold && BOLD || italic && ITALIC || NORMAL;
+ substitutionInfo = {
+ css: loadedName,
+ guessFallback: true,
+ loadedName,
+ baseFontName,
+ src: `local(${baseFontName})`,
+ style
+ };
+ systemFontCache.set(key, substitutionInfo);
+ return substitutionInfo;
+ }
+ const src = [];
+ if (mustAddBaseFont && validateFontName(baseFontName)) {
+ src.push(`local(${baseFontName})`);
+ }
+ const {
+ style,
+ ultimate
+ } = generateFont(substitution, src, localFontPath);
+ const guessFallback = ultimate === null;
+ const fallback = guessFallback ? "" : `,${ultimate}`;
+ substitutionInfo = {
+ css: `${loadedName}${fallback}`,
+ guessFallback,
+ loadedName,
+ baseFontName,
+ src: src.join(","),
+ style
+ };
+ systemFontCache.set(key, substitutionInfo);
+ return substitutionInfo;
+}
+
+;// CONCATENATED MODULE: ./src/core/image_resizer.js
+
+const MIN_IMAGE_DIM = 2048;
+const MAX_IMAGE_DIM = 65537;
+const MAX_ERROR = 128;
+class ImageResizer {
+ constructor(imgData, isMask) {
+ this._imgData = imgData;
+ this._isMask = isMask;
+ }
+ static needsToBeResized(width, height) {
+ if (width <= this._goodSquareLength && height <= this._goodSquareLength) {
+ return false;
+ }
+ const {
+ MAX_DIM
+ } = this;
+ if (width > MAX_DIM || height > MAX_DIM) {
+ return true;
+ }
+ const area = width * height;
+ if (this._hasMaxArea) {
+ return area > this.MAX_AREA;
+ }
+ if (area < this._goodSquareLength ** 2) {
+ return false;
+ }
+ if (this._areGoodDims(width, height)) {
+ this._goodSquareLength = Math.max(this._goodSquareLength, Math.floor(Math.sqrt(width * height)));
+ return false;
+ }
+ this._goodSquareLength = this._guessMax(this._goodSquareLength, MAX_DIM, MAX_ERROR, 0);
+ const maxArea = this.MAX_AREA = this._goodSquareLength ** 2;
+ return area > maxArea;
+ }
+ static get MAX_DIM() {
+ return shadow(this, "MAX_DIM", this._guessMax(MIN_IMAGE_DIM, MAX_IMAGE_DIM, 0, 1));
+ }
+ static get MAX_AREA() {
+ this._hasMaxArea = true;
+ return shadow(this, "MAX_AREA", this._guessMax(ImageResizer._goodSquareLength, this.MAX_DIM, MAX_ERROR, 0) ** 2);
+ }
+ static set MAX_AREA(area) {
+ if (area >= 0) {
+ this._hasMaxArea = true;
+ shadow(this, "MAX_AREA", area);
+ }
+ }
+ static setMaxArea(area) {
+ if (!this._hasMaxArea) {
+ this.MAX_AREA = area >> 2;
+ }
+ }
+ static _areGoodDims(width, height) {
+ try {
+ const canvas = new OffscreenCanvas(width, height);
+ const ctx = canvas.getContext("2d");
+ ctx.fillRect(0, 0, 1, 1);
+ const opacity = ctx.getImageData(0, 0, 1, 1).data[3];
+ canvas.width = canvas.height = 1;
+ return opacity !== 0;
+ } catch {
+ return false;
+ }
+ }
+ static _guessMax(start, end, tolerance, defaultHeight) {
+ while (start + tolerance + 1 < end) {
+ const middle = Math.floor((start + end) / 2);
+ const height = defaultHeight || middle;
+ if (this._areGoodDims(middle, height)) {
+ start = middle;
+ } else {
+ end = middle;
+ }
+ }
+ return start;
+ }
+ static async createImage(imgData, isMask = false) {
+ return new ImageResizer(imgData, isMask)._createImage();
+ }
+ async _createImage() {
+ const data = this._encodeBMP();
+ const blob = new Blob([data.buffer], {
+ type: "image/bmp"
+ });
+ const bitmapPromise = createImageBitmap(blob);
+ const {
+ MAX_AREA,
+ MAX_DIM
+ } = ImageResizer;
+ const {
+ _imgData: imgData
+ } = this;
+ const {
+ width,
+ height
+ } = imgData;
+ const minFactor = Math.max(width / MAX_DIM, height / MAX_DIM, Math.sqrt(width * height / MAX_AREA));
+ const firstFactor = Math.max(minFactor, 2);
+ const factor = Math.round(10 * (minFactor + 1.25)) / 10 / firstFactor;
+ const N = Math.floor(Math.log2(factor));
+ const steps = new Array(N + 2).fill(2);
+ steps[0] = firstFactor;
+ steps.splice(-1, 1, factor / (1 << N));
+ let newWidth = width;
+ let newHeight = height;
+ let bitmap = await bitmapPromise;
+ for (const step of steps) {
+ const prevWidth = newWidth;
+ const prevHeight = newHeight;
+ newWidth = Math.floor(newWidth / step) - 1;
+ newHeight = Math.floor(newHeight / step) - 1;
+ const canvas = new OffscreenCanvas(newWidth, newHeight);
+ const ctx = canvas.getContext("2d");
+ ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
+ bitmap = canvas.transferToImageBitmap();
+ }
+ imgData.data = null;
+ imgData.bitmap = bitmap;
+ imgData.width = newWidth;
+ imgData.height = newHeight;
+ return imgData;
+ }
+ _encodeBMP() {
+ const {
+ width,
+ height,
+ kind
+ } = this._imgData;
+ let data = this._imgData.data;
+ let bitPerPixel;
+ let colorTable = new Uint8Array(0);
+ let maskTable = colorTable;
+ let compression = 0;
+ switch (kind) {
+ case ImageKind.GRAYSCALE_1BPP:
+ {
+ bitPerPixel = 1;
+ colorTable = new Uint8Array(this._isMask ? [255, 255, 255, 255, 0, 0, 0, 0] : [0, 0, 0, 0, 255, 255, 255, 255]);
+ const rowLen = width + 7 >> 3;
+ const rowSize = rowLen + 3 & -4;
+ if (rowLen !== rowSize) {
+ const newData = new Uint8Array(rowSize * height);
+ let k = 0;
+ for (let i = 0, ii = height * rowLen; i < ii; i += rowLen, k += rowSize) {
+ newData.set(data.subarray(i, i + rowLen), k);
+ }
+ data = newData;
+ }
+ break;
+ }
+ case ImageKind.RGB_24BPP:
+ {
+ bitPerPixel = 24;
+ if (width & 3) {
+ const rowLen = 3 * width;
+ const rowSize = rowLen + 3 & -4;
+ const extraLen = rowSize - rowLen;
+ const newData = new Uint8Array(rowSize * height);
+ let k = 0;
+ for (let i = 0, ii = height * rowLen; i < ii; i += rowLen) {
+ const row = data.subarray(i, i + rowLen);
+ for (let j = 0; j < rowLen; j += 3) {
+ newData[k++] = row[j + 2];
+ newData[k++] = row[j + 1];
+ newData[k++] = row[j];
+ }
+ k += extraLen;
+ }
+ data = newData;
+ } else {
+ for (let i = 0, ii = data.length; i < ii; i += 3) {
+ const tmp = data[i];
+ data[i] = data[i + 2];
+ data[i + 2] = tmp;
+ }
+ }
+ break;
+ }
+ case ImageKind.RGBA_32BPP:
+ bitPerPixel = 32;
+ compression = 3;
+ maskTable = new Uint8Array(4 + 4 + 4 + 4 + 52);
+ const view = new DataView(maskTable.buffer);
+ if (FeatureTest.isLittleEndian) {
+ view.setUint32(0, 0x000000ff, true);
+ view.setUint32(4, 0x0000ff00, true);
+ view.setUint32(8, 0x00ff0000, true);
+ view.setUint32(12, 0xff000000, true);
+ } else {
+ view.setUint32(0, 0xff000000, true);
+ view.setUint32(4, 0x00ff0000, true);
+ view.setUint32(8, 0x0000ff00, true);
+ view.setUint32(12, 0x000000ff, true);
+ }
+ break;
+ default:
+ throw new Error("invalid format");
+ }
+ let i = 0;
+ const headerLength = 40 + maskTable.length;
+ const fileLength = 14 + headerLength + colorTable.length + data.length;
+ const bmpData = new Uint8Array(fileLength);
+ const view = new DataView(bmpData.buffer);
+ view.setUint16(i, 0x4d42, true);
+ i += 2;
+ view.setUint32(i, fileLength, true);
+ i += 4;
+ view.setUint32(i, 0, true);
+ i += 4;
+ view.setUint32(i, 14 + headerLength + colorTable.length, true);
+ i += 4;
+ view.setUint32(i, headerLength, true);
+ i += 4;
+ view.setInt32(i, width, true);
+ i += 4;
+ view.setInt32(i, -height, true);
+ i += 4;
+ view.setUint16(i, 1, true);
+ i += 2;
+ view.setUint16(i, bitPerPixel, true);
+ i += 2;
+ view.setUint32(i, compression, true);
+ i += 4;
+ view.setUint32(i, 0, true);
+ i += 4;
+ view.setInt32(i, 0, true);
+ i += 4;
+ view.setInt32(i, 0, true);
+ i += 4;
+ view.setUint32(i, colorTable.length / 4, true);
+ i += 4;
+ view.setUint32(i, 0, true);
+ i += 4;
+ bmpData.set(maskTable, i);
+ i += maskTable.length;
+ bmpData.set(colorTable, i);
+ i += colorTable.length;
+ bmpData.set(data, i);
+ return bmpData;
+ }
+}
+ImageResizer._goodSquareLength = MIN_IMAGE_DIM;
+
+;// CONCATENATED MODULE: ./src/shared/murmurhash3.js
+
+const SEED = 0xc3d2e1f0;
+const MASK_HIGH = 0xffff0000;
+const MASK_LOW = 0xffff;
+class MurmurHash3_64 {
+ constructor(seed) {
+ this.h1 = seed ? seed & 0xffffffff : SEED;
+ this.h2 = seed ? seed & 0xffffffff : SEED;
+ }
+ update(input) {
+ let data, length;
+ if (typeof input === "string") {
+ data = new Uint8Array(input.length * 2);
+ length = 0;
+ for (let i = 0, ii = input.length; i < ii; i++) {
+ const code = input.charCodeAt(i);
+ if (code <= 0xff) {
+ data[length++] = code;
+ } else {
+ data[length++] = code >>> 8;
+ data[length++] = code & 0xff;
+ }
+ }
+ } else if (isArrayBuffer(input)) {
+ data = input.slice();
+ length = data.byteLength;
+ } else {
+ throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array.");
+ }
+ const blockCounts = length >> 2;
+ const tailLength = length - blockCounts * 4;
+ const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);
+ let k1 = 0,
+ k2 = 0;
+ let h1 = this.h1,
+ h2 = this.h2;
+ const C1 = 0xcc9e2d51,
+ C2 = 0x1b873593;
+ const C1_LOW = C1 & MASK_LOW,
+ C2_LOW = C2 & MASK_LOW;
+ for (let i = 0; i < blockCounts; i++) {
+ if (i & 1) {
+ k1 = dataUint32[i];
+ k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;
+ k1 = k1 << 15 | k1 >>> 17;
+ k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;
+ h1 ^= k1;
+ h1 = h1 << 13 | h1 >>> 19;
+ h1 = h1 * 5 + 0xe6546b64;
+ } else {
+ k2 = dataUint32[i];
+ k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW;
+ k2 = k2 << 15 | k2 >>> 17;
+ k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW;
+ h2 ^= k2;
+ h2 = h2 << 13 | h2 >>> 19;
+ h2 = h2 * 5 + 0xe6546b64;
+ }
+ }
+ k1 = 0;
+ switch (tailLength) {
+ case 3:
+ k1 ^= data[blockCounts * 4 + 2] << 16;
+ case 2:
+ k1 ^= data[blockCounts * 4 + 1] << 8;
+ case 1:
+ k1 ^= data[blockCounts * 4];
+ k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;
+ k1 = k1 << 15 | k1 >>> 17;
+ k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;
+ if (blockCounts & 1) {
+ h1 ^= k1;
+ } else {
+ h2 ^= k1;
+ }
+ }
+ this.h1 = h1;
+ this.h2 = h2;
+ }
+ hexdigest() {
+ let h1 = this.h1,
+ h2 = this.h2;
+ h1 ^= h2 >>> 1;
+ h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW;
+ h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16;
+ h1 ^= h2 >>> 1;
+ h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;
+ h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;
+ h1 ^= h2 >>> 1;
+ return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/operator_list.js
+
+function addState(parentState, pattern, checkFn, iterateFn, processFn) {
+ let state = parentState;
+ for (let i = 0, ii = pattern.length - 1; i < ii; i++) {
+ const item = pattern[i];
+ state = state[item] ||= [];
+ }
+ state[pattern.at(-1)] = {
+ checkFn,
+ iterateFn,
+ processFn
+ };
+}
+const InitialState = [];
+addState(InitialState, [OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore], null, function iterateInlineImageGroup(context, i) {
+ const fnArray = context.fnArray;
+ const iFirstSave = context.iCurr - 3;
+ const pos = (i - iFirstSave) % 4;
+ switch (pos) {
+ case 0:
+ return fnArray[i] === OPS.save;
+ case 1:
+ return fnArray[i] === OPS.transform;
+ case 2:
+ return fnArray[i] === OPS.paintInlineImageXObject;
+ case 3:
+ return fnArray[i] === OPS.restore;
+ }
+ throw new Error(`iterateInlineImageGroup - invalid pos: ${pos}`);
+}, function foundInlineImageGroup(context, i) {
+ const MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
+ const MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
+ const MAX_WIDTH = 1000;
+ const IMAGE_PADDING = 1;
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const curr = context.iCurr;
+ const iFirstSave = curr - 3;
+ const iFirstTransform = curr - 2;
+ const iFirstPIIXO = curr - 1;
+ const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
+ if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
+ return i - (i - iFirstSave) % 4;
+ }
+ let maxX = 0;
+ const map = [];
+ let maxLineHeight = 0;
+ let currentX = IMAGE_PADDING,
+ currentY = IMAGE_PADDING;
+ for (let q = 0; q < count; q++) {
+ const transform = argsArray[iFirstTransform + (q << 2)];
+ const img = argsArray[iFirstPIIXO + (q << 2)][0];
+ if (currentX + img.width > MAX_WIDTH) {
+ maxX = Math.max(maxX, currentX);
+ currentY += maxLineHeight + 2 * IMAGE_PADDING;
+ currentX = 0;
+ maxLineHeight = 0;
+ }
+ map.push({
+ transform,
+ x: currentX,
+ y: currentY,
+ w: img.width,
+ h: img.height
+ });
+ currentX += img.width + 2 * IMAGE_PADDING;
+ maxLineHeight = Math.max(maxLineHeight, img.height);
+ }
+ const imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
+ const imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
+ const imgData = new Uint8Array(imgWidth * imgHeight * 4);
+ const imgRowSize = imgWidth << 2;
+ for (let q = 0; q < count; q++) {
+ const data = argsArray[iFirstPIIXO + (q << 2)][0].data;
+ const rowSize = map[q].w << 2;
+ let dataOffset = 0;
+ let offset = map[q].x + map[q].y * imgWidth << 2;
+ imgData.set(data.subarray(0, rowSize), offset - imgRowSize);
+ for (let k = 0, kk = map[q].h; k < kk; k++) {
+ imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset);
+ dataOffset += rowSize;
+ offset += imgRowSize;
+ }
+ imgData.set(data.subarray(dataOffset - rowSize, dataOffset), offset);
+ while (offset >= 0) {
+ data[offset - 4] = data[offset];
+ data[offset - 3] = data[offset + 1];
+ data[offset - 2] = data[offset + 2];
+ data[offset - 1] = data[offset + 3];
+ data[offset + rowSize] = data[offset + rowSize - 4];
+ data[offset + rowSize + 1] = data[offset + rowSize - 3];
+ data[offset + rowSize + 2] = data[offset + rowSize - 2];
+ data[offset + rowSize + 3] = data[offset + rowSize - 1];
+ offset -= imgRowSize;
+ }
+ }
+ const img = {
+ width: imgWidth,
+ height: imgHeight
+ };
+ if (context.isOffscreenCanvasSupported) {
+ const canvas = new OffscreenCanvas(imgWidth, imgHeight);
+ const ctx = canvas.getContext("2d");
+ ctx.putImageData(new ImageData(new Uint8ClampedArray(imgData.buffer), imgWidth, imgHeight), 0, 0);
+ img.bitmap = canvas.transferToImageBitmap();
+ img.data = null;
+ } else {
+ img.kind = ImageKind.RGBA_32BPP;
+ img.data = imgData;
+ }
+ fnArray.splice(iFirstSave, count * 4, OPS.paintInlineImageXObjectGroup);
+ argsArray.splice(iFirstSave, count * 4, [img, map]);
+ return iFirstSave + 1;
+});
+addState(InitialState, [OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore], null, function iterateImageMaskGroup(context, i) {
+ const fnArray = context.fnArray;
+ const iFirstSave = context.iCurr - 3;
+ const pos = (i - iFirstSave) % 4;
+ switch (pos) {
+ case 0:
+ return fnArray[i] === OPS.save;
+ case 1:
+ return fnArray[i] === OPS.transform;
+ case 2:
+ return fnArray[i] === OPS.paintImageMaskXObject;
+ case 3:
+ return fnArray[i] === OPS.restore;
+ }
+ throw new Error(`iterateImageMaskGroup - invalid pos: ${pos}`);
+}, function foundImageMaskGroup(context, i) {
+ const MIN_IMAGES_IN_MASKS_BLOCK = 10;
+ const MAX_IMAGES_IN_MASKS_BLOCK = 100;
+ const MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000;
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const curr = context.iCurr;
+ const iFirstSave = curr - 3;
+ const iFirstTransform = curr - 2;
+ const iFirstPIMXO = curr - 1;
+ let count = Math.floor((i - iFirstSave) / 4);
+ if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
+ return i - (i - iFirstSave) % 4;
+ }
+ let isSameImage = false;
+ let iTransform, transformArgs;
+ const firstPIMXOArg0 = argsArray[iFirstPIMXO][0];
+ const firstTransformArg0 = argsArray[iFirstTransform][0],
+ firstTransformArg1 = argsArray[iFirstTransform][1],
+ firstTransformArg2 = argsArray[iFirstTransform][2],
+ firstTransformArg3 = argsArray[iFirstTransform][3];
+ if (firstTransformArg1 === firstTransformArg2) {
+ isSameImage = true;
+ iTransform = iFirstTransform + 4;
+ let iPIMXO = iFirstPIMXO + 4;
+ for (let q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {
+ transformArgs = argsArray[iTransform];
+ if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || transformArgs[0] !== firstTransformArg0 || transformArgs[1] !== firstTransformArg1 || transformArgs[2] !== firstTransformArg2 || transformArgs[3] !== firstTransformArg3) {
+ if (q < MIN_IMAGES_IN_MASKS_BLOCK) {
+ isSameImage = false;
+ } else {
+ count = q;
+ }
+ break;
+ }
+ }
+ }
+ if (isSameImage) {
+ count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK);
+ const positions = new Float32Array(count * 2);
+ iTransform = iFirstTransform;
+ for (let q = 0; q < count; q++, iTransform += 4) {
+ transformArgs = argsArray[iTransform];
+ positions[q << 1] = transformArgs[4];
+ positions[(q << 1) + 1] = transformArgs[5];
+ }
+ fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectRepeat);
+ argsArray.splice(iFirstSave, count * 4, [firstPIMXOArg0, firstTransformArg0, firstTransformArg1, firstTransformArg2, firstTransformArg3, positions]);
+ } else {
+ count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK);
+ const images = [];
+ for (let q = 0; q < count; q++) {
+ transformArgs = argsArray[iFirstTransform + (q << 2)];
+ const maskParams = argsArray[iFirstPIMXO + (q << 2)][0];
+ images.push({
+ data: maskParams.data,
+ width: maskParams.width,
+ height: maskParams.height,
+ interpolate: maskParams.interpolate,
+ count: maskParams.count,
+ transform: transformArgs
+ });
+ }
+ fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectGroup);
+ argsArray.splice(iFirstSave, count * 4, [images]);
+ }
+ return iFirstSave + 1;
+});
+addState(InitialState, [OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore], function (context) {
+ const argsArray = context.argsArray;
+ const iFirstTransform = context.iCurr - 2;
+ return argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0;
+}, function iterateImageGroup(context, i) {
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const iFirstSave = context.iCurr - 3;
+ const pos = (i - iFirstSave) % 4;
+ switch (pos) {
+ case 0:
+ return fnArray[i] === OPS.save;
+ case 1:
+ if (fnArray[i] !== OPS.transform) {
+ return false;
+ }
+ const iFirstTransform = context.iCurr - 2;
+ const firstTransformArg0 = argsArray[iFirstTransform][0];
+ const firstTransformArg3 = argsArray[iFirstTransform][3];
+ if (argsArray[i][0] !== firstTransformArg0 || argsArray[i][1] !== 0 || argsArray[i][2] !== 0 || argsArray[i][3] !== firstTransformArg3) {
+ return false;
+ }
+ return true;
+ case 2:
+ if (fnArray[i] !== OPS.paintImageXObject) {
+ return false;
+ }
+ const iFirstPIXO = context.iCurr - 1;
+ const firstPIXOArg0 = argsArray[iFirstPIXO][0];
+ if (argsArray[i][0] !== firstPIXOArg0) {
+ return false;
+ }
+ return true;
+ case 3:
+ return fnArray[i] === OPS.restore;
+ }
+ throw new Error(`iterateImageGroup - invalid pos: ${pos}`);
+}, function (context, i) {
+ const MIN_IMAGES_IN_BLOCK = 3;
+ const MAX_IMAGES_IN_BLOCK = 1000;
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const curr = context.iCurr;
+ const iFirstSave = curr - 3;
+ const iFirstTransform = curr - 2;
+ const iFirstPIXO = curr - 1;
+ const firstPIXOArg0 = argsArray[iFirstPIXO][0];
+ const firstTransformArg0 = argsArray[iFirstTransform][0];
+ const firstTransformArg3 = argsArray[iFirstTransform][3];
+ const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK);
+ if (count < MIN_IMAGES_IN_BLOCK) {
+ return i - (i - iFirstSave) % 4;
+ }
+ const positions = new Float32Array(count * 2);
+ let iTransform = iFirstTransform;
+ for (let q = 0; q < count; q++, iTransform += 4) {
+ const transformArgs = argsArray[iTransform];
+ positions[q << 1] = transformArgs[4];
+ positions[(q << 1) + 1] = transformArgs[5];
+ }
+ const args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions];
+ fnArray.splice(iFirstSave, count * 4, OPS.paintImageXObjectRepeat);
+ argsArray.splice(iFirstSave, count * 4, args);
+ return iFirstSave + 1;
+});
+addState(InitialState, [OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText], null, function iterateShowTextGroup(context, i) {
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const iFirstSave = context.iCurr - 4;
+ const pos = (i - iFirstSave) % 5;
+ switch (pos) {
+ case 0:
+ return fnArray[i] === OPS.beginText;
+ case 1:
+ return fnArray[i] === OPS.setFont;
+ case 2:
+ return fnArray[i] === OPS.setTextMatrix;
+ case 3:
+ if (fnArray[i] !== OPS.showText) {
+ return false;
+ }
+ const iFirstSetFont = context.iCurr - 3;
+ const firstSetFontArg0 = argsArray[iFirstSetFont][0];
+ const firstSetFontArg1 = argsArray[iFirstSetFont][1];
+ if (argsArray[i][0] !== firstSetFontArg0 || argsArray[i][1] !== firstSetFontArg1) {
+ return false;
+ }
+ return true;
+ case 4:
+ return fnArray[i] === OPS.endText;
+ }
+ throw new Error(`iterateShowTextGroup - invalid pos: ${pos}`);
+}, function (context, i) {
+ const MIN_CHARS_IN_BLOCK = 3;
+ const MAX_CHARS_IN_BLOCK = 1000;
+ const fnArray = context.fnArray,
+ argsArray = context.argsArray;
+ const curr = context.iCurr;
+ const iFirstBeginText = curr - 4;
+ const iFirstSetFont = curr - 3;
+ const iFirstSetTextMatrix = curr - 2;
+ const iFirstShowText = curr - 1;
+ const iFirstEndText = curr;
+ const firstSetFontArg0 = argsArray[iFirstSetFont][0];
+ const firstSetFontArg1 = argsArray[iFirstSetFont][1];
+ let count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK);
+ if (count < MIN_CHARS_IN_BLOCK) {
+ return i - (i - iFirstBeginText) % 5;
+ }
+ let iFirst = iFirstBeginText;
+ if (iFirstBeginText >= 4 && fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) {
+ count++;
+ iFirst -= 5;
+ }
+ let iEndText = iFirst + 4;
+ for (let q = 1; q < count; q++) {
+ fnArray.splice(iEndText, 3);
+ argsArray.splice(iEndText, 3);
+ iEndText += 2;
+ }
+ return iEndText + 1;
+});
+class NullOptimizer {
+ constructor(queue) {
+ this.queue = queue;
+ }
+ _optimize() {}
+ push(fn, args) {
+ this.queue.fnArray.push(fn);
+ this.queue.argsArray.push(args);
+ this._optimize();
+ }
+ flush() {}
+ reset() {}
+}
+class QueueOptimizer extends NullOptimizer {
+ constructor(queue) {
+ super(queue);
+ this.state = null;
+ this.context = {
+ iCurr: 0,
+ fnArray: queue.fnArray,
+ argsArray: queue.argsArray,
+ isOffscreenCanvasSupported: false
+ };
+ this.match = null;
+ this.lastProcessed = 0;
+ }
+ set isOffscreenCanvasSupported(value) {
+ this.context.isOffscreenCanvasSupported = value;
+ }
+ _optimize() {
+ const fnArray = this.queue.fnArray;
+ let i = this.lastProcessed,
+ ii = fnArray.length;
+ let state = this.state;
+ let match = this.match;
+ if (!state && !match && i + 1 === ii && !InitialState[fnArray[i]]) {
+ this.lastProcessed = ii;
+ return;
+ }
+ const context = this.context;
+ while (i < ii) {
+ if (match) {
+ const iterate = (0, match.iterateFn)(context, i);
+ if (iterate) {
+ i++;
+ continue;
+ }
+ i = (0, match.processFn)(context, i + 1);
+ ii = fnArray.length;
+ match = null;
+ state = null;
+ if (i >= ii) {
+ break;
+ }
+ }
+ state = (state || InitialState)[fnArray[i]];
+ if (!state || Array.isArray(state)) {
+ i++;
+ continue;
+ }
+ context.iCurr = i;
+ i++;
+ if (state.checkFn && !(0, state.checkFn)(context)) {
+ state = null;
+ continue;
+ }
+ match = state;
+ state = null;
+ }
+ this.state = state;
+ this.match = match;
+ this.lastProcessed = i;
+ }
+ flush() {
+ while (this.match) {
+ const length = this.queue.fnArray.length;
+ this.lastProcessed = (0, this.match.processFn)(this.context, length);
+ this.match = null;
+ this.state = null;
+ this._optimize();
+ }
+ }
+ reset() {
+ this.state = null;
+ this.match = null;
+ this.lastProcessed = 0;
+ }
+}
+class OperatorList {
+ static CHUNK_SIZE = 1000;
+ static CHUNK_SIZE_ABOUT = this.CHUNK_SIZE - 5;
+ constructor(intent = 0, streamSink) {
+ this._streamSink = streamSink;
+ this.fnArray = [];
+ this.argsArray = [];
+ this.optimizer = streamSink && !(intent & RenderingIntentFlag.OPLIST) ? new QueueOptimizer(this) : new NullOptimizer(this);
+ this.dependencies = new Set();
+ this._totalLength = 0;
+ this.weight = 0;
+ this._resolved = streamSink ? null : Promise.resolve();
+ }
+ set isOffscreenCanvasSupported(value) {
+ this.optimizer.isOffscreenCanvasSupported = value;
+ }
+ get length() {
+ return this.argsArray.length;
+ }
+ get ready() {
+ return this._resolved || this._streamSink.ready;
+ }
+ get totalLength() {
+ return this._totalLength + this.length;
+ }
+ addOp(fn, args) {
+ this.optimizer.push(fn, args);
+ this.weight++;
+ if (this._streamSink) {
+ if (this.weight >= OperatorList.CHUNK_SIZE) {
+ this.flush();
+ } else if (this.weight >= OperatorList.CHUNK_SIZE_ABOUT && (fn === OPS.restore || fn === OPS.endText)) {
+ this.flush();
+ }
+ }
+ }
+ addImageOps(fn, args, optionalContent) {
+ if (optionalContent !== undefined) {
+ this.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
+ }
+ this.addOp(fn, args);
+ if (optionalContent !== undefined) {
+ this.addOp(OPS.endMarkedContent, []);
+ }
+ }
+ addDependency(dependency) {
+ if (this.dependencies.has(dependency)) {
+ return;
+ }
+ this.dependencies.add(dependency);
+ this.addOp(OPS.dependency, [dependency]);
+ }
+ addDependencies(dependencies) {
+ for (const dependency of dependencies) {
+ this.addDependency(dependency);
+ }
+ }
+ addOpList(opList) {
+ if (!(opList instanceof OperatorList)) {
+ warn('addOpList - ignoring invalid "opList" parameter.');
+ return;
+ }
+ for (const dependency of opList.dependencies) {
+ this.dependencies.add(dependency);
+ }
+ for (let i = 0, ii = opList.length; i < ii; i++) {
+ this.addOp(opList.fnArray[i], opList.argsArray[i]);
+ }
+ }
+ getIR() {
+ return {
+ fnArray: this.fnArray,
+ argsArray: this.argsArray,
+ length: this.length
+ };
+ }
+ get _transfers() {
+ const transfers = [];
+ const {
+ fnArray,
+ argsArray,
+ length
+ } = this;
+ for (let i = 0; i < length; i++) {
+ switch (fnArray[i]) {
+ case OPS.paintInlineImageXObject:
+ case OPS.paintInlineImageXObjectGroup:
+ case OPS.paintImageMaskXObject:
+ const arg = argsArray[i][0];
+ if (!arg.cached && arg.data?.buffer instanceof ArrayBuffer) {
+ transfers.push(arg.data.buffer);
+ }
+ break;
+ }
+ }
+ return transfers;
+ }
+ flush(lastChunk = false, separateAnnots = null) {
+ this.optimizer.flush();
+ const length = this.length;
+ this._totalLength += length;
+ this._streamSink.enqueue({
+ fnArray: this.fnArray,
+ argsArray: this.argsArray,
+ lastChunk,
+ separateAnnots,
+ length
+ }, 1, this._transfers);
+ this.dependencies.clear();
+ this.fnArray.length = 0;
+ this.argsArray.length = 0;
+ this.weight = 0;
+ this.optimizer.reset();
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/image.js
+
+
+
+
+
+
+
+
+
+function decodeAndClamp(value, addend, coefficient, max) {
+ value = addend + value * coefficient;
+ if (value < 0) {
+ value = 0;
+ } else if (value > max) {
+ value = max;
+ }
+ return value;
+}
+function resizeImageMask(src, bpc, w1, h1, w2, h2) {
+ const length = w2 * h2;
+ let dest;
+ if (bpc <= 8) {
+ dest = new Uint8Array(length);
+ } else if (bpc <= 16) {
+ dest = new Uint16Array(length);
+ } else {
+ dest = new Uint32Array(length);
+ }
+ const xRatio = w1 / w2;
+ const yRatio = h1 / h2;
+ let i,
+ j,
+ py,
+ newIndex = 0,
+ oldIndex;
+ const xScaled = new Uint16Array(w2);
+ const w1Scanline = w1;
+ for (i = 0; i < w2; i++) {
+ xScaled[i] = Math.floor(i * xRatio);
+ }
+ for (i = 0; i < h2; i++) {
+ py = Math.floor(i * yRatio) * w1Scanline;
+ for (j = 0; j < w2; j++) {
+ oldIndex = py + xScaled[j];
+ dest[newIndex++] = src[oldIndex];
+ }
+ }
+ return dest;
+}
+class PDFImage {
+ constructor({
+ xref,
+ res,
+ image,
+ isInline = false,
+ smask = null,
+ mask = null,
+ isMask = false,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ }) {
+ this.image = image;
+ const dict = image.dict;
+ const filter = dict.get("F", "Filter");
+ let filterName;
+ if (filter instanceof Name) {
+ filterName = filter.name;
+ } else if (Array.isArray(filter)) {
+ const filterZero = xref.fetchIfRef(filter[0]);
+ if (filterZero instanceof Name) {
+ filterName = filterZero.name;
+ }
+ }
+ switch (filterName) {
+ case "JPXDecode":
+ const jpxImage = new JpxImage();
+ jpxImage.parseImageProperties(image.stream);
+ image.stream.reset();
+ image.width = jpxImage.width;
+ image.height = jpxImage.height;
+ image.bitsPerComponent = jpxImage.bitsPerComponent;
+ image.numComps = jpxImage.componentsCount;
+ break;
+ case "JBIG2Decode":
+ image.bitsPerComponent = 1;
+ image.numComps = 1;
+ break;
+ }
+ let width = dict.get("W", "Width");
+ let height = dict.get("H", "Height");
+ if (Number.isInteger(image.width) && image.width > 0 && Number.isInteger(image.height) && image.height > 0 && (image.width !== width || image.height !== height)) {
+ warn("PDFImage - using the Width/Height of the image data, " + "rather than the image dictionary.");
+ width = image.width;
+ height = image.height;
+ }
+ if (width < 1 || height < 1) {
+ throw new FormatError(`Invalid image width: ${width} or height: ${height}`);
+ }
+ this.width = width;
+ this.height = height;
+ this.interpolate = dict.get("I", "Interpolate");
+ this.imageMask = dict.get("IM", "ImageMask") || false;
+ this.matte = dict.get("Matte") || false;
+ let bitsPerComponent = image.bitsPerComponent;
+ if (!bitsPerComponent) {
+ bitsPerComponent = dict.get("BPC", "BitsPerComponent");
+ if (!bitsPerComponent) {
+ if (this.imageMask) {
+ bitsPerComponent = 1;
+ } else {
+ throw new FormatError(`Bits per component missing in image: ${this.imageMask}`);
+ }
+ }
+ }
+ this.bpc = bitsPerComponent;
+ if (!this.imageMask) {
+ let colorSpace = dict.getRaw("CS") || dict.getRaw("ColorSpace");
+ if (!colorSpace) {
+ info("JPX images (which do not require color spaces)");
+ switch (image.numComps) {
+ case 1:
+ colorSpace = Name.get("DeviceGray");
+ break;
+ case 3:
+ colorSpace = Name.get("DeviceRGB");
+ break;
+ case 4:
+ colorSpace = Name.get("DeviceCMYK");
+ break;
+ default:
+ throw new Error(`JPX images with ${image.numComps} color components not supported.`);
+ }
+ }
+ this.colorSpace = ColorSpace.parse({
+ cs: colorSpace,
+ xref,
+ resources: isInline ? res : null,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ this.numComps = this.colorSpace.numComps;
+ }
+ this.decode = dict.getArray("D", "Decode");
+ this.needsDecode = false;
+ if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent) || isMask && !ColorSpace.isDefaultDecode(this.decode, 1))) {
+ this.needsDecode = true;
+ const max = (1 << bitsPerComponent) - 1;
+ this.decodeCoefficients = [];
+ this.decodeAddends = [];
+ const isIndexed = this.colorSpace?.name === "Indexed";
+ for (let i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
+ const dmin = this.decode[i];
+ const dmax = this.decode[i + 1];
+ this.decodeCoefficients[j] = isIndexed ? (dmax - dmin) / max : dmax - dmin;
+ this.decodeAddends[j] = isIndexed ? dmin : max * dmin;
+ }
+ }
+ if (smask) {
+ this.smask = new PDFImage({
+ xref,
+ res,
+ image: smask,
+ isInline,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ } else if (mask) {
+ if (mask instanceof BaseStream) {
+ const maskDict = mask.dict,
+ imageMask = maskDict.get("IM", "ImageMask");
+ if (!imageMask) {
+ warn("Ignoring /Mask in image without /ImageMask.");
+ } else {
+ this.mask = new PDFImage({
+ xref,
+ res,
+ image: mask,
+ isInline,
+ isMask: true,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ }
+ } else {
+ this.mask = mask;
+ }
+ }
+ }
+ static async buildImage({
+ xref,
+ res,
+ image,
+ isInline = false,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ }) {
+ const imageData = image;
+ let smaskData = null;
+ let maskData = null;
+ const smask = image.dict.get("SMask");
+ const mask = image.dict.get("Mask");
+ if (smask) {
+ if (smask instanceof BaseStream) {
+ smaskData = smask;
+ } else {
+ warn("Unsupported /SMask format.");
+ }
+ } else if (mask) {
+ if (mask instanceof BaseStream || Array.isArray(mask)) {
+ maskData = mask;
+ } else {
+ warn("Unsupported /Mask format.");
+ }
+ }
+ return new PDFImage({
+ xref,
+ res,
+ image: imageData,
+ isInline,
+ smask: smaskData,
+ mask: maskData,
+ pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ }
+ static createRawMask({
+ imgArray,
+ width,
+ height,
+ imageIsFromDecodeStream,
+ inverseDecode,
+ interpolate
+ }) {
+ const computedLength = (width + 7 >> 3) * height;
+ const actualLength = imgArray.byteLength;
+ const haveFullData = computedLength === actualLength;
+ let data, i;
+ if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) {
+ data = imgArray;
+ } else if (!inverseDecode) {
+ data = new Uint8Array(imgArray);
+ } else {
+ data = new Uint8Array(computedLength);
+ data.set(imgArray);
+ data.fill(0xff, actualLength);
+ }
+ if (inverseDecode) {
+ for (i = 0; i < actualLength; i++) {
+ data[i] ^= 0xff;
+ }
+ }
+ return {
+ data,
+ width,
+ height,
+ interpolate
+ };
+ }
+ static async createMask({
+ imgArray,
+ width,
+ height,
+ imageIsFromDecodeStream,
+ inverseDecode,
+ interpolate,
+ isOffscreenCanvasSupported = false
+ }) {
+ const isSingleOpaquePixel = width === 1 && height === 1 && inverseDecode === (imgArray.length === 0 || !!(imgArray[0] & 128));
+ if (isSingleOpaquePixel) {
+ return {
+ isSingleOpaquePixel
+ };
+ }
+ if (isOffscreenCanvasSupported) {
+ if (ImageResizer.needsToBeResized(width, height)) {
+ const data = new Uint8ClampedArray(width * height * 4);
+ convertBlackAndWhiteToRGBA({
+ src: imgArray,
+ dest: data,
+ width,
+ height,
+ nonBlackColor: 0,
+ inverseDecode
+ });
+ return ImageResizer.createImage({
+ kind: ImageKind.RGBA_32BPP,
+ data,
+ width,
+ height,
+ interpolate
+ });
+ }
+ const canvas = new OffscreenCanvas(width, height);
+ const ctx = canvas.getContext("2d");
+ const imgData = ctx.createImageData(width, height);
+ convertBlackAndWhiteToRGBA({
+ src: imgArray,
+ dest: imgData.data,
+ width,
+ height,
+ nonBlackColor: 0,
+ inverseDecode
+ });
+ ctx.putImageData(imgData, 0, 0);
+ const bitmap = canvas.transferToImageBitmap();
+ return {
+ data: null,
+ width,
+ height,
+ interpolate,
+ bitmap
+ };
+ }
+ return this.createRawMask({
+ imgArray,
+ width,
+ height,
+ inverseDecode,
+ imageIsFromDecodeStream,
+ interpolate
+ });
+ }
+ get drawWidth() {
+ return Math.max(this.width, this.smask?.width || 0, this.mask?.width || 0);
+ }
+ get drawHeight() {
+ return Math.max(this.height, this.smask?.height || 0, this.mask?.height || 0);
+ }
+ decodeBuffer(buffer) {
+ const bpc = this.bpc;
+ const numComps = this.numComps;
+ const decodeAddends = this.decodeAddends;
+ const decodeCoefficients = this.decodeCoefficients;
+ const max = (1 << bpc) - 1;
+ let i, ii;
+ if (bpc === 1) {
+ for (i = 0, ii = buffer.length; i < ii; i++) {
+ buffer[i] = +!buffer[i];
+ }
+ return;
+ }
+ let index = 0;
+ for (i = 0, ii = this.width * this.height; i < ii; i++) {
+ for (let j = 0; j < numComps; j++) {
+ buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], decodeCoefficients[j], max);
+ index++;
+ }
+ }
+ }
+ getComponents(buffer) {
+ const bpc = this.bpc;
+ if (bpc === 8) {
+ return buffer;
+ }
+ const width = this.width;
+ const height = this.height;
+ const numComps = this.numComps;
+ const length = width * height * numComps;
+ let bufferPos = 0;
+ let output;
+ if (bpc <= 8) {
+ output = new Uint8Array(length);
+ } else if (bpc <= 16) {
+ output = new Uint16Array(length);
+ } else {
+ output = new Uint32Array(length);
+ }
+ const rowComps = width * numComps;
+ const max = (1 << bpc) - 1;
+ let i = 0,
+ ii,
+ buf;
+ if (bpc === 1) {
+ let mask, loop1End, loop2End;
+ for (let j = 0; j < height; j++) {
+ loop1End = i + (rowComps & ~7);
+ loop2End = i + rowComps;
+ while (i < loop1End) {
+ buf = buffer[bufferPos++];
+ output[i] = buf >> 7 & 1;
+ output[i + 1] = buf >> 6 & 1;
+ output[i + 2] = buf >> 5 & 1;
+ output[i + 3] = buf >> 4 & 1;
+ output[i + 4] = buf >> 3 & 1;
+ output[i + 5] = buf >> 2 & 1;
+ output[i + 6] = buf >> 1 & 1;
+ output[i + 7] = buf & 1;
+ i += 8;
+ }
+ if (i < loop2End) {
+ buf = buffer[bufferPos++];
+ mask = 128;
+ while (i < loop2End) {
+ output[i++] = +!!(buf & mask);
+ mask >>= 1;
+ }
+ }
+ }
+ } else {
+ let bits = 0;
+ buf = 0;
+ for (i = 0, ii = length; i < ii; ++i) {
+ if (i % rowComps === 0) {
+ buf = 0;
+ bits = 0;
+ }
+ while (bits < bpc) {
+ buf = buf << 8 | buffer[bufferPos++];
+ bits += 8;
+ }
+ const remainingBits = bits - bpc;
+ let value = buf >> remainingBits;
+ if (value < 0) {
+ value = 0;
+ } else if (value > max) {
+ value = max;
+ }
+ output[i] = value;
+ buf &= (1 << remainingBits) - 1;
+ bits = remainingBits;
+ }
+ }
+ return output;
+ }
+ fillOpacity(rgbaBuf, width, height, actualHeight, image) {
+ const smask = this.smask;
+ const mask = this.mask;
+ let alphaBuf, sw, sh, i, ii, j;
+ if (smask) {
+ sw = smask.width;
+ sh = smask.height;
+ alphaBuf = new Uint8ClampedArray(sw * sh);
+ smask.fillGrayBuffer(alphaBuf);
+ if (sw !== width || sh !== height) {
+ alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh, width, height);
+ }
+ } else if (mask) {
+ if (mask instanceof PDFImage) {
+ sw = mask.width;
+ sh = mask.height;
+ alphaBuf = new Uint8ClampedArray(sw * sh);
+ mask.numComps = 1;
+ mask.fillGrayBuffer(alphaBuf);
+ for (i = 0, ii = sw * sh; i < ii; ++i) {
+ alphaBuf[i] = 255 - alphaBuf[i];
+ }
+ if (sw !== width || sh !== height) {
+ alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh, width, height);
+ }
+ } else if (Array.isArray(mask)) {
+ alphaBuf = new Uint8ClampedArray(width * height);
+ const numComps = this.numComps;
+ for (i = 0, ii = width * height; i < ii; ++i) {
+ let opacity = 0;
+ const imageOffset = i * numComps;
+ for (j = 0; j < numComps; ++j) {
+ const color = image[imageOffset + j];
+ const maskOffset = j * 2;
+ if (color < mask[maskOffset] || color > mask[maskOffset + 1]) {
+ opacity = 255;
+ break;
+ }
+ }
+ alphaBuf[i] = opacity;
+ }
+ } else {
+ throw new FormatError("Unknown mask format.");
+ }
+ }
+ if (alphaBuf) {
+ for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {
+ rgbaBuf[j] = alphaBuf[i];
+ }
+ } else {
+ for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {
+ rgbaBuf[j] = 255;
+ }
+ }
+ }
+ undoPreblend(buffer, width, height) {
+ const matte = this.smask?.matte;
+ if (!matte) {
+ return;
+ }
+ const matteRgb = this.colorSpace.getRgb(matte, 0);
+ const matteR = matteRgb[0];
+ const matteG = matteRgb[1];
+ const matteB = matteRgb[2];
+ const length = width * height * 4;
+ for (let i = 0; i < length; i += 4) {
+ const alpha = buffer[i + 3];
+ if (alpha === 0) {
+ buffer[i] = 255;
+ buffer[i + 1] = 255;
+ buffer[i + 2] = 255;
+ continue;
+ }
+ const k = 255 / alpha;
+ buffer[i] = (buffer[i] - matteR) * k + matteR;
+ buffer[i + 1] = (buffer[i + 1] - matteG) * k + matteG;
+ buffer[i + 2] = (buffer[i + 2] - matteB) * k + matteB;
+ }
+ }
+ async createImageData(forceRGBA = false, isOffscreenCanvasSupported = false) {
+ const drawWidth = this.drawWidth;
+ const drawHeight = this.drawHeight;
+ const imgData = {
+ width: drawWidth,
+ height: drawHeight,
+ interpolate: this.interpolate,
+ kind: 0,
+ data: null
+ };
+ const numComps = this.numComps;
+ const originalWidth = this.width;
+ const originalHeight = this.height;
+ const bpc = this.bpc;
+ const rowBytes = originalWidth * numComps * bpc + 7 >> 3;
+ const mustBeResized = isOffscreenCanvasSupported && ImageResizer.needsToBeResized(drawWidth, drawHeight);
+ if (!forceRGBA) {
+ let kind;
+ if (this.colorSpace.name === "DeviceGray" && bpc === 1) {
+ kind = ImageKind.GRAYSCALE_1BPP;
+ } else if (this.colorSpace.name === "DeviceRGB" && bpc === 8 && !this.needsDecode) {
+ kind = ImageKind.RGB_24BPP;
+ }
+ if (kind && !this.smask && !this.mask && drawWidth === originalWidth && drawHeight === originalHeight) {
+ const data = this.getImageBytes(originalHeight * rowBytes, {});
+ if (isOffscreenCanvasSupported) {
+ if (mustBeResized) {
+ return ImageResizer.createImage({
+ data,
+ kind,
+ width: drawWidth,
+ height: drawHeight,
+ interpolate: this.interpolate
+ }, this.needsDecode);
+ }
+ return this.createBitmap(kind, originalWidth, originalHeight, data);
+ }
+ imgData.kind = kind;
+ imgData.data = data;
+ if (this.needsDecode) {
+ assert(kind === ImageKind.GRAYSCALE_1BPP, "PDFImage.createImageData: The image must be grayscale.");
+ const buffer = imgData.data;
+ for (let i = 0, ii = buffer.length; i < ii; i++) {
+ buffer[i] ^= 0xff;
+ }
+ }
+ return imgData;
+ }
+ if (this.image instanceof JpegStream && !this.smask && !this.mask && !this.needsDecode) {
+ let imageLength = originalHeight * rowBytes;
+ if (isOffscreenCanvasSupported && !mustBeResized) {
+ let isHandled = false;
+ switch (this.colorSpace.name) {
+ case "DeviceGray":
+ imageLength *= 4;
+ isHandled = true;
+ break;
+ case "DeviceRGB":
+ imageLength = imageLength / 3 * 4;
+ isHandled = true;
+ break;
+ case "DeviceCMYK":
+ isHandled = true;
+ break;
+ }
+ if (isHandled) {
+ const rgba = this.getImageBytes(imageLength, {
+ drawWidth,
+ drawHeight,
+ forceRGBA: true
+ });
+ return this.createBitmap(ImageKind.RGBA_32BPP, drawWidth, drawHeight, rgba);
+ }
+ } else {
+ switch (this.colorSpace.name) {
+ case "DeviceGray":
+ imageLength *= 3;
+ case "DeviceRGB":
+ case "DeviceCMYK":
+ imgData.kind = ImageKind.RGB_24BPP;
+ imgData.data = this.getImageBytes(imageLength, {
+ drawWidth,
+ drawHeight,
+ forceRGB: true
+ });
+ if (mustBeResized) {
+ return ImageResizer.createImage(imgData);
+ }
+ return imgData;
+ }
+ }
+ }
+ }
+ const imgArray = this.getImageBytes(originalHeight * rowBytes, {
+ internal: true
+ });
+ const actualHeight = 0 | imgArray.length / rowBytes * drawHeight / originalHeight;
+ const comps = this.getComponents(imgArray);
+ let alpha01, maybeUndoPreblend;
+ let canvas, ctx, canvasImgData, data;
+ if (isOffscreenCanvasSupported && !mustBeResized) {
+ canvas = new OffscreenCanvas(drawWidth, drawHeight);
+ ctx = canvas.getContext("2d");
+ canvasImgData = ctx.createImageData(drawWidth, drawHeight);
+ data = canvasImgData.data;
+ }
+ imgData.kind = ImageKind.RGBA_32BPP;
+ if (!forceRGBA && !this.smask && !this.mask) {
+ if (!isOffscreenCanvasSupported || mustBeResized) {
+ imgData.kind = ImageKind.RGB_24BPP;
+ data = new Uint8ClampedArray(drawWidth * drawHeight * 3);
+ alpha01 = 0;
+ } else {
+ const arr = new Uint32Array(data.buffer);
+ arr.fill(FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff);
+ alpha01 = 1;
+ }
+ maybeUndoPreblend = false;
+ } else {
+ if (!isOffscreenCanvasSupported || mustBeResized) {
+ data = new Uint8ClampedArray(drawWidth * drawHeight * 4);
+ }
+ alpha01 = 1;
+ maybeUndoPreblend = true;
+ this.fillOpacity(data, drawWidth, drawHeight, actualHeight, comps);
+ }
+ if (this.needsDecode) {
+ this.decodeBuffer(comps);
+ }
+ this.colorSpace.fillRgb(data, originalWidth, originalHeight, drawWidth, drawHeight, actualHeight, bpc, comps, alpha01);
+ if (maybeUndoPreblend) {
+ this.undoPreblend(data, drawWidth, actualHeight);
+ }
+ if (isOffscreenCanvasSupported && !mustBeResized) {
+ ctx.putImageData(canvasImgData, 0, 0);
+ const bitmap = canvas.transferToImageBitmap();
+ return {
+ data: null,
+ width: drawWidth,
+ height: drawHeight,
+ bitmap,
+ interpolate: this.interpolate
+ };
+ }
+ imgData.data = data;
+ if (mustBeResized) {
+ return ImageResizer.createImage(imgData);
+ }
+ return imgData;
+ }
+ fillGrayBuffer(buffer) {
+ const numComps = this.numComps;
+ if (numComps !== 1) {
+ throw new FormatError(`Reading gray scale from a color image: ${numComps}`);
+ }
+ const width = this.width;
+ const height = this.height;
+ const bpc = this.bpc;
+ const rowBytes = width * numComps * bpc + 7 >> 3;
+ const imgArray = this.getImageBytes(height * rowBytes, {
+ internal: true
+ });
+ const comps = this.getComponents(imgArray);
+ let i, length;
+ if (bpc === 1) {
+ length = width * height;
+ if (this.needsDecode) {
+ for (i = 0; i < length; ++i) {
+ buffer[i] = comps[i] - 1 & 255;
+ }
+ } else {
+ for (i = 0; i < length; ++i) {
+ buffer[i] = -comps[i] & 255;
+ }
+ }
+ return;
+ }
+ if (this.needsDecode) {
+ this.decodeBuffer(comps);
+ }
+ length = width * height;
+ const scale = 255 / ((1 << bpc) - 1);
+ for (i = 0; i < length; ++i) {
+ buffer[i] = scale * comps[i];
+ }
+ }
+ createBitmap(kind, width, height, src) {
+ const canvas = new OffscreenCanvas(width, height);
+ const ctx = canvas.getContext("2d");
+ let imgData;
+ if (kind === ImageKind.RGBA_32BPP) {
+ imgData = new ImageData(src, width, height);
+ } else {
+ imgData = ctx.createImageData(width, height);
+ convertToRGBA({
+ kind,
+ src,
+ dest: new Uint32Array(imgData.data.buffer),
+ width,
+ height,
+ inverseDecode: this.needsDecode
+ });
+ }
+ ctx.putImageData(imgData, 0, 0);
+ const bitmap = canvas.transferToImageBitmap();
+ return {
+ data: null,
+ width,
+ height,
+ bitmap,
+ interpolate: this.interpolate
+ };
+ }
+ getImageBytes(length, {
+ drawWidth,
+ drawHeight,
+ forceRGBA = false,
+ forceRGB = false,
+ internal = false
+ }) {
+ this.image.reset();
+ this.image.drawWidth = drawWidth || this.width;
+ this.image.drawHeight = drawHeight || this.height;
+ this.image.forceRGBA = !!forceRGBA;
+ this.image.forceRGB = !!forceRGB;
+ const imageBytes = this.image.getBytes(length);
+ if (internal || this.image instanceof DecodeStream) {
+ return imageBytes;
+ }
+ assert(imageBytes instanceof Uint8Array, 'PDFImage.getImageBytes: Unsupported "imageBytes" type.');
+ return new Uint8Array(imageBytes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/evaluator.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const DefaultPartialEvaluatorOptions = Object.freeze({
+ maxImageSize: -1,
+ disableFontFace: false,
+ ignoreErrors: false,
+ isEvalSupported: true,
+ isOffscreenCanvasSupported: false,
+ canvasMaxAreaInBytes: -1,
+ fontExtraProperties: false,
+ useSystemFonts: true,
+ cMapUrl: null,
+ standardFontDataUrl: null
+});
+const PatternType = {
+ TILING: 1,
+ SHADING: 2
+};
+const TEXT_CHUNK_BATCH_SIZE = 10;
+const deferred = Promise.resolve();
+function normalizeBlendMode(value, parsingArray = false) {
+ if (Array.isArray(value)) {
+ for (const val of value) {
+ const maybeBM = normalizeBlendMode(val, true);
+ if (maybeBM) {
+ return maybeBM;
+ }
+ }
+ warn(`Unsupported blend mode Array: ${value}`);
+ return "source-over";
+ }
+ if (!(value instanceof Name)) {
+ if (parsingArray) {
+ return null;
+ }
+ return "source-over";
+ }
+ switch (value.name) {
+ case "Normal":
+ case "Compatible":
+ return "source-over";
+ case "Multiply":
+ return "multiply";
+ case "Screen":
+ return "screen";
+ case "Overlay":
+ return "overlay";
+ case "Darken":
+ return "darken";
+ case "Lighten":
+ return "lighten";
+ case "ColorDodge":
+ return "color-dodge";
+ case "ColorBurn":
+ return "color-burn";
+ case "HardLight":
+ return "hard-light";
+ case "SoftLight":
+ return "soft-light";
+ case "Difference":
+ return "difference";
+ case "Exclusion":
+ return "exclusion";
+ case "Hue":
+ return "hue";
+ case "Saturation":
+ return "saturation";
+ case "Color":
+ return "color";
+ case "Luminosity":
+ return "luminosity";
+ }
+ if (parsingArray) {
+ return null;
+ }
+ warn(`Unsupported blend mode: ${value.name}`);
+ return "source-over";
+}
+function incrementCachedImageMaskCount(data) {
+ if (data.fn === OPS.paintImageMaskXObject && data.args[0]?.count > 0) {
+ data.args[0].count++;
+ }
+}
+class TimeSlotManager {
+ static TIME_SLOT_DURATION_MS = 20;
+ static CHECK_TIME_EVERY = 100;
+ constructor() {
+ this.reset();
+ }
+ check() {
+ if (++this.checked < TimeSlotManager.CHECK_TIME_EVERY) {
+ return false;
+ }
+ this.checked = 0;
+ return this.endTime <= Date.now();
+ }
+ reset() {
+ this.endTime = Date.now() + TimeSlotManager.TIME_SLOT_DURATION_MS;
+ this.checked = 0;
+ }
+}
+class PartialEvaluator {
+ constructor({
+ xref,
+ handler,
+ pageIndex,
+ idFactory,
+ fontCache,
+ builtInCMapCache,
+ standardFontDataCache,
+ globalImageCache,
+ systemFontCache,
+ options = null
+ }) {
+ this.xref = xref;
+ this.handler = handler;
+ this.pageIndex = pageIndex;
+ this.idFactory = idFactory;
+ this.fontCache = fontCache;
+ this.builtInCMapCache = builtInCMapCache;
+ this.standardFontDataCache = standardFontDataCache;
+ this.globalImageCache = globalImageCache;
+ this.systemFontCache = systemFontCache;
+ this.options = options || DefaultPartialEvaluatorOptions;
+ this.parsingType3Font = false;
+ this._regionalImageCache = new RegionalImageCache();
+ this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);
+ ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes);
+ }
+ get _pdfFunctionFactory() {
+ const pdfFunctionFactory = new PDFFunctionFactory({
+ xref: this.xref,
+ isEvalSupported: this.options.isEvalSupported
+ });
+ return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory);
+ }
+ clone(newOptions = null) {
+ const newEvaluator = Object.create(this);
+ newEvaluator.options = Object.assign(Object.create(null), this.options, newOptions);
+ return newEvaluator;
+ }
+ hasBlendModes(resources, nonBlendModesSet) {
+ if (!(resources instanceof Dict)) {
+ return false;
+ }
+ if (resources.objId && nonBlendModesSet.has(resources.objId)) {
+ return false;
+ }
+ const processed = new RefSet(nonBlendModesSet);
+ if (resources.objId) {
+ processed.put(resources.objId);
+ }
+ const nodes = [resources],
+ xref = this.xref;
+ while (nodes.length) {
+ const node = nodes.shift();
+ const graphicStates = node.get("ExtGState");
+ if (graphicStates instanceof Dict) {
+ for (let graphicState of graphicStates.getRawValues()) {
+ if (graphicState instanceof Ref) {
+ if (processed.has(graphicState)) {
+ continue;
+ }
+ try {
+ graphicState = xref.fetch(graphicState);
+ } catch (ex) {
+ processed.put(graphicState);
+ info(`hasBlendModes - ignoring ExtGState: "${ex}".`);
+ continue;
+ }
+ }
+ if (!(graphicState instanceof Dict)) {
+ continue;
+ }
+ if (graphicState.objId) {
+ processed.put(graphicState.objId);
+ }
+ const bm = graphicState.get("BM");
+ if (bm instanceof Name) {
+ if (bm.name !== "Normal") {
+ return true;
+ }
+ continue;
+ }
+ if (bm !== undefined && Array.isArray(bm)) {
+ for (const element of bm) {
+ if (element instanceof Name && element.name !== "Normal") {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ const xObjects = node.get("XObject");
+ if (!(xObjects instanceof Dict)) {
+ continue;
+ }
+ for (let xObject of xObjects.getRawValues()) {
+ if (xObject instanceof Ref) {
+ if (processed.has(xObject)) {
+ continue;
+ }
+ try {
+ xObject = xref.fetch(xObject);
+ } catch (ex) {
+ processed.put(xObject);
+ info(`hasBlendModes - ignoring XObject: "${ex}".`);
+ continue;
+ }
+ }
+ if (!(xObject instanceof BaseStream)) {
+ continue;
+ }
+ if (xObject.dict.objId) {
+ processed.put(xObject.dict.objId);
+ }
+ const xResources = xObject.dict.get("Resources");
+ if (!(xResources instanceof Dict)) {
+ continue;
+ }
+ if (xResources.objId && processed.has(xResources.objId)) {
+ continue;
+ }
+ nodes.push(xResources);
+ if (xResources.objId) {
+ processed.put(xResources.objId);
+ }
+ }
+ }
+ for (const ref of processed) {
+ nonBlendModesSet.put(ref);
+ }
+ return false;
+ }
+ async fetchBuiltInCMap(name) {
+ const cachedData = this.builtInCMapCache.get(name);
+ if (cachedData) {
+ return cachedData;
+ }
+ let data;
+ if (this.options.cMapUrl !== null) {
+ const url = `${this.options.cMapUrl}${name}.bcmap`;
+ const response = await fetch(url);
+ if (!response.ok) {
+ throw new Error(`fetchBuiltInCMap: failed to fetch file "${url}" with "${response.statusText}".`);
+ }
+ data = {
+ cMapData: new Uint8Array(await response.arrayBuffer()),
+ compressionType: CMapCompressionType.BINARY
+ };
+ } else {
+ data = await this.handler.sendWithPromise("FetchBuiltInCMap", {
+ name
+ });
+ }
+ if (data.compressionType !== CMapCompressionType.NONE) {
+ this.builtInCMapCache.set(name, data);
+ }
+ return data;
+ }
+ async fetchStandardFontData(name) {
+ const cachedData = this.standardFontDataCache.get(name);
+ if (cachedData) {
+ return new Stream(cachedData);
+ }
+ if (this.options.useSystemFonts && name !== "Symbol" && name !== "ZapfDingbats") {
+ return null;
+ }
+ const standardFontNameToFileName = getFontNameToFileMap(),
+ filename = standardFontNameToFileName[name];
+ let data;
+ if (this.options.standardFontDataUrl !== null) {
+ const url = `${this.options.standardFontDataUrl}${filename}`;
+ const response = await fetch(url);
+ if (!response.ok) {
+ warn(`fetchStandardFontData: failed to fetch file "${url}" with "${response.statusText}".`);
+ } else {
+ data = new Uint8Array(await response.arrayBuffer());
+ }
+ } else {
+ try {
+ data = await this.handler.sendWithPromise("FetchStandardFontData", {
+ filename
+ });
+ } catch (e) {
+ warn(`fetchStandardFontData: failed to fetch file "${filename}" with "${e}".`);
+ }
+ }
+ if (!data) {
+ return null;
+ }
+ this.standardFontDataCache.set(name, data);
+ return new Stream(data);
+ }
+ async buildFormXObject(resources, xobj, smask, operatorList, task, initialState, localColorSpaceCache) {
+ const dict = xobj.dict;
+ const matrix = dict.getArray("Matrix");
+ let bbox = dict.getArray("BBox");
+ bbox = Array.isArray(bbox) && bbox.length === 4 ? Util.normalizeRect(bbox) : null;
+ let optionalContent, groupOptions;
+ if (dict.has("OC")) {
+ optionalContent = await this.parseMarkedContentProps(dict.get("OC"), resources);
+ }
+ if (optionalContent !== undefined) {
+ operatorList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
+ }
+ const group = dict.get("Group");
+ if (group) {
+ groupOptions = {
+ matrix,
+ bbox,
+ smask,
+ isolated: false,
+ knockout: false
+ };
+ const groupSubtype = group.get("S");
+ let colorSpace = null;
+ if (isName(groupSubtype, "Transparency")) {
+ groupOptions.isolated = group.get("I") || false;
+ groupOptions.knockout = group.get("K") || false;
+ if (group.has("CS")) {
+ const cs = group.getRaw("CS");
+ const cachedColorSpace = ColorSpace.getCached(cs, this.xref, localColorSpaceCache);
+ if (cachedColorSpace) {
+ colorSpace = cachedColorSpace;
+ } else {
+ colorSpace = await this.parseColorSpace({
+ cs,
+ resources,
+ localColorSpaceCache
+ });
+ }
+ }
+ }
+ if (smask?.backdrop) {
+ colorSpace ||= ColorSpace.singletons.rgb;
+ smask.backdrop = colorSpace.getRgb(smask.backdrop, 0);
+ }
+ operatorList.addOp(OPS.beginGroup, [groupOptions]);
+ }
+ const args = group ? [matrix, null] : [matrix, bbox];
+ operatorList.addOp(OPS.paintFormXObjectBegin, args);
+ return this.getOperatorList({
+ stream: xobj,
+ task,
+ resources: dict.get("Resources") || resources,
+ operatorList,
+ initialState
+ }).then(function () {
+ operatorList.addOp(OPS.paintFormXObjectEnd, []);
+ if (group) {
+ operatorList.addOp(OPS.endGroup, [groupOptions]);
+ }
+ if (optionalContent !== undefined) {
+ operatorList.addOp(OPS.endMarkedContent, []);
+ }
+ });
+ }
+ _sendImgData(objId, imgData, cacheGlobally = false) {
+ const transfers = imgData ? [imgData.bitmap || imgData.data.buffer] : null;
+ if (this.parsingType3Font || cacheGlobally) {
+ return this.handler.send("commonobj", [objId, "Image", imgData], transfers);
+ }
+ return this.handler.send("obj", [objId, this.pageIndex, "Image", imgData], transfers);
+ }
+ async buildPaintImageXObject({
+ resources,
+ image,
+ isInline = false,
+ operatorList,
+ cacheKey,
+ localImageCache,
+ localColorSpaceCache
+ }) {
+ const dict = image.dict;
+ const imageRef = dict.objId;
+ const w = dict.get("W", "Width");
+ const h = dict.get("H", "Height");
+ if (!(w && typeof w === "number") || !(h && typeof h === "number")) {
+ warn("Image dimensions are missing, or not numbers.");
+ return;
+ }
+ const maxImageSize = this.options.maxImageSize;
+ if (maxImageSize !== -1 && w * h > maxImageSize) {
+ const msg = "Image exceeded maximum allowed size and was removed.";
+ if (this.options.ignoreErrors) {
+ warn(msg);
+ return;
+ }
+ throw new Error(msg);
+ }
+ let optionalContent;
+ if (dict.has("OC")) {
+ optionalContent = await this.parseMarkedContentProps(dict.get("OC"), resources);
+ }
+ const imageMask = dict.get("IM", "ImageMask") || false;
+ let imgData, args;
+ if (imageMask) {
+ const interpolate = dict.get("I", "Interpolate");
+ const bitStrideLength = w + 7 >> 3;
+ const imgArray = image.getBytes(bitStrideLength * h);
+ const decode = dict.getArray("D", "Decode");
+ if (this.parsingType3Font) {
+ imgData = PDFImage.createRawMask({
+ imgArray,
+ width: w,
+ height: h,
+ imageIsFromDecodeStream: image instanceof DecodeStream,
+ inverseDecode: decode?.[0] > 0,
+ interpolate
+ });
+ imgData.cached = !!cacheKey;
+ args = [imgData];
+ operatorList.addImageOps(OPS.paintImageMaskXObject, args, optionalContent);
+ if (cacheKey) {
+ const cacheData = {
+ fn: OPS.paintImageMaskXObject,
+ args,
+ optionalContent
+ };
+ localImageCache.set(cacheKey, imageRef, cacheData);
+ if (imageRef) {
+ this._regionalImageCache.set(null, imageRef, cacheData);
+ }
+ }
+ return;
+ }
+ imgData = await PDFImage.createMask({
+ imgArray,
+ width: w,
+ height: h,
+ imageIsFromDecodeStream: image instanceof DecodeStream,
+ inverseDecode: decode?.[0] > 0,
+ interpolate,
+ isOffscreenCanvasSupported: this.options.isOffscreenCanvasSupported
+ });
+ if (imgData.isSingleOpaquePixel) {
+ operatorList.addImageOps(OPS.paintSolidColorImageMask, [], optionalContent);
+ if (cacheKey) {
+ const cacheData = {
+ fn: OPS.paintSolidColorImageMask,
+ args: [],
+ optionalContent
+ };
+ localImageCache.set(cacheKey, imageRef, cacheData);
+ if (imageRef) {
+ this._regionalImageCache.set(null, imageRef, cacheData);
+ }
+ }
+ return;
+ }
+ const objId = `mask_${this.idFactory.createObjId()}`;
+ operatorList.addDependency(objId);
+ imgData.dataLen = imgData.bitmap ? imgData.width * imgData.height * 4 : imgData.data.length;
+ this._sendImgData(objId, imgData);
+ args = [{
+ data: objId,
+ width: imgData.width,
+ height: imgData.height,
+ interpolate: imgData.interpolate,
+ count: 1
+ }];
+ operatorList.addImageOps(OPS.paintImageMaskXObject, args, optionalContent);
+ if (cacheKey) {
+ const cacheData = {
+ fn: OPS.paintImageMaskXObject,
+ args,
+ optionalContent
+ };
+ localImageCache.set(cacheKey, imageRef, cacheData);
+ if (imageRef) {
+ this._regionalImageCache.set(null, imageRef, cacheData);
+ }
+ }
+ return;
+ }
+ const SMALL_IMAGE_DIMENSIONS = 200;
+ if (isInline && !dict.has("SMask") && !dict.has("Mask") && w + h < SMALL_IMAGE_DIMENSIONS) {
+ const imageObj = new PDFImage({
+ xref: this.xref,
+ res: resources,
+ image,
+ isInline,
+ pdfFunctionFactory: this._pdfFunctionFactory,
+ localColorSpaceCache
+ });
+ imgData = await imageObj.createImageData(true, false);
+ operatorList.isOffscreenCanvasSupported = this.options.isOffscreenCanvasSupported;
+ operatorList.addImageOps(OPS.paintInlineImageXObject, [imgData], optionalContent);
+ return;
+ }
+ let objId = `img_${this.idFactory.createObjId()}`,
+ cacheGlobally = false;
+ if (this.parsingType3Font) {
+ objId = `${this.idFactory.getDocId()}_type3_${objId}`;
+ } else if (cacheKey && imageRef) {
+ cacheGlobally = this.globalImageCache.shouldCache(imageRef, this.pageIndex);
+ if (cacheGlobally) {
+ assert(!isInline, "Cannot cache an inline image globally.");
+ objId = `${this.idFactory.getDocId()}_${objId}`;
+ }
+ }
+ operatorList.addDependency(objId);
+ args = [objId, w, h];
+ operatorList.addImageOps(OPS.paintImageXObject, args, optionalContent);
+ if (cacheGlobally && w * h > 250000) {
+ const localLength = await this.handler.sendWithPromise("commonobj", [objId, "CopyLocalImage", {
+ imageRef
+ }]);
+ if (localLength) {
+ this.globalImageCache.setData(imageRef, {
+ objId,
+ fn: OPS.paintImageXObject,
+ args,
+ optionalContent,
+ byteSize: 0
+ });
+ this.globalImageCache.addByteSize(imageRef, localLength);
+ return;
+ }
+ }
+ PDFImage.buildImage({
+ xref: this.xref,
+ res: resources,
+ image,
+ isInline,
+ pdfFunctionFactory: this._pdfFunctionFactory,
+ localColorSpaceCache
+ }).then(async imageObj => {
+ imgData = await imageObj.createImageData(false, this.options.isOffscreenCanvasSupported);
+ imgData.dataLen = imgData.bitmap ? imgData.width * imgData.height * 4 : imgData.data.length;
+ imgData.ref = imageRef;
+ if (cacheGlobally) {
+ this.globalImageCache.addByteSize(imageRef, imgData.dataLen);
+ }
+ return this._sendImgData(objId, imgData, cacheGlobally);
+ }).catch(reason => {
+ warn(`Unable to decode image "${objId}": "${reason}".`);
+ return this._sendImgData(objId, null, cacheGlobally);
+ });
+ if (cacheKey) {
+ const cacheData = {
+ fn: OPS.paintImageXObject,
+ args,
+ optionalContent
+ };
+ localImageCache.set(cacheKey, imageRef, cacheData);
+ if (imageRef) {
+ this._regionalImageCache.set(null, imageRef, cacheData);
+ if (cacheGlobally) {
+ this.globalImageCache.setData(imageRef, {
+ objId,
+ fn: OPS.paintImageXObject,
+ args,
+ optionalContent,
+ byteSize: 0
+ });
+ }
+ }
+ }
+ }
+ handleSMask(smask, resources, operatorList, task, stateManager, localColorSpaceCache) {
+ const smaskContent = smask.get("G");
+ const smaskOptions = {
+ subtype: smask.get("S").name,
+ backdrop: smask.get("BC")
+ };
+ const transferObj = smask.get("TR");
+ if (isPDFFunction(transferObj)) {
+ const transferFn = this._pdfFunctionFactory.create(transferObj);
+ const transferMap = new Uint8Array(256);
+ const tmp = new Float32Array(1);
+ for (let i = 0; i < 256; i++) {
+ tmp[0] = i / 255;
+ transferFn(tmp, 0, tmp, 0);
+ transferMap[i] = tmp[0] * 255 | 0;
+ }
+ smaskOptions.transferMap = transferMap;
+ }
+ return this.buildFormXObject(resources, smaskContent, smaskOptions, operatorList, task, stateManager.state.clone(), localColorSpaceCache);
+ }
+ handleTransferFunction(tr) {
+ let transferArray;
+ if (Array.isArray(tr)) {
+ transferArray = tr;
+ } else if (isPDFFunction(tr)) {
+ transferArray = [tr];
+ } else {
+ return null;
+ }
+ const transferMaps = [];
+ let numFns = 0,
+ numEffectfulFns = 0;
+ for (const entry of transferArray) {
+ const transferObj = this.xref.fetchIfRef(entry);
+ numFns++;
+ if (isName(transferObj, "Identity")) {
+ transferMaps.push(null);
+ continue;
+ } else if (!isPDFFunction(transferObj)) {
+ return null;
+ }
+ const transferFn = this._pdfFunctionFactory.create(transferObj);
+ const transferMap = new Uint8Array(256),
+ tmp = new Float32Array(1);
+ for (let j = 0; j < 256; j++) {
+ tmp[0] = j / 255;
+ transferFn(tmp, 0, tmp, 0);
+ transferMap[j] = tmp[0] * 255 | 0;
+ }
+ transferMaps.push(transferMap);
+ numEffectfulFns++;
+ }
+ if (!(numFns === 1 || numFns === 4)) {
+ return null;
+ }
+ if (numEffectfulFns === 0) {
+ return null;
+ }
+ return transferMaps;
+ }
+ handleTilingType(fn, color, resources, pattern, patternDict, operatorList, task, localTilingPatternCache) {
+ const tilingOpList = new OperatorList();
+ const patternResources = Dict.merge({
+ xref: this.xref,
+ dictArray: [patternDict.get("Resources"), resources]
+ });
+ return this.getOperatorList({
+ stream: pattern,
+ task,
+ resources: patternResources,
+ operatorList: tilingOpList
+ }).then(function () {
+ const operatorListIR = tilingOpList.getIR();
+ const tilingPatternIR = getTilingPatternIR(operatorListIR, patternDict, color);
+ operatorList.addDependencies(tilingOpList.dependencies);
+ operatorList.addOp(fn, tilingPatternIR);
+ if (patternDict.objId) {
+ localTilingPatternCache.set(null, patternDict.objId, {
+ operatorListIR,
+ dict: patternDict
+ });
+ }
+ }).catch(reason => {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (this.options.ignoreErrors) {
+ warn(`handleTilingType - ignoring pattern: "${reason}".`);
+ return;
+ }
+ throw reason;
+ });
+ }
+ handleSetFont(resources, fontArgs, fontRef, operatorList, task, state, fallbackFontDict = null, cssFontInfo = null) {
+ const fontName = fontArgs?.[0] instanceof Name ? fontArgs[0].name : null;
+ return this.loadFont(fontName, fontRef, resources, fallbackFontDict, cssFontInfo).then(translated => {
+ if (!translated.font.isType3Font) {
+ return translated;
+ }
+ return translated.loadType3Data(this, resources, task).then(function () {
+ operatorList.addDependencies(translated.type3Dependencies);
+ return translated;
+ }).catch(reason => {
+ return new TranslatedFont({
+ loadedName: "g_font_error",
+ font: new ErrorFont(`Type3 font load error: ${reason}`),
+ dict: translated.font,
+ evaluatorOptions: this.options
+ });
+ });
+ }).then(translated => {
+ state.font = translated.font;
+ translated.send(this.handler);
+ return translated.loadedName;
+ });
+ }
+ handleText(chars, state) {
+ const font = state.font;
+ const glyphs = font.charsToGlyphs(chars);
+ if (font.data) {
+ const isAddToPathSet = !!(state.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG);
+ if (isAddToPathSet || state.fillColorSpace.name === "Pattern" || font.disableFontFace || this.options.disableFontFace) {
+ PartialEvaluator.buildFontPaths(font, glyphs, this.handler, this.options);
+ }
+ }
+ return glyphs;
+ }
+ ensureStateFont(state) {
+ if (state.font) {
+ return;
+ }
+ const reason = new FormatError("Missing setFont (Tf) operator before text rendering operator.");
+ if (this.options.ignoreErrors) {
+ warn(`ensureStateFont: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }
+ async setGState({
+ resources,
+ gState,
+ operatorList,
+ cacheKey,
+ task,
+ stateManager,
+ localGStateCache,
+ localColorSpaceCache
+ }) {
+ const gStateRef = gState.objId;
+ let isSimpleGState = true;
+ const gStateObj = [];
+ let promise = Promise.resolve();
+ for (const key of gState.getKeys()) {
+ const value = gState.get(key);
+ switch (key) {
+ case "Type":
+ break;
+ case "LW":
+ case "LC":
+ case "LJ":
+ case "ML":
+ case "D":
+ case "RI":
+ case "FL":
+ case "CA":
+ case "ca":
+ gStateObj.push([key, value]);
+ break;
+ case "Font":
+ isSimpleGState = false;
+ promise = promise.then(() => {
+ return this.handleSetFont(resources, null, value[0], operatorList, task, stateManager.state).then(function (loadedName) {
+ operatorList.addDependency(loadedName);
+ gStateObj.push([key, [loadedName, value[1]]]);
+ });
+ });
+ break;
+ case "BM":
+ gStateObj.push([key, normalizeBlendMode(value)]);
+ break;
+ case "SMask":
+ if (isName(value, "None")) {
+ gStateObj.push([key, false]);
+ break;
+ }
+ if (value instanceof Dict) {
+ isSimpleGState = false;
+ promise = promise.then(() => {
+ return this.handleSMask(value, resources, operatorList, task, stateManager, localColorSpaceCache);
+ });
+ gStateObj.push([key, true]);
+ } else {
+ warn("Unsupported SMask type");
+ }
+ break;
+ case "TR":
+ const transferMaps = this.handleTransferFunction(value);
+ gStateObj.push([key, transferMaps]);
+ break;
+ case "OP":
+ case "op":
+ case "OPM":
+ case "BG":
+ case "BG2":
+ case "UCR":
+ case "UCR2":
+ case "TR2":
+ case "HT":
+ case "SM":
+ case "SA":
+ case "AIS":
+ case "TK":
+ info("graphic state operator " + key);
+ break;
+ default:
+ info("Unknown graphic state operator " + key);
+ break;
+ }
+ }
+ return promise.then(function () {
+ if (gStateObj.length > 0) {
+ operatorList.addOp(OPS.setGState, [gStateObj]);
+ }
+ if (isSimpleGState) {
+ localGStateCache.set(cacheKey, gStateRef, gStateObj);
+ }
+ });
+ }
+ loadFont(fontName, font, resources, fallbackFontDict = null, cssFontInfo = null) {
+ const errorFont = async () => {
+ return new TranslatedFont({
+ loadedName: "g_font_error",
+ font: new ErrorFont(`Font "${fontName}" is not available.`),
+ dict: font,
+ evaluatorOptions: this.options
+ });
+ };
+ let fontRef;
+ if (font) {
+ if (font instanceof Ref) {
+ fontRef = font;
+ }
+ } else {
+ const fontRes = resources.get("Font");
+ if (fontRes) {
+ fontRef = fontRes.getRaw(fontName);
+ }
+ }
+ if (fontRef) {
+ if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) {
+ return errorFont();
+ }
+ if (this.fontCache.has(fontRef)) {
+ return this.fontCache.get(fontRef);
+ }
+ font = this.xref.fetchIfRef(fontRef);
+ }
+ if (!(font instanceof Dict)) {
+ if (!this.options.ignoreErrors && !this.parsingType3Font) {
+ warn(`Font "${fontName}" is not available.`);
+ return errorFont();
+ }
+ warn(`Font "${fontName}" is not available -- attempting to fallback to a default font.`);
+ font = fallbackFontDict || PartialEvaluator.fallbackFontDict;
+ }
+ if (font.cacheKey && this.fontCache.has(font.cacheKey)) {
+ return this.fontCache.get(font.cacheKey);
+ }
+ const fontCapability = new PromiseCapability();
+ let preEvaluatedFont;
+ try {
+ preEvaluatedFont = this.preEvaluateFont(font);
+ preEvaluatedFont.cssFontInfo = cssFontInfo;
+ } catch (reason) {
+ warn(`loadFont - preEvaluateFont failed: "${reason}".`);
+ return errorFont();
+ }
+ const {
+ descriptor,
+ hash
+ } = preEvaluatedFont;
+ const fontRefIsRef = fontRef instanceof Ref;
+ let fontID;
+ if (hash && descriptor instanceof Dict) {
+ const fontAliases = descriptor.fontAliases ||= Object.create(null);
+ if (fontAliases[hash]) {
+ const aliasFontRef = fontAliases[hash].aliasRef;
+ if (fontRefIsRef && aliasFontRef && this.fontCache.has(aliasFontRef)) {
+ this.fontCache.putAlias(fontRef, aliasFontRef);
+ return this.fontCache.get(fontRef);
+ }
+ } else {
+ fontAliases[hash] = {
+ fontID: this.idFactory.createFontId()
+ };
+ }
+ if (fontRefIsRef) {
+ fontAliases[hash].aliasRef = fontRef;
+ }
+ fontID = fontAliases[hash].fontID;
+ } else {
+ fontID = this.idFactory.createFontId();
+ }
+ assert(fontID?.startsWith("f"), 'The "fontID" must be (correctly) defined.');
+ if (fontRefIsRef) {
+ this.fontCache.put(fontRef, fontCapability.promise);
+ } else {
+ font.cacheKey = `cacheKey_${fontID}`;
+ this.fontCache.put(font.cacheKey, fontCapability.promise);
+ }
+ font.loadedName = `${this.idFactory.getDocId()}_${fontID}`;
+ this.translateFont(preEvaluatedFont).then(translatedFont => {
+ fontCapability.resolve(new TranslatedFont({
+ loadedName: font.loadedName,
+ font: translatedFont,
+ dict: font,
+ evaluatorOptions: this.options
+ }));
+ }).catch(reason => {
+ warn(`loadFont - translateFont failed: "${reason}".`);
+ fontCapability.resolve(new TranslatedFont({
+ loadedName: font.loadedName,
+ font: new ErrorFont(reason instanceof Error ? reason.message : reason),
+ dict: font,
+ evaluatorOptions: this.options
+ }));
+ });
+ return fontCapability.promise;
+ }
+ buildPath(operatorList, fn, args, parsingText = false) {
+ const lastIndex = operatorList.length - 1;
+ if (!args) {
+ args = [];
+ }
+ if (lastIndex < 0 || operatorList.fnArray[lastIndex] !== OPS.constructPath) {
+ if (parsingText) {
+ warn(`Encountered path operator "${fn}" inside of a text object.`);
+ operatorList.addOp(OPS.save, null);
+ }
+ let minMax;
+ switch (fn) {
+ case OPS.rectangle:
+ const x = args[0] + args[2];
+ const y = args[1] + args[3];
+ minMax = [Math.min(args[0], x), Math.max(args[0], x), Math.min(args[1], y), Math.max(args[1], y)];
+ break;
+ case OPS.moveTo:
+ case OPS.lineTo:
+ minMax = [args[0], args[0], args[1], args[1]];
+ break;
+ default:
+ minMax = [Infinity, -Infinity, Infinity, -Infinity];
+ break;
+ }
+ operatorList.addOp(OPS.constructPath, [[fn], args, minMax]);
+ if (parsingText) {
+ operatorList.addOp(OPS.restore, null);
+ }
+ } else {
+ const opArgs = operatorList.argsArray[lastIndex];
+ opArgs[0].push(fn);
+ opArgs[1].push(...args);
+ const minMax = opArgs[2];
+ switch (fn) {
+ case OPS.rectangle:
+ const x = args[0] + args[2];
+ const y = args[1] + args[3];
+ minMax[0] = Math.min(minMax[0], args[0], x);
+ minMax[1] = Math.max(minMax[1], args[0], x);
+ minMax[2] = Math.min(minMax[2], args[1], y);
+ minMax[3] = Math.max(minMax[3], args[1], y);
+ break;
+ case OPS.moveTo:
+ case OPS.lineTo:
+ minMax[0] = Math.min(minMax[0], args[0]);
+ minMax[1] = Math.max(minMax[1], args[0]);
+ minMax[2] = Math.min(minMax[2], args[1]);
+ minMax[3] = Math.max(minMax[3], args[1]);
+ break;
+ }
+ }
+ }
+ parseColorSpace({
+ cs,
+ resources,
+ localColorSpaceCache
+ }) {
+ return ColorSpace.parseAsync({
+ cs,
+ xref: this.xref,
+ resources,
+ pdfFunctionFactory: this._pdfFunctionFactory,
+ localColorSpaceCache
+ }).catch(reason => {
+ if (reason instanceof AbortException) {
+ return null;
+ }
+ if (this.options.ignoreErrors) {
+ warn(`parseColorSpace - ignoring ColorSpace: "${reason}".`);
+ return null;
+ }
+ throw reason;
+ });
+ }
+ parseShading({
+ shading,
+ resources,
+ localColorSpaceCache,
+ localShadingPatternCache
+ }) {
+ let id = localShadingPatternCache.get(shading);
+ if (!id) {
+ var shadingFill = Pattern.parseShading(shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache);
+ const patternIR = shadingFill.getIR();
+ id = `pattern_${this.idFactory.createObjId()}`;
+ if (this.parsingType3Font) {
+ id = `${this.idFactory.getDocId()}_type3_${id}`;
+ }
+ localShadingPatternCache.set(shading, id);
+ if (this.parsingType3Font) {
+ this.handler.send("commonobj", [id, "Pattern", patternIR]);
+ } else {
+ this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]);
+ }
+ }
+ return id;
+ }
+ handleColorN(operatorList, fn, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache) {
+ const patternName = args.pop();
+ if (patternName instanceof Name) {
+ const rawPattern = patterns.getRaw(patternName.name);
+ const localTilingPattern = rawPattern instanceof Ref && localTilingPatternCache.getByRef(rawPattern);
+ if (localTilingPattern) {
+ try {
+ const color = cs.base ? cs.base.getRgb(args, 0) : null;
+ const tilingPatternIR = getTilingPatternIR(localTilingPattern.operatorListIR, localTilingPattern.dict, color);
+ operatorList.addOp(fn, tilingPatternIR);
+ return undefined;
+ } catch {}
+ }
+ const pattern = this.xref.fetchIfRef(rawPattern);
+ if (pattern) {
+ const dict = pattern instanceof BaseStream ? pattern.dict : pattern;
+ const typeNum = dict.get("PatternType");
+ if (typeNum === PatternType.TILING) {
+ const color = cs.base ? cs.base.getRgb(args, 0) : null;
+ return this.handleTilingType(fn, color, resources, pattern, dict, operatorList, task, localTilingPatternCache);
+ } else if (typeNum === PatternType.SHADING) {
+ const shading = dict.get("Shading");
+ const matrix = dict.getArray("Matrix");
+ const objId = this.parseShading({
+ shading,
+ resources,
+ localColorSpaceCache,
+ localShadingPatternCache
+ });
+ operatorList.addOp(fn, ["Shading", objId, matrix]);
+ return undefined;
+ }
+ throw new FormatError(`Unknown PatternType: ${typeNum}`);
+ }
+ }
+ throw new FormatError(`Unknown PatternName: ${patternName}`);
+ }
+ _parseVisibilityExpression(array, nestingCounter, currentResult) {
+ const MAX_NESTING = 10;
+ if (++nestingCounter > MAX_NESTING) {
+ warn("Visibility expression is too deeply nested");
+ return;
+ }
+ const length = array.length;
+ const operator = this.xref.fetchIfRef(array[0]);
+ if (length < 2 || !(operator instanceof Name)) {
+ warn("Invalid visibility expression");
+ return;
+ }
+ switch (operator.name) {
+ case "And":
+ case "Or":
+ case "Not":
+ currentResult.push(operator.name);
+ break;
+ default:
+ warn(`Invalid operator ${operator.name} in visibility expression`);
+ return;
+ }
+ for (let i = 1; i < length; i++) {
+ const raw = array[i];
+ const object = this.xref.fetchIfRef(raw);
+ if (Array.isArray(object)) {
+ const nestedResult = [];
+ currentResult.push(nestedResult);
+ this._parseVisibilityExpression(object, nestingCounter, nestedResult);
+ } else if (raw instanceof Ref) {
+ currentResult.push(raw.toString());
+ }
+ }
+ }
+ async parseMarkedContentProps(contentProperties, resources) {
+ let optionalContent;
+ if (contentProperties instanceof Name) {
+ const properties = resources.get("Properties");
+ optionalContent = properties.get(contentProperties.name);
+ } else if (contentProperties instanceof Dict) {
+ optionalContent = contentProperties;
+ } else {
+ throw new FormatError("Optional content properties malformed.");
+ }
+ const optionalContentType = optionalContent.get("Type")?.name;
+ if (optionalContentType === "OCG") {
+ return {
+ type: optionalContentType,
+ id: optionalContent.objId
+ };
+ } else if (optionalContentType === "OCMD") {
+ const expression = optionalContent.get("VE");
+ if (Array.isArray(expression)) {
+ const result = [];
+ this._parseVisibilityExpression(expression, 0, result);
+ if (result.length > 0) {
+ return {
+ type: "OCMD",
+ expression: result
+ };
+ }
+ }
+ const optionalContentGroups = optionalContent.get("OCGs");
+ if (Array.isArray(optionalContentGroups) || optionalContentGroups instanceof Dict) {
+ const groupIds = [];
+ if (Array.isArray(optionalContentGroups)) {
+ for (const ocg of optionalContentGroups) {
+ groupIds.push(ocg.toString());
+ }
+ } else {
+ groupIds.push(optionalContentGroups.objId);
+ }
+ return {
+ type: optionalContentType,
+ ids: groupIds,
+ policy: optionalContent.get("P") instanceof Name ? optionalContent.get("P").name : null,
+ expression: null
+ };
+ } else if (optionalContentGroups instanceof Ref) {
+ return {
+ type: optionalContentType,
+ id: optionalContentGroups.toString()
+ };
+ }
+ }
+ return null;
+ }
+ getOperatorList({
+ stream,
+ task,
+ resources,
+ operatorList,
+ initialState = null,
+ fallbackFontDict = null
+ }) {
+ resources ||= Dict.empty;
+ initialState ||= new EvalState();
+ if (!operatorList) {
+ throw new Error('getOperatorList: missing "operatorList" parameter');
+ }
+ const self = this;
+ const xref = this.xref;
+ let parsingText = false;
+ const localImageCache = new LocalImageCache();
+ const localColorSpaceCache = new LocalColorSpaceCache();
+ const localGStateCache = new LocalGStateCache();
+ const localTilingPatternCache = new LocalTilingPatternCache();
+ const localShadingPatternCache = new Map();
+ const xobjs = resources.get("XObject") || Dict.empty;
+ const patterns = resources.get("Pattern") || Dict.empty;
+ const stateManager = new StateManager(initialState);
+ const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);
+ const timeSlotManager = new TimeSlotManager();
+ function closePendingRestoreOPS(argument) {
+ for (let i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {
+ operatorList.addOp(OPS.restore, []);
+ }
+ }
+ return new Promise(function promiseBody(resolve, reject) {
+ const next = function (promise) {
+ Promise.all([promise, operatorList.ready]).then(function () {
+ try {
+ promiseBody(resolve, reject);
+ } catch (ex) {
+ reject(ex);
+ }
+ }, reject);
+ };
+ task.ensureNotTerminated();
+ timeSlotManager.reset();
+ const operation = {};
+ let stop, i, ii, cs, name, isValidName;
+ while (!(stop = timeSlotManager.check())) {
+ operation.args = null;
+ if (!preprocessor.read(operation)) {
+ break;
+ }
+ let args = operation.args;
+ let fn = operation.fn;
+ switch (fn | 0) {
+ case OPS.paintXObject:
+ isValidName = args[0] instanceof Name;
+ name = args[0].name;
+ if (isValidName) {
+ const localImage = localImageCache.getByName(name);
+ if (localImage) {
+ operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);
+ incrementCachedImageMaskCount(localImage);
+ args = null;
+ continue;
+ }
+ }
+ next(new Promise(function (resolveXObject, rejectXObject) {
+ if (!isValidName) {
+ throw new FormatError("XObject must be referred to by name.");
+ }
+ let xobj = xobjs.getRaw(name);
+ if (xobj instanceof Ref) {
+ const localImage = localImageCache.getByRef(xobj) || self._regionalImageCache.getByRef(xobj);
+ if (localImage) {
+ operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);
+ incrementCachedImageMaskCount(localImage);
+ resolveXObject();
+ return;
+ }
+ const globalImage = self.globalImageCache.getData(xobj, self.pageIndex);
+ if (globalImage) {
+ operatorList.addDependency(globalImage.objId);
+ operatorList.addImageOps(globalImage.fn, globalImage.args, globalImage.optionalContent);
+ resolveXObject();
+ return;
+ }
+ xobj = xref.fetch(xobj);
+ }
+ if (!(xobj instanceof BaseStream)) {
+ throw new FormatError("XObject should be a stream");
+ }
+ const type = xobj.dict.get("Subtype");
+ if (!(type instanceof Name)) {
+ throw new FormatError("XObject should have a Name subtype");
+ }
+ if (type.name === "Form") {
+ stateManager.save();
+ self.buildFormXObject(resources, xobj, null, operatorList, task, stateManager.state.clone(), localColorSpaceCache).then(function () {
+ stateManager.restore();
+ resolveXObject();
+ }, rejectXObject);
+ return;
+ } else if (type.name === "Image") {
+ self.buildPaintImageXObject({
+ resources,
+ image: xobj,
+ operatorList,
+ cacheKey: name,
+ localImageCache,
+ localColorSpaceCache
+ }).then(resolveXObject, rejectXObject);
+ return;
+ } else if (type.name === "PS") {
+ info("Ignored XObject subtype PS");
+ } else {
+ throw new FormatError(`Unhandled XObject subtype ${type.name}`);
+ }
+ resolveXObject();
+ }).catch(function (reason) {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (self.options.ignoreErrors) {
+ warn(`getOperatorList - ignoring XObject: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }));
+ return;
+ case OPS.setFont:
+ var fontSize = args[1];
+ next(self.handleSetFont(resources, args, null, operatorList, task, stateManager.state, fallbackFontDict).then(function (loadedName) {
+ operatorList.addDependency(loadedName);
+ operatorList.addOp(OPS.setFont, [loadedName, fontSize]);
+ }));
+ return;
+ case OPS.beginText:
+ parsingText = true;
+ break;
+ case OPS.endText:
+ parsingText = false;
+ break;
+ case OPS.endInlineImage:
+ var cacheKey = args[0].cacheKey;
+ if (cacheKey) {
+ const localImage = localImageCache.getByName(cacheKey);
+ if (localImage) {
+ operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent);
+ incrementCachedImageMaskCount(localImage);
+ args = null;
+ continue;
+ }
+ }
+ next(self.buildPaintImageXObject({
+ resources,
+ image: args[0],
+ isInline: true,
+ operatorList,
+ cacheKey,
+ localImageCache,
+ localColorSpaceCache
+ }));
+ return;
+ case OPS.showText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ args[0] = self.handleText(args[0], stateManager.state);
+ break;
+ case OPS.showSpacedText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ var combinedGlyphs = [];
+ var state = stateManager.state;
+ for (const arrItem of args[0]) {
+ if (typeof arrItem === "string") {
+ combinedGlyphs.push(...self.handleText(arrItem, state));
+ } else if (typeof arrItem === "number") {
+ combinedGlyphs.push(arrItem);
+ }
+ }
+ args[0] = combinedGlyphs;
+ fn = OPS.showText;
+ break;
+ case OPS.nextLineShowText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ operatorList.addOp(OPS.nextLine);
+ args[0] = self.handleText(args[0], stateManager.state);
+ fn = OPS.showText;
+ break;
+ case OPS.nextLineSetSpacingShowText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ operatorList.addOp(OPS.nextLine);
+ operatorList.addOp(OPS.setWordSpacing, [args.shift()]);
+ operatorList.addOp(OPS.setCharSpacing, [args.shift()]);
+ args[0] = self.handleText(args[0], stateManager.state);
+ fn = OPS.showText;
+ break;
+ case OPS.setTextRenderingMode:
+ stateManager.state.textRenderingMode = args[0];
+ break;
+ case OPS.setFillColorSpace:
+ {
+ const cachedColorSpace = ColorSpace.getCached(args[0], xref, localColorSpaceCache);
+ if (cachedColorSpace) {
+ stateManager.state.fillColorSpace = cachedColorSpace;
+ continue;
+ }
+ next(self.parseColorSpace({
+ cs: args[0],
+ resources,
+ localColorSpaceCache
+ }).then(function (colorSpace) {
+ if (colorSpace) {
+ stateManager.state.fillColorSpace = colorSpace;
+ }
+ }));
+ return;
+ }
+ case OPS.setStrokeColorSpace:
+ {
+ const cachedColorSpace = ColorSpace.getCached(args[0], xref, localColorSpaceCache);
+ if (cachedColorSpace) {
+ stateManager.state.strokeColorSpace = cachedColorSpace;
+ continue;
+ }
+ next(self.parseColorSpace({
+ cs: args[0],
+ resources,
+ localColorSpaceCache
+ }).then(function (colorSpace) {
+ if (colorSpace) {
+ stateManager.state.strokeColorSpace = colorSpace;
+ }
+ }));
+ return;
+ }
+ case OPS.setFillColor:
+ cs = stateManager.state.fillColorSpace;
+ args = cs.getRgb(args, 0);
+ fn = OPS.setFillRGBColor;
+ break;
+ case OPS.setStrokeColor:
+ cs = stateManager.state.strokeColorSpace;
+ args = cs.getRgb(args, 0);
+ fn = OPS.setStrokeRGBColor;
+ break;
+ case OPS.setFillGray:
+ stateManager.state.fillColorSpace = ColorSpace.singletons.gray;
+ args = ColorSpace.singletons.gray.getRgb(args, 0);
+ fn = OPS.setFillRGBColor;
+ break;
+ case OPS.setStrokeGray:
+ stateManager.state.strokeColorSpace = ColorSpace.singletons.gray;
+ args = ColorSpace.singletons.gray.getRgb(args, 0);
+ fn = OPS.setStrokeRGBColor;
+ break;
+ case OPS.setFillCMYKColor:
+ stateManager.state.fillColorSpace = ColorSpace.singletons.cmyk;
+ args = ColorSpace.singletons.cmyk.getRgb(args, 0);
+ fn = OPS.setFillRGBColor;
+ break;
+ case OPS.setStrokeCMYKColor:
+ stateManager.state.strokeColorSpace = ColorSpace.singletons.cmyk;
+ args = ColorSpace.singletons.cmyk.getRgb(args, 0);
+ fn = OPS.setStrokeRGBColor;
+ break;
+ case OPS.setFillRGBColor:
+ stateManager.state.fillColorSpace = ColorSpace.singletons.rgb;
+ args = ColorSpace.singletons.rgb.getRgb(args, 0);
+ break;
+ case OPS.setStrokeRGBColor:
+ stateManager.state.strokeColorSpace = ColorSpace.singletons.rgb;
+ args = ColorSpace.singletons.rgb.getRgb(args, 0);
+ break;
+ case OPS.setFillColorN:
+ cs = stateManager.state.fillColorSpace;
+ if (cs.name === "Pattern") {
+ next(self.handleColorN(operatorList, OPS.setFillColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache));
+ return;
+ }
+ args = cs.getRgb(args, 0);
+ fn = OPS.setFillRGBColor;
+ break;
+ case OPS.setStrokeColorN:
+ cs = stateManager.state.strokeColorSpace;
+ if (cs.name === "Pattern") {
+ next(self.handleColorN(operatorList, OPS.setStrokeColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache));
+ return;
+ }
+ args = cs.getRgb(args, 0);
+ fn = OPS.setStrokeRGBColor;
+ break;
+ case OPS.shadingFill:
+ var shadingRes = resources.get("Shading");
+ if (!shadingRes) {
+ throw new FormatError("No shading resource found");
+ }
+ var shading = shadingRes.get(args[0].name);
+ if (!shading) {
+ throw new FormatError("No shading object found");
+ }
+ const patternId = self.parseShading({
+ shading,
+ resources,
+ localColorSpaceCache,
+ localShadingPatternCache
+ });
+ args = [patternId];
+ fn = OPS.shadingFill;
+ break;
+ case OPS.setGState:
+ isValidName = args[0] instanceof Name;
+ name = args[0].name;
+ if (isValidName) {
+ const localGStateObj = localGStateCache.getByName(name);
+ if (localGStateObj) {
+ if (localGStateObj.length > 0) {
+ operatorList.addOp(OPS.setGState, [localGStateObj]);
+ }
+ args = null;
+ continue;
+ }
+ }
+ next(new Promise(function (resolveGState, rejectGState) {
+ if (!isValidName) {
+ throw new FormatError("GState must be referred to by name.");
+ }
+ const extGState = resources.get("ExtGState");
+ if (!(extGState instanceof Dict)) {
+ throw new FormatError("ExtGState should be a dictionary.");
+ }
+ const gState = extGState.get(name);
+ if (!(gState instanceof Dict)) {
+ throw new FormatError("GState should be a dictionary.");
+ }
+ self.setGState({
+ resources,
+ gState,
+ operatorList,
+ cacheKey: name,
+ task,
+ stateManager,
+ localGStateCache,
+ localColorSpaceCache
+ }).then(resolveGState, rejectGState);
+ }).catch(function (reason) {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (self.options.ignoreErrors) {
+ warn(`getOperatorList - ignoring ExtGState: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }));
+ return;
+ case OPS.moveTo:
+ case OPS.lineTo:
+ case OPS.curveTo:
+ case OPS.curveTo2:
+ case OPS.curveTo3:
+ case OPS.closePath:
+ case OPS.rectangle:
+ self.buildPath(operatorList, fn, args, parsingText);
+ continue;
+ case OPS.markPoint:
+ case OPS.markPointProps:
+ case OPS.beginCompat:
+ case OPS.endCompat:
+ continue;
+ case OPS.beginMarkedContentProps:
+ if (!(args[0] instanceof Name)) {
+ warn(`Expected name for beginMarkedContentProps arg0=${args[0]}`);
+ continue;
+ }
+ if (args[0].name === "OC") {
+ next(self.parseMarkedContentProps(args[1], resources).then(data => {
+ operatorList.addOp(OPS.beginMarkedContentProps, ["OC", data]);
+ }).catch(reason => {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (self.options.ignoreErrors) {
+ warn(`getOperatorList - ignoring beginMarkedContentProps: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }));
+ return;
+ }
+ args = [args[0].name, args[1] instanceof Dict ? args[1].get("MCID") : null];
+ break;
+ case OPS.beginMarkedContent:
+ case OPS.endMarkedContent:
+ default:
+ if (args !== null) {
+ for (i = 0, ii = args.length; i < ii; i++) {
+ if (args[i] instanceof Dict) {
+ break;
+ }
+ }
+ if (i < ii) {
+ warn("getOperatorList - ignoring operator: " + fn);
+ continue;
+ }
+ }
+ }
+ operatorList.addOp(fn, args);
+ }
+ if (stop) {
+ next(deferred);
+ return;
+ }
+ closePendingRestoreOPS();
+ resolve();
+ }).catch(reason => {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (this.options.ignoreErrors) {
+ warn(`getOperatorList - ignoring errors during "${task.name}" ` + `task: "${reason}".`);
+ closePendingRestoreOPS();
+ return;
+ }
+ throw reason;
+ });
+ }
+ getTextContent({
+ stream,
+ task,
+ resources,
+ stateManager = null,
+ includeMarkedContent = false,
+ sink,
+ seenStyles = new Set(),
+ viewBox,
+ markedContentData = null,
+ disableNormalization = false
+ }) {
+ resources ||= Dict.empty;
+ stateManager ||= new StateManager(new TextState());
+ if (includeMarkedContent) {
+ markedContentData ||= {
+ level: 0
+ };
+ }
+ const textContent = {
+ items: [],
+ styles: Object.create(null)
+ };
+ const textContentItem = {
+ initialized: false,
+ str: [],
+ totalWidth: 0,
+ totalHeight: 0,
+ width: 0,
+ height: 0,
+ vertical: false,
+ prevTransform: null,
+ textAdvanceScale: 0,
+ spaceInFlowMin: 0,
+ spaceInFlowMax: 0,
+ trackingSpaceMin: Infinity,
+ negativeSpaceMax: -Infinity,
+ notASpace: -Infinity,
+ transform: null,
+ fontName: null,
+ hasEOL: false
+ };
+ const twoLastChars = [" ", " "];
+ let twoLastCharsPos = 0;
+ function saveLastChar(char) {
+ const nextPos = (twoLastCharsPos + 1) % 2;
+ const ret = twoLastChars[twoLastCharsPos] !== " " && twoLastChars[nextPos] === " ";
+ twoLastChars[twoLastCharsPos] = char;
+ twoLastCharsPos = nextPos;
+ return ret;
+ }
+ function shouldAddWhitepsace() {
+ return twoLastChars[twoLastCharsPos] !== " " && twoLastChars[(twoLastCharsPos + 1) % 2] === " ";
+ }
+ function resetLastChars() {
+ twoLastChars[0] = twoLastChars[1] = " ";
+ twoLastCharsPos = 0;
+ }
+ const TRACKING_SPACE_FACTOR = 0.102;
+ const NOT_A_SPACE_FACTOR = 0.03;
+ const NEGATIVE_SPACE_FACTOR = -0.2;
+ const SPACE_IN_FLOW_MIN_FACTOR = 0.102;
+ const SPACE_IN_FLOW_MAX_FACTOR = 0.6;
+ const VERTICAL_SHIFT_RATIO = 0.25;
+ const self = this;
+ const xref = this.xref;
+ const showSpacedTextBuffer = [];
+ let xobjs = null;
+ const emptyXObjectCache = new LocalImageCache();
+ const emptyGStateCache = new LocalGStateCache();
+ const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);
+ let textState;
+ function pushWhitespace({
+ width = 0,
+ height = 0,
+ transform = textContentItem.prevTransform,
+ fontName = textContentItem.fontName
+ }) {
+ textContent.items.push({
+ str: " ",
+ dir: "ltr",
+ width,
+ height,
+ transform,
+ fontName,
+ hasEOL: false
+ });
+ }
+ function getCurrentTextTransform() {
+ const font = textState.font;
+ const tsm = [textState.fontSize * textState.textHScale, 0, 0, textState.fontSize, 0, textState.textRise];
+ if (font.isType3Font && (textState.fontSize <= 1 || font.isCharBBox) && !isArrayEqual(textState.fontMatrix, FONT_IDENTITY_MATRIX)) {
+ const glyphHeight = font.bbox[3] - font.bbox[1];
+ if (glyphHeight > 0) {
+ tsm[3] *= glyphHeight * textState.fontMatrix[3];
+ }
+ }
+ return Util.transform(textState.ctm, Util.transform(textState.textMatrix, tsm));
+ }
+ function ensureTextContentItem() {
+ if (textContentItem.initialized) {
+ return textContentItem;
+ }
+ const {
+ font,
+ loadedName
+ } = textState;
+ if (!seenStyles.has(loadedName)) {
+ seenStyles.add(loadedName);
+ textContent.styles[loadedName] = {
+ fontFamily: font.fallbackName,
+ ascent: font.ascent,
+ descent: font.descent,
+ vertical: font.vertical
+ };
+ if (self.options.fontExtraProperties && font.systemFontInfo) {
+ const style = textContent.styles[loadedName];
+ style.fontSubstitution = font.systemFontInfo.css;
+ style.fontSubstitutionLoadedName = font.systemFontInfo.loadedName;
+ }
+ }
+ textContentItem.fontName = loadedName;
+ const trm = textContentItem.transform = getCurrentTextTransform();
+ if (!font.vertical) {
+ textContentItem.width = textContentItem.totalWidth = 0;
+ textContentItem.height = textContentItem.totalHeight = Math.hypot(trm[2], trm[3]);
+ textContentItem.vertical = false;
+ } else {
+ textContentItem.width = textContentItem.totalWidth = Math.hypot(trm[0], trm[1]);
+ textContentItem.height = textContentItem.totalHeight = 0;
+ textContentItem.vertical = true;
+ }
+ const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]);
+ const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);
+ textContentItem.textAdvanceScale = scaleCtmX * scaleLineX;
+ const {
+ fontSize
+ } = textState;
+ textContentItem.trackingSpaceMin = fontSize * TRACKING_SPACE_FACTOR;
+ textContentItem.notASpace = fontSize * NOT_A_SPACE_FACTOR;
+ textContentItem.negativeSpaceMax = fontSize * NEGATIVE_SPACE_FACTOR;
+ textContentItem.spaceInFlowMin = fontSize * SPACE_IN_FLOW_MIN_FACTOR;
+ textContentItem.spaceInFlowMax = fontSize * SPACE_IN_FLOW_MAX_FACTOR;
+ textContentItem.hasEOL = false;
+ textContentItem.initialized = true;
+ return textContentItem;
+ }
+ function updateAdvanceScale() {
+ if (!textContentItem.initialized) {
+ return;
+ }
+ const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]);
+ const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);
+ const scaleFactor = scaleCtmX * scaleLineX;
+ if (scaleFactor === textContentItem.textAdvanceScale) {
+ return;
+ }
+ if (!textContentItem.vertical) {
+ textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale;
+ textContentItem.width = 0;
+ } else {
+ textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale;
+ textContentItem.height = 0;
+ }
+ textContentItem.textAdvanceScale = scaleFactor;
+ }
+ function runBidiTransform(textChunk) {
+ let text = textChunk.str.join("");
+ if (!disableNormalization) {
+ text = normalizeUnicode(text);
+ }
+ const bidiResult = bidi(text, -1, textChunk.vertical);
+ return {
+ str: bidiResult.str,
+ dir: bidiResult.dir,
+ width: Math.abs(textChunk.totalWidth),
+ height: Math.abs(textChunk.totalHeight),
+ transform: textChunk.transform,
+ fontName: textChunk.fontName,
+ hasEOL: textChunk.hasEOL
+ };
+ }
+ function handleSetFont(fontName, fontRef) {
+ return self.loadFont(fontName, fontRef, resources).then(function (translated) {
+ if (!translated.font.isType3Font) {
+ return translated;
+ }
+ return translated.loadType3Data(self, resources, task).catch(function () {}).then(function () {
+ return translated;
+ });
+ }).then(function (translated) {
+ textState.loadedName = translated.loadedName;
+ textState.font = translated.font;
+ textState.fontMatrix = translated.font.fontMatrix || FONT_IDENTITY_MATRIX;
+ });
+ }
+ function applyInverseRotation(x, y, matrix) {
+ const scale = Math.hypot(matrix[0], matrix[1]);
+ return [(matrix[0] * x + matrix[1] * y) / scale, (matrix[2] * x + matrix[3] * y) / scale];
+ }
+ function compareWithLastPosition(glyphWidth) {
+ const currentTransform = getCurrentTextTransform();
+ let posX = currentTransform[4];
+ let posY = currentTransform[5];
+ if (textState.font?.vertical) {
+ if (posX < viewBox[0] || posX > viewBox[2] || posY + glyphWidth < viewBox[1] || posY > viewBox[3]) {
+ return false;
+ }
+ } else if (posX + glyphWidth < viewBox[0] || posX > viewBox[2] || posY < viewBox[1] || posY > viewBox[3]) {
+ return false;
+ }
+ if (!textState.font || !textContentItem.prevTransform) {
+ return true;
+ }
+ let lastPosX = textContentItem.prevTransform[4];
+ let lastPosY = textContentItem.prevTransform[5];
+ if (lastPosX === posX && lastPosY === posY) {
+ return true;
+ }
+ let rotate = -1;
+ if (currentTransform[0] && currentTransform[1] === 0 && currentTransform[2] === 0) {
+ rotate = currentTransform[0] > 0 ? 0 : 180;
+ } else if (currentTransform[1] && currentTransform[0] === 0 && currentTransform[3] === 0) {
+ rotate = currentTransform[1] > 0 ? 90 : 270;
+ }
+ switch (rotate) {
+ case 0:
+ break;
+ case 90:
+ [posX, posY] = [posY, posX];
+ [lastPosX, lastPosY] = [lastPosY, lastPosX];
+ break;
+ case 180:
+ [posX, posY, lastPosX, lastPosY] = [-posX, -posY, -lastPosX, -lastPosY];
+ break;
+ case 270:
+ [posX, posY] = [-posY, -posX];
+ [lastPosX, lastPosY] = [-lastPosY, -lastPosX];
+ break;
+ default:
+ [posX, posY] = applyInverseRotation(posX, posY, currentTransform);
+ [lastPosX, lastPosY] = applyInverseRotation(lastPosX, lastPosY, textContentItem.prevTransform);
+ }
+ if (textState.font.vertical) {
+ const advanceY = (lastPosY - posY) / textContentItem.textAdvanceScale;
+ const advanceX = posX - lastPosX;
+ const textOrientation = Math.sign(textContentItem.height);
+ if (advanceY < textOrientation * textContentItem.negativeSpaceMax) {
+ if (Math.abs(advanceX) > 0.5 * textContentItem.width) {
+ appendEOL();
+ return true;
+ }
+ resetLastChars();
+ flushTextContentItem();
+ return true;
+ }
+ if (Math.abs(advanceX) > textContentItem.width) {
+ appendEOL();
+ return true;
+ }
+ if (advanceY <= textOrientation * textContentItem.notASpace) {
+ resetLastChars();
+ }
+ if (advanceY <= textOrientation * textContentItem.trackingSpaceMin) {
+ if (shouldAddWhitepsace()) {
+ resetLastChars();
+ flushTextContentItem();
+ pushWhitespace({
+ height: Math.abs(advanceY)
+ });
+ } else {
+ textContentItem.height += advanceY;
+ }
+ } else if (!addFakeSpaces(advanceY, textContentItem.prevTransform, textOrientation)) {
+ if (textContentItem.str.length === 0) {
+ resetLastChars();
+ pushWhitespace({
+ height: Math.abs(advanceY)
+ });
+ } else {
+ textContentItem.height += advanceY;
+ }
+ }
+ if (Math.abs(advanceX) > textContentItem.width * VERTICAL_SHIFT_RATIO) {
+ flushTextContentItem();
+ }
+ return true;
+ }
+ const advanceX = (posX - lastPosX) / textContentItem.textAdvanceScale;
+ const advanceY = posY - lastPosY;
+ const textOrientation = Math.sign(textContentItem.width);
+ if (advanceX < textOrientation * textContentItem.negativeSpaceMax) {
+ if (Math.abs(advanceY) > 0.5 * textContentItem.height) {
+ appendEOL();
+ return true;
+ }
+ resetLastChars();
+ flushTextContentItem();
+ return true;
+ }
+ if (Math.abs(advanceY) > textContentItem.height) {
+ appendEOL();
+ return true;
+ }
+ if (advanceX <= textOrientation * textContentItem.notASpace) {
+ resetLastChars();
+ }
+ if (advanceX <= textOrientation * textContentItem.trackingSpaceMin) {
+ if (shouldAddWhitepsace()) {
+ resetLastChars();
+ flushTextContentItem();
+ pushWhitespace({
+ width: Math.abs(advanceX)
+ });
+ } else {
+ textContentItem.width += advanceX;
+ }
+ } else if (!addFakeSpaces(advanceX, textContentItem.prevTransform, textOrientation)) {
+ if (textContentItem.str.length === 0) {
+ resetLastChars();
+ pushWhitespace({
+ width: Math.abs(advanceX)
+ });
+ } else {
+ textContentItem.width += advanceX;
+ }
+ }
+ if (Math.abs(advanceY) > textContentItem.height * VERTICAL_SHIFT_RATIO) {
+ flushTextContentItem();
+ }
+ return true;
+ }
+ function buildTextContentItem({
+ chars,
+ extraSpacing
+ }) {
+ const font = textState.font;
+ if (!chars) {
+ const charSpacing = textState.charSpacing + extraSpacing;
+ if (charSpacing) {
+ if (!font.vertical) {
+ textState.translateTextMatrix(charSpacing * textState.textHScale, 0);
+ } else {
+ textState.translateTextMatrix(0, -charSpacing);
+ }
+ }
+ return;
+ }
+ const glyphs = font.charsToGlyphs(chars);
+ const scale = textState.fontMatrix[0] * textState.fontSize;
+ for (let i = 0, ii = glyphs.length; i < ii; i++) {
+ const glyph = glyphs[i];
+ const {
+ category
+ } = glyph;
+ if (category.isInvisibleFormatMark) {
+ continue;
+ }
+ let charSpacing = textState.charSpacing + (i + 1 === ii ? extraSpacing : 0);
+ let glyphWidth = glyph.width;
+ if (font.vertical) {
+ glyphWidth = glyph.vmetric ? glyph.vmetric[0] : -glyphWidth;
+ }
+ let scaledDim = glyphWidth * scale;
+ if (category.isWhitespace) {
+ if (!font.vertical) {
+ charSpacing += scaledDim + textState.wordSpacing;
+ textState.translateTextMatrix(charSpacing * textState.textHScale, 0);
+ } else {
+ charSpacing += -scaledDim + textState.wordSpacing;
+ textState.translateTextMatrix(0, -charSpacing);
+ }
+ saveLastChar(" ");
+ continue;
+ }
+ if (!category.isZeroWidthDiacritic && !compareWithLastPosition(scaledDim)) {
+ if (!font.vertical) {
+ textState.translateTextMatrix(scaledDim * textState.textHScale, 0);
+ } else {
+ textState.translateTextMatrix(0, scaledDim);
+ }
+ continue;
+ }
+ const textChunk = ensureTextContentItem();
+ if (category.isZeroWidthDiacritic) {
+ scaledDim = 0;
+ }
+ if (!font.vertical) {
+ scaledDim *= textState.textHScale;
+ textState.translateTextMatrix(scaledDim, 0);
+ textChunk.width += scaledDim;
+ } else {
+ textState.translateTextMatrix(0, scaledDim);
+ scaledDim = Math.abs(scaledDim);
+ textChunk.height += scaledDim;
+ }
+ if (scaledDim) {
+ textChunk.prevTransform = getCurrentTextTransform();
+ }
+ const glyphUnicode = glyph.unicode;
+ if (saveLastChar(glyphUnicode)) {
+ textChunk.str.push(" ");
+ }
+ textChunk.str.push(glyphUnicode);
+ if (charSpacing) {
+ if (!font.vertical) {
+ textState.translateTextMatrix(charSpacing * textState.textHScale, 0);
+ } else {
+ textState.translateTextMatrix(0, -charSpacing);
+ }
+ }
+ }
+ }
+ function appendEOL() {
+ resetLastChars();
+ if (textContentItem.initialized) {
+ textContentItem.hasEOL = true;
+ flushTextContentItem();
+ } else {
+ textContent.items.push({
+ str: "",
+ dir: "ltr",
+ width: 0,
+ height: 0,
+ transform: getCurrentTextTransform(),
+ fontName: textState.loadedName,
+ hasEOL: true
+ });
+ }
+ }
+ function addFakeSpaces(width, transf, textOrientation) {
+ if (textOrientation * textContentItem.spaceInFlowMin <= width && width <= textOrientation * textContentItem.spaceInFlowMax) {
+ if (textContentItem.initialized) {
+ resetLastChars();
+ textContentItem.str.push(" ");
+ }
+ return false;
+ }
+ const fontName = textContentItem.fontName;
+ let height = 0;
+ if (textContentItem.vertical) {
+ height = width;
+ width = 0;
+ }
+ flushTextContentItem();
+ resetLastChars();
+ pushWhitespace({
+ width: Math.abs(width),
+ height: Math.abs(height),
+ transform: transf || getCurrentTextTransform(),
+ fontName
+ });
+ return true;
+ }
+ function flushTextContentItem() {
+ if (!textContentItem.initialized || !textContentItem.str) {
+ return;
+ }
+ if (!textContentItem.vertical) {
+ textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale;
+ } else {
+ textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale;
+ }
+ textContent.items.push(runBidiTransform(textContentItem));
+ textContentItem.initialized = false;
+ textContentItem.str.length = 0;
+ }
+ function enqueueChunk(batch = false) {
+ const length = textContent.items.length;
+ if (length === 0) {
+ return;
+ }
+ if (batch && length < TEXT_CHUNK_BATCH_SIZE) {
+ return;
+ }
+ sink.enqueue(textContent, length);
+ textContent.items = [];
+ textContent.styles = Object.create(null);
+ }
+ const timeSlotManager = new TimeSlotManager();
+ return new Promise(function promiseBody(resolve, reject) {
+ const next = function (promise) {
+ enqueueChunk(true);
+ Promise.all([promise, sink.ready]).then(function () {
+ try {
+ promiseBody(resolve, reject);
+ } catch (ex) {
+ reject(ex);
+ }
+ }, reject);
+ };
+ task.ensureNotTerminated();
+ timeSlotManager.reset();
+ const operation = {};
+ let stop,
+ args = [];
+ while (!(stop = timeSlotManager.check())) {
+ args.length = 0;
+ operation.args = args;
+ if (!preprocessor.read(operation)) {
+ break;
+ }
+ const previousState = textState;
+ textState = stateManager.state;
+ const fn = operation.fn;
+ args = operation.args;
+ switch (fn | 0) {
+ case OPS.setFont:
+ var fontNameArg = args[0].name,
+ fontSizeArg = args[1];
+ if (textState.font && fontNameArg === textState.fontName && fontSizeArg === textState.fontSize) {
+ break;
+ }
+ flushTextContentItem();
+ textState.fontName = fontNameArg;
+ textState.fontSize = fontSizeArg;
+ next(handleSetFont(fontNameArg, null));
+ return;
+ case OPS.setTextRise:
+ textState.textRise = args[0];
+ break;
+ case OPS.setHScale:
+ textState.textHScale = args[0] / 100;
+ break;
+ case OPS.setLeading:
+ textState.leading = args[0];
+ break;
+ case OPS.moveText:
+ textState.translateTextLineMatrix(args[0], args[1]);
+ textState.textMatrix = textState.textLineMatrix.slice();
+ break;
+ case OPS.setLeadingMoveText:
+ textState.leading = -args[1];
+ textState.translateTextLineMatrix(args[0], args[1]);
+ textState.textMatrix = textState.textLineMatrix.slice();
+ break;
+ case OPS.nextLine:
+ textState.carriageReturn();
+ break;
+ case OPS.setTextMatrix:
+ textState.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);
+ textState.setTextLineMatrix(args[0], args[1], args[2], args[3], args[4], args[5]);
+ updateAdvanceScale();
+ break;
+ case OPS.setCharSpacing:
+ textState.charSpacing = args[0];
+ break;
+ case OPS.setWordSpacing:
+ textState.wordSpacing = args[0];
+ break;
+ case OPS.beginText:
+ textState.textMatrix = IDENTITY_MATRIX.slice();
+ textState.textLineMatrix = IDENTITY_MATRIX.slice();
+ break;
+ case OPS.showSpacedText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ const spaceFactor = (textState.font.vertical ? 1 : -1) * textState.fontSize / 1000;
+ const elements = args[0];
+ for (let i = 0, ii = elements.length; i < ii; i++) {
+ const item = elements[i];
+ if (typeof item === "string") {
+ showSpacedTextBuffer.push(item);
+ } else if (typeof item === "number" && item !== 0) {
+ const str = showSpacedTextBuffer.join("");
+ showSpacedTextBuffer.length = 0;
+ buildTextContentItem({
+ chars: str,
+ extraSpacing: item * spaceFactor
+ });
+ }
+ }
+ if (showSpacedTextBuffer.length > 0) {
+ const str = showSpacedTextBuffer.join("");
+ showSpacedTextBuffer.length = 0;
+ buildTextContentItem({
+ chars: str,
+ extraSpacing: 0
+ });
+ }
+ break;
+ case OPS.showText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ buildTextContentItem({
+ chars: args[0],
+ extraSpacing: 0
+ });
+ break;
+ case OPS.nextLineShowText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ textState.carriageReturn();
+ buildTextContentItem({
+ chars: args[0],
+ extraSpacing: 0
+ });
+ break;
+ case OPS.nextLineSetSpacingShowText:
+ if (!stateManager.state.font) {
+ self.ensureStateFont(stateManager.state);
+ continue;
+ }
+ textState.wordSpacing = args[0];
+ textState.charSpacing = args[1];
+ textState.carriageReturn();
+ buildTextContentItem({
+ chars: args[2],
+ extraSpacing: 0
+ });
+ break;
+ case OPS.paintXObject:
+ flushTextContentItem();
+ if (!xobjs) {
+ xobjs = resources.get("XObject") || Dict.empty;
+ }
+ var isValidName = args[0] instanceof Name;
+ var name = args[0].name;
+ if (isValidName && emptyXObjectCache.getByName(name)) {
+ break;
+ }
+ next(new Promise(function (resolveXObject, rejectXObject) {
+ if (!isValidName) {
+ throw new FormatError("XObject must be referred to by name.");
+ }
+ let xobj = xobjs.getRaw(name);
+ if (xobj instanceof Ref) {
+ if (emptyXObjectCache.getByRef(xobj)) {
+ resolveXObject();
+ return;
+ }
+ const globalImage = self.globalImageCache.getData(xobj, self.pageIndex);
+ if (globalImage) {
+ resolveXObject();
+ return;
+ }
+ xobj = xref.fetch(xobj);
+ }
+ if (!(xobj instanceof BaseStream)) {
+ throw new FormatError("XObject should be a stream");
+ }
+ const type = xobj.dict.get("Subtype");
+ if (!(type instanceof Name)) {
+ throw new FormatError("XObject should have a Name subtype");
+ }
+ if (type.name !== "Form") {
+ emptyXObjectCache.set(name, xobj.dict.objId, true);
+ resolveXObject();
+ return;
+ }
+ const currentState = stateManager.state.clone();
+ const xObjStateManager = new StateManager(currentState);
+ const matrix = xobj.dict.getArray("Matrix");
+ if (Array.isArray(matrix) && matrix.length === 6) {
+ xObjStateManager.transform(matrix);
+ }
+ enqueueChunk();
+ const sinkWrapper = {
+ enqueueInvoked: false,
+ enqueue(chunk, size) {
+ this.enqueueInvoked = true;
+ sink.enqueue(chunk, size);
+ },
+ get desiredSize() {
+ return sink.desiredSize;
+ },
+ get ready() {
+ return sink.ready;
+ }
+ };
+ self.getTextContent({
+ stream: xobj,
+ task,
+ resources: xobj.dict.get("Resources") || resources,
+ stateManager: xObjStateManager,
+ includeMarkedContent,
+ sink: sinkWrapper,
+ seenStyles,
+ viewBox,
+ markedContentData,
+ disableNormalization
+ }).then(function () {
+ if (!sinkWrapper.enqueueInvoked) {
+ emptyXObjectCache.set(name, xobj.dict.objId, true);
+ }
+ resolveXObject();
+ }, rejectXObject);
+ }).catch(function (reason) {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (self.options.ignoreErrors) {
+ warn(`getTextContent - ignoring XObject: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }));
+ return;
+ case OPS.setGState:
+ isValidName = args[0] instanceof Name;
+ name = args[0].name;
+ if (isValidName && emptyGStateCache.getByName(name)) {
+ break;
+ }
+ next(new Promise(function (resolveGState, rejectGState) {
+ if (!isValidName) {
+ throw new FormatError("GState must be referred to by name.");
+ }
+ const extGState = resources.get("ExtGState");
+ if (!(extGState instanceof Dict)) {
+ throw new FormatError("ExtGState should be a dictionary.");
+ }
+ const gState = extGState.get(name);
+ if (!(gState instanceof Dict)) {
+ throw new FormatError("GState should be a dictionary.");
+ }
+ const gStateFont = gState.get("Font");
+ if (!gStateFont) {
+ emptyGStateCache.set(name, gState.objId, true);
+ resolveGState();
+ return;
+ }
+ flushTextContentItem();
+ textState.fontName = null;
+ textState.fontSize = gStateFont[1];
+ handleSetFont(null, gStateFont[0]).then(resolveGState, rejectGState);
+ }).catch(function (reason) {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (self.options.ignoreErrors) {
+ warn(`getTextContent - ignoring ExtGState: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }));
+ return;
+ case OPS.beginMarkedContent:
+ flushTextContentItem();
+ if (includeMarkedContent) {
+ markedContentData.level++;
+ textContent.items.push({
+ type: "beginMarkedContent",
+ tag: args[0] instanceof Name ? args[0].name : null
+ });
+ }
+ break;
+ case OPS.beginMarkedContentProps:
+ flushTextContentItem();
+ if (includeMarkedContent) {
+ markedContentData.level++;
+ let mcid = null;
+ if (args[1] instanceof Dict) {
+ mcid = args[1].get("MCID");
+ }
+ textContent.items.push({
+ type: "beginMarkedContentProps",
+ id: Number.isInteger(mcid) ? `${self.idFactory.getPageObjId()}_mc${mcid}` : null,
+ tag: args[0] instanceof Name ? args[0].name : null
+ });
+ }
+ break;
+ case OPS.endMarkedContent:
+ flushTextContentItem();
+ if (includeMarkedContent) {
+ if (markedContentData.level === 0) {
+ break;
+ }
+ markedContentData.level--;
+ textContent.items.push({
+ type: "endMarkedContent"
+ });
+ }
+ break;
+ case OPS.restore:
+ if (previousState && (previousState.font !== textState.font || previousState.fontSize !== textState.fontSize || previousState.fontName !== textState.fontName)) {
+ flushTextContentItem();
+ }
+ break;
+ }
+ if (textContent.items.length >= sink.desiredSize) {
+ stop = true;
+ break;
+ }
+ }
+ if (stop) {
+ next(deferred);
+ return;
+ }
+ flushTextContentItem();
+ enqueueChunk();
+ resolve();
+ }).catch(reason => {
+ if (reason instanceof AbortException) {
+ return;
+ }
+ if (this.options.ignoreErrors) {
+ warn(`getTextContent - ignoring errors during "${task.name}" ` + `task: "${reason}".`);
+ flushTextContentItem();
+ enqueueChunk();
+ return;
+ }
+ throw reason;
+ });
+ }
+ extractDataStructures(dict, baseDict, properties) {
+ const xref = this.xref;
+ let cidToGidBytes;
+ const toUnicodePromise = this.readToUnicode(properties.toUnicode || dict.get("ToUnicode") || baseDict.get("ToUnicode"));
+ if (properties.composite) {
+ const cidSystemInfo = dict.get("CIDSystemInfo");
+ if (cidSystemInfo instanceof Dict) {
+ properties.cidSystemInfo = {
+ registry: stringToPDFString(cidSystemInfo.get("Registry")),
+ ordering: stringToPDFString(cidSystemInfo.get("Ordering")),
+ supplement: cidSystemInfo.get("Supplement")
+ };
+ }
+ try {
+ const cidToGidMap = dict.get("CIDToGIDMap");
+ if (cidToGidMap instanceof BaseStream) {
+ cidToGidBytes = cidToGidMap.getBytes();
+ }
+ } catch (ex) {
+ if (!this.options.ignoreErrors) {
+ throw ex;
+ }
+ warn(`extractDataStructures - ignoring CIDToGIDMap data: "${ex}".`);
+ }
+ }
+ const differences = [];
+ let baseEncodingName = null;
+ let encoding;
+ if (dict.has("Encoding")) {
+ encoding = dict.get("Encoding");
+ if (encoding instanceof Dict) {
+ baseEncodingName = encoding.get("BaseEncoding");
+ baseEncodingName = baseEncodingName instanceof Name ? baseEncodingName.name : null;
+ if (encoding.has("Differences")) {
+ const diffEncoding = encoding.get("Differences");
+ let index = 0;
+ for (const entry of diffEncoding) {
+ const data = xref.fetchIfRef(entry);
+ if (typeof data === "number") {
+ index = data;
+ } else if (data instanceof Name) {
+ differences[index++] = data.name;
+ } else {
+ throw new FormatError(`Invalid entry in 'Differences' array: ${data}`);
+ }
+ }
+ }
+ } else if (encoding instanceof Name) {
+ baseEncodingName = encoding.name;
+ } else {
+ const msg = "Encoding is not a Name nor a Dict";
+ if (!this.options.ignoreErrors) {
+ throw new FormatError(msg);
+ }
+ warn(msg);
+ }
+ if (baseEncodingName !== "MacRomanEncoding" && baseEncodingName !== "MacExpertEncoding" && baseEncodingName !== "WinAnsiEncoding") {
+ baseEncodingName = null;
+ }
+ }
+ const nonEmbeddedFont = !properties.file || properties.isInternalFont,
+ isSymbolsFontName = getSymbolsFonts()[properties.name];
+ if (baseEncodingName && nonEmbeddedFont && isSymbolsFontName) {
+ baseEncodingName = null;
+ }
+ if (baseEncodingName) {
+ properties.defaultEncoding = getEncoding(baseEncodingName);
+ } else {
+ const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
+ const isNonsymbolicFont = !!(properties.flags & FontFlags.Nonsymbolic);
+ encoding = StandardEncoding;
+ if (properties.type === "TrueType" && !isNonsymbolicFont) {
+ encoding = WinAnsiEncoding;
+ }
+ if (isSymbolicFont || isSymbolsFontName) {
+ encoding = MacRomanEncoding;
+ if (nonEmbeddedFont) {
+ if (/Symbol/i.test(properties.name)) {
+ encoding = SymbolSetEncoding;
+ } else if (/Dingbats/i.test(properties.name)) {
+ encoding = ZapfDingbatsEncoding;
+ } else if (/Wingdings/i.test(properties.name)) {
+ encoding = WinAnsiEncoding;
+ }
+ }
+ }
+ properties.defaultEncoding = encoding;
+ }
+ properties.differences = differences;
+ properties.baseEncodingName = baseEncodingName;
+ properties.hasEncoding = !!baseEncodingName || differences.length > 0;
+ properties.dict = dict;
+ return toUnicodePromise.then(readToUnicode => {
+ properties.toUnicode = readToUnicode;
+ return this.buildToUnicode(properties);
+ }).then(builtToUnicode => {
+ properties.toUnicode = builtToUnicode;
+ if (cidToGidBytes) {
+ properties.cidToGidMap = this.readCidToGidMap(cidToGidBytes, builtToUnicode);
+ }
+ return properties;
+ });
+ }
+ _simpleFontToUnicode(properties, forceGlyphs = false) {
+ assert(!properties.composite, "Must be a simple font.");
+ const toUnicode = [];
+ const encoding = properties.defaultEncoding.slice();
+ const baseEncodingName = properties.baseEncodingName;
+ const differences = properties.differences;
+ for (const charcode in differences) {
+ const glyphName = differences[charcode];
+ if (glyphName === ".notdef") {
+ continue;
+ }
+ encoding[charcode] = glyphName;
+ }
+ const glyphsUnicodeMap = getGlyphsUnicode();
+ for (const charcode in encoding) {
+ let glyphName = encoding[charcode];
+ if (glyphName === "") {
+ continue;
+ }
+ let unicode = glyphsUnicodeMap[glyphName];
+ if (unicode !== undefined) {
+ toUnicode[charcode] = String.fromCharCode(unicode);
+ continue;
+ }
+ let code = 0;
+ switch (glyphName[0]) {
+ case "G":
+ if (glyphName.length === 3) {
+ code = parseInt(glyphName.substring(1), 16);
+ }
+ break;
+ case "g":
+ if (glyphName.length === 5) {
+ code = parseInt(glyphName.substring(1), 16);
+ }
+ break;
+ case "C":
+ case "c":
+ if (glyphName.length >= 3 && glyphName.length <= 4) {
+ const codeStr = glyphName.substring(1);
+ if (forceGlyphs) {
+ code = parseInt(codeStr, 16);
+ break;
+ }
+ code = +codeStr;
+ if (Number.isNaN(code) && Number.isInteger(parseInt(codeStr, 16))) {
+ return this._simpleFontToUnicode(properties, true);
+ }
+ }
+ break;
+ case "u":
+ unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap);
+ if (unicode !== -1) {
+ code = unicode;
+ }
+ break;
+ default:
+ switch (glyphName) {
+ case "f_h":
+ case "f_t":
+ case "T_h":
+ toUnicode[charcode] = glyphName.replaceAll("_", "");
+ continue;
+ }
+ break;
+ }
+ if (code > 0 && code <= 0x10ffff && Number.isInteger(code)) {
+ if (baseEncodingName && code === +charcode) {
+ const baseEncoding = getEncoding(baseEncodingName);
+ if (baseEncoding && (glyphName = baseEncoding[charcode])) {
+ toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);
+ continue;
+ }
+ }
+ toUnicode[charcode] = String.fromCodePoint(code);
+ }
+ }
+ return toUnicode;
+ }
+ async buildToUnicode(properties) {
+ properties.hasIncludedToUnicodeMap = properties.toUnicode?.length > 0;
+ if (properties.hasIncludedToUnicodeMap) {
+ if (!properties.composite && properties.hasEncoding) {
+ properties.fallbackToUnicode = this._simpleFontToUnicode(properties);
+ }
+ return properties.toUnicode;
+ }
+ if (!properties.composite) {
+ return new ToUnicodeMap(this._simpleFontToUnicode(properties));
+ }
+ if (properties.composite && (properties.cMap.builtInCMap && !(properties.cMap instanceof IdentityCMap) || properties.cidSystemInfo.registry === "Adobe" && (properties.cidSystemInfo.ordering === "GB1" || properties.cidSystemInfo.ordering === "CNS1" || properties.cidSystemInfo.ordering === "Japan1" || properties.cidSystemInfo.ordering === "Korea1"))) {
+ const {
+ registry,
+ ordering
+ } = properties.cidSystemInfo;
+ const ucs2CMapName = Name.get(`${registry}-${ordering}-UCS2`);
+ const ucs2CMap = await CMapFactory.create({
+ encoding: ucs2CMapName,
+ fetchBuiltInCMap: this._fetchBuiltInCMapBound,
+ useCMap: null
+ });
+ const toUnicode = [],
+ buf = [];
+ properties.cMap.forEach(function (charcode, cid) {
+ if (cid > 0xffff) {
+ throw new FormatError("Max size of CID is 65,535");
+ }
+ const ucs2 = ucs2CMap.lookup(cid);
+ if (ucs2) {
+ buf.length = 0;
+ for (let i = 0, ii = ucs2.length; i < ii; i += 2) {
+ buf.push((ucs2.charCodeAt(i) << 8) + ucs2.charCodeAt(i + 1));
+ }
+ toUnicode[charcode] = String.fromCharCode(...buf);
+ }
+ });
+ return new ToUnicodeMap(toUnicode);
+ }
+ return new IdentityToUnicodeMap(properties.firstChar, properties.lastChar);
+ }
+ readToUnicode(cmapObj) {
+ if (!cmapObj) {
+ return Promise.resolve(null);
+ }
+ if (cmapObj instanceof Name) {
+ return CMapFactory.create({
+ encoding: cmapObj,
+ fetchBuiltInCMap: this._fetchBuiltInCMapBound,
+ useCMap: null
+ }).then(function (cmap) {
+ if (cmap instanceof IdentityCMap) {
+ return new IdentityToUnicodeMap(0, 0xffff);
+ }
+ return new ToUnicodeMap(cmap.getMap());
+ });
+ } else if (cmapObj instanceof BaseStream) {
+ return CMapFactory.create({
+ encoding: cmapObj,
+ fetchBuiltInCMap: this._fetchBuiltInCMapBound,
+ useCMap: null
+ }).then(function (cmap) {
+ if (cmap instanceof IdentityCMap) {
+ return new IdentityToUnicodeMap(0, 0xffff);
+ }
+ const map = new Array(cmap.length);
+ cmap.forEach(function (charCode, token) {
+ if (typeof token === "number") {
+ map[charCode] = String.fromCodePoint(token);
+ return;
+ }
+ const str = [];
+ for (let k = 0; k < token.length; k += 2) {
+ const w1 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1);
+ if ((w1 & 0xf800) !== 0xd800) {
+ str.push(w1);
+ continue;
+ }
+ k += 2;
+ const w2 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1);
+ str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
+ }
+ map[charCode] = String.fromCodePoint(...str);
+ });
+ return new ToUnicodeMap(map);
+ }, reason => {
+ if (reason instanceof AbortException) {
+ return null;
+ }
+ if (this.options.ignoreErrors) {
+ warn(`readToUnicode - ignoring ToUnicode data: "${reason}".`);
+ return null;
+ }
+ throw reason;
+ });
+ }
+ return Promise.resolve(null);
+ }
+ readCidToGidMap(glyphsData, toUnicode) {
+ const result = [];
+ for (let j = 0, jj = glyphsData.length; j < jj; j++) {
+ const glyphID = glyphsData[j++] << 8 | glyphsData[j];
+ const code = j >> 1;
+ if (glyphID === 0 && !toUnicode.has(code)) {
+ continue;
+ }
+ result[code] = glyphID;
+ }
+ return result;
+ }
+ extractWidths(dict, descriptor, properties) {
+ const xref = this.xref;
+ let glyphsWidths = [];
+ let defaultWidth = 0;
+ const glyphsVMetrics = [];
+ let defaultVMetrics;
+ let i, ii, j, jj, start, code, widths;
+ if (properties.composite) {
+ defaultWidth = dict.has("DW") ? dict.get("DW") : 1000;
+ widths = dict.get("W");
+ if (widths) {
+ for (i = 0, ii = widths.length; i < ii; i++) {
+ start = xref.fetchIfRef(widths[i++]);
+ code = xref.fetchIfRef(widths[i]);
+ if (Array.isArray(code)) {
+ for (j = 0, jj = code.length; j < jj; j++) {
+ glyphsWidths[start++] = xref.fetchIfRef(code[j]);
+ }
+ } else {
+ const width = xref.fetchIfRef(widths[++i]);
+ for (j = start; j <= code; j++) {
+ glyphsWidths[j] = width;
+ }
+ }
+ }
+ }
+ if (properties.vertical) {
+ let vmetrics = dict.getArray("DW2") || [880, -1000];
+ defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];
+ vmetrics = dict.get("W2");
+ if (vmetrics) {
+ for (i = 0, ii = vmetrics.length; i < ii; i++) {
+ start = xref.fetchIfRef(vmetrics[i++]);
+ code = xref.fetchIfRef(vmetrics[i]);
+ if (Array.isArray(code)) {
+ for (j = 0, jj = code.length; j < jj; j++) {
+ glyphsVMetrics[start++] = [xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j])];
+ }
+ } else {
+ const vmetric = [xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i])];
+ for (j = start; j <= code; j++) {
+ glyphsVMetrics[j] = vmetric;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ const firstChar = properties.firstChar;
+ widths = dict.get("Widths");
+ if (widths) {
+ j = firstChar;
+ for (i = 0, ii = widths.length; i < ii; i++) {
+ glyphsWidths[j++] = xref.fetchIfRef(widths[i]);
+ }
+ defaultWidth = parseFloat(descriptor.get("MissingWidth")) || 0;
+ } else {
+ const baseFontName = dict.get("BaseFont");
+ if (baseFontName instanceof Name) {
+ const metrics = this.getBaseFontMetrics(baseFontName.name);
+ glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties);
+ defaultWidth = metrics.defaultWidth;
+ }
+ }
+ }
+ let isMonospace = true;
+ let firstWidth = defaultWidth;
+ for (const glyph in glyphsWidths) {
+ const glyphWidth = glyphsWidths[glyph];
+ if (!glyphWidth) {
+ continue;
+ }
+ if (!firstWidth) {
+ firstWidth = glyphWidth;
+ continue;
+ }
+ if (firstWidth !== glyphWidth) {
+ isMonospace = false;
+ break;
+ }
+ }
+ if (isMonospace) {
+ properties.flags |= FontFlags.FixedPitch;
+ } else {
+ properties.flags &= ~FontFlags.FixedPitch;
+ }
+ properties.defaultWidth = defaultWidth;
+ properties.widths = glyphsWidths;
+ properties.defaultVMetrics = defaultVMetrics;
+ properties.vmetrics = glyphsVMetrics;
+ }
+ isSerifFont(baseFontName) {
+ const fontNameWoStyle = baseFontName.split("-")[0];
+ return fontNameWoStyle in getSerifFonts() || /serif/gi.test(fontNameWoStyle);
+ }
+ getBaseFontMetrics(name) {
+ let defaultWidth = 0;
+ let widths = Object.create(null);
+ let monospace = false;
+ const stdFontMap = getStdFontMap();
+ let lookupName = stdFontMap[name] || name;
+ const Metrics = getMetrics();
+ if (!(lookupName in Metrics)) {
+ lookupName = this.isSerifFont(name) ? "Times-Roman" : "Helvetica";
+ }
+ const glyphWidths = Metrics[lookupName];
+ if (typeof glyphWidths === "number") {
+ defaultWidth = glyphWidths;
+ monospace = true;
+ } else {
+ widths = glyphWidths();
+ }
+ return {
+ defaultWidth,
+ monospace,
+ widths
+ };
+ }
+ buildCharCodeToWidth(widthsByGlyphName, properties) {
+ const widths = Object.create(null);
+ const differences = properties.differences;
+ const encoding = properties.defaultEncoding;
+ for (let charCode = 0; charCode < 256; charCode++) {
+ if (charCode in differences && widthsByGlyphName[differences[charCode]]) {
+ widths[charCode] = widthsByGlyphName[differences[charCode]];
+ continue;
+ }
+ if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) {
+ widths[charCode] = widthsByGlyphName[encoding[charCode]];
+ continue;
+ }
+ }
+ return widths;
+ }
+ preEvaluateFont(dict) {
+ const baseDict = dict;
+ let type = dict.get("Subtype");
+ if (!(type instanceof Name)) {
+ throw new FormatError("invalid font Subtype");
+ }
+ let composite = false;
+ let hash, toUnicode;
+ if (type.name === "Type0") {
+ const df = dict.get("DescendantFonts");
+ if (!df) {
+ throw new FormatError("Descendant fonts are not specified");
+ }
+ dict = Array.isArray(df) ? this.xref.fetchIfRef(df[0]) : df;
+ if (!(dict instanceof Dict)) {
+ throw new FormatError("Descendant font is not a dictionary.");
+ }
+ type = dict.get("Subtype");
+ if (!(type instanceof Name)) {
+ throw new FormatError("invalid font Subtype");
+ }
+ composite = true;
+ }
+ const firstChar = dict.get("FirstChar") || 0,
+ lastChar = dict.get("LastChar") || (composite ? 0xffff : 0xff);
+ const descriptor = dict.get("FontDescriptor");
+ if (descriptor) {
+ hash = new MurmurHash3_64();
+ const encoding = baseDict.getRaw("Encoding");
+ if (encoding instanceof Name) {
+ hash.update(encoding.name);
+ } else if (encoding instanceof Ref) {
+ hash.update(encoding.toString());
+ } else if (encoding instanceof Dict) {
+ for (const entry of encoding.getRawValues()) {
+ if (entry instanceof Name) {
+ hash.update(entry.name);
+ } else if (entry instanceof Ref) {
+ hash.update(entry.toString());
+ } else if (Array.isArray(entry)) {
+ const diffLength = entry.length,
+ diffBuf = new Array(diffLength);
+ for (let j = 0; j < diffLength; j++) {
+ const diffEntry = entry[j];
+ if (diffEntry instanceof Name) {
+ diffBuf[j] = diffEntry.name;
+ } else if (typeof diffEntry === "number" || diffEntry instanceof Ref) {
+ diffBuf[j] = diffEntry.toString();
+ }
+ }
+ hash.update(diffBuf.join());
+ }
+ }
+ }
+ hash.update(`${firstChar}-${lastChar}`);
+ toUnicode = dict.get("ToUnicode") || baseDict.get("ToUnicode");
+ if (toUnicode instanceof BaseStream) {
+ const stream = toUnicode.str || toUnicode;
+ const uint8array = stream.buffer ? new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) : new Uint8Array(stream.bytes.buffer, stream.start, stream.end - stream.start);
+ hash.update(uint8array);
+ } else if (toUnicode instanceof Name) {
+ hash.update(toUnicode.name);
+ }
+ const widths = dict.get("Widths") || baseDict.get("Widths");
+ if (Array.isArray(widths)) {
+ const widthsBuf = [];
+ for (const entry of widths) {
+ if (typeof entry === "number" || entry instanceof Ref) {
+ widthsBuf.push(entry.toString());
+ }
+ }
+ hash.update(widthsBuf.join());
+ }
+ if (composite) {
+ hash.update("compositeFont");
+ const compositeWidths = dict.get("W") || baseDict.get("W");
+ if (Array.isArray(compositeWidths)) {
+ const widthsBuf = [];
+ for (const entry of compositeWidths) {
+ if (typeof entry === "number" || entry instanceof Ref) {
+ widthsBuf.push(entry.toString());
+ } else if (Array.isArray(entry)) {
+ const subWidthsBuf = [];
+ for (const element of entry) {
+ if (typeof element === "number" || element instanceof Ref) {
+ subWidthsBuf.push(element.toString());
+ }
+ }
+ widthsBuf.push(`[${subWidthsBuf.join()}]`);
+ }
+ }
+ hash.update(widthsBuf.join());
+ }
+ const cidToGidMap = dict.getRaw("CIDToGIDMap") || baseDict.getRaw("CIDToGIDMap");
+ if (cidToGidMap instanceof Name) {
+ hash.update(cidToGidMap.name);
+ } else if (cidToGidMap instanceof Ref) {
+ hash.update(cidToGidMap.toString());
+ } else if (cidToGidMap instanceof BaseStream) {
+ hash.update(cidToGidMap.peekBytes());
+ }
+ }
+ }
+ return {
+ descriptor,
+ dict,
+ baseDict,
+ composite,
+ type: type.name,
+ firstChar,
+ lastChar,
+ toUnicode,
+ hash: hash ? hash.hexdigest() : ""
+ };
+ }
+ async translateFont({
+ descriptor,
+ dict,
+ baseDict,
+ composite,
+ type,
+ firstChar,
+ lastChar,
+ toUnicode,
+ cssFontInfo
+ }) {
+ const isType3Font = type === "Type3";
+ let properties;
+ if (!descriptor) {
+ if (isType3Font) {
+ descriptor = new Dict(null);
+ descriptor.set("FontName", Name.get(type));
+ descriptor.set("FontBBox", dict.getArray("FontBBox") || [0, 0, 0, 0]);
+ } else {
+ let baseFontName = dict.get("BaseFont");
+ if (!(baseFontName instanceof Name)) {
+ throw new FormatError("Base font is not specified");
+ }
+ baseFontName = baseFontName.name.replaceAll(/[,_]/g, "-");
+ const metrics = this.getBaseFontMetrics(baseFontName);
+ const fontNameWoStyle = baseFontName.split("-")[0];
+ const flags = (this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) | (metrics.monospace ? FontFlags.FixedPitch : 0) | (getSymbolsFonts()[fontNameWoStyle] ? FontFlags.Symbolic : FontFlags.Nonsymbolic);
+ properties = {
+ type,
+ name: baseFontName,
+ loadedName: baseDict.loadedName,
+ systemFontInfo: null,
+ widths: metrics.widths,
+ defaultWidth: metrics.defaultWidth,
+ isSimulatedFlags: true,
+ flags,
+ firstChar,
+ lastChar,
+ toUnicode,
+ xHeight: 0,
+ capHeight: 0,
+ italicAngle: 0,
+ isType3Font
+ };
+ const widths = dict.get("Widths");
+ const standardFontName = getStandardFontName(baseFontName);
+ let file = null;
+ if (standardFontName) {
+ file = await this.fetchStandardFontData(standardFontName);
+ properties.isInternalFont = !!file;
+ }
+ if (!properties.isInternalFont && this.options.useSystemFonts) {
+ properties.systemFontInfo = getFontSubstitution(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, baseFontName, standardFontName);
+ }
+ return this.extractDataStructures(dict, dict, properties).then(newProperties => {
+ if (widths) {
+ const glyphWidths = [];
+ let j = firstChar;
+ for (const width of widths) {
+ glyphWidths[j++] = this.xref.fetchIfRef(width);
+ }
+ newProperties.widths = glyphWidths;
+ } else {
+ newProperties.widths = this.buildCharCodeToWidth(metrics.widths, newProperties);
+ }
+ return new Font(baseFontName, file, newProperties);
+ });
+ }
+ }
+ let fontName = descriptor.get("FontName");
+ let baseFont = dict.get("BaseFont");
+ if (typeof fontName === "string") {
+ fontName = Name.get(fontName);
+ }
+ if (typeof baseFont === "string") {
+ baseFont = Name.get(baseFont);
+ }
+ const fontNameStr = fontName?.name;
+ const baseFontStr = baseFont?.name;
+ if (!isType3Font && fontNameStr !== baseFontStr) {
+ info(`The FontDescriptor's FontName is "${fontNameStr}" but ` + `should be the same as the Font's BaseFont "${baseFontStr}".`);
+ if (fontNameStr && baseFontStr && (baseFontStr.startsWith(fontNameStr) || !isKnownFontName(fontNameStr) && isKnownFontName(baseFontStr))) {
+ fontName = null;
+ }
+ }
+ fontName ||= baseFont;
+ if (!(fontName instanceof Name)) {
+ throw new FormatError("invalid font name");
+ }
+ let fontFile, subtype, length1, length2, length3;
+ try {
+ fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3");
+ } catch (ex) {
+ if (!this.options.ignoreErrors) {
+ throw ex;
+ }
+ warn(`translateFont - fetching "${fontName.name}" font file: "${ex}".`);
+ fontFile = new NullStream();
+ }
+ let isInternalFont = false;
+ let glyphScaleFactors = null;
+ let systemFontInfo = null;
+ if (fontFile) {
+ if (fontFile.dict) {
+ const subtypeEntry = fontFile.dict.get("Subtype");
+ if (subtypeEntry instanceof Name) {
+ subtype = subtypeEntry.name;
+ }
+ length1 = fontFile.dict.get("Length1");
+ length2 = fontFile.dict.get("Length2");
+ length3 = fontFile.dict.get("Length3");
+ }
+ } else if (cssFontInfo) {
+ const standardFontName = getXfaFontName(fontName.name);
+ if (standardFontName) {
+ cssFontInfo.fontFamily = `${cssFontInfo.fontFamily}-PdfJS-XFA`;
+ cssFontInfo.metrics = standardFontName.metrics || null;
+ glyphScaleFactors = standardFontName.factors || null;
+ fontFile = await this.fetchStandardFontData(standardFontName.name);
+ isInternalFont = !!fontFile;
+ baseDict = dict = getXfaFontDict(fontName.name);
+ composite = true;
+ }
+ } else if (!isType3Font) {
+ const standardFontName = getStandardFontName(fontName.name);
+ if (standardFontName) {
+ fontFile = await this.fetchStandardFontData(standardFontName);
+ isInternalFont = !!fontFile;
+ }
+ if (!isInternalFont && this.options.useSystemFonts) {
+ systemFontInfo = getFontSubstitution(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, fontName.name, standardFontName);
+ }
+ }
+ properties = {
+ type,
+ name: fontName.name,
+ subtype,
+ file: fontFile,
+ length1,
+ length2,
+ length3,
+ isInternalFont,
+ loadedName: baseDict.loadedName,
+ composite,
+ fixedPitch: false,
+ fontMatrix: dict.getArray("FontMatrix") || FONT_IDENTITY_MATRIX,
+ firstChar,
+ lastChar,
+ toUnicode,
+ bbox: descriptor.getArray("FontBBox") || dict.getArray("FontBBox"),
+ ascent: descriptor.get("Ascent"),
+ descent: descriptor.get("Descent"),
+ xHeight: descriptor.get("XHeight") || 0,
+ capHeight: descriptor.get("CapHeight") || 0,
+ flags: descriptor.get("Flags"),
+ italicAngle: descriptor.get("ItalicAngle") || 0,
+ isType3Font,
+ cssFontInfo,
+ scaleFactors: glyphScaleFactors,
+ systemFontInfo
+ };
+ if (composite) {
+ const cidEncoding = baseDict.get("Encoding");
+ if (cidEncoding instanceof Name) {
+ properties.cidEncoding = cidEncoding.name;
+ }
+ const cMap = await CMapFactory.create({
+ encoding: cidEncoding,
+ fetchBuiltInCMap: this._fetchBuiltInCMapBound,
+ useCMap: null
+ });
+ properties.cMap = cMap;
+ properties.vertical = properties.cMap.vertical;
+ }
+ return this.extractDataStructures(dict, baseDict, properties).then(newProperties => {
+ this.extractWidths(dict, descriptor, newProperties);
+ return new Font(fontName.name, fontFile, newProperties);
+ });
+ }
+ static buildFontPaths(font, glyphs, handler, evaluatorOptions) {
+ function buildPath(fontChar) {
+ const glyphName = `${font.loadedName}_path_${fontChar}`;
+ try {
+ if (font.renderer.hasBuiltPath(fontChar)) {
+ return;
+ }
+ handler.send("commonobj", [glyphName, "FontPath", font.renderer.getPathJs(fontChar)]);
+ } catch (reason) {
+ if (evaluatorOptions.ignoreErrors) {
+ warn(`buildFontPaths - ignoring ${glyphName} glyph: "${reason}".`);
+ return;
+ }
+ throw reason;
+ }
+ }
+ for (const glyph of glyphs) {
+ buildPath(glyph.fontChar);
+ const accent = glyph.accent;
+ if (accent?.fontChar) {
+ buildPath(accent.fontChar);
+ }
+ }
+ }
+ static get fallbackFontDict() {
+ const dict = new Dict();
+ dict.set("BaseFont", Name.get("Helvetica"));
+ dict.set("Type", Name.get("FallbackType"));
+ dict.set("Subtype", Name.get("FallbackType"));
+ dict.set("Encoding", Name.get("WinAnsiEncoding"));
+ return shadow(this, "fallbackFontDict", dict);
+ }
+}
+class TranslatedFont {
+ constructor({
+ loadedName,
+ font,
+ dict,
+ evaluatorOptions
+ }) {
+ this.loadedName = loadedName;
+ this.font = font;
+ this.dict = dict;
+ this._evaluatorOptions = evaluatorOptions || DefaultPartialEvaluatorOptions;
+ this.type3Loaded = null;
+ this.type3Dependencies = font.isType3Font ? new Set() : null;
+ this.sent = false;
+ }
+ send(handler) {
+ if (this.sent) {
+ return;
+ }
+ this.sent = true;
+ handler.send("commonobj", [this.loadedName, "Font", this.font.exportData(this._evaluatorOptions.fontExtraProperties)]);
+ }
+ fallback(handler) {
+ if (!this.font.data) {
+ return;
+ }
+ this.font.disableFontFace = true;
+ PartialEvaluator.buildFontPaths(this.font, this.font.glyphCacheValues, handler, this._evaluatorOptions);
+ }
+ loadType3Data(evaluator, resources, task) {
+ if (this.type3Loaded) {
+ return this.type3Loaded;
+ }
+ if (!this.font.isType3Font) {
+ throw new Error("Must be a Type3 font.");
+ }
+ const type3Evaluator = evaluator.clone({
+ ignoreErrors: false
+ });
+ type3Evaluator.parsingType3Font = true;
+ const type3FontRefs = new RefSet(evaluator.type3FontRefs);
+ if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) {
+ type3FontRefs.put(this.dict.objId);
+ }
+ type3Evaluator.type3FontRefs = type3FontRefs;
+ const translatedFont = this.font,
+ type3Dependencies = this.type3Dependencies;
+ let loadCharProcsPromise = Promise.resolve();
+ const charProcs = this.dict.get("CharProcs");
+ const fontResources = this.dict.get("Resources") || resources;
+ const charProcOperatorList = Object.create(null);
+ const fontBBox = Util.normalizeRect(translatedFont.bbox || [0, 0, 0, 0]),
+ width = fontBBox[2] - fontBBox[0],
+ height = fontBBox[3] - fontBBox[1];
+ const fontBBoxSize = Math.hypot(width, height);
+ for (const key of charProcs.getKeys()) {
+ loadCharProcsPromise = loadCharProcsPromise.then(() => {
+ const glyphStream = charProcs.get(key);
+ const operatorList = new OperatorList();
+ return type3Evaluator.getOperatorList({
+ stream: glyphStream,
+ task,
+ resources: fontResources,
+ operatorList
+ }).then(() => {
+ if (operatorList.fnArray[0] === OPS.setCharWidthAndBounds) {
+ this._removeType3ColorOperators(operatorList, fontBBoxSize);
+ }
+ charProcOperatorList[key] = operatorList.getIR();
+ for (const dependency of operatorList.dependencies) {
+ type3Dependencies.add(dependency);
+ }
+ }).catch(function (reason) {
+ warn(`Type3 font resource "${key}" is not available.`);
+ const dummyOperatorList = new OperatorList();
+ charProcOperatorList[key] = dummyOperatorList.getIR();
+ });
+ });
+ }
+ this.type3Loaded = loadCharProcsPromise.then(() => {
+ translatedFont.charProcOperatorList = charProcOperatorList;
+ if (this._bbox) {
+ translatedFont.isCharBBox = true;
+ translatedFont.bbox = this._bbox;
+ }
+ });
+ return this.type3Loaded;
+ }
+ _removeType3ColorOperators(operatorList, fontBBoxSize = NaN) {
+ const charBBox = Util.normalizeRect(operatorList.argsArray[0].slice(2)),
+ width = charBBox[2] - charBBox[0],
+ height = charBBox[3] - charBBox[1];
+ const charBBoxSize = Math.hypot(width, height);
+ if (width === 0 || height === 0) {
+ operatorList.fnArray.splice(0, 1);
+ operatorList.argsArray.splice(0, 1);
+ } else if (fontBBoxSize === 0 || Math.round(charBBoxSize / fontBBoxSize) >= 10) {
+ if (!this._bbox) {
+ this._bbox = [Infinity, Infinity, -Infinity, -Infinity];
+ }
+ this._bbox[0] = Math.min(this._bbox[0], charBBox[0]);
+ this._bbox[1] = Math.min(this._bbox[1], charBBox[1]);
+ this._bbox[2] = Math.max(this._bbox[2], charBBox[2]);
+ this._bbox[3] = Math.max(this._bbox[3], charBBox[3]);
+ }
+ let i = 0,
+ ii = operatorList.length;
+ while (i < ii) {
+ switch (operatorList.fnArray[i]) {
+ case OPS.setCharWidthAndBounds:
+ break;
+ case OPS.setStrokeColorSpace:
+ case OPS.setFillColorSpace:
+ case OPS.setStrokeColor:
+ case OPS.setStrokeColorN:
+ case OPS.setFillColor:
+ case OPS.setFillColorN:
+ case OPS.setStrokeGray:
+ case OPS.setFillGray:
+ case OPS.setStrokeRGBColor:
+ case OPS.setFillRGBColor:
+ case OPS.setStrokeCMYKColor:
+ case OPS.setFillCMYKColor:
+ case OPS.shadingFill:
+ case OPS.setRenderingIntent:
+ operatorList.fnArray.splice(i, 1);
+ operatorList.argsArray.splice(i, 1);
+ ii--;
+ continue;
+ case OPS.setGState:
+ const [gStateObj] = operatorList.argsArray[i];
+ let j = 0,
+ jj = gStateObj.length;
+ while (j < jj) {
+ const [gStateKey] = gStateObj[j];
+ switch (gStateKey) {
+ case "TR":
+ case "TR2":
+ case "HT":
+ case "BG":
+ case "BG2":
+ case "UCR":
+ case "UCR2":
+ gStateObj.splice(j, 1);
+ jj--;
+ continue;
+ }
+ j++;
+ }
+ break;
+ }
+ i++;
+ }
+ }
+}
+class StateManager {
+ constructor(initialState = new EvalState()) {
+ this.state = initialState;
+ this.stateStack = [];
+ }
+ save() {
+ const old = this.state;
+ this.stateStack.push(this.state);
+ this.state = old.clone();
+ }
+ restore() {
+ const prev = this.stateStack.pop();
+ if (prev) {
+ this.state = prev;
+ }
+ }
+ transform(args) {
+ this.state.ctm = Util.transform(this.state.ctm, args);
+ }
+}
+class TextState {
+ constructor() {
+ this.ctm = new Float32Array(IDENTITY_MATRIX);
+ this.fontName = null;
+ this.fontSize = 0;
+ this.loadedName = null;
+ this.font = null;
+ this.fontMatrix = FONT_IDENTITY_MATRIX;
+ this.textMatrix = IDENTITY_MATRIX.slice();
+ this.textLineMatrix = IDENTITY_MATRIX.slice();
+ this.charSpacing = 0;
+ this.wordSpacing = 0;
+ this.leading = 0;
+ this.textHScale = 1;
+ this.textRise = 0;
+ }
+ setTextMatrix(a, b, c, d, e, f) {
+ const m = this.textMatrix;
+ m[0] = a;
+ m[1] = b;
+ m[2] = c;
+ m[3] = d;
+ m[4] = e;
+ m[5] = f;
+ }
+ setTextLineMatrix(a, b, c, d, e, f) {
+ const m = this.textLineMatrix;
+ m[0] = a;
+ m[1] = b;
+ m[2] = c;
+ m[3] = d;
+ m[4] = e;
+ m[5] = f;
+ }
+ translateTextMatrix(x, y) {
+ const m = this.textMatrix;
+ m[4] = m[0] * x + m[2] * y + m[4];
+ m[5] = m[1] * x + m[3] * y + m[5];
+ }
+ translateTextLineMatrix(x, y) {
+ const m = this.textLineMatrix;
+ m[4] = m[0] * x + m[2] * y + m[4];
+ m[5] = m[1] * x + m[3] * y + m[5];
+ }
+ carriageReturn() {
+ this.translateTextLineMatrix(0, -this.leading);
+ this.textMatrix = this.textLineMatrix.slice();
+ }
+ clone() {
+ const clone = Object.create(this);
+ clone.textMatrix = this.textMatrix.slice();
+ clone.textLineMatrix = this.textLineMatrix.slice();
+ clone.fontMatrix = this.fontMatrix.slice();
+ return clone;
+ }
+}
+class EvalState {
+ constructor() {
+ this.ctm = new Float32Array(IDENTITY_MATRIX);
+ this.font = null;
+ this.textRenderingMode = TextRenderingMode.FILL;
+ this.fillColorSpace = ColorSpace.singletons.gray;
+ this.strokeColorSpace = ColorSpace.singletons.gray;
+ }
+ clone() {
+ return Object.create(this);
+ }
+}
+class EvaluatorPreprocessor {
+ static get opMap() {
+ return shadow(this, "opMap", {
+ w: {
+ id: OPS.setLineWidth,
+ numArgs: 1,
+ variableArgs: false
+ },
+ J: {
+ id: OPS.setLineCap,
+ numArgs: 1,
+ variableArgs: false
+ },
+ j: {
+ id: OPS.setLineJoin,
+ numArgs: 1,
+ variableArgs: false
+ },
+ M: {
+ id: OPS.setMiterLimit,
+ numArgs: 1,
+ variableArgs: false
+ },
+ d: {
+ id: OPS.setDash,
+ numArgs: 2,
+ variableArgs: false
+ },
+ ri: {
+ id: OPS.setRenderingIntent,
+ numArgs: 1,
+ variableArgs: false
+ },
+ i: {
+ id: OPS.setFlatness,
+ numArgs: 1,
+ variableArgs: false
+ },
+ gs: {
+ id: OPS.setGState,
+ numArgs: 1,
+ variableArgs: false
+ },
+ q: {
+ id: OPS.save,
+ numArgs: 0,
+ variableArgs: false
+ },
+ Q: {
+ id: OPS.restore,
+ numArgs: 0,
+ variableArgs: false
+ },
+ cm: {
+ id: OPS.transform,
+ numArgs: 6,
+ variableArgs: false
+ },
+ m: {
+ id: OPS.moveTo,
+ numArgs: 2,
+ variableArgs: false
+ },
+ l: {
+ id: OPS.lineTo,
+ numArgs: 2,
+ variableArgs: false
+ },
+ c: {
+ id: OPS.curveTo,
+ numArgs: 6,
+ variableArgs: false
+ },
+ v: {
+ id: OPS.curveTo2,
+ numArgs: 4,
+ variableArgs: false
+ },
+ y: {
+ id: OPS.curveTo3,
+ numArgs: 4,
+ variableArgs: false
+ },
+ h: {
+ id: OPS.closePath,
+ numArgs: 0,
+ variableArgs: false
+ },
+ re: {
+ id: OPS.rectangle,
+ numArgs: 4,
+ variableArgs: false
+ },
+ S: {
+ id: OPS.stroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ s: {
+ id: OPS.closeStroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ f: {
+ id: OPS.fill,
+ numArgs: 0,
+ variableArgs: false
+ },
+ F: {
+ id: OPS.fill,
+ numArgs: 0,
+ variableArgs: false
+ },
+ "f*": {
+ id: OPS.eoFill,
+ numArgs: 0,
+ variableArgs: false
+ },
+ B: {
+ id: OPS.fillStroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ "B*": {
+ id: OPS.eoFillStroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ b: {
+ id: OPS.closeFillStroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ "b*": {
+ id: OPS.closeEOFillStroke,
+ numArgs: 0,
+ variableArgs: false
+ },
+ n: {
+ id: OPS.endPath,
+ numArgs: 0,
+ variableArgs: false
+ },
+ W: {
+ id: OPS.clip,
+ numArgs: 0,
+ variableArgs: false
+ },
+ "W*": {
+ id: OPS.eoClip,
+ numArgs: 0,
+ variableArgs: false
+ },
+ BT: {
+ id: OPS.beginText,
+ numArgs: 0,
+ variableArgs: false
+ },
+ ET: {
+ id: OPS.endText,
+ numArgs: 0,
+ variableArgs: false
+ },
+ Tc: {
+ id: OPS.setCharSpacing,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Tw: {
+ id: OPS.setWordSpacing,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Tz: {
+ id: OPS.setHScale,
+ numArgs: 1,
+ variableArgs: false
+ },
+ TL: {
+ id: OPS.setLeading,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Tf: {
+ id: OPS.setFont,
+ numArgs: 2,
+ variableArgs: false
+ },
+ Tr: {
+ id: OPS.setTextRenderingMode,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Ts: {
+ id: OPS.setTextRise,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Td: {
+ id: OPS.moveText,
+ numArgs: 2,
+ variableArgs: false
+ },
+ TD: {
+ id: OPS.setLeadingMoveText,
+ numArgs: 2,
+ variableArgs: false
+ },
+ Tm: {
+ id: OPS.setTextMatrix,
+ numArgs: 6,
+ variableArgs: false
+ },
+ "T*": {
+ id: OPS.nextLine,
+ numArgs: 0,
+ variableArgs: false
+ },
+ Tj: {
+ id: OPS.showText,
+ numArgs: 1,
+ variableArgs: false
+ },
+ TJ: {
+ id: OPS.showSpacedText,
+ numArgs: 1,
+ variableArgs: false
+ },
+ "'": {
+ id: OPS.nextLineShowText,
+ numArgs: 1,
+ variableArgs: false
+ },
+ '"': {
+ id: OPS.nextLineSetSpacingShowText,
+ numArgs: 3,
+ variableArgs: false
+ },
+ d0: {
+ id: OPS.setCharWidth,
+ numArgs: 2,
+ variableArgs: false
+ },
+ d1: {
+ id: OPS.setCharWidthAndBounds,
+ numArgs: 6,
+ variableArgs: false
+ },
+ CS: {
+ id: OPS.setStrokeColorSpace,
+ numArgs: 1,
+ variableArgs: false
+ },
+ cs: {
+ id: OPS.setFillColorSpace,
+ numArgs: 1,
+ variableArgs: false
+ },
+ SC: {
+ id: OPS.setStrokeColor,
+ numArgs: 4,
+ variableArgs: true
+ },
+ SCN: {
+ id: OPS.setStrokeColorN,
+ numArgs: 33,
+ variableArgs: true
+ },
+ sc: {
+ id: OPS.setFillColor,
+ numArgs: 4,
+ variableArgs: true
+ },
+ scn: {
+ id: OPS.setFillColorN,
+ numArgs: 33,
+ variableArgs: true
+ },
+ G: {
+ id: OPS.setStrokeGray,
+ numArgs: 1,
+ variableArgs: false
+ },
+ g: {
+ id: OPS.setFillGray,
+ numArgs: 1,
+ variableArgs: false
+ },
+ RG: {
+ id: OPS.setStrokeRGBColor,
+ numArgs: 3,
+ variableArgs: false
+ },
+ rg: {
+ id: OPS.setFillRGBColor,
+ numArgs: 3,
+ variableArgs: false
+ },
+ K: {
+ id: OPS.setStrokeCMYKColor,
+ numArgs: 4,
+ variableArgs: false
+ },
+ k: {
+ id: OPS.setFillCMYKColor,
+ numArgs: 4,
+ variableArgs: false
+ },
+ sh: {
+ id: OPS.shadingFill,
+ numArgs: 1,
+ variableArgs: false
+ },
+ BI: {
+ id: OPS.beginInlineImage,
+ numArgs: 0,
+ variableArgs: false
+ },
+ ID: {
+ id: OPS.beginImageData,
+ numArgs: 0,
+ variableArgs: false
+ },
+ EI: {
+ id: OPS.endInlineImage,
+ numArgs: 1,
+ variableArgs: false
+ },
+ Do: {
+ id: OPS.paintXObject,
+ numArgs: 1,
+ variableArgs: false
+ },
+ MP: {
+ id: OPS.markPoint,
+ numArgs: 1,
+ variableArgs: false
+ },
+ DP: {
+ id: OPS.markPointProps,
+ numArgs: 2,
+ variableArgs: false
+ },
+ BMC: {
+ id: OPS.beginMarkedContent,
+ numArgs: 1,
+ variableArgs: false
+ },
+ BDC: {
+ id: OPS.beginMarkedContentProps,
+ numArgs: 2,
+ variableArgs: false
+ },
+ EMC: {
+ id: OPS.endMarkedContent,
+ numArgs: 0,
+ variableArgs: false
+ },
+ BX: {
+ id: OPS.beginCompat,
+ numArgs: 0,
+ variableArgs: false
+ },
+ EX: {
+ id: OPS.endCompat,
+ numArgs: 0,
+ variableArgs: false
+ },
+ BM: null,
+ BD: null,
+ true: null,
+ fa: null,
+ fal: null,
+ fals: null,
+ false: null,
+ nu: null,
+ nul: null,
+ null: null
+ });
+ }
+ static MAX_INVALID_PATH_OPS = 10;
+ constructor(stream, xref, stateManager = new StateManager()) {
+ this.parser = new Parser({
+ lexer: new Lexer(stream, EvaluatorPreprocessor.opMap),
+ xref
+ });
+ this.stateManager = stateManager;
+ this.nonProcessedArgs = [];
+ this._isPathOp = false;
+ this._numInvalidPathOPS = 0;
+ }
+ get savedStatesDepth() {
+ return this.stateManager.stateStack.length;
+ }
+ read(operation) {
+ let args = operation.args;
+ while (true) {
+ const obj = this.parser.getObj();
+ if (obj instanceof Cmd) {
+ const cmd = obj.cmd;
+ const opSpec = EvaluatorPreprocessor.opMap[cmd];
+ if (!opSpec) {
+ warn(`Unknown command "${cmd}".`);
+ continue;
+ }
+ const fn = opSpec.id;
+ const numArgs = opSpec.numArgs;
+ let argsLength = args !== null ? args.length : 0;
+ if (!this._isPathOp) {
+ this._numInvalidPathOPS = 0;
+ }
+ this._isPathOp = fn >= OPS.moveTo && fn <= OPS.endPath;
+ if (!opSpec.variableArgs) {
+ if (argsLength !== numArgs) {
+ const nonProcessedArgs = this.nonProcessedArgs;
+ while (argsLength > numArgs) {
+ nonProcessedArgs.push(args.shift());
+ argsLength--;
+ }
+ while (argsLength < numArgs && nonProcessedArgs.length !== 0) {
+ if (args === null) {
+ args = [];
+ }
+ args.unshift(nonProcessedArgs.pop());
+ argsLength++;
+ }
+ }
+ if (argsLength < numArgs) {
+ const partialMsg = `command ${cmd}: expected ${numArgs} args, ` + `but received ${argsLength} args.`;
+ if (this._isPathOp && ++this._numInvalidPathOPS > EvaluatorPreprocessor.MAX_INVALID_PATH_OPS) {
+ throw new FormatError(`Invalid ${partialMsg}`);
+ }
+ warn(`Skipping ${partialMsg}`);
+ if (args !== null) {
+ args.length = 0;
+ }
+ continue;
+ }
+ } else if (argsLength > numArgs) {
+ info(`Command ${cmd}: expected [0, ${numArgs}] args, ` + `but received ${argsLength} args.`);
+ }
+ this.preprocessCommand(fn, args);
+ operation.fn = fn;
+ operation.args = args;
+ return true;
+ }
+ if (obj === EOF) {
+ return false;
+ }
+ if (obj !== null) {
+ if (args === null) {
+ args = [];
+ }
+ args.push(obj);
+ if (args.length > 33) {
+ throw new FormatError("Too many arguments");
+ }
+ }
+ }
+ }
+ preprocessCommand(fn, args) {
+ switch (fn | 0) {
+ case OPS.save:
+ this.stateManager.save();
+ break;
+ case OPS.restore:
+ this.stateManager.restore();
+ break;
+ case OPS.transform:
+ this.stateManager.transform(args);
+ break;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/default_appearance.js
+
+
+
+
+
+
+
+
+class DefaultAppearanceEvaluator extends EvaluatorPreprocessor {
+ constructor(str) {
+ super(new StringStream(str));
+ }
+ parse() {
+ const operation = {
+ fn: 0,
+ args: []
+ };
+ const result = {
+ fontSize: 0,
+ fontName: "",
+ fontColor: new Uint8ClampedArray(3)
+ };
+ try {
+ while (true) {
+ operation.args.length = 0;
+ if (!this.read(operation)) {
+ break;
+ }
+ if (this.savedStatesDepth !== 0) {
+ continue;
+ }
+ const {
+ fn,
+ args
+ } = operation;
+ switch (fn | 0) {
+ case OPS.setFont:
+ const [fontName, fontSize] = args;
+ if (fontName instanceof Name) {
+ result.fontName = fontName.name;
+ }
+ if (typeof fontSize === "number" && fontSize > 0) {
+ result.fontSize = fontSize;
+ }
+ break;
+ case OPS.setFillRGBColor:
+ ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.setFillGray:
+ ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.setFillCMYKColor:
+ ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ }
+ }
+ } catch (reason) {
+ warn(`parseDefaultAppearance - ignoring errors: "${reason}".`);
+ }
+ return result;
+ }
+}
+function parseDefaultAppearance(str) {
+ return new DefaultAppearanceEvaluator(str).parse();
+}
+class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
+ constructor(stream, evaluatorOptions, xref) {
+ super(stream);
+ this.stream = stream;
+ this.evaluatorOptions = evaluatorOptions;
+ this.xref = xref;
+ this.resources = stream.dict?.get("Resources");
+ }
+ parse() {
+ const operation = {
+ fn: 0,
+ args: []
+ };
+ let result = {
+ scaleFactor: 1,
+ fontSize: 0,
+ fontName: "",
+ fontColor: new Uint8ClampedArray(3),
+ fillColorSpace: ColorSpace.singletons.gray
+ };
+ let breakLoop = false;
+ const stack = [];
+ try {
+ while (true) {
+ operation.args.length = 0;
+ if (breakLoop || !this.read(operation)) {
+ break;
+ }
+ const {
+ fn,
+ args
+ } = operation;
+ switch (fn | 0) {
+ case OPS.save:
+ stack.push({
+ scaleFactor: result.scaleFactor,
+ fontSize: result.fontSize,
+ fontName: result.fontName,
+ fontColor: result.fontColor.slice(),
+ fillColorSpace: result.fillColorSpace
+ });
+ break;
+ case OPS.restore:
+ result = stack.pop() || result;
+ break;
+ case OPS.setTextMatrix:
+ result.scaleFactor *= Math.hypot(args[0], args[1]);
+ break;
+ case OPS.setFont:
+ const [fontName, fontSize] = args;
+ if (fontName instanceof Name) {
+ result.fontName = fontName.name;
+ }
+ if (typeof fontSize === "number" && fontSize > 0) {
+ result.fontSize = fontSize * result.scaleFactor;
+ }
+ break;
+ case OPS.setFillColorSpace:
+ result.fillColorSpace = ColorSpace.parse({
+ cs: args[0],
+ xref: this.xref,
+ resources: this.resources,
+ pdfFunctionFactory: this._pdfFunctionFactory,
+ localColorSpaceCache: this._localColorSpaceCache
+ });
+ break;
+ case OPS.setFillColor:
+ const cs = result.fillColorSpace;
+ cs.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.setFillRGBColor:
+ ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.setFillGray:
+ ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.setFillCMYKColor:
+ ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0);
+ break;
+ case OPS.showText:
+ case OPS.showSpacedText:
+ case OPS.nextLineShowText:
+ case OPS.nextLineSetSpacingShowText:
+ breakLoop = true;
+ break;
+ }
+ }
+ } catch (reason) {
+ warn(`parseAppearanceStream - ignoring errors: "${reason}".`);
+ }
+ this.stream.reset();
+ delete result.scaleFactor;
+ delete result.fillColorSpace;
+ return result;
+ }
+ get _localColorSpaceCache() {
+ return shadow(this, "_localColorSpaceCache", new LocalColorSpaceCache());
+ }
+ get _pdfFunctionFactory() {
+ const pdfFunctionFactory = new PDFFunctionFactory({
+ xref: this.xref,
+ isEvalSupported: this.evaluatorOptions.isEvalSupported
+ });
+ return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory);
+ }
+}
+function parseAppearanceStream(stream, evaluatorOptions, xref) {
+ return new AppearanceStreamEvaluator(stream, evaluatorOptions, xref).parse();
+}
+function getPdfColor(color, isFill) {
+ if (color[0] === color[1] && color[1] === color[2]) {
+ const gray = color[0] / 255;
+ return `${numberToString(gray)} ${isFill ? "g" : "G"}`;
+ }
+ return Array.from(color, c => numberToString(c / 255)).join(" ") + ` ${isFill ? "rg" : "RG"}`;
+}
+function createDefaultAppearance({
+ fontSize,
+ fontName,
+ fontColor
+}) {
+ return `/${escapePDFName(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`;
+}
+class FakeUnicodeFont {
+ constructor(xref, fontFamily) {
+ this.xref = xref;
+ this.widths = null;
+ this.firstChar = Infinity;
+ this.lastChar = -Infinity;
+ this.fontFamily = fontFamily;
+ const canvas = new OffscreenCanvas(1, 1);
+ this.ctxMeasure = canvas.getContext("2d");
+ if (!FakeUnicodeFont._fontNameId) {
+ FakeUnicodeFont._fontNameId = 1;
+ }
+ this.fontName = Name.get(`InvalidPDFjsFont_${fontFamily}_${FakeUnicodeFont._fontNameId++}`);
+ }
+ get toUnicodeRef() {
+ if (!FakeUnicodeFont._toUnicodeRef) {
+ const toUnicode = `/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (Adobe)
+/Ordering (UCS) /Supplement 0 >> def
+/CMapName /Adobe-Identity-UCS def
+/CMapType 2 def
+1 begincodespacerange
+<0000>
+endcodespacerange
+1 beginbfrange
+<0000> <0000>
+endbfrange
+endcmap CMapName currentdict /CMap defineresource pop end end`;
+ const toUnicodeStream = FakeUnicodeFont.toUnicodeStream = new StringStream(toUnicode);
+ const toUnicodeDict = new Dict(this.xref);
+ toUnicodeStream.dict = toUnicodeDict;
+ toUnicodeDict.set("Length", toUnicode.length);
+ FakeUnicodeFont._toUnicodeRef = this.xref.getNewPersistentRef(toUnicodeStream);
+ }
+ return FakeUnicodeFont._toUnicodeRef;
+ }
+ get fontDescriptorRef() {
+ if (!FakeUnicodeFont._fontDescriptorRef) {
+ const fontDescriptor = new Dict(this.xref);
+ fontDescriptor.set("Type", Name.get("FontDescriptor"));
+ fontDescriptor.set("FontName", this.fontName);
+ fontDescriptor.set("FontFamily", "MyriadPro Regular");
+ fontDescriptor.set("FontBBox", [0, 0, 0, 0]);
+ fontDescriptor.set("FontStretch", Name.get("Normal"));
+ fontDescriptor.set("FontWeight", 400);
+ fontDescriptor.set("ItalicAngle", 0);
+ FakeUnicodeFont._fontDescriptorRef = this.xref.getNewPersistentRef(fontDescriptor);
+ }
+ return FakeUnicodeFont._fontDescriptorRef;
+ }
+ get descendantFontRef() {
+ const descendantFont = new Dict(this.xref);
+ descendantFont.set("BaseFont", this.fontName);
+ descendantFont.set("Type", Name.get("Font"));
+ descendantFont.set("Subtype", Name.get("CIDFontType0"));
+ descendantFont.set("CIDToGIDMap", Name.get("Identity"));
+ descendantFont.set("FirstChar", this.firstChar);
+ descendantFont.set("LastChar", this.lastChar);
+ descendantFont.set("FontDescriptor", this.fontDescriptorRef);
+ descendantFont.set("DW", 1000);
+ const widths = [];
+ const chars = [...this.widths.entries()].sort();
+ let currentChar = null;
+ let currentWidths = null;
+ for (const [char, width] of chars) {
+ if (!currentChar) {
+ currentChar = char;
+ currentWidths = [width];
+ continue;
+ }
+ if (char === currentChar + currentWidths.length) {
+ currentWidths.push(width);
+ } else {
+ widths.push(currentChar, currentWidths);
+ currentChar = char;
+ currentWidths = [width];
+ }
+ }
+ if (currentChar) {
+ widths.push(currentChar, currentWidths);
+ }
+ descendantFont.set("W", widths);
+ const cidSystemInfo = new Dict(this.xref);
+ cidSystemInfo.set("Ordering", "Identity");
+ cidSystemInfo.set("Registry", "Adobe");
+ cidSystemInfo.set("Supplement", 0);
+ descendantFont.set("CIDSystemInfo", cidSystemInfo);
+ return this.xref.getNewPersistentRef(descendantFont);
+ }
+ get baseFontRef() {
+ const baseFont = new Dict(this.xref);
+ baseFont.set("BaseFont", this.fontName);
+ baseFont.set("Type", Name.get("Font"));
+ baseFont.set("Subtype", Name.get("Type0"));
+ baseFont.set("Encoding", Name.get("Identity-H"));
+ baseFont.set("DescendantFonts", [this.descendantFontRef]);
+ baseFont.set("ToUnicode", this.toUnicodeRef);
+ return this.xref.getNewPersistentRef(baseFont);
+ }
+ get resources() {
+ const resources = new Dict(this.xref);
+ const font = new Dict(this.xref);
+ font.set(this.fontName.name, this.baseFontRef);
+ resources.set("Font", font);
+ return resources;
+ }
+ _createContext() {
+ this.widths = new Map();
+ this.ctxMeasure.font = `1000px ${this.fontFamily}`;
+ return this.ctxMeasure;
+ }
+ createFontResources(text) {
+ const ctx = this._createContext();
+ for (const line of text.split(/\r\n?|\n/)) {
+ for (const char of line.split("")) {
+ const code = char.charCodeAt(0);
+ if (this.widths.has(code)) {
+ continue;
+ }
+ const metrics = ctx.measureText(char);
+ const width = Math.ceil(metrics.width);
+ this.widths.set(code, width);
+ this.firstChar = Math.min(code, this.firstChar);
+ this.lastChar = Math.max(code, this.lastChar);
+ }
+ }
+ return this.resources;
+ }
+ createAppearance(text, rect, rotation, fontSize, bgColor, strokeAlpha) {
+ const ctx = this._createContext();
+ const lines = [];
+ let maxWidth = -Infinity;
+ for (const line of text.split(/\r\n?|\n/)) {
+ lines.push(line);
+ const lineWidth = ctx.measureText(line).width;
+ maxWidth = Math.max(maxWidth, lineWidth);
+ for (const char of line.split("")) {
+ const code = char.charCodeAt(0);
+ let width = this.widths.get(code);
+ if (width === undefined) {
+ const metrics = ctx.measureText(char);
+ width = Math.ceil(metrics.width);
+ this.widths.set(code, width);
+ this.firstChar = Math.min(code, this.firstChar);
+ this.lastChar = Math.max(code, this.lastChar);
+ }
+ }
+ }
+ maxWidth *= fontSize / 1000;
+ const [x1, y1, x2, y2] = rect;
+ let w = x2 - x1;
+ let h = y2 - y1;
+ if (rotation % 180 !== 0) {
+ [w, h] = [h, w];
+ }
+ let hscale = 1;
+ if (maxWidth > w) {
+ hscale = w / maxWidth;
+ }
+ let vscale = 1;
+ const lineHeight = LINE_FACTOR * fontSize;
+ const lineDescent = LINE_DESCENT_FACTOR * fontSize;
+ const maxHeight = lineHeight * lines.length;
+ if (maxHeight > h) {
+ vscale = h / maxHeight;
+ }
+ const fscale = Math.min(hscale, vscale);
+ const newFontSize = fontSize * fscale;
+ const buffer = ["q", `0 0 ${numberToString(w)} ${numberToString(h)} re W n`, `BT`, `1 0 0 1 0 ${numberToString(h + lineDescent)} Tm 0 Tc ${getPdfColor(bgColor, true)}`, `/${this.fontName.name} ${numberToString(newFontSize)} Tf`];
+ const {
+ resources
+ } = this;
+ strokeAlpha = typeof strokeAlpha === "number" && strokeAlpha >= 0 && strokeAlpha <= 1 ? strokeAlpha : 1;
+ if (strokeAlpha !== 1) {
+ buffer.push("/R0 gs");
+ const extGState = new Dict(this.xref);
+ const r0 = new Dict(this.xref);
+ r0.set("ca", strokeAlpha);
+ r0.set("CA", strokeAlpha);
+ r0.set("Type", Name.get("ExtGState"));
+ extGState.set("R0", r0);
+ resources.set("ExtGState", extGState);
+ }
+ const vShift = numberToString(lineHeight);
+ for (const line of lines) {
+ buffer.push(`0 -${vShift} Td <${stringToUTF16HexString(line)}> Tj`);
+ }
+ buffer.push("ET", "Q");
+ const appearance = buffer.join("\n");
+ const appearanceStreamDict = new Dict(this.xref);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", [0, 0, w, h]);
+ appearanceStreamDict.set("Length", appearance.length);
+ appearanceStreamDict.set("Resources", resources);
+ if (rotation) {
+ const matrix = getRotationMatrix(rotation, w, h);
+ appearanceStreamDict.set("Matrix", matrix);
+ }
+ const ap = new StringStream(appearance);
+ ap.dict = appearanceStreamDict;
+ return ap;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/name_number_tree.js
+
+
+class NameOrNumberTree {
+ constructor(root, xref, type) {
+ if (this.constructor === NameOrNumberTree) {
+ unreachable("Cannot initialize NameOrNumberTree.");
+ }
+ this.root = root;
+ this.xref = xref;
+ this._type = type;
+ }
+ getAll() {
+ const map = new Map();
+ if (!this.root) {
+ return map;
+ }
+ const xref = this.xref;
+ const processed = new RefSet();
+ processed.put(this.root);
+ const queue = [this.root];
+ while (queue.length > 0) {
+ const obj = xref.fetchIfRef(queue.shift());
+ if (!(obj instanceof Dict)) {
+ continue;
+ }
+ if (obj.has("Kids")) {
+ const kids = obj.get("Kids");
+ if (!Array.isArray(kids)) {
+ continue;
+ }
+ for (const kid of kids) {
+ if (processed.has(kid)) {
+ throw new FormatError(`Duplicate entry in "${this._type}" tree.`);
+ }
+ queue.push(kid);
+ processed.put(kid);
+ }
+ continue;
+ }
+ const entries = obj.get(this._type);
+ if (!Array.isArray(entries)) {
+ continue;
+ }
+ for (let i = 0, ii = entries.length; i < ii; i += 2) {
+ map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1]));
+ }
+ }
+ return map;
+ }
+ get(key) {
+ if (!this.root) {
+ return null;
+ }
+ const xref = this.xref;
+ let kidsOrEntries = xref.fetchIfRef(this.root);
+ let loopCount = 0;
+ const MAX_LEVELS = 10;
+ while (kidsOrEntries.has("Kids")) {
+ if (++loopCount > MAX_LEVELS) {
+ warn(`Search depth limit reached for "${this._type}" tree.`);
+ return null;
+ }
+ const kids = kidsOrEntries.get("Kids");
+ if (!Array.isArray(kids)) {
+ return null;
+ }
+ let l = 0,
+ r = kids.length - 1;
+ while (l <= r) {
+ const m = l + r >> 1;
+ const kid = xref.fetchIfRef(kids[m]);
+ const limits = kid.get("Limits");
+ if (key < xref.fetchIfRef(limits[0])) {
+ r = m - 1;
+ } else if (key > xref.fetchIfRef(limits[1])) {
+ l = m + 1;
+ } else {
+ kidsOrEntries = kid;
+ break;
+ }
+ }
+ if (l > r) {
+ return null;
+ }
+ }
+ const entries = kidsOrEntries.get(this._type);
+ if (Array.isArray(entries)) {
+ let l = 0,
+ r = entries.length - 2;
+ while (l <= r) {
+ const tmp = l + r >> 1,
+ m = tmp + (tmp & 1);
+ const currentKey = xref.fetchIfRef(entries[m]);
+ if (key < currentKey) {
+ r = m - 2;
+ } else if (key > currentKey) {
+ l = m + 2;
+ } else {
+ return xref.fetchIfRef(entries[m + 1]);
+ }
+ }
+ }
+ return null;
+ }
+}
+class NameTree extends NameOrNumberTree {
+ constructor(root, xref) {
+ super(root, xref, "Names");
+ }
+}
+class NumberTree extends NameOrNumberTree {
+ constructor(root, xref) {
+ super(root, xref, "Nums");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/cleanup_helper.js
+
+
+
+function clearGlobalCaches() {
+ clearPatternCaches();
+ clearPrimitiveCaches();
+ clearUnicodeCaches();
+}
+
+;// CONCATENATED MODULE: ./src/core/file_spec.js
+
+
+
+function pickPlatformItem(dict) {
+ if (dict.has("UF")) {
+ return dict.get("UF");
+ } else if (dict.has("F")) {
+ return dict.get("F");
+ } else if (dict.has("Unix")) {
+ return dict.get("Unix");
+ } else if (dict.has("Mac")) {
+ return dict.get("Mac");
+ } else if (dict.has("DOS")) {
+ return dict.get("DOS");
+ }
+ return null;
+}
+class FileSpec {
+ constructor(root, xref) {
+ if (!(root instanceof Dict)) {
+ return;
+ }
+ this.xref = xref;
+ this.root = root;
+ if (root.has("FS")) {
+ this.fs = root.get("FS");
+ }
+ this.description = root.has("Desc") ? stringToPDFString(root.get("Desc")) : "";
+ if (root.has("RF")) {
+ warn("Related file specifications are not supported");
+ }
+ this.contentAvailable = true;
+ if (!root.has("EF")) {
+ this.contentAvailable = false;
+ warn("Non-embedded file specifications are not supported");
+ }
+ }
+ get filename() {
+ if (!this._filename && this.root) {
+ const filename = pickPlatformItem(this.root) || "unnamed";
+ this._filename = stringToPDFString(filename).replaceAll("\\\\", "\\").replaceAll("\\/", "/").replaceAll("\\", "/");
+ }
+ return this._filename;
+ }
+ get content() {
+ if (!this.contentAvailable) {
+ return null;
+ }
+ if (!this.contentRef && this.root) {
+ this.contentRef = pickPlatformItem(this.root.get("EF"));
+ }
+ let content = null;
+ if (this.contentRef) {
+ const fileObj = this.xref.fetchIfRef(this.contentRef);
+ if (fileObj instanceof BaseStream) {
+ content = fileObj.getBytes();
+ } else {
+ warn("Embedded file specification points to non-existing/invalid content");
+ }
+ } else {
+ warn("Embedded file specification does not have a content");
+ }
+ return content;
+ }
+ get serializable() {
+ return {
+ filename: this.filename,
+ content: this.content
+ };
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xml_parser.js
+
+const XMLParserErrorCode = {
+ NoError: 0,
+ EndOfDocument: -1,
+ UnterminatedCdat: -2,
+ UnterminatedXmlDeclaration: -3,
+ UnterminatedDoctypeDeclaration: -4,
+ UnterminatedComment: -5,
+ MalformedElement: -6,
+ OutOfMemory: -7,
+ UnterminatedAttributeValue: -8,
+ UnterminatedElement: -9,
+ ElementNeverBegun: -10
+};
+function isWhitespace(s, index) {
+ const ch = s[index];
+ return ch === " " || ch === "\n" || ch === "\r" || ch === "\t";
+}
+function isWhitespaceString(s) {
+ for (let i = 0, ii = s.length; i < ii; i++) {
+ if (!isWhitespace(s, i)) {
+ return false;
+ }
+ }
+ return true;
+}
+class XMLParserBase {
+ _resolveEntities(s) {
+ return s.replaceAll(/&([^;]+);/g, (all, entity) => {
+ if (entity.substring(0, 2) === "#x") {
+ return String.fromCodePoint(parseInt(entity.substring(2), 16));
+ } else if (entity.substring(0, 1) === "#") {
+ return String.fromCodePoint(parseInt(entity.substring(1), 10));
+ }
+ switch (entity) {
+ case "lt":
+ return "<";
+ case "gt":
+ return ">";
+ case "amp":
+ return "&";
+ case "quot":
+ return '"';
+ case "apos":
+ return "'";
+ }
+ return this.onResolveEntity(entity);
+ });
+ }
+ _parseContent(s, start) {
+ const attributes = [];
+ let pos = start;
+ function skipWs() {
+ while (pos < s.length && isWhitespace(s, pos)) {
+ ++pos;
+ }
+ }
+ while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "/") {
+ ++pos;
+ }
+ const name = s.substring(start, pos);
+ skipWs();
+ while (pos < s.length && s[pos] !== ">" && s[pos] !== "/" && s[pos] !== "?") {
+ skipWs();
+ let attrName = "",
+ attrValue = "";
+ while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== "=") {
+ attrName += s[pos];
+ ++pos;
+ }
+ skipWs();
+ if (s[pos] !== "=") {
+ return null;
+ }
+ ++pos;
+ skipWs();
+ const attrEndChar = s[pos];
+ if (attrEndChar !== '"' && attrEndChar !== "'") {
+ return null;
+ }
+ const attrEndIndex = s.indexOf(attrEndChar, ++pos);
+ if (attrEndIndex < 0) {
+ return null;
+ }
+ attrValue = s.substring(pos, attrEndIndex);
+ attributes.push({
+ name: attrName,
+ value: this._resolveEntities(attrValue)
+ });
+ pos = attrEndIndex + 1;
+ skipWs();
+ }
+ return {
+ name,
+ attributes,
+ parsed: pos - start
+ };
+ }
+ _parseProcessingInstruction(s, start) {
+ let pos = start;
+ function skipWs() {
+ while (pos < s.length && isWhitespace(s, pos)) {
+ ++pos;
+ }
+ }
+ while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "?" && s[pos] !== "/") {
+ ++pos;
+ }
+ const name = s.substring(start, pos);
+ skipWs();
+ const attrStart = pos;
+ while (pos < s.length && (s[pos] !== "?" || s[pos + 1] !== ">")) {
+ ++pos;
+ }
+ const value = s.substring(attrStart, pos);
+ return {
+ name,
+ value,
+ parsed: pos - start
+ };
+ }
+ parseXml(s) {
+ let i = 0;
+ while (i < s.length) {
+ const ch = s[i];
+ let j = i;
+ if (ch === "<") {
+ ++j;
+ const ch2 = s[j];
+ let q;
+ switch (ch2) {
+ case "/":
+ ++j;
+ q = s.indexOf(">", j);
+ if (q < 0) {
+ this.onError(XMLParserErrorCode.UnterminatedElement);
+ return;
+ }
+ this.onEndElement(s.substring(j, q));
+ j = q + 1;
+ break;
+ case "?":
+ ++j;
+ const pi = this._parseProcessingInstruction(s, j);
+ if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== "?>") {
+ this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration);
+ return;
+ }
+ this.onPi(pi.name, pi.value);
+ j += pi.parsed + 2;
+ break;
+ case "!":
+ if (s.substring(j + 1, j + 3) === "--") {
+ q = s.indexOf("-->", j + 3);
+ if (q < 0) {
+ this.onError(XMLParserErrorCode.UnterminatedComment);
+ return;
+ }
+ this.onComment(s.substring(j + 3, q));
+ j = q + 3;
+ } else if (s.substring(j + 1, j + 8) === "[CDATA[") {
+ q = s.indexOf("]]>", j + 8);
+ if (q < 0) {
+ this.onError(XMLParserErrorCode.UnterminatedCdat);
+ return;
+ }
+ this.onCdata(s.substring(j + 8, q));
+ j = q + 3;
+ } else if (s.substring(j + 1, j + 8) === "DOCTYPE") {
+ const q2 = s.indexOf("[", j + 8);
+ let complexDoctype = false;
+ q = s.indexOf(">", j + 8);
+ if (q < 0) {
+ this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);
+ return;
+ }
+ if (q2 > 0 && q > q2) {
+ q = s.indexOf("]>", j + 8);
+ if (q < 0) {
+ this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);
+ return;
+ }
+ complexDoctype = true;
+ }
+ const doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0));
+ this.onDoctype(doctypeContent);
+ j = q + (complexDoctype ? 2 : 1);
+ } else {
+ this.onError(XMLParserErrorCode.MalformedElement);
+ return;
+ }
+ break;
+ default:
+ const content = this._parseContent(s, j);
+ if (content === null) {
+ this.onError(XMLParserErrorCode.MalformedElement);
+ return;
+ }
+ let isClosed = false;
+ if (s.substring(j + content.parsed, j + content.parsed + 2) === "/>") {
+ isClosed = true;
+ } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== ">") {
+ this.onError(XMLParserErrorCode.UnterminatedElement);
+ return;
+ }
+ this.onBeginElement(content.name, content.attributes, isClosed);
+ j += content.parsed + (isClosed ? 2 : 1);
+ break;
+ }
+ } else {
+ while (j < s.length && s[j] !== "<") {
+ j++;
+ }
+ const text = s.substring(i, j);
+ this.onText(this._resolveEntities(text));
+ }
+ i = j;
+ }
+ }
+ onResolveEntity(name) {
+ return `&${name};`;
+ }
+ onPi(name, value) {}
+ onComment(text) {}
+ onCdata(text) {}
+ onDoctype(doctypeContent) {}
+ onText(text) {}
+ onBeginElement(name, attributes, isEmpty) {}
+ onEndElement(name) {}
+ onError(code) {}
+}
+class SimpleDOMNode {
+ constructor(nodeName, nodeValue) {
+ this.nodeName = nodeName;
+ this.nodeValue = nodeValue;
+ Object.defineProperty(this, "parentNode", {
+ value: null,
+ writable: true
+ });
+ }
+ get firstChild() {
+ return this.childNodes?.[0];
+ }
+ get nextSibling() {
+ const childNodes = this.parentNode.childNodes;
+ if (!childNodes) {
+ return undefined;
+ }
+ const index = childNodes.indexOf(this);
+ if (index === -1) {
+ return undefined;
+ }
+ return childNodes[index + 1];
+ }
+ get textContent() {
+ if (!this.childNodes) {
+ return this.nodeValue || "";
+ }
+ return this.childNodes.map(function (child) {
+ return child.textContent;
+ }).join("");
+ }
+ get children() {
+ return this.childNodes || [];
+ }
+ hasChildNodes() {
+ return this.childNodes?.length > 0;
+ }
+ searchNode(paths, pos) {
+ if (pos >= paths.length) {
+ return this;
+ }
+ const component = paths[pos];
+ if (component.name.startsWith("#") && pos < paths.length - 1) {
+ return this.searchNode(paths, pos + 1);
+ }
+ const stack = [];
+ let node = this;
+ while (true) {
+ if (component.name === node.nodeName) {
+ if (component.pos === 0) {
+ const res = node.searchNode(paths, pos + 1);
+ if (res !== null) {
+ return res;
+ }
+ } else if (stack.length === 0) {
+ return null;
+ } else {
+ const [parent] = stack.pop();
+ let siblingPos = 0;
+ for (const child of parent.childNodes) {
+ if (component.name === child.nodeName) {
+ if (siblingPos === component.pos) {
+ return child.searchNode(paths, pos + 1);
+ }
+ siblingPos++;
+ }
+ }
+ return node.searchNode(paths, pos + 1);
+ }
+ }
+ if (node.childNodes?.length > 0) {
+ stack.push([node, 0]);
+ node = node.childNodes[0];
+ } else if (stack.length === 0) {
+ return null;
+ } else {
+ while (stack.length !== 0) {
+ const [parent, currentPos] = stack.pop();
+ const newPos = currentPos + 1;
+ if (newPos < parent.childNodes.length) {
+ stack.push([parent, newPos]);
+ node = parent.childNodes[newPos];
+ break;
+ }
+ }
+ if (stack.length === 0) {
+ return null;
+ }
+ }
+ }
+ }
+ dump(buffer) {
+ if (this.nodeName === "#text") {
+ buffer.push(encodeToXmlString(this.nodeValue));
+ return;
+ }
+ buffer.push(`<${this.nodeName}`);
+ if (this.attributes) {
+ for (const attribute of this.attributes) {
+ buffer.push(` ${attribute.name}="${encodeToXmlString(attribute.value)}"`);
+ }
+ }
+ if (this.hasChildNodes()) {
+ buffer.push(">");
+ for (const child of this.childNodes) {
+ child.dump(buffer);
+ }
+ buffer.push(`${this.nodeName}>`);
+ } else if (this.nodeValue) {
+ buffer.push(`>${encodeToXmlString(this.nodeValue)}${this.nodeName}>`);
+ } else {
+ buffer.push("/>");
+ }
+ }
+}
+class SimpleXMLParser extends XMLParserBase {
+ constructor({
+ hasAttributes = false,
+ lowerCaseName = false
+ }) {
+ super();
+ this._currentFragment = null;
+ this._stack = null;
+ this._errorCode = XMLParserErrorCode.NoError;
+ this._hasAttributes = hasAttributes;
+ this._lowerCaseName = lowerCaseName;
+ }
+ parseFromString(data) {
+ this._currentFragment = [];
+ this._stack = [];
+ this._errorCode = XMLParserErrorCode.NoError;
+ this.parseXml(data);
+ if (this._errorCode !== XMLParserErrorCode.NoError) {
+ return undefined;
+ }
+ const [documentElement] = this._currentFragment;
+ if (!documentElement) {
+ return undefined;
+ }
+ return {
+ documentElement
+ };
+ }
+ onText(text) {
+ if (isWhitespaceString(text)) {
+ return;
+ }
+ const node = new SimpleDOMNode("#text", text);
+ this._currentFragment.push(node);
+ }
+ onCdata(text) {
+ const node = new SimpleDOMNode("#text", text);
+ this._currentFragment.push(node);
+ }
+ onBeginElement(name, attributes, isEmpty) {
+ if (this._lowerCaseName) {
+ name = name.toLowerCase();
+ }
+ const node = new SimpleDOMNode(name);
+ node.childNodes = [];
+ if (this._hasAttributes) {
+ node.attributes = attributes;
+ }
+ this._currentFragment.push(node);
+ if (isEmpty) {
+ return;
+ }
+ this._stack.push(this._currentFragment);
+ this._currentFragment = node.childNodes;
+ }
+ onEndElement(name) {
+ this._currentFragment = this._stack.pop() || [];
+ const lastElement = this._currentFragment.at(-1);
+ if (!lastElement) {
+ return null;
+ }
+ for (const childNode of lastElement.childNodes) {
+ childNode.parentNode = lastElement;
+ }
+ return lastElement;
+ }
+ onError(code) {
+ this._errorCode = code;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/metadata_parser.js
+
+class MetadataParser {
+ constructor(data) {
+ data = this._repair(data);
+ const parser = new SimpleXMLParser({
+ lowerCaseName: true
+ });
+ const xmlDocument = parser.parseFromString(data);
+ this._metadataMap = new Map();
+ this._data = data;
+ if (xmlDocument) {
+ this._parse(xmlDocument);
+ }
+ }
+ _repair(data) {
+ return data.replace(/^[^<]+/, "").replaceAll(/>\\376\\377([^<]+)/g, function (all, codes) {
+ const bytes = codes.replaceAll(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {
+ return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
+ }).replaceAll(/&(amp|apos|gt|lt|quot);/g, function (str, name) {
+ switch (name) {
+ case "amp":
+ return "&";
+ case "apos":
+ return "'";
+ case "gt":
+ return ">";
+ case "lt":
+ return "<";
+ case "quot":
+ return '"';
+ }
+ throw new Error(`_repair: ${name} isn't defined.`);
+ });
+ const charBuf = [">"];
+ for (let i = 0, ii = bytes.length; i < ii; i += 2) {
+ const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+ if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) {
+ charBuf.push(String.fromCharCode(code));
+ } else {
+ charBuf.push("" + (0x10000 + code).toString(16).substring(1) + ";");
+ }
+ }
+ return charBuf.join("");
+ });
+ }
+ _getSequence(entry) {
+ const name = entry.nodeName;
+ if (name !== "rdf:bag" && name !== "rdf:seq" && name !== "rdf:alt") {
+ return null;
+ }
+ return entry.childNodes.filter(node => node.nodeName === "rdf:li");
+ }
+ _parseArray(entry) {
+ if (!entry.hasChildNodes()) {
+ return;
+ }
+ const [seqNode] = entry.childNodes;
+ const sequence = this._getSequence(seqNode) || [];
+ this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim()));
+ }
+ _parse(xmlDocument) {
+ let rdf = xmlDocument.documentElement;
+ if (rdf.nodeName !== "rdf:rdf") {
+ rdf = rdf.firstChild;
+ while (rdf && rdf.nodeName !== "rdf:rdf") {
+ rdf = rdf.nextSibling;
+ }
+ }
+ if (!rdf || rdf.nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) {
+ return;
+ }
+ for (const desc of rdf.childNodes) {
+ if (desc.nodeName !== "rdf:description") {
+ continue;
+ }
+ for (const entry of desc.childNodes) {
+ const name = entry.nodeName;
+ switch (name) {
+ case "#text":
+ continue;
+ case "dc:creator":
+ case "dc:subject":
+ this._parseArray(entry);
+ continue;
+ }
+ this._metadataMap.set(name, entry.textContent.trim());
+ }
+ }
+ }
+ get serializable() {
+ return {
+ parsedData: this._metadataMap,
+ rawData: this._data
+ };
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/decrypt_stream.js
+
+const chunkSize = 512;
+class DecryptStream extends DecodeStream {
+ constructor(str, maybeLength, decrypt) {
+ super(maybeLength);
+ this.str = str;
+ this.dict = str.dict;
+ this.decrypt = decrypt;
+ this.nextChunk = null;
+ this.initialized = false;
+ }
+ readBlock() {
+ let chunk;
+ if (this.initialized) {
+ chunk = this.nextChunk;
+ } else {
+ chunk = this.str.getBytes(chunkSize);
+ this.initialized = true;
+ }
+ if (!chunk || chunk.length === 0) {
+ this.eof = true;
+ return;
+ }
+ this.nextChunk = this.str.getBytes(chunkSize);
+ const hasMoreData = this.nextChunk?.length > 0;
+ const decrypt = this.decrypt;
+ chunk = decrypt(chunk, !hasMoreData);
+ const bufferLength = this.bufferLength,
+ newLength = bufferLength + chunk.length,
+ buffer = this.ensureBuffer(newLength);
+ buffer.set(chunk, bufferLength);
+ this.bufferLength = newLength;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/crypto.js
+
+
+
+class ARCFourCipher {
+ constructor(key) {
+ this.a = 0;
+ this.b = 0;
+ const s = new Uint8Array(256);
+ const keyLength = key.length;
+ for (let i = 0; i < 256; ++i) {
+ s[i] = i;
+ }
+ for (let i = 0, j = 0; i < 256; ++i) {
+ const tmp = s[i];
+ j = j + tmp + key[i % keyLength] & 0xff;
+ s[i] = s[j];
+ s[j] = tmp;
+ }
+ this.s = s;
+ }
+ encryptBlock(data) {
+ let a = this.a,
+ b = this.b;
+ const s = this.s;
+ const n = data.length;
+ const output = new Uint8Array(n);
+ for (let i = 0; i < n; ++i) {
+ a = a + 1 & 0xff;
+ const tmp = s[a];
+ b = b + tmp & 0xff;
+ const tmp2 = s[b];
+ s[a] = tmp2;
+ s[b] = tmp;
+ output[i] = data[i] ^ s[tmp + tmp2 & 0xff];
+ }
+ this.a = a;
+ this.b = b;
+ return output;
+ }
+ decryptBlock(data) {
+ return this.encryptBlock(data);
+ }
+ encrypt(data) {
+ return this.encryptBlock(data);
+ }
+}
+const calculateMD5 = function calculateMD5Closure() {
+ const r = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]);
+ const k = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]);
+ function hash(data, offset, length) {
+ let h0 = 1732584193,
+ h1 = -271733879,
+ h2 = -1732584194,
+ h3 = 271733878;
+ const paddedLength = length + 72 & ~63;
+ const padded = new Uint8Array(paddedLength);
+ let i, j;
+ for (i = 0; i < length; ++i) {
+ padded[i] = data[offset++];
+ }
+ padded[i++] = 0x80;
+ const n = paddedLength - 8;
+ while (i < n) {
+ padded[i++] = 0;
+ }
+ padded[i++] = length << 3 & 0xff;
+ padded[i++] = length >> 5 & 0xff;
+ padded[i++] = length >> 13 & 0xff;
+ padded[i++] = length >> 21 & 0xff;
+ padded[i++] = length >>> 29 & 0xff;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ const w = new Int32Array(16);
+ for (i = 0; i < paddedLength;) {
+ for (j = 0; j < 16; ++j, i += 4) {
+ w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24;
+ }
+ let a = h0,
+ b = h1,
+ c = h2,
+ d = h3,
+ f,
+ g;
+ for (j = 0; j < 64; ++j) {
+ if (j < 16) {
+ f = b & c | ~b & d;
+ g = j;
+ } else if (j < 32) {
+ f = d & b | ~d & c;
+ g = 5 * j + 1 & 15;
+ } else if (j < 48) {
+ f = b ^ c ^ d;
+ g = 3 * j + 5 & 15;
+ } else {
+ f = c ^ (b | ~d);
+ g = 7 * j & 15;
+ }
+ const tmp = d,
+ rotateArg = a + f + k[j] + w[g] | 0,
+ rotate = r[j];
+ d = c;
+ c = b;
+ b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0;
+ a = tmp;
+ }
+ h0 = h0 + a | 0;
+ h1 = h1 + b | 0;
+ h2 = h2 + c | 0;
+ h3 = h3 + d | 0;
+ }
+ return new Uint8Array([h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >>> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >>> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >>> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >>> 24 & 0xFF]);
+ }
+ return hash;
+}();
+class Word64 {
+ constructor(highInteger, lowInteger) {
+ this.high = highInteger | 0;
+ this.low = lowInteger | 0;
+ }
+ and(word) {
+ this.high &= word.high;
+ this.low &= word.low;
+ }
+ xor(word) {
+ this.high ^= word.high;
+ this.low ^= word.low;
+ }
+ or(word) {
+ this.high |= word.high;
+ this.low |= word.low;
+ }
+ shiftRight(places) {
+ if (places >= 32) {
+ this.low = this.high >>> places - 32 | 0;
+ this.high = 0;
+ } else {
+ this.low = this.low >>> places | this.high << 32 - places;
+ this.high = this.high >>> places | 0;
+ }
+ }
+ shiftLeft(places) {
+ if (places >= 32) {
+ this.high = this.low << places - 32;
+ this.low = 0;
+ } else {
+ this.high = this.high << places | this.low >>> 32 - places;
+ this.low <<= places;
+ }
+ }
+ rotateRight(places) {
+ let low, high;
+ if (places & 32) {
+ high = this.low;
+ low = this.high;
+ } else {
+ low = this.low;
+ high = this.high;
+ }
+ places &= 31;
+ this.low = low >>> places | high << 32 - places;
+ this.high = high >>> places | low << 32 - places;
+ }
+ not() {
+ this.high = ~this.high;
+ this.low = ~this.low;
+ }
+ add(word) {
+ const lowAdd = (this.low >>> 0) + (word.low >>> 0);
+ let highAdd = (this.high >>> 0) + (word.high >>> 0);
+ if (lowAdd > 0xffffffff) {
+ highAdd += 1;
+ }
+ this.low = lowAdd | 0;
+ this.high = highAdd | 0;
+ }
+ copyTo(bytes, offset) {
+ bytes[offset] = this.high >>> 24 & 0xff;
+ bytes[offset + 1] = this.high >> 16 & 0xff;
+ bytes[offset + 2] = this.high >> 8 & 0xff;
+ bytes[offset + 3] = this.high & 0xff;
+ bytes[offset + 4] = this.low >>> 24 & 0xff;
+ bytes[offset + 5] = this.low >> 16 & 0xff;
+ bytes[offset + 6] = this.low >> 8 & 0xff;
+ bytes[offset + 7] = this.low & 0xff;
+ }
+ assign(word) {
+ this.high = word.high;
+ this.low = word.low;
+ }
+}
+const calculateSHA256 = function calculateSHA256Closure() {
+ function rotr(x, n) {
+ return x >>> n | x << 32 - n;
+ }
+ function ch(x, y, z) {
+ return x & y ^ ~x & z;
+ }
+ function maj(x, y, z) {
+ return x & y ^ x & z ^ y & z;
+ }
+ function sigma(x) {
+ return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
+ }
+ function sigmaPrime(x) {
+ return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
+ }
+ function littleSigma(x) {
+ return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3;
+ }
+ function littleSigmaPrime(x) {
+ return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10;
+ }
+ const k = [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 hash(data, offset, length) {
+ let h0 = 0x6a09e667,
+ h1 = 0xbb67ae85,
+ h2 = 0x3c6ef372,
+ h3 = 0xa54ff53a,
+ h4 = 0x510e527f,
+ h5 = 0x9b05688c,
+ h6 = 0x1f83d9ab,
+ h7 = 0x5be0cd19;
+ const paddedLength = Math.ceil((length + 9) / 64) * 64;
+ const padded = new Uint8Array(paddedLength);
+ let i, j;
+ for (i = 0; i < length; ++i) {
+ padded[i] = data[offset++];
+ }
+ padded[i++] = 0x80;
+ const n = paddedLength - 8;
+ while (i < n) {
+ padded[i++] = 0;
+ }
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = length >>> 29 & 0xff;
+ padded[i++] = length >> 21 & 0xff;
+ padded[i++] = length >> 13 & 0xff;
+ padded[i++] = length >> 5 & 0xff;
+ padded[i++] = length << 3 & 0xff;
+ const w = new Uint32Array(64);
+ for (i = 0; i < paddedLength;) {
+ for (j = 0; j < 16; ++j) {
+ w[j] = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3];
+ i += 4;
+ }
+ for (j = 16; j < 64; ++j) {
+ w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + littleSigma(w[j - 15]) + w[j - 16] | 0;
+ }
+ let a = h0,
+ b = h1,
+ c = h2,
+ d = h3,
+ e = h4,
+ f = h5,
+ g = h6,
+ h = h7,
+ t1,
+ t2;
+ for (j = 0; j < 64; ++j) {
+ t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j];
+ t2 = sigma(a) + maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1 | 0;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2 | 0;
+ }
+ h0 = h0 + a | 0;
+ h1 = h1 + b | 0;
+ h2 = h2 + c | 0;
+ h3 = h3 + d | 0;
+ h4 = h4 + e | 0;
+ h5 = h5 + f | 0;
+ h6 = h6 + g | 0;
+ h7 = h7 + h | 0;
+ }
+ return new Uint8Array([h0 >> 24 & 0xFF, h0 >> 16 & 0xFF, h0 >> 8 & 0xFF, h0 & 0xFF, h1 >> 24 & 0xFF, h1 >> 16 & 0xFF, h1 >> 8 & 0xFF, h1 & 0xFF, h2 >> 24 & 0xFF, h2 >> 16 & 0xFF, h2 >> 8 & 0xFF, h2 & 0xFF, h3 >> 24 & 0xFF, h3 >> 16 & 0xFF, h3 >> 8 & 0xFF, h3 & 0xFF, h4 >> 24 & 0xFF, h4 >> 16 & 0xFF, h4 >> 8 & 0xFF, h4 & 0xFF, h5 >> 24 & 0xFF, h5 >> 16 & 0xFF, h5 >> 8 & 0xFF, h5 & 0xFF, h6 >> 24 & 0xFF, h6 >> 16 & 0xFF, h6 >> 8 & 0xFF, h6 & 0xFF, h7 >> 24 & 0xFF, h7 >> 16 & 0xFF, h7 >> 8 & 0xFF, h7 & 0xFF]);
+ }
+ return hash;
+}();
+const calculateSHA512 = function calculateSHA512Closure() {
+ function ch(result, x, y, z, tmp) {
+ result.assign(x);
+ result.and(y);
+ tmp.assign(x);
+ tmp.not();
+ tmp.and(z);
+ result.xor(tmp);
+ }
+ function maj(result, x, y, z, tmp) {
+ result.assign(x);
+ result.and(y);
+ tmp.assign(x);
+ tmp.and(z);
+ result.xor(tmp);
+ tmp.assign(y);
+ tmp.and(z);
+ result.xor(tmp);
+ }
+ function sigma(result, x, tmp) {
+ result.assign(x);
+ result.rotateRight(28);
+ tmp.assign(x);
+ tmp.rotateRight(34);
+ result.xor(tmp);
+ tmp.assign(x);
+ tmp.rotateRight(39);
+ result.xor(tmp);
+ }
+ function sigmaPrime(result, x, tmp) {
+ result.assign(x);
+ result.rotateRight(14);
+ tmp.assign(x);
+ tmp.rotateRight(18);
+ result.xor(tmp);
+ tmp.assign(x);
+ tmp.rotateRight(41);
+ result.xor(tmp);
+ }
+ function littleSigma(result, x, tmp) {
+ result.assign(x);
+ result.rotateRight(1);
+ tmp.assign(x);
+ tmp.rotateRight(8);
+ result.xor(tmp);
+ tmp.assign(x);
+ tmp.shiftRight(7);
+ result.xor(tmp);
+ }
+ function littleSigmaPrime(result, x, tmp) {
+ result.assign(x);
+ result.rotateRight(19);
+ tmp.assign(x);
+ tmp.rotateRight(61);
+ result.xor(tmp);
+ tmp.assign(x);
+ tmp.shiftRight(6);
+ result.xor(tmp);
+ }
+ const k = [new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), new Word64(0x72be5d74, 0xf27b896f), new Word64(0x80deb1fe, 0x3b1696b1), new Word64(0x9bdc06a7, 0x25c71235), new Word64(0xc19bf174, 0xcf692694), new Word64(0xe49b69c1, 0x9ef14ad2), new Word64(0xefbe4786, 0x384f25e3), new Word64(0x0fc19dc6, 0x8b8cd5b5), new Word64(0x240ca1cc, 0x77ac9c65), new Word64(0x2de92c6f, 0x592b0275), new Word64(0x4a7484aa, 0x6ea6e483), new Word64(0x5cb0a9dc, 0xbd41fbd4), new Word64(0x76f988da, 0x831153b5), new Word64(0x983e5152, 0xee66dfab), new Word64(0xa831c66d, 0x2db43210), new Word64(0xb00327c8, 0x98fb213f), new Word64(0xbf597fc7, 0xbeef0ee4), new Word64(0xc6e00bf3, 0x3da88fc2), new Word64(0xd5a79147, 0x930aa725), new Word64(0x06ca6351, 0xe003826f), new Word64(0x14292967, 0x0a0e6e70), new Word64(0x27b70a85, 0x46d22ffc), new Word64(0x2e1b2138, 0x5c26c926), new Word64(0x4d2c6dfc, 0x5ac42aed), new Word64(0x53380d13, 0x9d95b3df), new Word64(0x650a7354, 0x8baf63de), new Word64(0x766a0abb, 0x3c77b2a8), new Word64(0x81c2c92e, 0x47edaee6), new Word64(0x92722c85, 0x1482353b), new Word64(0xa2bfe8a1, 0x4cf10364), new Word64(0xa81a664b, 0xbc423001), new Word64(0xc24b8b70, 0xd0f89791), new Word64(0xc76c51a3, 0x0654be30), new Word64(0xd192e819, 0xd6ef5218), new Word64(0xd6990624, 0x5565a910), new Word64(0xf40e3585, 0x5771202a), new Word64(0x106aa070, 0x32bbd1b8), new Word64(0x19a4c116, 0xb8d2d0c8), new Word64(0x1e376c08, 0x5141ab53), new Word64(0x2748774c, 0xdf8eeb99), new Word64(0x34b0bcb5, 0xe19b48a8), new Word64(0x391c0cb3, 0xc5c95a63), new Word64(0x4ed8aa4a, 0xe3418acb), new Word64(0x5b9cca4f, 0x7763e373), new Word64(0x682e6ff3, 0xd6b2b8a3), new Word64(0x748f82ee, 0x5defb2fc), new Word64(0x78a5636f, 0x43172f60), new Word64(0x84c87814, 0xa1f0ab72), new Word64(0x8cc70208, 0x1a6439ec), new Word64(0x90befffa, 0x23631e28), new Word64(0xa4506ceb, 0xde82bde9), new Word64(0xbef9a3f7, 0xb2c67915), new Word64(0xc67178f2, 0xe372532b), new Word64(0xca273ece, 0xea26619c), new Word64(0xd186b8c7, 0x21c0c207), new Word64(0xeada7dd6, 0xcde0eb1e), new Word64(0xf57d4f7f, 0xee6ed178), new Word64(0x06f067aa, 0x72176fba), new Word64(0x0a637dc5, 0xa2c898a6), new Word64(0x113f9804, 0xbef90dae), new Word64(0x1b710b35, 0x131c471b), new Word64(0x28db77f5, 0x23047d84), new Word64(0x32caab7b, 0x40c72493), new Word64(0x3c9ebe0a, 0x15c9bebc), new Word64(0x431d67c4, 0x9c100d4c), new Word64(0x4cc5d4be, 0xcb3e42b6), new Word64(0x597f299c, 0xfc657e2a), new Word64(0x5fcb6fab, 0x3ad6faec), new Word64(0x6c44198c, 0x4a475817)];
+ function hash(data, offset, length, mode384 = false) {
+ let h0, h1, h2, h3, h4, h5, h6, h7;
+ if (!mode384) {
+ h0 = new Word64(0x6a09e667, 0xf3bcc908);
+ h1 = new Word64(0xbb67ae85, 0x84caa73b);
+ h2 = new Word64(0x3c6ef372, 0xfe94f82b);
+ h3 = new Word64(0xa54ff53a, 0x5f1d36f1);
+ h4 = new Word64(0x510e527f, 0xade682d1);
+ h5 = new Word64(0x9b05688c, 0x2b3e6c1f);
+ h6 = new Word64(0x1f83d9ab, 0xfb41bd6b);
+ h7 = new Word64(0x5be0cd19, 0x137e2179);
+ } else {
+ h0 = new Word64(0xcbbb9d5d, 0xc1059ed8);
+ h1 = new Word64(0x629a292a, 0x367cd507);
+ h2 = new Word64(0x9159015a, 0x3070dd17);
+ h3 = new Word64(0x152fecd8, 0xf70e5939);
+ h4 = new Word64(0x67332667, 0xffc00b31);
+ h5 = new Word64(0x8eb44a87, 0x68581511);
+ h6 = new Word64(0xdb0c2e0d, 0x64f98fa7);
+ h7 = new Word64(0x47b5481d, 0xbefa4fa4);
+ }
+ const paddedLength = Math.ceil((length + 17) / 128) * 128;
+ const padded = new Uint8Array(paddedLength);
+ let i, j;
+ for (i = 0; i < length; ++i) {
+ padded[i] = data[offset++];
+ }
+ padded[i++] = 0x80;
+ const n = paddedLength - 16;
+ while (i < n) {
+ padded[i++] = 0;
+ }
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = 0;
+ padded[i++] = length >>> 29 & 0xff;
+ padded[i++] = length >> 21 & 0xff;
+ padded[i++] = length >> 13 & 0xff;
+ padded[i++] = length >> 5 & 0xff;
+ padded[i++] = length << 3 & 0xff;
+ const w = new Array(80);
+ for (i = 0; i < 80; i++) {
+ w[i] = new Word64(0, 0);
+ }
+ let a = new Word64(0, 0),
+ b = new Word64(0, 0),
+ c = new Word64(0, 0);
+ let d = new Word64(0, 0),
+ e = new Word64(0, 0),
+ f = new Word64(0, 0);
+ let g = new Word64(0, 0),
+ h = new Word64(0, 0);
+ const t1 = new Word64(0, 0),
+ t2 = new Word64(0, 0);
+ const tmp1 = new Word64(0, 0),
+ tmp2 = new Word64(0, 0);
+ let tmp3;
+ for (i = 0; i < paddedLength;) {
+ for (j = 0; j < 16; ++j) {
+ w[j].high = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3];
+ w[j].low = padded[i + 4] << 24 | padded[i + 5] << 16 | padded[i + 6] << 8 | padded[i + 7];
+ i += 8;
+ }
+ for (j = 16; j < 80; ++j) {
+ tmp3 = w[j];
+ littleSigmaPrime(tmp3, w[j - 2], tmp2);
+ tmp3.add(w[j - 7]);
+ littleSigma(tmp1, w[j - 15], tmp2);
+ tmp3.add(tmp1);
+ tmp3.add(w[j - 16]);
+ }
+ a.assign(h0);
+ b.assign(h1);
+ c.assign(h2);
+ d.assign(h3);
+ e.assign(h4);
+ f.assign(h5);
+ g.assign(h6);
+ h.assign(h7);
+ for (j = 0; j < 80; ++j) {
+ t1.assign(h);
+ sigmaPrime(tmp1, e, tmp2);
+ t1.add(tmp1);
+ ch(tmp1, e, f, g, tmp2);
+ t1.add(tmp1);
+ t1.add(k[j]);
+ t1.add(w[j]);
+ sigma(t2, a, tmp2);
+ maj(tmp1, a, b, c, tmp2);
+ t2.add(tmp1);
+ tmp3 = h;
+ h = g;
+ g = f;
+ f = e;
+ d.add(t1);
+ e = d;
+ d = c;
+ c = b;
+ b = a;
+ tmp3.assign(t1);
+ tmp3.add(t2);
+ a = tmp3;
+ }
+ h0.add(a);
+ h1.add(b);
+ h2.add(c);
+ h3.add(d);
+ h4.add(e);
+ h5.add(f);
+ h6.add(g);
+ h7.add(h);
+ }
+ let result;
+ if (!mode384) {
+ result = new Uint8Array(64);
+ h0.copyTo(result, 0);
+ h1.copyTo(result, 8);
+ h2.copyTo(result, 16);
+ h3.copyTo(result, 24);
+ h4.copyTo(result, 32);
+ h5.copyTo(result, 40);
+ h6.copyTo(result, 48);
+ h7.copyTo(result, 56);
+ } else {
+ result = new Uint8Array(48);
+ h0.copyTo(result, 0);
+ h1.copyTo(result, 8);
+ h2.copyTo(result, 16);
+ h3.copyTo(result, 24);
+ h4.copyTo(result, 32);
+ h5.copyTo(result, 40);
+ }
+ return result;
+ }
+ return hash;
+}();
+function calculateSHA384(data, offset, length) {
+ return calculateSHA512(data, offset, length, true);
+}
+class NullCipher {
+ decryptBlock(data) {
+ return data;
+ }
+ encrypt(data) {
+ return data;
+ }
+}
+class AESBaseCipher {
+ constructor() {
+ if (this.constructor === AESBaseCipher) {
+ unreachable("Cannot initialize AESBaseCipher.");
+ }
+ this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]);
+ this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]);
+ this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]);
+ this._mixCol = new Uint8Array(256);
+ for (let i = 0; i < 256; i++) {
+ this._mixCol[i] = i < 128 ? i << 1 : i << 1 ^ 0x1b;
+ }
+ this.buffer = new Uint8Array(16);
+ this.bufferPosition = 0;
+ }
+ _expandKey(cipherKey) {
+ unreachable("Cannot call `_expandKey` on the base class");
+ }
+ _decrypt(input, key) {
+ let t, u, v;
+ const state = new Uint8Array(16);
+ state.set(input);
+ for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {
+ state[j] ^= key[k];
+ }
+ for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) {
+ t = state[13];
+ state[13] = state[9];
+ state[9] = state[5];
+ state[5] = state[1];
+ state[1] = t;
+ t = state[14];
+ u = state[10];
+ state[14] = state[6];
+ state[10] = state[2];
+ state[6] = t;
+ state[2] = u;
+ t = state[15];
+ u = state[11];
+ v = state[7];
+ state[15] = state[3];
+ state[11] = t;
+ state[7] = u;
+ state[3] = v;
+ for (let j = 0; j < 16; ++j) {
+ state[j] = this._inv_s[state[j]];
+ }
+ for (let j = 0, k = i * 16; j < 16; ++j, ++k) {
+ state[j] ^= key[k];
+ }
+ for (let j = 0; j < 16; j += 4) {
+ const s0 = this._mix[state[j]];
+ const s1 = this._mix[state[j + 1]];
+ const s2 = this._mix[state[j + 2]];
+ const s3 = this._mix[state[j + 3]];
+ t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8;
+ state[j] = t >>> 24 & 0xff;
+ state[j + 1] = t >> 16 & 0xff;
+ state[j + 2] = t >> 8 & 0xff;
+ state[j + 3] = t & 0xff;
+ }
+ }
+ t = state[13];
+ state[13] = state[9];
+ state[9] = state[5];
+ state[5] = state[1];
+ state[1] = t;
+ t = state[14];
+ u = state[10];
+ state[14] = state[6];
+ state[10] = state[2];
+ state[6] = t;
+ state[2] = u;
+ t = state[15];
+ u = state[11];
+ v = state[7];
+ state[15] = state[3];
+ state[11] = t;
+ state[7] = u;
+ state[3] = v;
+ for (let j = 0; j < 16; ++j) {
+ state[j] = this._inv_s[state[j]];
+ state[j] ^= key[j];
+ }
+ return state;
+ }
+ _encrypt(input, key) {
+ const s = this._s;
+ let t, u, v;
+ const state = new Uint8Array(16);
+ state.set(input);
+ for (let j = 0; j < 16; ++j) {
+ state[j] ^= key[j];
+ }
+ for (let i = 1; i < this._cyclesOfRepetition; i++) {
+ for (let j = 0; j < 16; ++j) {
+ state[j] = s[state[j]];
+ }
+ v = state[1];
+ state[1] = state[5];
+ state[5] = state[9];
+ state[9] = state[13];
+ state[13] = v;
+ v = state[2];
+ u = state[6];
+ state[2] = state[10];
+ state[6] = state[14];
+ state[10] = v;
+ state[14] = u;
+ v = state[3];
+ u = state[7];
+ t = state[11];
+ state[3] = state[15];
+ state[7] = v;
+ state[11] = u;
+ state[15] = t;
+ for (let j = 0; j < 16; j += 4) {
+ const s0 = state[j + 0];
+ const s1 = state[j + 1];
+ const s2 = state[j + 2];
+ const s3 = state[j + 3];
+ t = s0 ^ s1 ^ s2 ^ s3;
+ state[j + 0] ^= t ^ this._mixCol[s0 ^ s1];
+ state[j + 1] ^= t ^ this._mixCol[s1 ^ s2];
+ state[j + 2] ^= t ^ this._mixCol[s2 ^ s3];
+ state[j + 3] ^= t ^ this._mixCol[s3 ^ s0];
+ }
+ for (let j = 0, k = i * 16; j < 16; ++j, ++k) {
+ state[j] ^= key[k];
+ }
+ }
+ for (let j = 0; j < 16; ++j) {
+ state[j] = s[state[j]];
+ }
+ v = state[1];
+ state[1] = state[5];
+ state[5] = state[9];
+ state[9] = state[13];
+ state[13] = v;
+ v = state[2];
+ u = state[6];
+ state[2] = state[10];
+ state[6] = state[14];
+ state[10] = v;
+ state[14] = u;
+ v = state[3];
+ u = state[7];
+ t = state[11];
+ state[3] = state[15];
+ state[7] = v;
+ state[11] = u;
+ state[15] = t;
+ for (let j = 0, k = this._keySize; j < 16; ++j, ++k) {
+ state[j] ^= key[k];
+ }
+ return state;
+ }
+ _decryptBlock2(data, finalize) {
+ const sourceLength = data.length;
+ let buffer = this.buffer,
+ bufferLength = this.bufferPosition;
+ const result = [];
+ let iv = this.iv;
+ for (let i = 0; i < sourceLength; ++i) {
+ buffer[bufferLength] = data[i];
+ ++bufferLength;
+ if (bufferLength < 16) {
+ continue;
+ }
+ const plain = this._decrypt(buffer, this._key);
+ for (let j = 0; j < 16; ++j) {
+ plain[j] ^= iv[j];
+ }
+ iv = buffer;
+ result.push(plain);
+ buffer = new Uint8Array(16);
+ bufferLength = 0;
+ }
+ this.buffer = buffer;
+ this.bufferLength = bufferLength;
+ this.iv = iv;
+ if (result.length === 0) {
+ return new Uint8Array(0);
+ }
+ let outputLength = 16 * result.length;
+ if (finalize) {
+ const lastBlock = result.at(-1);
+ let psLen = lastBlock[15];
+ if (psLen <= 16) {
+ for (let i = 15, ii = 16 - psLen; i >= ii; --i) {
+ if (lastBlock[i] !== psLen) {
+ psLen = 0;
+ break;
+ }
+ }
+ outputLength -= psLen;
+ result[result.length - 1] = lastBlock.subarray(0, 16 - psLen);
+ }
+ }
+ const output = new Uint8Array(outputLength);
+ for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
+ output.set(result[i], j);
+ }
+ return output;
+ }
+ decryptBlock(data, finalize, iv = null) {
+ const sourceLength = data.length;
+ const buffer = this.buffer;
+ let bufferLength = this.bufferPosition;
+ if (iv) {
+ this.iv = iv;
+ } else {
+ for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) {
+ buffer[bufferLength] = data[i];
+ }
+ if (bufferLength < 16) {
+ this.bufferLength = bufferLength;
+ return new Uint8Array(0);
+ }
+ this.iv = buffer;
+ data = data.subarray(16);
+ }
+ this.buffer = new Uint8Array(16);
+ this.bufferLength = 0;
+ this.decryptBlock = this._decryptBlock2;
+ return this.decryptBlock(data, finalize);
+ }
+ encrypt(data, iv) {
+ const sourceLength = data.length;
+ let buffer = this.buffer,
+ bufferLength = this.bufferPosition;
+ const result = [];
+ if (!iv) {
+ iv = new Uint8Array(16);
+ }
+ for (let i = 0; i < sourceLength; ++i) {
+ buffer[bufferLength] = data[i];
+ ++bufferLength;
+ if (bufferLength < 16) {
+ continue;
+ }
+ for (let j = 0; j < 16; ++j) {
+ buffer[j] ^= iv[j];
+ }
+ const cipher = this._encrypt(buffer, this._key);
+ iv = cipher;
+ result.push(cipher);
+ buffer = new Uint8Array(16);
+ bufferLength = 0;
+ }
+ this.buffer = buffer;
+ this.bufferLength = bufferLength;
+ this.iv = iv;
+ if (result.length === 0) {
+ return new Uint8Array(0);
+ }
+ const outputLength = 16 * result.length;
+ const output = new Uint8Array(outputLength);
+ for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) {
+ output.set(result[i], j);
+ }
+ return output;
+ }
+}
+class AES128Cipher extends AESBaseCipher {
+ constructor(key) {
+ super();
+ this._cyclesOfRepetition = 10;
+ this._keySize = 160;
+ this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]);
+ this._key = this._expandKey(key);
+ }
+ _expandKey(cipherKey) {
+ const b = 176;
+ const s = this._s;
+ const rcon = this._rcon;
+ const result = new Uint8Array(b);
+ result.set(cipherKey);
+ for (let j = 16, i = 1; j < b; ++i) {
+ let t1 = result[j - 3];
+ let t2 = result[j - 2];
+ let t3 = result[j - 1];
+ let t4 = result[j - 4];
+ t1 = s[t1];
+ t2 = s[t2];
+ t3 = s[t3];
+ t4 = s[t4];
+ t1 ^= rcon[i];
+ for (let n = 0; n < 4; ++n) {
+ result[j] = t1 ^= result[j - 16];
+ j++;
+ result[j] = t2 ^= result[j - 16];
+ j++;
+ result[j] = t3 ^= result[j - 16];
+ j++;
+ result[j] = t4 ^= result[j - 16];
+ j++;
+ }
+ }
+ return result;
+ }
+}
+class AES256Cipher extends AESBaseCipher {
+ constructor(key) {
+ super();
+ this._cyclesOfRepetition = 14;
+ this._keySize = 224;
+ this._key = this._expandKey(key);
+ }
+ _expandKey(cipherKey) {
+ const b = 240;
+ const s = this._s;
+ const result = new Uint8Array(b);
+ result.set(cipherKey);
+ let r = 1;
+ let t1, t2, t3, t4;
+ for (let j = 32, i = 1; j < b; ++i) {
+ if (j % 32 === 16) {
+ t1 = s[t1];
+ t2 = s[t2];
+ t3 = s[t3];
+ t4 = s[t4];
+ } else if (j % 32 === 0) {
+ t1 = result[j - 3];
+ t2 = result[j - 2];
+ t3 = result[j - 1];
+ t4 = result[j - 4];
+ t1 = s[t1];
+ t2 = s[t2];
+ t3 = s[t3];
+ t4 = s[t4];
+ t1 ^= r;
+ if ((r <<= 1) >= 256) {
+ r = (r ^ 0x1b) & 0xff;
+ }
+ }
+ for (let n = 0; n < 4; ++n) {
+ result[j] = t1 ^= result[j - 32];
+ j++;
+ result[j] = t2 ^= result[j - 32];
+ j++;
+ result[j] = t3 ^= result[j - 32];
+ j++;
+ result[j] = t4 ^= result[j - 32];
+ j++;
+ }
+ }
+ return result;
+ }
+}
+class PDF17 {
+ checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
+ const hashData = new Uint8Array(password.length + 56);
+ hashData.set(password, 0);
+ hashData.set(ownerValidationSalt, password.length);
+ hashData.set(userBytes, password.length + ownerValidationSalt.length);
+ const result = calculateSHA256(hashData, 0, hashData.length);
+ return isArrayEqual(result, ownerPassword);
+ }
+ checkUserPassword(password, userValidationSalt, userPassword) {
+ const hashData = new Uint8Array(password.length + 8);
+ hashData.set(password, 0);
+ hashData.set(userValidationSalt, password.length);
+ const result = calculateSHA256(hashData, 0, hashData.length);
+ return isArrayEqual(result, userPassword);
+ }
+ getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {
+ const hashData = new Uint8Array(password.length + 56);
+ hashData.set(password, 0);
+ hashData.set(ownerKeySalt, password.length);
+ hashData.set(userBytes, password.length + ownerKeySalt.length);
+ const key = calculateSHA256(hashData, 0, hashData.length);
+ const cipher = new AES256Cipher(key);
+ return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
+ }
+ getUserKey(password, userKeySalt, userEncryption) {
+ const hashData = new Uint8Array(password.length + 8);
+ hashData.set(password, 0);
+ hashData.set(userKeySalt, password.length);
+ const key = calculateSHA256(hashData, 0, hashData.length);
+ const cipher = new AES256Cipher(key);
+ return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
+ }
+}
+class PDF20 {
+ _hash(password, input, userBytes) {
+ let k = calculateSHA256(input, 0, input.length).subarray(0, 32);
+ let e = [0];
+ let i = 0;
+ while (i < 64 || e.at(-1) > i - 32) {
+ const combinedLength = password.length + k.length + userBytes.length,
+ combinedArray = new Uint8Array(combinedLength);
+ let writeOffset = 0;
+ combinedArray.set(password, writeOffset);
+ writeOffset += password.length;
+ combinedArray.set(k, writeOffset);
+ writeOffset += k.length;
+ combinedArray.set(userBytes, writeOffset);
+ const k1 = new Uint8Array(combinedLength * 64);
+ for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) {
+ k1.set(combinedArray, pos);
+ }
+ const cipher = new AES128Cipher(k.subarray(0, 16));
+ e = cipher.encrypt(k1, k.subarray(16, 32));
+ const remainder = e.slice(0, 16).reduce((a, b) => a + b, 0) % 3;
+ if (remainder === 0) {
+ k = calculateSHA256(e, 0, e.length);
+ } else if (remainder === 1) {
+ k = calculateSHA384(e, 0, e.length);
+ } else if (remainder === 2) {
+ k = calculateSHA512(e, 0, e.length);
+ }
+ i++;
+ }
+ return k.subarray(0, 32);
+ }
+ checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
+ const hashData = new Uint8Array(password.length + 56);
+ hashData.set(password, 0);
+ hashData.set(ownerValidationSalt, password.length);
+ hashData.set(userBytes, password.length + ownerValidationSalt.length);
+ const result = this._hash(password, hashData, userBytes);
+ return isArrayEqual(result, ownerPassword);
+ }
+ checkUserPassword(password, userValidationSalt, userPassword) {
+ const hashData = new Uint8Array(password.length + 8);
+ hashData.set(password, 0);
+ hashData.set(userValidationSalt, password.length);
+ const result = this._hash(password, hashData, []);
+ return isArrayEqual(result, userPassword);
+ }
+ getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {
+ const hashData = new Uint8Array(password.length + 56);
+ hashData.set(password, 0);
+ hashData.set(ownerKeySalt, password.length);
+ hashData.set(userBytes, password.length + ownerKeySalt.length);
+ const key = this._hash(password, hashData, userBytes);
+ const cipher = new AES256Cipher(key);
+ return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
+ }
+ getUserKey(password, userKeySalt, userEncryption) {
+ const hashData = new Uint8Array(password.length + 8);
+ hashData.set(password, 0);
+ hashData.set(userKeySalt, password.length);
+ const key = this._hash(password, hashData, []);
+ const cipher = new AES256Cipher(key);
+ return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
+ }
+}
+class CipherTransform {
+ constructor(stringCipherConstructor, streamCipherConstructor) {
+ this.StringCipherConstructor = stringCipherConstructor;
+ this.StreamCipherConstructor = streamCipherConstructor;
+ }
+ createStream(stream, length) {
+ const cipher = new this.StreamCipherConstructor();
+ return new DecryptStream(stream, length, function cipherTransformDecryptStream(data, finalize) {
+ return cipher.decryptBlock(data, finalize);
+ });
+ }
+ decryptString(s) {
+ const cipher = new this.StringCipherConstructor();
+ let data = stringToBytes(s);
+ data = cipher.decryptBlock(data, true);
+ return bytesToString(data);
+ }
+ encryptString(s) {
+ const cipher = new this.StringCipherConstructor();
+ if (cipher instanceof AESBaseCipher) {
+ const strLen = s.length;
+ const pad = 16 - strLen % 16;
+ s += String.fromCharCode(pad).repeat(pad);
+ const iv = new Uint8Array(16);
+ if (typeof crypto !== "undefined") {
+ crypto.getRandomValues(iv);
+ } else {
+ for (let i = 0; i < 16; i++) {
+ iv[i] = Math.floor(256 * Math.random());
+ }
+ }
+ let data = stringToBytes(s);
+ data = cipher.encrypt(data, iv);
+ const buf = new Uint8Array(16 + data.length);
+ buf.set(iv);
+ buf.set(data, 16);
+ return bytesToString(buf);
+ }
+ let data = stringToBytes(s);
+ data = cipher.encrypt(data);
+ return bytesToString(data);
+ }
+}
+class CipherTransformFactory {
+ static #defaultPasswordBytes = new Uint8Array([0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a]);
+ #createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) {
+ if (password) {
+ const passwordLength = Math.min(127, password.length);
+ password = password.subarray(0, passwordLength);
+ } else {
+ password = [];
+ }
+ const pdfAlgorithm = revision === 6 ? new PDF20() : new PDF17();
+ if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) {
+ return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption);
+ } else if (password.length && pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, uBytes, ownerPassword)) {
+ return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption);
+ }
+ return null;
+ }
+ #prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) {
+ const hashDataSize = 40 + ownerPassword.length + fileId.length;
+ const hashData = new Uint8Array(hashDataSize);
+ let i = 0,
+ j,
+ n;
+ if (password) {
+ n = Math.min(32, password.length);
+ for (; i < n; ++i) {
+ hashData[i] = password[i];
+ }
+ }
+ j = 0;
+ while (i < 32) {
+ hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++];
+ }
+ for (j = 0, n = ownerPassword.length; j < n; ++j) {
+ hashData[i++] = ownerPassword[j];
+ }
+ hashData[i++] = flags & 0xff;
+ hashData[i++] = flags >> 8 & 0xff;
+ hashData[i++] = flags >> 16 & 0xff;
+ hashData[i++] = flags >>> 24 & 0xff;
+ for (j = 0, n = fileId.length; j < n; ++j) {
+ hashData[i++] = fileId[j];
+ }
+ if (revision >= 4 && !encryptMetadata) {
+ hashData[i++] = 0xff;
+ hashData[i++] = 0xff;
+ hashData[i++] = 0xff;
+ hashData[i++] = 0xff;
+ }
+ let hash = calculateMD5(hashData, 0, i);
+ const keyLengthInBytes = keyLength >> 3;
+ if (revision >= 3) {
+ for (j = 0; j < 50; ++j) {
+ hash = calculateMD5(hash, 0, keyLengthInBytes);
+ }
+ }
+ const encryptionKey = hash.subarray(0, keyLengthInBytes);
+ let cipher, checkData;
+ if (revision >= 3) {
+ for (i = 0; i < 32; ++i) {
+ hashData[i] = CipherTransformFactory.#defaultPasswordBytes[i];
+ }
+ for (j = 0, n = fileId.length; j < n; ++j) {
+ hashData[i++] = fileId[j];
+ }
+ cipher = new ARCFourCipher(encryptionKey);
+ checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i));
+ n = encryptionKey.length;
+ const derivedKey = new Uint8Array(n);
+ for (j = 1; j <= 19; ++j) {
+ for (let k = 0; k < n; ++k) {
+ derivedKey[k] = encryptionKey[k] ^ j;
+ }
+ cipher = new ARCFourCipher(derivedKey);
+ checkData = cipher.encryptBlock(checkData);
+ }
+ for (j = 0, n = checkData.length; j < n; ++j) {
+ if (userPassword[j] !== checkData[j]) {
+ return null;
+ }
+ }
+ } else {
+ cipher = new ARCFourCipher(encryptionKey);
+ checkData = cipher.encryptBlock(CipherTransformFactory.#defaultPasswordBytes);
+ for (j = 0, n = checkData.length; j < n; ++j) {
+ if (userPassword[j] !== checkData[j]) {
+ return null;
+ }
+ }
+ }
+ return encryptionKey;
+ }
+ #decodeUserPassword(password, ownerPassword, revision, keyLength) {
+ const hashData = new Uint8Array(32);
+ let i = 0;
+ const n = Math.min(32, password.length);
+ for (; i < n; ++i) {
+ hashData[i] = password[i];
+ }
+ let j = 0;
+ while (i < 32) {
+ hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++];
+ }
+ let hash = calculateMD5(hashData, 0, i);
+ const keyLengthInBytes = keyLength >> 3;
+ if (revision >= 3) {
+ for (j = 0; j < 50; ++j) {
+ hash = calculateMD5(hash, 0, hash.length);
+ }
+ }
+ let cipher, userPassword;
+ if (revision >= 3) {
+ userPassword = ownerPassword;
+ const derivedKey = new Uint8Array(keyLengthInBytes);
+ for (j = 19; j >= 0; j--) {
+ for (let k = 0; k < keyLengthInBytes; ++k) {
+ derivedKey[k] = hash[k] ^ j;
+ }
+ cipher = new ARCFourCipher(derivedKey);
+ userPassword = cipher.encryptBlock(userPassword);
+ }
+ } else {
+ cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes));
+ userPassword = cipher.encryptBlock(ownerPassword);
+ }
+ return userPassword;
+ }
+ #buildObjectKey(num, gen, encryptionKey, isAes = false) {
+ const key = new Uint8Array(encryptionKey.length + 9);
+ const n = encryptionKey.length;
+ let i;
+ for (i = 0; i < n; ++i) {
+ key[i] = encryptionKey[i];
+ }
+ key[i++] = num & 0xff;
+ key[i++] = num >> 8 & 0xff;
+ key[i++] = num >> 16 & 0xff;
+ key[i++] = gen & 0xff;
+ key[i++] = gen >> 8 & 0xff;
+ if (isAes) {
+ key[i++] = 0x73;
+ key[i++] = 0x41;
+ key[i++] = 0x6c;
+ key[i++] = 0x54;
+ }
+ const hash = calculateMD5(key, 0, i);
+ return hash.subarray(0, Math.min(encryptionKey.length + 5, 16));
+ }
+ #buildCipherConstructor(cf, name, num, gen, key) {
+ if (!(name instanceof Name)) {
+ throw new FormatError("Invalid crypt filter name.");
+ }
+ const self = this;
+ const cryptFilter = cf.get(name.name);
+ const cfm = cryptFilter?.get("CFM");
+ if (!cfm || cfm.name === "None") {
+ return function () {
+ return new NullCipher();
+ };
+ }
+ if (cfm.name === "V2") {
+ return function () {
+ return new ARCFourCipher(self.#buildObjectKey(num, gen, key, false));
+ };
+ }
+ if (cfm.name === "AESV2") {
+ return function () {
+ return new AES128Cipher(self.#buildObjectKey(num, gen, key, true));
+ };
+ }
+ if (cfm.name === "AESV3") {
+ return function () {
+ return new AES256Cipher(key);
+ };
+ }
+ throw new FormatError("Unknown crypto method");
+ }
+ constructor(dict, fileId, password) {
+ const filter = dict.get("Filter");
+ if (!isName(filter, "Standard")) {
+ throw new FormatError("unknown encryption method");
+ }
+ this.filterName = filter.name;
+ this.dict = dict;
+ const algorithm = dict.get("V");
+ if (!Number.isInteger(algorithm) || algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5) {
+ throw new FormatError("unsupported encryption algorithm");
+ }
+ this.algorithm = algorithm;
+ let keyLength = dict.get("Length");
+ if (!keyLength) {
+ if (algorithm <= 3) {
+ keyLength = 40;
+ } else {
+ const cfDict = dict.get("CF");
+ const streamCryptoName = dict.get("StmF");
+ if (cfDict instanceof Dict && streamCryptoName instanceof Name) {
+ cfDict.suppressEncryption = true;
+ const handlerDict = cfDict.get(streamCryptoName.name);
+ keyLength = handlerDict?.get("Length") || 128;
+ if (keyLength < 40) {
+ keyLength <<= 3;
+ }
+ }
+ }
+ }
+ if (!Number.isInteger(keyLength) || keyLength < 40 || keyLength % 8 !== 0) {
+ throw new FormatError("invalid key length");
+ }
+ const ownerBytes = stringToBytes(dict.get("O")),
+ userBytes = stringToBytes(dict.get("U"));
+ const ownerPassword = ownerBytes.subarray(0, 32);
+ const userPassword = userBytes.subarray(0, 32);
+ const flags = dict.get("P");
+ const revision = dict.get("R");
+ const encryptMetadata = (algorithm === 4 || algorithm === 5) && dict.get("EncryptMetadata") !== false;
+ this.encryptMetadata = encryptMetadata;
+ const fileIdBytes = stringToBytes(fileId);
+ let passwordBytes;
+ if (password) {
+ if (revision === 6) {
+ try {
+ password = utf8StringToString(password);
+ } catch {
+ warn("CipherTransformFactory: Unable to convert UTF8 encoded password.");
+ }
+ }
+ passwordBytes = stringToBytes(password);
+ }
+ let encryptionKey;
+ if (algorithm !== 5) {
+ encryptionKey = this.#prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata);
+ } else {
+ const ownerValidationSalt = ownerBytes.subarray(32, 40);
+ const ownerKeySalt = ownerBytes.subarray(40, 48);
+ const uBytes = userBytes.subarray(0, 48);
+ const userValidationSalt = userBytes.subarray(32, 40);
+ const userKeySalt = userBytes.subarray(40, 48);
+ const ownerEncryption = stringToBytes(dict.get("OE"));
+ const userEncryption = stringToBytes(dict.get("UE"));
+ const perms = stringToBytes(dict.get("Perms"));
+ encryptionKey = this.#createEncryptionKey20(revision, passwordBytes, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms);
+ }
+ if (!encryptionKey && !password) {
+ throw new PasswordException("No password given", PasswordResponses.NEED_PASSWORD);
+ } else if (!encryptionKey && password) {
+ const decodedPassword = this.#decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength);
+ encryptionKey = this.#prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata);
+ }
+ if (!encryptionKey) {
+ throw new PasswordException("Incorrect Password", PasswordResponses.INCORRECT_PASSWORD);
+ }
+ this.encryptionKey = encryptionKey;
+ if (algorithm >= 4) {
+ const cf = dict.get("CF");
+ if (cf instanceof Dict) {
+ cf.suppressEncryption = true;
+ }
+ this.cf = cf;
+ this.stmf = dict.get("StmF") || Name.get("Identity");
+ this.strf = dict.get("StrF") || Name.get("Identity");
+ this.eff = dict.get("EFF") || this.stmf;
+ }
+ }
+ createCipherTransform(num, gen) {
+ if (this.algorithm === 4 || this.algorithm === 5) {
+ return new CipherTransform(this.#buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey), this.#buildCipherConstructor(this.cf, this.stmf, num, gen, this.encryptionKey));
+ }
+ const key = this.#buildObjectKey(num, gen, this.encryptionKey, false);
+ const cipherConstructor = function () {
+ return new ARCFourCipher(key);
+ };
+ return new CipherTransform(cipherConstructor, cipherConstructor);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/writer.js
+
+
+
+
+
+
+async function writeObject(ref, obj, buffer, {
+ encrypt = null
+}) {
+ const transform = encrypt?.createCipherTransform(ref.num, ref.gen);
+ buffer.push(`${ref.num} ${ref.gen} obj\n`);
+ if (obj instanceof Dict) {
+ await writeDict(obj, buffer, transform);
+ } else if (obj instanceof BaseStream) {
+ await writeStream(obj, buffer, transform);
+ } else if (Array.isArray(obj)) {
+ await writeArray(obj, buffer, transform);
+ }
+ buffer.push("\nendobj\n");
+}
+async function writeDict(dict, buffer, transform) {
+ buffer.push("<<");
+ for (const key of dict.getKeys()) {
+ buffer.push(` /${escapePDFName(key)} `);
+ await writeValue(dict.getRaw(key), buffer, transform);
+ }
+ buffer.push(">>");
+}
+async function writeStream(stream, buffer, transform) {
+ let bytes = stream.getBytes();
+ const {
+ dict
+ } = stream;
+ const [filter, params] = await Promise.all([dict.getAsync("Filter"), dict.getAsync("DecodeParms")]);
+ const filterZero = Array.isArray(filter) ? await dict.xref.fetchIfRefAsync(filter[0]) : filter;
+ const isFilterZeroFlateDecode = isName(filterZero, "FlateDecode");
+ const MIN_LENGTH_FOR_COMPRESSING = 256;
+ if (typeof CompressionStream !== "undefined" && (bytes.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode)) {
+ try {
+ const cs = new CompressionStream("deflate");
+ const writer = cs.writable.getWriter();
+ writer.write(bytes);
+ writer.close();
+ const buf = await new Response(cs.readable).arrayBuffer();
+ bytes = new Uint8Array(buf);
+ let newFilter, newParams;
+ if (!filter) {
+ newFilter = Name.get("FlateDecode");
+ } else if (!isFilterZeroFlateDecode) {
+ newFilter = Array.isArray(filter) ? [Name.get("FlateDecode"), ...filter] : [Name.get("FlateDecode"), filter];
+ if (params) {
+ newParams = Array.isArray(params) ? [null, ...params] : [null, params];
+ }
+ }
+ if (newFilter) {
+ dict.set("Filter", newFilter);
+ }
+ if (newParams) {
+ dict.set("DecodeParms", newParams);
+ }
+ } catch (ex) {
+ info(`writeStream - cannot compress data: "${ex}".`);
+ }
+ }
+ let string = bytesToString(bytes);
+ if (transform) {
+ string = transform.encryptString(string);
+ }
+ dict.set("Length", string.length);
+ await writeDict(dict, buffer, transform);
+ buffer.push(" stream\n", string, "\nendstream");
+}
+async function writeArray(array, buffer, transform) {
+ buffer.push("[");
+ let first = true;
+ for (const val of array) {
+ if (!first) {
+ buffer.push(" ");
+ } else {
+ first = false;
+ }
+ await writeValue(val, buffer, transform);
+ }
+ buffer.push("]");
+}
+async function writeValue(value, buffer, transform) {
+ if (value instanceof Name) {
+ buffer.push(`/${escapePDFName(value.name)}`);
+ } else if (value instanceof Ref) {
+ buffer.push(`${value.num} ${value.gen} R`);
+ } else if (Array.isArray(value)) {
+ await writeArray(value, buffer, transform);
+ } else if (typeof value === "string") {
+ if (transform) {
+ value = transform.encryptString(value);
+ }
+ buffer.push(`(${escapeString(value)})`);
+ } else if (typeof value === "number") {
+ buffer.push(numberToString(value));
+ } else if (typeof value === "boolean") {
+ buffer.push(value.toString());
+ } else if (value instanceof Dict) {
+ await writeDict(value, buffer, transform);
+ } else if (value instanceof BaseStream) {
+ await writeStream(value, buffer, transform);
+ } else if (value === null) {
+ buffer.push("null");
+ } else {
+ warn(`Unhandled value in writer: ${typeof value}, please file a bug.`);
+ }
+}
+function writeInt(number, size, offset, buffer) {
+ for (let i = size + offset - 1; i > offset - 1; i--) {
+ buffer[i] = number & 0xff;
+ number >>= 8;
+ }
+ return offset + size;
+}
+function writeString(string, offset, buffer) {
+ for (let i = 0, len = string.length; i < len; i++) {
+ buffer[offset + i] = string.charCodeAt(i) & 0xff;
+ }
+}
+function computeMD5(filesize, xrefInfo) {
+ const time = Math.floor(Date.now() / 1000);
+ const filename = xrefInfo.filename || "";
+ const md5Buffer = [time.toString(), filename, filesize.toString()];
+ let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0);
+ for (const value of Object.values(xrefInfo.info)) {
+ md5Buffer.push(value);
+ md5BufferLen += value.length;
+ }
+ const array = new Uint8Array(md5BufferLen);
+ let offset = 0;
+ for (const str of md5Buffer) {
+ writeString(str, offset, array);
+ offset += str.length;
+ }
+ return bytesToString(calculateMD5(array));
+}
+function writeXFADataForAcroform(str, newRefs) {
+ const xml = new SimpleXMLParser({
+ hasAttributes: true
+ }).parseFromString(str);
+ for (const {
+ xfa
+ } of newRefs) {
+ if (!xfa) {
+ continue;
+ }
+ const {
+ path,
+ value
+ } = xfa;
+ if (!path) {
+ continue;
+ }
+ const nodePath = parseXFAPath(path);
+ let node = xml.documentElement.searchNode(nodePath, 0);
+ if (!node && nodePath.length > 1) {
+ node = xml.documentElement.searchNode([nodePath.at(-1)], 0);
+ }
+ if (node) {
+ node.childNodes = Array.isArray(value) ? value.map(val => new SimpleDOMNode("value", val)) : [new SimpleDOMNode("#text", value)];
+ } else {
+ warn(`Node not found for path: ${path}`);
+ }
+ }
+ const buffer = [];
+ xml.documentElement.dump(buffer);
+ return buffer.join("");
+}
+async function updateAcroform({
+ xref,
+ acroForm,
+ acroFormRef,
+ hasXfa,
+ hasXfaDatasetsEntry,
+ xfaDatasetsRef,
+ needAppearances,
+ newRefs
+}) {
+ if (hasXfa && !hasXfaDatasetsEntry && !xfaDatasetsRef) {
+ warn("XFA - Cannot save it");
+ }
+ if (!needAppearances && (!hasXfa || !xfaDatasetsRef || hasXfaDatasetsEntry)) {
+ return;
+ }
+ const dict = acroForm.clone();
+ if (hasXfa && !hasXfaDatasetsEntry) {
+ const newXfa = acroForm.get("XFA").slice();
+ newXfa.splice(2, 0, "datasets");
+ newXfa.splice(3, 0, xfaDatasetsRef);
+ dict.set("XFA", newXfa);
+ }
+ if (needAppearances) {
+ dict.set("NeedAppearances", true);
+ }
+ const buffer = [];
+ await writeObject(acroFormRef, dict, buffer, xref);
+ newRefs.push({
+ ref: acroFormRef,
+ data: buffer.join("")
+ });
+}
+function updateXFA({
+ xfaData,
+ xfaDatasetsRef,
+ newRefs,
+ xref
+}) {
+ if (xfaData === null) {
+ const datasets = xref.fetchIfRef(xfaDatasetsRef);
+ xfaData = writeXFADataForAcroform(datasets.getString(), newRefs);
+ }
+ const encrypt = xref.encrypt;
+ if (encrypt) {
+ const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen);
+ xfaData = transform.encryptString(xfaData);
+ }
+ const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n";
+ newRefs.push({
+ ref: xfaDatasetsRef,
+ data
+ });
+}
+async function incrementalUpdate({
+ originalData,
+ xrefInfo,
+ newRefs,
+ xref = null,
+ hasXfa = false,
+ xfaDatasetsRef = null,
+ hasXfaDatasetsEntry = false,
+ needAppearances,
+ acroFormRef = null,
+ acroForm = null,
+ xfaData = null
+}) {
+ await updateAcroform({
+ xref,
+ acroForm,
+ acroFormRef,
+ hasXfa,
+ hasXfaDatasetsEntry,
+ xfaDatasetsRef,
+ needAppearances,
+ newRefs
+ });
+ if (hasXfa) {
+ updateXFA({
+ xfaData,
+ xfaDatasetsRef,
+ newRefs,
+ xref
+ });
+ }
+ const newXref = new Dict(null);
+ const refForXrefTable = xrefInfo.newRef;
+ let buffer, baseOffset;
+ const lastByte = originalData.at(-1);
+ if (lastByte === 0x0a || lastByte === 0x0d) {
+ buffer = [];
+ baseOffset = originalData.length;
+ } else {
+ buffer = ["\n"];
+ baseOffset = originalData.length + 1;
+ }
+ newXref.set("Size", refForXrefTable.num + 1);
+ newXref.set("Prev", xrefInfo.startXRef);
+ newXref.set("Type", Name.get("XRef"));
+ if (xrefInfo.rootRef !== null) {
+ newXref.set("Root", xrefInfo.rootRef);
+ }
+ if (xrefInfo.infoRef !== null) {
+ newXref.set("Info", xrefInfo.infoRef);
+ }
+ if (xrefInfo.encryptRef !== null) {
+ newXref.set("Encrypt", xrefInfo.encryptRef);
+ }
+ newRefs.push({
+ ref: refForXrefTable,
+ data: ""
+ });
+ newRefs = newRefs.sort((a, b) => {
+ return a.ref.num - b.ref.num;
+ });
+ const xrefTableData = [[0, 1, 0xffff]];
+ const indexes = [0, 1];
+ let maxOffset = 0;
+ for (const {
+ ref,
+ data
+ } of newRefs) {
+ maxOffset = Math.max(maxOffset, baseOffset);
+ xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]);
+ baseOffset += data.length;
+ indexes.push(ref.num, 1);
+ buffer.push(data);
+ }
+ newXref.set("Index", indexes);
+ if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) {
+ const md5 = computeMD5(baseOffset, xrefInfo);
+ newXref.set("ID", [xrefInfo.fileIds[0], md5]);
+ }
+ const offsetSize = Math.ceil(Math.log2(maxOffset) / 8);
+ const sizes = [1, offsetSize, 2];
+ const structSize = sizes[0] + sizes[1] + sizes[2];
+ const tableLength = structSize * xrefTableData.length;
+ newXref.set("W", sizes);
+ newXref.set("Length", tableLength);
+ buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`);
+ await writeDict(newXref, buffer, null);
+ buffer.push(" stream\n");
+ const bufferLen = buffer.reduce((a, str) => a + str.length, 0);
+ const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`;
+ const array = new Uint8Array(originalData.length + bufferLen + tableLength + footer.length);
+ array.set(originalData);
+ let offset = originalData.length;
+ for (const str of buffer) {
+ writeString(str, offset, array);
+ offset += str.length;
+ }
+ for (const [type, objOffset, gen] of xrefTableData) {
+ offset = writeInt(type, sizes[0], offset, array);
+ offset = writeInt(objOffset, sizes[1], offset, array);
+ offset = writeInt(gen, sizes[2], offset, array);
+ }
+ writeString(footer, offset, array);
+ return array;
+}
+
+;// CONCATENATED MODULE: ./src/core/struct_tree.js
+
+
+
+
+const MAX_DEPTH = 40;
+const StructElementType = {
+ PAGE_CONTENT: 1,
+ STREAM_CONTENT: 2,
+ OBJECT: 3,
+ ANNOTATION: 4,
+ ELEMENT: 5
+};
+class StructTreeRoot {
+ constructor(rootDict, rootRef) {
+ this.dict = rootDict;
+ this.ref = rootRef instanceof Ref ? rootRef : null;
+ this.roleMap = new Map();
+ this.structParentIds = null;
+ }
+ init() {
+ this.readRoleMap();
+ }
+ #addIdToPage(pageRef, id, type) {
+ if (!(pageRef instanceof Ref) || id < 0) {
+ return;
+ }
+ this.structParentIds ||= new RefSetCache();
+ let ids = this.structParentIds.get(pageRef);
+ if (!ids) {
+ ids = [];
+ this.structParentIds.put(pageRef, ids);
+ }
+ ids.push([id, type]);
+ }
+ addAnnotationIdToPage(pageRef, id) {
+ this.#addIdToPage(pageRef, id, StructElementType.ANNOTATION);
+ }
+ readRoleMap() {
+ const roleMapDict = this.dict.get("RoleMap");
+ if (!(roleMapDict instanceof Dict)) {
+ return;
+ }
+ roleMapDict.forEach((key, value) => {
+ if (!(value instanceof Name)) {
+ return;
+ }
+ this.roleMap.set(key, value.name);
+ });
+ }
+ static async canCreateStructureTree({
+ catalogRef,
+ pdfManager,
+ newAnnotationsByPage
+ }) {
+ if (!(catalogRef instanceof Ref)) {
+ warn("Cannot save the struct tree: no catalog reference.");
+ return false;
+ }
+ let nextKey = 0;
+ let hasNothingToUpdate = true;
+ for (const [pageIndex, elements] of newAnnotationsByPage) {
+ const {
+ ref: pageRef
+ } = await pdfManager.getPage(pageIndex);
+ if (!(pageRef instanceof Ref)) {
+ warn(`Cannot save the struct tree: page ${pageIndex} has no ref.`);
+ hasNothingToUpdate = true;
+ break;
+ }
+ for (const element of elements) {
+ if (element.accessibilityData?.type) {
+ element.parentTreeId = nextKey++;
+ hasNothingToUpdate = false;
+ }
+ }
+ }
+ if (hasNothingToUpdate) {
+ for (const elements of newAnnotationsByPage.values()) {
+ for (const element of elements) {
+ delete element.parentTreeId;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+ static async createStructureTree({
+ newAnnotationsByPage,
+ xref,
+ catalogRef,
+ pdfManager,
+ newRefs
+ }) {
+ const root = pdfManager.catalog.cloneDict();
+ const structTreeRootRef = xref.getNewTemporaryRef();
+ root.set("StructTreeRoot", structTreeRootRef);
+ const buffer = [];
+ await writeObject(catalogRef, root, buffer, xref);
+ newRefs.push({
+ ref: catalogRef,
+ data: buffer.join("")
+ });
+ const structTreeRoot = new Dict(xref);
+ structTreeRoot.set("Type", Name.get("StructTreeRoot"));
+ const parentTreeRef = xref.getNewTemporaryRef();
+ structTreeRoot.set("ParentTree", parentTreeRef);
+ const kids = [];
+ structTreeRoot.set("K", kids);
+ const parentTree = new Dict(xref);
+ const nums = [];
+ parentTree.set("Nums", nums);
+ const nextKey = await this.#writeKids({
+ newAnnotationsByPage,
+ structTreeRootRef,
+ kids,
+ nums,
+ xref,
+ pdfManager,
+ newRefs,
+ buffer
+ });
+ structTreeRoot.set("ParentTreeNextKey", nextKey);
+ buffer.length = 0;
+ await writeObject(parentTreeRef, parentTree, buffer, xref);
+ newRefs.push({
+ ref: parentTreeRef,
+ data: buffer.join("")
+ });
+ buffer.length = 0;
+ await writeObject(structTreeRootRef, structTreeRoot, buffer, xref);
+ newRefs.push({
+ ref: structTreeRootRef,
+ data: buffer.join("")
+ });
+ }
+ async canUpdateStructTree({
+ pdfManager,
+ xref,
+ newAnnotationsByPage
+ }) {
+ if (!this.ref) {
+ warn("Cannot update the struct tree: no root reference.");
+ return false;
+ }
+ let nextKey = this.dict.get("ParentTreeNextKey");
+ if (!Number.isInteger(nextKey) || nextKey < 0) {
+ warn("Cannot update the struct tree: invalid next key.");
+ return false;
+ }
+ const parentTree = this.dict.get("ParentTree");
+ if (!(parentTree instanceof Dict)) {
+ warn("Cannot update the struct tree: ParentTree isn't a dict.");
+ return false;
+ }
+ const nums = parentTree.get("Nums");
+ if (!Array.isArray(nums)) {
+ warn("Cannot update the struct tree: nums isn't an array.");
+ return false;
+ }
+ const numberTree = new NumberTree(parentTree, xref);
+ for (const pageIndex of newAnnotationsByPage.keys()) {
+ const {
+ pageDict
+ } = await pdfManager.getPage(pageIndex);
+ if (!pageDict.has("StructParents")) {
+ continue;
+ }
+ const id = pageDict.get("StructParents");
+ if (!Number.isInteger(id) || !Array.isArray(numberTree.get(id))) {
+ warn(`Cannot save the struct tree: page ${pageIndex} has a wrong id.`);
+ return false;
+ }
+ }
+ let hasNothingToUpdate = true;
+ for (const [pageIndex, elements] of newAnnotationsByPage) {
+ const {
+ pageDict
+ } = await pdfManager.getPage(pageIndex);
+ StructTreeRoot.#collectParents({
+ elements,
+ xref: this.dict.xref,
+ pageDict,
+ numberTree
+ });
+ for (const element of elements) {
+ if (element.accessibilityData?.type) {
+ element.parentTreeId = nextKey++;
+ hasNothingToUpdate = false;
+ }
+ }
+ }
+ if (hasNothingToUpdate) {
+ for (const elements of newAnnotationsByPage.values()) {
+ for (const element of elements) {
+ delete element.parentTreeId;
+ delete element.structTreeParent;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+ async updateStructureTree({
+ newAnnotationsByPage,
+ pdfManager,
+ newRefs
+ }) {
+ const xref = this.dict.xref;
+ const structTreeRoot = this.dict.clone();
+ const structTreeRootRef = this.ref;
+ let parentTreeRef = structTreeRoot.getRaw("ParentTree");
+ let parentTree;
+ if (parentTreeRef instanceof Ref) {
+ parentTree = xref.fetch(parentTreeRef);
+ } else {
+ parentTree = parentTreeRef;
+ parentTreeRef = xref.getNewTemporaryRef();
+ structTreeRoot.set("ParentTree", parentTreeRef);
+ }
+ parentTree = parentTree.clone();
+ let nums = parentTree.getRaw("Nums");
+ let numsRef = null;
+ if (nums instanceof Ref) {
+ numsRef = nums;
+ nums = xref.fetch(numsRef);
+ }
+ nums = nums.slice();
+ if (!numsRef) {
+ parentTree.set("Nums", nums);
+ }
+ let kids = structTreeRoot.getRaw("K");
+ let kidsRef = null;
+ if (kids instanceof Ref) {
+ kidsRef = kids;
+ kids = xref.fetch(kidsRef);
+ } else {
+ kidsRef = xref.getNewTemporaryRef();
+ structTreeRoot.set("K", kidsRef);
+ }
+ kids = Array.isArray(kids) ? kids.slice() : [kids];
+ const buffer = [];
+ const newNextkey = await StructTreeRoot.#writeKids({
+ newAnnotationsByPage,
+ structTreeRootRef,
+ kids,
+ nums,
+ xref,
+ pdfManager,
+ newRefs,
+ buffer
+ });
+ structTreeRoot.set("ParentTreeNextKey", newNextkey);
+ buffer.length = 0;
+ await writeObject(kidsRef, kids, buffer, xref);
+ newRefs.push({
+ ref: kidsRef,
+ data: buffer.join("")
+ });
+ if (numsRef) {
+ buffer.length = 0;
+ await writeObject(numsRef, nums, buffer, xref);
+ newRefs.push({
+ ref: numsRef,
+ data: buffer.join("")
+ });
+ }
+ buffer.length = 0;
+ await writeObject(parentTreeRef, parentTree, buffer, xref);
+ newRefs.push({
+ ref: parentTreeRef,
+ data: buffer.join("")
+ });
+ buffer.length = 0;
+ await writeObject(structTreeRootRef, structTreeRoot, buffer, xref);
+ newRefs.push({
+ ref: structTreeRootRef,
+ data: buffer.join("")
+ });
+ }
+ static async #writeKids({
+ newAnnotationsByPage,
+ structTreeRootRef,
+ kids,
+ nums,
+ xref,
+ pdfManager,
+ newRefs,
+ buffer
+ }) {
+ const objr = Name.get("OBJR");
+ let nextKey = -Infinity;
+ for (const [pageIndex, elements] of newAnnotationsByPage) {
+ const {
+ ref: pageRef
+ } = await pdfManager.getPage(pageIndex);
+ const isPageRef = pageRef instanceof Ref;
+ for (const {
+ accessibilityData,
+ ref,
+ parentTreeId,
+ structTreeParent
+ } of elements) {
+ if (!accessibilityData?.type) {
+ continue;
+ }
+ const {
+ type,
+ title,
+ lang,
+ alt,
+ expanded,
+ actualText
+ } = accessibilityData;
+ nextKey = Math.max(nextKey, parentTreeId);
+ const tagRef = xref.getNewTemporaryRef();
+ const tagDict = new Dict(xref);
+ tagDict.set("S", Name.get(type));
+ if (title) {
+ tagDict.set("T", title);
+ }
+ if (lang) {
+ tagDict.set("Lang", lang);
+ }
+ if (alt) {
+ tagDict.set("Alt", alt);
+ }
+ if (expanded) {
+ tagDict.set("E", expanded);
+ }
+ if (actualText) {
+ tagDict.set("ActualText", actualText);
+ }
+ if (structTreeParent) {
+ await this.#updateParentTag({
+ structTreeParent,
+ tagDict,
+ newTagRef: tagRef,
+ fallbackRef: structTreeRootRef,
+ xref,
+ newRefs,
+ buffer
+ });
+ } else {
+ tagDict.set("P", structTreeRootRef);
+ }
+ const objDict = new Dict(xref);
+ tagDict.set("K", objDict);
+ objDict.set("Type", objr);
+ if (isPageRef) {
+ objDict.set("Pg", pageRef);
+ }
+ objDict.set("Obj", ref);
+ buffer.length = 0;
+ await writeObject(tagRef, tagDict, buffer, xref);
+ newRefs.push({
+ ref: tagRef,
+ data: buffer.join("")
+ });
+ nums.push(parentTreeId, tagRef);
+ kids.push(tagRef);
+ }
+ }
+ return nextKey + 1;
+ }
+ static #collectParents({
+ elements,
+ xref,
+ pageDict,
+ numberTree
+ }) {
+ const idToElement = new Map();
+ for (const element of elements) {
+ if (element.structTreeParentId) {
+ const id = parseInt(element.structTreeParentId.split("_mc")[1], 10);
+ idToElement.set(id, element);
+ }
+ }
+ const id = pageDict.get("StructParents");
+ if (!Number.isInteger(id)) {
+ return;
+ }
+ const parentArray = numberTree.get(id);
+ const updateElement = (kid, pageKid, kidRef) => {
+ const element = idToElement.get(kid);
+ if (element) {
+ const parentRef = pageKid.getRaw("P");
+ const parentDict = xref.fetchIfRef(parentRef);
+ if (parentRef instanceof Ref && parentDict instanceof Dict) {
+ element.structTreeParent = {
+ ref: kidRef,
+ dict: pageKid
+ };
+ }
+ return true;
+ }
+ return false;
+ };
+ for (const kidRef of parentArray) {
+ if (!(kidRef instanceof Ref)) {
+ continue;
+ }
+ const pageKid = xref.fetch(kidRef);
+ const k = pageKid.get("K");
+ if (Number.isInteger(k)) {
+ updateElement(k, pageKid, kidRef);
+ continue;
+ }
+ if (!Array.isArray(k)) {
+ continue;
+ }
+ for (let kid of k) {
+ kid = xref.fetchIfRef(kid);
+ if (Number.isInteger(kid) && updateElement(kid, pageKid, kidRef)) {
+ break;
+ }
+ }
+ }
+ }
+ static async #updateParentTag({
+ structTreeParent: {
+ ref,
+ dict
+ },
+ tagDict,
+ newTagRef,
+ fallbackRef,
+ xref,
+ newRefs,
+ buffer
+ }) {
+ const parentRef = dict.getRaw("P");
+ let parentDict = xref.fetchIfRef(parentRef);
+ tagDict.set("P", parentRef);
+ let saveParentDict = false;
+ let parentKids;
+ let parentKidsRef = parentDict.getRaw("K");
+ if (!(parentKidsRef instanceof Ref)) {
+ parentKids = parentKidsRef;
+ parentKidsRef = xref.getNewTemporaryRef();
+ parentDict = parentDict.clone();
+ parentDict.set("K", parentKidsRef);
+ saveParentDict = true;
+ } else {
+ parentKids = xref.fetch(parentKidsRef);
+ }
+ if (Array.isArray(parentKids)) {
+ const index = parentKids.indexOf(ref);
+ if (index >= 0) {
+ parentKids = parentKids.slice();
+ parentKids.splice(index + 1, 0, newTagRef);
+ } else {
+ warn("Cannot update the struct tree: parent kid not found.");
+ tagDict.set("P", fallbackRef);
+ return;
+ }
+ } else if (parentKids instanceof Dict) {
+ parentKids = [parentKidsRef, newTagRef];
+ parentKidsRef = xref.getNewTemporaryRef();
+ parentDict.set("K", parentKidsRef);
+ saveParentDict = true;
+ }
+ buffer.length = 0;
+ await writeObject(parentKidsRef, parentKids, buffer, xref);
+ newRefs.push({
+ ref: parentKidsRef,
+ data: buffer.join("")
+ });
+ if (!saveParentDict) {
+ return;
+ }
+ buffer.length = 0;
+ await writeObject(parentRef, parentDict, buffer, xref);
+ newRefs.push({
+ ref: parentRef,
+ data: buffer.join("")
+ });
+ }
+}
+class StructElementNode {
+ constructor(tree, dict) {
+ this.tree = tree;
+ this.dict = dict;
+ this.kids = [];
+ this.parseKids();
+ }
+ get role() {
+ const nameObj = this.dict.get("S");
+ const name = nameObj instanceof Name ? nameObj.name : "";
+ const {
+ root
+ } = this.tree;
+ if (root.roleMap.has(name)) {
+ return root.roleMap.get(name);
+ }
+ return name;
+ }
+ parseKids() {
+ let pageObjId = null;
+ const objRef = this.dict.getRaw("Pg");
+ if (objRef instanceof Ref) {
+ pageObjId = objRef.toString();
+ }
+ const kids = this.dict.get("K");
+ if (Array.isArray(kids)) {
+ for (const kid of kids) {
+ const element = this.parseKid(pageObjId, kid);
+ if (element) {
+ this.kids.push(element);
+ }
+ }
+ } else {
+ const element = this.parseKid(pageObjId, kids);
+ if (element) {
+ this.kids.push(element);
+ }
+ }
+ }
+ parseKid(pageObjId, kid) {
+ if (Number.isInteger(kid)) {
+ if (this.tree.pageDict.objId !== pageObjId) {
+ return null;
+ }
+ return new StructElement({
+ type: StructElementType.PAGE_CONTENT,
+ mcid: kid,
+ pageObjId
+ });
+ }
+ let kidDict = null;
+ if (kid instanceof Ref) {
+ kidDict = this.dict.xref.fetch(kid);
+ } else if (kid instanceof Dict) {
+ kidDict = kid;
+ }
+ if (!kidDict) {
+ return null;
+ }
+ const pageRef = kidDict.getRaw("Pg");
+ if (pageRef instanceof Ref) {
+ pageObjId = pageRef.toString();
+ }
+ const type = kidDict.get("Type") instanceof Name ? kidDict.get("Type").name : null;
+ if (type === "MCR") {
+ if (this.tree.pageDict.objId !== pageObjId) {
+ return null;
+ }
+ const kidRef = kidDict.getRaw("Stm");
+ return new StructElement({
+ type: StructElementType.STREAM_CONTENT,
+ refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
+ pageObjId,
+ mcid: kidDict.get("MCID")
+ });
+ }
+ if (type === "OBJR") {
+ if (this.tree.pageDict.objId !== pageObjId) {
+ return null;
+ }
+ const kidRef = kidDict.getRaw("Obj");
+ return new StructElement({
+ type: StructElementType.OBJECT,
+ refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
+ pageObjId
+ });
+ }
+ return new StructElement({
+ type: StructElementType.ELEMENT,
+ dict: kidDict
+ });
+ }
+}
+class StructElement {
+ constructor({
+ type,
+ dict = null,
+ mcid = null,
+ pageObjId = null,
+ refObjId = null
+ }) {
+ this.type = type;
+ this.dict = dict;
+ this.mcid = mcid;
+ this.pageObjId = pageObjId;
+ this.refObjId = refObjId;
+ this.parentNode = null;
+ }
+}
+class StructTreePage {
+ constructor(structTreeRoot, pageDict) {
+ this.root = structTreeRoot;
+ this.rootDict = structTreeRoot ? structTreeRoot.dict : null;
+ this.pageDict = pageDict;
+ this.nodes = [];
+ }
+ parse(pageRef) {
+ if (!this.root || !this.rootDict) {
+ return;
+ }
+ const parentTree = this.rootDict.get("ParentTree");
+ if (!parentTree) {
+ return;
+ }
+ const id = this.pageDict.get("StructParents");
+ const ids = pageRef instanceof Ref && this.root.structParentIds?.get(pageRef);
+ if (!Number.isInteger(id) && !ids) {
+ return;
+ }
+ const map = new Map();
+ const numberTree = new NumberTree(parentTree, this.rootDict.xref);
+ if (Number.isInteger(id)) {
+ const parentArray = numberTree.get(id);
+ if (Array.isArray(parentArray)) {
+ for (const ref of parentArray) {
+ if (ref instanceof Ref) {
+ this.addNode(this.rootDict.xref.fetch(ref), map);
+ }
+ }
+ }
+ }
+ if (!ids) {
+ return;
+ }
+ for (const [elemId, type] of ids) {
+ const obj = numberTree.get(elemId);
+ if (obj) {
+ const elem = this.addNode(this.rootDict.xref.fetchIfRef(obj), map);
+ if (elem?.kids?.length === 1 && elem.kids[0].type === StructElementType.OBJECT) {
+ elem.kids[0].type = type;
+ }
+ }
+ }
+ }
+ addNode(dict, map, level = 0) {
+ if (level > MAX_DEPTH) {
+ warn("StructTree MAX_DEPTH reached.");
+ return null;
+ }
+ if (map.has(dict)) {
+ return map.get(dict);
+ }
+ const element = new StructElementNode(this, dict);
+ map.set(dict, element);
+ const parent = dict.get("P");
+ if (!parent || isName(parent.get("Type"), "StructTreeRoot")) {
+ if (!this.addTopLevelNode(dict, element)) {
+ map.delete(dict);
+ }
+ return element;
+ }
+ const parentNode = this.addNode(parent, map, level + 1);
+ if (!parentNode) {
+ return element;
+ }
+ let save = false;
+ for (const kid of parentNode.kids) {
+ if (kid.type === StructElementType.ELEMENT && kid.dict === dict) {
+ kid.parentNode = element;
+ save = true;
+ }
+ }
+ if (!save) {
+ map.delete(dict);
+ }
+ return element;
+ }
+ addTopLevelNode(dict, element) {
+ const obj = this.rootDict.get("K");
+ if (!obj) {
+ return false;
+ }
+ if (obj instanceof Dict) {
+ if (obj.objId !== dict.objId) {
+ return false;
+ }
+ this.nodes[0] = element;
+ return true;
+ }
+ if (!Array.isArray(obj)) {
+ return true;
+ }
+ let save = false;
+ for (let i = 0; i < obj.length; i++) {
+ const kidRef = obj[i];
+ if (kidRef?.toString() === dict.objId) {
+ this.nodes[i] = element;
+ save = true;
+ }
+ }
+ return save;
+ }
+ get serializable() {
+ function nodeToSerializable(node, parent, level = 0) {
+ if (level > MAX_DEPTH) {
+ warn("StructTree too deep to be fully serialized.");
+ return;
+ }
+ const obj = Object.create(null);
+ obj.role = node.role;
+ obj.children = [];
+ parent.children.push(obj);
+ const alt = node.dict.get("Alt");
+ if (typeof alt === "string") {
+ obj.alt = stringToPDFString(alt);
+ }
+ const lang = node.dict.get("Lang");
+ if (typeof lang === "string") {
+ obj.lang = stringToPDFString(lang);
+ }
+ for (const kid of node.kids) {
+ const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null;
+ if (kidElement) {
+ nodeToSerializable(kidElement, obj, level + 1);
+ continue;
+ } else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) {
+ obj.children.push({
+ type: "content",
+ id: `p${kid.pageObjId}_mc${kid.mcid}`
+ });
+ } else if (kid.type === StructElementType.OBJECT) {
+ obj.children.push({
+ type: "object",
+ id: kid.refObjId
+ });
+ } else if (kid.type === StructElementType.ANNOTATION) {
+ obj.children.push({
+ type: "annotation",
+ id: `${AnnotationPrefix}${kid.refObjId}`
+ });
+ }
+ }
+ }
+ const root = Object.create(null);
+ root.children = [];
+ root.role = "Root";
+ for (const child of this.nodes) {
+ if (!child) {
+ continue;
+ }
+ nodeToSerializable(child, root);
+ }
+ return root;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/catalog.js
+
+
+
+
+
+
+
+
+
+
+
+function fetchDestination(dest) {
+ if (dest instanceof Dict) {
+ dest = dest.get("D");
+ }
+ return Array.isArray(dest) ? dest : null;
+}
+function fetchRemoteDest(action) {
+ let dest = action.get("D");
+ if (dest) {
+ if (dest instanceof Name) {
+ dest = dest.name;
+ }
+ if (typeof dest === "string") {
+ return stringToPDFString(dest);
+ } else if (Array.isArray(dest)) {
+ return JSON.stringify(dest);
+ }
+ }
+ return null;
+}
+class Catalog {
+ constructor(pdfManager, xref) {
+ this.pdfManager = pdfManager;
+ this.xref = xref;
+ this._catDict = xref.getCatalogObj();
+ if (!(this._catDict instanceof Dict)) {
+ throw new FormatError("Catalog object is not a dictionary.");
+ }
+ this.toplevelPagesDict;
+ this._actualNumPages = null;
+ this.fontCache = new RefSetCache();
+ this.builtInCMapCache = new Map();
+ this.standardFontDataCache = new Map();
+ this.globalImageCache = new GlobalImageCache();
+ this.pageKidsCountCache = new RefSetCache();
+ this.pageIndexCache = new RefSetCache();
+ this.nonBlendModesSet = new RefSet();
+ this.systemFontCache = new Map();
+ }
+ cloneDict() {
+ return this._catDict.clone();
+ }
+ get version() {
+ const version = this._catDict.get("Version");
+ if (version instanceof Name) {
+ if (PDF_VERSION_REGEXP.test(version.name)) {
+ return shadow(this, "version", version.name);
+ }
+ warn(`Invalid PDF catalog version: ${version.name}`);
+ }
+ return shadow(this, "version", null);
+ }
+ get lang() {
+ const lang = this._catDict.get("Lang");
+ return shadow(this, "lang", typeof lang === "string" ? stringToPDFString(lang) : null);
+ }
+ get needsRendering() {
+ const needsRendering = this._catDict.get("NeedsRendering");
+ return shadow(this, "needsRendering", typeof needsRendering === "boolean" ? needsRendering : false);
+ }
+ get collection() {
+ let collection = null;
+ try {
+ const obj = this._catDict.get("Collection");
+ if (obj instanceof Dict && obj.size > 0) {
+ collection = obj;
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ info("Cannot fetch Collection entry; assuming no collection is present.");
+ }
+ return shadow(this, "collection", collection);
+ }
+ get acroForm() {
+ let acroForm = null;
+ try {
+ const obj = this._catDict.get("AcroForm");
+ if (obj instanceof Dict && obj.size > 0) {
+ acroForm = obj;
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ info("Cannot fetch AcroForm entry; assuming no forms are present.");
+ }
+ return shadow(this, "acroForm", acroForm);
+ }
+ get acroFormRef() {
+ const value = this._catDict.getRaw("AcroForm");
+ return shadow(this, "acroFormRef", value instanceof Ref ? value : null);
+ }
+ get metadata() {
+ const streamRef = this._catDict.getRaw("Metadata");
+ if (!(streamRef instanceof Ref)) {
+ return shadow(this, "metadata", null);
+ }
+ let metadata = null;
+ try {
+ const stream = this.xref.fetch(streamRef, !this.xref.encrypt?.encryptMetadata);
+ if (stream instanceof BaseStream && stream.dict instanceof Dict) {
+ const type = stream.dict.get("Type");
+ const subtype = stream.dict.get("Subtype");
+ if (isName(type, "Metadata") && isName(subtype, "XML")) {
+ const data = stringToUTF8String(stream.getString());
+ if (data) {
+ metadata = new MetadataParser(data).serializable;
+ }
+ }
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ info(`Skipping invalid Metadata: "${ex}".`);
+ }
+ return shadow(this, "metadata", metadata);
+ }
+ get markInfo() {
+ let markInfo = null;
+ try {
+ markInfo = this._readMarkInfo();
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Unable to read mark info.");
+ }
+ return shadow(this, "markInfo", markInfo);
+ }
+ _readMarkInfo() {
+ const obj = this._catDict.get("MarkInfo");
+ if (!(obj instanceof Dict)) {
+ return null;
+ }
+ const markInfo = {
+ Marked: false,
+ UserProperties: false,
+ Suspects: false
+ };
+ for (const key in markInfo) {
+ const value = obj.get(key);
+ if (typeof value === "boolean") {
+ markInfo[key] = value;
+ }
+ }
+ return markInfo;
+ }
+ get structTreeRoot() {
+ let structTree = null;
+ try {
+ structTree = this._readStructTreeRoot();
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Unable read to structTreeRoot info.");
+ }
+ return shadow(this, "structTreeRoot", structTree);
+ }
+ _readStructTreeRoot() {
+ const rawObj = this._catDict.getRaw("StructTreeRoot");
+ const obj = this.xref.fetchIfRef(rawObj);
+ if (!(obj instanceof Dict)) {
+ return null;
+ }
+ const root = new StructTreeRoot(obj, rawObj);
+ root.init();
+ return root;
+ }
+ get toplevelPagesDict() {
+ const pagesObj = this._catDict.get("Pages");
+ if (!(pagesObj instanceof Dict)) {
+ throw new FormatError("Invalid top-level pages dictionary.");
+ }
+ return shadow(this, "toplevelPagesDict", pagesObj);
+ }
+ get documentOutline() {
+ let obj = null;
+ try {
+ obj = this._readDocumentOutline();
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Unable to read document outline.");
+ }
+ return shadow(this, "documentOutline", obj);
+ }
+ _readDocumentOutline() {
+ let obj = this._catDict.get("Outlines");
+ if (!(obj instanceof Dict)) {
+ return null;
+ }
+ obj = obj.getRaw("First");
+ if (!(obj instanceof Ref)) {
+ return null;
+ }
+ const root = {
+ items: []
+ };
+ const queue = [{
+ obj,
+ parent: root
+ }];
+ const processed = new RefSet();
+ processed.put(obj);
+ const xref = this.xref,
+ blackColor = new Uint8ClampedArray(3);
+ while (queue.length > 0) {
+ const i = queue.shift();
+ const outlineDict = xref.fetchIfRef(i.obj);
+ if (outlineDict === null) {
+ continue;
+ }
+ if (!outlineDict.has("Title")) {
+ throw new FormatError("Invalid outline item encountered.");
+ }
+ const data = {
+ url: null,
+ dest: null,
+ action: null
+ };
+ Catalog.parseDestDictionary({
+ destDict: outlineDict,
+ resultObj: data,
+ docBaseUrl: this.baseUrl,
+ docAttachments: this.attachments
+ });
+ const title = outlineDict.get("Title");
+ const flags = outlineDict.get("F") || 0;
+ const color = outlineDict.getArray("C");
+ const count = outlineDict.get("Count");
+ let rgbColor = blackColor;
+ if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {
+ rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0);
+ }
+ const outlineItem = {
+ action: data.action,
+ attachment: data.attachment,
+ dest: data.dest,
+ url: data.url,
+ unsafeUrl: data.unsafeUrl,
+ newWindow: data.newWindow,
+ setOCGState: data.setOCGState,
+ title: stringToPDFString(title),
+ color: rgbColor,
+ count: Number.isInteger(count) ? count : undefined,
+ bold: !!(flags & 2),
+ italic: !!(flags & 1),
+ items: []
+ };
+ i.parent.items.push(outlineItem);
+ obj = outlineDict.getRaw("First");
+ if (obj instanceof Ref && !processed.has(obj)) {
+ queue.push({
+ obj,
+ parent: outlineItem
+ });
+ processed.put(obj);
+ }
+ obj = outlineDict.getRaw("Next");
+ if (obj instanceof Ref && !processed.has(obj)) {
+ queue.push({
+ obj,
+ parent: i.parent
+ });
+ processed.put(obj);
+ }
+ }
+ return root.items.length > 0 ? root.items : null;
+ }
+ get permissions() {
+ let permissions = null;
+ try {
+ permissions = this._readPermissions();
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Unable to read permissions.");
+ }
+ return shadow(this, "permissions", permissions);
+ }
+ _readPermissions() {
+ const encrypt = this.xref.trailer.get("Encrypt");
+ if (!(encrypt instanceof Dict)) {
+ return null;
+ }
+ let flags = encrypt.get("P");
+ if (typeof flags !== "number") {
+ return null;
+ }
+ flags += 2 ** 32;
+ const permissions = [];
+ for (const key in PermissionFlag) {
+ const value = PermissionFlag[key];
+ if (flags & value) {
+ permissions.push(value);
+ }
+ }
+ return permissions;
+ }
+ get optionalContentConfig() {
+ let config = null;
+ try {
+ const properties = this._catDict.get("OCProperties");
+ if (!properties) {
+ return shadow(this, "optionalContentConfig", null);
+ }
+ const defaultConfig = properties.get("D");
+ if (!defaultConfig) {
+ return shadow(this, "optionalContentConfig", null);
+ }
+ const groupsData = properties.get("OCGs");
+ if (!Array.isArray(groupsData)) {
+ return shadow(this, "optionalContentConfig", null);
+ }
+ const groups = [];
+ const groupRefs = new RefSet();
+ for (const groupRef of groupsData) {
+ if (!(groupRef instanceof Ref) || groupRefs.has(groupRef)) {
+ continue;
+ }
+ groupRefs.put(groupRef);
+ const group = this.xref.fetch(groupRef);
+ groups.push({
+ id: groupRef.toString(),
+ name: typeof group.get("Name") === "string" ? stringToPDFString(group.get("Name")) : null,
+ intent: typeof group.get("Intent") === "string" ? stringToPDFString(group.get("Intent")) : null
+ });
+ }
+ config = this._readOptionalContentConfig(defaultConfig, groupRefs);
+ config.groups = groups;
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`Unable to read optional content config: ${ex}`);
+ }
+ return shadow(this, "optionalContentConfig", config);
+ }
+ _readOptionalContentConfig(config, contentGroupRefs) {
+ function parseOnOff(refs) {
+ const onParsed = [];
+ if (Array.isArray(refs)) {
+ for (const value of refs) {
+ if (!(value instanceof Ref)) {
+ continue;
+ }
+ if (contentGroupRefs.has(value)) {
+ onParsed.push(value.toString());
+ }
+ }
+ }
+ return onParsed;
+ }
+ function parseOrder(refs, nestedLevels = 0) {
+ if (!Array.isArray(refs)) {
+ return null;
+ }
+ const order = [];
+ for (const value of refs) {
+ if (value instanceof Ref && contentGroupRefs.has(value)) {
+ parsedOrderRefs.put(value);
+ order.push(value.toString());
+ continue;
+ }
+ const nestedOrder = parseNestedOrder(value, nestedLevels);
+ if (nestedOrder) {
+ order.push(nestedOrder);
+ }
+ }
+ if (nestedLevels > 0) {
+ return order;
+ }
+ const hiddenGroups = [];
+ for (const groupRef of contentGroupRefs) {
+ if (parsedOrderRefs.has(groupRef)) {
+ continue;
+ }
+ hiddenGroups.push(groupRef.toString());
+ }
+ if (hiddenGroups.length) {
+ order.push({
+ name: null,
+ order: hiddenGroups
+ });
+ }
+ return order;
+ }
+ function parseNestedOrder(ref, nestedLevels) {
+ if (++nestedLevels > MAX_NESTED_LEVELS) {
+ warn("parseNestedOrder - reached MAX_NESTED_LEVELS.");
+ return null;
+ }
+ const value = xref.fetchIfRef(ref);
+ if (!Array.isArray(value)) {
+ return null;
+ }
+ const nestedName = xref.fetchIfRef(value[0]);
+ if (typeof nestedName !== "string") {
+ return null;
+ }
+ const nestedOrder = parseOrder(value.slice(1), nestedLevels);
+ if (!nestedOrder || !nestedOrder.length) {
+ return null;
+ }
+ return {
+ name: stringToPDFString(nestedName),
+ order: nestedOrder
+ };
+ }
+ const xref = this.xref,
+ parsedOrderRefs = new RefSet(),
+ MAX_NESTED_LEVELS = 10;
+ return {
+ name: typeof config.get("Name") === "string" ? stringToPDFString(config.get("Name")) : null,
+ creator: typeof config.get("Creator") === "string" ? stringToPDFString(config.get("Creator")) : null,
+ baseState: config.get("BaseState") instanceof Name ? config.get("BaseState").name : null,
+ on: parseOnOff(config.get("ON")),
+ off: parseOnOff(config.get("OFF")),
+ order: parseOrder(config.get("Order")),
+ groups: null
+ };
+ }
+ setActualNumPages(num = null) {
+ this._actualNumPages = num;
+ }
+ get hasActualNumPages() {
+ return this._actualNumPages !== null;
+ }
+ get _pagesCount() {
+ const obj = this.toplevelPagesDict.get("Count");
+ if (!Number.isInteger(obj)) {
+ throw new FormatError("Page count in top-level pages dictionary is not an integer.");
+ }
+ return shadow(this, "_pagesCount", obj);
+ }
+ get numPages() {
+ return this.hasActualNumPages ? this._actualNumPages : this._pagesCount;
+ }
+ get destinations() {
+ const obj = this._readDests(),
+ dests = Object.create(null);
+ if (obj instanceof NameTree) {
+ for (const [key, value] of obj.getAll()) {
+ const dest = fetchDestination(value);
+ if (dest) {
+ dests[stringToPDFString(key)] = dest;
+ }
+ }
+ } else if (obj instanceof Dict) {
+ obj.forEach(function (key, value) {
+ const dest = fetchDestination(value);
+ if (dest) {
+ dests[key] = dest;
+ }
+ });
+ }
+ return shadow(this, "destinations", dests);
+ }
+ getDestination(id) {
+ const obj = this._readDests();
+ if (obj instanceof NameTree) {
+ const dest = fetchDestination(obj.get(id));
+ if (dest) {
+ return dest;
+ }
+ const allDest = this.destinations[id];
+ if (allDest) {
+ warn(`Found "${id}" at an incorrect position in the NameTree.`);
+ return allDest;
+ }
+ } else if (obj instanceof Dict) {
+ const dest = fetchDestination(obj.get(id));
+ if (dest) {
+ return dest;
+ }
+ }
+ return null;
+ }
+ _readDests() {
+ const obj = this._catDict.get("Names");
+ if (obj?.has("Dests")) {
+ return new NameTree(obj.getRaw("Dests"), this.xref);
+ } else if (this._catDict.has("Dests")) {
+ return this._catDict.get("Dests");
+ }
+ return undefined;
+ }
+ get pageLabels() {
+ let obj = null;
+ try {
+ obj = this._readPageLabels();
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn("Unable to read page labels.");
+ }
+ return shadow(this, "pageLabels", obj);
+ }
+ _readPageLabels() {
+ const obj = this._catDict.getRaw("PageLabels");
+ if (!obj) {
+ return null;
+ }
+ const pageLabels = new Array(this.numPages);
+ let style = null,
+ prefix = "";
+ const numberTree = new NumberTree(obj, this.xref);
+ const nums = numberTree.getAll();
+ let currentLabel = "",
+ currentIndex = 1;
+ for (let i = 0, ii = this.numPages; i < ii; i++) {
+ const labelDict = nums.get(i);
+ if (labelDict !== undefined) {
+ if (!(labelDict instanceof Dict)) {
+ throw new FormatError("PageLabel is not a dictionary.");
+ }
+ if (labelDict.has("Type") && !isName(labelDict.get("Type"), "PageLabel")) {
+ throw new FormatError("Invalid type in PageLabel dictionary.");
+ }
+ if (labelDict.has("S")) {
+ const s = labelDict.get("S");
+ if (!(s instanceof Name)) {
+ throw new FormatError("Invalid style in PageLabel dictionary.");
+ }
+ style = s.name;
+ } else {
+ style = null;
+ }
+ if (labelDict.has("P")) {
+ const p = labelDict.get("P");
+ if (typeof p !== "string") {
+ throw new FormatError("Invalid prefix in PageLabel dictionary.");
+ }
+ prefix = stringToPDFString(p);
+ } else {
+ prefix = "";
+ }
+ if (labelDict.has("St")) {
+ const st = labelDict.get("St");
+ if (!(Number.isInteger(st) && st >= 1)) {
+ throw new FormatError("Invalid start in PageLabel dictionary.");
+ }
+ currentIndex = st;
+ } else {
+ currentIndex = 1;
+ }
+ }
+ switch (style) {
+ case "D":
+ currentLabel = currentIndex;
+ break;
+ case "R":
+ case "r":
+ currentLabel = toRomanNumerals(currentIndex, style === "r");
+ break;
+ case "A":
+ case "a":
+ const LIMIT = 26;
+ const A_UPPER_CASE = 0x41,
+ A_LOWER_CASE = 0x61;
+ const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE;
+ const letterIndex = currentIndex - 1;
+ const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT);
+ currentLabel = character.repeat(Math.floor(letterIndex / LIMIT) + 1);
+ break;
+ default:
+ if (style) {
+ throw new FormatError(`Invalid style "${style}" in PageLabel dictionary.`);
+ }
+ currentLabel = "";
+ }
+ pageLabels[i] = prefix + currentLabel;
+ currentIndex++;
+ }
+ return pageLabels;
+ }
+ get pageLayout() {
+ const obj = this._catDict.get("PageLayout");
+ let pageLayout = "";
+ if (obj instanceof Name) {
+ switch (obj.name) {
+ case "SinglePage":
+ case "OneColumn":
+ case "TwoColumnLeft":
+ case "TwoColumnRight":
+ case "TwoPageLeft":
+ case "TwoPageRight":
+ pageLayout = obj.name;
+ }
+ }
+ return shadow(this, "pageLayout", pageLayout);
+ }
+ get pageMode() {
+ const obj = this._catDict.get("PageMode");
+ let pageMode = "UseNone";
+ if (obj instanceof Name) {
+ switch (obj.name) {
+ case "UseNone":
+ case "UseOutlines":
+ case "UseThumbs":
+ case "FullScreen":
+ case "UseOC":
+ case "UseAttachments":
+ pageMode = obj.name;
+ }
+ }
+ return shadow(this, "pageMode", pageMode);
+ }
+ get viewerPreferences() {
+ const obj = this._catDict.get("ViewerPreferences");
+ if (!(obj instanceof Dict)) {
+ return shadow(this, "viewerPreferences", null);
+ }
+ let prefs = null;
+ for (const key of obj.getKeys()) {
+ const value = obj.get(key);
+ let prefValue;
+ switch (key) {
+ case "HideToolbar":
+ case "HideMenubar":
+ case "HideWindowUI":
+ case "FitWindow":
+ case "CenterWindow":
+ case "DisplayDocTitle":
+ case "PickTrayByPDFSize":
+ if (typeof value === "boolean") {
+ prefValue = value;
+ }
+ break;
+ case "NonFullScreenPageMode":
+ if (value instanceof Name) {
+ switch (value.name) {
+ case "UseNone":
+ case "UseOutlines":
+ case "UseThumbs":
+ case "UseOC":
+ prefValue = value.name;
+ break;
+ default:
+ prefValue = "UseNone";
+ }
+ }
+ break;
+ case "Direction":
+ if (value instanceof Name) {
+ switch (value.name) {
+ case "L2R":
+ case "R2L":
+ prefValue = value.name;
+ break;
+ default:
+ prefValue = "L2R";
+ }
+ }
+ break;
+ case "ViewArea":
+ case "ViewClip":
+ case "PrintArea":
+ case "PrintClip":
+ if (value instanceof Name) {
+ switch (value.name) {
+ case "MediaBox":
+ case "CropBox":
+ case "BleedBox":
+ case "TrimBox":
+ case "ArtBox":
+ prefValue = value.name;
+ break;
+ default:
+ prefValue = "CropBox";
+ }
+ }
+ break;
+ case "PrintScaling":
+ if (value instanceof Name) {
+ switch (value.name) {
+ case "None":
+ case "AppDefault":
+ prefValue = value.name;
+ break;
+ default:
+ prefValue = "AppDefault";
+ }
+ }
+ break;
+ case "Duplex":
+ if (value instanceof Name) {
+ switch (value.name) {
+ case "Simplex":
+ case "DuplexFlipShortEdge":
+ case "DuplexFlipLongEdge":
+ prefValue = value.name;
+ break;
+ default:
+ prefValue = "None";
+ }
+ }
+ break;
+ case "PrintPageRange":
+ if (Array.isArray(value) && value.length % 2 === 0) {
+ const isValid = value.every((page, i, arr) => {
+ return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages;
+ });
+ if (isValid) {
+ prefValue = value;
+ }
+ }
+ break;
+ case "NumCopies":
+ if (Number.isInteger(value) && value > 0) {
+ prefValue = value;
+ }
+ break;
+ default:
+ warn(`Ignoring non-standard key in ViewerPreferences: ${key}.`);
+ continue;
+ }
+ if (prefValue === undefined) {
+ warn(`Bad value, for key "${key}", in ViewerPreferences: ${value}.`);
+ continue;
+ }
+ if (!prefs) {
+ prefs = Object.create(null);
+ }
+ prefs[key] = prefValue;
+ }
+ return shadow(this, "viewerPreferences", prefs);
+ }
+ get openAction() {
+ const obj = this._catDict.get("OpenAction");
+ const openAction = Object.create(null);
+ if (obj instanceof Dict) {
+ const destDict = new Dict(this.xref);
+ destDict.set("A", obj);
+ const resultObj = {
+ url: null,
+ dest: null,
+ action: null
+ };
+ Catalog.parseDestDictionary({
+ destDict,
+ resultObj
+ });
+ if (Array.isArray(resultObj.dest)) {
+ openAction.dest = resultObj.dest;
+ } else if (resultObj.action) {
+ openAction.action = resultObj.action;
+ }
+ } else if (Array.isArray(obj)) {
+ openAction.dest = obj;
+ }
+ return shadow(this, "openAction", objectSize(openAction) > 0 ? openAction : null);
+ }
+ get attachments() {
+ const obj = this._catDict.get("Names");
+ let attachments = null;
+ if (obj instanceof Dict && obj.has("EmbeddedFiles")) {
+ const nameTree = new NameTree(obj.getRaw("EmbeddedFiles"), this.xref);
+ for (const [key, value] of nameTree.getAll()) {
+ const fs = new FileSpec(value, this.xref);
+ if (!attachments) {
+ attachments = Object.create(null);
+ }
+ attachments[stringToPDFString(key)] = fs.serializable;
+ }
+ }
+ return shadow(this, "attachments", attachments);
+ }
+ get xfaImages() {
+ const obj = this._catDict.get("Names");
+ let xfaImages = null;
+ if (obj instanceof Dict && obj.has("XFAImages")) {
+ const nameTree = new NameTree(obj.getRaw("XFAImages"), this.xref);
+ for (const [key, value] of nameTree.getAll()) {
+ if (!xfaImages) {
+ xfaImages = new Dict(this.xref);
+ }
+ xfaImages.set(stringToPDFString(key), value);
+ }
+ }
+ return shadow(this, "xfaImages", xfaImages);
+ }
+ _collectJavaScript() {
+ const obj = this._catDict.get("Names");
+ let javaScript = null;
+ function appendIfJavaScriptDict(name, jsDict) {
+ if (!(jsDict instanceof Dict)) {
+ return;
+ }
+ if (!isName(jsDict.get("S"), "JavaScript")) {
+ return;
+ }
+ let js = jsDict.get("JS");
+ if (js instanceof BaseStream) {
+ js = js.getString();
+ } else if (typeof js !== "string") {
+ return;
+ }
+ js = stringToPDFString(js).replaceAll("\x00", "");
+ if (js) {
+ (javaScript ||= new Map()).set(name, js);
+ }
+ }
+ if (obj instanceof Dict && obj.has("JavaScript")) {
+ const nameTree = new NameTree(obj.getRaw("JavaScript"), this.xref);
+ for (const [key, value] of nameTree.getAll()) {
+ appendIfJavaScriptDict(stringToPDFString(key), value);
+ }
+ }
+ const openAction = this._catDict.get("OpenAction");
+ if (openAction) {
+ appendIfJavaScriptDict("OpenAction", openAction);
+ }
+ return javaScript;
+ }
+ get jsActions() {
+ const javaScript = this._collectJavaScript();
+ let actions = collectActions(this.xref, this._catDict, DocumentActionEventType);
+ if (javaScript) {
+ actions ||= Object.create(null);
+ for (const [key, val] of javaScript) {
+ if (key in actions) {
+ actions[key].push(val);
+ } else {
+ actions[key] = [val];
+ }
+ }
+ }
+ return shadow(this, "jsActions", actions);
+ }
+ async fontFallback(id, handler) {
+ const translatedFonts = await Promise.all(this.fontCache);
+ for (const translatedFont of translatedFonts) {
+ if (translatedFont.loadedName === id) {
+ translatedFont.fallback(handler);
+ return;
+ }
+ }
+ }
+ async cleanup(manuallyTriggered = false) {
+ clearGlobalCaches();
+ this.globalImageCache.clear(manuallyTriggered);
+ this.pageKidsCountCache.clear();
+ this.pageIndexCache.clear();
+ this.nonBlendModesSet.clear();
+ const translatedFonts = await Promise.all(this.fontCache);
+ for (const {
+ dict
+ } of translatedFonts) {
+ delete dict.cacheKey;
+ }
+ this.fontCache.clear();
+ this.builtInCMapCache.clear();
+ this.standardFontDataCache.clear();
+ this.systemFontCache.clear();
+ }
+ async getPageDict(pageIndex) {
+ const nodesToVisit = [this.toplevelPagesDict];
+ const visitedNodes = new RefSet();
+ const pagesRef = this._catDict.getRaw("Pages");
+ if (pagesRef instanceof Ref) {
+ visitedNodes.put(pagesRef);
+ }
+ const xref = this.xref,
+ pageKidsCountCache = this.pageKidsCountCache,
+ pageIndexCache = this.pageIndexCache;
+ let currentPageIndex = 0;
+ while (nodesToVisit.length) {
+ const currentNode = nodesToVisit.pop();
+ if (currentNode instanceof Ref) {
+ const count = pageKidsCountCache.get(currentNode);
+ if (count >= 0 && currentPageIndex + count <= pageIndex) {
+ currentPageIndex += count;
+ continue;
+ }
+ if (visitedNodes.has(currentNode)) {
+ throw new FormatError("Pages tree contains circular reference.");
+ }
+ visitedNodes.put(currentNode);
+ const obj = await xref.fetchAsync(currentNode);
+ if (obj instanceof Dict) {
+ let type = obj.getRaw("Type");
+ if (type instanceof Ref) {
+ type = await xref.fetchAsync(type);
+ }
+ if (isName(type, "Page") || !obj.has("Kids")) {
+ if (!pageKidsCountCache.has(currentNode)) {
+ pageKidsCountCache.put(currentNode, 1);
+ }
+ if (!pageIndexCache.has(currentNode)) {
+ pageIndexCache.put(currentNode, currentPageIndex);
+ }
+ if (currentPageIndex === pageIndex) {
+ return [obj, currentNode];
+ }
+ currentPageIndex++;
+ continue;
+ }
+ }
+ nodesToVisit.push(obj);
+ continue;
+ }
+ if (!(currentNode instanceof Dict)) {
+ throw new FormatError("Page dictionary kid reference points to wrong type of object.");
+ }
+ const {
+ objId
+ } = currentNode;
+ let count = currentNode.getRaw("Count");
+ if (count instanceof Ref) {
+ count = await xref.fetchAsync(count);
+ }
+ if (Number.isInteger(count) && count >= 0) {
+ if (objId && !pageKidsCountCache.has(objId)) {
+ pageKidsCountCache.put(objId, count);
+ }
+ if (currentPageIndex + count <= pageIndex) {
+ currentPageIndex += count;
+ continue;
+ }
+ }
+ let kids = currentNode.getRaw("Kids");
+ if (kids instanceof Ref) {
+ kids = await xref.fetchAsync(kids);
+ }
+ if (!Array.isArray(kids)) {
+ let type = currentNode.getRaw("Type");
+ if (type instanceof Ref) {
+ type = await xref.fetchAsync(type);
+ }
+ if (isName(type, "Page") || !currentNode.has("Kids")) {
+ if (currentPageIndex === pageIndex) {
+ return [currentNode, null];
+ }
+ currentPageIndex++;
+ continue;
+ }
+ throw new FormatError("Page dictionary kids object is not an array.");
+ }
+ for (let last = kids.length - 1; last >= 0; last--) {
+ nodesToVisit.push(kids[last]);
+ }
+ }
+ throw new Error(`Page index ${pageIndex} not found.`);
+ }
+ async getAllPageDicts(recoveryMode = false) {
+ const {
+ ignoreErrors
+ } = this.pdfManager.evaluatorOptions;
+ const queue = [{
+ currentNode: this.toplevelPagesDict,
+ posInKids: 0
+ }];
+ const visitedNodes = new RefSet();
+ const pagesRef = this._catDict.getRaw("Pages");
+ if (pagesRef instanceof Ref) {
+ visitedNodes.put(pagesRef);
+ }
+ const map = new Map(),
+ xref = this.xref,
+ pageIndexCache = this.pageIndexCache;
+ let pageIndex = 0;
+ function addPageDict(pageDict, pageRef) {
+ if (pageRef && !pageIndexCache.has(pageRef)) {
+ pageIndexCache.put(pageRef, pageIndex);
+ }
+ map.set(pageIndex++, [pageDict, pageRef]);
+ }
+ function addPageError(error) {
+ if (error instanceof XRefEntryException && !recoveryMode) {
+ throw error;
+ }
+ if (recoveryMode && ignoreErrors && pageIndex === 0) {
+ warn(`getAllPageDicts - Skipping invalid first page: "${error}".`);
+ error = Dict.empty;
+ }
+ map.set(pageIndex++, [error, null]);
+ }
+ while (queue.length > 0) {
+ const queueItem = queue.at(-1);
+ const {
+ currentNode,
+ posInKids
+ } = queueItem;
+ let kids = currentNode.getRaw("Kids");
+ if (kids instanceof Ref) {
+ try {
+ kids = await xref.fetchAsync(kids);
+ } catch (ex) {
+ addPageError(ex);
+ break;
+ }
+ }
+ if (!Array.isArray(kids)) {
+ addPageError(new FormatError("Page dictionary kids object is not an array."));
+ break;
+ }
+ if (posInKids >= kids.length) {
+ queue.pop();
+ continue;
+ }
+ const kidObj = kids[posInKids];
+ let obj;
+ if (kidObj instanceof Ref) {
+ if (visitedNodes.has(kidObj)) {
+ addPageError(new FormatError("Pages tree contains circular reference."));
+ break;
+ }
+ visitedNodes.put(kidObj);
+ try {
+ obj = await xref.fetchAsync(kidObj);
+ } catch (ex) {
+ addPageError(ex);
+ break;
+ }
+ } else {
+ obj = kidObj;
+ }
+ if (!(obj instanceof Dict)) {
+ addPageError(new FormatError("Page dictionary kid reference points to wrong type of object."));
+ break;
+ }
+ let type = obj.getRaw("Type");
+ if (type instanceof Ref) {
+ try {
+ type = await xref.fetchAsync(type);
+ } catch (ex) {
+ addPageError(ex);
+ break;
+ }
+ }
+ if (isName(type, "Page") || !obj.has("Kids")) {
+ addPageDict(obj, kidObj instanceof Ref ? kidObj : null);
+ } else {
+ queue.push({
+ currentNode: obj,
+ posInKids: 0
+ });
+ }
+ queueItem.posInKids++;
+ }
+ return map;
+ }
+ getPageIndex(pageRef) {
+ const cachedPageIndex = this.pageIndexCache.get(pageRef);
+ if (cachedPageIndex !== undefined) {
+ return Promise.resolve(cachedPageIndex);
+ }
+ const xref = this.xref;
+ function pagesBeforeRef(kidRef) {
+ let total = 0,
+ parentRef;
+ return xref.fetchAsync(kidRef).then(function (node) {
+ if (isRefsEqual(kidRef, pageRef) && !isDict(node, "Page") && !(node instanceof Dict && !node.has("Type") && node.has("Contents"))) {
+ throw new FormatError("The reference does not point to a /Page dictionary.");
+ }
+ if (!node) {
+ return null;
+ }
+ if (!(node instanceof Dict)) {
+ throw new FormatError("Node must be a dictionary.");
+ }
+ parentRef = node.getRaw("Parent");
+ return node.getAsync("Parent");
+ }).then(function (parent) {
+ if (!parent) {
+ return null;
+ }
+ if (!(parent instanceof Dict)) {
+ throw new FormatError("Parent must be a dictionary.");
+ }
+ return parent.getAsync("Kids");
+ }).then(function (kids) {
+ if (!kids) {
+ return null;
+ }
+ const kidPromises = [];
+ let found = false;
+ for (const kid of kids) {
+ if (!(kid instanceof Ref)) {
+ throw new FormatError("Kid must be a reference.");
+ }
+ if (isRefsEqual(kid, kidRef)) {
+ found = true;
+ break;
+ }
+ kidPromises.push(xref.fetchAsync(kid).then(function (obj) {
+ if (!(obj instanceof Dict)) {
+ throw new FormatError("Kid node must be a dictionary.");
+ }
+ if (obj.has("Count")) {
+ total += obj.get("Count");
+ } else {
+ total++;
+ }
+ }));
+ }
+ if (!found) {
+ throw new FormatError("Kid reference not found in parent's kids.");
+ }
+ return Promise.all(kidPromises).then(function () {
+ return [total, parentRef];
+ });
+ });
+ }
+ let total = 0;
+ const next = ref => pagesBeforeRef(ref).then(args => {
+ if (!args) {
+ this.pageIndexCache.put(pageRef, total);
+ return total;
+ }
+ const [count, parentRef] = args;
+ total += count;
+ return next(parentRef);
+ });
+ return next(pageRef);
+ }
+ get baseUrl() {
+ const uri = this._catDict.get("URI");
+ if (uri instanceof Dict) {
+ const base = uri.get("Base");
+ if (typeof base === "string") {
+ const absoluteUrl = createValidAbsoluteUrl(base, null, {
+ tryConvertEncoding: true
+ });
+ if (absoluteUrl) {
+ return shadow(this, "baseUrl", absoluteUrl.href);
+ }
+ }
+ }
+ return shadow(this, "baseUrl", this.pdfManager.docBaseUrl);
+ }
+ static parseDestDictionary({
+ destDict,
+ resultObj,
+ docBaseUrl = null,
+ docAttachments = null
+ }) {
+ if (!(destDict instanceof Dict)) {
+ warn("parseDestDictionary: `destDict` must be a dictionary.");
+ return;
+ }
+ let action = destDict.get("A"),
+ url,
+ dest;
+ if (!(action instanceof Dict)) {
+ if (destDict.has("Dest")) {
+ action = destDict.get("Dest");
+ } else {
+ action = destDict.get("AA");
+ if (action instanceof Dict) {
+ if (action.has("D")) {
+ action = action.get("D");
+ } else if (action.has("U")) {
+ action = action.get("U");
+ }
+ }
+ }
+ }
+ if (action instanceof Dict) {
+ const actionType = action.get("S");
+ if (!(actionType instanceof Name)) {
+ warn("parseDestDictionary: Invalid type in Action dictionary.");
+ return;
+ }
+ const actionName = actionType.name;
+ switch (actionName) {
+ case "ResetForm":
+ const flags = action.get("Flags");
+ const include = ((typeof flags === "number" ? flags : 0) & 1) === 0;
+ const fields = [];
+ const refs = [];
+ for (const obj of action.get("Fields") || []) {
+ if (obj instanceof Ref) {
+ refs.push(obj.toString());
+ } else if (typeof obj === "string") {
+ fields.push(stringToPDFString(obj));
+ }
+ }
+ resultObj.resetForm = {
+ fields,
+ refs,
+ include
+ };
+ break;
+ case "URI":
+ url = action.get("URI");
+ if (url instanceof Name) {
+ url = "/" + url.name;
+ }
+ break;
+ case "GoTo":
+ dest = action.get("D");
+ break;
+ case "Launch":
+ case "GoToR":
+ const urlDict = action.get("F");
+ if (urlDict instanceof Dict) {
+ url = urlDict.get("F") || null;
+ } else if (typeof urlDict === "string") {
+ url = urlDict;
+ }
+ const remoteDest = fetchRemoteDest(action);
+ if (remoteDest && typeof url === "string") {
+ url = url.split("#", 1)[0] + "#" + remoteDest;
+ }
+ const newWindow = action.get("NewWindow");
+ if (typeof newWindow === "boolean") {
+ resultObj.newWindow = newWindow;
+ }
+ break;
+ case "GoToE":
+ const target = action.get("T");
+ let attachment;
+ if (docAttachments && target instanceof Dict) {
+ const relationship = target.get("R");
+ const name = target.get("N");
+ if (isName(relationship, "C") && typeof name === "string") {
+ attachment = docAttachments[stringToPDFString(name)];
+ }
+ }
+ if (attachment) {
+ resultObj.attachment = attachment;
+ const attachmentDest = fetchRemoteDest(action);
+ if (attachmentDest) {
+ resultObj.attachmentDest = attachmentDest;
+ }
+ } else {
+ warn(`parseDestDictionary - unimplemented "GoToE" action.`);
+ }
+ break;
+ case "Named":
+ const namedAction = action.get("N");
+ if (namedAction instanceof Name) {
+ resultObj.action = namedAction.name;
+ }
+ break;
+ case "SetOCGState":
+ const state = action.get("State");
+ const preserveRB = action.get("PreserveRB");
+ if (!Array.isArray(state) || state.length === 0) {
+ break;
+ }
+ const stateArr = [];
+ for (const elem of state) {
+ if (elem instanceof Name) {
+ switch (elem.name) {
+ case "ON":
+ case "OFF":
+ case "Toggle":
+ stateArr.push(elem.name);
+ break;
+ }
+ } else if (elem instanceof Ref) {
+ stateArr.push(elem.toString());
+ }
+ }
+ if (stateArr.length !== state.length) {
+ break;
+ }
+ resultObj.setOCGState = {
+ state: stateArr,
+ preserveRB: typeof preserveRB === "boolean" ? preserveRB : true
+ };
+ break;
+ case "JavaScript":
+ const jsAction = action.get("JS");
+ let js;
+ if (jsAction instanceof BaseStream) {
+ js = jsAction.getString();
+ } else if (typeof jsAction === "string") {
+ js = jsAction;
+ }
+ const jsURL = js && recoverJsURL(stringToPDFString(js));
+ if (jsURL) {
+ url = jsURL.url;
+ resultObj.newWindow = jsURL.newWindow;
+ break;
+ }
+ default:
+ if (actionName === "JavaScript" || actionName === "SubmitForm") {
+ break;
+ }
+ warn(`parseDestDictionary - unsupported action: "${actionName}".`);
+ break;
+ }
+ } else if (destDict.has("Dest")) {
+ dest = destDict.get("Dest");
+ }
+ if (typeof url === "string") {
+ const absoluteUrl = createValidAbsoluteUrl(url, docBaseUrl, {
+ addDefaultProtocol: true,
+ tryConvertEncoding: true
+ });
+ if (absoluteUrl) {
+ resultObj.url = absoluteUrl.href;
+ }
+ resultObj.unsafeUrl = url;
+ }
+ if (dest) {
+ if (dest instanceof Name) {
+ dest = dest.name;
+ }
+ if (typeof dest === "string") {
+ resultObj.dest = stringToPDFString(dest);
+ } else if (Array.isArray(dest)) {
+ resultObj.dest = dest;
+ }
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/object_loader.js
+
+
+
+
+function mayHaveChildren(value) {
+ return value instanceof Ref || value instanceof Dict || value instanceof BaseStream || Array.isArray(value);
+}
+function addChildren(node, nodesToVisit) {
+ if (node instanceof Dict) {
+ node = node.getRawValues();
+ } else if (node instanceof BaseStream) {
+ node = node.dict.getRawValues();
+ } else if (!Array.isArray(node)) {
+ return;
+ }
+ for (const rawValue of node) {
+ if (mayHaveChildren(rawValue)) {
+ nodesToVisit.push(rawValue);
+ }
+ }
+}
+class ObjectLoader {
+ constructor(dict, keys, xref) {
+ this.dict = dict;
+ this.keys = keys;
+ this.xref = xref;
+ this.refSet = null;
+ }
+ async load() {
+ if (this.xref.stream.isDataLoaded) {
+ return undefined;
+ }
+ const {
+ keys,
+ dict
+ } = this;
+ this.refSet = new RefSet();
+ const nodesToVisit = [];
+ for (const key of keys) {
+ const rawValue = dict.getRaw(key);
+ if (rawValue !== undefined) {
+ nodesToVisit.push(rawValue);
+ }
+ }
+ return this._walk(nodesToVisit);
+ }
+ async _walk(nodesToVisit) {
+ const nodesToRevisit = [];
+ const pendingRequests = [];
+ while (nodesToVisit.length) {
+ let currentNode = nodesToVisit.pop();
+ if (currentNode instanceof Ref) {
+ if (this.refSet.has(currentNode)) {
+ continue;
+ }
+ try {
+ this.refSet.put(currentNode);
+ currentNode = this.xref.fetch(currentNode);
+ } catch (ex) {
+ if (!(ex instanceof MissingDataException)) {
+ warn(`ObjectLoader._walk - requesting all data: "${ex}".`);
+ this.refSet = null;
+ const {
+ manager
+ } = this.xref.stream;
+ return manager.requestAllChunks();
+ }
+ nodesToRevisit.push(currentNode);
+ pendingRequests.push({
+ begin: ex.begin,
+ end: ex.end
+ });
+ }
+ }
+ if (currentNode instanceof BaseStream) {
+ const baseStreams = currentNode.getBaseStreams();
+ if (baseStreams) {
+ let foundMissingData = false;
+ for (const stream of baseStreams) {
+ if (stream.isDataLoaded) {
+ continue;
+ }
+ foundMissingData = true;
+ pendingRequests.push({
+ begin: stream.start,
+ end: stream.end
+ });
+ }
+ if (foundMissingData) {
+ nodesToRevisit.push(currentNode);
+ }
+ }
+ }
+ addChildren(currentNode, nodesToVisit);
+ }
+ if (pendingRequests.length) {
+ await this.xref.stream.manager.requestRanges(pendingRequests);
+ for (const node of nodesToRevisit) {
+ if (node instanceof Ref) {
+ this.refSet.remove(node);
+ }
+ }
+ return this._walk(nodesToRevisit);
+ }
+ this.refSet = null;
+ return undefined;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/symbol_utils.js
+const $acceptWhitespace = Symbol();
+const $addHTML = Symbol();
+const $appendChild = Symbol();
+const $childrenToHTML = Symbol();
+const $clean = Symbol();
+const $cleanPage = Symbol();
+const $cleanup = Symbol();
+const $clone = Symbol();
+const $consumed = Symbol();
+const $content = Symbol("content");
+const $data = Symbol("data");
+const $dump = Symbol();
+const $extra = Symbol("extra");
+const $finalize = Symbol();
+const $flushHTML = Symbol();
+const $getAttributeIt = Symbol();
+const $getAttributes = Symbol();
+const $getAvailableSpace = Symbol();
+const $getChildrenByClass = Symbol();
+const $getChildrenByName = Symbol();
+const $getChildrenByNameIt = Symbol();
+const $getDataValue = Symbol();
+const $getExtra = Symbol();
+const $getRealChildrenByNameIt = Symbol();
+const $getChildren = Symbol();
+const $getContainedChildren = Symbol();
+const $getNextPage = Symbol();
+const $getSubformParent = Symbol();
+const $getParent = Symbol();
+const $getTemplateRoot = Symbol();
+const $globalData = Symbol();
+const $hasSettableValue = Symbol();
+const $ids = Symbol();
+const $indexOf = Symbol();
+const $insertAt = Symbol();
+const $isCDATAXml = Symbol();
+const $isBindable = Symbol();
+const $isDataValue = Symbol();
+const $isDescendent = Symbol();
+const $isNsAgnostic = Symbol();
+const $isSplittable = Symbol();
+const $isThereMoreWidth = Symbol();
+const $isTransparent = Symbol();
+const $isUsable = Symbol();
+const $lastAttribute = Symbol();
+const $namespaceId = Symbol("namespaceId");
+const $nodeName = Symbol("nodeName");
+const $nsAttributes = Symbol();
+const $onChild = Symbol();
+const $onChildCheck = Symbol();
+const $onText = Symbol();
+const $pushGlyphs = Symbol();
+const $popPara = Symbol();
+const $pushPara = Symbol();
+const $removeChild = Symbol();
+const $root = Symbol("root");
+const $resolvePrototypes = Symbol();
+const $searchNode = Symbol();
+const $setId = Symbol();
+const $setSetAttributes = Symbol();
+const $setValue = Symbol();
+const $tabIndex = Symbol();
+const $text = Symbol();
+const $toPages = Symbol();
+const $toHTML = Symbol();
+const $toString = Symbol();
+const $toStyle = Symbol();
+const $uid = Symbol("uid");
+
+;// CONCATENATED MODULE: ./src/core/xfa/namespaces.js
+const $buildXFAObject = Symbol();
+const NamespaceIds = {
+ config: {
+ id: 0,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xci/")
+ },
+ connectionSet: {
+ id: 1,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-connection-set/")
+ },
+ datasets: {
+ id: 2,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-data/")
+ },
+ form: {
+ id: 3,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-form/")
+ },
+ localeSet: {
+ id: 4,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-locale-set/")
+ },
+ pdf: {
+ id: 5,
+ check: ns => ns === "http://ns.adobe.com/xdp/pdf/"
+ },
+ signature: {
+ id: 6,
+ check: ns => ns === "http://www.w3.org/2000/09/xmldsig#"
+ },
+ sourceSet: {
+ id: 7,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-source-set/")
+ },
+ stylesheet: {
+ id: 8,
+ check: ns => ns === "http://www.w3.org/1999/XSL/Transform"
+ },
+ template: {
+ id: 9,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-template/")
+ },
+ xdc: {
+ id: 10,
+ check: ns => ns.startsWith("http://www.xfa.org/schema/xdc/")
+ },
+ xdp: {
+ id: 11,
+ check: ns => ns === "http://ns.adobe.com/xdp/"
+ },
+ xfdf: {
+ id: 12,
+ check: ns => ns === "http://ns.adobe.com/xfdf/"
+ },
+ xhtml: {
+ id: 13,
+ check: ns => ns === "http://www.w3.org/1999/xhtml"
+ },
+ xmpmeta: {
+ id: 14,
+ check: ns => ns === "http://ns.adobe.com/xmpmeta/"
+ }
+};
+
+;// CONCATENATED MODULE: ./src/core/xfa/utils.js
+
+const dimConverters = {
+ pt: x => x,
+ cm: x => x / 2.54 * 72,
+ mm: x => x / (10 * 2.54) * 72,
+ in: x => x * 72,
+ px: x => x
+};
+const measurementPattern = /([+-]?\d+\.?\d*)(.*)/;
+function stripQuotes(str) {
+ if (str.startsWith("'") || str.startsWith('"')) {
+ return str.slice(1, -1);
+ }
+ return str;
+}
+function getInteger({
+ data,
+ defaultValue,
+ validate
+}) {
+ if (!data) {
+ return defaultValue;
+ }
+ data = data.trim();
+ const n = parseInt(data, 10);
+ if (!isNaN(n) && validate(n)) {
+ return n;
+ }
+ return defaultValue;
+}
+function getFloat({
+ data,
+ defaultValue,
+ validate
+}) {
+ if (!data) {
+ return defaultValue;
+ }
+ data = data.trim();
+ const n = parseFloat(data);
+ if (!isNaN(n) && validate(n)) {
+ return n;
+ }
+ return defaultValue;
+}
+function getKeyword({
+ data,
+ defaultValue,
+ validate
+}) {
+ if (!data) {
+ return defaultValue;
+ }
+ data = data.trim();
+ if (validate(data)) {
+ return data;
+ }
+ return defaultValue;
+}
+function getStringOption(data, options) {
+ return getKeyword({
+ data,
+ defaultValue: options[0],
+ validate: k => options.includes(k)
+ });
+}
+function getMeasurement(str, def = "0") {
+ def ||= "0";
+ if (!str) {
+ return getMeasurement(def);
+ }
+ const match = str.trim().match(measurementPattern);
+ if (!match) {
+ return getMeasurement(def);
+ }
+ const [, valueStr, unit] = match;
+ const value = parseFloat(valueStr);
+ if (isNaN(value)) {
+ return getMeasurement(def);
+ }
+ if (value === 0) {
+ return 0;
+ }
+ const conv = dimConverters[unit];
+ if (conv) {
+ return conv(value);
+ }
+ return value;
+}
+function getRatio(data) {
+ if (!data) {
+ return {
+ num: 1,
+ den: 1
+ };
+ }
+ const ratio = data.trim().split(/\s*:\s*/).map(x => parseFloat(x)).filter(x => !isNaN(x));
+ if (ratio.length === 1) {
+ ratio.push(1);
+ }
+ if (ratio.length === 0) {
+ return {
+ num: 1,
+ den: 1
+ };
+ }
+ const [num, den] = ratio;
+ return {
+ num,
+ den
+ };
+}
+function getRelevant(data) {
+ if (!data) {
+ return [];
+ }
+ return data.trim().split(/\s+/).map(e => {
+ return {
+ excluded: e[0] === "-",
+ viewname: e.substring(1)
+ };
+ });
+}
+function getColor(data, def = [0, 0, 0]) {
+ let [r, g, b] = def;
+ if (!data) {
+ return {
+ r,
+ g,
+ b
+ };
+ }
+ const color = data.trim().split(/\s*,\s*/).map(c => Math.min(Math.max(0, parseInt(c.trim(), 10)), 255)).map(c => isNaN(c) ? 0 : c);
+ if (color.length < 3) {
+ return {
+ r,
+ g,
+ b
+ };
+ }
+ [r, g, b] = color;
+ return {
+ r,
+ g,
+ b
+ };
+}
+function getBBox(data) {
+ const def = -1;
+ if (!data) {
+ return {
+ x: def,
+ y: def,
+ width: def,
+ height: def
+ };
+ }
+ const bbox = data.trim().split(/\s*,\s*/).map(m => getMeasurement(m, "-1"));
+ if (bbox.length < 4 || bbox[2] < 0 || bbox[3] < 0) {
+ return {
+ x: def,
+ y: def,
+ width: def,
+ height: def
+ };
+ }
+ const [x, y, width, height] = bbox;
+ return {
+ x,
+ y,
+ width,
+ height
+ };
+}
+class HTMLResult {
+ static get FAILURE() {
+ return shadow(this, "FAILURE", new HTMLResult(false, null, null, null));
+ }
+ static get EMPTY() {
+ return shadow(this, "EMPTY", new HTMLResult(true, null, null, null));
+ }
+ constructor(success, html, bbox, breakNode) {
+ this.success = success;
+ this.html = html;
+ this.bbox = bbox;
+ this.breakNode = breakNode;
+ }
+ isBreak() {
+ return !!this.breakNode;
+ }
+ static breakNode(node) {
+ return new HTMLResult(false, null, null, node);
+ }
+ static success(html, bbox = null) {
+ return new HTMLResult(true, html, bbox, null);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/fonts.js
+
+
+
+class FontFinder {
+ constructor(pdfFonts) {
+ this.fonts = new Map();
+ this.cache = new Map();
+ this.warned = new Set();
+ this.defaultFont = null;
+ this.add(pdfFonts);
+ }
+ add(pdfFonts, reallyMissingFonts = null) {
+ for (const pdfFont of pdfFonts) {
+ this.addPdfFont(pdfFont);
+ }
+ for (const pdfFont of this.fonts.values()) {
+ if (!pdfFont.regular) {
+ pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic;
+ }
+ }
+ if (!reallyMissingFonts || reallyMissingFonts.size === 0) {
+ return;
+ }
+ const myriad = this.fonts.get("PdfJS-Fallback-PdfJS-XFA");
+ for (const missing of reallyMissingFonts) {
+ this.fonts.set(missing, myriad);
+ }
+ }
+ addPdfFont(pdfFont) {
+ const cssFontInfo = pdfFont.cssFontInfo;
+ const name = cssFontInfo.fontFamily;
+ let font = this.fonts.get(name);
+ if (!font) {
+ font = Object.create(null);
+ this.fonts.set(name, font);
+ if (!this.defaultFont) {
+ this.defaultFont = font;
+ }
+ }
+ let property = "";
+ const fontWeight = parseFloat(cssFontInfo.fontWeight);
+ if (parseFloat(cssFontInfo.italicAngle) !== 0) {
+ property = fontWeight >= 700 ? "bolditalic" : "italic";
+ } else if (fontWeight >= 700) {
+ property = "bold";
+ }
+ if (!property) {
+ if (pdfFont.name.includes("Bold") || pdfFont.psName?.includes("Bold")) {
+ property = "bold";
+ }
+ if (pdfFont.name.includes("Italic") || pdfFont.name.endsWith("It") || pdfFont.psName?.includes("Italic") || pdfFont.psName?.endsWith("It")) {
+ property += "italic";
+ }
+ }
+ if (!property) {
+ property = "regular";
+ }
+ font[property] = pdfFont;
+ }
+ getDefault() {
+ return this.defaultFont;
+ }
+ find(fontName, mustWarn = true) {
+ let font = this.fonts.get(fontName) || this.cache.get(fontName);
+ if (font) {
+ return font;
+ }
+ const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi;
+ let name = fontName.replaceAll(pattern, "");
+ font = this.fonts.get(name);
+ if (font) {
+ this.cache.set(fontName, font);
+ return font;
+ }
+ name = name.toLowerCase();
+ const maybe = [];
+ for (const [family, pdfFont] of this.fonts.entries()) {
+ if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) {
+ maybe.push(pdfFont);
+ }
+ }
+ if (maybe.length === 0) {
+ for (const [, pdfFont] of this.fonts.entries()) {
+ if (pdfFont.regular.name?.replaceAll(pattern, "").toLowerCase().startsWith(name)) {
+ maybe.push(pdfFont);
+ }
+ }
+ }
+ if (maybe.length === 0) {
+ name = name.replaceAll(/psmt|mt/gi, "");
+ for (const [family, pdfFont] of this.fonts.entries()) {
+ if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) {
+ maybe.push(pdfFont);
+ }
+ }
+ }
+ if (maybe.length === 0) {
+ for (const pdfFont of this.fonts.values()) {
+ if (pdfFont.regular.name?.replaceAll(pattern, "").toLowerCase().startsWith(name)) {
+ maybe.push(pdfFont);
+ }
+ }
+ }
+ if (maybe.length >= 1) {
+ if (maybe.length !== 1 && mustWarn) {
+ warn(`XFA - Too many choices to guess the correct font: ${fontName}`);
+ }
+ this.cache.set(fontName, maybe[0]);
+ return maybe[0];
+ }
+ if (mustWarn && !this.warned.has(fontName)) {
+ this.warned.add(fontName);
+ warn(`XFA - Cannot find the font: ${fontName}`);
+ }
+ return null;
+ }
+}
+function selectFont(xfaFont, typeface) {
+ if (xfaFont.posture === "italic") {
+ if (xfaFont.weight === "bold") {
+ return typeface.bolditalic;
+ }
+ return typeface.italic;
+ } else if (xfaFont.weight === "bold") {
+ return typeface.bold;
+ }
+ return typeface.regular;
+}
+function fonts_getMetrics(xfaFont, real = false) {
+ let pdfFont = null;
+ if (xfaFont) {
+ const name = stripQuotes(xfaFont.typeface);
+ const typeface = xfaFont[$globalData].fontFinder.find(name);
+ pdfFont = selectFont(xfaFont, typeface);
+ }
+ if (!pdfFont) {
+ return {
+ lineHeight: 12,
+ lineGap: 2,
+ lineNoGap: 10
+ };
+ }
+ const size = xfaFont.size || 10;
+ const lineHeight = pdfFont.lineHeight ? Math.max(real ? 0 : 1.2, pdfFont.lineHeight) : 1.2;
+ const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap;
+ return {
+ lineHeight: lineHeight * size,
+ lineGap: lineGap * size,
+ lineNoGap: Math.max(1, lineHeight - lineGap) * size
+ };
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/text.js
+
+const WIDTH_FACTOR = 1.02;
+class FontInfo {
+ constructor(xfaFont, margin, lineHeight, fontFinder) {
+ this.lineHeight = lineHeight;
+ this.paraMargin = margin || {
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0
+ };
+ if (!xfaFont) {
+ [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
+ return;
+ }
+ this.xfaFont = {
+ typeface: xfaFont.typeface,
+ posture: xfaFont.posture,
+ weight: xfaFont.weight,
+ size: xfaFont.size,
+ letterSpacing: xfaFont.letterSpacing
+ };
+ const typeface = fontFinder.find(xfaFont.typeface);
+ if (!typeface) {
+ [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
+ return;
+ }
+ this.pdfFont = selectFont(xfaFont, typeface);
+ if (!this.pdfFont) {
+ [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
+ }
+ }
+ defaultFont(fontFinder) {
+ const font = fontFinder.find("Helvetica", false) || fontFinder.find("Myriad Pro", false) || fontFinder.find("Arial", false) || fontFinder.getDefault();
+ if (font?.regular) {
+ const pdfFont = font.regular;
+ const info = pdfFont.cssFontInfo;
+ const xfaFont = {
+ typeface: info.fontFamily,
+ posture: "normal",
+ weight: "normal",
+ size: 10,
+ letterSpacing: 0
+ };
+ return [pdfFont, xfaFont];
+ }
+ const xfaFont = {
+ typeface: "Courier",
+ posture: "normal",
+ weight: "normal",
+ size: 10,
+ letterSpacing: 0
+ };
+ return [null, xfaFont];
+ }
+}
+class FontSelector {
+ constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder) {
+ this.fontFinder = fontFinder;
+ this.stack = [new FontInfo(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder)];
+ }
+ pushData(xfaFont, margin, lineHeight) {
+ const lastFont = this.stack.at(-1);
+ for (const name of ["typeface", "posture", "weight", "size", "letterSpacing"]) {
+ if (!xfaFont[name]) {
+ xfaFont[name] = lastFont.xfaFont[name];
+ }
+ }
+ for (const name of ["top", "bottom", "left", "right"]) {
+ if (isNaN(margin[name])) {
+ margin[name] = lastFont.paraMargin[name];
+ }
+ }
+ const fontInfo = new FontInfo(xfaFont, margin, lineHeight || lastFont.lineHeight, this.fontFinder);
+ if (!fontInfo.pdfFont) {
+ fontInfo.pdfFont = lastFont.pdfFont;
+ }
+ this.stack.push(fontInfo);
+ }
+ popFont() {
+ this.stack.pop();
+ }
+ topFont() {
+ return this.stack.at(-1);
+ }
+}
+class TextMeasure {
+ constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts) {
+ this.glyphs = [];
+ this.fontSelector = new FontSelector(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts);
+ this.extraHeight = 0;
+ }
+ pushData(xfaFont, margin, lineHeight) {
+ this.fontSelector.pushData(xfaFont, margin, lineHeight);
+ }
+ popFont(xfaFont) {
+ return this.fontSelector.popFont();
+ }
+ addPara() {
+ const lastFont = this.fontSelector.topFont();
+ this.extraHeight += lastFont.paraMargin.top + lastFont.paraMargin.bottom;
+ }
+ addString(str) {
+ if (!str) {
+ return;
+ }
+ const lastFont = this.fontSelector.topFont();
+ const fontSize = lastFont.xfaFont.size;
+ if (lastFont.pdfFont) {
+ const letterSpacing = lastFont.xfaFont.letterSpacing;
+ const pdfFont = lastFont.pdfFont;
+ const fontLineHeight = pdfFont.lineHeight || 1.2;
+ const lineHeight = lastFont.lineHeight || Math.max(1.2, fontLineHeight) * fontSize;
+ const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap;
+ const noGap = fontLineHeight - lineGap;
+ const firstLineHeight = Math.max(1, noGap) * fontSize;
+ const scale = fontSize / 1000;
+ const fallbackWidth = pdfFont.defaultWidth || pdfFont.charsToGlyphs(" ")[0].width;
+ for (const line of str.split(/[\u2029\n]/)) {
+ const encodedLine = pdfFont.encodeString(line).join("");
+ const glyphs = pdfFont.charsToGlyphs(encodedLine);
+ for (const glyph of glyphs) {
+ const width = glyph.width || fallbackWidth;
+ this.glyphs.push([width * scale + letterSpacing, lineHeight, firstLineHeight, glyph.unicode, false]);
+ }
+ this.glyphs.push([0, 0, 0, "\n", true]);
+ }
+ this.glyphs.pop();
+ return;
+ }
+ for (const line of str.split(/[\u2029\n]/)) {
+ for (const char of line.split("")) {
+ this.glyphs.push([fontSize, 1.2 * fontSize, fontSize, char, false]);
+ }
+ this.glyphs.push([0, 0, 0, "\n", true]);
+ }
+ this.glyphs.pop();
+ }
+ compute(maxWidth) {
+ let lastSpacePos = -1,
+ lastSpaceWidth = 0,
+ width = 0,
+ height = 0,
+ currentLineWidth = 0,
+ currentLineHeight = 0;
+ let isBroken = false;
+ let isFirstLine = true;
+ for (let i = 0, ii = this.glyphs.length; i < ii; i++) {
+ const [glyphWidth, lineHeight, firstLineHeight, char, isEOL] = this.glyphs[i];
+ const isSpace = char === " ";
+ const glyphHeight = isFirstLine ? firstLineHeight : lineHeight;
+ if (isEOL) {
+ width = Math.max(width, currentLineWidth);
+ currentLineWidth = 0;
+ height += currentLineHeight;
+ currentLineHeight = glyphHeight;
+ lastSpacePos = -1;
+ lastSpaceWidth = 0;
+ isFirstLine = false;
+ continue;
+ }
+ if (isSpace) {
+ if (currentLineWidth + glyphWidth > maxWidth) {
+ width = Math.max(width, currentLineWidth);
+ currentLineWidth = 0;
+ height += currentLineHeight;
+ currentLineHeight = glyphHeight;
+ lastSpacePos = -1;
+ lastSpaceWidth = 0;
+ isBroken = true;
+ isFirstLine = false;
+ } else {
+ currentLineHeight = Math.max(glyphHeight, currentLineHeight);
+ lastSpaceWidth = currentLineWidth;
+ currentLineWidth += glyphWidth;
+ lastSpacePos = i;
+ }
+ continue;
+ }
+ if (currentLineWidth + glyphWidth > maxWidth) {
+ height += currentLineHeight;
+ currentLineHeight = glyphHeight;
+ if (lastSpacePos !== -1) {
+ i = lastSpacePos;
+ width = Math.max(width, lastSpaceWidth);
+ currentLineWidth = 0;
+ lastSpacePos = -1;
+ lastSpaceWidth = 0;
+ } else {
+ width = Math.max(width, currentLineWidth);
+ currentLineWidth = glyphWidth;
+ }
+ isBroken = true;
+ isFirstLine = false;
+ continue;
+ }
+ currentLineWidth += glyphWidth;
+ currentLineHeight = Math.max(glyphHeight, currentLineHeight);
+ }
+ width = Math.max(width, currentLineWidth);
+ height += currentLineHeight + this.extraHeight;
+ return {
+ width: WIDTH_FACTOR * width,
+ height,
+ isBroken
+ };
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/som.js
+
+
+const namePattern = /^[^.[]+/;
+const indexPattern = /^[^\]]+/;
+const operators = {
+ dot: 0,
+ dotDot: 1,
+ dotHash: 2,
+ dotBracket: 3,
+ dotParen: 4
+};
+const shortcuts = new Map([["$data", (root, current) => root.datasets ? root.datasets.data : root], ["$record", (root, current) => (root.datasets ? root.datasets.data : root)[$getChildren]()[0]], ["$template", (root, current) => root.template], ["$connectionSet", (root, current) => root.connectionSet], ["$form", (root, current) => root.form], ["$layout", (root, current) => root.layout], ["$host", (root, current) => root.host], ["$dataWindow", (root, current) => root.dataWindow], ["$event", (root, current) => root.event], ["!", (root, current) => root.datasets], ["$xfa", (root, current) => root], ["xfa", (root, current) => root], ["$", (root, current) => current]]);
+const somCache = new WeakMap();
+function parseIndex(index) {
+ index = index.trim();
+ if (index === "*") {
+ return Infinity;
+ }
+ return parseInt(index, 10) || 0;
+}
+function parseExpression(expr, dotDotAllowed, noExpr = true) {
+ let match = expr.match(namePattern);
+ if (!match) {
+ return null;
+ }
+ let [name] = match;
+ const parsed = [{
+ name,
+ cacheName: "." + name,
+ index: 0,
+ js: null,
+ formCalc: null,
+ operator: operators.dot
+ }];
+ let pos = name.length;
+ while (pos < expr.length) {
+ const spos = pos;
+ const char = expr.charAt(pos++);
+ if (char === "[") {
+ match = expr.slice(pos).match(indexPattern);
+ if (!match) {
+ warn("XFA - Invalid index in SOM expression");
+ return null;
+ }
+ parsed.at(-1).index = parseIndex(match[0]);
+ pos += match[0].length + 1;
+ continue;
+ }
+ let operator;
+ switch (expr.charAt(pos)) {
+ case ".":
+ if (!dotDotAllowed) {
+ return null;
+ }
+ pos++;
+ operator = operators.dotDot;
+ break;
+ case "#":
+ pos++;
+ operator = operators.dotHash;
+ break;
+ case "[":
+ if (noExpr) {
+ warn("XFA - SOM expression contains a FormCalc subexpression which is not supported for now.");
+ return null;
+ }
+ operator = operators.dotBracket;
+ break;
+ case "(":
+ if (noExpr) {
+ warn("XFA - SOM expression contains a JavaScript subexpression which is not supported for now.");
+ return null;
+ }
+ operator = operators.dotParen;
+ break;
+ default:
+ operator = operators.dot;
+ break;
+ }
+ match = expr.slice(pos).match(namePattern);
+ if (!match) {
+ break;
+ }
+ [name] = match;
+ pos += name.length;
+ parsed.push({
+ name,
+ cacheName: expr.slice(spos, pos),
+ operator,
+ index: 0,
+ js: null,
+ formCalc: null
+ });
+ }
+ return parsed;
+}
+function searchNode(root, container, expr, dotDotAllowed = true, useCache = true) {
+ const parsed = parseExpression(expr, dotDotAllowed);
+ if (!parsed) {
+ return null;
+ }
+ const fn = shortcuts.get(parsed[0].name);
+ let i = 0;
+ let isQualified;
+ if (fn) {
+ isQualified = true;
+ root = [fn(root, container)];
+ i = 1;
+ } else {
+ isQualified = container === null;
+ root = [container || root];
+ }
+ for (let ii = parsed.length; i < ii; i++) {
+ const {
+ name,
+ cacheName,
+ operator,
+ index
+ } = parsed[i];
+ const nodes = [];
+ for (const node of root) {
+ if (!node.isXFAObject) {
+ continue;
+ }
+ let children, cached;
+ if (useCache) {
+ cached = somCache.get(node);
+ if (!cached) {
+ cached = new Map();
+ somCache.set(node, cached);
+ }
+ children = cached.get(cacheName);
+ }
+ if (!children) {
+ switch (operator) {
+ case operators.dot:
+ children = node[$getChildrenByName](name, false);
+ break;
+ case operators.dotDot:
+ children = node[$getChildrenByName](name, true);
+ break;
+ case operators.dotHash:
+ children = node[$getChildrenByClass](name);
+ children = children.isXFAObjectArray ? children.children : [children];
+ break;
+ default:
+ break;
+ }
+ if (useCache) {
+ cached.set(cacheName, children);
+ }
+ }
+ if (children.length > 0) {
+ nodes.push(children);
+ }
+ }
+ if (nodes.length === 0 && !isQualified && i === 0) {
+ const parent = container[$getParent]();
+ container = parent;
+ if (!container) {
+ return null;
+ }
+ i = -1;
+ root = [container];
+ continue;
+ }
+ root = isFinite(index) ? nodes.filter(node => index < node.length).map(node => node[index]) : nodes.flat();
+ }
+ if (root.length === 0) {
+ return null;
+ }
+ return root;
+}
+function createDataNode(root, container, expr) {
+ const parsed = parseExpression(expr);
+ if (!parsed) {
+ return null;
+ }
+ if (parsed.some(x => x.operator === operators.dotDot)) {
+ return null;
+ }
+ const fn = shortcuts.get(parsed[0].name);
+ let i = 0;
+ if (fn) {
+ root = fn(root, container);
+ i = 1;
+ } else {
+ root = container || root;
+ }
+ for (let ii = parsed.length; i < ii; i++) {
+ const {
+ name,
+ operator,
+ index
+ } = parsed[i];
+ if (!isFinite(index)) {
+ parsed[i].index = 0;
+ return root.createNodes(parsed.slice(i));
+ }
+ let children;
+ switch (operator) {
+ case operators.dot:
+ children = root[$getChildrenByName](name, false);
+ break;
+ case operators.dotDot:
+ children = root[$getChildrenByName](name, true);
+ break;
+ case operators.dotHash:
+ children = root[$getChildrenByClass](name);
+ children = children.isXFAObjectArray ? children.children : [children];
+ break;
+ default:
+ break;
+ }
+ if (children.length === 0) {
+ return root.createNodes(parsed.slice(i));
+ }
+ if (index < children.length) {
+ const child = children[index];
+ if (!child.isXFAObject) {
+ warn(`XFA - Cannot create a node.`);
+ return null;
+ }
+ root = child;
+ } else {
+ parsed[i].index = index - children.length;
+ return root.createNodes(parsed.slice(i));
+ }
+ }
+ return null;
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/xfa_object.js
+
+
+
+
+
+
+const _applyPrototype = Symbol();
+const _attributes = Symbol();
+const _attributeNames = Symbol();
+const _children = Symbol("_children");
+const _cloneAttribute = Symbol();
+const _dataValue = Symbol();
+const _defaultValue = Symbol();
+const _filteredChildrenGenerator = Symbol();
+const _getPrototype = Symbol();
+const _getUnsetAttributes = Symbol();
+const _hasChildren = Symbol();
+const _max = Symbol();
+const _options = Symbol();
+const _parent = Symbol("parent");
+const _resolvePrototypesHelper = Symbol();
+const _setAttributes = Symbol();
+const _validator = Symbol();
+let uid = 0;
+const NS_DATASETS = NamespaceIds.datasets.id;
+class XFAObject {
+ constructor(nsId, name, hasChildren = false) {
+ this[$namespaceId] = nsId;
+ this[$nodeName] = name;
+ this[_hasChildren] = hasChildren;
+ this[_parent] = null;
+ this[_children] = [];
+ this[$uid] = `${name}${uid++}`;
+ this[$globalData] = null;
+ }
+ get isXFAObject() {
+ return true;
+ }
+ get isXFAObjectArray() {
+ return false;
+ }
+ createNodes(path) {
+ let root = this,
+ node = null;
+ for (const {
+ name,
+ index
+ } of path) {
+ for (let i = 0, ii = isFinite(index) ? index : 0; i <= ii; i++) {
+ const nsId = root[$namespaceId] === NS_DATASETS ? -1 : root[$namespaceId];
+ node = new XmlObject(nsId, name);
+ root[$appendChild](node);
+ }
+ root = node;
+ }
+ return node;
+ }
+ [$onChild](child) {
+ if (!this[_hasChildren] || !this[$onChildCheck](child)) {
+ return false;
+ }
+ const name = child[$nodeName];
+ const node = this[name];
+ if (node instanceof XFAObjectArray) {
+ if (node.push(child)) {
+ this[$appendChild](child);
+ return true;
+ }
+ } else {
+ if (node !== null) {
+ this[$removeChild](node);
+ }
+ this[name] = child;
+ this[$appendChild](child);
+ return true;
+ }
+ let id = "";
+ if (this.id) {
+ id = ` (id: ${this.id})`;
+ } else if (this.name) {
+ id = ` (name: ${this.name} ${this.h.value})`;
+ }
+ warn(`XFA - node "${this[$nodeName]}"${id} has already enough "${name}"!`);
+ return false;
+ }
+ [$onChildCheck](child) {
+ return this.hasOwnProperty(child[$nodeName]) && child[$namespaceId] === this[$namespaceId];
+ }
+ [$isNsAgnostic]() {
+ return false;
+ }
+ [$acceptWhitespace]() {
+ return false;
+ }
+ [$isCDATAXml]() {
+ return false;
+ }
+ [$isBindable]() {
+ return false;
+ }
+ [$popPara]() {
+ if (this.para) {
+ this[$getTemplateRoot]()[$extra].paraStack.pop();
+ }
+ }
+ [$pushPara]() {
+ this[$getTemplateRoot]()[$extra].paraStack.push(this.para);
+ }
+ [$setId](ids) {
+ if (this.id && this[$namespaceId] === NamespaceIds.template.id) {
+ ids.set(this.id, this);
+ }
+ }
+ [$getTemplateRoot]() {
+ return this[$globalData].template;
+ }
+ [$isSplittable]() {
+ return false;
+ }
+ [$isThereMoreWidth]() {
+ return false;
+ }
+ [$appendChild](child) {
+ child[_parent] = this;
+ this[_children].push(child);
+ if (!child[$globalData] && this[$globalData]) {
+ child[$globalData] = this[$globalData];
+ }
+ }
+ [$removeChild](child) {
+ const i = this[_children].indexOf(child);
+ this[_children].splice(i, 1);
+ }
+ [$hasSettableValue]() {
+ return this.hasOwnProperty("value");
+ }
+ [$setValue](_) {}
+ [$onText](_) {}
+ [$finalize]() {}
+ [$clean](builder) {
+ delete this[_hasChildren];
+ if (this[$cleanup]) {
+ builder.clean(this[$cleanup]);
+ delete this[$cleanup];
+ }
+ }
+ [$indexOf](child) {
+ return this[_children].indexOf(child);
+ }
+ [$insertAt](i, child) {
+ child[_parent] = this;
+ this[_children].splice(i, 0, child);
+ if (!child[$globalData] && this[$globalData]) {
+ child[$globalData] = this[$globalData];
+ }
+ }
+ [$isTransparent]() {
+ return !this.name;
+ }
+ [$lastAttribute]() {
+ return "";
+ }
+ [$text]() {
+ if (this[_children].length === 0) {
+ return this[$content];
+ }
+ return this[_children].map(c => c[$text]()).join("");
+ }
+ get [_attributeNames]() {
+ const proto = Object.getPrototypeOf(this);
+ if (!proto._attributes) {
+ const attributes = proto._attributes = new Set();
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (this[name] === null || this[name] instanceof XFAObject || this[name] instanceof XFAObjectArray) {
+ break;
+ }
+ attributes.add(name);
+ }
+ }
+ return shadow(this, _attributeNames, proto._attributes);
+ }
+ [$isDescendent](parent) {
+ let node = this;
+ while (node) {
+ if (node === parent) {
+ return true;
+ }
+ node = node[$getParent]();
+ }
+ return false;
+ }
+ [$getParent]() {
+ return this[_parent];
+ }
+ [$getSubformParent]() {
+ return this[$getParent]();
+ }
+ [$getChildren](name = null) {
+ if (!name) {
+ return this[_children];
+ }
+ return this[name];
+ }
+ [$dump]() {
+ const dumped = Object.create(null);
+ if (this[$content]) {
+ dumped.$content = this[$content];
+ }
+ for (const name of Object.getOwnPropertyNames(this)) {
+ const value = this[name];
+ if (value === null) {
+ continue;
+ }
+ if (value instanceof XFAObject) {
+ dumped[name] = value[$dump]();
+ } else if (value instanceof XFAObjectArray) {
+ if (!value.isEmpty()) {
+ dumped[name] = value.dump();
+ }
+ } else {
+ dumped[name] = value;
+ }
+ }
+ return dumped;
+ }
+ [$toStyle]() {
+ return null;
+ }
+ [$toHTML]() {
+ return HTMLResult.EMPTY;
+ }
+ *[$getContainedChildren]() {
+ for (const node of this[$getChildren]()) {
+ yield node;
+ }
+ }
+ *[_filteredChildrenGenerator](filter, include) {
+ for (const node of this[$getContainedChildren]()) {
+ if (!filter || include === filter.has(node[$nodeName])) {
+ const availableSpace = this[$getAvailableSpace]();
+ const res = node[$toHTML](availableSpace);
+ if (!res.success) {
+ this[$extra].failingNode = node;
+ }
+ yield res;
+ }
+ }
+ }
+ [$flushHTML]() {
+ return null;
+ }
+ [$addHTML](html, bbox) {
+ this[$extra].children.push(html);
+ }
+ [$getAvailableSpace]() {}
+ [$childrenToHTML]({
+ filter = null,
+ include = true
+ }) {
+ if (!this[$extra].generator) {
+ this[$extra].generator = this[_filteredChildrenGenerator](filter, include);
+ } else {
+ const availableSpace = this[$getAvailableSpace]();
+ const res = this[$extra].failingNode[$toHTML](availableSpace);
+ if (!res.success) {
+ return res;
+ }
+ if (res.html) {
+ this[$addHTML](res.html, res.bbox);
+ }
+ delete this[$extra].failingNode;
+ }
+ while (true) {
+ const gen = this[$extra].generator.next();
+ if (gen.done) {
+ break;
+ }
+ const res = gen.value;
+ if (!res.success) {
+ return res;
+ }
+ if (res.html) {
+ this[$addHTML](res.html, res.bbox);
+ }
+ }
+ this[$extra].generator = null;
+ return HTMLResult.EMPTY;
+ }
+ [$setSetAttributes](attributes) {
+ this[_setAttributes] = new Set(Object.keys(attributes));
+ }
+ [_getUnsetAttributes](protoAttributes) {
+ const allAttr = this[_attributeNames];
+ const setAttr = this[_setAttributes];
+ return [...protoAttributes].filter(x => allAttr.has(x) && !setAttr.has(x));
+ }
+ [$resolvePrototypes](ids, ancestors = new Set()) {
+ for (const child of this[_children]) {
+ child[_resolvePrototypesHelper](ids, ancestors);
+ }
+ }
+ [_resolvePrototypesHelper](ids, ancestors) {
+ const proto = this[_getPrototype](ids, ancestors);
+ if (proto) {
+ this[_applyPrototype](proto, ids, ancestors);
+ } else {
+ this[$resolvePrototypes](ids, ancestors);
+ }
+ }
+ [_getPrototype](ids, ancestors) {
+ const {
+ use,
+ usehref
+ } = this;
+ if (!use && !usehref) {
+ return null;
+ }
+ let proto = null;
+ let somExpression = null;
+ let id = null;
+ let ref = use;
+ if (usehref) {
+ ref = usehref;
+ if (usehref.startsWith("#som(") && usehref.endsWith(")")) {
+ somExpression = usehref.slice("#som(".length, -1);
+ } else if (usehref.startsWith(".#som(") && usehref.endsWith(")")) {
+ somExpression = usehref.slice(".#som(".length, -1);
+ } else if (usehref.startsWith("#")) {
+ id = usehref.slice(1);
+ } else if (usehref.startsWith(".#")) {
+ id = usehref.slice(2);
+ }
+ } else if (use.startsWith("#")) {
+ id = use.slice(1);
+ } else {
+ somExpression = use;
+ }
+ this.use = this.usehref = "";
+ if (id) {
+ proto = ids.get(id);
+ } else {
+ proto = searchNode(ids.get($root), this, somExpression, true, false);
+ if (proto) {
+ proto = proto[0];
+ }
+ }
+ if (!proto) {
+ warn(`XFA - Invalid prototype reference: ${ref}.`);
+ return null;
+ }
+ if (proto[$nodeName] !== this[$nodeName]) {
+ warn(`XFA - Incompatible prototype: ${proto[$nodeName]} !== ${this[$nodeName]}.`);
+ return null;
+ }
+ if (ancestors.has(proto)) {
+ warn(`XFA - Cycle detected in prototypes use.`);
+ return null;
+ }
+ ancestors.add(proto);
+ const protoProto = proto[_getPrototype](ids, ancestors);
+ if (protoProto) {
+ proto[_applyPrototype](protoProto, ids, ancestors);
+ }
+ proto[$resolvePrototypes](ids, ancestors);
+ ancestors.delete(proto);
+ return proto;
+ }
+ [_applyPrototype](proto, ids, ancestors) {
+ if (ancestors.has(proto)) {
+ warn(`XFA - Cycle detected in prototypes use.`);
+ return;
+ }
+ if (!this[$content] && proto[$content]) {
+ this[$content] = proto[$content];
+ }
+ const newAncestors = new Set(ancestors);
+ newAncestors.add(proto);
+ for (const unsetAttrName of this[_getUnsetAttributes](proto[_setAttributes])) {
+ this[unsetAttrName] = proto[unsetAttrName];
+ if (this[_setAttributes]) {
+ this[_setAttributes].add(unsetAttrName);
+ }
+ }
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (this[_attributeNames].has(name)) {
+ continue;
+ }
+ const value = this[name];
+ const protoValue = proto[name];
+ if (value instanceof XFAObjectArray) {
+ for (const child of value[_children]) {
+ child[_resolvePrototypesHelper](ids, ancestors);
+ }
+ for (let i = value[_children].length, ii = protoValue[_children].length; i < ii; i++) {
+ const child = proto[_children][i][$clone]();
+ if (value.push(child)) {
+ child[_parent] = this;
+ this[_children].push(child);
+ child[_resolvePrototypesHelper](ids, ancestors);
+ } else {
+ break;
+ }
+ }
+ continue;
+ }
+ if (value !== null) {
+ value[$resolvePrototypes](ids, ancestors);
+ if (protoValue) {
+ value[_applyPrototype](protoValue, ids, ancestors);
+ }
+ continue;
+ }
+ if (protoValue !== null) {
+ const child = protoValue[$clone]();
+ child[_parent] = this;
+ this[name] = child;
+ this[_children].push(child);
+ child[_resolvePrototypesHelper](ids, ancestors);
+ }
+ }
+ }
+ static [_cloneAttribute](obj) {
+ if (Array.isArray(obj)) {
+ return obj.map(x => XFAObject[_cloneAttribute](x));
+ }
+ if (typeof obj === "object" && obj !== null) {
+ return Object.assign({}, obj);
+ }
+ return obj;
+ }
+ [$clone]() {
+ const clone = Object.create(Object.getPrototypeOf(this));
+ for (const $symbol of Object.getOwnPropertySymbols(this)) {
+ try {
+ clone[$symbol] = this[$symbol];
+ } catch {
+ shadow(clone, $symbol, this[$symbol]);
+ }
+ }
+ clone[$uid] = `${clone[$nodeName]}${uid++}`;
+ clone[_children] = [];
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (this[_attributeNames].has(name)) {
+ clone[name] = XFAObject[_cloneAttribute](this[name]);
+ continue;
+ }
+ const value = this[name];
+ clone[name] = value instanceof XFAObjectArray ? new XFAObjectArray(value[_max]) : null;
+ }
+ for (const child of this[_children]) {
+ const name = child[$nodeName];
+ const clonedChild = child[$clone]();
+ clone[_children].push(clonedChild);
+ clonedChild[_parent] = clone;
+ if (clone[name] === null) {
+ clone[name] = clonedChild;
+ } else {
+ clone[name][_children].push(clonedChild);
+ }
+ }
+ return clone;
+ }
+ [$getChildren](name = null) {
+ if (!name) {
+ return this[_children];
+ }
+ return this[_children].filter(c => c[$nodeName] === name);
+ }
+ [$getChildrenByClass](name) {
+ return this[name];
+ }
+ [$getChildrenByName](name, allTransparent, first = true) {
+ return Array.from(this[$getChildrenByNameIt](name, allTransparent, first));
+ }
+ *[$getChildrenByNameIt](name, allTransparent, first = true) {
+ if (name === "parent") {
+ yield this[_parent];
+ return;
+ }
+ for (const child of this[_children]) {
+ if (child[$nodeName] === name) {
+ yield child;
+ }
+ if (child.name === name) {
+ yield child;
+ }
+ if (allTransparent || child[$isTransparent]()) {
+ yield* child[$getChildrenByNameIt](name, allTransparent, false);
+ }
+ }
+ if (first && this[_attributeNames].has(name)) {
+ yield new XFAAttribute(this, name, this[name]);
+ }
+ }
+}
+class XFAObjectArray {
+ constructor(max = Infinity) {
+ this[_max] = max;
+ this[_children] = [];
+ }
+ get isXFAObject() {
+ return false;
+ }
+ get isXFAObjectArray() {
+ return true;
+ }
+ push(child) {
+ const len = this[_children].length;
+ if (len <= this[_max]) {
+ this[_children].push(child);
+ return true;
+ }
+ warn(`XFA - node "${child[$nodeName]}" accepts no more than ${this[_max]} children`);
+ return false;
+ }
+ isEmpty() {
+ return this[_children].length === 0;
+ }
+ dump() {
+ return this[_children].length === 1 ? this[_children][0][$dump]() : this[_children].map(x => x[$dump]());
+ }
+ [$clone]() {
+ const clone = new XFAObjectArray(this[_max]);
+ clone[_children] = this[_children].map(c => c[$clone]());
+ return clone;
+ }
+ get children() {
+ return this[_children];
+ }
+ clear() {
+ this[_children].length = 0;
+ }
+}
+class XFAAttribute {
+ constructor(node, name, value) {
+ this[_parent] = node;
+ this[$nodeName] = name;
+ this[$content] = value;
+ this[$consumed] = false;
+ this[$uid] = `attribute${uid++}`;
+ }
+ [$getParent]() {
+ return this[_parent];
+ }
+ [$isDataValue]() {
+ return true;
+ }
+ [$getDataValue]() {
+ return this[$content].trim();
+ }
+ [$setValue](value) {
+ value = value.value || "";
+ this[$content] = value.toString();
+ }
+ [$text]() {
+ return this[$content];
+ }
+ [$isDescendent](parent) {
+ return this[_parent] === parent || this[_parent][$isDescendent](parent);
+ }
+}
+class XmlObject extends XFAObject {
+ constructor(nsId, name, attributes = {}) {
+ super(nsId, name);
+ this[$content] = "";
+ this[_dataValue] = null;
+ if (name !== "#text") {
+ const map = new Map();
+ this[_attributes] = map;
+ for (const [attrName, value] of Object.entries(attributes)) {
+ map.set(attrName, new XFAAttribute(this, attrName, value));
+ }
+ if (attributes.hasOwnProperty($nsAttributes)) {
+ const dataNode = attributes[$nsAttributes].xfa.dataNode;
+ if (dataNode !== undefined) {
+ if (dataNode === "dataGroup") {
+ this[_dataValue] = false;
+ } else if (dataNode === "dataValue") {
+ this[_dataValue] = true;
+ }
+ }
+ }
+ }
+ this[$consumed] = false;
+ }
+ [$toString](buf) {
+ const tagName = this[$nodeName];
+ if (tagName === "#text") {
+ buf.push(encodeToXmlString(this[$content]));
+ return;
+ }
+ const utf8TagName = utf8StringToString(tagName);
+ const prefix = this[$namespaceId] === NS_DATASETS ? "xfa:" : "";
+ buf.push(`<${prefix}${utf8TagName}`);
+ for (const [name, value] of this[_attributes].entries()) {
+ const utf8Name = utf8StringToString(name);
+ buf.push(` ${utf8Name}="${encodeToXmlString(value[$content])}"`);
+ }
+ if (this[_dataValue] !== null) {
+ if (this[_dataValue]) {
+ buf.push(` xfa:dataNode="dataValue"`);
+ } else {
+ buf.push(` xfa:dataNode="dataGroup"`);
+ }
+ }
+ if (!this[$content] && this[_children].length === 0) {
+ buf.push("/>");
+ return;
+ }
+ buf.push(">");
+ if (this[$content]) {
+ if (typeof this[$content] === "string") {
+ buf.push(encodeToXmlString(this[$content]));
+ } else {
+ this[$content][$toString](buf);
+ }
+ } else {
+ for (const child of this[_children]) {
+ child[$toString](buf);
+ }
+ }
+ buf.push(`${prefix}${utf8TagName}>`);
+ }
+ [$onChild](child) {
+ if (this[$content]) {
+ const node = new XmlObject(this[$namespaceId], "#text");
+ this[$appendChild](node);
+ node[$content] = this[$content];
+ this[$content] = "";
+ }
+ this[$appendChild](child);
+ return true;
+ }
+ [$onText](str) {
+ this[$content] += str;
+ }
+ [$finalize]() {
+ if (this[$content] && this[_children].length > 0) {
+ const node = new XmlObject(this[$namespaceId], "#text");
+ this[$appendChild](node);
+ node[$content] = this[$content];
+ delete this[$content];
+ }
+ }
+ [$toHTML]() {
+ if (this[$nodeName] === "#text") {
+ return HTMLResult.success({
+ name: "#text",
+ value: this[$content]
+ });
+ }
+ return HTMLResult.EMPTY;
+ }
+ [$getChildren](name = null) {
+ if (!name) {
+ return this[_children];
+ }
+ return this[_children].filter(c => c[$nodeName] === name);
+ }
+ [$getAttributes]() {
+ return this[_attributes];
+ }
+ [$getChildrenByClass](name) {
+ const value = this[_attributes].get(name);
+ if (value !== undefined) {
+ return value;
+ }
+ return this[$getChildren](name);
+ }
+ *[$getChildrenByNameIt](name, allTransparent) {
+ const value = this[_attributes].get(name);
+ if (value) {
+ yield value;
+ }
+ for (const child of this[_children]) {
+ if (child[$nodeName] === name) {
+ yield child;
+ }
+ if (allTransparent) {
+ yield* child[$getChildrenByNameIt](name, allTransparent);
+ }
+ }
+ }
+ *[$getAttributeIt](name, skipConsumed) {
+ const value = this[_attributes].get(name);
+ if (value && (!skipConsumed || !value[$consumed])) {
+ yield value;
+ }
+ for (const child of this[_children]) {
+ yield* child[$getAttributeIt](name, skipConsumed);
+ }
+ }
+ *[$getRealChildrenByNameIt](name, allTransparent, skipConsumed) {
+ for (const child of this[_children]) {
+ if (child[$nodeName] === name && (!skipConsumed || !child[$consumed])) {
+ yield child;
+ }
+ if (allTransparent) {
+ yield* child[$getRealChildrenByNameIt](name, allTransparent, skipConsumed);
+ }
+ }
+ }
+ [$isDataValue]() {
+ if (this[_dataValue] === null) {
+ return this[_children].length === 0 || this[_children][0][$namespaceId] === NamespaceIds.xhtml.id;
+ }
+ return this[_dataValue];
+ }
+ [$getDataValue]() {
+ if (this[_dataValue] === null) {
+ if (this[_children].length === 0) {
+ return this[$content].trim();
+ }
+ if (this[_children][0][$namespaceId] === NamespaceIds.xhtml.id) {
+ return this[_children][0][$text]().trim();
+ }
+ return null;
+ }
+ return this[$content].trim();
+ }
+ [$setValue](value) {
+ value = value.value || "";
+ this[$content] = value.toString();
+ }
+ [$dump](hasNS = false) {
+ const dumped = Object.create(null);
+ if (hasNS) {
+ dumped.$ns = this[$namespaceId];
+ }
+ if (this[$content]) {
+ dumped.$content = this[$content];
+ }
+ dumped.$name = this[$nodeName];
+ dumped.children = [];
+ for (const child of this[_children]) {
+ dumped.children.push(child[$dump](hasNS));
+ }
+ dumped.attributes = Object.create(null);
+ for (const [name, value] of this[_attributes]) {
+ dumped.attributes[name] = value[$content];
+ }
+ return dumped;
+ }
+}
+class ContentObject extends XFAObject {
+ constructor(nsId, name) {
+ super(nsId, name);
+ this[$content] = "";
+ }
+ [$onText](text) {
+ this[$content] += text;
+ }
+ [$finalize]() {}
+}
+class OptionObject extends ContentObject {
+ constructor(nsId, name, options) {
+ super(nsId, name);
+ this[_options] = options;
+ }
+ [$finalize]() {
+ this[$content] = getKeyword({
+ data: this[$content],
+ defaultValue: this[_options][0],
+ validate: k => this[_options].includes(k)
+ });
+ }
+ [$clean](builder) {
+ super[$clean](builder);
+ delete this[_options];
+ }
+}
+class StringObject extends ContentObject {
+ [$finalize]() {
+ this[$content] = this[$content].trim();
+ }
+}
+class IntegerObject extends ContentObject {
+ constructor(nsId, name, defaultValue, validator) {
+ super(nsId, name);
+ this[_defaultValue] = defaultValue;
+ this[_validator] = validator;
+ }
+ [$finalize]() {
+ this[$content] = getInteger({
+ data: this[$content],
+ defaultValue: this[_defaultValue],
+ validate: this[_validator]
+ });
+ }
+ [$clean](builder) {
+ super[$clean](builder);
+ delete this[_defaultValue];
+ delete this[_validator];
+ }
+}
+class Option01 extends IntegerObject {
+ constructor(nsId, name) {
+ super(nsId, name, 0, n => n === 1);
+ }
+}
+class Option10 extends IntegerObject {
+ constructor(nsId, name) {
+ super(nsId, name, 1, n => n === 0);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/html_utils.js
+
+
+
+
+
+
+function measureToString(m) {
+ if (typeof m === "string") {
+ return "0px";
+ }
+ return Number.isInteger(m) ? `${m}px` : `${m.toFixed(2)}px`;
+}
+const converters = {
+ anchorType(node, style) {
+ const parent = node[$getSubformParent]();
+ if (!parent || parent.layout && parent.layout !== "position") {
+ return;
+ }
+ if (!("transform" in style)) {
+ style.transform = "";
+ }
+ switch (node.anchorType) {
+ case "bottomCenter":
+ style.transform += "translate(-50%, -100%)";
+ break;
+ case "bottomLeft":
+ style.transform += "translate(0,-100%)";
+ break;
+ case "bottomRight":
+ style.transform += "translate(-100%,-100%)";
+ break;
+ case "middleCenter":
+ style.transform += "translate(-50%,-50%)";
+ break;
+ case "middleLeft":
+ style.transform += "translate(0,-50%)";
+ break;
+ case "middleRight":
+ style.transform += "translate(-100%,-50%)";
+ break;
+ case "topCenter":
+ style.transform += "translate(-50%,0)";
+ break;
+ case "topRight":
+ style.transform += "translate(-100%,0)";
+ break;
+ }
+ },
+ dimensions(node, style) {
+ const parent = node[$getSubformParent]();
+ let width = node.w;
+ const height = node.h;
+ if (parent.layout?.includes("row")) {
+ const extra = parent[$extra];
+ const colSpan = node.colSpan;
+ let w;
+ if (colSpan === -1) {
+ w = extra.columnWidths.slice(extra.currentColumn).reduce((a, x) => a + x, 0);
+ extra.currentColumn = 0;
+ } else {
+ w = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, x) => a + x, 0);
+ extra.currentColumn = (extra.currentColumn + node.colSpan) % extra.columnWidths.length;
+ }
+ if (!isNaN(w)) {
+ width = node.w = w;
+ }
+ }
+ style.width = width !== "" ? measureToString(width) : "auto";
+ style.height = height !== "" ? measureToString(height) : "auto";
+ },
+ position(node, style) {
+ const parent = node[$getSubformParent]();
+ if (parent?.layout && parent.layout !== "position") {
+ return;
+ }
+ style.position = "absolute";
+ style.left = measureToString(node.x);
+ style.top = measureToString(node.y);
+ },
+ rotate(node, style) {
+ if (node.rotate) {
+ if (!("transform" in style)) {
+ style.transform = "";
+ }
+ style.transform += `rotate(-${node.rotate}deg)`;
+ style.transformOrigin = "top left";
+ }
+ },
+ presence(node, style) {
+ switch (node.presence) {
+ case "invisible":
+ style.visibility = "hidden";
+ break;
+ case "hidden":
+ case "inactive":
+ style.display = "none";
+ break;
+ }
+ },
+ hAlign(node, style) {
+ if (node[$nodeName] === "para") {
+ switch (node.hAlign) {
+ case "justifyAll":
+ style.textAlign = "justify-all";
+ break;
+ case "radix":
+ style.textAlign = "left";
+ break;
+ default:
+ style.textAlign = node.hAlign;
+ }
+ } else {
+ switch (node.hAlign) {
+ case "left":
+ style.alignSelf = "start";
+ break;
+ case "center":
+ style.alignSelf = "center";
+ break;
+ case "right":
+ style.alignSelf = "end";
+ break;
+ }
+ }
+ },
+ margin(node, style) {
+ if (node.margin) {
+ style.margin = node.margin[$toStyle]().margin;
+ }
+ }
+};
+function setMinMaxDimensions(node, style) {
+ const parent = node[$getSubformParent]();
+ if (parent.layout === "position") {
+ if (node.minW > 0) {
+ style.minWidth = measureToString(node.minW);
+ }
+ if (node.maxW > 0) {
+ style.maxWidth = measureToString(node.maxW);
+ }
+ if (node.minH > 0) {
+ style.minHeight = measureToString(node.minH);
+ }
+ if (node.maxH > 0) {
+ style.maxHeight = measureToString(node.maxH);
+ }
+ }
+}
+function layoutText(text, xfaFont, margin, lineHeight, fontFinder, width) {
+ const measure = new TextMeasure(xfaFont, margin, lineHeight, fontFinder);
+ if (typeof text === "string") {
+ measure.addString(text);
+ } else {
+ text[$pushGlyphs](measure);
+ }
+ return measure.compute(width);
+}
+function layoutNode(node, availableSpace) {
+ let height = null;
+ let width = null;
+ let isBroken = false;
+ if ((!node.w || !node.h) && node.value) {
+ let marginH = 0;
+ let marginV = 0;
+ if (node.margin) {
+ marginH = node.margin.leftInset + node.margin.rightInset;
+ marginV = node.margin.topInset + node.margin.bottomInset;
+ }
+ let lineHeight = null;
+ let margin = null;
+ if (node.para) {
+ margin = Object.create(null);
+ lineHeight = node.para.lineHeight === "" ? null : node.para.lineHeight;
+ margin.top = node.para.spaceAbove === "" ? 0 : node.para.spaceAbove;
+ margin.bottom = node.para.spaceBelow === "" ? 0 : node.para.spaceBelow;
+ margin.left = node.para.marginLeft === "" ? 0 : node.para.marginLeft;
+ margin.right = node.para.marginRight === "" ? 0 : node.para.marginRight;
+ }
+ let font = node.font;
+ if (!font) {
+ const root = node[$getTemplateRoot]();
+ let parent = node[$getParent]();
+ while (parent && parent !== root) {
+ if (parent.font) {
+ font = parent.font;
+ break;
+ }
+ parent = parent[$getParent]();
+ }
+ }
+ const maxWidth = (node.w || availableSpace.width) - marginH;
+ const fontFinder = node[$globalData].fontFinder;
+ if (node.value.exData && node.value.exData[$content] && node.value.exData.contentType === "text/html") {
+ const res = layoutText(node.value.exData[$content], font, margin, lineHeight, fontFinder, maxWidth);
+ width = res.width;
+ height = res.height;
+ isBroken = res.isBroken;
+ } else {
+ const text = node.value[$text]();
+ if (text) {
+ const res = layoutText(text, font, margin, lineHeight, fontFinder, maxWidth);
+ width = res.width;
+ height = res.height;
+ isBroken = res.isBroken;
+ }
+ }
+ if (width !== null && !node.w) {
+ width += marginH;
+ }
+ if (height !== null && !node.h) {
+ height += marginV;
+ }
+ }
+ return {
+ w: width,
+ h: height,
+ isBroken
+ };
+}
+function computeBbox(node, html, availableSpace) {
+ let bbox;
+ if (node.w !== "" && node.h !== "") {
+ bbox = [node.x, node.y, node.w, node.h];
+ } else {
+ if (!availableSpace) {
+ return null;
+ }
+ let width = node.w;
+ if (width === "") {
+ if (node.maxW === 0) {
+ const parent = node[$getSubformParent]();
+ width = parent.layout === "position" && parent.w !== "" ? 0 : node.minW;
+ } else {
+ width = Math.min(node.maxW, availableSpace.width);
+ }
+ html.attributes.style.width = measureToString(width);
+ }
+ let height = node.h;
+ if (height === "") {
+ if (node.maxH === 0) {
+ const parent = node[$getSubformParent]();
+ height = parent.layout === "position" && parent.h !== "" ? 0 : node.minH;
+ } else {
+ height = Math.min(node.maxH, availableSpace.height);
+ }
+ html.attributes.style.height = measureToString(height);
+ }
+ bbox = [node.x, node.y, width, height];
+ }
+ return bbox;
+}
+function fixDimensions(node) {
+ const parent = node[$getSubformParent]();
+ if (parent.layout?.includes("row")) {
+ const extra = parent[$extra];
+ const colSpan = node.colSpan;
+ let width;
+ if (colSpan === -1) {
+ width = extra.columnWidths.slice(extra.currentColumn).reduce((a, w) => a + w, 0);
+ } else {
+ width = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, w) => a + w, 0);
+ }
+ if (!isNaN(width)) {
+ node.w = width;
+ }
+ }
+ if (parent.layout && parent.layout !== "position") {
+ node.x = node.y = 0;
+ }
+ if (node.layout === "table") {
+ if (node.w === "" && Array.isArray(node.columnWidths)) {
+ node.w = node.columnWidths.reduce((a, x) => a + x, 0);
+ }
+ }
+}
+function layoutClass(node) {
+ switch (node.layout) {
+ case "position":
+ return "xfaPosition";
+ case "lr-tb":
+ return "xfaLrTb";
+ case "rl-row":
+ return "xfaRlRow";
+ case "rl-tb":
+ return "xfaRlTb";
+ case "row":
+ return "xfaRow";
+ case "table":
+ return "xfaTable";
+ case "tb":
+ return "xfaTb";
+ default:
+ return "xfaPosition";
+ }
+}
+function toStyle(node, ...names) {
+ const style = Object.create(null);
+ for (const name of names) {
+ const value = node[name];
+ if (value === null) {
+ continue;
+ }
+ if (converters.hasOwnProperty(name)) {
+ converters[name](node, style);
+ continue;
+ }
+ if (value instanceof XFAObject) {
+ const newStyle = value[$toStyle]();
+ if (newStyle) {
+ Object.assign(style, newStyle);
+ } else {
+ warn(`(DEBUG) - XFA - style for ${name} not implemented yet`);
+ }
+ }
+ }
+ return style;
+}
+function createWrapper(node, html) {
+ const {
+ attributes
+ } = html;
+ const {
+ style
+ } = attributes;
+ const wrapper = {
+ name: "div",
+ attributes: {
+ class: ["xfaWrapper"],
+ style: Object.create(null)
+ },
+ children: []
+ };
+ attributes.class.push("xfaWrapped");
+ if (node.border) {
+ const {
+ widths,
+ insets
+ } = node.border[$extra];
+ let width, height;
+ let top = insets[0];
+ let left = insets[3];
+ const insetsH = insets[0] + insets[2];
+ const insetsW = insets[1] + insets[3];
+ switch (node.border.hand) {
+ case "even":
+ top -= widths[0] / 2;
+ left -= widths[3] / 2;
+ width = `calc(100% + ${(widths[1] + widths[3]) / 2 - insetsW}px)`;
+ height = `calc(100% + ${(widths[0] + widths[2]) / 2 - insetsH}px)`;
+ break;
+ case "left":
+ top -= widths[0];
+ left -= widths[3];
+ width = `calc(100% + ${widths[1] + widths[3] - insetsW}px)`;
+ height = `calc(100% + ${widths[0] + widths[2] - insetsH}px)`;
+ break;
+ case "right":
+ width = insetsW ? `calc(100% - ${insetsW}px)` : "100%";
+ height = insetsH ? `calc(100% - ${insetsH}px)` : "100%";
+ break;
+ }
+ const classNames = ["xfaBorder"];
+ if (isPrintOnly(node.border)) {
+ classNames.push("xfaPrintOnly");
+ }
+ const border = {
+ name: "div",
+ attributes: {
+ class: classNames,
+ style: {
+ top: `${top}px`,
+ left: `${left}px`,
+ width,
+ height
+ }
+ },
+ children: []
+ };
+ for (const key of ["border", "borderWidth", "borderColor", "borderRadius", "borderStyle"]) {
+ if (style[key] !== undefined) {
+ border.attributes.style[key] = style[key];
+ delete style[key];
+ }
+ }
+ wrapper.children.push(border, html);
+ } else {
+ wrapper.children.push(html);
+ }
+ for (const key of ["background", "backgroundClip", "top", "left", "width", "height", "minWidth", "minHeight", "maxWidth", "maxHeight", "transform", "transformOrigin", "visibility"]) {
+ if (style[key] !== undefined) {
+ wrapper.attributes.style[key] = style[key];
+ delete style[key];
+ }
+ }
+ wrapper.attributes.style.position = style.position === "absolute" ? "absolute" : "relative";
+ delete style.position;
+ if (style.alignSelf) {
+ wrapper.attributes.style.alignSelf = style.alignSelf;
+ delete style.alignSelf;
+ }
+ return wrapper;
+}
+function fixTextIndent(styles) {
+ const indent = getMeasurement(styles.textIndent, "0px");
+ if (indent >= 0) {
+ return;
+ }
+ const align = styles.textAlign === "right" ? "right" : "left";
+ const name = "padding" + (align === "left" ? "Left" : "Right");
+ const padding = getMeasurement(styles[name], "0px");
+ styles[name] = `${padding - indent}px`;
+}
+function setAccess(node, classNames) {
+ switch (node.access) {
+ case "nonInteractive":
+ classNames.push("xfaNonInteractive");
+ break;
+ case "readOnly":
+ classNames.push("xfaReadOnly");
+ break;
+ case "protected":
+ classNames.push("xfaDisabled");
+ break;
+ }
+}
+function isPrintOnly(node) {
+ return node.relevant.length > 0 && !node.relevant[0].excluded && node.relevant[0].viewname === "print";
+}
+function getCurrentPara(node) {
+ const stack = node[$getTemplateRoot]()[$extra].paraStack;
+ return stack.length ? stack.at(-1) : null;
+}
+function setPara(node, nodeStyle, value) {
+ if (value.attributes.class?.includes("xfaRich")) {
+ if (nodeStyle) {
+ if (node.h === "") {
+ nodeStyle.height = "auto";
+ }
+ if (node.w === "") {
+ nodeStyle.width = "auto";
+ }
+ }
+ const para = getCurrentPara(node);
+ if (para) {
+ const valueStyle = value.attributes.style;
+ valueStyle.display = "flex";
+ valueStyle.flexDirection = "column";
+ switch (para.vAlign) {
+ case "top":
+ valueStyle.justifyContent = "start";
+ break;
+ case "bottom":
+ valueStyle.justifyContent = "end";
+ break;
+ case "middle":
+ valueStyle.justifyContent = "center";
+ break;
+ }
+ const paraStyle = para[$toStyle]();
+ for (const [key, val] of Object.entries(paraStyle)) {
+ if (!(key in valueStyle)) {
+ valueStyle[key] = val;
+ }
+ }
+ }
+ }
+}
+function setFontFamily(xfaFont, node, fontFinder, style) {
+ if (!fontFinder) {
+ delete style.fontFamily;
+ return;
+ }
+ const name = stripQuotes(xfaFont.typeface);
+ style.fontFamily = `"${name}"`;
+ const typeface = fontFinder.find(name);
+ if (typeface) {
+ const {
+ fontFamily
+ } = typeface.regular.cssFontInfo;
+ if (fontFamily !== name) {
+ style.fontFamily = `"${fontFamily}"`;
+ }
+ const para = getCurrentPara(node);
+ if (para && para.lineHeight !== "") {
+ return;
+ }
+ if (style.lineHeight) {
+ return;
+ }
+ const pdfFont = selectFont(xfaFont, typeface);
+ if (pdfFont) {
+ style.lineHeight = Math.max(1.2, pdfFont.lineHeight);
+ }
+ }
+}
+function fixURL(str) {
+ const absoluteUrl = createValidAbsoluteUrl(str, null, {
+ addDefaultProtocol: true,
+ tryConvertEncoding: true
+ });
+ return absoluteUrl ? absoluteUrl.href : null;
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/layout.js
+
+
+function createLine(node, children) {
+ return {
+ name: "div",
+ attributes: {
+ class: [node.layout === "lr-tb" ? "xfaLr" : "xfaRl"]
+ },
+ children
+ };
+}
+function flushHTML(node) {
+ if (!node[$extra]) {
+ return null;
+ }
+ const attributes = node[$extra].attributes;
+ const html = {
+ name: "div",
+ attributes,
+ children: node[$extra].children
+ };
+ if (node[$extra].failingNode) {
+ const htmlFromFailing = node[$extra].failingNode[$flushHTML]();
+ if (htmlFromFailing) {
+ if (node.layout.endsWith("-tb")) {
+ html.children.push(createLine(node, [htmlFromFailing]));
+ } else {
+ html.children.push(htmlFromFailing);
+ }
+ }
+ }
+ if (html.children.length === 0) {
+ return null;
+ }
+ return html;
+}
+function addHTML(node, html, bbox) {
+ const extra = node[$extra];
+ const availableSpace = extra.availableSpace;
+ const [x, y, w, h] = bbox;
+ switch (node.layout) {
+ case "position":
+ {
+ extra.width = Math.max(extra.width, x + w);
+ extra.height = Math.max(extra.height, y + h);
+ extra.children.push(html);
+ break;
+ }
+ case "lr-tb":
+ case "rl-tb":
+ if (!extra.line || extra.attempt === 1) {
+ extra.line = createLine(node, []);
+ extra.children.push(extra.line);
+ extra.numberInLine = 0;
+ }
+ extra.numberInLine += 1;
+ extra.line.children.push(html);
+ if (extra.attempt === 0) {
+ extra.currentWidth += w;
+ extra.height = Math.max(extra.height, extra.prevHeight + h);
+ } else {
+ extra.currentWidth = w;
+ extra.prevHeight = extra.height;
+ extra.height += h;
+ extra.attempt = 0;
+ }
+ extra.width = Math.max(extra.width, extra.currentWidth);
+ break;
+ case "rl-row":
+ case "row":
+ {
+ extra.children.push(html);
+ extra.width += w;
+ extra.height = Math.max(extra.height, h);
+ const height = measureToString(extra.height);
+ for (const child of extra.children) {
+ child.attributes.style.height = height;
+ }
+ break;
+ }
+ case "table":
+ {
+ extra.width = Math.min(availableSpace.width, Math.max(extra.width, w));
+ extra.height += h;
+ extra.children.push(html);
+ break;
+ }
+ case "tb":
+ {
+ extra.width = Math.min(availableSpace.width, Math.max(extra.width, w));
+ extra.height += h;
+ extra.children.push(html);
+ break;
+ }
+ }
+}
+function getAvailableSpace(node) {
+ const availableSpace = node[$extra].availableSpace;
+ const marginV = node.margin ? node.margin.topInset + node.margin.bottomInset : 0;
+ const marginH = node.margin ? node.margin.leftInset + node.margin.rightInset : 0;
+ switch (node.layout) {
+ case "lr-tb":
+ case "rl-tb":
+ if (node[$extra].attempt === 0) {
+ return {
+ width: availableSpace.width - marginH - node[$extra].currentWidth,
+ height: availableSpace.height - marginV - node[$extra].prevHeight
+ };
+ }
+ return {
+ width: availableSpace.width - marginH,
+ height: availableSpace.height - marginV - node[$extra].height
+ };
+ case "rl-row":
+ case "row":
+ const width = node[$extra].columnWidths.slice(node[$extra].currentColumn).reduce((a, x) => a + x);
+ return {
+ width,
+ height: availableSpace.height - marginH
+ };
+ case "table":
+ case "tb":
+ return {
+ width: availableSpace.width - marginH,
+ height: availableSpace.height - marginV - node[$extra].height
+ };
+ case "position":
+ default:
+ return availableSpace;
+ }
+}
+function getTransformedBBox(node) {
+ let w = node.w === "" ? NaN : node.w;
+ let h = node.h === "" ? NaN : node.h;
+ let [centerX, centerY] = [0, 0];
+ switch (node.anchorType || "") {
+ case "bottomCenter":
+ [centerX, centerY] = [w / 2, h];
+ break;
+ case "bottomLeft":
+ [centerX, centerY] = [0, h];
+ break;
+ case "bottomRight":
+ [centerX, centerY] = [w, h];
+ break;
+ case "middleCenter":
+ [centerX, centerY] = [w / 2, h / 2];
+ break;
+ case "middleLeft":
+ [centerX, centerY] = [0, h / 2];
+ break;
+ case "middleRight":
+ [centerX, centerY] = [w, h / 2];
+ break;
+ case "topCenter":
+ [centerX, centerY] = [w / 2, 0];
+ break;
+ case "topRight":
+ [centerX, centerY] = [w, 0];
+ break;
+ }
+ let x, y;
+ switch (node.rotate || 0) {
+ case 0:
+ [x, y] = [-centerX, -centerY];
+ break;
+ case 90:
+ [x, y] = [-centerY, centerX];
+ [w, h] = [h, -w];
+ break;
+ case 180:
+ [x, y] = [centerX, centerY];
+ [w, h] = [-w, -h];
+ break;
+ case 270:
+ [x, y] = [centerY, -centerX];
+ [w, h] = [-h, w];
+ break;
+ }
+ return [node.x + x + Math.min(0, w), node.y + y + Math.min(0, h), Math.abs(w), Math.abs(h)];
+}
+function checkDimensions(node, space) {
+ if (node[$getTemplateRoot]()[$extra].firstUnsplittable === null) {
+ return true;
+ }
+ if (node.w === 0 || node.h === 0) {
+ return true;
+ }
+ const ERROR = 2;
+ const parent = node[$getSubformParent]();
+ const attempt = parent[$extra]?.attempt || 0;
+ const [, y, w, h] = getTransformedBBox(node);
+ switch (parent.layout) {
+ case "lr-tb":
+ case "rl-tb":
+ if (attempt === 0) {
+ if (!node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ if (node.h !== "" && Math.round(h - space.height) > ERROR) {
+ return false;
+ }
+ if (node.w !== "") {
+ if (Math.round(w - space.width) <= ERROR) {
+ return true;
+ }
+ if (parent[$extra].numberInLine === 0) {
+ return space.height > ERROR;
+ }
+ return false;
+ }
+ return space.width > ERROR;
+ }
+ if (node.w !== "") {
+ return Math.round(w - space.width) <= ERROR;
+ }
+ return space.width > ERROR;
+ }
+ if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ return true;
+ }
+ if (node.h !== "" && Math.round(h - space.height) > ERROR) {
+ return false;
+ }
+ if (node.w === "" || Math.round(w - space.width) <= ERROR) {
+ return space.height > ERROR;
+ }
+ if (parent[$isThereMoreWidth]()) {
+ return false;
+ }
+ return space.height > ERROR;
+ case "table":
+ case "tb":
+ if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ return true;
+ }
+ if (node.h !== "" && !node[$isSplittable]()) {
+ return Math.round(h - space.height) <= ERROR;
+ }
+ if (node.w === "" || Math.round(w - space.width) <= ERROR) {
+ return space.height > ERROR;
+ }
+ if (parent[$isThereMoreWidth]()) {
+ return false;
+ }
+ return space.height > ERROR;
+ case "position":
+ if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ return true;
+ }
+ if (node.h === "" || Math.round(h + y - space.height) <= ERROR) {
+ return true;
+ }
+ const area = node[$getTemplateRoot]()[$extra].currentContentArea;
+ return h + y > area.h;
+ case "rl-row":
+ case "row":
+ if (node[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ return true;
+ }
+ if (node.h !== "") {
+ return Math.round(h - space.height) <= ERROR;
+ }
+ return true;
+ default:
+ return true;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/template.js
+
+
+
+
+
+
+
+
+
+
+const TEMPLATE_NS_ID = NamespaceIds.template.id;
+const SVG_NS = "http://www.w3.org/2000/svg";
+const MAX_ATTEMPTS_FOR_LRTB_LAYOUT = 2;
+const MAX_EMPTY_PAGES = 3;
+const DEFAULT_TAB_INDEX = 5000;
+const HEADING_PATTERN = /^H(\d+)$/;
+const MIMES = new Set(["image/gif", "image/jpeg", "image/jpg", "image/pjpeg", "image/png", "image/apng", "image/x-png", "image/bmp", "image/x-ms-bmp", "image/tiff", "image/tif", "application/octet-stream"]);
+const IMAGES_HEADERS = [[[0x42, 0x4d], "image/bmp"], [[0xff, 0xd8, 0xff], "image/jpeg"], [[0x49, 0x49, 0x2a, 0x00], "image/tiff"], [[0x4d, 0x4d, 0x00, 0x2a], "image/tiff"], [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61], "image/gif"], [[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], "image/png"]];
+function getBorderDims(node) {
+ if (!node || !node.border) {
+ return {
+ w: 0,
+ h: 0
+ };
+ }
+ const borderExtra = node.border[$getExtra]();
+ if (!borderExtra) {
+ return {
+ w: 0,
+ h: 0
+ };
+ }
+ return {
+ w: borderExtra.widths[0] + borderExtra.widths[2] + borderExtra.insets[0] + borderExtra.insets[2],
+ h: borderExtra.widths[1] + borderExtra.widths[3] + borderExtra.insets[1] + borderExtra.insets[3]
+ };
+}
+function hasMargin(node) {
+ return node.margin && (node.margin.topInset || node.margin.rightInset || node.margin.bottomInset || node.margin.leftInset);
+}
+function _setValue(templateNode, value) {
+ if (!templateNode.value) {
+ const nodeValue = new Value({});
+ templateNode[$appendChild](nodeValue);
+ templateNode.value = nodeValue;
+ }
+ templateNode.value[$setValue](value);
+}
+function* getContainedChildren(node) {
+ for (const child of node[$getChildren]()) {
+ if (child instanceof SubformSet) {
+ yield* child[$getContainedChildren]();
+ continue;
+ }
+ yield child;
+ }
+}
+function isRequired(node) {
+ return node.validate?.nullTest === "error";
+}
+function setTabIndex(node) {
+ while (node) {
+ if (!node.traversal) {
+ node[$tabIndex] = node[$getParent]()[$tabIndex];
+ return;
+ }
+ if (node[$tabIndex]) {
+ return;
+ }
+ let next = null;
+ for (const child of node.traversal[$getChildren]()) {
+ if (child.operation === "next") {
+ next = child;
+ break;
+ }
+ }
+ if (!next || !next.ref) {
+ node[$tabIndex] = node[$getParent]()[$tabIndex];
+ return;
+ }
+ const root = node[$getTemplateRoot]();
+ node[$tabIndex] = ++root[$tabIndex];
+ const ref = root[$searchNode](next.ref, node);
+ if (!ref) {
+ return;
+ }
+ node = ref[0];
+ }
+}
+function applyAssist(obj, attributes) {
+ const assist = obj.assist;
+ if (assist) {
+ const assistTitle = assist[$toHTML]();
+ if (assistTitle) {
+ attributes.title = assistTitle;
+ }
+ const role = assist.role;
+ const match = role.match(HEADING_PATTERN);
+ if (match) {
+ const ariaRole = "heading";
+ const ariaLevel = match[1];
+ attributes.role = ariaRole;
+ attributes["aria-level"] = ariaLevel;
+ }
+ }
+ if (obj.layout === "table") {
+ attributes.role = "table";
+ } else if (obj.layout === "row") {
+ attributes.role = "row";
+ } else {
+ const parent = obj[$getParent]();
+ if (parent.layout === "row") {
+ attributes.role = parent.assist?.role === "TH" ? "columnheader" : "cell";
+ }
+ }
+}
+function ariaLabel(obj) {
+ if (!obj.assist) {
+ return null;
+ }
+ const assist = obj.assist;
+ if (assist.speak && assist.speak[$content] !== "") {
+ return assist.speak[$content];
+ }
+ if (assist.toolTip) {
+ return assist.toolTip[$content];
+ }
+ return null;
+}
+function valueToHtml(value) {
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ class: ["xfaRich"],
+ style: Object.create(null)
+ },
+ children: [{
+ name: "span",
+ attributes: {
+ style: Object.create(null)
+ },
+ value
+ }]
+ });
+}
+function setFirstUnsplittable(node) {
+ const root = node[$getTemplateRoot]();
+ if (root[$extra].firstUnsplittable === null) {
+ root[$extra].firstUnsplittable = node;
+ root[$extra].noLayoutFailure = true;
+ }
+}
+function unsetFirstUnsplittable(node) {
+ const root = node[$getTemplateRoot]();
+ if (root[$extra].firstUnsplittable === node) {
+ root[$extra].noLayoutFailure = false;
+ }
+}
+function handleBreak(node) {
+ if (node[$extra]) {
+ return false;
+ }
+ node[$extra] = Object.create(null);
+ if (node.targetType === "auto") {
+ return false;
+ }
+ const root = node[$getTemplateRoot]();
+ let target = null;
+ if (node.target) {
+ target = root[$searchNode](node.target, node[$getParent]());
+ if (!target) {
+ return false;
+ }
+ target = target[0];
+ }
+ const {
+ currentPageArea,
+ currentContentArea
+ } = root[$extra];
+ if (node.targetType === "pageArea") {
+ if (!(target instanceof PageArea)) {
+ target = null;
+ }
+ if (node.startNew) {
+ node[$extra].target = target || currentPageArea;
+ return true;
+ } else if (target && target !== currentPageArea) {
+ node[$extra].target = target;
+ return true;
+ }
+ return false;
+ }
+ if (!(target instanceof ContentArea)) {
+ target = null;
+ }
+ const pageArea = target && target[$getParent]();
+ let index;
+ let nextPageArea = pageArea;
+ if (node.startNew) {
+ if (target) {
+ const contentAreas = pageArea.contentArea.children;
+ const indexForCurrent = contentAreas.indexOf(currentContentArea);
+ const indexForTarget = contentAreas.indexOf(target);
+ if (indexForCurrent !== -1 && indexForCurrent < indexForTarget) {
+ nextPageArea = null;
+ }
+ index = indexForTarget - 1;
+ } else {
+ index = currentPageArea.contentArea.children.indexOf(currentContentArea);
+ }
+ } else if (target && target !== currentContentArea) {
+ const contentAreas = pageArea.contentArea.children;
+ index = contentAreas.indexOf(target) - 1;
+ nextPageArea = pageArea === currentPageArea ? null : pageArea;
+ } else {
+ return false;
+ }
+ node[$extra].target = nextPageArea;
+ node[$extra].index = index;
+ return true;
+}
+function handleOverflow(node, extraNode, space) {
+ const root = node[$getTemplateRoot]();
+ const saved = root[$extra].noLayoutFailure;
+ const savedMethod = extraNode[$getSubformParent];
+ extraNode[$getSubformParent] = () => node;
+ root[$extra].noLayoutFailure = true;
+ const res = extraNode[$toHTML](space);
+ node[$addHTML](res.html, res.bbox);
+ root[$extra].noLayoutFailure = saved;
+ extraNode[$getSubformParent] = savedMethod;
+}
+class AppearanceFilter extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "appearanceFilter");
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Arc extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "arc", true);
+ this.circular = getInteger({
+ data: attributes.circular,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.hand = getStringOption(attributes.hand, ["even", "left", "right"]);
+ this.id = attributes.id || "";
+ this.startAngle = getFloat({
+ data: attributes.startAngle,
+ defaultValue: 0,
+ validate: x => true
+ });
+ this.sweepAngle = getFloat({
+ data: attributes.sweepAngle,
+ defaultValue: 360,
+ validate: x => true
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.edge = null;
+ this.fill = null;
+ }
+ [$toHTML]() {
+ const edge = this.edge || new Edge({});
+ const edgeStyle = edge[$toStyle]();
+ const style = Object.create(null);
+ if (this.fill?.presence === "visible") {
+ Object.assign(style, this.fill[$toStyle]());
+ } else {
+ style.fill = "transparent";
+ }
+ style.strokeWidth = measureToString(edge.presence === "visible" ? edge.thickness : 0);
+ style.stroke = edgeStyle.color;
+ let arc;
+ const attributes = {
+ xmlns: SVG_NS,
+ style: {
+ width: "100%",
+ height: "100%",
+ overflow: "visible"
+ }
+ };
+ if (this.sweepAngle === 360) {
+ arc = {
+ name: "ellipse",
+ attributes: {
+ xmlns: SVG_NS,
+ cx: "50%",
+ cy: "50%",
+ rx: "50%",
+ ry: "50%",
+ style
+ }
+ };
+ } else {
+ const startAngle = this.startAngle * Math.PI / 180;
+ const sweepAngle = this.sweepAngle * Math.PI / 180;
+ const largeArc = this.sweepAngle > 180 ? 1 : 0;
+ const [x1, y1, x2, y2] = [50 * (1 + Math.cos(startAngle)), 50 * (1 - Math.sin(startAngle)), 50 * (1 + Math.cos(startAngle + sweepAngle)), 50 * (1 - Math.sin(startAngle + sweepAngle))];
+ arc = {
+ name: "path",
+ attributes: {
+ xmlns: SVG_NS,
+ d: `M ${x1} ${y1} A 50 50 0 ${largeArc} 0 ${x2} ${y2}`,
+ vectorEffect: "non-scaling-stroke",
+ style
+ }
+ };
+ Object.assign(attributes, {
+ viewBox: "0 0 100 100",
+ preserveAspectRatio: "none"
+ });
+ }
+ const svg = {
+ name: "svg",
+ children: [arc],
+ attributes
+ };
+ const parent = this[$getParent]()[$getParent]();
+ if (hasMargin(parent)) {
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ style: {
+ display: "inline",
+ width: "100%",
+ height: "100%"
+ }
+ },
+ children: [svg]
+ });
+ }
+ svg.attributes.style.position = "absolute";
+ return HTMLResult.success(svg);
+ }
+}
+class Area extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "area", true);
+ this.colSpan = getInteger({
+ data: attributes.colSpan,
+ defaultValue: 1,
+ validate: n => n >= 1 || n === -1
+ });
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.desc = null;
+ this.extras = null;
+ this.area = new XFAObjectArray();
+ this.draw = new XFAObjectArray();
+ this.exObject = new XFAObjectArray();
+ this.exclGroup = new XFAObjectArray();
+ this.field = new XFAObjectArray();
+ this.subform = new XFAObjectArray();
+ this.subformSet = new XFAObjectArray();
+ }
+ *[$getContainedChildren]() {
+ yield* getContainedChildren(this);
+ }
+ [$isTransparent]() {
+ return true;
+ }
+ [$isBindable]() {
+ return true;
+ }
+ [$addHTML](html, bbox) {
+ const [x, y, w, h] = bbox;
+ this[$extra].width = Math.max(this[$extra].width, x + w);
+ this[$extra].height = Math.max(this[$extra].height, y + h);
+ this[$extra].children.push(html);
+ }
+ [$getAvailableSpace]() {
+ return this[$extra].availableSpace;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle(this, "position");
+ const attributes = {
+ style,
+ id: this[$uid],
+ class: ["xfaArea"]
+ };
+ if (isPrintOnly(this)) {
+ attributes.class.push("xfaPrintOnly");
+ }
+ if (this.name) {
+ attributes.xfaName = this.name;
+ }
+ const children = [];
+ this[$extra] = {
+ children,
+ width: 0,
+ height: 0,
+ availableSpace
+ };
+ const result = this[$childrenToHTML]({
+ filter: new Set(["area", "draw", "field", "exclGroup", "subform", "subformSet"]),
+ include: true
+ });
+ if (!result.success) {
+ if (result.isBreak()) {
+ return result;
+ }
+ delete this[$extra];
+ return HTMLResult.FAILURE;
+ }
+ style.width = measureToString(this[$extra].width);
+ style.height = measureToString(this[$extra].height);
+ const html = {
+ name: "div",
+ attributes,
+ children
+ };
+ const bbox = [this.x, this.y, this[$extra].width, this[$extra].height];
+ delete this[$extra];
+ return HTMLResult.success(html, bbox);
+ }
+}
+class Assist extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "assist", true);
+ this.id = attributes.id || "";
+ this.role = attributes.role || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.speak = null;
+ this.toolTip = null;
+ }
+ [$toHTML]() {
+ return this.toolTip?.[$content] || null;
+ }
+}
+class Barcode extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "barcode", true);
+ this.charEncoding = getKeyword({
+ data: attributes.charEncoding ? attributes.charEncoding.toLowerCase() : "",
+ defaultValue: "",
+ validate: k => ["utf-8", "big-five", "fontspecific", "gbk", "gb-18030", "gb-2312", "ksc-5601", "none", "shift-jis", "ucs-2", "utf-16"].includes(k) || k.match(/iso-8859-\d{2}/)
+ });
+ this.checksum = getStringOption(attributes.checksum, ["none", "1mod10", "1mod10_1mod11", "2mod10", "auto"]);
+ this.dataColumnCount = getInteger({
+ data: attributes.dataColumnCount,
+ defaultValue: -1,
+ validate: x => x >= 0
+ });
+ this.dataLength = getInteger({
+ data: attributes.dataLength,
+ defaultValue: -1,
+ validate: x => x >= 0
+ });
+ this.dataPrep = getStringOption(attributes.dataPrep, ["none", "flateCompress"]);
+ this.dataRowCount = getInteger({
+ data: attributes.dataRowCount,
+ defaultValue: -1,
+ validate: x => x >= 0
+ });
+ this.endChar = attributes.endChar || "";
+ this.errorCorrectionLevel = getInteger({
+ data: attributes.errorCorrectionLevel,
+ defaultValue: -1,
+ validate: x => x >= 0 && x <= 8
+ });
+ this.id = attributes.id || "";
+ this.moduleHeight = getMeasurement(attributes.moduleHeight, "5mm");
+ this.moduleWidth = getMeasurement(attributes.moduleWidth, "0.25mm");
+ this.printCheckDigit = getInteger({
+ data: attributes.printCheckDigit,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.rowColumnRatio = getRatio(attributes.rowColumnRatio);
+ this.startChar = attributes.startChar || "";
+ this.textLocation = getStringOption(attributes.textLocation, ["below", "above", "aboveEmbedded", "belowEmbedded", "none"]);
+ this.truncate = getInteger({
+ data: attributes.truncate,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.type = getStringOption(attributes.type ? attributes.type.toLowerCase() : "", ["aztec", "codabar", "code2of5industrial", "code2of5interleaved", "code2of5matrix", "code2of5standard", "code3of9", "code3of9extended", "code11", "code49", "code93", "code128", "code128a", "code128b", "code128c", "code128sscc", "datamatrix", "ean8", "ean8add2", "ean8add5", "ean13", "ean13add2", "ean13add5", "ean13pwcd", "fim", "logmars", "maxicode", "msi", "pdf417", "pdf417macro", "plessey", "postauscust2", "postauscust3", "postausreplypaid", "postausstandard", "postukrm4scc", "postusdpbc", "postusimb", "postusstandard", "postus5zip", "qrcode", "rfid", "rss14", "rss14expanded", "rss14limited", "rss14stacked", "rss14stackedomni", "rss14truncated", "telepen", "ucc128", "ucc128random", "ucc128sscc", "upca", "upcaadd2", "upcaadd5", "upcapwcd", "upce", "upceadd2", "upceadd5", "upcean2", "upcean5", "upsmaxicode"]);
+ this.upsMode = getStringOption(attributes.upsMode, ["usCarrier", "internationalCarrier", "secureSymbol", "standardSymbol"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.wideNarrowRatio = getRatio(attributes.wideNarrowRatio);
+ this.encrypt = null;
+ this.extras = null;
+ }
+}
+class Bind extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "bind", true);
+ this.match = getStringOption(attributes.match, ["once", "dataRef", "global", "none"]);
+ this.ref = attributes.ref || "";
+ this.picture = null;
+ }
+}
+class BindItems extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "bindItems");
+ this.connection = attributes.connection || "";
+ this.labelRef = attributes.labelRef || "";
+ this.ref = attributes.ref || "";
+ this.valueRef = attributes.valueRef || "";
+ }
+}
+class Bookend extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "bookend");
+ this.id = attributes.id || "";
+ this.leader = attributes.leader || "";
+ this.trailer = attributes.trailer || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class BooleanElement extends Option01 {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "boolean");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] === 1 ? "1" : "0");
+ }
+}
+class Border extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "border", true);
+ this.break = getStringOption(attributes.break, ["close", "open"]);
+ this.hand = getStringOption(attributes.hand, ["even", "left", "right"]);
+ this.id = attributes.id || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.corner = new XFAObjectArray(4);
+ this.edge = new XFAObjectArray(4);
+ this.extras = null;
+ this.fill = null;
+ this.margin = null;
+ }
+ [$getExtra]() {
+ if (!this[$extra]) {
+ const edges = this.edge.children.slice();
+ if (edges.length < 4) {
+ const defaultEdge = edges.at(-1) || new Edge({});
+ for (let i = edges.length; i < 4; i++) {
+ edges.push(defaultEdge);
+ }
+ }
+ const widths = edges.map(edge => edge.thickness);
+ const insets = [0, 0, 0, 0];
+ if (this.margin) {
+ insets[0] = this.margin.topInset;
+ insets[1] = this.margin.rightInset;
+ insets[2] = this.margin.bottomInset;
+ insets[3] = this.margin.leftInset;
+ }
+ this[$extra] = {
+ widths,
+ insets,
+ edges
+ };
+ }
+ return this[$extra];
+ }
+ [$toStyle]() {
+ const {
+ edges
+ } = this[$getExtra]();
+ const edgeStyles = edges.map(node => {
+ const style = node[$toStyle]();
+ style.color ||= "#000000";
+ return style;
+ });
+ const style = Object.create(null);
+ if (this.margin) {
+ Object.assign(style, this.margin[$toStyle]());
+ }
+ if (this.fill?.presence === "visible") {
+ Object.assign(style, this.fill[$toStyle]());
+ }
+ if (this.corner.children.some(node => node.radius !== 0)) {
+ const cornerStyles = this.corner.children.map(node => node[$toStyle]());
+ if (cornerStyles.length === 2 || cornerStyles.length === 3) {
+ const last = cornerStyles.at(-1);
+ for (let i = cornerStyles.length; i < 4; i++) {
+ cornerStyles.push(last);
+ }
+ }
+ style.borderRadius = cornerStyles.map(s => s.radius).join(" ");
+ }
+ switch (this.presence) {
+ case "invisible":
+ case "hidden":
+ style.borderStyle = "";
+ break;
+ case "inactive":
+ style.borderStyle = "none";
+ break;
+ default:
+ style.borderStyle = edgeStyles.map(s => s.style).join(" ");
+ break;
+ }
+ style.borderWidth = edgeStyles.map(s => s.width).join(" ");
+ style.borderColor = edgeStyles.map(s => s.color).join(" ");
+ return style;
+ }
+}
+class Break extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "break", true);
+ this.after = getStringOption(attributes.after, ["auto", "contentArea", "pageArea", "pageEven", "pageOdd"]);
+ this.afterTarget = attributes.afterTarget || "";
+ this.before = getStringOption(attributes.before, ["auto", "contentArea", "pageArea", "pageEven", "pageOdd"]);
+ this.beforeTarget = attributes.beforeTarget || "";
+ this.bookendLeader = attributes.bookendLeader || "";
+ this.bookendTrailer = attributes.bookendTrailer || "";
+ this.id = attributes.id || "";
+ this.overflowLeader = attributes.overflowLeader || "";
+ this.overflowTarget = attributes.overflowTarget || "";
+ this.overflowTrailer = attributes.overflowTrailer || "";
+ this.startNew = getInteger({
+ data: attributes.startNew,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+}
+class BreakAfter extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "breakAfter", true);
+ this.id = attributes.id || "";
+ this.leader = attributes.leader || "";
+ this.startNew = getInteger({
+ data: attributes.startNew,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.target = attributes.target || "";
+ this.targetType = getStringOption(attributes.targetType, ["auto", "contentArea", "pageArea"]);
+ this.trailer = attributes.trailer || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.script = null;
+ }
+}
+class BreakBefore extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "breakBefore", true);
+ this.id = attributes.id || "";
+ this.leader = attributes.leader || "";
+ this.startNew = getInteger({
+ data: attributes.startNew,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.target = attributes.target || "";
+ this.targetType = getStringOption(attributes.targetType, ["auto", "contentArea", "pageArea"]);
+ this.trailer = attributes.trailer || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.script = null;
+ }
+ [$toHTML](availableSpace) {
+ this[$extra] = {};
+ return HTMLResult.FAILURE;
+ }
+}
+class Button extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "button", true);
+ this.highlight = getStringOption(attributes.highlight, ["inverted", "none", "outline", "push"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+ [$toHTML](availableSpace) {
+ const parent = this[$getParent]();
+ const grandpa = parent[$getParent]();
+ const htmlButton = {
+ name: "button",
+ attributes: {
+ id: this[$uid],
+ class: ["xfaButton"],
+ style: {}
+ },
+ children: []
+ };
+ for (const event of grandpa.event.children) {
+ if (event.activity !== "click" || !event.script) {
+ continue;
+ }
+ const jsURL = recoverJsURL(event.script[$content]);
+ if (!jsURL) {
+ continue;
+ }
+ const href = fixURL(jsURL.url);
+ if (!href) {
+ continue;
+ }
+ htmlButton.children.push({
+ name: "a",
+ attributes: {
+ id: "link" + this[$uid],
+ href,
+ newWindow: jsURL.newWindow,
+ class: ["xfaLink"],
+ style: {}
+ },
+ children: []
+ });
+ }
+ return HTMLResult.success(htmlButton);
+ }
+}
+class Calculate extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "calculate", true);
+ this.id = attributes.id || "";
+ this.override = getStringOption(attributes.override, ["disabled", "error", "ignore", "warning"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.message = null;
+ this.script = null;
+ }
+}
+class Caption extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "caption", true);
+ this.id = attributes.id || "";
+ this.placement = getStringOption(attributes.placement, ["left", "bottom", "inline", "right", "top"]);
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.reserve = Math.ceil(getMeasurement(attributes.reserve));
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.font = null;
+ this.margin = null;
+ this.para = null;
+ this.value = null;
+ }
+ [$setValue](value) {
+ _setValue(this, value);
+ }
+ [$getExtra](availableSpace) {
+ if (!this[$extra]) {
+ let {
+ width,
+ height
+ } = availableSpace;
+ switch (this.placement) {
+ case "left":
+ case "right":
+ case "inline":
+ width = this.reserve <= 0 ? width : this.reserve;
+ break;
+ case "top":
+ case "bottom":
+ height = this.reserve <= 0 ? height : this.reserve;
+ break;
+ }
+ this[$extra] = layoutNode(this, {
+ width,
+ height
+ });
+ }
+ return this[$extra];
+ }
+ [$toHTML](availableSpace) {
+ if (!this.value) {
+ return HTMLResult.EMPTY;
+ }
+ this[$pushPara]();
+ const value = this.value[$toHTML](availableSpace).html;
+ if (!value) {
+ this[$popPara]();
+ return HTMLResult.EMPTY;
+ }
+ const savedReserve = this.reserve;
+ if (this.reserve <= 0) {
+ const {
+ w,
+ h
+ } = this[$getExtra](availableSpace);
+ switch (this.placement) {
+ case "left":
+ case "right":
+ case "inline":
+ this.reserve = w;
+ break;
+ case "top":
+ case "bottom":
+ this.reserve = h;
+ break;
+ }
+ }
+ const children = [];
+ if (typeof value === "string") {
+ children.push({
+ name: "#text",
+ value
+ });
+ } else {
+ children.push(value);
+ }
+ const style = toStyle(this, "font", "margin", "visibility");
+ switch (this.placement) {
+ case "left":
+ case "right":
+ if (this.reserve > 0) {
+ style.width = measureToString(this.reserve);
+ }
+ break;
+ case "top":
+ case "bottom":
+ if (this.reserve > 0) {
+ style.height = measureToString(this.reserve);
+ }
+ break;
+ }
+ setPara(this, null, value);
+ this[$popPara]();
+ this.reserve = savedReserve;
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ style,
+ class: ["xfaCaption"]
+ },
+ children
+ });
+ }
+}
+class Certificate extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "certificate");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Certificates extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "certificates", true);
+ this.credentialServerPolicy = getStringOption(attributes.credentialServerPolicy, ["optional", "required"]);
+ this.id = attributes.id || "";
+ this.url = attributes.url || "";
+ this.urlPolicy = attributes.urlPolicy || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.encryption = null;
+ this.issuers = null;
+ this.keyUsage = null;
+ this.oids = null;
+ this.signing = null;
+ this.subjectDNs = null;
+ }
+}
+class CheckButton extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "checkButton", true);
+ this.id = attributes.id || "";
+ this.mark = getStringOption(attributes.mark, ["default", "check", "circle", "cross", "diamond", "square", "star"]);
+ this.shape = getStringOption(attributes.shape, ["square", "round"]);
+ this.size = getMeasurement(attributes.size, "10pt");
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle("margin");
+ const size = measureToString(this.size);
+ style.width = style.height = size;
+ let type;
+ let className;
+ let groupId;
+ const field = this[$getParent]()[$getParent]();
+ const items = field.items.children.length && field.items.children[0][$toHTML]().html || [];
+ const exportedValue = {
+ on: (items[0] !== undefined ? items[0] : "on").toString(),
+ off: (items[1] !== undefined ? items[1] : "off").toString()
+ };
+ const value = field.value?.[$text]() || "off";
+ const checked = value === exportedValue.on || undefined;
+ const container = field[$getSubformParent]();
+ const fieldId = field[$uid];
+ let dataId;
+ if (container instanceof ExclGroup) {
+ groupId = container[$uid];
+ type = "radio";
+ className = "xfaRadio";
+ dataId = container[$data]?.[$uid] || container[$uid];
+ } else {
+ type = "checkbox";
+ className = "xfaCheckbox";
+ dataId = field[$data]?.[$uid] || field[$uid];
+ }
+ const input = {
+ name: "input",
+ attributes: {
+ class: [className],
+ style,
+ fieldId,
+ dataId,
+ type,
+ checked,
+ xfaOn: exportedValue.on,
+ xfaOff: exportedValue.off,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ }
+ };
+ if (groupId) {
+ input.attributes.name = groupId;
+ }
+ if (isRequired(field)) {
+ input.attributes["aria-required"] = true;
+ input.attributes.required = true;
+ }
+ return HTMLResult.success({
+ name: "label",
+ attributes: {
+ class: ["xfaLabel"]
+ },
+ children: [input]
+ });
+ }
+}
+class ChoiceList extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "choiceList", true);
+ this.commitOn = getStringOption(attributes.commitOn, ["select", "exit"]);
+ this.id = attributes.id || "";
+ this.open = getStringOption(attributes.open, ["userControl", "always", "multiSelect", "onEntry"]);
+ this.textEntry = getInteger({
+ data: attributes.textEntry,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle(this, "border", "margin");
+ const ui = this[$getParent]();
+ const field = ui[$getParent]();
+ const fontSize = field.font?.size || 10;
+ const optionStyle = {
+ fontSize: `calc(${fontSize}px * var(--scale-factor))`
+ };
+ const children = [];
+ if (field.items.children.length > 0) {
+ const items = field.items;
+ let displayedIndex = 0;
+ let saveIndex = 0;
+ if (items.children.length === 2) {
+ displayedIndex = items.children[0].save;
+ saveIndex = 1 - displayedIndex;
+ }
+ const displayed = items.children[displayedIndex][$toHTML]().html;
+ const values = items.children[saveIndex][$toHTML]().html;
+ let selected = false;
+ const value = field.value?.[$text]() || "";
+ for (let i = 0, ii = displayed.length; i < ii; i++) {
+ const option = {
+ name: "option",
+ attributes: {
+ value: values[i] || displayed[i],
+ style: optionStyle
+ },
+ value: displayed[i]
+ };
+ if (values[i] === value) {
+ option.attributes.selected = selected = true;
+ }
+ children.push(option);
+ }
+ if (!selected) {
+ children.splice(0, 0, {
+ name: "option",
+ attributes: {
+ hidden: true,
+ selected: true
+ },
+ value: " "
+ });
+ }
+ }
+ const selectAttributes = {
+ class: ["xfaSelect"],
+ fieldId: field[$uid],
+ dataId: field[$data]?.[$uid] || field[$uid],
+ style,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ };
+ if (isRequired(field)) {
+ selectAttributes["aria-required"] = true;
+ selectAttributes.required = true;
+ }
+ if (this.open === "multiSelect") {
+ selectAttributes.multiple = true;
+ }
+ return HTMLResult.success({
+ name: "label",
+ attributes: {
+ class: ["xfaLabel"]
+ },
+ children: [{
+ name: "select",
+ children,
+ attributes: selectAttributes
+ }]
+ });
+ }
+}
+class Color extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "color", true);
+ this.cSpace = getStringOption(attributes.cSpace, ["SRGB"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.value = attributes.value ? getColor(attributes.value) : "";
+ this.extras = null;
+ }
+ [$hasSettableValue]() {
+ return false;
+ }
+ [$toStyle]() {
+ return this.value ? Util.makeHexColor(this.value.r, this.value.g, this.value.b) : null;
+ }
+}
+class Comb extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "comb");
+ this.id = attributes.id || "";
+ this.numberOfCells = getInteger({
+ data: attributes.numberOfCells,
+ defaultValue: 0,
+ validate: x => x >= 0
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Connect extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "connect", true);
+ this.connection = attributes.connection || "";
+ this.id = attributes.id || "";
+ this.ref = attributes.ref || "";
+ this.usage = getStringOption(attributes.usage, ["exportAndImport", "exportOnly", "importOnly"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.picture = null;
+ }
+}
+class ContentArea extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "contentArea", true);
+ this.h = getMeasurement(attributes.h);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.w = getMeasurement(attributes.w);
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.desc = null;
+ this.extras = null;
+ }
+ [$toHTML](availableSpace) {
+ const left = measureToString(this.x);
+ const top = measureToString(this.y);
+ const style = {
+ left,
+ top,
+ width: measureToString(this.w),
+ height: measureToString(this.h)
+ };
+ const classNames = ["xfaContentarea"];
+ if (isPrintOnly(this)) {
+ classNames.push("xfaPrintOnly");
+ }
+ return HTMLResult.success({
+ name: "div",
+ children: [],
+ attributes: {
+ style,
+ class: classNames,
+ id: this[$uid]
+ }
+ });
+ }
+}
+class Corner extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "corner", true);
+ this.id = attributes.id || "";
+ this.inverted = getInteger({
+ data: attributes.inverted,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.join = getStringOption(attributes.join, ["square", "round"]);
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.radius = getMeasurement(attributes.radius);
+ this.stroke = getStringOption(attributes.stroke, ["solid", "dashDot", "dashDotDot", "dashed", "dotted", "embossed", "etched", "lowered", "raised"]);
+ this.thickness = getMeasurement(attributes.thickness, "0.5pt");
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle]() {
+ const style = toStyle(this, "visibility");
+ style.radius = measureToString(this.join === "square" ? 0 : this.radius);
+ return style;
+ }
+}
+class DateElement extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "date");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const date = this[$content].trim();
+ this[$content] = date ? new Date(date) : null;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] ? this[$content].toString() : "");
+ }
+}
+class DateTime extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "dateTime");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const date = this[$content].trim();
+ this[$content] = date ? new Date(date) : null;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] ? this[$content].toString() : "");
+ }
+}
+class DateTimeEdit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "dateTimeEdit", true);
+ this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, ["auto", "off", "on"]);
+ this.id = attributes.id || "";
+ this.picker = getStringOption(attributes.picker, ["host", "none"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.comb = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle(this, "border", "font", "margin");
+ const field = this[$getParent]()[$getParent]();
+ const html = {
+ name: "input",
+ attributes: {
+ type: "text",
+ fieldId: field[$uid],
+ dataId: field[$data]?.[$uid] || field[$uid],
+ class: ["xfaTextfield"],
+ style,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ }
+ };
+ if (isRequired(field)) {
+ html.attributes["aria-required"] = true;
+ html.attributes.required = true;
+ }
+ return HTMLResult.success({
+ name: "label",
+ attributes: {
+ class: ["xfaLabel"]
+ },
+ children: [html]
+ });
+ }
+}
+class Decimal extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "decimal");
+ this.fracDigits = getInteger({
+ data: attributes.fracDigits,
+ defaultValue: 2,
+ validate: x => true
+ });
+ this.id = attributes.id || "";
+ this.leadDigits = getInteger({
+ data: attributes.leadDigits,
+ defaultValue: -1,
+ validate: x => true
+ });
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const number = parseFloat(this[$content].trim());
+ this[$content] = isNaN(number) ? null : number;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] !== null ? this[$content].toString() : "");
+ }
+}
+class DefaultUi extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "defaultUi", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+}
+class Desc extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "desc", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.boolean = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ }
+}
+class DigestMethod extends OptionObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "digestMethod", ["", "SHA1", "SHA256", "SHA512", "RIPEMD160"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class DigestMethods extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "digestMethods", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.digestMethod = new XFAObjectArray();
+ }
+}
+class Draw extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "draw", true);
+ this.anchorType = getStringOption(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]);
+ this.colSpan = getInteger({
+ data: attributes.colSpan,
+ defaultValue: 1,
+ validate: n => n >= 1 || n === -1
+ });
+ this.h = attributes.h ? getMeasurement(attributes.h) : "";
+ this.hAlign = getStringOption(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]);
+ this.id = attributes.id || "";
+ this.locale = attributes.locale || "";
+ this.maxH = getMeasurement(attributes.maxH, "0pt");
+ this.maxW = getMeasurement(attributes.maxW, "0pt");
+ this.minH = getMeasurement(attributes.minH, "0pt");
+ this.minW = getMeasurement(attributes.minW, "0pt");
+ this.name = attributes.name || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.rotate = getInteger({
+ data: attributes.rotate,
+ defaultValue: 0,
+ validate: x => x % 90 === 0
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.w = attributes.w ? getMeasurement(attributes.w) : "";
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.assist = null;
+ this.border = null;
+ this.caption = null;
+ this.desc = null;
+ this.extras = null;
+ this.font = null;
+ this.keep = null;
+ this.margin = null;
+ this.para = null;
+ this.traversal = null;
+ this.ui = null;
+ this.value = null;
+ this.setProperty = new XFAObjectArray();
+ }
+ [$setValue](value) {
+ _setValue(this, value);
+ }
+ [$toHTML](availableSpace) {
+ setTabIndex(this);
+ if (this.presence === "hidden" || this.presence === "inactive") {
+ return HTMLResult.EMPTY;
+ }
+ fixDimensions(this);
+ this[$pushPara]();
+ const savedW = this.w;
+ const savedH = this.h;
+ const {
+ w,
+ h,
+ isBroken
+ } = layoutNode(this, availableSpace);
+ if (w && this.w === "") {
+ if (isBroken && this[$getSubformParent]()[$isThereMoreWidth]()) {
+ this[$popPara]();
+ return HTMLResult.FAILURE;
+ }
+ this.w = w;
+ }
+ if (h && this.h === "") {
+ this.h = h;
+ }
+ setFirstUnsplittable(this);
+ if (!checkDimensions(this, availableSpace)) {
+ this.w = savedW;
+ this.h = savedH;
+ this[$popPara]();
+ return HTMLResult.FAILURE;
+ }
+ unsetFirstUnsplittable(this);
+ const style = toStyle(this, "font", "hAlign", "dimensions", "position", "presence", "rotate", "anchorType", "border", "margin");
+ setMinMaxDimensions(this, style);
+ if (style.margin) {
+ style.padding = style.margin;
+ delete style.margin;
+ }
+ const classNames = ["xfaDraw"];
+ if (this.font) {
+ classNames.push("xfaFont");
+ }
+ if (isPrintOnly(this)) {
+ classNames.push("xfaPrintOnly");
+ }
+ const attributes = {
+ style,
+ id: this[$uid],
+ class: classNames
+ };
+ if (this.name) {
+ attributes.xfaName = this.name;
+ }
+ const html = {
+ name: "div",
+ attributes,
+ children: []
+ };
+ applyAssist(this, attributes);
+ const bbox = computeBbox(this, html, availableSpace);
+ const value = this.value ? this.value[$toHTML](availableSpace).html : null;
+ if (value === null) {
+ this.w = savedW;
+ this.h = savedH;
+ this[$popPara]();
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+ html.children.push(value);
+ setPara(this, style, value);
+ this.w = savedW;
+ this.h = savedH;
+ this[$popPara]();
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+}
+class Edge extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "edge", true);
+ this.cap = getStringOption(attributes.cap, ["square", "butt", "round"]);
+ this.id = attributes.id || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.stroke = getStringOption(attributes.stroke, ["solid", "dashDot", "dashDotDot", "dashed", "dotted", "embossed", "etched", "lowered", "raised"]);
+ this.thickness = getMeasurement(attributes.thickness, "0.5pt");
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle]() {
+ const style = toStyle(this, "visibility");
+ Object.assign(style, {
+ linecap: this.cap,
+ width: measureToString(this.thickness),
+ color: this.color ? this.color[$toStyle]() : "#000000",
+ style: ""
+ });
+ if (this.presence !== "visible") {
+ style.style = "none";
+ } else {
+ switch (this.stroke) {
+ case "solid":
+ style.style = "solid";
+ break;
+ case "dashDot":
+ style.style = "dashed";
+ break;
+ case "dashDotDot":
+ style.style = "dashed";
+ break;
+ case "dashed":
+ style.style = "dashed";
+ break;
+ case "dotted":
+ style.style = "dotted";
+ break;
+ case "embossed":
+ style.style = "ridge";
+ break;
+ case "etched":
+ style.style = "groove";
+ break;
+ case "lowered":
+ style.style = "inset";
+ break;
+ case "raised":
+ style.style = "outset";
+ break;
+ }
+ }
+ return style;
+ }
+}
+class Encoding extends OptionObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encoding", ["adbe.x509.rsa_sha1", "adbe.pkcs7.detached", "adbe.pkcs7.sha1"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Encodings extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encodings", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.encoding = new XFAObjectArray();
+ }
+}
+class Encrypt extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encrypt", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.certificate = null;
+ }
+}
+class EncryptData extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encryptData", true);
+ this.id = attributes.id || "";
+ this.operation = getStringOption(attributes.operation, ["encrypt", "decrypt"]);
+ this.target = attributes.target || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.filter = null;
+ this.manifest = null;
+ }
+}
+class Encryption extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encryption", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.certificate = new XFAObjectArray();
+ }
+}
+class EncryptionMethod extends OptionObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encryptionMethod", ["", "AES256-CBC", "TRIPLEDES-CBC", "AES128-CBC", "AES192-CBC"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class EncryptionMethods extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "encryptionMethods", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.encryptionMethod = new XFAObjectArray();
+ }
+}
+class Event extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "event", true);
+ this.activity = getStringOption(attributes.activity, ["click", "change", "docClose", "docReady", "enter", "exit", "full", "indexChange", "initialize", "mouseDown", "mouseEnter", "mouseExit", "mouseUp", "postExecute", "postOpen", "postPrint", "postSave", "postSign", "postSubmit", "preExecute", "preOpen", "prePrint", "preSave", "preSign", "preSubmit", "ready", "validationState"]);
+ this.id = attributes.id || "";
+ this.listen = getStringOption(attributes.listen, ["refOnly", "refAndDescendents"]);
+ this.name = attributes.name || "";
+ this.ref = attributes.ref || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.encryptData = null;
+ this.execute = null;
+ this.script = null;
+ this.signData = null;
+ this.submit = null;
+ }
+}
+class ExData extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "exData");
+ this.contentType = attributes.contentType || "";
+ this.href = attributes.href || "";
+ this.id = attributes.id || "";
+ this.maxLength = getInteger({
+ data: attributes.maxLength,
+ defaultValue: -1,
+ validate: x => x >= -1
+ });
+ this.name = attributes.name || "";
+ this.rid = attributes.rid || "";
+ this.transferEncoding = getStringOption(attributes.transferEncoding, ["none", "base64", "package"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$isCDATAXml]() {
+ return this.contentType === "text/html";
+ }
+ [$onChild](child) {
+ if (this.contentType === "text/html" && child[$namespaceId] === NamespaceIds.xhtml.id) {
+ this[$content] = child;
+ return true;
+ }
+ if (this.contentType === "text/xml") {
+ this[$content] = child;
+ return true;
+ }
+ return false;
+ }
+ [$toHTML](availableSpace) {
+ if (this.contentType !== "text/html" || !this[$content]) {
+ return HTMLResult.EMPTY;
+ }
+ return this[$content][$toHTML](availableSpace);
+ }
+}
+class ExObject extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "exObject", true);
+ this.archive = attributes.archive || "";
+ this.classId = attributes.classId || "";
+ this.codeBase = attributes.codeBase || "";
+ this.codeType = attributes.codeType || "";
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.boolean = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.exObject = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ }
+}
+class ExclGroup extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "exclGroup", true);
+ this.access = getStringOption(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]);
+ this.accessKey = attributes.accessKey || "";
+ this.anchorType = getStringOption(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]);
+ this.colSpan = getInteger({
+ data: attributes.colSpan,
+ defaultValue: 1,
+ validate: n => n >= 1 || n === -1
+ });
+ this.h = attributes.h ? getMeasurement(attributes.h) : "";
+ this.hAlign = getStringOption(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]);
+ this.id = attributes.id || "";
+ this.layout = getStringOption(attributes.layout, ["position", "lr-tb", "rl-row", "rl-tb", "row", "table", "tb"]);
+ this.maxH = getMeasurement(attributes.maxH, "0pt");
+ this.maxW = getMeasurement(attributes.maxW, "0pt");
+ this.minH = getMeasurement(attributes.minH, "0pt");
+ this.minW = getMeasurement(attributes.minW, "0pt");
+ this.name = attributes.name || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.w = attributes.w ? getMeasurement(attributes.w) : "";
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.assist = null;
+ this.bind = null;
+ this.border = null;
+ this.calculate = null;
+ this.caption = null;
+ this.desc = null;
+ this.extras = null;
+ this.margin = null;
+ this.para = null;
+ this.traversal = null;
+ this.validate = null;
+ this.connect = new XFAObjectArray();
+ this.event = new XFAObjectArray();
+ this.field = new XFAObjectArray();
+ this.setProperty = new XFAObjectArray();
+ }
+ [$isBindable]() {
+ return true;
+ }
+ [$hasSettableValue]() {
+ return true;
+ }
+ [$setValue](value) {
+ for (const field of this.field.children) {
+ if (!field.value) {
+ const nodeValue = new Value({});
+ field[$appendChild](nodeValue);
+ field.value = nodeValue;
+ }
+ field.value[$setValue](value);
+ }
+ }
+ [$isThereMoreWidth]() {
+ return this.layout.endsWith("-tb") && this[$extra].attempt === 0 && this[$extra].numberInLine > 0 || this[$getParent]()[$isThereMoreWidth]();
+ }
+ [$isSplittable]() {
+ const parent = this[$getSubformParent]();
+ if (!parent[$isSplittable]()) {
+ return false;
+ }
+ if (this[$extra]._isSplittable !== undefined) {
+ return this[$extra]._isSplittable;
+ }
+ if (this.layout === "position" || this.layout.includes("row")) {
+ this[$extra]._isSplittable = false;
+ return false;
+ }
+ if (parent.layout?.endsWith("-tb") && parent[$extra].numberInLine !== 0) {
+ return false;
+ }
+ this[$extra]._isSplittable = true;
+ return true;
+ }
+ [$flushHTML]() {
+ return flushHTML(this);
+ }
+ [$addHTML](html, bbox) {
+ addHTML(this, html, bbox);
+ }
+ [$getAvailableSpace]() {
+ return getAvailableSpace(this);
+ }
+ [$toHTML](availableSpace) {
+ setTabIndex(this);
+ if (this.presence === "hidden" || this.presence === "inactive" || this.h === 0 || this.w === 0) {
+ return HTMLResult.EMPTY;
+ }
+ fixDimensions(this);
+ const children = [];
+ const attributes = {
+ id: this[$uid],
+ class: []
+ };
+ setAccess(this, attributes.class);
+ if (!this[$extra]) {
+ this[$extra] = Object.create(null);
+ }
+ Object.assign(this[$extra], {
+ children,
+ attributes,
+ attempt: 0,
+ line: null,
+ numberInLine: 0,
+ availableSpace: {
+ width: Math.min(this.w || Infinity, availableSpace.width),
+ height: Math.min(this.h || Infinity, availableSpace.height)
+ },
+ width: 0,
+ height: 0,
+ prevHeight: 0,
+ currentWidth: 0
+ });
+ const isSplittable = this[$isSplittable]();
+ if (!isSplittable) {
+ setFirstUnsplittable(this);
+ }
+ if (!checkDimensions(this, availableSpace)) {
+ return HTMLResult.FAILURE;
+ }
+ const filter = new Set(["field"]);
+ if (this.layout.includes("row")) {
+ const columnWidths = this[$getSubformParent]().columnWidths;
+ if (Array.isArray(columnWidths) && columnWidths.length > 0) {
+ this[$extra].columnWidths = columnWidths;
+ this[$extra].currentColumn = 0;
+ }
+ }
+ const style = toStyle(this, "anchorType", "dimensions", "position", "presence", "border", "margin", "hAlign");
+ const classNames = ["xfaExclgroup"];
+ const cl = layoutClass(this);
+ if (cl) {
+ classNames.push(cl);
+ }
+ if (isPrintOnly(this)) {
+ classNames.push("xfaPrintOnly");
+ }
+ attributes.style = style;
+ attributes.class = classNames;
+ if (this.name) {
+ attributes.xfaName = this.name;
+ }
+ this[$pushPara]();
+ const isLrTb = this.layout === "lr-tb" || this.layout === "rl-tb";
+ const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1;
+ for (; this[$extra].attempt < maxRun; this[$extra].attempt++) {
+ if (isLrTb && this[$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) {
+ this[$extra].numberInLine = 0;
+ }
+ const result = this[$childrenToHTML]({
+ filter,
+ include: true
+ });
+ if (result.success) {
+ break;
+ }
+ if (result.isBreak()) {
+ this[$popPara]();
+ return result;
+ }
+ if (isLrTb && this[$extra].attempt === 0 && this[$extra].numberInLine === 0 && !this[$getTemplateRoot]()[$extra].noLayoutFailure) {
+ this[$extra].attempt = maxRun;
+ break;
+ }
+ }
+ this[$popPara]();
+ if (!isSplittable) {
+ unsetFirstUnsplittable(this);
+ }
+ if (this[$extra].attempt === maxRun) {
+ if (!isSplittable) {
+ delete this[$extra];
+ }
+ return HTMLResult.FAILURE;
+ }
+ let marginH = 0;
+ let marginV = 0;
+ if (this.margin) {
+ marginH = this.margin.leftInset + this.margin.rightInset;
+ marginV = this.margin.topInset + this.margin.bottomInset;
+ }
+ const width = Math.max(this[$extra].width + marginH, this.w || 0);
+ const height = Math.max(this[$extra].height + marginV, this.h || 0);
+ const bbox = [this.x, this.y, width, height];
+ if (this.w === "") {
+ style.width = measureToString(width);
+ }
+ if (this.h === "") {
+ style.height = measureToString(height);
+ }
+ const html = {
+ name: "div",
+ attributes,
+ children
+ };
+ applyAssist(this, attributes);
+ delete this[$extra];
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+}
+class Execute extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "execute");
+ this.connection = attributes.connection || "";
+ this.executeType = getStringOption(attributes.executeType, ["import", "remerge"]);
+ this.id = attributes.id || "";
+ this.runAt = getStringOption(attributes.runAt, ["client", "both", "server"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Extras extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "extras", true);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.boolean = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.extras = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ }
+}
+class Field extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "field", true);
+ this.access = getStringOption(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]);
+ this.accessKey = attributes.accessKey || "";
+ this.anchorType = getStringOption(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]);
+ this.colSpan = getInteger({
+ data: attributes.colSpan,
+ defaultValue: 1,
+ validate: n => n >= 1 || n === -1
+ });
+ this.h = attributes.h ? getMeasurement(attributes.h) : "";
+ this.hAlign = getStringOption(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]);
+ this.id = attributes.id || "";
+ this.locale = attributes.locale || "";
+ this.maxH = getMeasurement(attributes.maxH, "0pt");
+ this.maxW = getMeasurement(attributes.maxW, "0pt");
+ this.minH = getMeasurement(attributes.minH, "0pt");
+ this.minW = getMeasurement(attributes.minW, "0pt");
+ this.name = attributes.name || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.rotate = getInteger({
+ data: attributes.rotate,
+ defaultValue: 0,
+ validate: x => x % 90 === 0
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.w = attributes.w ? getMeasurement(attributes.w) : "";
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.assist = null;
+ this.bind = null;
+ this.border = null;
+ this.calculate = null;
+ this.caption = null;
+ this.desc = null;
+ this.extras = null;
+ this.font = null;
+ this.format = null;
+ this.items = new XFAObjectArray(2);
+ this.keep = null;
+ this.margin = null;
+ this.para = null;
+ this.traversal = null;
+ this.ui = null;
+ this.validate = null;
+ this.value = null;
+ this.bindItems = new XFAObjectArray();
+ this.connect = new XFAObjectArray();
+ this.event = new XFAObjectArray();
+ this.setProperty = new XFAObjectArray();
+ }
+ [$isBindable]() {
+ return true;
+ }
+ [$setValue](value) {
+ _setValue(this, value);
+ }
+ [$toHTML](availableSpace) {
+ setTabIndex(this);
+ if (!this.ui) {
+ this.ui = new Ui({});
+ this.ui[$globalData] = this[$globalData];
+ this[$appendChild](this.ui);
+ let node;
+ switch (this.items.children.length) {
+ case 0:
+ node = new TextEdit({});
+ this.ui.textEdit = node;
+ break;
+ case 1:
+ node = new CheckButton({});
+ this.ui.checkButton = node;
+ break;
+ case 2:
+ node = new ChoiceList({});
+ this.ui.choiceList = node;
+ break;
+ }
+ this.ui[$appendChild](node);
+ }
+ if (!this.ui || this.presence === "hidden" || this.presence === "inactive" || this.h === 0 || this.w === 0) {
+ return HTMLResult.EMPTY;
+ }
+ if (this.caption) {
+ delete this.caption[$extra];
+ }
+ this[$pushPara]();
+ const caption = this.caption ? this.caption[$toHTML](availableSpace).html : null;
+ const savedW = this.w;
+ const savedH = this.h;
+ let marginH = 0;
+ let marginV = 0;
+ if (this.margin) {
+ marginH = this.margin.leftInset + this.margin.rightInset;
+ marginV = this.margin.topInset + this.margin.bottomInset;
+ }
+ let borderDims = null;
+ if (this.w === "" || this.h === "") {
+ let width = null;
+ let height = null;
+ let uiW = 0;
+ let uiH = 0;
+ if (this.ui.checkButton) {
+ uiW = uiH = this.ui.checkButton.size;
+ } else {
+ const {
+ w,
+ h
+ } = layoutNode(this, availableSpace);
+ if (w !== null) {
+ uiW = w;
+ uiH = h;
+ } else {
+ uiH = fonts_getMetrics(this.font, true).lineNoGap;
+ }
+ }
+ borderDims = getBorderDims(this.ui[$getExtra]());
+ uiW += borderDims.w;
+ uiH += borderDims.h;
+ if (this.caption) {
+ const {
+ w,
+ h,
+ isBroken
+ } = this.caption[$getExtra](availableSpace);
+ if (isBroken && this[$getSubformParent]()[$isThereMoreWidth]()) {
+ this[$popPara]();
+ return HTMLResult.FAILURE;
+ }
+ width = w;
+ height = h;
+ switch (this.caption.placement) {
+ case "left":
+ case "right":
+ case "inline":
+ width += uiW;
+ break;
+ case "top":
+ case "bottom":
+ height += uiH;
+ break;
+ }
+ } else {
+ width = uiW;
+ height = uiH;
+ }
+ if (width && this.w === "") {
+ width += marginH;
+ this.w = Math.min(this.maxW <= 0 ? Infinity : this.maxW, this.minW + 1 < width ? width : this.minW);
+ }
+ if (height && this.h === "") {
+ height += marginV;
+ this.h = Math.min(this.maxH <= 0 ? Infinity : this.maxH, this.minH + 1 < height ? height : this.minH);
+ }
+ }
+ this[$popPara]();
+ fixDimensions(this);
+ setFirstUnsplittable(this);
+ if (!checkDimensions(this, availableSpace)) {
+ this.w = savedW;
+ this.h = savedH;
+ this[$popPara]();
+ return HTMLResult.FAILURE;
+ }
+ unsetFirstUnsplittable(this);
+ const style = toStyle(this, "font", "dimensions", "position", "rotate", "anchorType", "presence", "margin", "hAlign");
+ setMinMaxDimensions(this, style);
+ const classNames = ["xfaField"];
+ if (this.font) {
+ classNames.push("xfaFont");
+ }
+ if (isPrintOnly(this)) {
+ classNames.push("xfaPrintOnly");
+ }
+ const attributes = {
+ style,
+ id: this[$uid],
+ class: classNames
+ };
+ if (style.margin) {
+ style.padding = style.margin;
+ delete style.margin;
+ }
+ setAccess(this, classNames);
+ if (this.name) {
+ attributes.xfaName = this.name;
+ }
+ const children = [];
+ const html = {
+ name: "div",
+ attributes,
+ children
+ };
+ applyAssist(this, attributes);
+ const borderStyle = this.border ? this.border[$toStyle]() : null;
+ const bbox = computeBbox(this, html, availableSpace);
+ const ui = this.ui[$toHTML]().html;
+ if (!ui) {
+ Object.assign(style, borderStyle);
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+ if (this[$tabIndex]) {
+ if (ui.children?.[0]) {
+ ui.children[0].attributes.tabindex = this[$tabIndex];
+ } else {
+ ui.attributes.tabindex = this[$tabIndex];
+ }
+ }
+ if (!ui.attributes.style) {
+ ui.attributes.style = Object.create(null);
+ }
+ let aElement = null;
+ if (this.ui.button) {
+ if (ui.children.length === 1) {
+ [aElement] = ui.children.splice(0, 1);
+ }
+ Object.assign(ui.attributes.style, borderStyle);
+ } else {
+ Object.assign(style, borderStyle);
+ }
+ children.push(ui);
+ if (this.value) {
+ if (this.ui.imageEdit) {
+ ui.children.push(this.value[$toHTML]().html);
+ } else if (!this.ui.button) {
+ let value = "";
+ if (this.value.exData) {
+ value = this.value.exData[$text]();
+ } else if (this.value.text) {
+ value = this.value.text[$getExtra]();
+ } else {
+ const htmlValue = this.value[$toHTML]().html;
+ if (htmlValue !== null) {
+ value = htmlValue.children[0].value;
+ }
+ }
+ if (this.ui.textEdit && this.value.text?.maxChars) {
+ ui.children[0].attributes.maxLength = this.value.text.maxChars;
+ }
+ if (value) {
+ if (this.ui.numericEdit) {
+ value = parseFloat(value);
+ value = isNaN(value) ? "" : value.toString();
+ }
+ if (ui.children[0].name === "textarea") {
+ ui.children[0].attributes.textContent = value;
+ } else {
+ ui.children[0].attributes.value = value;
+ }
+ }
+ }
+ }
+ if (!this.ui.imageEdit && ui.children?.[0] && this.h) {
+ borderDims = borderDims || getBorderDims(this.ui[$getExtra]());
+ let captionHeight = 0;
+ if (this.caption && ["top", "bottom"].includes(this.caption.placement)) {
+ captionHeight = this.caption.reserve;
+ if (captionHeight <= 0) {
+ captionHeight = this.caption[$getExtra](availableSpace).h;
+ }
+ const inputHeight = this.h - captionHeight - marginV - borderDims.h;
+ ui.children[0].attributes.style.height = measureToString(inputHeight);
+ } else {
+ ui.children[0].attributes.style.height = "100%";
+ }
+ }
+ if (aElement) {
+ ui.children.push(aElement);
+ }
+ if (!caption) {
+ if (ui.attributes.class) {
+ ui.attributes.class.push("xfaLeft");
+ }
+ this.w = savedW;
+ this.h = savedH;
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+ if (this.ui.button) {
+ if (style.padding) {
+ delete style.padding;
+ }
+ if (caption.name === "div") {
+ caption.name = "span";
+ }
+ ui.children.push(caption);
+ return HTMLResult.success(html, bbox);
+ } else if (this.ui.checkButton) {
+ caption.attributes.class[0] = "xfaCaptionForCheckButton";
+ }
+ if (!ui.attributes.class) {
+ ui.attributes.class = [];
+ }
+ ui.children.splice(0, 0, caption);
+ switch (this.caption.placement) {
+ case "left":
+ ui.attributes.class.push("xfaLeft");
+ break;
+ case "right":
+ ui.attributes.class.push("xfaRight");
+ break;
+ case "top":
+ ui.attributes.class.push("xfaTop");
+ break;
+ case "bottom":
+ ui.attributes.class.push("xfaBottom");
+ break;
+ case "inline":
+ ui.attributes.class.push("xfaLeft");
+ break;
+ }
+ this.w = savedW;
+ this.h = savedH;
+ return HTMLResult.success(createWrapper(this, html), bbox);
+ }
+}
+class Fill extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "fill", true);
+ this.id = attributes.id || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ this.linear = null;
+ this.pattern = null;
+ this.radial = null;
+ this.solid = null;
+ this.stipple = null;
+ }
+ [$toStyle]() {
+ const parent = this[$getParent]();
+ const grandpa = parent[$getParent]();
+ const ggrandpa = grandpa[$getParent]();
+ const style = Object.create(null);
+ let propName = "color";
+ let altPropName = propName;
+ if (parent instanceof Border) {
+ propName = "background-color";
+ altPropName = "background";
+ if (ggrandpa instanceof Ui) {
+ style.backgroundColor = "white";
+ }
+ }
+ if (parent instanceof Rectangle || parent instanceof Arc) {
+ propName = altPropName = "fill";
+ style.fill = "white";
+ }
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (name === "extras" || name === "color") {
+ continue;
+ }
+ const obj = this[name];
+ if (!(obj instanceof XFAObject)) {
+ continue;
+ }
+ const color = obj[$toStyle](this.color);
+ if (color) {
+ style[color.startsWith("#") ? propName : altPropName] = color;
+ }
+ return style;
+ }
+ if (this.color?.value) {
+ const color = this.color[$toStyle]();
+ style[color.startsWith("#") ? propName : altPropName] = color;
+ }
+ return style;
+ }
+}
+class Filter extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "filter", true);
+ this.addRevocationInfo = getStringOption(attributes.addRevocationInfo, ["", "required", "optional", "none"]);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.version = getInteger({
+ data: this.version,
+ defaultValue: 5,
+ validate: x => x >= 1 && x <= 5
+ });
+ this.appearanceFilter = null;
+ this.certificates = null;
+ this.digestMethods = null;
+ this.encodings = null;
+ this.encryptionMethods = null;
+ this.handler = null;
+ this.lockDocument = null;
+ this.mdp = null;
+ this.reasons = null;
+ this.timeStamp = null;
+ }
+}
+class Float extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "float");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const number = parseFloat(this[$content].trim());
+ this[$content] = isNaN(number) ? null : number;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] !== null ? this[$content].toString() : "");
+ }
+}
+class template_Font extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "font", true);
+ this.baselineShift = getMeasurement(attributes.baselineShift);
+ this.fontHorizontalScale = getFloat({
+ data: attributes.fontHorizontalScale,
+ defaultValue: 100,
+ validate: x => x >= 0
+ });
+ this.fontVerticalScale = getFloat({
+ data: attributes.fontVerticalScale,
+ defaultValue: 100,
+ validate: x => x >= 0
+ });
+ this.id = attributes.id || "";
+ this.kerningMode = getStringOption(attributes.kerningMode, ["none", "pair"]);
+ this.letterSpacing = getMeasurement(attributes.letterSpacing, "0");
+ this.lineThrough = getInteger({
+ data: attributes.lineThrough,
+ defaultValue: 0,
+ validate: x => x === 1 || x === 2
+ });
+ this.lineThroughPeriod = getStringOption(attributes.lineThroughPeriod, ["all", "word"]);
+ this.overline = getInteger({
+ data: attributes.overline,
+ defaultValue: 0,
+ validate: x => x === 1 || x === 2
+ });
+ this.overlinePeriod = getStringOption(attributes.overlinePeriod, ["all", "word"]);
+ this.posture = getStringOption(attributes.posture, ["normal", "italic"]);
+ this.size = getMeasurement(attributes.size, "10pt");
+ this.typeface = attributes.typeface || "Courier";
+ this.underline = getInteger({
+ data: attributes.underline,
+ defaultValue: 0,
+ validate: x => x === 1 || x === 2
+ });
+ this.underlinePeriod = getStringOption(attributes.underlinePeriod, ["all", "word"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.weight = getStringOption(attributes.weight, ["normal", "bold"]);
+ this.extras = null;
+ this.fill = null;
+ }
+ [$clean](builder) {
+ super[$clean](builder);
+ this[$globalData].usedTypefaces.add(this.typeface);
+ }
+ [$toStyle]() {
+ const style = toStyle(this, "fill");
+ const color = style.color;
+ if (color) {
+ if (color === "#000000") {
+ delete style.color;
+ } else if (!color.startsWith("#")) {
+ style.background = color;
+ style.backgroundClip = "text";
+ style.color = "transparent";
+ }
+ }
+ if (this.baselineShift) {
+ style.verticalAlign = measureToString(this.baselineShift);
+ }
+ style.fontKerning = this.kerningMode === "none" ? "none" : "normal";
+ style.letterSpacing = measureToString(this.letterSpacing);
+ if (this.lineThrough !== 0) {
+ style.textDecoration = "line-through";
+ if (this.lineThrough === 2) {
+ style.textDecorationStyle = "double";
+ }
+ }
+ if (this.overline !== 0) {
+ style.textDecoration = "overline";
+ if (this.overline === 2) {
+ style.textDecorationStyle = "double";
+ }
+ }
+ style.fontStyle = this.posture;
+ style.fontSize = measureToString(0.99 * this.size);
+ setFontFamily(this, this, this[$globalData].fontFinder, style);
+ if (this.underline !== 0) {
+ style.textDecoration = "underline";
+ if (this.underline === 2) {
+ style.textDecorationStyle = "double";
+ }
+ }
+ style.fontWeight = this.weight;
+ return style;
+ }
+}
+class Format extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "format", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.picture = null;
+ }
+}
+class Handler extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "handler");
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Hyphenation extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "hyphenation");
+ this.excludeAllCaps = getInteger({
+ data: attributes.excludeAllCaps,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.excludeInitialCap = getInteger({
+ data: attributes.excludeInitialCap,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.hyphenate = getInteger({
+ data: attributes.hyphenate,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.id = attributes.id || "";
+ this.pushCharacterCount = getInteger({
+ data: attributes.pushCharacterCount,
+ defaultValue: 3,
+ validate: x => x >= 0
+ });
+ this.remainCharacterCount = getInteger({
+ data: attributes.remainCharacterCount,
+ defaultValue: 3,
+ validate: x => x >= 0
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.wordCharacterCount = getInteger({
+ data: attributes.wordCharacterCount,
+ defaultValue: 7,
+ validate: x => x >= 0
+ });
+ }
+}
+class Image extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "image");
+ this.aspect = getStringOption(attributes.aspect, ["fit", "actual", "height", "none", "width"]);
+ this.contentType = attributes.contentType || "";
+ this.href = attributes.href || "";
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.transferEncoding = getStringOption(attributes.transferEncoding, ["base64", "none", "package"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$toHTML]() {
+ if (this.contentType && !MIMES.has(this.contentType.toLowerCase())) {
+ return HTMLResult.EMPTY;
+ }
+ let buffer = this[$globalData].images && this[$globalData].images.get(this.href);
+ if (!buffer && (this.href || !this[$content])) {
+ return HTMLResult.EMPTY;
+ }
+ if (!buffer && this.transferEncoding === "base64") {
+ buffer = stringToBytes(atob(this[$content]));
+ }
+ if (!buffer) {
+ return HTMLResult.EMPTY;
+ }
+ if (!this.contentType) {
+ for (const [header, type] of IMAGES_HEADERS) {
+ if (buffer.length > header.length && header.every((x, i) => x === buffer[i])) {
+ this.contentType = type;
+ break;
+ }
+ }
+ if (!this.contentType) {
+ return HTMLResult.EMPTY;
+ }
+ }
+ const blob = new Blob([buffer], {
+ type: this.contentType
+ });
+ let style;
+ switch (this.aspect) {
+ case "fit":
+ case "actual":
+ break;
+ case "height":
+ style = {
+ height: "100%",
+ objectFit: "fill"
+ };
+ break;
+ case "none":
+ style = {
+ width: "100%",
+ height: "100%",
+ objectFit: "fill"
+ };
+ break;
+ case "width":
+ style = {
+ width: "100%",
+ objectFit: "fill"
+ };
+ break;
+ }
+ const parent = this[$getParent]();
+ return HTMLResult.success({
+ name: "img",
+ attributes: {
+ class: ["xfaImage"],
+ style,
+ src: URL.createObjectURL(blob),
+ alt: parent ? ariaLabel(parent[$getParent]()) : null
+ }
+ });
+ }
+}
+class ImageEdit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "imageEdit", true);
+ this.data = getStringOption(attributes.data, ["link", "embed"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ if (this.data === "embed") {
+ return HTMLResult.success({
+ name: "div",
+ children: [],
+ attributes: {}
+ });
+ }
+ return HTMLResult.EMPTY;
+ }
+}
+class Integer extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "integer");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const number = parseInt(this[$content].trim(), 10);
+ this[$content] = isNaN(number) ? null : number;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] !== null ? this[$content].toString() : "");
+ }
+}
+class Issuers extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "issuers", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.certificate = new XFAObjectArray();
+ }
+}
+class Items extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "items", true);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.ref = attributes.ref || "";
+ this.save = getInteger({
+ data: attributes.save,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.boolean = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ }
+ [$toHTML]() {
+ const output = [];
+ for (const child of this[$getChildren]()) {
+ output.push(child[$text]());
+ }
+ return HTMLResult.success(output);
+ }
+}
+class Keep extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "keep", true);
+ this.id = attributes.id || "";
+ const options = ["none", "contentArea", "pageArea"];
+ this.intact = getStringOption(attributes.intact, options);
+ this.next = getStringOption(attributes.next, options);
+ this.previous = getStringOption(attributes.previous, options);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+}
+class KeyUsage extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "keyUsage");
+ const options = ["", "yes", "no"];
+ this.crlSign = getStringOption(attributes.crlSign, options);
+ this.dataEncipherment = getStringOption(attributes.dataEncipherment, options);
+ this.decipherOnly = getStringOption(attributes.decipherOnly, options);
+ this.digitalSignature = getStringOption(attributes.digitalSignature, options);
+ this.encipherOnly = getStringOption(attributes.encipherOnly, options);
+ this.id = attributes.id || "";
+ this.keyAgreement = getStringOption(attributes.keyAgreement, options);
+ this.keyCertSign = getStringOption(attributes.keyCertSign, options);
+ this.keyEncipherment = getStringOption(attributes.keyEncipherment, options);
+ this.nonRepudiation = getStringOption(attributes.nonRepudiation, options);
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Line extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "line", true);
+ this.hand = getStringOption(attributes.hand, ["even", "left", "right"]);
+ this.id = attributes.id || "";
+ this.slope = getStringOption(attributes.slope, ["\\", "/"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.edge = null;
+ }
+ [$toHTML]() {
+ const parent = this[$getParent]()[$getParent]();
+ const edge = this.edge || new Edge({});
+ const edgeStyle = edge[$toStyle]();
+ const style = Object.create(null);
+ const thickness = edge.presence === "visible" ? edge.thickness : 0;
+ style.strokeWidth = measureToString(thickness);
+ style.stroke = edgeStyle.color;
+ let x1, y1, x2, y2;
+ let width = "100%";
+ let height = "100%";
+ if (parent.w <= thickness) {
+ [x1, y1, x2, y2] = ["50%", 0, "50%", "100%"];
+ width = style.strokeWidth;
+ } else if (parent.h <= thickness) {
+ [x1, y1, x2, y2] = [0, "50%", "100%", "50%"];
+ height = style.strokeWidth;
+ } else if (this.slope === "\\") {
+ [x1, y1, x2, y2] = [0, 0, "100%", "100%"];
+ } else {
+ [x1, y1, x2, y2] = [0, "100%", "100%", 0];
+ }
+ const line = {
+ name: "line",
+ attributes: {
+ xmlns: SVG_NS,
+ x1,
+ y1,
+ x2,
+ y2,
+ style
+ }
+ };
+ const svg = {
+ name: "svg",
+ children: [line],
+ attributes: {
+ xmlns: SVG_NS,
+ width,
+ height,
+ style: {
+ overflow: "visible"
+ }
+ }
+ };
+ if (hasMargin(parent)) {
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ style: {
+ display: "inline",
+ width: "100%",
+ height: "100%"
+ }
+ },
+ children: [svg]
+ });
+ }
+ svg.attributes.style.position = "absolute";
+ return HTMLResult.success(svg);
+ }
+}
+class Linear extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "linear", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["toRight", "toBottom", "toLeft", "toTop"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle](startColor) {
+ startColor = startColor ? startColor[$toStyle]() : "#FFFFFF";
+ const transf = this.type.replace(/([RBLT])/, " $1").toLowerCase();
+ const endColor = this.color ? this.color[$toStyle]() : "#000000";
+ return `linear-gradient(${transf}, ${startColor}, ${endColor})`;
+ }
+}
+class LockDocument extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "lockDocument");
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ this[$content] = getStringOption(this[$content], ["auto", "0", "1"]);
+ }
+}
+class Manifest extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "manifest", true);
+ this.action = getStringOption(attributes.action, ["include", "all", "exclude"]);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.ref = new XFAObjectArray();
+ }
+}
+class Margin extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "margin", true);
+ this.bottomInset = getMeasurement(attributes.bottomInset, "0");
+ this.id = attributes.id || "";
+ this.leftInset = getMeasurement(attributes.leftInset, "0");
+ this.rightInset = getMeasurement(attributes.rightInset, "0");
+ this.topInset = getMeasurement(attributes.topInset, "0");
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+ [$toStyle]() {
+ return {
+ margin: measureToString(this.topInset) + " " + measureToString(this.rightInset) + " " + measureToString(this.bottomInset) + " " + measureToString(this.leftInset)
+ };
+ }
+}
+class Mdp extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "mdp");
+ this.id = attributes.id || "";
+ this.permissions = getInteger({
+ data: attributes.permissions,
+ defaultValue: 2,
+ validate: x => x === 1 || x === 3
+ });
+ this.signatureType = getStringOption(attributes.signatureType, ["filler", "author"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Medium extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "medium");
+ this.id = attributes.id || "";
+ this.imagingBBox = getBBox(attributes.imagingBBox);
+ this.long = getMeasurement(attributes.long);
+ this.orientation = getStringOption(attributes.orientation, ["portrait", "landscape"]);
+ this.short = getMeasurement(attributes.short);
+ this.stock = attributes.stock || "";
+ this.trayIn = getStringOption(attributes.trayIn, ["auto", "delegate", "pageFront"]);
+ this.trayOut = getStringOption(attributes.trayOut, ["auto", "delegate"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Message extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "message", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.text = new XFAObjectArray();
+ }
+}
+class NumericEdit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "numericEdit", true);
+ this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, ["auto", "off", "on"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.comb = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle(this, "border", "font", "margin");
+ const field = this[$getParent]()[$getParent]();
+ const html = {
+ name: "input",
+ attributes: {
+ type: "text",
+ fieldId: field[$uid],
+ dataId: field[$data]?.[$uid] || field[$uid],
+ class: ["xfaTextfield"],
+ style,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ }
+ };
+ if (isRequired(field)) {
+ html.attributes["aria-required"] = true;
+ html.attributes.required = true;
+ }
+ return HTMLResult.success({
+ name: "label",
+ attributes: {
+ class: ["xfaLabel"]
+ },
+ children: [html]
+ });
+ }
+}
+class Occur extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "occur", true);
+ this.id = attributes.id || "";
+ this.initial = attributes.initial !== "" ? getInteger({
+ data: attributes.initial,
+ defaultValue: "",
+ validate: x => true
+ }) : "";
+ this.max = attributes.max !== "" ? getInteger({
+ data: attributes.max,
+ defaultValue: 1,
+ validate: x => true
+ }) : "";
+ this.min = attributes.min !== "" ? getInteger({
+ data: attributes.min,
+ defaultValue: 1,
+ validate: x => true
+ }) : "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+ [$clean]() {
+ const parent = this[$getParent]();
+ const originalMin = this.min;
+ if (this.min === "") {
+ this.min = parent instanceof PageArea || parent instanceof PageSet ? 0 : 1;
+ }
+ if (this.max === "") {
+ if (originalMin === "") {
+ this.max = parent instanceof PageArea || parent instanceof PageSet ? -1 : 1;
+ } else {
+ this.max = this.min;
+ }
+ }
+ if (this.max !== -1 && this.max < this.min) {
+ this.max = this.min;
+ }
+ if (this.initial === "") {
+ this.initial = parent instanceof Template ? 1 : this.min;
+ }
+ }
+}
+class Oid extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "oid");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Oids extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "oids", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.oid = new XFAObjectArray();
+ }
+}
+class Overflow extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "overflow");
+ this.id = attributes.id || "";
+ this.leader = attributes.leader || "";
+ this.target = attributes.target || "";
+ this.trailer = attributes.trailer || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$getExtra]() {
+ if (!this[$extra]) {
+ const parent = this[$getParent]();
+ const root = this[$getTemplateRoot]();
+ const target = root[$searchNode](this.target, parent);
+ const leader = root[$searchNode](this.leader, parent);
+ const trailer = root[$searchNode](this.trailer, parent);
+ this[$extra] = {
+ target: target?.[0] || null,
+ leader: leader?.[0] || null,
+ trailer: trailer?.[0] || null,
+ addLeader: false,
+ addTrailer: false
+ };
+ }
+ return this[$extra];
+ }
+}
+class PageArea extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "pageArea", true);
+ this.blankOrNotBlank = getStringOption(attributes.blankOrNotBlank, ["any", "blank", "notBlank"]);
+ this.id = attributes.id || "";
+ this.initialNumber = getInteger({
+ data: attributes.initialNumber,
+ defaultValue: 1,
+ validate: x => true
+ });
+ this.name = attributes.name || "";
+ this.numbered = getInteger({
+ data: attributes.numbered,
+ defaultValue: 1,
+ validate: x => true
+ });
+ this.oddOrEven = getStringOption(attributes.oddOrEven, ["any", "even", "odd"]);
+ this.pagePosition = getStringOption(attributes.pagePosition, ["any", "first", "last", "only", "rest"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.desc = null;
+ this.extras = null;
+ this.medium = null;
+ this.occur = null;
+ this.area = new XFAObjectArray();
+ this.contentArea = new XFAObjectArray();
+ this.draw = new XFAObjectArray();
+ this.exclGroup = new XFAObjectArray();
+ this.field = new XFAObjectArray();
+ this.subform = new XFAObjectArray();
+ }
+ [$isUsable]() {
+ if (!this[$extra]) {
+ this[$extra] = {
+ numberOfUse: 0
+ };
+ return true;
+ }
+ return !this.occur || this.occur.max === -1 || this[$extra].numberOfUse < this.occur.max;
+ }
+ [$cleanPage]() {
+ delete this[$extra];
+ }
+ [$getNextPage]() {
+ if (!this[$extra]) {
+ this[$extra] = {
+ numberOfUse: 0
+ };
+ }
+ const parent = this[$getParent]();
+ if (parent.relation === "orderedOccurrence") {
+ if (this[$isUsable]()) {
+ this[$extra].numberOfUse += 1;
+ return this;
+ }
+ }
+ return parent[$getNextPage]();
+ }
+ [$getAvailableSpace]() {
+ return this[$extra].space || {
+ width: 0,
+ height: 0
+ };
+ }
+ [$toHTML]() {
+ if (!this[$extra]) {
+ this[$extra] = {
+ numberOfUse: 1
+ };
+ }
+ const children = [];
+ this[$extra].children = children;
+ const style = Object.create(null);
+ if (this.medium && this.medium.short && this.medium.long) {
+ style.width = measureToString(this.medium.short);
+ style.height = measureToString(this.medium.long);
+ this[$extra].space = {
+ width: this.medium.short,
+ height: this.medium.long
+ };
+ if (this.medium.orientation === "landscape") {
+ const x = style.width;
+ style.width = style.height;
+ style.height = x;
+ this[$extra].space = {
+ width: this.medium.long,
+ height: this.medium.short
+ };
+ }
+ } else {
+ warn("XFA - No medium specified in pageArea: please file a bug.");
+ }
+ this[$childrenToHTML]({
+ filter: new Set(["area", "draw", "field", "subform"]),
+ include: true
+ });
+ this[$childrenToHTML]({
+ filter: new Set(["contentArea"]),
+ include: true
+ });
+ return HTMLResult.success({
+ name: "div",
+ children,
+ attributes: {
+ class: ["xfaPage"],
+ id: this[$uid],
+ style,
+ xfaName: this.name
+ }
+ });
+ }
+}
+class PageSet extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "pageSet", true);
+ this.duplexImposition = getStringOption(attributes.duplexImposition, ["longEdge", "shortEdge"]);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.relation = getStringOption(attributes.relation, ["orderedOccurrence", "duplexPaginated", "simplexPaginated"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.occur = null;
+ this.pageArea = new XFAObjectArray();
+ this.pageSet = new XFAObjectArray();
+ }
+ [$cleanPage]() {
+ for (const page of this.pageArea.children) {
+ page[$cleanPage]();
+ }
+ for (const page of this.pageSet.children) {
+ page[$cleanPage]();
+ }
+ }
+ [$isUsable]() {
+ return !this.occur || this.occur.max === -1 || this[$extra].numberOfUse < this.occur.max;
+ }
+ [$getNextPage]() {
+ if (!this[$extra]) {
+ this[$extra] = {
+ numberOfUse: 1,
+ pageIndex: -1,
+ pageSetIndex: -1
+ };
+ }
+ if (this.relation === "orderedOccurrence") {
+ if (this[$extra].pageIndex + 1 < this.pageArea.children.length) {
+ this[$extra].pageIndex += 1;
+ const pageArea = this.pageArea.children[this[$extra].pageIndex];
+ return pageArea[$getNextPage]();
+ }
+ if (this[$extra].pageSetIndex + 1 < this.pageSet.children.length) {
+ this[$extra].pageSetIndex += 1;
+ return this.pageSet.children[this[$extra].pageSetIndex][$getNextPage]();
+ }
+ if (this[$isUsable]()) {
+ this[$extra].numberOfUse += 1;
+ this[$extra].pageIndex = -1;
+ this[$extra].pageSetIndex = -1;
+ return this[$getNextPage]();
+ }
+ const parent = this[$getParent]();
+ if (parent instanceof PageSet) {
+ return parent[$getNextPage]();
+ }
+ this[$cleanPage]();
+ return this[$getNextPage]();
+ }
+ const pageNumber = this[$getTemplateRoot]()[$extra].pageNumber;
+ const parity = pageNumber % 2 === 0 ? "even" : "odd";
+ const position = pageNumber === 0 ? "first" : "rest";
+ let page = this.pageArea.children.find(p => p.oddOrEven === parity && p.pagePosition === position);
+ if (page) {
+ return page;
+ }
+ page = this.pageArea.children.find(p => p.oddOrEven === "any" && p.pagePosition === position);
+ if (page) {
+ return page;
+ }
+ page = this.pageArea.children.find(p => p.oddOrEven === "any" && p.pagePosition === "any");
+ if (page) {
+ return page;
+ }
+ return this.pageArea.children[0];
+ }
+}
+class Para extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "para", true);
+ this.hAlign = getStringOption(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]);
+ this.id = attributes.id || "";
+ this.lineHeight = attributes.lineHeight ? getMeasurement(attributes.lineHeight, "0pt") : "";
+ this.marginLeft = attributes.marginLeft ? getMeasurement(attributes.marginLeft, "0pt") : "";
+ this.marginRight = attributes.marginRight ? getMeasurement(attributes.marginRight, "0pt") : "";
+ this.orphans = getInteger({
+ data: attributes.orphans,
+ defaultValue: 0,
+ validate: x => x >= 0
+ });
+ this.preserve = attributes.preserve || "";
+ this.radixOffset = attributes.radixOffset ? getMeasurement(attributes.radixOffset, "0pt") : "";
+ this.spaceAbove = attributes.spaceAbove ? getMeasurement(attributes.spaceAbove, "0pt") : "";
+ this.spaceBelow = attributes.spaceBelow ? getMeasurement(attributes.spaceBelow, "0pt") : "";
+ this.tabDefault = attributes.tabDefault ? getMeasurement(this.tabDefault) : "";
+ this.tabStops = (attributes.tabStops || "").trim().split(/\s+/).map((x, i) => i % 2 === 1 ? getMeasurement(x) : x);
+ this.textIndent = attributes.textIndent ? getMeasurement(attributes.textIndent, "0pt") : "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.vAlign = getStringOption(attributes.vAlign, ["top", "bottom", "middle"]);
+ this.widows = getInteger({
+ data: attributes.widows,
+ defaultValue: 0,
+ validate: x => x >= 0
+ });
+ this.hyphenation = null;
+ }
+ [$toStyle]() {
+ const style = toStyle(this, "hAlign");
+ if (this.marginLeft !== "") {
+ style.paddingLeft = measureToString(this.marginLeft);
+ }
+ if (this.marginRight !== "") {
+ style.paddingight = measureToString(this.marginRight);
+ }
+ if (this.spaceAbove !== "") {
+ style.paddingTop = measureToString(this.spaceAbove);
+ }
+ if (this.spaceBelow !== "") {
+ style.paddingBottom = measureToString(this.spaceBelow);
+ }
+ if (this.textIndent !== "") {
+ style.textIndent = measureToString(this.textIndent);
+ fixTextIndent(style);
+ }
+ if (this.lineHeight > 0) {
+ style.lineHeight = measureToString(this.lineHeight);
+ }
+ if (this.tabDefault !== "") {
+ style.tabSize = measureToString(this.tabDefault);
+ }
+ if (this.tabStops.length > 0) {}
+ if (this.hyphenatation) {
+ Object.assign(style, this.hyphenatation[$toStyle]());
+ }
+ return style;
+ }
+}
+class PasswordEdit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "passwordEdit", true);
+ this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, ["auto", "off", "on"]);
+ this.id = attributes.id || "";
+ this.passwordChar = attributes.passwordChar || "*";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.extras = null;
+ this.margin = null;
+ }
+}
+class template_Pattern extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "pattern", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["crossHatch", "crossDiagonal", "diagonalLeft", "diagonalRight", "horizontal", "vertical"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle](startColor) {
+ startColor = startColor ? startColor[$toStyle]() : "#FFFFFF";
+ const endColor = this.color ? this.color[$toStyle]() : "#000000";
+ const width = 5;
+ const cmd = "repeating-linear-gradient";
+ const colors = `${startColor},${startColor} ${width}px,${endColor} ${width}px,${endColor} ${2 * width}px`;
+ switch (this.type) {
+ case "crossHatch":
+ return `${cmd}(to top,${colors}) ${cmd}(to right,${colors})`;
+ case "crossDiagonal":
+ return `${cmd}(45deg,${colors}) ${cmd}(-45deg,${colors})`;
+ case "diagonalLeft":
+ return `${cmd}(45deg,${colors})`;
+ case "diagonalRight":
+ return `${cmd}(-45deg,${colors})`;
+ case "horizontal":
+ return `${cmd}(to top,${colors})`;
+ case "vertical":
+ return `${cmd}(to right,${colors})`;
+ }
+ return "";
+ }
+}
+class Picture extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "picture");
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Proto extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "proto", true);
+ this.appearanceFilter = new XFAObjectArray();
+ this.arc = new XFAObjectArray();
+ this.area = new XFAObjectArray();
+ this.assist = new XFAObjectArray();
+ this.barcode = new XFAObjectArray();
+ this.bindItems = new XFAObjectArray();
+ this.bookend = new XFAObjectArray();
+ this.boolean = new XFAObjectArray();
+ this.border = new XFAObjectArray();
+ this.break = new XFAObjectArray();
+ this.breakAfter = new XFAObjectArray();
+ this.breakBefore = new XFAObjectArray();
+ this.button = new XFAObjectArray();
+ this.calculate = new XFAObjectArray();
+ this.caption = new XFAObjectArray();
+ this.certificate = new XFAObjectArray();
+ this.certificates = new XFAObjectArray();
+ this.checkButton = new XFAObjectArray();
+ this.choiceList = new XFAObjectArray();
+ this.color = new XFAObjectArray();
+ this.comb = new XFAObjectArray();
+ this.connect = new XFAObjectArray();
+ this.contentArea = new XFAObjectArray();
+ this.corner = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.dateTimeEdit = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.defaultUi = new XFAObjectArray();
+ this.desc = new XFAObjectArray();
+ this.digestMethod = new XFAObjectArray();
+ this.digestMethods = new XFAObjectArray();
+ this.draw = new XFAObjectArray();
+ this.edge = new XFAObjectArray();
+ this.encoding = new XFAObjectArray();
+ this.encodings = new XFAObjectArray();
+ this.encrypt = new XFAObjectArray();
+ this.encryptData = new XFAObjectArray();
+ this.encryption = new XFAObjectArray();
+ this.encryptionMethod = new XFAObjectArray();
+ this.encryptionMethods = new XFAObjectArray();
+ this.event = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.exObject = new XFAObjectArray();
+ this.exclGroup = new XFAObjectArray();
+ this.execute = new XFAObjectArray();
+ this.extras = new XFAObjectArray();
+ this.field = new XFAObjectArray();
+ this.fill = new XFAObjectArray();
+ this.filter = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.font = new XFAObjectArray();
+ this.format = new XFAObjectArray();
+ this.handler = new XFAObjectArray();
+ this.hyphenation = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.imageEdit = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.issuers = new XFAObjectArray();
+ this.items = new XFAObjectArray();
+ this.keep = new XFAObjectArray();
+ this.keyUsage = new XFAObjectArray();
+ this.line = new XFAObjectArray();
+ this.linear = new XFAObjectArray();
+ this.lockDocument = new XFAObjectArray();
+ this.manifest = new XFAObjectArray();
+ this.margin = new XFAObjectArray();
+ this.mdp = new XFAObjectArray();
+ this.medium = new XFAObjectArray();
+ this.message = new XFAObjectArray();
+ this.numericEdit = new XFAObjectArray();
+ this.occur = new XFAObjectArray();
+ this.oid = new XFAObjectArray();
+ this.oids = new XFAObjectArray();
+ this.overflow = new XFAObjectArray();
+ this.pageArea = new XFAObjectArray();
+ this.pageSet = new XFAObjectArray();
+ this.para = new XFAObjectArray();
+ this.passwordEdit = new XFAObjectArray();
+ this.pattern = new XFAObjectArray();
+ this.picture = new XFAObjectArray();
+ this.radial = new XFAObjectArray();
+ this.reason = new XFAObjectArray();
+ this.reasons = new XFAObjectArray();
+ this.rectangle = new XFAObjectArray();
+ this.ref = new XFAObjectArray();
+ this.script = new XFAObjectArray();
+ this.setProperty = new XFAObjectArray();
+ this.signData = new XFAObjectArray();
+ this.signature = new XFAObjectArray();
+ this.signing = new XFAObjectArray();
+ this.solid = new XFAObjectArray();
+ this.speak = new XFAObjectArray();
+ this.stipple = new XFAObjectArray();
+ this.subform = new XFAObjectArray();
+ this.subformSet = new XFAObjectArray();
+ this.subjectDN = new XFAObjectArray();
+ this.subjectDNs = new XFAObjectArray();
+ this.submit = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.textEdit = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ this.timeStamp = new XFAObjectArray();
+ this.toolTip = new XFAObjectArray();
+ this.traversal = new XFAObjectArray();
+ this.traverse = new XFAObjectArray();
+ this.ui = new XFAObjectArray();
+ this.validate = new XFAObjectArray();
+ this.value = new XFAObjectArray();
+ this.variables = new XFAObjectArray();
+ }
+}
+class Radial extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "radial", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["toEdge", "toCenter"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle](startColor) {
+ startColor = startColor ? startColor[$toStyle]() : "#FFFFFF";
+ const endColor = this.color ? this.color[$toStyle]() : "#000000";
+ const colors = this.type === "toEdge" ? `${startColor},${endColor}` : `${endColor},${startColor}`;
+ return `radial-gradient(circle at center, ${colors})`;
+ }
+}
+class Reason extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "reason");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Reasons extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "reasons", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.reason = new XFAObjectArray();
+ }
+}
+class Rectangle extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "rectangle", true);
+ this.hand = getStringOption(attributes.hand, ["even", "left", "right"]);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.corner = new XFAObjectArray(4);
+ this.edge = new XFAObjectArray(4);
+ this.fill = null;
+ }
+ [$toHTML]() {
+ const edge = this.edge.children.length ? this.edge.children[0] : new Edge({});
+ const edgeStyle = edge[$toStyle]();
+ const style = Object.create(null);
+ if (this.fill?.presence === "visible") {
+ Object.assign(style, this.fill[$toStyle]());
+ } else {
+ style.fill = "transparent";
+ }
+ style.strokeWidth = measureToString(edge.presence === "visible" ? edge.thickness : 0);
+ style.stroke = edgeStyle.color;
+ const corner = this.corner.children.length ? this.corner.children[0] : new Corner({});
+ const cornerStyle = corner[$toStyle]();
+ const rect = {
+ name: "rect",
+ attributes: {
+ xmlns: SVG_NS,
+ width: "100%",
+ height: "100%",
+ x: 0,
+ y: 0,
+ rx: cornerStyle.radius,
+ ry: cornerStyle.radius,
+ style
+ }
+ };
+ const svg = {
+ name: "svg",
+ children: [rect],
+ attributes: {
+ xmlns: SVG_NS,
+ style: {
+ overflow: "visible"
+ },
+ width: "100%",
+ height: "100%"
+ }
+ };
+ const parent = this[$getParent]()[$getParent]();
+ if (hasMargin(parent)) {
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ style: {
+ display: "inline",
+ width: "100%",
+ height: "100%"
+ }
+ },
+ children: [svg]
+ });
+ }
+ svg.attributes.style.position = "absolute";
+ return HTMLResult.success(svg);
+ }
+}
+class RefElement extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "ref");
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Script extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "script");
+ this.binding = attributes.binding || "";
+ this.contentType = attributes.contentType || "";
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.runAt = getStringOption(attributes.runAt, ["client", "both", "server"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class SetProperty extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "setProperty");
+ this.connection = attributes.connection || "";
+ this.ref = attributes.ref || "";
+ this.target = attributes.target || "";
+ }
+}
+class SignData extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "signData", true);
+ this.id = attributes.id || "";
+ this.operation = getStringOption(attributes.operation, ["sign", "clear", "verify"]);
+ this.ref = attributes.ref || "";
+ this.target = attributes.target || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.filter = null;
+ this.manifest = null;
+ }
+}
+class Signature extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "signature", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["PDF1.3", "PDF1.6"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.border = null;
+ this.extras = null;
+ this.filter = null;
+ this.manifest = null;
+ this.margin = null;
+ }
+}
+class Signing extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "signing", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.certificate = new XFAObjectArray();
+ }
+}
+class Solid extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "solid", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ }
+ [$toStyle](startColor) {
+ return startColor ? startColor[$toStyle]() : "#FFFFFF";
+ }
+}
+class Speak extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "speak");
+ this.disable = getInteger({
+ data: attributes.disable,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.id = attributes.id || "";
+ this.priority = getStringOption(attributes.priority, ["custom", "caption", "name", "toolTip"]);
+ this.rid = attributes.rid || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Stipple extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "stipple", true);
+ this.id = attributes.id || "";
+ this.rate = getInteger({
+ data: attributes.rate,
+ defaultValue: 50,
+ validate: x => x >= 0 && x <= 100
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.color = null;
+ this.extras = null;
+ }
+ [$toStyle](bgColor) {
+ const alpha = this.rate / 100;
+ return Util.makeHexColor(Math.round(bgColor.value.r * (1 - alpha) + this.value.r * alpha), Math.round(bgColor.value.g * (1 - alpha) + this.value.g * alpha), Math.round(bgColor.value.b * (1 - alpha) + this.value.b * alpha));
+ }
+}
+class Subform extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "subform", true);
+ this.access = getStringOption(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]);
+ this.allowMacro = getInteger({
+ data: attributes.allowMacro,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.anchorType = getStringOption(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]);
+ this.colSpan = getInteger({
+ data: attributes.colSpan,
+ defaultValue: 1,
+ validate: n => n >= 1 || n === -1
+ });
+ this.columnWidths = (attributes.columnWidths || "").trim().split(/\s+/).map(x => x === "-1" ? -1 : getMeasurement(x));
+ this.h = attributes.h ? getMeasurement(attributes.h) : "";
+ this.hAlign = getStringOption(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]);
+ this.id = attributes.id || "";
+ this.layout = getStringOption(attributes.layout, ["position", "lr-tb", "rl-row", "rl-tb", "row", "table", "tb"]);
+ this.locale = attributes.locale || "";
+ this.maxH = getMeasurement(attributes.maxH, "0pt");
+ this.maxW = getMeasurement(attributes.maxW, "0pt");
+ this.mergeMode = getStringOption(attributes.mergeMode, ["consumeData", "matchTemplate"]);
+ this.minH = getMeasurement(attributes.minH, "0pt");
+ this.minW = getMeasurement(attributes.minW, "0pt");
+ this.name = attributes.name || "";
+ this.presence = getStringOption(attributes.presence, ["visible", "hidden", "inactive", "invisible"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.restoreState = getStringOption(attributes.restoreState, ["manual", "auto"]);
+ this.scope = getStringOption(attributes.scope, ["name", "none"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.w = attributes.w ? getMeasurement(attributes.w) : "";
+ this.x = getMeasurement(attributes.x, "0pt");
+ this.y = getMeasurement(attributes.y, "0pt");
+ this.assist = null;
+ this.bind = null;
+ this.bookend = null;
+ this.border = null;
+ this.break = null;
+ this.calculate = null;
+ this.desc = null;
+ this.extras = null;
+ this.keep = null;
+ this.margin = null;
+ this.occur = null;
+ this.overflow = null;
+ this.pageSet = null;
+ this.para = null;
+ this.traversal = null;
+ this.validate = null;
+ this.variables = null;
+ this.area = new XFAObjectArray();
+ this.breakAfter = new XFAObjectArray();
+ this.breakBefore = new XFAObjectArray();
+ this.connect = new XFAObjectArray();
+ this.draw = new XFAObjectArray();
+ this.event = new XFAObjectArray();
+ this.exObject = new XFAObjectArray();
+ this.exclGroup = new XFAObjectArray();
+ this.field = new XFAObjectArray();
+ this.proto = new XFAObjectArray();
+ this.setProperty = new XFAObjectArray();
+ this.subform = new XFAObjectArray();
+ this.subformSet = new XFAObjectArray();
+ }
+ [$getSubformParent]() {
+ const parent = this[$getParent]();
+ if (parent instanceof SubformSet) {
+ return parent[$getSubformParent]();
+ }
+ return parent;
+ }
+ [$isBindable]() {
+ return true;
+ }
+ [$isThereMoreWidth]() {
+ return this.layout.endsWith("-tb") && this[$extra].attempt === 0 && this[$extra].numberInLine > 0 || this[$getParent]()[$isThereMoreWidth]();
+ }
+ *[$getContainedChildren]() {
+ yield* getContainedChildren(this);
+ }
+ [$flushHTML]() {
+ return flushHTML(this);
+ }
+ [$addHTML](html, bbox) {
+ addHTML(this, html, bbox);
+ }
+ [$getAvailableSpace]() {
+ return getAvailableSpace(this);
+ }
+ [$isSplittable]() {
+ const parent = this[$getSubformParent]();
+ if (!parent[$isSplittable]()) {
+ return false;
+ }
+ if (this[$extra]._isSplittable !== undefined) {
+ return this[$extra]._isSplittable;
+ }
+ if (this.layout === "position" || this.layout.includes("row")) {
+ this[$extra]._isSplittable = false;
+ return false;
+ }
+ if (this.keep && this.keep.intact !== "none") {
+ this[$extra]._isSplittable = false;
+ return false;
+ }
+ if (parent.layout?.endsWith("-tb") && parent[$extra].numberInLine !== 0) {
+ return false;
+ }
+ this[$extra]._isSplittable = true;
+ return true;
+ }
+ [$toHTML](availableSpace) {
+ setTabIndex(this);
+ if (this.break) {
+ if (this.break.after !== "auto" || this.break.afterTarget !== "") {
+ const node = new BreakAfter({
+ targetType: this.break.after,
+ target: this.break.afterTarget,
+ startNew: this.break.startNew.toString()
+ });
+ node[$globalData] = this[$globalData];
+ this[$appendChild](node);
+ this.breakAfter.push(node);
+ }
+ if (this.break.before !== "auto" || this.break.beforeTarget !== "") {
+ const node = new BreakBefore({
+ targetType: this.break.before,
+ target: this.break.beforeTarget,
+ startNew: this.break.startNew.toString()
+ });
+ node[$globalData] = this[$globalData];
+ this[$appendChild](node);
+ this.breakBefore.push(node);
+ }
+ if (this.break.overflowTarget !== "") {
+ const node = new Overflow({
+ target: this.break.overflowTarget,
+ leader: this.break.overflowLeader,
+ trailer: this.break.overflowTrailer
+ });
+ node[$globalData] = this[$globalData];
+ this[$appendChild](node);
+ this.overflow.push(node);
+ }
+ this[$removeChild](this.break);
+ this.break = null;
+ }
+ if (this.presence === "hidden" || this.presence === "inactive") {
+ return HTMLResult.EMPTY;
+ }
+ if (this.breakBefore.children.length > 1 || this.breakAfter.children.length > 1) {
+ warn("XFA - Several breakBefore or breakAfter in subforms: please file a bug.");
+ }
+ if (this.breakBefore.children.length >= 1) {
+ const breakBefore = this.breakBefore.children[0];
+ if (handleBreak(breakBefore)) {
+ return HTMLResult.breakNode(breakBefore);
+ }
+ }
+ if (this[$extra]?.afterBreakAfter) {
+ return HTMLResult.EMPTY;
+ }
+ fixDimensions(this);
+ const children = [];
+ const attributes = {
+ id: this[$uid],
+ class: []
+ };
+ setAccess(this, attributes.class);
+ if (!this[$extra]) {
+ this[$extra] = Object.create(null);
+ }
+ Object.assign(this[$extra], {
+ children,
+ line: null,
+ attributes,
+ attempt: 0,
+ numberInLine: 0,
+ availableSpace: {
+ width: Math.min(this.w || Infinity, availableSpace.width),
+ height: Math.min(this.h || Infinity, availableSpace.height)
+ },
+ width: 0,
+ height: 0,
+ prevHeight: 0,
+ currentWidth: 0
+ });
+ const root = this[$getTemplateRoot]();
+ const savedNoLayoutFailure = root[$extra].noLayoutFailure;
+ const isSplittable = this[$isSplittable]();
+ if (!isSplittable) {
+ setFirstUnsplittable(this);
+ }
+ if (!checkDimensions(this, availableSpace)) {
+ return HTMLResult.FAILURE;
+ }
+ const filter = new Set(["area", "draw", "exclGroup", "field", "subform", "subformSet"]);
+ if (this.layout.includes("row")) {
+ const columnWidths = this[$getSubformParent]().columnWidths;
+ if (Array.isArray(columnWidths) && columnWidths.length > 0) {
+ this[$extra].columnWidths = columnWidths;
+ this[$extra].currentColumn = 0;
+ }
+ }
+ const style = toStyle(this, "anchorType", "dimensions", "position", "presence", "border", "margin", "hAlign");
+ const classNames = ["xfaSubform"];
+ const cl = layoutClass(this);
+ if (cl) {
+ classNames.push(cl);
+ }
+ attributes.style = style;
+ attributes.class = classNames;
+ if (this.name) {
+ attributes.xfaName = this.name;
+ }
+ if (this.overflow) {
+ const overflowExtra = this.overflow[$getExtra]();
+ if (overflowExtra.addLeader) {
+ overflowExtra.addLeader = false;
+ handleOverflow(this, overflowExtra.leader, availableSpace);
+ }
+ }
+ this[$pushPara]();
+ const isLrTb = this.layout === "lr-tb" || this.layout === "rl-tb";
+ const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1;
+ for (; this[$extra].attempt < maxRun; this[$extra].attempt++) {
+ if (isLrTb && this[$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) {
+ this[$extra].numberInLine = 0;
+ }
+ const result = this[$childrenToHTML]({
+ filter,
+ include: true
+ });
+ if (result.success) {
+ break;
+ }
+ if (result.isBreak()) {
+ this[$popPara]();
+ return result;
+ }
+ if (isLrTb && this[$extra].attempt === 0 && this[$extra].numberInLine === 0 && !root[$extra].noLayoutFailure) {
+ this[$extra].attempt = maxRun;
+ break;
+ }
+ }
+ this[$popPara]();
+ if (!isSplittable) {
+ unsetFirstUnsplittable(this);
+ }
+ root[$extra].noLayoutFailure = savedNoLayoutFailure;
+ if (this[$extra].attempt === maxRun) {
+ if (this.overflow) {
+ this[$getTemplateRoot]()[$extra].overflowNode = this.overflow;
+ }
+ if (!isSplittable) {
+ delete this[$extra];
+ }
+ return HTMLResult.FAILURE;
+ }
+ if (this.overflow) {
+ const overflowExtra = this.overflow[$getExtra]();
+ if (overflowExtra.addTrailer) {
+ overflowExtra.addTrailer = false;
+ handleOverflow(this, overflowExtra.trailer, availableSpace);
+ }
+ }
+ let marginH = 0;
+ let marginV = 0;
+ if (this.margin) {
+ marginH = this.margin.leftInset + this.margin.rightInset;
+ marginV = this.margin.topInset + this.margin.bottomInset;
+ }
+ const width = Math.max(this[$extra].width + marginH, this.w || 0);
+ const height = Math.max(this[$extra].height + marginV, this.h || 0);
+ const bbox = [this.x, this.y, width, height];
+ if (this.w === "") {
+ style.width = measureToString(width);
+ }
+ if (this.h === "") {
+ style.height = measureToString(height);
+ }
+ if ((style.width === "0px" || style.height === "0px") && children.length === 0) {
+ return HTMLResult.EMPTY;
+ }
+ const html = {
+ name: "div",
+ attributes,
+ children
+ };
+ applyAssist(this, attributes);
+ const result = HTMLResult.success(createWrapper(this, html), bbox);
+ if (this.breakAfter.children.length >= 1) {
+ const breakAfter = this.breakAfter.children[0];
+ if (handleBreak(breakAfter)) {
+ this[$extra].afterBreakAfter = result;
+ return HTMLResult.breakNode(breakAfter);
+ }
+ }
+ delete this[$extra];
+ return result;
+ }
+}
+class SubformSet extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "subformSet", true);
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.relation = getStringOption(attributes.relation, ["ordered", "choice", "unordered"]);
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.bookend = null;
+ this.break = null;
+ this.desc = null;
+ this.extras = null;
+ this.occur = null;
+ this.overflow = null;
+ this.breakAfter = new XFAObjectArray();
+ this.breakBefore = new XFAObjectArray();
+ this.subform = new XFAObjectArray();
+ this.subformSet = new XFAObjectArray();
+ }
+ *[$getContainedChildren]() {
+ yield* getContainedChildren(this);
+ }
+ [$getSubformParent]() {
+ let parent = this[$getParent]();
+ while (!(parent instanceof Subform)) {
+ parent = parent[$getParent]();
+ }
+ return parent;
+ }
+ [$isBindable]() {
+ return true;
+ }
+}
+class SubjectDN extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "subjectDN");
+ this.delimiter = attributes.delimiter || ",";
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ this[$content] = new Map(this[$content].split(this.delimiter).map(kv => {
+ kv = kv.split("=", 2);
+ kv[0] = kv[0].trim();
+ return kv;
+ }));
+ }
+}
+class SubjectDNs extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "subjectDNs", true);
+ this.id = attributes.id || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.subjectDN = new XFAObjectArray();
+ }
+}
+class Submit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "submit", true);
+ this.embedPDF = getInteger({
+ data: attributes.embedPDF,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.format = getStringOption(attributes.format, ["xdp", "formdata", "pdf", "urlencoded", "xfd", "xml"]);
+ this.id = attributes.id || "";
+ this.target = attributes.target || "";
+ this.textEncoding = getKeyword({
+ data: attributes.textEncoding ? attributes.textEncoding.toLowerCase() : "",
+ defaultValue: "",
+ validate: k => ["utf-8", "big-five", "fontspecific", "gbk", "gb-18030", "gb-2312", "ksc-5601", "none", "shift-jis", "ucs-2", "utf-16"].includes(k) || k.match(/iso-8859-\d{2}/)
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.xdpContent = attributes.xdpContent || "";
+ this.encrypt = null;
+ this.encryptData = new XFAObjectArray();
+ this.signData = new XFAObjectArray();
+ }
+}
+class Template extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "template", true);
+ this.baseProfile = getStringOption(attributes.baseProfile, ["full", "interactiveForms"]);
+ this.extras = null;
+ this.subform = new XFAObjectArray();
+ }
+ [$finalize]() {
+ if (this.subform.children.length === 0) {
+ warn("XFA - No subforms in template node.");
+ }
+ if (this.subform.children.length >= 2) {
+ warn("XFA - Several subforms in template node: please file a bug.");
+ }
+ this[$tabIndex] = DEFAULT_TAB_INDEX;
+ }
+ [$isSplittable]() {
+ return true;
+ }
+ [$searchNode](expr, container) {
+ if (expr.startsWith("#")) {
+ return [this[$ids].get(expr.slice(1))];
+ }
+ return searchNode(this, container, expr, true, true);
+ }
+ *[$toPages]() {
+ if (!this.subform.children.length) {
+ return HTMLResult.success({
+ name: "div",
+ children: []
+ });
+ }
+ this[$extra] = {
+ overflowNode: null,
+ firstUnsplittable: null,
+ currentContentArea: null,
+ currentPageArea: null,
+ noLayoutFailure: false,
+ pageNumber: 1,
+ pagePosition: "first",
+ oddOrEven: "odd",
+ blankOrNotBlank: "nonBlank",
+ paraStack: []
+ };
+ const root = this.subform.children[0];
+ root.pageSet[$cleanPage]();
+ const pageAreas = root.pageSet.pageArea.children;
+ const mainHtml = {
+ name: "div",
+ children: []
+ };
+ let pageArea = null;
+ let breakBefore = null;
+ let breakBeforeTarget = null;
+ if (root.breakBefore.children.length >= 1) {
+ breakBefore = root.breakBefore.children[0];
+ breakBeforeTarget = breakBefore.target;
+ } else if (root.subform.children.length >= 1 && root.subform.children[0].breakBefore.children.length >= 1) {
+ breakBefore = root.subform.children[0].breakBefore.children[0];
+ breakBeforeTarget = breakBefore.target;
+ } else if (root.break?.beforeTarget) {
+ breakBefore = root.break;
+ breakBeforeTarget = breakBefore.beforeTarget;
+ } else if (root.subform.children.length >= 1 && root.subform.children[0].break?.beforeTarget) {
+ breakBefore = root.subform.children[0].break;
+ breakBeforeTarget = breakBefore.beforeTarget;
+ }
+ if (breakBefore) {
+ const target = this[$searchNode](breakBeforeTarget, breakBefore[$getParent]());
+ if (target instanceof PageArea) {
+ pageArea = target;
+ breakBefore[$extra] = {};
+ }
+ }
+ if (!pageArea) {
+ pageArea = pageAreas[0];
+ }
+ pageArea[$extra] = {
+ numberOfUse: 1
+ };
+ const pageAreaParent = pageArea[$getParent]();
+ pageAreaParent[$extra] = {
+ numberOfUse: 1,
+ pageIndex: pageAreaParent.pageArea.children.indexOf(pageArea),
+ pageSetIndex: 0
+ };
+ let targetPageArea;
+ let leader = null;
+ let trailer = null;
+ let hasSomething = true;
+ let hasSomethingCounter = 0;
+ let startIndex = 0;
+ while (true) {
+ if (!hasSomething) {
+ mainHtml.children.pop();
+ if (++hasSomethingCounter === MAX_EMPTY_PAGES) {
+ warn("XFA - Something goes wrong: please file a bug.");
+ return mainHtml;
+ }
+ } else {
+ hasSomethingCounter = 0;
+ }
+ targetPageArea = null;
+ this[$extra].currentPageArea = pageArea;
+ const page = pageArea[$toHTML]().html;
+ mainHtml.children.push(page);
+ if (leader) {
+ this[$extra].noLayoutFailure = true;
+ page.children.push(leader[$toHTML](pageArea[$extra].space).html);
+ leader = null;
+ }
+ if (trailer) {
+ this[$extra].noLayoutFailure = true;
+ page.children.push(trailer[$toHTML](pageArea[$extra].space).html);
+ trailer = null;
+ }
+ const contentAreas = pageArea.contentArea.children;
+ const htmlContentAreas = page.children.filter(node => node.attributes.class.includes("xfaContentarea"));
+ hasSomething = false;
+ this[$extra].firstUnsplittable = null;
+ this[$extra].noLayoutFailure = false;
+ const flush = index => {
+ const html = root[$flushHTML]();
+ if (html) {
+ hasSomething ||= html.children?.length > 0;
+ htmlContentAreas[index].children.push(html);
+ }
+ };
+ for (let i = startIndex, ii = contentAreas.length; i < ii; i++) {
+ const contentArea = this[$extra].currentContentArea = contentAreas[i];
+ const space = {
+ width: contentArea.w,
+ height: contentArea.h
+ };
+ startIndex = 0;
+ if (leader) {
+ htmlContentAreas[i].children.push(leader[$toHTML](space).html);
+ leader = null;
+ }
+ if (trailer) {
+ htmlContentAreas[i].children.push(trailer[$toHTML](space).html);
+ trailer = null;
+ }
+ const html = root[$toHTML](space);
+ if (html.success) {
+ if (html.html) {
+ hasSomething ||= html.html.children?.length > 0;
+ htmlContentAreas[i].children.push(html.html);
+ } else if (!hasSomething && mainHtml.children.length > 1) {
+ mainHtml.children.pop();
+ }
+ return mainHtml;
+ }
+ if (html.isBreak()) {
+ const node = html.breakNode;
+ flush(i);
+ if (node.targetType === "auto") {
+ continue;
+ }
+ if (node.leader) {
+ leader = this[$searchNode](node.leader, node[$getParent]());
+ leader = leader ? leader[0] : null;
+ }
+ if (node.trailer) {
+ trailer = this[$searchNode](node.trailer, node[$getParent]());
+ trailer = trailer ? trailer[0] : null;
+ }
+ if (node.targetType === "pageArea") {
+ targetPageArea = node[$extra].target;
+ i = Infinity;
+ } else if (!node[$extra].target) {
+ i = node[$extra].index;
+ } else {
+ targetPageArea = node[$extra].target;
+ startIndex = node[$extra].index + 1;
+ i = Infinity;
+ }
+ continue;
+ }
+ if (this[$extra].overflowNode) {
+ const node = this[$extra].overflowNode;
+ this[$extra].overflowNode = null;
+ const overflowExtra = node[$getExtra]();
+ const target = overflowExtra.target;
+ overflowExtra.addLeader = overflowExtra.leader !== null;
+ overflowExtra.addTrailer = overflowExtra.trailer !== null;
+ flush(i);
+ const currentIndex = i;
+ i = Infinity;
+ if (target instanceof PageArea) {
+ targetPageArea = target;
+ } else if (target instanceof ContentArea) {
+ const index = contentAreas.indexOf(target);
+ if (index !== -1) {
+ if (index > currentIndex) {
+ i = index - 1;
+ } else {
+ startIndex = index;
+ }
+ } else {
+ targetPageArea = target[$getParent]();
+ startIndex = targetPageArea.contentArea.children.indexOf(target);
+ }
+ }
+ continue;
+ }
+ flush(i);
+ }
+ this[$extra].pageNumber += 1;
+ if (targetPageArea) {
+ if (targetPageArea[$isUsable]()) {
+ targetPageArea[$extra].numberOfUse += 1;
+ } else {
+ targetPageArea = null;
+ }
+ }
+ pageArea = targetPageArea || pageArea[$getNextPage]();
+ yield null;
+ }
+ }
+}
+class Text extends ContentObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "text");
+ this.id = attributes.id || "";
+ this.maxChars = getInteger({
+ data: attributes.maxChars,
+ defaultValue: 0,
+ validate: x => x >= 0
+ });
+ this.name = attributes.name || "";
+ this.rid = attributes.rid || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$acceptWhitespace]() {
+ return true;
+ }
+ [$onChild](child) {
+ if (child[$namespaceId] === NamespaceIds.xhtml.id) {
+ this[$content] = child;
+ return true;
+ }
+ warn(`XFA - Invalid content in Text: ${child[$nodeName]}.`);
+ return false;
+ }
+ [$onText](str) {
+ if (this[$content] instanceof XFAObject) {
+ return;
+ }
+ super[$onText](str);
+ }
+ [$finalize]() {
+ if (typeof this[$content] === "string") {
+ this[$content] = this[$content].replaceAll("\r\n", "\n");
+ }
+ }
+ [$getExtra]() {
+ if (typeof this[$content] === "string") {
+ return this[$content].split(/[\u2029\u2028\n]/).reduce((acc, line) => {
+ if (line) {
+ acc.push(line);
+ }
+ return acc;
+ }, []).join("\n");
+ }
+ return this[$content][$text]();
+ }
+ [$toHTML](availableSpace) {
+ if (typeof this[$content] === "string") {
+ const html = valueToHtml(this[$content]).html;
+ if (this[$content].includes("\u2029")) {
+ html.name = "div";
+ html.children = [];
+ this[$content].split("\u2029").map(para => para.split(/[\u2028\n]/).reduce((acc, line) => {
+ acc.push({
+ name: "span",
+ value: line
+ }, {
+ name: "br"
+ });
+ return acc;
+ }, [])).forEach(lines => {
+ html.children.push({
+ name: "p",
+ children: lines
+ });
+ });
+ } else if (/[\u2028\n]/.test(this[$content])) {
+ html.name = "div";
+ html.children = [];
+ this[$content].split(/[\u2028\n]/).forEach(line => {
+ html.children.push({
+ name: "span",
+ value: line
+ }, {
+ name: "br"
+ });
+ });
+ }
+ return HTMLResult.success(html);
+ }
+ return this[$content][$toHTML](availableSpace);
+ }
+}
+class TextEdit extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "textEdit", true);
+ this.allowRichText = getInteger({
+ data: attributes.allowRichText,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.hScrollPolicy = getStringOption(attributes.hScrollPolicy, ["auto", "off", "on"]);
+ this.id = attributes.id || "";
+ this.multiLine = getInteger({
+ data: attributes.multiLine,
+ defaultValue: "",
+ validate: x => x === 0 || x === 1
+ });
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.vScrollPolicy = getStringOption(attributes.vScrollPolicy, ["auto", "off", "on"]);
+ this.border = null;
+ this.comb = null;
+ this.extras = null;
+ this.margin = null;
+ }
+ [$toHTML](availableSpace) {
+ const style = toStyle(this, "border", "font", "margin");
+ let html;
+ const field = this[$getParent]()[$getParent]();
+ if (this.multiLine === "") {
+ this.multiLine = field instanceof Draw ? 1 : 0;
+ }
+ if (this.multiLine === 1) {
+ html = {
+ name: "textarea",
+ attributes: {
+ dataId: field[$data]?.[$uid] || field[$uid],
+ fieldId: field[$uid],
+ class: ["xfaTextfield"],
+ style,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ }
+ };
+ } else {
+ html = {
+ name: "input",
+ attributes: {
+ type: "text",
+ dataId: field[$data]?.[$uid] || field[$uid],
+ fieldId: field[$uid],
+ class: ["xfaTextfield"],
+ style,
+ "aria-label": ariaLabel(field),
+ "aria-required": false
+ }
+ };
+ }
+ if (isRequired(field)) {
+ html.attributes["aria-required"] = true;
+ html.attributes.required = true;
+ }
+ return HTMLResult.success({
+ name: "label",
+ attributes: {
+ class: ["xfaLabel"]
+ },
+ children: [html]
+ });
+ }
+}
+class Time extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "time");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+ [$finalize]() {
+ const date = this[$content].trim();
+ this[$content] = date ? new Date(date) : null;
+ }
+ [$toHTML](availableSpace) {
+ return valueToHtml(this[$content] ? this[$content].toString() : "");
+ }
+}
+class TimeStamp extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "timeStamp");
+ this.id = attributes.id || "";
+ this.server = attributes.server || "";
+ this.type = getStringOption(attributes.type, ["optional", "required"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class ToolTip extends StringObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "toolTip");
+ this.id = attributes.id || "";
+ this.rid = attributes.rid || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Traversal extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "traversal", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.traverse = new XFAObjectArray();
+ }
+}
+class Traverse extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "traverse", true);
+ this.id = attributes.id || "";
+ this.operation = getStringOption(attributes.operation, ["next", "back", "down", "first", "left", "right", "up"]);
+ this.ref = attributes.ref || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.script = null;
+ }
+ get name() {
+ return this.operation;
+ }
+ [$isTransparent]() {
+ return false;
+ }
+}
+class Ui extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "ui", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.picture = null;
+ this.barcode = null;
+ this.button = null;
+ this.checkButton = null;
+ this.choiceList = null;
+ this.dateTimeEdit = null;
+ this.defaultUi = null;
+ this.imageEdit = null;
+ this.numericEdit = null;
+ this.passwordEdit = null;
+ this.signature = null;
+ this.textEdit = null;
+ }
+ [$getExtra]() {
+ if (this[$extra] === undefined) {
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (name === "extras" || name === "picture") {
+ continue;
+ }
+ const obj = this[name];
+ if (!(obj instanceof XFAObject)) {
+ continue;
+ }
+ this[$extra] = obj;
+ return obj;
+ }
+ this[$extra] = null;
+ }
+ return this[$extra];
+ }
+ [$toHTML](availableSpace) {
+ const obj = this[$getExtra]();
+ if (obj) {
+ return obj[$toHTML](availableSpace);
+ }
+ return HTMLResult.EMPTY;
+ }
+}
+class Validate extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "validate", true);
+ this.formatTest = getStringOption(attributes.formatTest, ["warning", "disabled", "error"]);
+ this.id = attributes.id || "";
+ this.nullTest = getStringOption(attributes.nullTest, ["disabled", "error", "warning"]);
+ this.scriptTest = getStringOption(attributes.scriptTest, ["error", "disabled", "warning"]);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.extras = null;
+ this.message = null;
+ this.picture = null;
+ this.script = null;
+ }
+}
+class Value extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "value", true);
+ this.id = attributes.id || "";
+ this.override = getInteger({
+ data: attributes.override,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.relevant = getRelevant(attributes.relevant);
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.arc = null;
+ this.boolean = null;
+ this.date = null;
+ this.dateTime = null;
+ this.decimal = null;
+ this.exData = null;
+ this.float = null;
+ this.image = null;
+ this.integer = null;
+ this.line = null;
+ this.rectangle = null;
+ this.text = null;
+ this.time = null;
+ }
+ [$setValue](value) {
+ const parent = this[$getParent]();
+ if (parent instanceof Field) {
+ if (parent.ui?.imageEdit) {
+ if (!this.image) {
+ this.image = new Image({});
+ this[$appendChild](this.image);
+ }
+ this.image[$content] = value[$content];
+ return;
+ }
+ }
+ const valueName = value[$nodeName];
+ if (this[valueName] !== null) {
+ this[valueName][$content] = value[$content];
+ return;
+ }
+ for (const name of Object.getOwnPropertyNames(this)) {
+ const obj = this[name];
+ if (obj instanceof XFAObject) {
+ this[name] = null;
+ this[$removeChild](obj);
+ }
+ }
+ this[value[$nodeName]] = value;
+ this[$appendChild](value);
+ }
+ [$text]() {
+ if (this.exData) {
+ if (typeof this.exData[$content] === "string") {
+ return this.exData[$content].trim();
+ }
+ return this.exData[$content][$text]().trim();
+ }
+ for (const name of Object.getOwnPropertyNames(this)) {
+ if (name === "image") {
+ continue;
+ }
+ const obj = this[name];
+ if (obj instanceof XFAObject) {
+ return (obj[$content] || "").toString().trim();
+ }
+ }
+ return null;
+ }
+ [$toHTML](availableSpace) {
+ for (const name of Object.getOwnPropertyNames(this)) {
+ const obj = this[name];
+ if (!(obj instanceof XFAObject)) {
+ continue;
+ }
+ return obj[$toHTML](availableSpace);
+ }
+ return HTMLResult.EMPTY;
+ }
+}
+class Variables extends XFAObject {
+ constructor(attributes) {
+ super(TEMPLATE_NS_ID, "variables", true);
+ this.id = attributes.id || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ this.boolean = new XFAObjectArray();
+ this.date = new XFAObjectArray();
+ this.dateTime = new XFAObjectArray();
+ this.decimal = new XFAObjectArray();
+ this.exData = new XFAObjectArray();
+ this.float = new XFAObjectArray();
+ this.image = new XFAObjectArray();
+ this.integer = new XFAObjectArray();
+ this.manifest = new XFAObjectArray();
+ this.script = new XFAObjectArray();
+ this.text = new XFAObjectArray();
+ this.time = new XFAObjectArray();
+ }
+ [$isTransparent]() {
+ return true;
+ }
+}
+class TemplateNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (TemplateNamespace.hasOwnProperty(name)) {
+ const node = TemplateNamespace[name](attributes);
+ node[$setSetAttributes](attributes);
+ return node;
+ }
+ return undefined;
+ }
+ static appearanceFilter(attrs) {
+ return new AppearanceFilter(attrs);
+ }
+ static arc(attrs) {
+ return new Arc(attrs);
+ }
+ static area(attrs) {
+ return new Area(attrs);
+ }
+ static assist(attrs) {
+ return new Assist(attrs);
+ }
+ static barcode(attrs) {
+ return new Barcode(attrs);
+ }
+ static bind(attrs) {
+ return new Bind(attrs);
+ }
+ static bindItems(attrs) {
+ return new BindItems(attrs);
+ }
+ static bookend(attrs) {
+ return new Bookend(attrs);
+ }
+ static boolean(attrs) {
+ return new BooleanElement(attrs);
+ }
+ static border(attrs) {
+ return new Border(attrs);
+ }
+ static break(attrs) {
+ return new Break(attrs);
+ }
+ static breakAfter(attrs) {
+ return new BreakAfter(attrs);
+ }
+ static breakBefore(attrs) {
+ return new BreakBefore(attrs);
+ }
+ static button(attrs) {
+ return new Button(attrs);
+ }
+ static calculate(attrs) {
+ return new Calculate(attrs);
+ }
+ static caption(attrs) {
+ return new Caption(attrs);
+ }
+ static certificate(attrs) {
+ return new Certificate(attrs);
+ }
+ static certificates(attrs) {
+ return new Certificates(attrs);
+ }
+ static checkButton(attrs) {
+ return new CheckButton(attrs);
+ }
+ static choiceList(attrs) {
+ return new ChoiceList(attrs);
+ }
+ static color(attrs) {
+ return new Color(attrs);
+ }
+ static comb(attrs) {
+ return new Comb(attrs);
+ }
+ static connect(attrs) {
+ return new Connect(attrs);
+ }
+ static contentArea(attrs) {
+ return new ContentArea(attrs);
+ }
+ static corner(attrs) {
+ return new Corner(attrs);
+ }
+ static date(attrs) {
+ return new DateElement(attrs);
+ }
+ static dateTime(attrs) {
+ return new DateTime(attrs);
+ }
+ static dateTimeEdit(attrs) {
+ return new DateTimeEdit(attrs);
+ }
+ static decimal(attrs) {
+ return new Decimal(attrs);
+ }
+ static defaultUi(attrs) {
+ return new DefaultUi(attrs);
+ }
+ static desc(attrs) {
+ return new Desc(attrs);
+ }
+ static digestMethod(attrs) {
+ return new DigestMethod(attrs);
+ }
+ static digestMethods(attrs) {
+ return new DigestMethods(attrs);
+ }
+ static draw(attrs) {
+ return new Draw(attrs);
+ }
+ static edge(attrs) {
+ return new Edge(attrs);
+ }
+ static encoding(attrs) {
+ return new Encoding(attrs);
+ }
+ static encodings(attrs) {
+ return new Encodings(attrs);
+ }
+ static encrypt(attrs) {
+ return new Encrypt(attrs);
+ }
+ static encryptData(attrs) {
+ return new EncryptData(attrs);
+ }
+ static encryption(attrs) {
+ return new Encryption(attrs);
+ }
+ static encryptionMethod(attrs) {
+ return new EncryptionMethod(attrs);
+ }
+ static encryptionMethods(attrs) {
+ return new EncryptionMethods(attrs);
+ }
+ static event(attrs) {
+ return new Event(attrs);
+ }
+ static exData(attrs) {
+ return new ExData(attrs);
+ }
+ static exObject(attrs) {
+ return new ExObject(attrs);
+ }
+ static exclGroup(attrs) {
+ return new ExclGroup(attrs);
+ }
+ static execute(attrs) {
+ return new Execute(attrs);
+ }
+ static extras(attrs) {
+ return new Extras(attrs);
+ }
+ static field(attrs) {
+ return new Field(attrs);
+ }
+ static fill(attrs) {
+ return new Fill(attrs);
+ }
+ static filter(attrs) {
+ return new Filter(attrs);
+ }
+ static float(attrs) {
+ return new Float(attrs);
+ }
+ static font(attrs) {
+ return new template_Font(attrs);
+ }
+ static format(attrs) {
+ return new Format(attrs);
+ }
+ static handler(attrs) {
+ return new Handler(attrs);
+ }
+ static hyphenation(attrs) {
+ return new Hyphenation(attrs);
+ }
+ static image(attrs) {
+ return new Image(attrs);
+ }
+ static imageEdit(attrs) {
+ return new ImageEdit(attrs);
+ }
+ static integer(attrs) {
+ return new Integer(attrs);
+ }
+ static issuers(attrs) {
+ return new Issuers(attrs);
+ }
+ static items(attrs) {
+ return new Items(attrs);
+ }
+ static keep(attrs) {
+ return new Keep(attrs);
+ }
+ static keyUsage(attrs) {
+ return new KeyUsage(attrs);
+ }
+ static line(attrs) {
+ return new Line(attrs);
+ }
+ static linear(attrs) {
+ return new Linear(attrs);
+ }
+ static lockDocument(attrs) {
+ return new LockDocument(attrs);
+ }
+ static manifest(attrs) {
+ return new Manifest(attrs);
+ }
+ static margin(attrs) {
+ return new Margin(attrs);
+ }
+ static mdp(attrs) {
+ return new Mdp(attrs);
+ }
+ static medium(attrs) {
+ return new Medium(attrs);
+ }
+ static message(attrs) {
+ return new Message(attrs);
+ }
+ static numericEdit(attrs) {
+ return new NumericEdit(attrs);
+ }
+ static occur(attrs) {
+ return new Occur(attrs);
+ }
+ static oid(attrs) {
+ return new Oid(attrs);
+ }
+ static oids(attrs) {
+ return new Oids(attrs);
+ }
+ static overflow(attrs) {
+ return new Overflow(attrs);
+ }
+ static pageArea(attrs) {
+ return new PageArea(attrs);
+ }
+ static pageSet(attrs) {
+ return new PageSet(attrs);
+ }
+ static para(attrs) {
+ return new Para(attrs);
+ }
+ static passwordEdit(attrs) {
+ return new PasswordEdit(attrs);
+ }
+ static pattern(attrs) {
+ return new template_Pattern(attrs);
+ }
+ static picture(attrs) {
+ return new Picture(attrs);
+ }
+ static proto(attrs) {
+ return new Proto(attrs);
+ }
+ static radial(attrs) {
+ return new Radial(attrs);
+ }
+ static reason(attrs) {
+ return new Reason(attrs);
+ }
+ static reasons(attrs) {
+ return new Reasons(attrs);
+ }
+ static rectangle(attrs) {
+ return new Rectangle(attrs);
+ }
+ static ref(attrs) {
+ return new RefElement(attrs);
+ }
+ static script(attrs) {
+ return new Script(attrs);
+ }
+ static setProperty(attrs) {
+ return new SetProperty(attrs);
+ }
+ static signData(attrs) {
+ return new SignData(attrs);
+ }
+ static signature(attrs) {
+ return new Signature(attrs);
+ }
+ static signing(attrs) {
+ return new Signing(attrs);
+ }
+ static solid(attrs) {
+ return new Solid(attrs);
+ }
+ static speak(attrs) {
+ return new Speak(attrs);
+ }
+ static stipple(attrs) {
+ return new Stipple(attrs);
+ }
+ static subform(attrs) {
+ return new Subform(attrs);
+ }
+ static subformSet(attrs) {
+ return new SubformSet(attrs);
+ }
+ static subjectDN(attrs) {
+ return new SubjectDN(attrs);
+ }
+ static subjectDNs(attrs) {
+ return new SubjectDNs(attrs);
+ }
+ static submit(attrs) {
+ return new Submit(attrs);
+ }
+ static template(attrs) {
+ return new Template(attrs);
+ }
+ static text(attrs) {
+ return new Text(attrs);
+ }
+ static textEdit(attrs) {
+ return new TextEdit(attrs);
+ }
+ static time(attrs) {
+ return new Time(attrs);
+ }
+ static timeStamp(attrs) {
+ return new TimeStamp(attrs);
+ }
+ static toolTip(attrs) {
+ return new ToolTip(attrs);
+ }
+ static traversal(attrs) {
+ return new Traversal(attrs);
+ }
+ static traverse(attrs) {
+ return new Traverse(attrs);
+ }
+ static ui(attrs) {
+ return new Ui(attrs);
+ }
+ static validate(attrs) {
+ return new Validate(attrs);
+ }
+ static value(attrs) {
+ return new Value(attrs);
+ }
+ static variables(attrs) {
+ return new Variables(attrs);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/bind.js
+
+
+
+
+
+
+const bind_NS_DATASETS = NamespaceIds.datasets.id;
+function createText(content) {
+ const node = new Text({});
+ node[$content] = content;
+ return node;
+}
+class Binder {
+ constructor(root) {
+ this.root = root;
+ this.datasets = root.datasets;
+ this.data = root.datasets?.data || new XmlObject(NamespaceIds.datasets.id, "data");
+ this.emptyMerge = this.data[$getChildren]().length === 0;
+ this.root.form = this.form = root.template[$clone]();
+ }
+ _isConsumeData() {
+ return !this.emptyMerge && this._mergeMode;
+ }
+ _isMatchTemplate() {
+ return !this._isConsumeData();
+ }
+ bind() {
+ this._bindElement(this.form, this.data);
+ return this.form;
+ }
+ getData() {
+ return this.data;
+ }
+ _bindValue(formNode, data, picture) {
+ formNode[$data] = data;
+ if (formNode[$hasSettableValue]()) {
+ if (data[$isDataValue]()) {
+ const value = data[$getDataValue]();
+ formNode[$setValue](createText(value));
+ } else if (formNode instanceof Field && formNode.ui?.choiceList?.open === "multiSelect") {
+ const value = data[$getChildren]().map(child => child[$content].trim()).join("\n");
+ formNode[$setValue](createText(value));
+ } else if (this._isConsumeData()) {
+ warn(`XFA - Nodes haven't the same type.`);
+ }
+ } else if (!data[$isDataValue]() || this._isMatchTemplate()) {
+ this._bindElement(formNode, data);
+ } else {
+ warn(`XFA - Nodes haven't the same type.`);
+ }
+ }
+ _findDataByNameToConsume(name, isValue, dataNode, global) {
+ if (!name) {
+ return null;
+ }
+ let generator, match;
+ for (let i = 0; i < 3; i++) {
+ generator = dataNode[$getRealChildrenByNameIt](name, false, true);
+ while (true) {
+ match = generator.next().value;
+ if (!match) {
+ break;
+ }
+ if (isValue === match[$isDataValue]()) {
+ return match;
+ }
+ }
+ if (dataNode[$namespaceId] === NamespaceIds.datasets.id && dataNode[$nodeName] === "data") {
+ break;
+ }
+ dataNode = dataNode[$getParent]();
+ }
+ if (!global) {
+ return null;
+ }
+ generator = this.data[$getRealChildrenByNameIt](name, true, false);
+ match = generator.next().value;
+ if (match) {
+ return match;
+ }
+ generator = this.data[$getAttributeIt](name, true);
+ match = generator.next().value;
+ if (match?.[$isDataValue]()) {
+ return match;
+ }
+ return null;
+ }
+ _setProperties(formNode, dataNode) {
+ if (!formNode.hasOwnProperty("setProperty")) {
+ return;
+ }
+ for (const {
+ ref,
+ target,
+ connection
+ } of formNode.setProperty.children) {
+ if (connection) {
+ continue;
+ }
+ if (!ref) {
+ continue;
+ }
+ const nodes = searchNode(this.root, dataNode, ref, false, false);
+ if (!nodes) {
+ warn(`XFA - Invalid reference: ${ref}.`);
+ continue;
+ }
+ const [node] = nodes;
+ if (!node[$isDescendent](this.data)) {
+ warn(`XFA - Invalid node: must be a data node.`);
+ continue;
+ }
+ const targetNodes = searchNode(this.root, formNode, target, false, false);
+ if (!targetNodes) {
+ warn(`XFA - Invalid target: ${target}.`);
+ continue;
+ }
+ const [targetNode] = targetNodes;
+ if (!targetNode[$isDescendent](formNode)) {
+ warn(`XFA - Invalid target: must be a property or subproperty.`);
+ continue;
+ }
+ const targetParent = targetNode[$getParent]();
+ if (targetNode instanceof SetProperty || targetParent instanceof SetProperty) {
+ warn(`XFA - Invalid target: cannot be a setProperty or one of its properties.`);
+ continue;
+ }
+ if (targetNode instanceof BindItems || targetParent instanceof BindItems) {
+ warn(`XFA - Invalid target: cannot be a bindItems or one of its properties.`);
+ continue;
+ }
+ const content = node[$text]();
+ const name = targetNode[$nodeName];
+ if (targetNode instanceof XFAAttribute) {
+ const attrs = Object.create(null);
+ attrs[name] = content;
+ const obj = Reflect.construct(Object.getPrototypeOf(targetParent).constructor, [attrs]);
+ targetParent[name] = obj[name];
+ continue;
+ }
+ if (!targetNode.hasOwnProperty($content)) {
+ warn(`XFA - Invalid node to use in setProperty`);
+ continue;
+ }
+ targetNode[$data] = node;
+ targetNode[$content] = content;
+ targetNode[$finalize]();
+ }
+ }
+ _bindItems(formNode, dataNode) {
+ if (!formNode.hasOwnProperty("items") || !formNode.hasOwnProperty("bindItems") || formNode.bindItems.isEmpty()) {
+ return;
+ }
+ for (const item of formNode.items.children) {
+ formNode[$removeChild](item);
+ }
+ formNode.items.clear();
+ const labels = new Items({});
+ const values = new Items({});
+ formNode[$appendChild](labels);
+ formNode.items.push(labels);
+ formNode[$appendChild](values);
+ formNode.items.push(values);
+ for (const {
+ ref,
+ labelRef,
+ valueRef,
+ connection
+ } of formNode.bindItems.children) {
+ if (connection) {
+ continue;
+ }
+ if (!ref) {
+ continue;
+ }
+ const nodes = searchNode(this.root, dataNode, ref, false, false);
+ if (!nodes) {
+ warn(`XFA - Invalid reference: ${ref}.`);
+ continue;
+ }
+ for (const node of nodes) {
+ if (!node[$isDescendent](this.datasets)) {
+ warn(`XFA - Invalid ref (${ref}): must be a datasets child.`);
+ continue;
+ }
+ const labelNodes = searchNode(this.root, node, labelRef, true, false);
+ if (!labelNodes) {
+ warn(`XFA - Invalid label: ${labelRef}.`);
+ continue;
+ }
+ const [labelNode] = labelNodes;
+ if (!labelNode[$isDescendent](this.datasets)) {
+ warn(`XFA - Invalid label: must be a datasets child.`);
+ continue;
+ }
+ const valueNodes = searchNode(this.root, node, valueRef, true, false);
+ if (!valueNodes) {
+ warn(`XFA - Invalid value: ${valueRef}.`);
+ continue;
+ }
+ const [valueNode] = valueNodes;
+ if (!valueNode[$isDescendent](this.datasets)) {
+ warn(`XFA - Invalid value: must be a datasets child.`);
+ continue;
+ }
+ const label = createText(labelNode[$text]());
+ const value = createText(valueNode[$text]());
+ labels[$appendChild](label);
+ labels.text.push(label);
+ values[$appendChild](value);
+ values.text.push(value);
+ }
+ }
+ }
+ _bindOccurrences(formNode, matches, picture) {
+ let baseClone;
+ if (matches.length > 1) {
+ baseClone = formNode[$clone]();
+ baseClone[$removeChild](baseClone.occur);
+ baseClone.occur = null;
+ }
+ this._bindValue(formNode, matches[0], picture);
+ this._setProperties(formNode, matches[0]);
+ this._bindItems(formNode, matches[0]);
+ if (matches.length === 1) {
+ return;
+ }
+ const parent = formNode[$getParent]();
+ const name = formNode[$nodeName];
+ const pos = parent[$indexOf](formNode);
+ for (let i = 1, ii = matches.length; i < ii; i++) {
+ const match = matches[i];
+ const clone = baseClone[$clone]();
+ parent[name].push(clone);
+ parent[$insertAt](pos + i, clone);
+ this._bindValue(clone, match, picture);
+ this._setProperties(clone, match);
+ this._bindItems(clone, match);
+ }
+ }
+ _createOccurrences(formNode) {
+ if (!this.emptyMerge) {
+ return;
+ }
+ const {
+ occur
+ } = formNode;
+ if (!occur || occur.initial <= 1) {
+ return;
+ }
+ const parent = formNode[$getParent]();
+ const name = formNode[$nodeName];
+ if (!(parent[name] instanceof XFAObjectArray)) {
+ return;
+ }
+ let currentNumber;
+ if (formNode.name) {
+ currentNumber = parent[name].children.filter(e => e.name === formNode.name).length;
+ } else {
+ currentNumber = parent[name].children.length;
+ }
+ const pos = parent[$indexOf](formNode) + 1;
+ const ii = occur.initial - currentNumber;
+ if (ii) {
+ const nodeClone = formNode[$clone]();
+ nodeClone[$removeChild](nodeClone.occur);
+ nodeClone.occur = null;
+ parent[name].push(nodeClone);
+ parent[$insertAt](pos, nodeClone);
+ for (let i = 1; i < ii; i++) {
+ const clone = nodeClone[$clone]();
+ parent[name].push(clone);
+ parent[$insertAt](pos + i, clone);
+ }
+ }
+ }
+ _getOccurInfo(formNode) {
+ const {
+ name,
+ occur
+ } = formNode;
+ if (!occur || !name) {
+ return [1, 1];
+ }
+ const max = occur.max === -1 ? Infinity : occur.max;
+ return [occur.min, max];
+ }
+ _setAndBind(formNode, dataNode) {
+ this._setProperties(formNode, dataNode);
+ this._bindItems(formNode, dataNode);
+ this._bindElement(formNode, dataNode);
+ }
+ _bindElement(formNode, dataNode) {
+ const uselessNodes = [];
+ this._createOccurrences(formNode);
+ for (const child of formNode[$getChildren]()) {
+ if (child[$data]) {
+ continue;
+ }
+ if (this._mergeMode === undefined && child[$nodeName] === "subform") {
+ this._mergeMode = child.mergeMode === "consumeData";
+ const dataChildren = dataNode[$getChildren]();
+ if (dataChildren.length > 0) {
+ this._bindOccurrences(child, [dataChildren[0]], null);
+ } else if (this.emptyMerge) {
+ const nsId = dataNode[$namespaceId] === bind_NS_DATASETS ? -1 : dataNode[$namespaceId];
+ const dataChild = child[$data] = new XmlObject(nsId, child.name || "root");
+ dataNode[$appendChild](dataChild);
+ this._bindElement(child, dataChild);
+ }
+ continue;
+ }
+ if (!child[$isBindable]()) {
+ continue;
+ }
+ let global = false;
+ let picture = null;
+ let ref = null;
+ let match = null;
+ if (child.bind) {
+ switch (child.bind.match) {
+ case "none":
+ this._setAndBind(child, dataNode);
+ continue;
+ case "global":
+ global = true;
+ break;
+ case "dataRef":
+ if (!child.bind.ref) {
+ warn(`XFA - ref is empty in node ${child[$nodeName]}.`);
+ this._setAndBind(child, dataNode);
+ continue;
+ }
+ ref = child.bind.ref;
+ break;
+ default:
+ break;
+ }
+ if (child.bind.picture) {
+ picture = child.bind.picture[$content];
+ }
+ }
+ const [min, max] = this._getOccurInfo(child);
+ if (ref) {
+ match = searchNode(this.root, dataNode, ref, true, false);
+ if (match === null) {
+ match = createDataNode(this.data, dataNode, ref);
+ if (!match) {
+ continue;
+ }
+ if (this._isConsumeData()) {
+ match[$consumed] = true;
+ }
+ this._setAndBind(child, match);
+ continue;
+ } else {
+ if (this._isConsumeData()) {
+ match = match.filter(node => !node[$consumed]);
+ }
+ if (match.length > max) {
+ match = match.slice(0, max);
+ } else if (match.length === 0) {
+ match = null;
+ }
+ if (match && this._isConsumeData()) {
+ match.forEach(node => {
+ node[$consumed] = true;
+ });
+ }
+ }
+ } else {
+ if (!child.name) {
+ this._setAndBind(child, dataNode);
+ continue;
+ }
+ if (this._isConsumeData()) {
+ const matches = [];
+ while (matches.length < max) {
+ const found = this._findDataByNameToConsume(child.name, child[$hasSettableValue](), dataNode, global);
+ if (!found) {
+ break;
+ }
+ found[$consumed] = true;
+ matches.push(found);
+ }
+ match = matches.length > 0 ? matches : null;
+ } else {
+ match = dataNode[$getRealChildrenByNameIt](child.name, false, this.emptyMerge).next().value;
+ if (!match) {
+ if (min === 0) {
+ uselessNodes.push(child);
+ continue;
+ }
+ const nsId = dataNode[$namespaceId] === bind_NS_DATASETS ? -1 : dataNode[$namespaceId];
+ match = child[$data] = new XmlObject(nsId, child.name);
+ if (this.emptyMerge) {
+ match[$consumed] = true;
+ }
+ dataNode[$appendChild](match);
+ this._setAndBind(child, match);
+ continue;
+ }
+ if (this.emptyMerge) {
+ match[$consumed] = true;
+ }
+ match = [match];
+ }
+ }
+ if (match) {
+ this._bindOccurrences(child, match, picture);
+ } else if (min > 0) {
+ this._setAndBind(child, dataNode);
+ } else {
+ uselessNodes.push(child);
+ }
+ }
+ uselessNodes.forEach(node => node[$getParent]()[$removeChild](node));
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/data.js
+
+class DataHandler {
+ constructor(root, data) {
+ this.data = data;
+ this.dataset = root.datasets || null;
+ }
+ serialize(storage) {
+ const stack = [[-1, this.data[$getChildren]()]];
+ while (stack.length > 0) {
+ const last = stack.at(-1);
+ const [i, children] = last;
+ if (i + 1 === children.length) {
+ stack.pop();
+ continue;
+ }
+ const child = children[++last[0]];
+ const storageEntry = storage.get(child[$uid]);
+ if (storageEntry) {
+ child[$setValue](storageEntry);
+ } else {
+ const attributes = child[$getAttributes]();
+ for (const value of attributes.values()) {
+ const entry = storage.get(value[$uid]);
+ if (entry) {
+ value[$setValue](entry);
+ break;
+ }
+ }
+ }
+ const nodes = child[$getChildren]();
+ if (nodes.length > 0) {
+ stack.push([-1, nodes]);
+ }
+ }
+ const buf = [``];
+ if (this.dataset) {
+ for (const child of this.dataset[$getChildren]()) {
+ if (child[$nodeName] !== "data") {
+ child[$toString](buf);
+ }
+ }
+ }
+ this.data[$toString](buf);
+ buf.push("");
+ return buf.join("");
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/config.js
+
+
+
+
+
+const CONFIG_NS_ID = NamespaceIds.config.id;
+class Acrobat extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "acrobat", true);
+ this.acrobat7 = null;
+ this.autoSave = null;
+ this.common = null;
+ this.validate = null;
+ this.validateApprovalSignatures = null;
+ this.submitUrl = new XFAObjectArray();
+ }
+}
+class Acrobat7 extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "acrobat7", true);
+ this.dynamicRender = null;
+ }
+}
+class ADBE_JSConsole extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "ADBE_JSConsole", ["delegate", "Enable", "Disable"]);
+ }
+}
+class ADBE_JSDebugger extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "ADBE_JSDebugger", ["delegate", "Enable", "Disable"]);
+ }
+}
+class AddSilentPrint extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "addSilentPrint");
+ }
+}
+class AddViewerPreferences extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "addViewerPreferences");
+ }
+}
+class AdjustData extends Option10 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "adjustData");
+ }
+}
+class AdobeExtensionLevel extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "adobeExtensionLevel", 0, n => n >= 1 && n <= 8);
+ }
+}
+class Agent extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "agent", true);
+ this.name = attributes.name ? attributes.name.trim() : "";
+ this.common = new XFAObjectArray();
+ }
+}
+class AlwaysEmbed extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "alwaysEmbed");
+ }
+}
+class Amd extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "amd");
+ }
+}
+class config_Area extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "area");
+ this.level = getInteger({
+ data: attributes.level,
+ defaultValue: 0,
+ validate: n => n >= 1 && n <= 3
+ });
+ this.name = getStringOption(attributes.name, ["", "barcode", "coreinit", "deviceDriver", "font", "general", "layout", "merge", "script", "signature", "sourceSet", "templateCache"]);
+ }
+}
+class Attributes extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "attributes", ["preserve", "delegate", "ignore"]);
+ }
+}
+class AutoSave extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "autoSave", ["disabled", "enabled"]);
+ }
+}
+class Base extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "base");
+ }
+}
+class BatchOutput extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "batchOutput");
+ this.format = getStringOption(attributes.format, ["none", "concat", "zip", "zipCompress"]);
+ }
+}
+class BehaviorOverride extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "behaviorOverride");
+ }
+ [$finalize]() {
+ this[$content] = new Map(this[$content].trim().split(/\s+/).filter(x => x.includes(":")).map(x => x.split(":", 2)));
+ }
+}
+class Cache extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "cache", true);
+ this.templateCache = null;
+ }
+}
+class Change extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "change");
+ }
+}
+class Common extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "common", true);
+ this.data = null;
+ this.locale = null;
+ this.localeSet = null;
+ this.messaging = null;
+ this.suppressBanner = null;
+ this.template = null;
+ this.validationMessaging = null;
+ this.versionControl = null;
+ this.log = new XFAObjectArray();
+ }
+}
+class Compress extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "compress");
+ this.scope = getStringOption(attributes.scope, ["imageOnly", "document"]);
+ }
+}
+class CompressLogicalStructure extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "compressLogicalStructure");
+ }
+}
+class CompressObjectStream extends Option10 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "compressObjectStream");
+ }
+}
+class Compression extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "compression", true);
+ this.compressLogicalStructure = null;
+ this.compressObjectStream = null;
+ this.level = null;
+ this.type = null;
+ }
+}
+class Config extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "config", true);
+ this.acrobat = null;
+ this.present = null;
+ this.trace = null;
+ this.agent = new XFAObjectArray();
+ }
+}
+class Conformance extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "conformance", ["A", "B"]);
+ }
+}
+class ContentCopy extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "contentCopy");
+ }
+}
+class Copies extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "copies", 1, n => n >= 1);
+ }
+}
+class Creator extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "creator");
+ }
+}
+class CurrentPage extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "currentPage", 0, n => n >= 0);
+ }
+}
+class Data extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "data", true);
+ this.adjustData = null;
+ this.attributes = null;
+ this.incrementalLoad = null;
+ this.outputXSL = null;
+ this.range = null;
+ this.record = null;
+ this.startNode = null;
+ this.uri = null;
+ this.window = null;
+ this.xsl = null;
+ this.excludeNS = new XFAObjectArray();
+ this.transform = new XFAObjectArray();
+ }
+}
+class Debug extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "debug", true);
+ this.uri = null;
+ }
+}
+class DefaultTypeface extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "defaultTypeface");
+ this.writingScript = getStringOption(attributes.writingScript, ["*", "Arabic", "Cyrillic", "EastEuropeanRoman", "Greek", "Hebrew", "Japanese", "Korean", "Roman", "SimplifiedChinese", "Thai", "TraditionalChinese", "Vietnamese"]);
+ }
+}
+class Destination extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "destination", ["pdf", "pcl", "ps", "webClient", "zpl"]);
+ }
+}
+class DocumentAssembly extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "documentAssembly");
+ }
+}
+class Driver extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "driver", true);
+ this.name = attributes.name ? attributes.name.trim() : "";
+ this.fontInfo = null;
+ this.xdc = null;
+ }
+}
+class DuplexOption extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "duplexOption", ["simplex", "duplexFlipLongEdge", "duplexFlipShortEdge"]);
+ }
+}
+class DynamicRender extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "dynamicRender", ["forbidden", "required"]);
+ }
+}
+class Embed extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "embed");
+ }
+}
+class config_Encrypt extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "encrypt");
+ }
+}
+class config_Encryption extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "encryption", true);
+ this.encrypt = null;
+ this.encryptionLevel = null;
+ this.permissions = null;
+ }
+}
+class EncryptionLevel extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "encryptionLevel", ["40bit", "128bit"]);
+ }
+}
+class Enforce extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "enforce");
+ }
+}
+class Equate extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "equate");
+ this.force = getInteger({
+ data: attributes.force,
+ defaultValue: 1,
+ validate: n => n === 0
+ });
+ this.from = attributes.from || "";
+ this.to = attributes.to || "";
+ }
+}
+class EquateRange extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "equateRange");
+ this.from = attributes.from || "";
+ this.to = attributes.to || "";
+ this._unicodeRange = attributes.unicodeRange || "";
+ }
+ get unicodeRange() {
+ const ranges = [];
+ const unicodeRegex = /U\+([0-9a-fA-F]+)/;
+ const unicodeRange = this._unicodeRange;
+ for (let range of unicodeRange.split(",").map(x => x.trim()).filter(x => !!x)) {
+ range = range.split("-", 2).map(x => {
+ const found = x.match(unicodeRegex);
+ if (!found) {
+ return 0;
+ }
+ return parseInt(found[1], 16);
+ });
+ if (range.length === 1) {
+ range.push(range[0]);
+ }
+ ranges.push(range);
+ }
+ return shadow(this, "unicodeRange", ranges);
+ }
+}
+class Exclude extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "exclude");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim().split(/\s+/).filter(x => x && ["calculate", "close", "enter", "exit", "initialize", "ready", "validate"].includes(x));
+ }
+}
+class ExcludeNS extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "excludeNS");
+ }
+}
+class FlipLabel extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "flipLabel", ["usePrinterSetting", "on", "off"]);
+ }
+}
+class config_FontInfo extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "fontInfo", true);
+ this.embed = null;
+ this.map = null;
+ this.subsetBelow = null;
+ this.alwaysEmbed = new XFAObjectArray();
+ this.defaultTypeface = new XFAObjectArray();
+ this.neverEmbed = new XFAObjectArray();
+ }
+}
+class FormFieldFilling extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "formFieldFilling");
+ }
+}
+class GroupParent extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "groupParent");
+ }
+}
+class IfEmpty extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "ifEmpty", ["dataValue", "dataGroup", "ignore", "remove"]);
+ }
+}
+class IncludeXDPContent extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "includeXDPContent");
+ }
+}
+class IncrementalLoad extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "incrementalLoad", ["none", "forwardOnly"]);
+ }
+}
+class IncrementalMerge extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "incrementalMerge");
+ }
+}
+class Interactive extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "interactive");
+ }
+}
+class Jog extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "jog", ["usePrinterSetting", "none", "pageSet"]);
+ }
+}
+class LabelPrinter extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "labelPrinter", true);
+ this.name = getStringOption(attributes.name, ["zpl", "dpl", "ipl", "tcpl"]);
+ this.batchOutput = null;
+ this.flipLabel = null;
+ this.fontInfo = null;
+ this.xdc = null;
+ }
+}
+class Layout extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "layout", ["paginate", "panel"]);
+ }
+}
+class Level extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "level", 0, n => n > 0);
+ }
+}
+class Linearized extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "linearized");
+ }
+}
+class Locale extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "locale");
+ }
+}
+class LocaleSet extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "localeSet");
+ }
+}
+class Log extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "log", true);
+ this.mode = null;
+ this.threshold = null;
+ this.to = null;
+ this.uri = null;
+ }
+}
+class MapElement extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "map", true);
+ this.equate = new XFAObjectArray();
+ this.equateRange = new XFAObjectArray();
+ }
+}
+class MediumInfo extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "mediumInfo", true);
+ this.map = null;
+ }
+}
+class config_Message extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "message", true);
+ this.msgId = null;
+ this.severity = null;
+ }
+}
+class Messaging extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "messaging", true);
+ this.message = new XFAObjectArray();
+ }
+}
+class Mode extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "mode", ["append", "overwrite"]);
+ }
+}
+class ModifyAnnots extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "modifyAnnots");
+ }
+}
+class MsgId extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "msgId", 1, n => n >= 1);
+ }
+}
+class NameAttr extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "nameAttr");
+ }
+}
+class NeverEmbed extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "neverEmbed");
+ }
+}
+class NumberOfCopies extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "numberOfCopies", null, n => n >= 2 && n <= 5);
+ }
+}
+class OpenAction extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "openAction", true);
+ this.destination = null;
+ }
+}
+class Output extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "output", true);
+ this.to = null;
+ this.type = null;
+ this.uri = null;
+ }
+}
+class OutputBin extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "outputBin");
+ }
+}
+class OutputXSL extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "outputXSL", true);
+ this.uri = null;
+ }
+}
+class Overprint extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "overprint", ["none", "both", "draw", "field"]);
+ }
+}
+class Packets extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "packets");
+ }
+ [$finalize]() {
+ if (this[$content] === "*") {
+ return;
+ }
+ this[$content] = this[$content].trim().split(/\s+/).filter(x => ["config", "datasets", "template", "xfdf", "xslt"].includes(x));
+ }
+}
+class PageOffset extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pageOffset");
+ this.x = getInteger({
+ data: attributes.x,
+ defaultValue: "useXDCSetting",
+ validate: n => true
+ });
+ this.y = getInteger({
+ data: attributes.y,
+ defaultValue: "useXDCSetting",
+ validate: n => true
+ });
+ }
+}
+class PageRange extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pageRange");
+ }
+ [$finalize]() {
+ const numbers = this[$content].trim().split(/\s+/).map(x => parseInt(x, 10));
+ const ranges = [];
+ for (let i = 0, ii = numbers.length; i < ii; i += 2) {
+ ranges.push(numbers.slice(i, i + 2));
+ }
+ this[$content] = ranges;
+ }
+}
+class Pagination extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pagination", ["simplex", "duplexShortEdge", "duplexLongEdge"]);
+ }
+}
+class PaginationOverride extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "paginationOverride", ["none", "forceDuplex", "forceDuplexLongEdge", "forceDuplexShortEdge", "forceSimplex"]);
+ }
+}
+class Part extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "part", 1, n => false);
+ }
+}
+class Pcl extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pcl", true);
+ this.name = attributes.name || "";
+ this.batchOutput = null;
+ this.fontInfo = null;
+ this.jog = null;
+ this.mediumInfo = null;
+ this.outputBin = null;
+ this.pageOffset = null;
+ this.staple = null;
+ this.xdc = null;
+ }
+}
+class Pdf extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pdf", true);
+ this.name = attributes.name || "";
+ this.adobeExtensionLevel = null;
+ this.batchOutput = null;
+ this.compression = null;
+ this.creator = null;
+ this.encryption = null;
+ this.fontInfo = null;
+ this.interactive = null;
+ this.linearized = null;
+ this.openAction = null;
+ this.pdfa = null;
+ this.producer = null;
+ this.renderPolicy = null;
+ this.scriptModel = null;
+ this.silentPrint = null;
+ this.submitFormat = null;
+ this.tagged = null;
+ this.version = null;
+ this.viewerPreferences = null;
+ this.xdc = null;
+ }
+}
+class Pdfa extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pdfa", true);
+ this.amd = null;
+ this.conformance = null;
+ this.includeXDPContent = null;
+ this.part = null;
+ }
+}
+class Permissions extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "permissions", true);
+ this.accessibleContent = null;
+ this.change = null;
+ this.contentCopy = null;
+ this.documentAssembly = null;
+ this.formFieldFilling = null;
+ this.modifyAnnots = null;
+ this.plaintextMetadata = null;
+ this.print = null;
+ this.printHighQuality = null;
+ }
+}
+class PickTrayByPDFSize extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "pickTrayByPDFSize");
+ }
+}
+class config_Picture extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "picture");
+ }
+}
+class PlaintextMetadata extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "plaintextMetadata");
+ }
+}
+class Presence extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "presence", ["preserve", "dissolve", "dissolveStructure", "ignore", "remove"]);
+ }
+}
+class Present extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "present", true);
+ this.behaviorOverride = null;
+ this.cache = null;
+ this.common = null;
+ this.copies = null;
+ this.destination = null;
+ this.incrementalMerge = null;
+ this.layout = null;
+ this.output = null;
+ this.overprint = null;
+ this.pagination = null;
+ this.paginationOverride = null;
+ this.script = null;
+ this.validate = null;
+ this.xdp = null;
+ this.driver = new XFAObjectArray();
+ this.labelPrinter = new XFAObjectArray();
+ this.pcl = new XFAObjectArray();
+ this.pdf = new XFAObjectArray();
+ this.ps = new XFAObjectArray();
+ this.submitUrl = new XFAObjectArray();
+ this.webClient = new XFAObjectArray();
+ this.zpl = new XFAObjectArray();
+ }
+}
+class Print extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "print");
+ }
+}
+class PrintHighQuality extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "printHighQuality");
+ }
+}
+class PrintScaling extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "printScaling", ["appdefault", "noScaling"]);
+ }
+}
+class PrinterName extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "printerName");
+ }
+}
+class Producer extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "producer");
+ }
+}
+class Ps extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "ps", true);
+ this.name = attributes.name || "";
+ this.batchOutput = null;
+ this.fontInfo = null;
+ this.jog = null;
+ this.mediumInfo = null;
+ this.outputBin = null;
+ this.staple = null;
+ this.xdc = null;
+ }
+}
+class Range extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "range");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim().split(/\s*,\s*/, 2).map(range => range.split("-").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => {
+ if (range.length === 1) {
+ range.push(range[0]);
+ }
+ return range;
+ });
+ }
+}
+class Record extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "record");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim();
+ const n = parseInt(this[$content], 10);
+ if (!isNaN(n) && n >= 0) {
+ this[$content] = n;
+ }
+ }
+}
+class Relevant extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "relevant");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim().split(/\s+/);
+ }
+}
+class Rename extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "rename");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim();
+ if (this[$content].toLowerCase().startsWith("xml") || new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*", "u").test(this[$content])) {
+ warn("XFA - Rename: invalid XFA name");
+ }
+ }
+}
+class RenderPolicy extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "renderPolicy", ["server", "client"]);
+ }
+}
+class RunScripts extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "runScripts", ["both", "client", "none", "server"]);
+ }
+}
+class config_Script extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "script", true);
+ this.currentPage = null;
+ this.exclude = null;
+ this.runScripts = null;
+ }
+}
+class ScriptModel extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "scriptModel", ["XFA", "none"]);
+ }
+}
+class Severity extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "severity", ["ignore", "error", "information", "trace", "warning"]);
+ }
+}
+class SilentPrint extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "silentPrint", true);
+ this.addSilentPrint = null;
+ this.printerName = null;
+ }
+}
+class Staple extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "staple");
+ this.mode = getStringOption(attributes.mode, ["usePrinterSetting", "on", "off"]);
+ }
+}
+class StartNode extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "startNode");
+ }
+}
+class StartPage extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "startPage", 0, n => true);
+ }
+}
+class SubmitFormat extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "submitFormat", ["html", "delegate", "fdf", "xml", "pdf"]);
+ }
+}
+class SubmitUrl extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "submitUrl");
+ }
+}
+class SubsetBelow extends IntegerObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "subsetBelow", 100, n => n >= 0 && n <= 100);
+ }
+}
+class SuppressBanner extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "suppressBanner");
+ }
+}
+class Tagged extends Option01 {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "tagged");
+ }
+}
+class config_Template extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "template", true);
+ this.base = null;
+ this.relevant = null;
+ this.startPage = null;
+ this.uri = null;
+ this.xsl = null;
+ }
+}
+class Threshold extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "threshold", ["trace", "error", "information", "warning"]);
+ }
+}
+class To extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "to", ["null", "memory", "stderr", "stdout", "system", "uri"]);
+ }
+}
+class TemplateCache extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "templateCache");
+ this.maxEntries = getInteger({
+ data: attributes.maxEntries,
+ defaultValue: 5,
+ validate: n => n >= 0
+ });
+ }
+}
+class Trace extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "trace", true);
+ this.area = new XFAObjectArray();
+ }
+}
+class config_Transform extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "transform", true);
+ this.groupParent = null;
+ this.ifEmpty = null;
+ this.nameAttr = null;
+ this.picture = null;
+ this.presence = null;
+ this.rename = null;
+ this.whitespace = null;
+ }
+}
+class Type extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "type", ["none", "ascii85", "asciiHex", "ccittfax", "flate", "lzw", "runLength", "native", "xdp", "mergedXDP"]);
+ }
+}
+class Uri extends StringObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "uri");
+ }
+}
+class config_Validate extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "validate", ["preSubmit", "prePrint", "preExecute", "preSave"]);
+ }
+}
+class ValidateApprovalSignatures extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "validateApprovalSignatures");
+ }
+ [$finalize]() {
+ this[$content] = this[$content].trim().split(/\s+/).filter(x => ["docReady", "postSign"].includes(x));
+ }
+}
+class ValidationMessaging extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "validationMessaging", ["allMessagesIndividually", "allMessagesTogether", "firstMessageOnly", "noMessages"]);
+ }
+}
+class Version extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "version", ["1.7", "1.6", "1.5", "1.4", "1.3", "1.2"]);
+ }
+}
+class VersionControl extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "VersionControl");
+ this.outputBelow = getStringOption(attributes.outputBelow, ["warn", "error", "update"]);
+ this.sourceAbove = getStringOption(attributes.sourceAbove, ["warn", "error"]);
+ this.sourceBelow = getStringOption(attributes.sourceBelow, ["update", "maintain"]);
+ }
+}
+class ViewerPreferences extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "viewerPreferences", true);
+ this.ADBE_JSConsole = null;
+ this.ADBE_JSDebugger = null;
+ this.addViewerPreferences = null;
+ this.duplexOption = null;
+ this.enforce = null;
+ this.numberOfCopies = null;
+ this.pageRange = null;
+ this.pickTrayByPDFSize = null;
+ this.printScaling = null;
+ }
+}
+class WebClient extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "webClient", true);
+ this.name = attributes.name ? attributes.name.trim() : "";
+ this.fontInfo = null;
+ this.xdc = null;
+ }
+}
+class Whitespace extends OptionObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "whitespace", ["preserve", "ltrim", "normalize", "rtrim", "trim"]);
+ }
+}
+class Window extends ContentObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "window");
+ }
+ [$finalize]() {
+ const pair = this[$content].trim().split(/\s*,\s*/, 2).map(x => parseInt(x, 10));
+ if (pair.some(x => isNaN(x))) {
+ this[$content] = [0, 0];
+ return;
+ }
+ if (pair.length === 1) {
+ pair.push(pair[0]);
+ }
+ this[$content] = pair;
+ }
+}
+class Xdc extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "xdc", true);
+ this.uri = new XFAObjectArray();
+ this.xsl = new XFAObjectArray();
+ }
+}
+class Xdp extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "xdp", true);
+ this.packets = null;
+ }
+}
+class Xsl extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "xsl", true);
+ this.debug = null;
+ this.uri = null;
+ }
+}
+class Zpl extends XFAObject {
+ constructor(attributes) {
+ super(CONFIG_NS_ID, "zpl", true);
+ this.name = attributes.name ? attributes.name.trim() : "";
+ this.batchOutput = null;
+ this.flipLabel = null;
+ this.fontInfo = null;
+ this.xdc = null;
+ }
+}
+class ConfigNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (ConfigNamespace.hasOwnProperty(name)) {
+ return ConfigNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static acrobat(attrs) {
+ return new Acrobat(attrs);
+ }
+ static acrobat7(attrs) {
+ return new Acrobat7(attrs);
+ }
+ static ADBE_JSConsole(attrs) {
+ return new ADBE_JSConsole(attrs);
+ }
+ static ADBE_JSDebugger(attrs) {
+ return new ADBE_JSDebugger(attrs);
+ }
+ static addSilentPrint(attrs) {
+ return new AddSilentPrint(attrs);
+ }
+ static addViewerPreferences(attrs) {
+ return new AddViewerPreferences(attrs);
+ }
+ static adjustData(attrs) {
+ return new AdjustData(attrs);
+ }
+ static adobeExtensionLevel(attrs) {
+ return new AdobeExtensionLevel(attrs);
+ }
+ static agent(attrs) {
+ return new Agent(attrs);
+ }
+ static alwaysEmbed(attrs) {
+ return new AlwaysEmbed(attrs);
+ }
+ static amd(attrs) {
+ return new Amd(attrs);
+ }
+ static area(attrs) {
+ return new config_Area(attrs);
+ }
+ static attributes(attrs) {
+ return new Attributes(attrs);
+ }
+ static autoSave(attrs) {
+ return new AutoSave(attrs);
+ }
+ static base(attrs) {
+ return new Base(attrs);
+ }
+ static batchOutput(attrs) {
+ return new BatchOutput(attrs);
+ }
+ static behaviorOverride(attrs) {
+ return new BehaviorOverride(attrs);
+ }
+ static cache(attrs) {
+ return new Cache(attrs);
+ }
+ static change(attrs) {
+ return new Change(attrs);
+ }
+ static common(attrs) {
+ return new Common(attrs);
+ }
+ static compress(attrs) {
+ return new Compress(attrs);
+ }
+ static compressLogicalStructure(attrs) {
+ return new CompressLogicalStructure(attrs);
+ }
+ static compressObjectStream(attrs) {
+ return new CompressObjectStream(attrs);
+ }
+ static compression(attrs) {
+ return new Compression(attrs);
+ }
+ static config(attrs) {
+ return new Config(attrs);
+ }
+ static conformance(attrs) {
+ return new Conformance(attrs);
+ }
+ static contentCopy(attrs) {
+ return new ContentCopy(attrs);
+ }
+ static copies(attrs) {
+ return new Copies(attrs);
+ }
+ static creator(attrs) {
+ return new Creator(attrs);
+ }
+ static currentPage(attrs) {
+ return new CurrentPage(attrs);
+ }
+ static data(attrs) {
+ return new Data(attrs);
+ }
+ static debug(attrs) {
+ return new Debug(attrs);
+ }
+ static defaultTypeface(attrs) {
+ return new DefaultTypeface(attrs);
+ }
+ static destination(attrs) {
+ return new Destination(attrs);
+ }
+ static documentAssembly(attrs) {
+ return new DocumentAssembly(attrs);
+ }
+ static driver(attrs) {
+ return new Driver(attrs);
+ }
+ static duplexOption(attrs) {
+ return new DuplexOption(attrs);
+ }
+ static dynamicRender(attrs) {
+ return new DynamicRender(attrs);
+ }
+ static embed(attrs) {
+ return new Embed(attrs);
+ }
+ static encrypt(attrs) {
+ return new config_Encrypt(attrs);
+ }
+ static encryption(attrs) {
+ return new config_Encryption(attrs);
+ }
+ static encryptionLevel(attrs) {
+ return new EncryptionLevel(attrs);
+ }
+ static enforce(attrs) {
+ return new Enforce(attrs);
+ }
+ static equate(attrs) {
+ return new Equate(attrs);
+ }
+ static equateRange(attrs) {
+ return new EquateRange(attrs);
+ }
+ static exclude(attrs) {
+ return new Exclude(attrs);
+ }
+ static excludeNS(attrs) {
+ return new ExcludeNS(attrs);
+ }
+ static flipLabel(attrs) {
+ return new FlipLabel(attrs);
+ }
+ static fontInfo(attrs) {
+ return new config_FontInfo(attrs);
+ }
+ static formFieldFilling(attrs) {
+ return new FormFieldFilling(attrs);
+ }
+ static groupParent(attrs) {
+ return new GroupParent(attrs);
+ }
+ static ifEmpty(attrs) {
+ return new IfEmpty(attrs);
+ }
+ static includeXDPContent(attrs) {
+ return new IncludeXDPContent(attrs);
+ }
+ static incrementalLoad(attrs) {
+ return new IncrementalLoad(attrs);
+ }
+ static incrementalMerge(attrs) {
+ return new IncrementalMerge(attrs);
+ }
+ static interactive(attrs) {
+ return new Interactive(attrs);
+ }
+ static jog(attrs) {
+ return new Jog(attrs);
+ }
+ static labelPrinter(attrs) {
+ return new LabelPrinter(attrs);
+ }
+ static layout(attrs) {
+ return new Layout(attrs);
+ }
+ static level(attrs) {
+ return new Level(attrs);
+ }
+ static linearized(attrs) {
+ return new Linearized(attrs);
+ }
+ static locale(attrs) {
+ return new Locale(attrs);
+ }
+ static localeSet(attrs) {
+ return new LocaleSet(attrs);
+ }
+ static log(attrs) {
+ return new Log(attrs);
+ }
+ static map(attrs) {
+ return new MapElement(attrs);
+ }
+ static mediumInfo(attrs) {
+ return new MediumInfo(attrs);
+ }
+ static message(attrs) {
+ return new config_Message(attrs);
+ }
+ static messaging(attrs) {
+ return new Messaging(attrs);
+ }
+ static mode(attrs) {
+ return new Mode(attrs);
+ }
+ static modifyAnnots(attrs) {
+ return new ModifyAnnots(attrs);
+ }
+ static msgId(attrs) {
+ return new MsgId(attrs);
+ }
+ static nameAttr(attrs) {
+ return new NameAttr(attrs);
+ }
+ static neverEmbed(attrs) {
+ return new NeverEmbed(attrs);
+ }
+ static numberOfCopies(attrs) {
+ return new NumberOfCopies(attrs);
+ }
+ static openAction(attrs) {
+ return new OpenAction(attrs);
+ }
+ static output(attrs) {
+ return new Output(attrs);
+ }
+ static outputBin(attrs) {
+ return new OutputBin(attrs);
+ }
+ static outputXSL(attrs) {
+ return new OutputXSL(attrs);
+ }
+ static overprint(attrs) {
+ return new Overprint(attrs);
+ }
+ static packets(attrs) {
+ return new Packets(attrs);
+ }
+ static pageOffset(attrs) {
+ return new PageOffset(attrs);
+ }
+ static pageRange(attrs) {
+ return new PageRange(attrs);
+ }
+ static pagination(attrs) {
+ return new Pagination(attrs);
+ }
+ static paginationOverride(attrs) {
+ return new PaginationOverride(attrs);
+ }
+ static part(attrs) {
+ return new Part(attrs);
+ }
+ static pcl(attrs) {
+ return new Pcl(attrs);
+ }
+ static pdf(attrs) {
+ return new Pdf(attrs);
+ }
+ static pdfa(attrs) {
+ return new Pdfa(attrs);
+ }
+ static permissions(attrs) {
+ return new Permissions(attrs);
+ }
+ static pickTrayByPDFSize(attrs) {
+ return new PickTrayByPDFSize(attrs);
+ }
+ static picture(attrs) {
+ return new config_Picture(attrs);
+ }
+ static plaintextMetadata(attrs) {
+ return new PlaintextMetadata(attrs);
+ }
+ static presence(attrs) {
+ return new Presence(attrs);
+ }
+ static present(attrs) {
+ return new Present(attrs);
+ }
+ static print(attrs) {
+ return new Print(attrs);
+ }
+ static printHighQuality(attrs) {
+ return new PrintHighQuality(attrs);
+ }
+ static printScaling(attrs) {
+ return new PrintScaling(attrs);
+ }
+ static printerName(attrs) {
+ return new PrinterName(attrs);
+ }
+ static producer(attrs) {
+ return new Producer(attrs);
+ }
+ static ps(attrs) {
+ return new Ps(attrs);
+ }
+ static range(attrs) {
+ return new Range(attrs);
+ }
+ static record(attrs) {
+ return new Record(attrs);
+ }
+ static relevant(attrs) {
+ return new Relevant(attrs);
+ }
+ static rename(attrs) {
+ return new Rename(attrs);
+ }
+ static renderPolicy(attrs) {
+ return new RenderPolicy(attrs);
+ }
+ static runScripts(attrs) {
+ return new RunScripts(attrs);
+ }
+ static script(attrs) {
+ return new config_Script(attrs);
+ }
+ static scriptModel(attrs) {
+ return new ScriptModel(attrs);
+ }
+ static severity(attrs) {
+ return new Severity(attrs);
+ }
+ static silentPrint(attrs) {
+ return new SilentPrint(attrs);
+ }
+ static staple(attrs) {
+ return new Staple(attrs);
+ }
+ static startNode(attrs) {
+ return new StartNode(attrs);
+ }
+ static startPage(attrs) {
+ return new StartPage(attrs);
+ }
+ static submitFormat(attrs) {
+ return new SubmitFormat(attrs);
+ }
+ static submitUrl(attrs) {
+ return new SubmitUrl(attrs);
+ }
+ static subsetBelow(attrs) {
+ return new SubsetBelow(attrs);
+ }
+ static suppressBanner(attrs) {
+ return new SuppressBanner(attrs);
+ }
+ static tagged(attrs) {
+ return new Tagged(attrs);
+ }
+ static template(attrs) {
+ return new config_Template(attrs);
+ }
+ static templateCache(attrs) {
+ return new TemplateCache(attrs);
+ }
+ static threshold(attrs) {
+ return new Threshold(attrs);
+ }
+ static to(attrs) {
+ return new To(attrs);
+ }
+ static trace(attrs) {
+ return new Trace(attrs);
+ }
+ static transform(attrs) {
+ return new config_Transform(attrs);
+ }
+ static type(attrs) {
+ return new Type(attrs);
+ }
+ static uri(attrs) {
+ return new Uri(attrs);
+ }
+ static validate(attrs) {
+ return new config_Validate(attrs);
+ }
+ static validateApprovalSignatures(attrs) {
+ return new ValidateApprovalSignatures(attrs);
+ }
+ static validationMessaging(attrs) {
+ return new ValidationMessaging(attrs);
+ }
+ static version(attrs) {
+ return new Version(attrs);
+ }
+ static versionControl(attrs) {
+ return new VersionControl(attrs);
+ }
+ static viewerPreferences(attrs) {
+ return new ViewerPreferences(attrs);
+ }
+ static webClient(attrs) {
+ return new WebClient(attrs);
+ }
+ static whitespace(attrs) {
+ return new Whitespace(attrs);
+ }
+ static window(attrs) {
+ return new Window(attrs);
+ }
+ static xdc(attrs) {
+ return new Xdc(attrs);
+ }
+ static xdp(attrs) {
+ return new Xdp(attrs);
+ }
+ static xsl(attrs) {
+ return new Xsl(attrs);
+ }
+ static zpl(attrs) {
+ return new Zpl(attrs);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/connection_set.js
+
+
+const CONNECTION_SET_NS_ID = NamespaceIds.connectionSet.id;
+class ConnectionSet extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "connectionSet", true);
+ this.wsdlConnection = new XFAObjectArray();
+ this.xmlConnection = new XFAObjectArray();
+ this.xsdConnection = new XFAObjectArray();
+ }
+}
+class EffectiveInputPolicy extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "effectiveInputPolicy");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class EffectiveOutputPolicy extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "effectiveOutputPolicy");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class Operation extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "operation");
+ this.id = attributes.id || "";
+ this.input = attributes.input || "";
+ this.name = attributes.name || "";
+ this.output = attributes.output || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class RootElement extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "rootElement");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class SoapAction extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "soapAction");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class SoapAddress extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "soapAddress");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class connection_set_Uri extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "uri");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class WsdlAddress extends StringObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "wsdlAddress");
+ this.id = attributes.id || "";
+ this.name = attributes.name || "";
+ this.use = attributes.use || "";
+ this.usehref = attributes.usehref || "";
+ }
+}
+class WsdlConnection extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "wsdlConnection", true);
+ this.dataDescription = attributes.dataDescription || "";
+ this.name = attributes.name || "";
+ this.effectiveInputPolicy = null;
+ this.effectiveOutputPolicy = null;
+ this.operation = null;
+ this.soapAction = null;
+ this.soapAddress = null;
+ this.wsdlAddress = null;
+ }
+}
+class XmlConnection extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "xmlConnection", true);
+ this.dataDescription = attributes.dataDescription || "";
+ this.name = attributes.name || "";
+ this.uri = null;
+ }
+}
+class XsdConnection extends XFAObject {
+ constructor(attributes) {
+ super(CONNECTION_SET_NS_ID, "xsdConnection", true);
+ this.dataDescription = attributes.dataDescription || "";
+ this.name = attributes.name || "";
+ this.rootElement = null;
+ this.uri = null;
+ }
+}
+class ConnectionSetNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (ConnectionSetNamespace.hasOwnProperty(name)) {
+ return ConnectionSetNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static connectionSet(attrs) {
+ return new ConnectionSet(attrs);
+ }
+ static effectiveInputPolicy(attrs) {
+ return new EffectiveInputPolicy(attrs);
+ }
+ static effectiveOutputPolicy(attrs) {
+ return new EffectiveOutputPolicy(attrs);
+ }
+ static operation(attrs) {
+ return new Operation(attrs);
+ }
+ static rootElement(attrs) {
+ return new RootElement(attrs);
+ }
+ static soapAction(attrs) {
+ return new SoapAction(attrs);
+ }
+ static soapAddress(attrs) {
+ return new SoapAddress(attrs);
+ }
+ static uri(attrs) {
+ return new connection_set_Uri(attrs);
+ }
+ static wsdlAddress(attrs) {
+ return new WsdlAddress(attrs);
+ }
+ static wsdlConnection(attrs) {
+ return new WsdlConnection(attrs);
+ }
+ static xmlConnection(attrs) {
+ return new XmlConnection(attrs);
+ }
+ static xsdConnection(attrs) {
+ return new XsdConnection(attrs);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/datasets.js
+
+
+
+const DATASETS_NS_ID = NamespaceIds.datasets.id;
+class datasets_Data extends XmlObject {
+ constructor(attributes) {
+ super(DATASETS_NS_ID, "data", attributes);
+ }
+ [$isNsAgnostic]() {
+ return true;
+ }
+}
+class Datasets extends XFAObject {
+ constructor(attributes) {
+ super(DATASETS_NS_ID, "datasets", true);
+ this.data = null;
+ this.Signature = null;
+ }
+ [$onChild](child) {
+ const name = child[$nodeName];
+ if (name === "data" && child[$namespaceId] === DATASETS_NS_ID || name === "Signature" && child[$namespaceId] === NamespaceIds.signature.id) {
+ this[name] = child;
+ }
+ this[$appendChild](child);
+ }
+}
+class DatasetsNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (DatasetsNamespace.hasOwnProperty(name)) {
+ return DatasetsNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static datasets(attributes) {
+ return new Datasets(attributes);
+ }
+ static data(attributes) {
+ return new datasets_Data(attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/locale_set.js
+
+
+
+const LOCALE_SET_NS_ID = NamespaceIds.localeSet.id;
+class CalendarSymbols extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "calendarSymbols", true);
+ this.name = "gregorian";
+ this.dayNames = new XFAObjectArray(2);
+ this.eraNames = null;
+ this.meridiemNames = null;
+ this.monthNames = new XFAObjectArray(2);
+ }
+}
+class CurrencySymbol extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "currencySymbol");
+ this.name = getStringOption(attributes.name, ["symbol", "isoname", "decimal"]);
+ }
+}
+class CurrencySymbols extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "currencySymbols", true);
+ this.currencySymbol = new XFAObjectArray(3);
+ }
+}
+class DatePattern extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "datePattern");
+ this.name = getStringOption(attributes.name, ["full", "long", "med", "short"]);
+ }
+}
+class DatePatterns extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "datePatterns", true);
+ this.datePattern = new XFAObjectArray(4);
+ }
+}
+class DateTimeSymbols extends ContentObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "dateTimeSymbols");
+ }
+}
+class Day extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "day");
+ }
+}
+class DayNames extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "dayNames", true);
+ this.abbr = getInteger({
+ data: attributes.abbr,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.day = new XFAObjectArray(7);
+ }
+}
+class Era extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "era");
+ }
+}
+class EraNames extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "eraNames", true);
+ this.era = new XFAObjectArray(2);
+ }
+}
+class locale_set_Locale extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "locale", true);
+ this.desc = attributes.desc || "";
+ this.name = "isoname";
+ this.calendarSymbols = null;
+ this.currencySymbols = null;
+ this.datePatterns = null;
+ this.dateTimeSymbols = null;
+ this.numberPatterns = null;
+ this.numberSymbols = null;
+ this.timePatterns = null;
+ this.typeFaces = null;
+ }
+}
+class locale_set_LocaleSet extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "localeSet", true);
+ this.locale = new XFAObjectArray();
+ }
+}
+class Meridiem extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "meridiem");
+ }
+}
+class MeridiemNames extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "meridiemNames", true);
+ this.meridiem = new XFAObjectArray(2);
+ }
+}
+class Month extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "month");
+ }
+}
+class MonthNames extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "monthNames", true);
+ this.abbr = getInteger({
+ data: attributes.abbr,
+ defaultValue: 0,
+ validate: x => x === 1
+ });
+ this.month = new XFAObjectArray(12);
+ }
+}
+class NumberPattern extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "numberPattern");
+ this.name = getStringOption(attributes.name, ["full", "long", "med", "short"]);
+ }
+}
+class NumberPatterns extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "numberPatterns", true);
+ this.numberPattern = new XFAObjectArray(4);
+ }
+}
+class NumberSymbol extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "numberSymbol");
+ this.name = getStringOption(attributes.name, ["decimal", "grouping", "percent", "minus", "zero"]);
+ }
+}
+class NumberSymbols extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "numberSymbols", true);
+ this.numberSymbol = new XFAObjectArray(5);
+ }
+}
+class TimePattern extends StringObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "timePattern");
+ this.name = getStringOption(attributes.name, ["full", "long", "med", "short"]);
+ }
+}
+class TimePatterns extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "timePatterns", true);
+ this.timePattern = new XFAObjectArray(4);
+ }
+}
+class TypeFace extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "typeFace", true);
+ this.name = attributes.name | "";
+ }
+}
+class TypeFaces extends XFAObject {
+ constructor(attributes) {
+ super(LOCALE_SET_NS_ID, "typeFaces", true);
+ this.typeFace = new XFAObjectArray();
+ }
+}
+class LocaleSetNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (LocaleSetNamespace.hasOwnProperty(name)) {
+ return LocaleSetNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static calendarSymbols(attrs) {
+ return new CalendarSymbols(attrs);
+ }
+ static currencySymbol(attrs) {
+ return new CurrencySymbol(attrs);
+ }
+ static currencySymbols(attrs) {
+ return new CurrencySymbols(attrs);
+ }
+ static datePattern(attrs) {
+ return new DatePattern(attrs);
+ }
+ static datePatterns(attrs) {
+ return new DatePatterns(attrs);
+ }
+ static dateTimeSymbols(attrs) {
+ return new DateTimeSymbols(attrs);
+ }
+ static day(attrs) {
+ return new Day(attrs);
+ }
+ static dayNames(attrs) {
+ return new DayNames(attrs);
+ }
+ static era(attrs) {
+ return new Era(attrs);
+ }
+ static eraNames(attrs) {
+ return new EraNames(attrs);
+ }
+ static locale(attrs) {
+ return new locale_set_Locale(attrs);
+ }
+ static localeSet(attrs) {
+ return new locale_set_LocaleSet(attrs);
+ }
+ static meridiem(attrs) {
+ return new Meridiem(attrs);
+ }
+ static meridiemNames(attrs) {
+ return new MeridiemNames(attrs);
+ }
+ static month(attrs) {
+ return new Month(attrs);
+ }
+ static monthNames(attrs) {
+ return new MonthNames(attrs);
+ }
+ static numberPattern(attrs) {
+ return new NumberPattern(attrs);
+ }
+ static numberPatterns(attrs) {
+ return new NumberPatterns(attrs);
+ }
+ static numberSymbol(attrs) {
+ return new NumberSymbol(attrs);
+ }
+ static numberSymbols(attrs) {
+ return new NumberSymbols(attrs);
+ }
+ static timePattern(attrs) {
+ return new TimePattern(attrs);
+ }
+ static timePatterns(attrs) {
+ return new TimePatterns(attrs);
+ }
+ static typeFace(attrs) {
+ return new TypeFace(attrs);
+ }
+ static typeFaces(attrs) {
+ return new TypeFaces(attrs);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/signature.js
+
+
+const SIGNATURE_NS_ID = NamespaceIds.signature.id;
+class signature_Signature extends XFAObject {
+ constructor(attributes) {
+ super(SIGNATURE_NS_ID, "signature", true);
+ }
+}
+class SignatureNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (SignatureNamespace.hasOwnProperty(name)) {
+ return SignatureNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static signature(attributes) {
+ return new signature_Signature(attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/stylesheet.js
+
+
+const STYLESHEET_NS_ID = NamespaceIds.stylesheet.id;
+class Stylesheet extends XFAObject {
+ constructor(attributes) {
+ super(STYLESHEET_NS_ID, "stylesheet", true);
+ }
+}
+class StylesheetNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (StylesheetNamespace.hasOwnProperty(name)) {
+ return StylesheetNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static stylesheet(attributes) {
+ return new Stylesheet(attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/xdp.js
+
+
+
+const XDP_NS_ID = NamespaceIds.xdp.id;
+class xdp_Xdp extends XFAObject {
+ constructor(attributes) {
+ super(XDP_NS_ID, "xdp", true);
+ this.uuid = attributes.uuid || "";
+ this.timeStamp = attributes.timeStamp || "";
+ this.config = null;
+ this.connectionSet = null;
+ this.datasets = null;
+ this.localeSet = null;
+ this.stylesheet = new XFAObjectArray();
+ this.template = null;
+ }
+ [$onChildCheck](child) {
+ const ns = NamespaceIds[child[$nodeName]];
+ return ns && child[$namespaceId] === ns.id;
+ }
+}
+class XdpNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (XdpNamespace.hasOwnProperty(name)) {
+ return XdpNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static xdp(attributes) {
+ return new xdp_Xdp(attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/xhtml.js
+
+
+
+
+
+const XHTML_NS_ID = NamespaceIds.xhtml.id;
+const $richText = Symbol();
+const VALID_STYLES = new Set(["color", "font", "font-family", "font-size", "font-stretch", "font-style", "font-weight", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "letter-spacing", "line-height", "orphans", "page-break-after", "page-break-before", "page-break-inside", "tab-interval", "tab-stop", "text-align", "text-decoration", "text-indent", "vertical-align", "widows", "kerning-mode", "xfa-font-horizontal-scale", "xfa-font-vertical-scale", "xfa-spacerun", "xfa-tab-stops"]);
+const StyleMapping = new Map([["page-break-after", "breakAfter"], ["page-break-before", "breakBefore"], ["page-break-inside", "breakInside"], ["kerning-mode", value => value === "none" ? "none" : "normal"], ["xfa-font-horizontal-scale", value => `scaleX(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-font-vertical-scale", value => `scaleY(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-spacerun", ""], ["xfa-tab-stops", ""], ["font-size", (value, original) => {
+ value = original.fontSize = getMeasurement(value);
+ return measureToString(0.99 * value);
+}], ["letter-spacing", value => measureToString(getMeasurement(value))], ["line-height", value => measureToString(getMeasurement(value))], ["margin", value => measureToString(getMeasurement(value))], ["margin-bottom", value => measureToString(getMeasurement(value))], ["margin-left", value => measureToString(getMeasurement(value))], ["margin-right", value => measureToString(getMeasurement(value))], ["margin-top", value => measureToString(getMeasurement(value))], ["text-indent", value => measureToString(getMeasurement(value))], ["font-family", value => value], ["vertical-align", value => measureToString(getMeasurement(value))]]);
+const spacesRegExp = /\s+/g;
+const crlfRegExp = /[\r\n]+/g;
+const crlfForRichTextRegExp = /\r\n?/g;
+function mapStyle(styleStr, node, richText) {
+ const style = Object.create(null);
+ if (!styleStr) {
+ return style;
+ }
+ const original = Object.create(null);
+ for (const [key, value] of styleStr.split(";").map(s => s.split(":", 2))) {
+ const mapping = StyleMapping.get(key);
+ if (mapping === "") {
+ continue;
+ }
+ let newValue = value;
+ if (mapping) {
+ newValue = typeof mapping === "string" ? mapping : mapping(value, original);
+ }
+ if (key.endsWith("scale")) {
+ style.transform = style.transform ? `${style[key]} ${newValue}` : newValue;
+ } else {
+ style[key.replaceAll(/-([a-zA-Z])/g, (_, x) => x.toUpperCase())] = newValue;
+ }
+ }
+ if (style.fontFamily) {
+ setFontFamily({
+ typeface: style.fontFamily,
+ weight: style.fontWeight || "normal",
+ posture: style.fontStyle || "normal",
+ size: original.fontSize || 0
+ }, node, node[$globalData].fontFinder, style);
+ }
+ if (richText && style.verticalAlign && style.verticalAlign !== "0px" && style.fontSize) {
+ const SUB_SUPER_SCRIPT_FACTOR = 0.583;
+ const VERTICAL_FACTOR = 0.333;
+ const fontSize = getMeasurement(style.fontSize);
+ style.fontSize = measureToString(fontSize * SUB_SUPER_SCRIPT_FACTOR);
+ style.verticalAlign = measureToString(Math.sign(getMeasurement(style.verticalAlign)) * fontSize * VERTICAL_FACTOR);
+ }
+ if (richText && style.fontSize) {
+ style.fontSize = `calc(${style.fontSize} * var(--scale-factor))`;
+ }
+ fixTextIndent(style);
+ return style;
+}
+function checkStyle(node) {
+ if (!node.style) {
+ return "";
+ }
+ return node.style.trim().split(/\s*;\s*/).filter(s => !!s).map(s => s.split(/\s*:\s*/, 2)).filter(([key, value]) => {
+ if (key === "font-family") {
+ node[$globalData].usedTypefaces.add(value);
+ }
+ return VALID_STYLES.has(key);
+ }).map(kv => kv.join(":")).join(";");
+}
+const NoWhites = new Set(["body", "html"]);
+class XhtmlObject extends XmlObject {
+ constructor(attributes, name) {
+ super(XHTML_NS_ID, name);
+ this[$richText] = false;
+ this.style = attributes.style || "";
+ }
+ [$clean](builder) {
+ super[$clean](builder);
+ this.style = checkStyle(this);
+ }
+ [$acceptWhitespace]() {
+ return !NoWhites.has(this[$nodeName]);
+ }
+ [$onText](str, richText = false) {
+ if (!richText) {
+ str = str.replaceAll(crlfRegExp, "");
+ if (!this.style.includes("xfa-spacerun:yes")) {
+ str = str.replaceAll(spacesRegExp, " ");
+ }
+ } else {
+ this[$richText] = true;
+ }
+ if (str) {
+ this[$content] += str;
+ }
+ }
+ [$pushGlyphs](measure, mustPop = true) {
+ const xfaFont = Object.create(null);
+ const margin = {
+ top: NaN,
+ bottom: NaN,
+ left: NaN,
+ right: NaN
+ };
+ let lineHeight = null;
+ for (const [key, value] of this.style.split(";").map(s => s.split(":", 2))) {
+ switch (key) {
+ case "font-family":
+ xfaFont.typeface = stripQuotes(value);
+ break;
+ case "font-size":
+ xfaFont.size = getMeasurement(value);
+ break;
+ case "font-weight":
+ xfaFont.weight = value;
+ break;
+ case "font-style":
+ xfaFont.posture = value;
+ break;
+ case "letter-spacing":
+ xfaFont.letterSpacing = getMeasurement(value);
+ break;
+ case "margin":
+ const values = value.split(/ \t/).map(x => getMeasurement(x));
+ switch (values.length) {
+ case 1:
+ margin.top = margin.bottom = margin.left = margin.right = values[0];
+ break;
+ case 2:
+ margin.top = margin.bottom = values[0];
+ margin.left = margin.right = values[1];
+ break;
+ case 3:
+ margin.top = values[0];
+ margin.bottom = values[2];
+ margin.left = margin.right = values[1];
+ break;
+ case 4:
+ margin.top = values[0];
+ margin.left = values[1];
+ margin.bottom = values[2];
+ margin.right = values[3];
+ break;
+ }
+ break;
+ case "margin-top":
+ margin.top = getMeasurement(value);
+ break;
+ case "margin-bottom":
+ margin.bottom = getMeasurement(value);
+ break;
+ case "margin-left":
+ margin.left = getMeasurement(value);
+ break;
+ case "margin-right":
+ margin.right = getMeasurement(value);
+ break;
+ case "line-height":
+ lineHeight = getMeasurement(value);
+ break;
+ }
+ }
+ measure.pushData(xfaFont, margin, lineHeight);
+ if (this[$content]) {
+ measure.addString(this[$content]);
+ } else {
+ for (const child of this[$getChildren]()) {
+ if (child[$nodeName] === "#text") {
+ measure.addString(child[$content]);
+ continue;
+ }
+ child[$pushGlyphs](measure);
+ }
+ }
+ if (mustPop) {
+ measure.popFont();
+ }
+ }
+ [$toHTML](availableSpace) {
+ const children = [];
+ this[$extra] = {
+ children
+ };
+ this[$childrenToHTML]({});
+ if (children.length === 0 && !this[$content]) {
+ return HTMLResult.EMPTY;
+ }
+ let value;
+ if (this[$richText]) {
+ value = this[$content] ? this[$content].replaceAll(crlfForRichTextRegExp, "\n") : undefined;
+ } else {
+ value = this[$content] || undefined;
+ }
+ return HTMLResult.success({
+ name: this[$nodeName],
+ attributes: {
+ href: this.href,
+ style: mapStyle(this.style, this, this[$richText])
+ },
+ children,
+ value
+ });
+ }
+}
+class A extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "a");
+ this.href = fixURL(attributes.href) || "";
+ }
+}
+class B extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "b");
+ }
+ [$pushGlyphs](measure) {
+ measure.pushFont({
+ weight: "bold"
+ });
+ super[$pushGlyphs](measure);
+ measure.popFont();
+ }
+}
+class Body extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "body");
+ }
+ [$toHTML](availableSpace) {
+ const res = super[$toHTML](availableSpace);
+ const {
+ html
+ } = res;
+ if (!html) {
+ return HTMLResult.EMPTY;
+ }
+ html.name = "div";
+ html.attributes.class = ["xfaRich"];
+ return res;
+ }
+}
+class Br extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "br");
+ }
+ [$text]() {
+ return "\n";
+ }
+ [$pushGlyphs](measure) {
+ measure.addString("\n");
+ }
+ [$toHTML](availableSpace) {
+ return HTMLResult.success({
+ name: "br"
+ });
+ }
+}
+class Html extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "html");
+ }
+ [$toHTML](availableSpace) {
+ const children = [];
+ this[$extra] = {
+ children
+ };
+ this[$childrenToHTML]({});
+ if (children.length === 0) {
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ class: ["xfaRich"],
+ style: {}
+ },
+ value: this[$content] || ""
+ });
+ }
+ if (children.length === 1) {
+ const child = children[0];
+ if (child.attributes?.class.includes("xfaRich")) {
+ return HTMLResult.success(child);
+ }
+ }
+ return HTMLResult.success({
+ name: "div",
+ attributes: {
+ class: ["xfaRich"],
+ style: {}
+ },
+ children
+ });
+ }
+}
+class I extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "i");
+ }
+ [$pushGlyphs](measure) {
+ measure.pushFont({
+ posture: "italic"
+ });
+ super[$pushGlyphs](measure);
+ measure.popFont();
+ }
+}
+class Li extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "li");
+ }
+}
+class Ol extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "ol");
+ }
+}
+class P extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "p");
+ }
+ [$pushGlyphs](measure) {
+ super[$pushGlyphs](measure, false);
+ measure.addString("\n");
+ measure.addPara();
+ measure.popFont();
+ }
+ [$text]() {
+ const siblings = this[$getParent]()[$getChildren]();
+ if (siblings.at(-1) === this) {
+ return super[$text]();
+ }
+ return super[$text]() + "\n";
+ }
+}
+class Span extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "span");
+ }
+}
+class Sub extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "sub");
+ }
+}
+class Sup extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "sup");
+ }
+}
+class Ul extends XhtmlObject {
+ constructor(attributes) {
+ super(attributes, "ul");
+ }
+}
+class XhtmlNamespace {
+ static [$buildXFAObject](name, attributes) {
+ if (XhtmlNamespace.hasOwnProperty(name)) {
+ return XhtmlNamespace[name](attributes);
+ }
+ return undefined;
+ }
+ static a(attributes) {
+ return new A(attributes);
+ }
+ static b(attributes) {
+ return new B(attributes);
+ }
+ static body(attributes) {
+ return new Body(attributes);
+ }
+ static br(attributes) {
+ return new Br(attributes);
+ }
+ static html(attributes) {
+ return new Html(attributes);
+ }
+ static i(attributes) {
+ return new I(attributes);
+ }
+ static li(attributes) {
+ return new Li(attributes);
+ }
+ static ol(attributes) {
+ return new Ol(attributes);
+ }
+ static p(attributes) {
+ return new P(attributes);
+ }
+ static span(attributes) {
+ return new Span(attributes);
+ }
+ static sub(attributes) {
+ return new Sub(attributes);
+ }
+ static sup(attributes) {
+ return new Sup(attributes);
+ }
+ static ul(attributes) {
+ return new Ul(attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/setup.js
+
+
+
+
+
+
+
+
+
+const NamespaceSetUp = {
+ config: ConfigNamespace,
+ connection: ConnectionSetNamespace,
+ datasets: DatasetsNamespace,
+ localeSet: LocaleSetNamespace,
+ signature: SignatureNamespace,
+ stylesheet: StylesheetNamespace,
+ template: TemplateNamespace,
+ xdp: XdpNamespace,
+ xhtml: XhtmlNamespace
+};
+
+;// CONCATENATED MODULE: ./src/core/xfa/unknown.js
+
+
+class UnknownNamespace {
+ constructor(nsId) {
+ this.namespaceId = nsId;
+ }
+ [$buildXFAObject](name, attributes) {
+ return new XmlObject(this.namespaceId, name, attributes);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/builder.js
+
+
+
+
+
+
+
+class Root extends XFAObject {
+ constructor(ids) {
+ super(-1, "root", Object.create(null));
+ this.element = null;
+ this[$ids] = ids;
+ }
+ [$onChild](child) {
+ this.element = child;
+ return true;
+ }
+ [$finalize]() {
+ super[$finalize]();
+ if (this.element.template instanceof Template) {
+ this[$ids].set($root, this.element);
+ this.element.template[$resolvePrototypes](this[$ids]);
+ this.element.template[$ids] = this[$ids];
+ }
+ }
+}
+class Empty extends XFAObject {
+ constructor() {
+ super(-1, "", Object.create(null));
+ }
+ [$onChild](_) {
+ return false;
+ }
+}
+class Builder {
+ constructor(rootNameSpace = null) {
+ this._namespaceStack = [];
+ this._nsAgnosticLevel = 0;
+ this._namespacePrefixes = new Map();
+ this._namespaces = new Map();
+ this._nextNsId = Math.max(...Object.values(NamespaceIds).map(({
+ id
+ }) => id));
+ this._currentNamespace = rootNameSpace || new UnknownNamespace(++this._nextNsId);
+ }
+ buildRoot(ids) {
+ return new Root(ids);
+ }
+ build({
+ nsPrefix,
+ name,
+ attributes,
+ namespace,
+ prefixes
+ }) {
+ const hasNamespaceDef = namespace !== null;
+ if (hasNamespaceDef) {
+ this._namespaceStack.push(this._currentNamespace);
+ this._currentNamespace = this._searchNamespace(namespace);
+ }
+ if (prefixes) {
+ this._addNamespacePrefix(prefixes);
+ }
+ if (attributes.hasOwnProperty($nsAttributes)) {
+ const dataTemplate = NamespaceSetUp.datasets;
+ const nsAttrs = attributes[$nsAttributes];
+ let xfaAttrs = null;
+ for (const [ns, attrs] of Object.entries(nsAttrs)) {
+ const nsToUse = this._getNamespaceToUse(ns);
+ if (nsToUse === dataTemplate) {
+ xfaAttrs = {
+ xfa: attrs
+ };
+ break;
+ }
+ }
+ if (xfaAttrs) {
+ attributes[$nsAttributes] = xfaAttrs;
+ } else {
+ delete attributes[$nsAttributes];
+ }
+ }
+ const namespaceToUse = this._getNamespaceToUse(nsPrefix);
+ const node = namespaceToUse?.[$buildXFAObject](name, attributes) || new Empty();
+ if (node[$isNsAgnostic]()) {
+ this._nsAgnosticLevel++;
+ }
+ if (hasNamespaceDef || prefixes || node[$isNsAgnostic]()) {
+ node[$cleanup] = {
+ hasNamespace: hasNamespaceDef,
+ prefixes,
+ nsAgnostic: node[$isNsAgnostic]()
+ };
+ }
+ return node;
+ }
+ isNsAgnostic() {
+ return this._nsAgnosticLevel > 0;
+ }
+ _searchNamespace(nsName) {
+ let ns = this._namespaces.get(nsName);
+ if (ns) {
+ return ns;
+ }
+ for (const [name, {
+ check
+ }] of Object.entries(NamespaceIds)) {
+ if (check(nsName)) {
+ ns = NamespaceSetUp[name];
+ if (ns) {
+ this._namespaces.set(nsName, ns);
+ return ns;
+ }
+ break;
+ }
+ }
+ ns = new UnknownNamespace(++this._nextNsId);
+ this._namespaces.set(nsName, ns);
+ return ns;
+ }
+ _addNamespacePrefix(prefixes) {
+ for (const {
+ prefix,
+ value
+ } of prefixes) {
+ const namespace = this._searchNamespace(value);
+ let prefixStack = this._namespacePrefixes.get(prefix);
+ if (!prefixStack) {
+ prefixStack = [];
+ this._namespacePrefixes.set(prefix, prefixStack);
+ }
+ prefixStack.push(namespace);
+ }
+ }
+ _getNamespaceToUse(prefix) {
+ if (!prefix) {
+ return this._currentNamespace;
+ }
+ const prefixStack = this._namespacePrefixes.get(prefix);
+ if (prefixStack?.length > 0) {
+ return prefixStack.at(-1);
+ }
+ warn(`Unknown namespace prefix: ${prefix}.`);
+ return null;
+ }
+ clean(data) {
+ const {
+ hasNamespace,
+ prefixes,
+ nsAgnostic
+ } = data;
+ if (hasNamespace) {
+ this._currentNamespace = this._namespaceStack.pop();
+ }
+ if (prefixes) {
+ prefixes.forEach(({
+ prefix
+ }) => {
+ this._namespacePrefixes.get(prefix).pop();
+ });
+ }
+ if (nsAgnostic) {
+ this._nsAgnosticLevel--;
+ }
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/parser.js
+
+
+
+
+class XFAParser extends XMLParserBase {
+ constructor(rootNameSpace = null, richText = false) {
+ super();
+ this._builder = new Builder(rootNameSpace);
+ this._stack = [];
+ this._globalData = {
+ usedTypefaces: new Set()
+ };
+ this._ids = new Map();
+ this._current = this._builder.buildRoot(this._ids);
+ this._errorCode = XMLParserErrorCode.NoError;
+ this._whiteRegex = /^\s+$/;
+ this._nbsps = /\xa0+/g;
+ this._richText = richText;
+ }
+ parse(data) {
+ this.parseXml(data);
+ if (this._errorCode !== XMLParserErrorCode.NoError) {
+ return undefined;
+ }
+ this._current[$finalize]();
+ return this._current.element;
+ }
+ onText(text) {
+ text = text.replace(this._nbsps, match => match.slice(1) + " ");
+ if (this._richText || this._current[$acceptWhitespace]()) {
+ this._current[$onText](text, this._richText);
+ return;
+ }
+ if (this._whiteRegex.test(text)) {
+ return;
+ }
+ this._current[$onText](text.trim());
+ }
+ onCdata(text) {
+ this._current[$onText](text);
+ }
+ _mkAttributes(attributes, tagName) {
+ let namespace = null;
+ let prefixes = null;
+ const attributeObj = Object.create({});
+ for (const {
+ name,
+ value
+ } of attributes) {
+ if (name === "xmlns") {
+ if (!namespace) {
+ namespace = value;
+ } else {
+ warn(`XFA - multiple namespace definition in <${tagName}>`);
+ }
+ } else if (name.startsWith("xmlns:")) {
+ const prefix = name.substring("xmlns:".length);
+ if (!prefixes) {
+ prefixes = [];
+ }
+ prefixes.push({
+ prefix,
+ value
+ });
+ } else {
+ const i = name.indexOf(":");
+ if (i === -1) {
+ attributeObj[name] = value;
+ } else {
+ let nsAttrs = attributeObj[$nsAttributes];
+ if (!nsAttrs) {
+ nsAttrs = attributeObj[$nsAttributes] = Object.create(null);
+ }
+ const [ns, attrName] = [name.slice(0, i), name.slice(i + 1)];
+ const attrs = nsAttrs[ns] ||= Object.create(null);
+ attrs[attrName] = value;
+ }
+ }
+ }
+ return [namespace, prefixes, attributeObj];
+ }
+ _getNameAndPrefix(name, nsAgnostic) {
+ const i = name.indexOf(":");
+ if (i === -1) {
+ return [name, null];
+ }
+ return [name.substring(i + 1), nsAgnostic ? "" : name.substring(0, i)];
+ }
+ onBeginElement(tagName, attributes, isEmpty) {
+ const [namespace, prefixes, attributesObj] = this._mkAttributes(attributes, tagName);
+ const [name, nsPrefix] = this._getNameAndPrefix(tagName, this._builder.isNsAgnostic());
+ const node = this._builder.build({
+ nsPrefix,
+ name,
+ attributes: attributesObj,
+ namespace,
+ prefixes
+ });
+ node[$globalData] = this._globalData;
+ if (isEmpty) {
+ node[$finalize]();
+ if (this._current[$onChild](node)) {
+ node[$setId](this._ids);
+ }
+ node[$clean](this._builder);
+ return;
+ }
+ this._stack.push(this._current);
+ this._current = node;
+ }
+ onEndElement(name) {
+ const node = this._current;
+ if (node[$isCDATAXml]() && typeof node[$content] === "string") {
+ const parser = new XFAParser();
+ parser._globalData = this._globalData;
+ const root = parser.parse(node[$content]);
+ node[$content] = null;
+ node[$onChild](root);
+ }
+ node[$finalize]();
+ this._current = this._stack.pop();
+ if (this._current[$onChild](node)) {
+ node[$setId](this._ids);
+ }
+ node[$clean](this._builder);
+ }
+ onError(code) {
+ this._errorCode = code;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xfa/factory.js
+
+
+
+
+
+
+
+
+class XFAFactory {
+ constructor(data) {
+ try {
+ this.root = new XFAParser().parse(XFAFactory._createDocument(data));
+ const binder = new Binder(this.root);
+ this.form = binder.bind();
+ this.dataHandler = new DataHandler(this.root, binder.getData());
+ this.form[$globalData].template = this.form;
+ } catch (e) {
+ warn(`XFA - an error occurred during parsing and binding: ${e}`);
+ }
+ }
+ isValid() {
+ return this.root && this.form;
+ }
+ _createPagesHelper() {
+ const iterator = this.form[$toPages]();
+ return new Promise((resolve, reject) => {
+ const nextIteration = () => {
+ try {
+ const value = iterator.next();
+ if (value.done) {
+ resolve(value.value);
+ } else {
+ setTimeout(nextIteration, 0);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ };
+ setTimeout(nextIteration, 0);
+ });
+ }
+ async _createPages() {
+ try {
+ this.pages = await this._createPagesHelper();
+ this.dims = this.pages.children.map(c => {
+ const {
+ width,
+ height
+ } = c.attributes.style;
+ return [0, 0, parseInt(width), parseInt(height)];
+ });
+ } catch (e) {
+ warn(`XFA - an error occurred during layout: ${e}`);
+ }
+ }
+ getBoundingBox(pageIndex) {
+ return this.dims[pageIndex];
+ }
+ async getNumPages() {
+ if (!this.pages) {
+ await this._createPages();
+ }
+ return this.dims.length;
+ }
+ setImages(images) {
+ this.form[$globalData].images = images;
+ }
+ setFonts(fonts) {
+ this.form[$globalData].fontFinder = new FontFinder(fonts);
+ const missingFonts = [];
+ for (let typeface of this.form[$globalData].usedTypefaces) {
+ typeface = stripQuotes(typeface);
+ const font = this.form[$globalData].fontFinder.find(typeface);
+ if (!font) {
+ missingFonts.push(typeface);
+ }
+ }
+ if (missingFonts.length > 0) {
+ return missingFonts;
+ }
+ return null;
+ }
+ appendFonts(fonts, reallyMissingFonts) {
+ this.form[$globalData].fontFinder.add(fonts, reallyMissingFonts);
+ }
+ async getPages() {
+ if (!this.pages) {
+ await this._createPages();
+ }
+ const pages = this.pages;
+ this.pages = null;
+ return pages;
+ }
+ serializeData(storage) {
+ return this.dataHandler.serialize(storage);
+ }
+ static _createDocument(data) {
+ if (!data["/xdp:xdp"]) {
+ return data["xdp:xdp"];
+ }
+ return Object.values(data).join("");
+ }
+ static getRichTextAsHtml(rc) {
+ if (!rc || typeof rc !== "string") {
+ return null;
+ }
+ try {
+ let root = new XFAParser(XhtmlNamespace, true).parse(rc);
+ if (!["body", "xhtml"].includes(root[$nodeName])) {
+ const newRoot = XhtmlNamespace.body({});
+ newRoot[$appendChild](root);
+ root = newRoot;
+ }
+ const result = root[$toHTML]();
+ if (!result.success) {
+ return null;
+ }
+ const {
+ html
+ } = result;
+ const {
+ attributes
+ } = html;
+ if (attributes) {
+ if (attributes.class) {
+ attributes.class = attributes.class.filter(attr => !attr.startsWith("xfa"));
+ }
+ attributes.dir = "auto";
+ }
+ return {
+ html,
+ str: root[$text]()
+ };
+ } catch (e) {
+ warn(`XFA - an error occurred during parsing of rich text: ${e}`);
+ }
+ return null;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/annotation.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class AnnotationFactory {
+ static createGlobals(pdfManager) {
+ return Promise.all([pdfManager.ensureCatalog("acroForm"), pdfManager.ensureDoc("xfaDatasets"), pdfManager.ensureCatalog("structTreeRoot"), pdfManager.ensureCatalog("baseUrl"), pdfManager.ensureCatalog("attachments")]).then(([acroForm, xfaDatasets, structTreeRoot, baseUrl, attachments]) => {
+ return {
+ pdfManager,
+ acroForm: acroForm instanceof Dict ? acroForm : Dict.empty,
+ xfaDatasets,
+ structTreeRoot,
+ baseUrl,
+ attachments
+ };
+ }, reason => {
+ warn(`createGlobals: "${reason}".`);
+ return null;
+ });
+ }
+ static async create(xref, ref, annotationGlobals, idFactory, collectFields, pageRef) {
+ const pageIndex = collectFields ? await this._getPageIndex(xref, ref, annotationGlobals.pdfManager) : null;
+ return annotationGlobals.pdfManager.ensure(this, "_create", [xref, ref, annotationGlobals, idFactory, collectFields, pageIndex, pageRef]);
+ }
+ static _create(xref, ref, annotationGlobals, idFactory, collectFields = false, pageIndex = null, pageRef = null) {
+ const dict = xref.fetchIfRef(ref);
+ if (!(dict instanceof Dict)) {
+ return undefined;
+ }
+ const {
+ acroForm,
+ pdfManager
+ } = annotationGlobals;
+ const id = ref instanceof Ref ? ref.toString() : `annot_${idFactory.createObjId()}`;
+ let subtype = dict.get("Subtype");
+ subtype = subtype instanceof Name ? subtype.name : null;
+ const parameters = {
+ xref,
+ ref,
+ dict,
+ subtype,
+ id,
+ annotationGlobals,
+ collectFields,
+ needAppearances: !collectFields && acroForm.get("NeedAppearances") === true,
+ pageIndex,
+ evaluatorOptions: pdfManager.evaluatorOptions,
+ pageRef
+ };
+ switch (subtype) {
+ case "Link":
+ return new LinkAnnotation(parameters);
+ case "Text":
+ return new TextAnnotation(parameters);
+ case "Widget":
+ let fieldType = getInheritableProperty({
+ dict,
+ key: "FT"
+ });
+ fieldType = fieldType instanceof Name ? fieldType.name : null;
+ switch (fieldType) {
+ case "Tx":
+ return new TextWidgetAnnotation(parameters);
+ case "Btn":
+ return new ButtonWidgetAnnotation(parameters);
+ case "Ch":
+ return new ChoiceWidgetAnnotation(parameters);
+ case "Sig":
+ return new SignatureWidgetAnnotation(parameters);
+ }
+ warn(`Unimplemented widget field type "${fieldType}", ` + "falling back to base field type.");
+ return new WidgetAnnotation(parameters);
+ case "Popup":
+ return new PopupAnnotation(parameters);
+ case "FreeText":
+ return new FreeTextAnnotation(parameters);
+ case "Line":
+ return new LineAnnotation(parameters);
+ case "Square":
+ return new SquareAnnotation(parameters);
+ case "Circle":
+ return new CircleAnnotation(parameters);
+ case "PolyLine":
+ return new PolylineAnnotation(parameters);
+ case "Polygon":
+ return new PolygonAnnotation(parameters);
+ case "Caret":
+ return new CaretAnnotation(parameters);
+ case "Ink":
+ return new InkAnnotation(parameters);
+ case "Highlight":
+ return new HighlightAnnotation(parameters);
+ case "Underline":
+ return new UnderlineAnnotation(parameters);
+ case "Squiggly":
+ return new SquigglyAnnotation(parameters);
+ case "StrikeOut":
+ return new StrikeOutAnnotation(parameters);
+ case "Stamp":
+ return new StampAnnotation(parameters);
+ case "FileAttachment":
+ return new FileAttachmentAnnotation(parameters);
+ default:
+ if (!collectFields) {
+ if (!subtype) {
+ warn("Annotation is missing the required /Subtype.");
+ } else {
+ warn(`Unimplemented annotation type "${subtype}", ` + "falling back to base annotation.");
+ }
+ }
+ return new Annotation(parameters);
+ }
+ }
+ static async _getPageIndex(xref, ref, pdfManager) {
+ try {
+ const annotDict = await xref.fetchIfRefAsync(ref);
+ if (!(annotDict instanceof Dict)) {
+ return -1;
+ }
+ const pageRef = annotDict.getRaw("P");
+ if (pageRef instanceof Ref) {
+ try {
+ const pageIndex = await pdfManager.ensureCatalog("getPageIndex", [pageRef]);
+ return pageIndex;
+ } catch (ex) {
+ info(`_getPageIndex -- not a valid page reference: "${ex}".`);
+ }
+ }
+ if (annotDict.has("Kids")) {
+ return -1;
+ }
+ const numPages = await pdfManager.ensureDoc("numPages");
+ for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {
+ const page = await pdfManager.getPage(pageIndex);
+ const annotations = await pdfManager.ensure(page, "annotations");
+ for (const annotRef of annotations) {
+ if (annotRef instanceof Ref && isRefsEqual(annotRef, ref)) {
+ return pageIndex;
+ }
+ }
+ }
+ } catch (ex) {
+ warn(`_getPageIndex: "${ex}".`);
+ }
+ return -1;
+ }
+ static generateImages(annotations, xref, isOffscreenCanvasSupported) {
+ if (!isOffscreenCanvasSupported) {
+ warn("generateImages: OffscreenCanvas is not supported, cannot save or print some annotations with images.");
+ return null;
+ }
+ let imagePromises;
+ for (const {
+ bitmapId,
+ bitmap
+ } of annotations) {
+ if (!bitmap) {
+ continue;
+ }
+ imagePromises ||= new Map();
+ imagePromises.set(bitmapId, StampAnnotation.createImage(bitmap, xref));
+ }
+ return imagePromises;
+ }
+ static async saveNewAnnotations(evaluator, task, annotations, imagePromises) {
+ const xref = evaluator.xref;
+ let baseFontRef;
+ const dependencies = [];
+ const promises = [];
+ const {
+ isOffscreenCanvasSupported
+ } = evaluator.options;
+ for (const annotation of annotations) {
+ if (annotation.deleted) {
+ continue;
+ }
+ switch (annotation.annotationType) {
+ case AnnotationEditorType.FREETEXT:
+ if (!baseFontRef) {
+ const baseFont = new Dict(xref);
+ baseFont.set("BaseFont", Name.get("Helvetica"));
+ baseFont.set("Type", Name.get("Font"));
+ baseFont.set("Subtype", Name.get("Type1"));
+ baseFont.set("Encoding", Name.get("WinAnsiEncoding"));
+ const buffer = [];
+ baseFontRef = xref.getNewTemporaryRef();
+ await writeObject(baseFontRef, baseFont, buffer, xref);
+ dependencies.push({
+ ref: baseFontRef,
+ data: buffer.join("")
+ });
+ }
+ promises.push(FreeTextAnnotation.createNewAnnotation(xref, annotation, dependencies, {
+ evaluator,
+ task,
+ baseFontRef
+ }));
+ break;
+ case AnnotationEditorType.HIGHLIGHT:
+ promises.push(HighlightAnnotation.createNewAnnotation(xref, annotation, dependencies));
+ break;
+ case AnnotationEditorType.INK:
+ promises.push(InkAnnotation.createNewAnnotation(xref, annotation, dependencies));
+ break;
+ case AnnotationEditorType.STAMP:
+ if (!isOffscreenCanvasSupported) {
+ break;
+ }
+ const image = await imagePromises.get(annotation.bitmapId);
+ if (image.imageStream) {
+ const {
+ imageStream,
+ smaskStream
+ } = image;
+ const buffer = [];
+ if (smaskStream) {
+ const smaskRef = xref.getNewTemporaryRef();
+ await writeObject(smaskRef, smaskStream, buffer, xref);
+ dependencies.push({
+ ref: smaskRef,
+ data: buffer.join("")
+ });
+ imageStream.dict.set("SMask", smaskRef);
+ buffer.length = 0;
+ }
+ const imageRef = image.imageRef = xref.getNewTemporaryRef();
+ await writeObject(imageRef, imageStream, buffer, xref);
+ dependencies.push({
+ ref: imageRef,
+ data: buffer.join("")
+ });
+ image.imageStream = image.smaskStream = null;
+ }
+ promises.push(StampAnnotation.createNewAnnotation(xref, annotation, dependencies, {
+ image
+ }));
+ break;
+ }
+ }
+ return {
+ annotations: await Promise.all(promises),
+ dependencies
+ };
+ }
+ static async printNewAnnotations(annotationGlobals, evaluator, task, annotations, imagePromises) {
+ if (!annotations) {
+ return null;
+ }
+ const {
+ options,
+ xref
+ } = evaluator;
+ const promises = [];
+ for (const annotation of annotations) {
+ if (annotation.deleted) {
+ continue;
+ }
+ switch (annotation.annotationType) {
+ case AnnotationEditorType.FREETEXT:
+ promises.push(FreeTextAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {
+ evaluator,
+ task,
+ evaluatorOptions: options
+ }));
+ break;
+ case AnnotationEditorType.HIGHLIGHT:
+ promises.push(HighlightAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {
+ evaluatorOptions: options
+ }));
+ break;
+ case AnnotationEditorType.INK:
+ promises.push(InkAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {
+ evaluatorOptions: options
+ }));
+ break;
+ case AnnotationEditorType.STAMP:
+ if (!options.isOffscreenCanvasSupported) {
+ break;
+ }
+ const image = await imagePromises.get(annotation.bitmapId);
+ if (image.imageStream) {
+ const {
+ imageStream,
+ smaskStream
+ } = image;
+ if (smaskStream) {
+ imageStream.dict.set("SMask", smaskStream);
+ }
+ image.imageRef = new JpegStream(imageStream, imageStream.length);
+ image.imageStream = image.smaskStream = null;
+ }
+ promises.push(StampAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, {
+ image,
+ evaluatorOptions: options
+ }));
+ break;
+ }
+ }
+ return Promise.all(promises);
+ }
+}
+function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) {
+ if (!Array.isArray(color)) {
+ return defaultColor;
+ }
+ const rgbColor = defaultColor || new Uint8ClampedArray(3);
+ switch (color.length) {
+ case 0:
+ return null;
+ case 1:
+ ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);
+ return rgbColor;
+ case 3:
+ ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);
+ return rgbColor;
+ case 4:
+ ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);
+ return rgbColor;
+ default:
+ return defaultColor;
+ }
+}
+function getPdfColorArray(color) {
+ return Array.from(color, c => c / 255);
+}
+function getQuadPoints(dict, rect) {
+ const quadPoints = dict.getArray("QuadPoints");
+ if (!Array.isArray(quadPoints) || quadPoints.length === 0 || quadPoints.length % 8 > 0) {
+ return null;
+ }
+ const quadPointsLists = [];
+ for (let i = 0, ii = quadPoints.length / 8; i < ii; i++) {
+ let minX = Infinity,
+ maxX = -Infinity,
+ minY = Infinity,
+ maxY = -Infinity;
+ for (let j = i * 8, jj = i * 8 + 8; j < jj; j += 2) {
+ const x = quadPoints[j];
+ const y = quadPoints[j + 1];
+ minX = Math.min(x, minX);
+ maxX = Math.max(x, maxX);
+ minY = Math.min(y, minY);
+ maxY = Math.max(y, maxY);
+ }
+ if (rect !== null && (minX < rect[0] || maxX > rect[2] || minY < rect[1] || maxY > rect[3])) {
+ return null;
+ }
+ quadPointsLists.push([{
+ x: minX,
+ y: maxY
+ }, {
+ x: maxX,
+ y: maxY
+ }, {
+ x: minX,
+ y: minY
+ }, {
+ x: maxX,
+ y: minY
+ }]);
+ }
+ return quadPointsLists;
+}
+function getTransformMatrix(rect, bbox, matrix) {
+ const [minX, minY, maxX, maxY] = Util.getAxialAlignedBoundingBox(bbox, matrix);
+ if (minX === maxX || minY === maxY) {
+ return [1, 0, 0, 1, rect[0], rect[1]];
+ }
+ const xRatio = (rect[2] - rect[0]) / (maxX - minX);
+ const yRatio = (rect[3] - rect[1]) / (maxY - minY);
+ return [xRatio, 0, 0, yRatio, rect[0] - minX * xRatio, rect[1] - minY * yRatio];
+}
+class Annotation {
+ constructor(params) {
+ const {
+ dict,
+ xref,
+ annotationGlobals
+ } = params;
+ this.setTitle(dict.get("T"));
+ this.setContents(dict.get("Contents"));
+ this.setModificationDate(dict.get("M"));
+ this.setFlags(dict.get("F"));
+ this.setRectangle(dict.getArray("Rect"));
+ this.setColor(dict.getArray("C"));
+ this.setBorderStyle(dict);
+ this.setAppearance(dict);
+ this.setOptionalContent(dict);
+ const MK = dict.get("MK");
+ this.setBorderAndBackgroundColors(MK);
+ this.setRotation(MK, dict);
+ this.ref = params.ref instanceof Ref ? params.ref : null;
+ this._streams = [];
+ if (this.appearance) {
+ this._streams.push(this.appearance);
+ }
+ const isLocked = !!(this.flags & AnnotationFlag.LOCKED);
+ const isContentLocked = !!(this.flags & AnnotationFlag.LOCKEDCONTENTS);
+ if (annotationGlobals.structTreeRoot) {
+ let structParent = dict.get("StructParent");
+ structParent = Number.isInteger(structParent) && structParent >= 0 ? structParent : -1;
+ annotationGlobals.structTreeRoot.addAnnotationIdToPage(params.pageRef, structParent);
+ }
+ this.data = {
+ annotationFlags: this.flags,
+ borderStyle: this.borderStyle,
+ color: this.color,
+ backgroundColor: this.backgroundColor,
+ borderColor: this.borderColor,
+ rotation: this.rotation,
+ contentsObj: this._contents,
+ hasAppearance: !!this.appearance,
+ id: params.id,
+ modificationDate: this.modificationDate,
+ rect: this.rectangle,
+ subtype: params.subtype,
+ hasOwnCanvas: false,
+ noRotate: !!(this.flags & AnnotationFlag.NOROTATE),
+ noHTML: isLocked && isContentLocked
+ };
+ if (params.collectFields) {
+ const kids = dict.get("Kids");
+ if (Array.isArray(kids)) {
+ const kidIds = [];
+ for (const kid of kids) {
+ if (kid instanceof Ref) {
+ kidIds.push(kid.toString());
+ }
+ }
+ if (kidIds.length !== 0) {
+ this.data.kidIds = kidIds;
+ }
+ }
+ this.data.actions = collectActions(xref, dict, AnnotationActionEventType);
+ this.data.fieldName = this._constructFieldName(dict);
+ this.data.pageIndex = params.pageIndex;
+ }
+ this._isOffscreenCanvasSupported = params.evaluatorOptions.isOffscreenCanvasSupported;
+ this._fallbackFontDict = null;
+ this._needAppearances = false;
+ }
+ _hasFlag(flags, flag) {
+ return !!(flags & flag);
+ }
+ _isViewable(flags) {
+ return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, AnnotationFlag.NOVIEW);
+ }
+ _isPrintable(flags) {
+ return this._hasFlag(flags, AnnotationFlag.PRINT) && !this._hasFlag(flags, AnnotationFlag.HIDDEN) && !this._hasFlag(flags, AnnotationFlag.INVISIBLE);
+ }
+ mustBeViewed(annotationStorage, _renderForms) {
+ const noView = annotationStorage?.get(this.data.id)?.noView;
+ if (noView !== undefined) {
+ return !noView;
+ }
+ return this.viewable && !this._hasFlag(this.flags, AnnotationFlag.HIDDEN);
+ }
+ mustBePrinted(annotationStorage) {
+ const noPrint = annotationStorage?.get(this.data.id)?.noPrint;
+ if (noPrint !== undefined) {
+ return !noPrint;
+ }
+ return this.printable;
+ }
+ get viewable() {
+ if (this.data.quadPoints === null) {
+ return false;
+ }
+ if (this.flags === 0) {
+ return true;
+ }
+ return this._isViewable(this.flags);
+ }
+ get printable() {
+ if (this.data.quadPoints === null) {
+ return false;
+ }
+ if (this.flags === 0) {
+ return false;
+ }
+ return this._isPrintable(this.flags);
+ }
+ _parseStringHelper(data) {
+ const str = typeof data === "string" ? stringToPDFString(data) : "";
+ const dir = str && bidi(str).dir === "rtl" ? "rtl" : "ltr";
+ return {
+ str,
+ dir
+ };
+ }
+ setDefaultAppearance(params) {
+ const {
+ dict,
+ annotationGlobals
+ } = params;
+ const defaultAppearance = getInheritableProperty({
+ dict,
+ key: "DA"
+ }) || annotationGlobals.acroForm.get("DA");
+ this._defaultAppearance = typeof defaultAppearance === "string" ? defaultAppearance : "";
+ this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance);
+ }
+ setTitle(title) {
+ this._title = this._parseStringHelper(title);
+ }
+ setContents(contents) {
+ this._contents = this._parseStringHelper(contents);
+ }
+ setModificationDate(modificationDate) {
+ this.modificationDate = typeof modificationDate === "string" ? modificationDate : null;
+ }
+ setFlags(flags) {
+ this.flags = Number.isInteger(flags) && flags > 0 ? flags : 0;
+ if (this.flags & AnnotationFlag.INVISIBLE && this.constructor.name !== "Annotation") {
+ this.flags ^= AnnotationFlag.INVISIBLE;
+ }
+ }
+ hasFlag(flag) {
+ return this._hasFlag(this.flags, flag);
+ }
+ setRectangle(rectangle) {
+ this.rectangle = Array.isArray(rectangle) && rectangle.length === 4 ? Util.normalizeRect(rectangle) : [0, 0, 0, 0];
+ }
+ setColor(color) {
+ this.color = getRgbColor(color);
+ }
+ setLineEndings(lineEndings) {
+ this.lineEndings = ["None", "None"];
+ if (Array.isArray(lineEndings) && lineEndings.length === 2) {
+ for (let i = 0; i < 2; i++) {
+ const obj = lineEndings[i];
+ if (obj instanceof Name) {
+ switch (obj.name) {
+ case "None":
+ continue;
+ case "Square":
+ case "Circle":
+ case "Diamond":
+ case "OpenArrow":
+ case "ClosedArrow":
+ case "Butt":
+ case "ROpenArrow":
+ case "RClosedArrow":
+ case "Slash":
+ this.lineEndings[i] = obj.name;
+ continue;
+ }
+ }
+ warn(`Ignoring invalid lineEnding: ${obj}`);
+ }
+ }
+ }
+ setRotation(mk, dict) {
+ this.rotation = 0;
+ let angle = mk instanceof Dict ? mk.get("R") || 0 : dict.get("Rotate") || 0;
+ if (Number.isInteger(angle) && angle !== 0) {
+ angle %= 360;
+ if (angle < 0) {
+ angle += 360;
+ }
+ if (angle % 90 === 0) {
+ this.rotation = angle;
+ }
+ }
+ }
+ setBorderAndBackgroundColors(mk) {
+ if (mk instanceof Dict) {
+ this.borderColor = getRgbColor(mk.getArray("BC"), null);
+ this.backgroundColor = getRgbColor(mk.getArray("BG"), null);
+ } else {
+ this.borderColor = this.backgroundColor = null;
+ }
+ }
+ setBorderStyle(borderStyle) {
+ this.borderStyle = new AnnotationBorderStyle();
+ if (!(borderStyle instanceof Dict)) {
+ return;
+ }
+ if (borderStyle.has("BS")) {
+ const dict = borderStyle.get("BS");
+ if (dict instanceof Dict) {
+ const dictType = dict.get("Type");
+ if (!dictType || isName(dictType, "Border")) {
+ this.borderStyle.setWidth(dict.get("W"), this.rectangle);
+ this.borderStyle.setStyle(dict.get("S"));
+ this.borderStyle.setDashArray(dict.getArray("D"));
+ }
+ }
+ } else if (borderStyle.has("Border")) {
+ const array = borderStyle.getArray("Border");
+ if (Array.isArray(array) && array.length >= 3) {
+ this.borderStyle.setHorizontalCornerRadius(array[0]);
+ this.borderStyle.setVerticalCornerRadius(array[1]);
+ this.borderStyle.setWidth(array[2], this.rectangle);
+ if (array.length === 4) {
+ this.borderStyle.setDashArray(array[3], true);
+ }
+ }
+ } else {
+ this.borderStyle.setWidth(0);
+ }
+ }
+ setAppearance(dict) {
+ this.appearance = null;
+ const appearanceStates = dict.get("AP");
+ if (!(appearanceStates instanceof Dict)) {
+ return;
+ }
+ const normalAppearanceState = appearanceStates.get("N");
+ if (normalAppearanceState instanceof BaseStream) {
+ this.appearance = normalAppearanceState;
+ return;
+ }
+ if (!(normalAppearanceState instanceof Dict)) {
+ return;
+ }
+ const as = dict.get("AS");
+ if (!(as instanceof Name) || !normalAppearanceState.has(as.name)) {
+ return;
+ }
+ const appearance = normalAppearanceState.get(as.name);
+ if (appearance instanceof BaseStream) {
+ this.appearance = appearance;
+ }
+ }
+ setOptionalContent(dict) {
+ this.oc = null;
+ const oc = dict.get("OC");
+ if (oc instanceof Name) {
+ warn("setOptionalContent: Support for /Name-entry is not implemented.");
+ } else if (oc instanceof Dict) {
+ this.oc = oc;
+ }
+ }
+ loadResources(keys, appearance) {
+ return appearance.dict.getAsync("Resources").then(resources => {
+ if (!resources) {
+ return undefined;
+ }
+ const objectLoader = new ObjectLoader(resources, keys, resources.xref);
+ return objectLoader.load().then(function () {
+ return resources;
+ });
+ });
+ }
+ async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {
+ const data = this.data;
+ let appearance = this.appearance;
+ const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & RenderingIntentFlag.DISPLAY);
+ if (!appearance) {
+ if (!isUsingOwnCanvas) {
+ return {
+ opList: new OperatorList(),
+ separateForm: false,
+ separateCanvas: false
+ };
+ }
+ appearance = new StringStream("");
+ appearance.dict = new Dict();
+ }
+ const appearanceDict = appearance.dict;
+ const resources = await this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"], appearance);
+ const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1];
+ const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0];
+ const transform = getTransformMatrix(data.rect, bbox, matrix);
+ const opList = new OperatorList();
+ let optionalContent;
+ if (this.oc) {
+ optionalContent = await evaluator.parseMarkedContentProps(this.oc, null);
+ }
+ if (optionalContent !== undefined) {
+ opList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
+ }
+ opList.addOp(OPS.beginAnnotation, [data.id, data.rect, transform, matrix, isUsingOwnCanvas]);
+ await evaluator.getOperatorList({
+ stream: appearance,
+ task,
+ resources,
+ operatorList: opList,
+ fallbackFontDict: this._fallbackFontDict
+ });
+ opList.addOp(OPS.endAnnotation, []);
+ if (optionalContent !== undefined) {
+ opList.addOp(OPS.endMarkedContent, []);
+ }
+ this.reset();
+ return {
+ opList,
+ separateForm: false,
+ separateCanvas: isUsingOwnCanvas
+ };
+ }
+ async save(evaluator, task, annotationStorage) {
+ return null;
+ }
+ get hasTextContent() {
+ return false;
+ }
+ async extractTextContent(evaluator, task, viewBox) {
+ if (!this.appearance) {
+ return;
+ }
+ const resources = await this.loadResources(["ExtGState", "Font", "Properties", "XObject"], this.appearance);
+ const text = [];
+ const buffer = [];
+ let firstPosition = null;
+ const sink = {
+ desiredSize: Math.Infinity,
+ ready: true,
+ enqueue(chunk, size) {
+ for (const item of chunk.items) {
+ if (item.str === undefined) {
+ continue;
+ }
+ firstPosition ||= item.transform.slice(-2);
+ buffer.push(item.str);
+ if (item.hasEOL) {
+ text.push(buffer.join(""));
+ buffer.length = 0;
+ }
+ }
+ }
+ };
+ await evaluator.getTextContent({
+ stream: this.appearance,
+ task,
+ resources,
+ includeMarkedContent: true,
+ sink,
+ viewBox
+ });
+ this.reset();
+ if (buffer.length) {
+ text.push(buffer.join(""));
+ }
+ if (text.length > 1 || text[0]) {
+ const appearanceDict = this.appearance.dict;
+ const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1];
+ const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0];
+ const rect = this.data.rect;
+ const transform = getTransformMatrix(rect, bbox, matrix);
+ transform[4] -= rect[0];
+ transform[5] -= rect[1];
+ firstPosition = Util.applyTransform(firstPosition, transform);
+ firstPosition = Util.applyTransform(firstPosition, matrix);
+ this.data.textPosition = firstPosition;
+ this.data.textContent = text;
+ }
+ }
+ getFieldObject() {
+ if (this.data.kidIds) {
+ return {
+ id: this.data.id,
+ actions: this.data.actions,
+ name: this.data.fieldName,
+ strokeColor: this.data.borderColor,
+ fillColor: this.data.backgroundColor,
+ type: "",
+ kidIds: this.data.kidIds,
+ page: this.data.pageIndex,
+ rotation: this.rotation
+ };
+ }
+ return null;
+ }
+ reset() {
+ for (const stream of this._streams) {
+ stream.reset();
+ }
+ }
+ _constructFieldName(dict) {
+ if (!dict.has("T") && !dict.has("Parent")) {
+ warn("Unknown field name, falling back to empty field name.");
+ return "";
+ }
+ if (!dict.has("Parent")) {
+ return stringToPDFString(dict.get("T"));
+ }
+ const fieldName = [];
+ if (dict.has("T")) {
+ fieldName.unshift(stringToPDFString(dict.get("T")));
+ }
+ let loopDict = dict;
+ const visited = new RefSet();
+ if (dict.objId) {
+ visited.put(dict.objId);
+ }
+ while (loopDict.has("Parent")) {
+ loopDict = loopDict.get("Parent");
+ if (!(loopDict instanceof Dict) || loopDict.objId && visited.has(loopDict.objId)) {
+ break;
+ }
+ if (loopDict.objId) {
+ visited.put(loopDict.objId);
+ }
+ if (loopDict.has("T")) {
+ fieldName.unshift(stringToPDFString(loopDict.get("T")));
+ }
+ }
+ return fieldName.join(".");
+ }
+}
+class AnnotationBorderStyle {
+ constructor() {
+ this.width = 1;
+ this.style = AnnotationBorderStyleType.SOLID;
+ this.dashArray = [3];
+ this.horizontalCornerRadius = 0;
+ this.verticalCornerRadius = 0;
+ }
+ setWidth(width, rect = [0, 0, 0, 0]) {
+ if (width instanceof Name) {
+ this.width = 0;
+ return;
+ }
+ if (typeof width === "number") {
+ if (width > 0) {
+ const maxWidth = (rect[2] - rect[0]) / 2;
+ const maxHeight = (rect[3] - rect[1]) / 2;
+ if (maxWidth > 0 && maxHeight > 0 && (width > maxWidth || width > maxHeight)) {
+ warn(`AnnotationBorderStyle.setWidth - ignoring width: ${width}`);
+ width = 1;
+ }
+ }
+ this.width = width;
+ }
+ }
+ setStyle(style) {
+ if (!(style instanceof Name)) {
+ return;
+ }
+ switch (style.name) {
+ case "S":
+ this.style = AnnotationBorderStyleType.SOLID;
+ break;
+ case "D":
+ this.style = AnnotationBorderStyleType.DASHED;
+ break;
+ case "B":
+ this.style = AnnotationBorderStyleType.BEVELED;
+ break;
+ case "I":
+ this.style = AnnotationBorderStyleType.INSET;
+ break;
+ case "U":
+ this.style = AnnotationBorderStyleType.UNDERLINE;
+ break;
+ default:
+ break;
+ }
+ }
+ setDashArray(dashArray, forceStyle = false) {
+ if (Array.isArray(dashArray) && dashArray.length > 0) {
+ let isValid = true;
+ let allZeros = true;
+ for (const element of dashArray) {
+ const validNumber = +element >= 0;
+ if (!validNumber) {
+ isValid = false;
+ break;
+ } else if (element > 0) {
+ allZeros = false;
+ }
+ }
+ if (isValid && !allZeros) {
+ this.dashArray = dashArray;
+ if (forceStyle) {
+ this.setStyle(Name.get("D"));
+ }
+ } else {
+ this.width = 0;
+ }
+ } else if (dashArray) {
+ this.width = 0;
+ }
+ }
+ setHorizontalCornerRadius(radius) {
+ if (Number.isInteger(radius)) {
+ this.horizontalCornerRadius = radius;
+ }
+ }
+ setVerticalCornerRadius(radius) {
+ if (Number.isInteger(radius)) {
+ this.verticalCornerRadius = radius;
+ }
+ }
+}
+class MarkupAnnotation extends Annotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict
+ } = params;
+ if (dict.has("IRT")) {
+ const rawIRT = dict.getRaw("IRT");
+ this.data.inReplyTo = rawIRT instanceof Ref ? rawIRT.toString() : null;
+ const rt = dict.get("RT");
+ this.data.replyType = rt instanceof Name ? rt.name : AnnotationReplyType.REPLY;
+ }
+ let popupRef = null;
+ if (this.data.replyType === AnnotationReplyType.GROUP) {
+ const parent = dict.get("IRT");
+ this.setTitle(parent.get("T"));
+ this.data.titleObj = this._title;
+ this.setContents(parent.get("Contents"));
+ this.data.contentsObj = this._contents;
+ if (!parent.has("CreationDate")) {
+ this.data.creationDate = null;
+ } else {
+ this.setCreationDate(parent.get("CreationDate"));
+ this.data.creationDate = this.creationDate;
+ }
+ if (!parent.has("M")) {
+ this.data.modificationDate = null;
+ } else {
+ this.setModificationDate(parent.get("M"));
+ this.data.modificationDate = this.modificationDate;
+ }
+ popupRef = parent.getRaw("Popup");
+ if (!parent.has("C")) {
+ this.data.color = null;
+ } else {
+ this.setColor(parent.getArray("C"));
+ this.data.color = this.color;
+ }
+ } else {
+ this.data.titleObj = this._title;
+ this.setCreationDate(dict.get("CreationDate"));
+ this.data.creationDate = this.creationDate;
+ popupRef = dict.getRaw("Popup");
+ if (!dict.has("C")) {
+ this.data.color = null;
+ }
+ }
+ this.data.popupRef = popupRef instanceof Ref ? popupRef.toString() : null;
+ if (dict.has("RC")) {
+ this.data.richText = XFAFactory.getRichTextAsHtml(dict.get("RC"));
+ }
+ }
+ setCreationDate(creationDate) {
+ this.creationDate = typeof creationDate === "string" ? creationDate : null;
+ }
+ _setDefaultAppearance({
+ xref,
+ extra,
+ strokeColor,
+ fillColor,
+ blendMode,
+ strokeAlpha,
+ fillAlpha,
+ pointsCallback
+ }) {
+ let minX = Number.MAX_VALUE;
+ let minY = Number.MAX_VALUE;
+ let maxX = Number.MIN_VALUE;
+ let maxY = Number.MIN_VALUE;
+ const buffer = ["q"];
+ if (extra) {
+ buffer.push(extra);
+ }
+ if (strokeColor) {
+ buffer.push(`${strokeColor[0]} ${strokeColor[1]} ${strokeColor[2]} RG`);
+ }
+ if (fillColor) {
+ buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`);
+ }
+ let pointsArray = this.data.quadPoints;
+ if (!pointsArray) {
+ pointsArray = [[{
+ x: this.rectangle[0],
+ y: this.rectangle[3]
+ }, {
+ x: this.rectangle[2],
+ y: this.rectangle[3]
+ }, {
+ x: this.rectangle[0],
+ y: this.rectangle[1]
+ }, {
+ x: this.rectangle[2],
+ y: this.rectangle[1]
+ }]];
+ }
+ for (const points of pointsArray) {
+ const [mX, MX, mY, MY] = pointsCallback(buffer, points);
+ minX = Math.min(minX, mX);
+ maxX = Math.max(maxX, MX);
+ minY = Math.min(minY, mY);
+ maxY = Math.max(maxY, MY);
+ }
+ buffer.push("Q");
+ const formDict = new Dict(xref);
+ const appearanceStreamDict = new Dict(xref);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ const appearanceStream = new StringStream(buffer.join(" "));
+ appearanceStream.dict = appearanceStreamDict;
+ formDict.set("Fm0", appearanceStream);
+ const gsDict = new Dict(xref);
+ if (blendMode) {
+ gsDict.set("BM", Name.get(blendMode));
+ }
+ if (typeof strokeAlpha === "number") {
+ gsDict.set("CA", strokeAlpha);
+ }
+ if (typeof fillAlpha === "number") {
+ gsDict.set("ca", fillAlpha);
+ }
+ const stateDict = new Dict(xref);
+ stateDict.set("GS0", gsDict);
+ const resources = new Dict(xref);
+ resources.set("ExtGState", stateDict);
+ resources.set("XObject", formDict);
+ const appearanceDict = new Dict(xref);
+ appearanceDict.set("Resources", resources);
+ const bbox = this.data.rect = [minX, minY, maxX, maxY];
+ appearanceDict.set("BBox", bbox);
+ this.appearance = new StringStream("/GS0 gs /Fm0 Do");
+ this.appearance.dict = appearanceDict;
+ this._streams.push(this.appearance, appearanceStream);
+ }
+ static async createNewAnnotation(xref, annotation, dependencies, params) {
+ const annotationRef = annotation.ref ||= xref.getNewTemporaryRef();
+ const ap = await this.createNewAppearanceStream(annotation, xref, params);
+ const buffer = [];
+ let annotationDict;
+ if (ap) {
+ const apRef = xref.getNewTemporaryRef();
+ annotationDict = this.createNewDict(annotation, xref, {
+ apRef
+ });
+ await writeObject(apRef, ap, buffer, xref);
+ dependencies.push({
+ ref: apRef,
+ data: buffer.join("")
+ });
+ } else {
+ annotationDict = this.createNewDict(annotation, xref, {});
+ }
+ if (Number.isInteger(annotation.parentTreeId)) {
+ annotationDict.set("StructParent", annotation.parentTreeId);
+ }
+ buffer.length = 0;
+ await writeObject(annotationRef, annotationDict, buffer, xref);
+ return {
+ ref: annotationRef,
+ data: buffer.join("")
+ };
+ }
+ static async createNewPrintAnnotation(annotationGlobals, xref, annotation, params) {
+ const ap = await this.createNewAppearanceStream(annotation, xref, params);
+ const annotationDict = this.createNewDict(annotation, xref, {
+ ap
+ });
+ const newAnnotation = new this.prototype.constructor({
+ dict: annotationDict,
+ xref,
+ annotationGlobals,
+ evaluatorOptions: params.evaluatorOptions
+ });
+ if (annotation.ref) {
+ newAnnotation.ref = newAnnotation.refToReplace = annotation.ref;
+ }
+ return newAnnotation;
+ }
+}
+class WidgetAnnotation extends Annotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref,
+ annotationGlobals
+ } = params;
+ const data = this.data;
+ this._needAppearances = params.needAppearances;
+ data.annotationType = AnnotationType.WIDGET;
+ if (data.fieldName === undefined) {
+ data.fieldName = this._constructFieldName(dict);
+ }
+ if (data.actions === undefined) {
+ data.actions = collectActions(xref, dict, AnnotationActionEventType);
+ }
+ let fieldValue = getInheritableProperty({
+ dict,
+ key: "V",
+ getArray: true
+ });
+ data.fieldValue = this._decodeFormValue(fieldValue);
+ const defaultFieldValue = getInheritableProperty({
+ dict,
+ key: "DV",
+ getArray: true
+ });
+ data.defaultFieldValue = this._decodeFormValue(defaultFieldValue);
+ if (fieldValue === undefined && annotationGlobals.xfaDatasets) {
+ const path = this._title.str;
+ if (path) {
+ this._hasValueFromXFA = true;
+ data.fieldValue = fieldValue = annotationGlobals.xfaDatasets.getValue(path);
+ }
+ }
+ if (fieldValue === undefined && data.defaultFieldValue !== null) {
+ data.fieldValue = data.defaultFieldValue;
+ }
+ data.alternativeText = stringToPDFString(dict.get("TU") || "");
+ this.setDefaultAppearance(params);
+ data.hasAppearance ||= this._needAppearances && data.fieldValue !== undefined && data.fieldValue !== null;
+ const fieldType = getInheritableProperty({
+ dict,
+ key: "FT"
+ });
+ data.fieldType = fieldType instanceof Name ? fieldType.name : null;
+ const localResources = getInheritableProperty({
+ dict,
+ key: "DR"
+ });
+ const acroFormResources = annotationGlobals.acroForm.get("DR");
+ const appearanceResources = this.appearance?.dict.get("Resources");
+ this._fieldResources = {
+ localResources,
+ acroFormResources,
+ appearanceResources,
+ mergedResources: Dict.merge({
+ xref,
+ dictArray: [localResources, appearanceResources, acroFormResources],
+ mergeSubDicts: true
+ })
+ };
+ data.fieldFlags = getInheritableProperty({
+ dict,
+ key: "Ff"
+ });
+ if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {
+ data.fieldFlags = 0;
+ }
+ data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
+ data.required = this.hasFieldFlag(AnnotationFieldFlag.REQUIRED);
+ data.hidden = this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN) || this._hasFlag(data.annotationFlags, AnnotationFlag.NOVIEW);
+ }
+ _decodeFormValue(formValue) {
+ if (Array.isArray(formValue)) {
+ return formValue.filter(item => typeof item === "string").map(item => stringToPDFString(item));
+ } else if (formValue instanceof Name) {
+ return stringToPDFString(formValue.name);
+ } else if (typeof formValue === "string") {
+ return stringToPDFString(formValue);
+ }
+ return null;
+ }
+ hasFieldFlag(flag) {
+ return !!(this.data.fieldFlags & flag);
+ }
+ _isViewable(flags) {
+ return true;
+ }
+ mustBeViewed(annotationStorage, renderForms) {
+ if (renderForms) {
+ return this.viewable;
+ }
+ return super.mustBeViewed(annotationStorage, renderForms) && !this._hasFlag(this.flags, AnnotationFlag.NOVIEW);
+ }
+ getRotationMatrix(annotationStorage) {
+ let rotation = annotationStorage?.get(this.data.id)?.rotation;
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ if (rotation === 0) {
+ return IDENTITY_MATRIX;
+ }
+ const width = this.data.rect[2] - this.data.rect[0];
+ const height = this.data.rect[3] - this.data.rect[1];
+ return getRotationMatrix(rotation, width, height);
+ }
+ getBorderAndBackgroundAppearances(annotationStorage) {
+ let rotation = annotationStorage?.get(this.data.id)?.rotation;
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ if (!this.backgroundColor && !this.borderColor) {
+ return "";
+ }
+ const width = this.data.rect[2] - this.data.rect[0];
+ const height = this.data.rect[3] - this.data.rect[1];
+ const rect = rotation === 0 || rotation === 180 ? `0 0 ${width} ${height} re` : `0 0 ${height} ${width} re`;
+ let str = "";
+ if (this.backgroundColor) {
+ str = `${getPdfColor(this.backgroundColor, true)} ${rect} f `;
+ }
+ if (this.borderColor) {
+ const borderWidth = this.borderStyle.width || 1;
+ str += `${borderWidth} w ${getPdfColor(this.borderColor, false)} ${rect} S `;
+ }
+ return str;
+ }
+ async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {
+ if (renderForms && !(this instanceof SignatureWidgetAnnotation) && !this.data.noHTML && !this.data.hasOwnCanvas) {
+ return {
+ opList: new OperatorList(),
+ separateForm: true,
+ separateCanvas: false
+ };
+ }
+ if (!this._hasText) {
+ return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);
+ }
+ const content = await this._getAppearance(evaluator, task, intent, annotationStorage);
+ if (this.appearance && content === null) {
+ return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);
+ }
+ const opList = new OperatorList();
+ if (!this._defaultAppearance || content === null) {
+ return {
+ opList,
+ separateForm: false,
+ separateCanvas: false
+ };
+ }
+ const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & RenderingIntentFlag.DISPLAY);
+ const matrix = [1, 0, 0, 1, 0, 0];
+ const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]];
+ const transform = getTransformMatrix(this.data.rect, bbox, matrix);
+ let optionalContent;
+ if (this.oc) {
+ optionalContent = await evaluator.parseMarkedContentProps(this.oc, null);
+ }
+ if (optionalContent !== undefined) {
+ opList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
+ }
+ opList.addOp(OPS.beginAnnotation, [this.data.id, this.data.rect, transform, this.getRotationMatrix(annotationStorage), isUsingOwnCanvas]);
+ const stream = new StringStream(content);
+ await evaluator.getOperatorList({
+ stream,
+ task,
+ resources: this._fieldResources.mergedResources,
+ operatorList: opList
+ });
+ opList.addOp(OPS.endAnnotation, []);
+ if (optionalContent !== undefined) {
+ opList.addOp(OPS.endMarkedContent, []);
+ }
+ return {
+ opList,
+ separateForm: false,
+ separateCanvas: isUsingOwnCanvas
+ };
+ }
+ _getMKDict(rotation) {
+ const mk = new Dict(null);
+ if (rotation) {
+ mk.set("R", rotation);
+ }
+ if (this.borderColor) {
+ mk.set("BC", getPdfColorArray(this.borderColor));
+ }
+ if (this.backgroundColor) {
+ mk.set("BG", getPdfColorArray(this.backgroundColor));
+ }
+ return mk.size > 0 ? mk : null;
+ }
+ amendSavedDict(annotationStorage, dict) {}
+ async save(evaluator, task, annotationStorage) {
+ const storageEntry = annotationStorage?.get(this.data.id);
+ let value = storageEntry?.value,
+ rotation = storageEntry?.rotation;
+ if (value === this.data.fieldValue || value === undefined) {
+ if (!this._hasValueFromXFA && rotation === undefined) {
+ return null;
+ }
+ value ||= this.data.fieldValue;
+ }
+ if (rotation === undefined && !this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && value.length === this.data.fieldValue.length && value.every((x, i) => x === this.data.fieldValue[i])) {
+ return null;
+ }
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ let appearance = null;
+ if (!this._needAppearances) {
+ appearance = await this._getAppearance(evaluator, task, RenderingIntentFlag.SAVE, annotationStorage);
+ if (appearance === null) {
+ return null;
+ }
+ } else {}
+ let needAppearances = false;
+ if (appearance?.needAppearances) {
+ needAppearances = true;
+ appearance = null;
+ }
+ const {
+ xref
+ } = evaluator;
+ const originalDict = xref.fetchIfRef(this.ref);
+ if (!(originalDict instanceof Dict)) {
+ return null;
+ }
+ const dict = new Dict(xref);
+ for (const key of originalDict.getKeys()) {
+ if (key !== "AP") {
+ dict.set(key, originalDict.getRaw(key));
+ }
+ }
+ const xfa = {
+ path: this.data.fieldName,
+ value
+ };
+ const encoder = val => {
+ return isAscii(val) ? val : stringToUTF16String(val, true);
+ };
+ dict.set("V", Array.isArray(value) ? value.map(encoder) : encoder(value));
+ this.amendSavedDict(annotationStorage, dict);
+ const maybeMK = this._getMKDict(rotation);
+ if (maybeMK) {
+ dict.set("MK", maybeMK);
+ }
+ const buffer = [];
+ const changes = [{
+ ref: this.ref,
+ data: "",
+ xfa,
+ needAppearances
+ }];
+ if (appearance !== null) {
+ const newRef = xref.getNewTemporaryRef();
+ const AP = new Dict(xref);
+ dict.set("AP", AP);
+ AP.set("N", newRef);
+ const resources = this._getSaveFieldResources(xref);
+ const appearanceStream = new StringStream(appearance);
+ const appearanceDict = appearanceStream.dict = new Dict(xref);
+ appearanceDict.set("Subtype", Name.get("Form"));
+ appearanceDict.set("Resources", resources);
+ appearanceDict.set("BBox", [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]);
+ const rotationMatrix = this.getRotationMatrix(annotationStorage);
+ if (rotationMatrix !== IDENTITY_MATRIX) {
+ appearanceDict.set("Matrix", rotationMatrix);
+ }
+ await writeObject(newRef, appearanceStream, buffer, xref);
+ changes.push({
+ ref: newRef,
+ data: buffer.join(""),
+ xfa: null,
+ needAppearances: false
+ });
+ buffer.length = 0;
+ }
+ dict.set("M", `D:${getModificationDate()}`);
+ await writeObject(this.ref, dict, buffer, xref);
+ changes[0].data = buffer.join("");
+ return changes;
+ }
+ async _getAppearance(evaluator, task, intent, annotationStorage) {
+ const isPassword = this.hasFieldFlag(AnnotationFieldFlag.PASSWORD);
+ if (isPassword) {
+ return null;
+ }
+ const storageEntry = annotationStorage?.get(this.data.id);
+ let value, rotation;
+ if (storageEntry) {
+ value = storageEntry.formattedValue || storageEntry.value;
+ rotation = storageEntry.rotation;
+ }
+ if (rotation === undefined && value === undefined && !this._needAppearances) {
+ if (!this._hasValueFromXFA || this.appearance) {
+ return null;
+ }
+ }
+ const colors = this.getBorderAndBackgroundAppearances(annotationStorage);
+ if (value === undefined) {
+ value = this.data.fieldValue;
+ if (!value) {
+ return `/Tx BMC q ${colors}Q EMC`;
+ }
+ }
+ if (Array.isArray(value) && value.length === 1) {
+ value = value[0];
+ }
+ assert(typeof value === "string", "Expected `value` to be a string.");
+ value = value.trim();
+ if (this.data.combo) {
+ const option = this.data.options.find(({
+ exportValue
+ }) => value === exportValue);
+ value = option?.displayValue || value;
+ }
+ if (value === "") {
+ return `/Tx BMC q ${colors}Q EMC`;
+ }
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ let lineCount = -1;
+ let lines;
+ if (this.data.multiLine) {
+ lines = value.split(/\r\n?|\n/).map(line => line.normalize("NFC"));
+ lineCount = lines.length;
+ } else {
+ lines = [value.replace(/\r\n?|\n/, "").normalize("NFC")];
+ }
+ const defaultPadding = 1;
+ const defaultHPadding = 2;
+ let totalHeight = this.data.rect[3] - this.data.rect[1];
+ let totalWidth = this.data.rect[2] - this.data.rect[0];
+ if (rotation === 90 || rotation === 270) {
+ [totalWidth, totalHeight] = [totalHeight, totalWidth];
+ }
+ if (!this._defaultAppearance) {
+ this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance = "/Helvetica 0 Tf 0 g");
+ }
+ let font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources);
+ let defaultAppearance, fontSize, lineHeight;
+ const encodedLines = [];
+ let encodingError = false;
+ for (const line of lines) {
+ const encodedString = font.encodeString(line);
+ if (encodedString.length > 1) {
+ encodingError = true;
+ }
+ encodedLines.push(encodedString.join(""));
+ }
+ if (encodingError && intent & RenderingIntentFlag.SAVE) {
+ return {
+ needAppearances: true
+ };
+ }
+ if (encodingError && this._isOffscreenCanvasSupported) {
+ const fontFamily = this.data.comb ? "monospace" : "sans-serif";
+ const fakeUnicodeFont = new FakeUnicodeFont(evaluator.xref, fontFamily);
+ const resources = fakeUnicodeFont.createFontResources(lines.join(""));
+ const newFont = resources.getRaw("Font");
+ if (this._fieldResources.mergedResources.has("Font")) {
+ const oldFont = this._fieldResources.mergedResources.get("Font");
+ for (const key of newFont.getKeys()) {
+ oldFont.set(key, newFont.getRaw(key));
+ }
+ } else {
+ this._fieldResources.mergedResources.set("Font", newFont);
+ }
+ const fontName = fakeUnicodeFont.fontName.name;
+ font = await WidgetAnnotation._getFontData(evaluator, task, {
+ fontName,
+ fontSize: 0
+ }, resources);
+ for (let i = 0, ii = encodedLines.length; i < ii; i++) {
+ encodedLines[i] = stringToUTF16String(lines[i]);
+ }
+ const savedDefaultAppearance = Object.assign(Object.create(null), this.data.defaultAppearanceData);
+ this.data.defaultAppearanceData.fontSize = 0;
+ this.data.defaultAppearanceData.fontName = fontName;
+ [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount);
+ this.data.defaultAppearanceData = savedDefaultAppearance;
+ } else {
+ if (!this._isOffscreenCanvasSupported) {
+ warn("_getAppearance: OffscreenCanvas is not supported, annotation may not render correctly.");
+ }
+ [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount);
+ }
+ let descent = font.descent;
+ if (isNaN(descent)) {
+ descent = BASELINE_FACTOR * lineHeight;
+ } else {
+ descent = Math.max(BASELINE_FACTOR * lineHeight, Math.abs(descent) * fontSize);
+ }
+ const defaultVPadding = Math.min(Math.floor((totalHeight - fontSize) / 2), defaultPadding);
+ const alignment = this.data.textAlignment;
+ if (this.data.multiLine) {
+ return this._getMultilineAppearance(defaultAppearance, encodedLines, font, fontSize, totalWidth, totalHeight, alignment, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage);
+ }
+ if (this.data.comb) {
+ return this._getCombAppearance(defaultAppearance, font, encodedLines[0], fontSize, totalWidth, totalHeight, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage);
+ }
+ const bottomPadding = defaultVPadding + descent;
+ if (alignment === 0 || alignment > 2) {
+ return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${numberToString(defaultHPadding)} ${numberToString(bottomPadding)} Tm (${escapeString(encodedLines[0])}) Tj` + " ET Q EMC";
+ }
+ const prevInfo = {
+ shift: 0
+ };
+ const renderedText = this._renderText(encodedLines[0], font, fontSize, totalWidth, alignment, prevInfo, defaultHPadding, bottomPadding);
+ return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC";
+ }
+ static async _getFontData(evaluator, task, appearanceData, resources) {
+ const operatorList = new OperatorList();
+ const initialState = {
+ font: null,
+ clone() {
+ return this;
+ }
+ };
+ const {
+ fontName,
+ fontSize
+ } = appearanceData;
+ await evaluator.handleSetFont(resources, [fontName && Name.get(fontName), fontSize], null, operatorList, task, initialState, null);
+ return initialState.font;
+ }
+ _getTextWidth(text, font) {
+ return font.charsToGlyphs(text).reduce((width, glyph) => width + glyph.width, 0) / 1000;
+ }
+ _computeFontSize(height, width, text, font, lineCount) {
+ let {
+ fontSize
+ } = this.data.defaultAppearanceData;
+ let lineHeight = (fontSize || 12) * LINE_FACTOR,
+ numberOfLines = Math.round(height / lineHeight);
+ if (!fontSize) {
+ const roundWithTwoDigits = x => Math.floor(x * 100) / 100;
+ if (lineCount === -1) {
+ const textWidth = this._getTextWidth(text, font);
+ fontSize = roundWithTwoDigits(Math.min(height / LINE_FACTOR, textWidth > width ? width / textWidth : Infinity));
+ numberOfLines = 1;
+ } else {
+ const lines = text.split(/\r\n?|\n/);
+ const cachedLines = [];
+ for (const line of lines) {
+ const encoded = font.encodeString(line).join("");
+ const glyphs = font.charsToGlyphs(encoded);
+ const positions = font.getCharPositions(encoded);
+ cachedLines.push({
+ line: encoded,
+ glyphs,
+ positions
+ });
+ }
+ const isTooBig = fsize => {
+ let totalHeight = 0;
+ for (const cache of cachedLines) {
+ const chunks = this._splitLine(null, font, fsize, width, cache);
+ totalHeight += chunks.length * fsize;
+ if (totalHeight > height) {
+ return true;
+ }
+ }
+ return false;
+ };
+ numberOfLines = Math.max(numberOfLines, lineCount);
+ while (true) {
+ lineHeight = height / numberOfLines;
+ fontSize = roundWithTwoDigits(lineHeight / LINE_FACTOR);
+ if (isTooBig(fontSize)) {
+ numberOfLines++;
+ continue;
+ }
+ break;
+ }
+ }
+ const {
+ fontName,
+ fontColor
+ } = this.data.defaultAppearanceData;
+ this._defaultAppearance = createDefaultAppearance({
+ fontSize,
+ fontName,
+ fontColor
+ });
+ }
+ return [this._defaultAppearance, fontSize, height / numberOfLines];
+ }
+ _renderText(text, font, fontSize, totalWidth, alignment, prevInfo, hPadding, vPadding) {
+ let shift;
+ if (alignment === 1) {
+ const width = this._getTextWidth(text, font) * fontSize;
+ shift = (totalWidth - width) / 2;
+ } else if (alignment === 2) {
+ const width = this._getTextWidth(text, font) * fontSize;
+ shift = totalWidth - width - hPadding;
+ } else {
+ shift = hPadding;
+ }
+ const shiftStr = numberToString(shift - prevInfo.shift);
+ prevInfo.shift = shift;
+ vPadding = numberToString(vPadding);
+ return `${shiftStr} ${vPadding} Td (${escapeString(text)}) Tj`;
+ }
+ _getSaveFieldResources(xref) {
+ const {
+ localResources,
+ appearanceResources,
+ acroFormResources
+ } = this._fieldResources;
+ const fontName = this.data.defaultAppearanceData?.fontName;
+ if (!fontName) {
+ return localResources || Dict.empty;
+ }
+ for (const resources of [localResources, appearanceResources]) {
+ if (resources instanceof Dict) {
+ const localFont = resources.get("Font");
+ if (localFont instanceof Dict && localFont.has(fontName)) {
+ return resources;
+ }
+ }
+ }
+ if (acroFormResources instanceof Dict) {
+ const acroFormFont = acroFormResources.get("Font");
+ if (acroFormFont instanceof Dict && acroFormFont.has(fontName)) {
+ const subFontDict = new Dict(xref);
+ subFontDict.set(fontName, acroFormFont.getRaw(fontName));
+ const subResourcesDict = new Dict(xref);
+ subResourcesDict.set("Font", subFontDict);
+ return Dict.merge({
+ xref,
+ dictArray: [subResourcesDict, localResources],
+ mergeSubDicts: true
+ });
+ }
+ }
+ return localResources || Dict.empty;
+ }
+ getFieldObject() {
+ return null;
+ }
+}
+class TextWidgetAnnotation extends WidgetAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.hasOwnCanvas = this.data.readOnly && !this.data.noHTML;
+ this._hasText = true;
+ const dict = params.dict;
+ if (typeof this.data.fieldValue !== "string") {
+ this.data.fieldValue = "";
+ }
+ let alignment = getInheritableProperty({
+ dict,
+ key: "Q"
+ });
+ if (!Number.isInteger(alignment) || alignment < 0 || alignment > 2) {
+ alignment = null;
+ }
+ this.data.textAlignment = alignment;
+ let maximumLength = getInheritableProperty({
+ dict,
+ key: "MaxLen"
+ });
+ if (!Number.isInteger(maximumLength) || maximumLength < 0) {
+ maximumLength = 0;
+ }
+ this.data.maxLen = maximumLength;
+ this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
+ this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) && !this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== 0;
+ this.data.doNotScroll = this.hasFieldFlag(AnnotationFieldFlag.DONOTSCROLL);
+ }
+ get hasTextContent() {
+ return !!this.appearance && !this._needAppearances;
+ }
+ _getCombAppearance(defaultAppearance, font, text, fontSize, width, height, hPadding, vPadding, descent, lineHeight, annotationStorage) {
+ const combWidth = width / this.data.maxLen;
+ const colors = this.getBorderAndBackgroundAppearances(annotationStorage);
+ const buf = [];
+ const positions = font.getCharPositions(text);
+ for (const [start, end] of positions) {
+ buf.push(`(${escapeString(text.substring(start, end))}) Tj`);
+ }
+ const renderedComb = buf.join(` ${numberToString(combWidth)} 0 Td `);
+ return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${numberToString(hPadding)} ${numberToString(vPadding + descent)} Tm ${renderedComb}` + " ET Q EMC";
+ }
+ _getMultilineAppearance(defaultAppearance, lines, font, fontSize, width, height, alignment, hPadding, vPadding, descent, lineHeight, annotationStorage) {
+ const buf = [];
+ const totalWidth = width - 2 * hPadding;
+ const prevInfo = {
+ shift: 0
+ };
+ for (let i = 0, ii = lines.length; i < ii; i++) {
+ const line = lines[i];
+ const chunks = this._splitLine(line, font, fontSize, totalWidth);
+ for (let j = 0, jj = chunks.length; j < jj; j++) {
+ const chunk = chunks[j];
+ const vShift = i === 0 && j === 0 ? -vPadding - (lineHeight - descent) : -lineHeight;
+ buf.push(this._renderText(chunk, font, fontSize, width, alignment, prevInfo, hPadding, vShift));
+ }
+ }
+ const colors = this.getBorderAndBackgroundAppearances(annotationStorage);
+ const renderedText = buf.join("\n");
+ return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 ${numberToString(height)} Tm ${renderedText}` + " ET Q EMC";
+ }
+ _splitLine(line, font, fontSize, width, cache = {}) {
+ line = cache.line || line;
+ const glyphs = cache.glyphs || font.charsToGlyphs(line);
+ if (glyphs.length <= 1) {
+ return [line];
+ }
+ const positions = cache.positions || font.getCharPositions(line);
+ const scale = fontSize / 1000;
+ const chunks = [];
+ let lastSpacePosInStringStart = -1,
+ lastSpacePosInStringEnd = -1,
+ lastSpacePos = -1,
+ startChunk = 0,
+ currentWidth = 0;
+ for (let i = 0, ii = glyphs.length; i < ii; i++) {
+ const [start, end] = positions[i];
+ const glyph = glyphs[i];
+ const glyphWidth = glyph.width * scale;
+ if (glyph.unicode === " ") {
+ if (currentWidth + glyphWidth > width) {
+ chunks.push(line.substring(startChunk, start));
+ startChunk = start;
+ currentWidth = glyphWidth;
+ lastSpacePosInStringStart = -1;
+ lastSpacePos = -1;
+ } else {
+ currentWidth += glyphWidth;
+ lastSpacePosInStringStart = start;
+ lastSpacePosInStringEnd = end;
+ lastSpacePos = i;
+ }
+ } else if (currentWidth + glyphWidth > width) {
+ if (lastSpacePosInStringStart !== -1) {
+ chunks.push(line.substring(startChunk, lastSpacePosInStringEnd));
+ startChunk = lastSpacePosInStringEnd;
+ i = lastSpacePos + 1;
+ lastSpacePosInStringStart = -1;
+ currentWidth = 0;
+ } else {
+ chunks.push(line.substring(startChunk, start));
+ startChunk = start;
+ currentWidth = glyphWidth;
+ }
+ } else {
+ currentWidth += glyphWidth;
+ }
+ }
+ if (startChunk < line.length) {
+ chunks.push(line.substring(startChunk, line.length));
+ }
+ return chunks;
+ }
+ getFieldObject() {
+ return {
+ id: this.data.id,
+ value: this.data.fieldValue,
+ defaultValue: this.data.defaultFieldValue || "",
+ multiline: this.data.multiLine,
+ password: this.hasFieldFlag(AnnotationFieldFlag.PASSWORD),
+ charLimit: this.data.maxLen,
+ comb: this.data.comb,
+ editable: !this.data.readOnly,
+ hidden: this.data.hidden,
+ name: this.data.fieldName,
+ rect: this.data.rect,
+ actions: this.data.actions,
+ page: this.data.pageIndex,
+ strokeColor: this.data.borderColor,
+ fillColor: this.data.backgroundColor,
+ rotation: this.rotation,
+ type: "text"
+ };
+ }
+}
+class ButtonWidgetAnnotation extends WidgetAnnotation {
+ constructor(params) {
+ super(params);
+ this.checkedAppearance = null;
+ this.uncheckedAppearance = null;
+ this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
+ this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
+ this.data.pushButton = this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
+ this.data.isTooltipOnly = false;
+ if (this.data.checkBox) {
+ this._processCheckBox(params);
+ } else if (this.data.radioButton) {
+ this._processRadioButton(params);
+ } else if (this.data.pushButton) {
+ this.data.hasOwnCanvas = true;
+ this.data.noHTML = false;
+ this._processPushButton(params);
+ } else {
+ warn("Invalid field flags for button widget annotation");
+ }
+ }
+ async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) {
+ if (this.data.pushButton) {
+ return super.getOperatorList(evaluator, task, intent, false, annotationStorage);
+ }
+ let value = null;
+ let rotation = null;
+ if (annotationStorage) {
+ const storageEntry = annotationStorage.get(this.data.id);
+ value = storageEntry ? storageEntry.value : null;
+ rotation = storageEntry ? storageEntry.rotation : null;
+ }
+ if (value === null && this.appearance) {
+ return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);
+ }
+ if (value === null || value === undefined) {
+ value = this.data.checkBox ? this.data.fieldValue === this.data.exportValue : this.data.fieldValue === this.data.buttonValue;
+ }
+ const appearance = value ? this.checkedAppearance : this.uncheckedAppearance;
+ if (appearance) {
+ const savedAppearance = this.appearance;
+ const savedMatrix = appearance.dict.getArray("Matrix") || IDENTITY_MATRIX;
+ if (rotation) {
+ appearance.dict.set("Matrix", this.getRotationMatrix(annotationStorage));
+ }
+ this.appearance = appearance;
+ const operatorList = super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage);
+ this.appearance = savedAppearance;
+ appearance.dict.set("Matrix", savedMatrix);
+ return operatorList;
+ }
+ return {
+ opList: new OperatorList(),
+ separateForm: false,
+ separateCanvas: false
+ };
+ }
+ async save(evaluator, task, annotationStorage) {
+ if (this.data.checkBox) {
+ return this._saveCheckbox(evaluator, task, annotationStorage);
+ }
+ if (this.data.radioButton) {
+ return this._saveRadioButton(evaluator, task, annotationStorage);
+ }
+ return null;
+ }
+ async _saveCheckbox(evaluator, task, annotationStorage) {
+ if (!annotationStorage) {
+ return null;
+ }
+ const storageEntry = annotationStorage.get(this.data.id);
+ let rotation = storageEntry?.rotation,
+ value = storageEntry?.value;
+ if (rotation === undefined) {
+ if (value === undefined) {
+ return null;
+ }
+ const defaultValue = this.data.fieldValue === this.data.exportValue;
+ if (defaultValue === value) {
+ return null;
+ }
+ }
+ const dict = evaluator.xref.fetchIfRef(this.ref);
+ if (!(dict instanceof Dict)) {
+ return null;
+ }
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ if (value === undefined) {
+ value = this.data.fieldValue === this.data.exportValue;
+ }
+ const xfa = {
+ path: this.data.fieldName,
+ value: value ? this.data.exportValue : ""
+ };
+ const name = Name.get(value ? this.data.exportValue : "Off");
+ dict.set("V", name);
+ dict.set("AS", name);
+ dict.set("M", `D:${getModificationDate()}`);
+ const maybeMK = this._getMKDict(rotation);
+ if (maybeMK) {
+ dict.set("MK", maybeMK);
+ }
+ const buffer = [];
+ await writeObject(this.ref, dict, buffer, evaluator.xref);
+ return [{
+ ref: this.ref,
+ data: buffer.join(""),
+ xfa
+ }];
+ }
+ async _saveRadioButton(evaluator, task, annotationStorage) {
+ if (!annotationStorage) {
+ return null;
+ }
+ const storageEntry = annotationStorage.get(this.data.id);
+ let rotation = storageEntry?.rotation,
+ value = storageEntry?.value;
+ if (rotation === undefined) {
+ if (value === undefined) {
+ return null;
+ }
+ const defaultValue = this.data.fieldValue === this.data.buttonValue;
+ if (defaultValue === value) {
+ return null;
+ }
+ }
+ const dict = evaluator.xref.fetchIfRef(this.ref);
+ if (!(dict instanceof Dict)) {
+ return null;
+ }
+ if (value === undefined) {
+ value = this.data.fieldValue === this.data.buttonValue;
+ }
+ if (rotation === undefined) {
+ rotation = this.rotation;
+ }
+ const xfa = {
+ path: this.data.fieldName,
+ value: value ? this.data.buttonValue : ""
+ };
+ const name = Name.get(value ? this.data.buttonValue : "Off");
+ const buffer = [];
+ let parentData = null;
+ if (value) {
+ if (this.parent instanceof Ref) {
+ const parent = evaluator.xref.fetch(this.parent);
+ parent.set("V", name);
+ await writeObject(this.parent, parent, buffer, evaluator.xref);
+ parentData = buffer.join("");
+ buffer.length = 0;
+ } else if (this.parent instanceof Dict) {
+ this.parent.set("V", name);
+ }
+ }
+ dict.set("AS", name);
+ dict.set("M", `D:${getModificationDate()}`);
+ const maybeMK = this._getMKDict(rotation);
+ if (maybeMK) {
+ dict.set("MK", maybeMK);
+ }
+ await writeObject(this.ref, dict, buffer, evaluator.xref);
+ const newRefs = [{
+ ref: this.ref,
+ data: buffer.join(""),
+ xfa
+ }];
+ if (parentData) {
+ newRefs.push({
+ ref: this.parent,
+ data: parentData,
+ xfa: null
+ });
+ }
+ return newRefs;
+ }
+ _getDefaultCheckedAppearance(params, type) {
+ const width = this.data.rect[2] - this.data.rect[0];
+ const height = this.data.rect[3] - this.data.rect[1];
+ const bbox = [0, 0, width, height];
+ const FONT_RATIO = 0.8;
+ const fontSize = Math.min(width, height) * FONT_RATIO;
+ let metrics, char;
+ if (type === "check") {
+ metrics = {
+ width: 0.755 * fontSize,
+ height: 0.705 * fontSize
+ };
+ char = "\x33";
+ } else if (type === "disc") {
+ metrics = {
+ width: 0.791 * fontSize,
+ height: 0.705 * fontSize
+ };
+ char = "\x6C";
+ } else {
+ unreachable(`_getDefaultCheckedAppearance - unsupported type: ${type}`);
+ }
+ const xShift = numberToString((width - metrics.width) / 2);
+ const yShift = numberToString((height - metrics.height) / 2);
+ const appearance = `q BT /PdfJsZaDb ${fontSize} Tf 0 g ${xShift} ${yShift} Td (${char}) Tj ET Q`;
+ const appearanceStreamDict = new Dict(params.xref);
+ appearanceStreamDict.set("FormType", 1);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", bbox);
+ appearanceStreamDict.set("Matrix", [1, 0, 0, 1, 0, 0]);
+ appearanceStreamDict.set("Length", appearance.length);
+ const resources = new Dict(params.xref);
+ const font = new Dict(params.xref);
+ font.set("PdfJsZaDb", this.fallbackFontDict);
+ resources.set("Font", font);
+ appearanceStreamDict.set("Resources", resources);
+ this.checkedAppearance = new StringStream(appearance);
+ this.checkedAppearance.dict = appearanceStreamDict;
+ this._streams.push(this.checkedAppearance);
+ }
+ _processCheckBox(params) {
+ const customAppearance = params.dict.get("AP");
+ if (!(customAppearance instanceof Dict)) {
+ return;
+ }
+ const normalAppearance = customAppearance.get("N");
+ if (!(normalAppearance instanceof Dict)) {
+ return;
+ }
+ const asValue = this._decodeFormValue(params.dict.get("AS"));
+ if (typeof asValue === "string") {
+ this.data.fieldValue = asValue;
+ }
+ const yes = this.data.fieldValue !== null && this.data.fieldValue !== "Off" ? this.data.fieldValue : "Yes";
+ const exportValues = normalAppearance.getKeys();
+ if (exportValues.length === 0) {
+ exportValues.push("Off", yes);
+ } else if (exportValues.length === 1) {
+ if (exportValues[0] === "Off") {
+ exportValues.push(yes);
+ } else {
+ exportValues.unshift("Off");
+ }
+ } else if (exportValues.includes(yes)) {
+ exportValues.length = 0;
+ exportValues.push("Off", yes);
+ } else {
+ const otherYes = exportValues.find(v => v !== "Off");
+ exportValues.length = 0;
+ exportValues.push("Off", otherYes);
+ }
+ if (!exportValues.includes(this.data.fieldValue)) {
+ this.data.fieldValue = "Off";
+ }
+ this.data.exportValue = exportValues[1];
+ const checkedAppearance = normalAppearance.get(this.data.exportValue);
+ this.checkedAppearance = checkedAppearance instanceof BaseStream ? checkedAppearance : null;
+ const uncheckedAppearance = normalAppearance.get("Off");
+ this.uncheckedAppearance = uncheckedAppearance instanceof BaseStream ? uncheckedAppearance : null;
+ if (this.checkedAppearance) {
+ this._streams.push(this.checkedAppearance);
+ } else {
+ this._getDefaultCheckedAppearance(params, "check");
+ }
+ if (this.uncheckedAppearance) {
+ this._streams.push(this.uncheckedAppearance);
+ }
+ this._fallbackFontDict = this.fallbackFontDict;
+ if (this.data.defaultFieldValue === null) {
+ this.data.defaultFieldValue = "Off";
+ }
+ }
+ _processRadioButton(params) {
+ this.data.buttonValue = null;
+ const fieldParent = params.dict.get("Parent");
+ if (fieldParent instanceof Dict) {
+ this.parent = params.dict.getRaw("Parent");
+ const fieldParentValue = fieldParent.get("V");
+ if (fieldParentValue instanceof Name) {
+ this.data.fieldValue = this._decodeFormValue(fieldParentValue);
+ }
+ }
+ const appearanceStates = params.dict.get("AP");
+ if (!(appearanceStates instanceof Dict)) {
+ return;
+ }
+ const normalAppearance = appearanceStates.get("N");
+ if (!(normalAppearance instanceof Dict)) {
+ return;
+ }
+ for (const key of normalAppearance.getKeys()) {
+ if (key !== "Off") {
+ this.data.buttonValue = this._decodeFormValue(key);
+ break;
+ }
+ }
+ const checkedAppearance = normalAppearance.get(this.data.buttonValue);
+ this.checkedAppearance = checkedAppearance instanceof BaseStream ? checkedAppearance : null;
+ const uncheckedAppearance = normalAppearance.get("Off");
+ this.uncheckedAppearance = uncheckedAppearance instanceof BaseStream ? uncheckedAppearance : null;
+ if (this.checkedAppearance) {
+ this._streams.push(this.checkedAppearance);
+ } else {
+ this._getDefaultCheckedAppearance(params, "disc");
+ }
+ if (this.uncheckedAppearance) {
+ this._streams.push(this.uncheckedAppearance);
+ }
+ this._fallbackFontDict = this.fallbackFontDict;
+ if (this.data.defaultFieldValue === null) {
+ this.data.defaultFieldValue = "Off";
+ }
+ }
+ _processPushButton(params) {
+ const {
+ dict,
+ annotationGlobals
+ } = params;
+ if (!dict.has("A") && !dict.has("AA") && !this.data.alternativeText) {
+ warn("Push buttons without action dictionaries are not supported");
+ return;
+ }
+ this.data.isTooltipOnly = !dict.has("A") && !dict.has("AA");
+ Catalog.parseDestDictionary({
+ destDict: dict,
+ resultObj: this.data,
+ docBaseUrl: annotationGlobals.baseUrl,
+ docAttachments: annotationGlobals.attachments
+ });
+ }
+ getFieldObject() {
+ let type = "button";
+ let exportValues;
+ if (this.data.checkBox) {
+ type = "checkbox";
+ exportValues = this.data.exportValue;
+ } else if (this.data.radioButton) {
+ type = "radiobutton";
+ exportValues = this.data.buttonValue;
+ }
+ return {
+ id: this.data.id,
+ value: this.data.fieldValue || "Off",
+ defaultValue: this.data.defaultFieldValue,
+ exportValues,
+ editable: !this.data.readOnly,
+ name: this.data.fieldName,
+ rect: this.data.rect,
+ hidden: this.data.hidden,
+ actions: this.data.actions,
+ page: this.data.pageIndex,
+ strokeColor: this.data.borderColor,
+ fillColor: this.data.backgroundColor,
+ rotation: this.rotation,
+ type
+ };
+ }
+ get fallbackFontDict() {
+ const dict = new Dict();
+ dict.set("BaseFont", Name.get("ZapfDingbats"));
+ dict.set("Type", Name.get("FallbackType"));
+ dict.set("Subtype", Name.get("FallbackType"));
+ dict.set("Encoding", Name.get("ZapfDingbatsEncoding"));
+ return shadow(this, "fallbackFontDict", dict);
+ }
+}
+class ChoiceWidgetAnnotation extends WidgetAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.indices = dict.getArray("I");
+ this.hasIndices = Array.isArray(this.indices) && this.indices.length > 0;
+ this.data.options = [];
+ const options = getInheritableProperty({
+ dict,
+ key: "Opt"
+ });
+ if (Array.isArray(options)) {
+ for (let i = 0, ii = options.length; i < ii; i++) {
+ const option = xref.fetchIfRef(options[i]);
+ const isOptionArray = Array.isArray(option);
+ this.data.options[i] = {
+ exportValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[0]) : option),
+ displayValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[1]) : option)
+ };
+ }
+ }
+ if (!this.hasIndices) {
+ if (typeof this.data.fieldValue === "string") {
+ this.data.fieldValue = [this.data.fieldValue];
+ } else if (!this.data.fieldValue) {
+ this.data.fieldValue = [];
+ }
+ } else {
+ this.data.fieldValue = [];
+ const ii = this.data.options.length;
+ for (const i of this.indices) {
+ if (Number.isInteger(i) && i >= 0 && i < ii) {
+ this.data.fieldValue.push(this.data.options[i].exportValue);
+ }
+ }
+ }
+ this.data.combo = this.hasFieldFlag(AnnotationFieldFlag.COMBO);
+ this.data.multiSelect = this.hasFieldFlag(AnnotationFieldFlag.MULTISELECT);
+ this._hasText = true;
+ }
+ getFieldObject() {
+ const type = this.data.combo ? "combobox" : "listbox";
+ const value = this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : null;
+ return {
+ id: this.data.id,
+ value,
+ defaultValue: this.data.defaultFieldValue,
+ editable: !this.data.readOnly,
+ name: this.data.fieldName,
+ rect: this.data.rect,
+ numItems: this.data.fieldValue.length,
+ multipleSelection: this.data.multiSelect,
+ hidden: this.data.hidden,
+ actions: this.data.actions,
+ items: this.data.options,
+ page: this.data.pageIndex,
+ strokeColor: this.data.borderColor,
+ fillColor: this.data.backgroundColor,
+ rotation: this.rotation,
+ type
+ };
+ }
+ amendSavedDict(annotationStorage, dict) {
+ if (!this.hasIndices) {
+ return;
+ }
+ let values = annotationStorage?.get(this.data.id)?.value;
+ if (!Array.isArray(values)) {
+ values = [values];
+ }
+ const indices = [];
+ const {
+ options
+ } = this.data;
+ for (let i = 0, j = 0, ii = options.length; i < ii; i++) {
+ if (options[i].exportValue === values[j]) {
+ indices.push(i);
+ j += 1;
+ }
+ }
+ dict.set("I", indices);
+ }
+ async _getAppearance(evaluator, task, intent, annotationStorage) {
+ if (this.data.combo) {
+ return super._getAppearance(evaluator, task, intent, annotationStorage);
+ }
+ let exportedValue, rotation;
+ const storageEntry = annotationStorage?.get(this.data.id);
+ if (storageEntry) {
+ rotation = storageEntry.rotation;
+ exportedValue = storageEntry.value;
+ }
+ if (rotation === undefined && exportedValue === undefined && !this._needAppearances) {
+ return null;
+ }
+ if (exportedValue === undefined) {
+ exportedValue = this.data.fieldValue;
+ } else if (!Array.isArray(exportedValue)) {
+ exportedValue = [exportedValue];
+ }
+ const defaultPadding = 1;
+ const defaultHPadding = 2;
+ let totalHeight = this.data.rect[3] - this.data.rect[1];
+ let totalWidth = this.data.rect[2] - this.data.rect[0];
+ if (rotation === 90 || rotation === 270) {
+ [totalWidth, totalHeight] = [totalHeight, totalWidth];
+ }
+ const lineCount = this.data.options.length;
+ const valueIndices = [];
+ for (let i = 0; i < lineCount; i++) {
+ const {
+ exportValue
+ } = this.data.options[i];
+ if (exportedValue.includes(exportValue)) {
+ valueIndices.push(i);
+ }
+ }
+ if (!this._defaultAppearance) {
+ this.data.defaultAppearanceData = parseDefaultAppearance(this._defaultAppearance = "/Helvetica 0 Tf 0 g");
+ }
+ const font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources);
+ let defaultAppearance;
+ let {
+ fontSize
+ } = this.data.defaultAppearanceData;
+ if (!fontSize) {
+ const lineHeight = (totalHeight - defaultPadding) / lineCount;
+ let lineWidth = -1;
+ let value;
+ for (const {
+ displayValue
+ } of this.data.options) {
+ const width = this._getTextWidth(displayValue, font);
+ if (width > lineWidth) {
+ lineWidth = width;
+ value = displayValue;
+ }
+ }
+ [defaultAppearance, fontSize] = this._computeFontSize(lineHeight, totalWidth - 2 * defaultHPadding, value, font, -1);
+ } else {
+ defaultAppearance = this._defaultAppearance;
+ }
+ const lineHeight = fontSize * LINE_FACTOR;
+ const vPadding = (lineHeight - fontSize) / 2;
+ const numberOfVisibleLines = Math.floor(totalHeight / lineHeight);
+ let firstIndex = 0;
+ if (valueIndices.length > 0) {
+ const minIndex = Math.min(...valueIndices);
+ const maxIndex = Math.max(...valueIndices);
+ firstIndex = Math.max(0, maxIndex - numberOfVisibleLines + 1);
+ if (firstIndex > minIndex) {
+ firstIndex = minIndex;
+ }
+ }
+ const end = Math.min(firstIndex + numberOfVisibleLines + 1, lineCount);
+ const buf = ["/Tx BMC q", `1 1 ${totalWidth} ${totalHeight} re W n`];
+ if (valueIndices.length) {
+ buf.push("0.600006 0.756866 0.854904 rg");
+ for (const index of valueIndices) {
+ if (firstIndex <= index && index < end) {
+ buf.push(`1 ${totalHeight - (index - firstIndex + 1) * lineHeight} ${totalWidth} ${lineHeight} re f`);
+ }
+ }
+ }
+ buf.push("BT", defaultAppearance, `1 0 0 1 0 ${totalHeight} Tm`);
+ const prevInfo = {
+ shift: 0
+ };
+ for (let i = firstIndex; i < end; i++) {
+ const {
+ displayValue
+ } = this.data.options[i];
+ const vpadding = i === firstIndex ? vPadding : 0;
+ buf.push(this._renderText(displayValue, font, fontSize, totalWidth, 0, prevInfo, defaultHPadding, -lineHeight + vpadding));
+ }
+ buf.push("ET Q EMC");
+ return buf.join("\n");
+ }
+}
+class SignatureWidgetAnnotation extends WidgetAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.fieldValue = null;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = !this.data.hasOwnCanvas;
+ }
+ getFieldObject() {
+ return {
+ id: this.data.id,
+ value: null,
+ page: this.data.pageIndex,
+ type: "signature"
+ };
+ }
+}
+class TextAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ const DEFAULT_ICON_SIZE = 22;
+ super(params);
+ this.data.noRotate = true;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ const {
+ dict
+ } = params;
+ this.data.annotationType = AnnotationType.TEXT;
+ if (this.data.hasAppearance) {
+ this.data.name = "NoIcon";
+ } else {
+ this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
+ this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
+ this.data.name = dict.has("Name") ? dict.get("Name").name : "Note";
+ }
+ if (dict.has("State")) {
+ this.data.state = dict.get("State") || null;
+ this.data.stateModel = dict.get("StateModel") || null;
+ } else {
+ this.data.state = null;
+ this.data.stateModel = null;
+ }
+ }
+}
+class LinkAnnotation extends Annotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ annotationGlobals
+ } = params;
+ this.data.annotationType = AnnotationType.LINK;
+ const quadPoints = getQuadPoints(dict, this.rectangle);
+ if (quadPoints) {
+ this.data.quadPoints = quadPoints;
+ }
+ this.data.borderColor ||= this.data.color;
+ Catalog.parseDestDictionary({
+ destDict: dict,
+ resultObj: this.data,
+ docBaseUrl: annotationGlobals.baseUrl,
+ docAttachments: annotationGlobals.attachments
+ });
+ }
+}
+class PopupAnnotation extends Annotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict
+ } = params;
+ this.data.annotationType = AnnotationType.POPUP;
+ this.data.noHTML = false;
+ if (this.data.rect[0] === this.data.rect[2] || this.data.rect[1] === this.data.rect[3]) {
+ this.data.rect = null;
+ }
+ let parentItem = dict.get("Parent");
+ if (!parentItem) {
+ warn("Popup annotation has a missing or invalid parent annotation.");
+ return;
+ }
+ const parentRect = parentItem.getArray("Rect");
+ this.data.parentRect = Array.isArray(parentRect) && parentRect.length === 4 ? Util.normalizeRect(parentRect) : null;
+ const rt = parentItem.get("RT");
+ if (isName(rt, AnnotationReplyType.GROUP)) {
+ parentItem = parentItem.get("IRT");
+ }
+ if (!parentItem.has("M")) {
+ this.data.modificationDate = null;
+ } else {
+ this.setModificationDate(parentItem.get("M"));
+ this.data.modificationDate = this.modificationDate;
+ }
+ if (!parentItem.has("C")) {
+ this.data.color = null;
+ } else {
+ this.setColor(parentItem.getArray("C"));
+ this.data.color = this.color;
+ }
+ if (!this.viewable) {
+ const parentFlags = parentItem.get("F");
+ if (this._isViewable(parentFlags)) {
+ this.setFlags(parentFlags);
+ }
+ }
+ this.setTitle(parentItem.get("T"));
+ this.data.titleObj = this._title;
+ this.setContents(parentItem.get("Contents"));
+ this.data.contentsObj = this._contents;
+ if (parentItem.has("RC")) {
+ this.data.richText = XFAFactory.getRichTextAsHtml(parentItem.get("RC"));
+ }
+ this.data.open = !!dict.get("Open");
+ }
+}
+class FreeTextAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.hasOwnCanvas = !this.data.noHTML;
+ this.data.noHTML = false;
+ const {
+ evaluatorOptions,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.FREETEXT;
+ this.setDefaultAppearance(params);
+ if (this.appearance) {
+ const {
+ fontColor,
+ fontSize
+ } = parseAppearanceStream(this.appearance, evaluatorOptions, xref);
+ this.data.defaultAppearanceData.fontColor = fontColor;
+ this.data.defaultAppearanceData.fontSize = fontSize || 10;
+ } else if (this._isOffscreenCanvasSupported) {
+ const strokeAlpha = params.dict.get("CA");
+ const fakeUnicodeFont = new FakeUnicodeFont(xref, "sans-serif");
+ this.data.defaultAppearanceData.fontSize ||= 10;
+ const {
+ fontColor,
+ fontSize
+ } = this.data.defaultAppearanceData;
+ this.appearance = fakeUnicodeFont.createAppearance(this._contents.str, this.rectangle, this.rotation, fontSize, fontColor, strokeAlpha);
+ this._streams.push(this.appearance, FakeUnicodeFont.toUnicodeStream);
+ } else {
+ warn("FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly.");
+ }
+ }
+ get hasTextContent() {
+ return !!this.appearance;
+ }
+ static createNewDict(annotation, xref, {
+ apRef,
+ ap
+ }) {
+ const {
+ color,
+ fontSize,
+ rect,
+ rotation,
+ user,
+ value
+ } = annotation;
+ const freetext = new Dict(xref);
+ freetext.set("Type", Name.get("Annot"));
+ freetext.set("Subtype", Name.get("FreeText"));
+ freetext.set("CreationDate", `D:${getModificationDate()}`);
+ freetext.set("Rect", rect);
+ const da = `/Helv ${fontSize} Tf ${getPdfColor(color, true)}`;
+ freetext.set("DA", da);
+ freetext.set("Contents", isAscii(value) ? value : stringToUTF16String(value, true));
+ freetext.set("F", 4);
+ freetext.set("Border", [0, 0, 0]);
+ freetext.set("Rotate", rotation);
+ if (user) {
+ freetext.set("T", isAscii(user) ? user : stringToUTF16String(user, true));
+ }
+ if (apRef || ap) {
+ const n = new Dict(xref);
+ freetext.set("AP", n);
+ if (apRef) {
+ n.set("N", apRef);
+ } else {
+ n.set("N", ap);
+ }
+ }
+ return freetext;
+ }
+ static async createNewAppearanceStream(annotation, xref, params) {
+ const {
+ baseFontRef,
+ evaluator,
+ task
+ } = params;
+ const {
+ color,
+ fontSize,
+ rect,
+ rotation,
+ value
+ } = annotation;
+ const resources = new Dict(xref);
+ const font = new Dict(xref);
+ if (baseFontRef) {
+ font.set("Helv", baseFontRef);
+ } else {
+ const baseFont = new Dict(xref);
+ baseFont.set("BaseFont", Name.get("Helvetica"));
+ baseFont.set("Type", Name.get("Font"));
+ baseFont.set("Subtype", Name.get("Type1"));
+ baseFont.set("Encoding", Name.get("WinAnsiEncoding"));
+ font.set("Helv", baseFont);
+ }
+ resources.set("Font", font);
+ const helv = await WidgetAnnotation._getFontData(evaluator, task, {
+ fontName: "Helv",
+ fontSize
+ }, resources);
+ const [x1, y1, x2, y2] = rect;
+ let w = x2 - x1;
+ let h = y2 - y1;
+ if (rotation % 180 !== 0) {
+ [w, h] = [h, w];
+ }
+ const lines = value.split("\n");
+ const scale = fontSize / 1000;
+ let totalWidth = -Infinity;
+ const encodedLines = [];
+ for (let line of lines) {
+ const encoded = helv.encodeString(line);
+ if (encoded.length > 1) {
+ return null;
+ }
+ line = encoded.join("");
+ encodedLines.push(line);
+ let lineWidth = 0;
+ const glyphs = helv.charsToGlyphs(line);
+ for (const glyph of glyphs) {
+ lineWidth += glyph.width * scale;
+ }
+ totalWidth = Math.max(totalWidth, lineWidth);
+ }
+ let hscale = 1;
+ if (totalWidth > w) {
+ hscale = w / totalWidth;
+ }
+ let vscale = 1;
+ const lineHeight = LINE_FACTOR * fontSize;
+ const lineAscent = (LINE_FACTOR - LINE_DESCENT_FACTOR) * fontSize;
+ const totalHeight = lineHeight * lines.length;
+ if (totalHeight > h) {
+ vscale = h / totalHeight;
+ }
+ const fscale = Math.min(hscale, vscale);
+ const newFontSize = fontSize * fscale;
+ let firstPoint, clipBox, matrix;
+ switch (rotation) {
+ case 0:
+ matrix = [1, 0, 0, 1];
+ clipBox = [rect[0], rect[1], w, h];
+ firstPoint = [rect[0], rect[3] - lineAscent];
+ break;
+ case 90:
+ matrix = [0, 1, -1, 0];
+ clipBox = [rect[1], -rect[2], w, h];
+ firstPoint = [rect[1], -rect[0] - lineAscent];
+ break;
+ case 180:
+ matrix = [-1, 0, 0, -1];
+ clipBox = [-rect[2], -rect[3], w, h];
+ firstPoint = [-rect[2], -rect[1] - lineAscent];
+ break;
+ case 270:
+ matrix = [0, -1, 1, 0];
+ clipBox = [-rect[3], rect[0], w, h];
+ firstPoint = [-rect[3], rect[2] - lineAscent];
+ break;
+ }
+ const buffer = ["q", `${matrix.join(" ")} 0 0 cm`, `${clipBox.join(" ")} re W n`, `BT`, `${getPdfColor(color, true)}`, `0 Tc /Helv ${numberToString(newFontSize)} Tf`];
+ buffer.push(`${firstPoint.join(" ")} Td (${escapeString(encodedLines[0])}) Tj`);
+ const vShift = numberToString(lineHeight);
+ for (let i = 1, ii = encodedLines.length; i < ii; i++) {
+ const line = encodedLines[i];
+ buffer.push(`0 -${vShift} Td (${escapeString(line)}) Tj`);
+ }
+ buffer.push("ET", "Q");
+ const appearance = buffer.join("\n");
+ const appearanceStreamDict = new Dict(xref);
+ appearanceStreamDict.set("FormType", 1);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", rect);
+ appearanceStreamDict.set("Resources", resources);
+ appearanceStreamDict.set("Matrix", [1, 0, 0, 1, -rect[0], -rect[1]]);
+ const ap = new StringStream(appearance);
+ ap.dict = appearanceStreamDict;
+ return ap;
+ }
+}
+class LineAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.LINE;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ const lineCoordinates = dict.getArray("L");
+ this.data.lineCoordinates = Util.normalizeRect(lineCoordinates);
+ this.setLineEndings(dict.getArray("LE"));
+ this.data.lineEndings = this.lineEndings;
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ const interiorColor = getRgbColor(dict.getArray("IC"), null);
+ const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;
+ const fillAlpha = fillColor ? strokeAlpha : null;
+ const borderWidth = this.borderStyle.width || 1,
+ borderAdjust = 2 * borderWidth;
+ const bbox = [this.data.lineCoordinates[0] - borderAdjust, this.data.lineCoordinates[1] - borderAdjust, this.data.lineCoordinates[2] + borderAdjust, this.data.lineCoordinates[3] + borderAdjust];
+ if (!Util.intersect(this.rectangle, bbox)) {
+ this.rectangle = bbox;
+ }
+ this._setDefaultAppearance({
+ xref,
+ extra: `${borderWidth} w`,
+ strokeColor,
+ fillColor,
+ strokeAlpha,
+ fillAlpha,
+ pointsCallback: (buffer, points) => {
+ buffer.push(`${lineCoordinates[0]} ${lineCoordinates[1]} m`, `${lineCoordinates[2]} ${lineCoordinates[3]} l`, "S");
+ return [points[0].x - borderWidth, points[1].x + borderWidth, points[3].y - borderWidth, points[1].y + borderWidth];
+ }
+ });
+ }
+ }
+}
+class SquareAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.SQUARE;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ const interiorColor = getRgbColor(dict.getArray("IC"), null);
+ const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;
+ const fillAlpha = fillColor ? strokeAlpha : null;
+ if (this.borderStyle.width === 0 && !fillColor) {
+ return;
+ }
+ this._setDefaultAppearance({
+ xref,
+ extra: `${this.borderStyle.width} w`,
+ strokeColor,
+ fillColor,
+ strokeAlpha,
+ fillAlpha,
+ pointsCallback: (buffer, points) => {
+ const x = points[2].x + this.borderStyle.width / 2;
+ const y = points[2].y + this.borderStyle.width / 2;
+ const width = points[3].x - points[2].x - this.borderStyle.width;
+ const height = points[1].y - points[3].y - this.borderStyle.width;
+ buffer.push(`${x} ${y} ${width} ${height} re`);
+ if (fillColor) {
+ buffer.push("B");
+ } else {
+ buffer.push("S");
+ }
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ }
+}
+class CircleAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.CIRCLE;
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ const interiorColor = getRgbColor(dict.getArray("IC"), null);
+ const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null;
+ const fillAlpha = fillColor ? strokeAlpha : null;
+ if (this.borderStyle.width === 0 && !fillColor) {
+ return;
+ }
+ const controlPointsDistance = 4 / 3 * Math.tan(Math.PI / (2 * 4));
+ this._setDefaultAppearance({
+ xref,
+ extra: `${this.borderStyle.width} w`,
+ strokeColor,
+ fillColor,
+ strokeAlpha,
+ fillAlpha,
+ pointsCallback: (buffer, points) => {
+ const x0 = points[0].x + this.borderStyle.width / 2;
+ const y0 = points[0].y - this.borderStyle.width / 2;
+ const x1 = points[3].x - this.borderStyle.width / 2;
+ const y1 = points[3].y + this.borderStyle.width / 2;
+ const xMid = x0 + (x1 - x0) / 2;
+ const yMid = y0 + (y1 - y0) / 2;
+ const xOffset = (x1 - x0) / 2 * controlPointsDistance;
+ const yOffset = (y1 - y0) / 2 * controlPointsDistance;
+ buffer.push(`${xMid} ${y1} m`, `${xMid + xOffset} ${y1} ${x1} ${yMid + yOffset} ${x1} ${yMid} c`, `${x1} ${yMid - yOffset} ${xMid + xOffset} ${y0} ${xMid} ${y0} c`, `${xMid - xOffset} ${y0} ${x0} ${yMid - yOffset} ${x0} ${yMid} c`, `${x0} ${yMid + yOffset} ${xMid - xOffset} ${y1} ${xMid} ${y1} c`, "h");
+ if (fillColor) {
+ buffer.push("B");
+ } else {
+ buffer.push("S");
+ }
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ }
+}
+class PolylineAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.POLYLINE;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ this.data.vertices = [];
+ if (!(this instanceof PolygonAnnotation)) {
+ this.setLineEndings(dict.getArray("LE"));
+ this.data.lineEndings = this.lineEndings;
+ }
+ const rawVertices = dict.getArray("Vertices");
+ if (!Array.isArray(rawVertices)) {
+ return;
+ }
+ for (let i = 0, ii = rawVertices.length; i < ii; i += 2) {
+ this.data.vertices.push({
+ x: rawVertices[i],
+ y: rawVertices[i + 1]
+ });
+ }
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ const borderWidth = this.borderStyle.width || 1,
+ borderAdjust = 2 * borderWidth;
+ const bbox = [Infinity, Infinity, -Infinity, -Infinity];
+ for (const vertex of this.data.vertices) {
+ bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust);
+ bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust);
+ bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust);
+ bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust);
+ }
+ if (!Util.intersect(this.rectangle, bbox)) {
+ this.rectangle = bbox;
+ }
+ this._setDefaultAppearance({
+ xref,
+ extra: `${borderWidth} w`,
+ strokeColor,
+ strokeAlpha,
+ pointsCallback: (buffer, points) => {
+ const vertices = this.data.vertices;
+ for (let i = 0, ii = vertices.length; i < ii; i++) {
+ buffer.push(`${vertices[i].x} ${vertices[i].y} ${i === 0 ? "m" : "l"}`);
+ }
+ buffer.push("S");
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ }
+}
+class PolygonAnnotation extends PolylineAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.annotationType = AnnotationType.POLYGON;
+ }
+}
+class CaretAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.annotationType = AnnotationType.CARET;
+ }
+}
+class InkAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.INK;
+ this.data.inkLists = [];
+ const rawInkLists = dict.getArray("InkList");
+ if (!Array.isArray(rawInkLists)) {
+ return;
+ }
+ for (let i = 0, ii = rawInkLists.length; i < ii; ++i) {
+ this.data.inkLists.push([]);
+ for (let j = 0, jj = rawInkLists[i].length; j < jj; j += 2) {
+ this.data.inkLists[i].push({
+ x: xref.fetchIfRef(rawInkLists[i][j]),
+ y: xref.fetchIfRef(rawInkLists[i][j + 1])
+ });
+ }
+ }
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ const borderWidth = this.borderStyle.width || 1,
+ borderAdjust = 2 * borderWidth;
+ const bbox = [Infinity, Infinity, -Infinity, -Infinity];
+ for (const inkLists of this.data.inkLists) {
+ for (const vertex of inkLists) {
+ bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust);
+ bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust);
+ bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust);
+ bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust);
+ }
+ }
+ if (!Util.intersect(this.rectangle, bbox)) {
+ this.rectangle = bbox;
+ }
+ this._setDefaultAppearance({
+ xref,
+ extra: `${borderWidth} w`,
+ strokeColor,
+ strokeAlpha,
+ pointsCallback: (buffer, points) => {
+ for (const inkList of this.data.inkLists) {
+ for (let i = 0, ii = inkList.length; i < ii; i++) {
+ buffer.push(`${inkList[i].x} ${inkList[i].y} ${i === 0 ? "m" : "l"}`);
+ }
+ buffer.push("S");
+ }
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ }
+ static createNewDict(annotation, xref, {
+ apRef,
+ ap
+ }) {
+ const {
+ color,
+ opacity,
+ paths,
+ rect,
+ rotation,
+ thickness
+ } = annotation;
+ const ink = new Dict(xref);
+ ink.set("Type", Name.get("Annot"));
+ ink.set("Subtype", Name.get("Ink"));
+ ink.set("CreationDate", `D:${getModificationDate()}`);
+ ink.set("Rect", rect);
+ ink.set("InkList", paths.map(p => p.points));
+ ink.set("F", 4);
+ ink.set("Rotate", rotation);
+ const bs = new Dict(xref);
+ ink.set("BS", bs);
+ bs.set("W", thickness);
+ ink.set("C", Array.from(color, c => c / 255));
+ ink.set("CA", opacity);
+ const n = new Dict(xref);
+ ink.set("AP", n);
+ if (apRef) {
+ n.set("N", apRef);
+ } else {
+ n.set("N", ap);
+ }
+ return ink;
+ }
+ static async createNewAppearanceStream(annotation, xref, params) {
+ const {
+ color,
+ rect,
+ paths,
+ thickness,
+ opacity
+ } = annotation;
+ const appearanceBuffer = [`${thickness} w 1 J 1 j`, `${getPdfColor(color, false)}`];
+ if (opacity !== 1) {
+ appearanceBuffer.push("/R0 gs");
+ }
+ const buffer = [];
+ for (const {
+ bezier
+ } of paths) {
+ buffer.length = 0;
+ buffer.push(`${numberToString(bezier[0])} ${numberToString(bezier[1])} m`);
+ for (let i = 2, ii = bezier.length; i < ii; i += 6) {
+ const curve = bezier.slice(i, i + 6).map(numberToString).join(" ");
+ buffer.push(`${curve} c`);
+ }
+ buffer.push("S");
+ appearanceBuffer.push(buffer.join("\n"));
+ }
+ const appearance = appearanceBuffer.join("\n");
+ const appearanceStreamDict = new Dict(xref);
+ appearanceStreamDict.set("FormType", 1);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", rect);
+ appearanceStreamDict.set("Length", appearance.length);
+ if (opacity !== 1) {
+ const resources = new Dict(xref);
+ const extGState = new Dict(xref);
+ const r0 = new Dict(xref);
+ r0.set("CA", opacity);
+ r0.set("Type", Name.get("ExtGState"));
+ extGState.set("R0", r0);
+ resources.set("ExtGState", extGState);
+ appearanceStreamDict.set("Resources", resources);
+ }
+ const ap = new StringStream(appearance);
+ ap.dict = appearanceStreamDict;
+ return ap;
+ }
+}
+class HighlightAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.HIGHLIGHT;
+ const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);
+ if (quadPoints) {
+ const resources = this.appearance?.dict.get("Resources");
+ if (!this.appearance || !resources?.has("ExtGState")) {
+ if (this.appearance) {
+ warn("HighlightAnnotation - ignoring built-in appearance stream.");
+ }
+ const fillColor = this.color ? getPdfColorArray(this.color) : [1, 1, 0];
+ const fillAlpha = dict.get("CA");
+ this._setDefaultAppearance({
+ xref,
+ fillColor,
+ blendMode: "Multiply",
+ fillAlpha,
+ pointsCallback: (buffer, points) => {
+ buffer.push(`${points[0].x} ${points[0].y} m`, `${points[1].x} ${points[1].y} l`, `${points[3].x} ${points[3].y} l`, `${points[2].x} ${points[2].y} l`, "f");
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ } else {
+ this.data.popupRef = null;
+ }
+ }
+ static createNewDict(annotation, xref, {
+ apRef,
+ ap
+ }) {
+ const {
+ color,
+ opacity,
+ rect,
+ rotation,
+ user,
+ quadPoints
+ } = annotation;
+ const highlight = new Dict(xref);
+ highlight.set("Type", Name.get("Annot"));
+ highlight.set("Subtype", Name.get("Highlight"));
+ highlight.set("CreationDate", `D:${getModificationDate()}`);
+ highlight.set("Rect", rect);
+ highlight.set("F", 4);
+ highlight.set("Border", [0, 0, 0]);
+ highlight.set("Rotate", rotation);
+ highlight.set("QuadPoints", quadPoints);
+ highlight.set("C", Array.from(color, c => c / 255));
+ highlight.set("CA", opacity);
+ if (user) {
+ highlight.set("T", isAscii(user) ? user : stringToUTF16String(user, true));
+ }
+ if (apRef || ap) {
+ const n = new Dict(xref);
+ highlight.set("AP", n);
+ n.set("N", apRef || ap);
+ }
+ return highlight;
+ }
+ static async createNewAppearanceStream(annotation, xref, params) {
+ const {
+ color,
+ rect,
+ outlines,
+ opacity
+ } = annotation;
+ const appearanceBuffer = [`${getPdfColor(color, true)}`, "/R0 gs"];
+ const buffer = [];
+ for (const outline of outlines) {
+ buffer.length = 0;
+ buffer.push(`${numberToString(outline[0])} ${numberToString(outline[1])} m`);
+ for (let i = 2, ii = outline.length; i < ii; i += 2) {
+ buffer.push(`${numberToString(outline[i])} ${numberToString(outline[i + 1])} l`);
+ }
+ buffer.push("h");
+ appearanceBuffer.push(buffer.join("\n"));
+ }
+ appearanceBuffer.push("f*");
+ const appearance = appearanceBuffer.join("\n");
+ const appearanceStreamDict = new Dict(xref);
+ appearanceStreamDict.set("FormType", 1);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", rect);
+ appearanceStreamDict.set("Length", appearance.length);
+ const resources = new Dict(xref);
+ const extGState = new Dict(xref);
+ resources.set("ExtGState", extGState);
+ appearanceStreamDict.set("Resources", resources);
+ const r0 = new Dict(xref);
+ extGState.set("R0", r0);
+ r0.set("BM", Name.get("Multiply"));
+ if (opacity !== 1) {
+ r0.set("ca", opacity);
+ r0.set("Type", Name.get("ExtGState"));
+ }
+ const ap = new StringStream(appearance);
+ ap.dict = appearanceStreamDict;
+ return ap;
+ }
+}
+class UnderlineAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.UNDERLINE;
+ const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);
+ if (quadPoints) {
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ this._setDefaultAppearance({
+ xref,
+ extra: "[] 0 d 0.571 w",
+ strokeColor,
+ strokeAlpha,
+ pointsCallback: (buffer, points) => {
+ buffer.push(`${points[2].x} ${points[2].y + 1.3} m`, `${points[3].x} ${points[3].y + 1.3} l`, "S");
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ } else {
+ this.data.popupRef = null;
+ }
+ }
+}
+class SquigglyAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.SQUIGGLY;
+ const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);
+ if (quadPoints) {
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ this._setDefaultAppearance({
+ xref,
+ extra: "[] 0 d 1 w",
+ strokeColor,
+ strokeAlpha,
+ pointsCallback: (buffer, points) => {
+ const dy = (points[0].y - points[2].y) / 6;
+ let shift = dy;
+ let x = points[2].x;
+ const y = points[2].y;
+ const xEnd = points[3].x;
+ buffer.push(`${x} ${y + shift} m`);
+ do {
+ x += 2;
+ shift = shift === 0 ? dy : 0;
+ buffer.push(`${x} ${y + shift} l`);
+ } while (x < xEnd);
+ buffer.push("S");
+ return [points[2].x, xEnd, y - 2 * dy, y + 2 * dy];
+ }
+ });
+ }
+ } else {
+ this.data.popupRef = null;
+ }
+ }
+}
+class StrikeOutAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ this.data.annotationType = AnnotationType.STRIKEOUT;
+ const quadPoints = this.data.quadPoints = getQuadPoints(dict, null);
+ if (quadPoints) {
+ if (!this.appearance) {
+ const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0];
+ const strokeAlpha = dict.get("CA");
+ this._setDefaultAppearance({
+ xref,
+ extra: "[] 0 d 1 w",
+ strokeColor,
+ strokeAlpha,
+ pointsCallback: (buffer, points) => {
+ buffer.push(`${(points[0].x + points[2].x) / 2} ` + `${(points[0].y + points[2].y) / 2} m`, `${(points[1].x + points[3].x) / 2} ` + `${(points[1].y + points[3].y) / 2} l`, "S");
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
+ }
+ });
+ }
+ } else {
+ this.data.popupRef = null;
+ }
+ }
+}
+class StampAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ this.data.annotationType = AnnotationType.STAMP;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ }
+ static async createImage(bitmap, xref) {
+ const {
+ width,
+ height
+ } = bitmap;
+ const canvas = new OffscreenCanvas(width, height);
+ const ctx = canvas.getContext("2d", {
+ alpha: true
+ });
+ ctx.drawImage(bitmap, 0, 0);
+ const data = ctx.getImageData(0, 0, width, height).data;
+ const buf32 = new Uint32Array(data.buffer);
+ const hasAlpha = buf32.some(FeatureTest.isLittleEndian ? x => x >>> 24 !== 0xff : x => (x & 0xff) !== 0xff);
+ if (hasAlpha) {
+ ctx.fillStyle = "white";
+ ctx.fillRect(0, 0, width, height);
+ ctx.drawImage(bitmap, 0, 0);
+ }
+ const jpegBufferPromise = canvas.convertToBlob({
+ type: "image/jpeg",
+ quality: 1
+ }).then(blob => {
+ return blob.arrayBuffer();
+ });
+ const xobjectName = Name.get("XObject");
+ const imageName = Name.get("Image");
+ const image = new Dict(xref);
+ image.set("Type", xobjectName);
+ image.set("Subtype", imageName);
+ image.set("BitsPerComponent", 8);
+ image.set("ColorSpace", Name.get("DeviceRGB"));
+ image.set("Filter", Name.get("DCTDecode"));
+ image.set("BBox", [0, 0, width, height]);
+ image.set("Width", width);
+ image.set("Height", height);
+ let smaskStream = null;
+ if (hasAlpha) {
+ const alphaBuffer = new Uint8Array(buf32.length);
+ if (FeatureTest.isLittleEndian) {
+ for (let i = 0, ii = buf32.length; i < ii; i++) {
+ alphaBuffer[i] = buf32[i] >>> 24;
+ }
+ } else {
+ for (let i = 0, ii = buf32.length; i < ii; i++) {
+ alphaBuffer[i] = buf32[i] & 0xff;
+ }
+ }
+ const smask = new Dict(xref);
+ smask.set("Type", xobjectName);
+ smask.set("Subtype", imageName);
+ smask.set("BitsPerComponent", 8);
+ smask.set("ColorSpace", Name.get("DeviceGray"));
+ smask.set("Width", width);
+ smask.set("Height", height);
+ smaskStream = new Stream(alphaBuffer, 0, 0, smask);
+ }
+ const imageStream = new Stream(await jpegBufferPromise, 0, 0, image);
+ return {
+ imageStream,
+ smaskStream,
+ width,
+ height
+ };
+ }
+ static createNewDict(annotation, xref, {
+ apRef,
+ ap
+ }) {
+ const {
+ rect,
+ rotation,
+ user
+ } = annotation;
+ const stamp = new Dict(xref);
+ stamp.set("Type", Name.get("Annot"));
+ stamp.set("Subtype", Name.get("Stamp"));
+ stamp.set("CreationDate", `D:${getModificationDate()}`);
+ stamp.set("Rect", rect);
+ stamp.set("F", 4);
+ stamp.set("Border", [0, 0, 0]);
+ stamp.set("Rotate", rotation);
+ if (user) {
+ stamp.set("T", isAscii(user) ? user : stringToUTF16String(user, true));
+ }
+ if (apRef || ap) {
+ const n = new Dict(xref);
+ stamp.set("AP", n);
+ if (apRef) {
+ n.set("N", apRef);
+ } else {
+ n.set("N", ap);
+ }
+ }
+ return stamp;
+ }
+ static async createNewAppearanceStream(annotation, xref, params) {
+ const {
+ rotation
+ } = annotation;
+ const {
+ imageRef,
+ width,
+ height
+ } = params.image;
+ const resources = new Dict(xref);
+ const xobject = new Dict(xref);
+ resources.set("XObject", xobject);
+ xobject.set("Im0", imageRef);
+ const appearance = `q ${width} 0 0 ${height} 0 0 cm /Im0 Do Q`;
+ const appearanceStreamDict = new Dict(xref);
+ appearanceStreamDict.set("FormType", 1);
+ appearanceStreamDict.set("Subtype", Name.get("Form"));
+ appearanceStreamDict.set("Type", Name.get("XObject"));
+ appearanceStreamDict.set("BBox", [0, 0, width, height]);
+ appearanceStreamDict.set("Resources", resources);
+ if (rotation) {
+ const matrix = getRotationMatrix(rotation, width, height);
+ appearanceStreamDict.set("Matrix", matrix);
+ }
+ const ap = new StringStream(appearance);
+ ap.dict = appearanceStreamDict;
+ return ap;
+ }
+}
+class FileAttachmentAnnotation extends MarkupAnnotation {
+ constructor(params) {
+ super(params);
+ const {
+ dict,
+ xref
+ } = params;
+ const file = new FileSpec(dict.get("FS"), xref);
+ this.data.annotationType = AnnotationType.FILEATTACHMENT;
+ this.data.hasOwnCanvas = this.data.noRotate;
+ this.data.noHTML = false;
+ this.data.file = file.serializable;
+ const name = dict.get("Name");
+ this.data.name = name instanceof Name ? stringToPDFString(name.name) : "PushPin";
+ const fillAlpha = dict.get("ca");
+ this.data.fillAlpha = typeof fillAlpha === "number" && fillAlpha >= 0 && fillAlpha <= 1 ? fillAlpha : null;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/dataset_reader.js
+
+
+
+function decodeString(str) {
+ try {
+ return stringToUTF8String(str);
+ } catch (ex) {
+ warn(`UTF-8 decoding failed: "${ex}".`);
+ return str;
+ }
+}
+class DatasetXMLParser extends SimpleXMLParser {
+ constructor(options) {
+ super(options);
+ this.node = null;
+ }
+ onEndElement(name) {
+ const node = super.onEndElement(name);
+ if (node && name === "xfa:datasets") {
+ this.node = node;
+ throw new Error("Aborting DatasetXMLParser.");
+ }
+ }
+}
+class DatasetReader {
+ constructor(data) {
+ if (data.datasets) {
+ this.node = new SimpleXMLParser({
+ hasAttributes: true
+ }).parseFromString(data.datasets).documentElement;
+ } else {
+ const parser = new DatasetXMLParser({
+ hasAttributes: true
+ });
+ try {
+ parser.parseFromString(data["xdp:xdp"]);
+ } catch {}
+ this.node = parser.node;
+ }
+ }
+ getValue(path) {
+ if (!this.node || !path) {
+ return "";
+ }
+ const node = this.node.searchNode(parseXFAPath(path), 0);
+ if (!node) {
+ return "";
+ }
+ const first = node.firstChild;
+ if (first?.nodeName === "value") {
+ return node.children.map(child => decodeString(child.textContent));
+ }
+ return decodeString(node.textContent);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/xref.js
+
+
+
+
+
+
+class XRef {
+ #firstXRefStmPos = null;
+ constructor(stream, pdfManager) {
+ this.stream = stream;
+ this.pdfManager = pdfManager;
+ this.entries = [];
+ this._xrefStms = new Set();
+ this._cacheMap = new Map();
+ this._pendingRefs = new RefSet();
+ this._newPersistentRefNum = null;
+ this._newTemporaryRefNum = null;
+ this._persistentRefsCache = null;
+ }
+ getNewPersistentRef(obj) {
+ if (this._newPersistentRefNum === null) {
+ this._newPersistentRefNum = this.entries.length || 1;
+ }
+ const num = this._newPersistentRefNum++;
+ this._cacheMap.set(num, obj);
+ return Ref.get(num, 0);
+ }
+ getNewTemporaryRef() {
+ if (this._newTemporaryRefNum === null) {
+ this._newTemporaryRefNum = this.entries.length || 1;
+ if (this._newPersistentRefNum) {
+ this._persistentRefsCache = new Map();
+ for (let i = this._newTemporaryRefNum; i < this._newPersistentRefNum; i++) {
+ this._persistentRefsCache.set(i, this._cacheMap.get(i));
+ this._cacheMap.delete(i);
+ }
+ }
+ }
+ return Ref.get(this._newTemporaryRefNum++, 0);
+ }
+ resetNewTemporaryRef() {
+ this._newTemporaryRefNum = null;
+ if (this._persistentRefsCache) {
+ for (const [num, obj] of this._persistentRefsCache) {
+ this._cacheMap.set(num, obj);
+ }
+ }
+ this._persistentRefsCache = null;
+ }
+ setStartXRef(startXRef) {
+ this.startXRefQueue = [startXRef];
+ }
+ parse(recoveryMode = false) {
+ let trailerDict;
+ if (!recoveryMode) {
+ trailerDict = this.readXRef();
+ } else {
+ warn("Indexing all PDF objects");
+ trailerDict = this.indexObjects();
+ }
+ trailerDict.assignXref(this);
+ this.trailer = trailerDict;
+ let encrypt;
+ try {
+ encrypt = trailerDict.get("Encrypt");
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`);
+ }
+ if (encrypt instanceof Dict) {
+ const ids = trailerDict.get("ID");
+ const fileId = ids?.length ? ids[0] : "";
+ encrypt.suppressEncryption = true;
+ this.encrypt = new CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
+ }
+ let root;
+ try {
+ root = trailerDict.get("Root");
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`XRef.parse - Invalid "Root" reference: "${ex}".`);
+ }
+ if (root instanceof Dict) {
+ try {
+ const pages = root.get("Pages");
+ if (pages instanceof Dict) {
+ this.root = root;
+ return;
+ }
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`XRef.parse - Invalid "Pages" reference: "${ex}".`);
+ }
+ }
+ if (!recoveryMode) {
+ throw new XRefParseException();
+ }
+ throw new InvalidPDFException("Invalid Root reference.");
+ }
+ processXRefTable(parser) {
+ if (!("tableState" in this)) {
+ this.tableState = {
+ entryNum: 0,
+ streamPos: parser.lexer.stream.pos,
+ parserBuf1: parser.buf1,
+ parserBuf2: parser.buf2
+ };
+ }
+ const obj = this.readXRefTable(parser);
+ if (!isCmd(obj, "trailer")) {
+ throw new FormatError("Invalid XRef table: could not find trailer dictionary");
+ }
+ let dict = parser.getObj();
+ if (!(dict instanceof Dict) && dict.dict) {
+ dict = dict.dict;
+ }
+ if (!(dict instanceof Dict)) {
+ throw new FormatError("Invalid XRef table: could not parse trailer dictionary");
+ }
+ delete this.tableState;
+ return dict;
+ }
+ readXRefTable(parser) {
+ const stream = parser.lexer.stream;
+ const tableState = this.tableState;
+ stream.pos = tableState.streamPos;
+ parser.buf1 = tableState.parserBuf1;
+ parser.buf2 = tableState.parserBuf2;
+ let obj;
+ while (true) {
+ if (!("firstEntryNum" in tableState) || !("entryCount" in tableState)) {
+ if (isCmd(obj = parser.getObj(), "trailer")) {
+ break;
+ }
+ tableState.firstEntryNum = obj;
+ tableState.entryCount = parser.getObj();
+ }
+ let first = tableState.firstEntryNum;
+ const count = tableState.entryCount;
+ if (!Number.isInteger(first) || !Number.isInteger(count)) {
+ throw new FormatError("Invalid XRef table: wrong types in subsection header");
+ }
+ for (let i = tableState.entryNum; i < count; i++) {
+ tableState.streamPos = stream.pos;
+ tableState.entryNum = i;
+ tableState.parserBuf1 = parser.buf1;
+ tableState.parserBuf2 = parser.buf2;
+ const entry = {};
+ entry.offset = parser.getObj();
+ entry.gen = parser.getObj();
+ const type = parser.getObj();
+ if (type instanceof Cmd) {
+ switch (type.cmd) {
+ case "f":
+ entry.free = true;
+ break;
+ case "n":
+ entry.uncompressed = true;
+ break;
+ }
+ }
+ if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {
+ throw new FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`);
+ }
+ if (i === 0 && entry.free && first === 1) {
+ first = 0;
+ }
+ if (!this.entries[i + first]) {
+ this.entries[i + first] = entry;
+ }
+ }
+ tableState.entryNum = 0;
+ tableState.streamPos = stream.pos;
+ tableState.parserBuf1 = parser.buf1;
+ tableState.parserBuf2 = parser.buf2;
+ delete tableState.firstEntryNum;
+ delete tableState.entryCount;
+ }
+ if (this.entries[0] && !this.entries[0].free) {
+ throw new FormatError("Invalid XRef table: unexpected first object");
+ }
+ return obj;
+ }
+ processXRefStream(stream) {
+ if (!("streamState" in this)) {
+ const streamParameters = stream.dict;
+ const byteWidths = streamParameters.get("W");
+ let range = streamParameters.get("Index");
+ if (!range) {
+ range = [0, streamParameters.get("Size")];
+ }
+ this.streamState = {
+ entryRanges: range,
+ byteWidths,
+ entryNum: 0,
+ streamPos: stream.pos
+ };
+ }
+ this.readXRefStream(stream);
+ delete this.streamState;
+ return stream.dict;
+ }
+ readXRefStream(stream) {
+ const streamState = this.streamState;
+ stream.pos = streamState.streamPos;
+ const [typeFieldWidth, offsetFieldWidth, generationFieldWidth] = streamState.byteWidths;
+ const entryRanges = streamState.entryRanges;
+ while (entryRanges.length > 0) {
+ const [first, n] = entryRanges;
+ if (!Number.isInteger(first) || !Number.isInteger(n)) {
+ throw new FormatError(`Invalid XRef range fields: ${first}, ${n}`);
+ }
+ if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {
+ throw new FormatError(`Invalid XRef entry fields length: ${first}, ${n}`);
+ }
+ for (let i = streamState.entryNum; i < n; ++i) {
+ streamState.entryNum = i;
+ streamState.streamPos = stream.pos;
+ let type = 0,
+ offset = 0,
+ generation = 0;
+ for (let j = 0; j < typeFieldWidth; ++j) {
+ const typeByte = stream.getByte();
+ if (typeByte === -1) {
+ throw new FormatError("Invalid XRef byteWidths 'type'.");
+ }
+ type = type << 8 | typeByte;
+ }
+ if (typeFieldWidth === 0) {
+ type = 1;
+ }
+ for (let j = 0; j < offsetFieldWidth; ++j) {
+ const offsetByte = stream.getByte();
+ if (offsetByte === -1) {
+ throw new FormatError("Invalid XRef byteWidths 'offset'.");
+ }
+ offset = offset << 8 | offsetByte;
+ }
+ for (let j = 0; j < generationFieldWidth; ++j) {
+ const generationByte = stream.getByte();
+ if (generationByte === -1) {
+ throw new FormatError("Invalid XRef byteWidths 'generation'.");
+ }
+ generation = generation << 8 | generationByte;
+ }
+ const entry = {};
+ entry.offset = offset;
+ entry.gen = generation;
+ switch (type) {
+ case 0:
+ entry.free = true;
+ break;
+ case 1:
+ entry.uncompressed = true;
+ break;
+ case 2:
+ break;
+ default:
+ throw new FormatError(`Invalid XRef entry type: ${type}`);
+ }
+ if (!this.entries[first + i]) {
+ this.entries[first + i] = entry;
+ }
+ }
+ streamState.entryNum = 0;
+ streamState.streamPos = stream.pos;
+ entryRanges.splice(0, 2);
+ }
+ }
+ indexObjects() {
+ const TAB = 0x9,
+ LF = 0xa,
+ CR = 0xd,
+ SPACE = 0x20;
+ const PERCENT = 0x25,
+ LT = 0x3c;
+ function readToken(data, offset) {
+ let token = "",
+ ch = data[offset];
+ while (ch !== LF && ch !== CR && ch !== LT) {
+ if (++offset >= data.length) {
+ break;
+ }
+ token += String.fromCharCode(ch);
+ ch = data[offset];
+ }
+ return token;
+ }
+ function skipUntil(data, offset, what) {
+ const length = what.length,
+ dataLength = data.length;
+ let skipped = 0;
+ while (offset < dataLength) {
+ let i = 0;
+ while (i < length && data[offset + i] === what[i]) {
+ ++i;
+ }
+ if (i >= length) {
+ break;
+ }
+ offset++;
+ skipped++;
+ }
+ return skipped;
+ }
+ const gEndobjRegExp = /\b(endobj|\d+\s+\d+\s+obj|xref|trailer\s*<<)\b/g;
+ const gStartxrefRegExp = /\b(startxref|\d+\s+\d+\s+obj)\b/g;
+ const objRegExp = /^(\d+)\s+(\d+)\s+obj\b/;
+ const trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]);
+ const startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]);
+ const xrefBytes = new Uint8Array([47, 88, 82, 101, 102]);
+ this.entries.length = 0;
+ this._cacheMap.clear();
+ const stream = this.stream;
+ stream.pos = 0;
+ const buffer = stream.getBytes(),
+ bufferStr = bytesToString(buffer),
+ length = buffer.length;
+ let position = stream.start;
+ const trailers = [],
+ xrefStms = [];
+ while (position < length) {
+ let ch = buffer[position];
+ if (ch === TAB || ch === LF || ch === CR || ch === SPACE) {
+ ++position;
+ continue;
+ }
+ if (ch === PERCENT) {
+ do {
+ ++position;
+ if (position >= length) {
+ break;
+ }
+ ch = buffer[position];
+ } while (ch !== LF && ch !== CR);
+ continue;
+ }
+ const token = readToken(buffer, position);
+ let m;
+ if (token.startsWith("xref") && (token.length === 4 || /\s/.test(token[4]))) {
+ position += skipUntil(buffer, position, trailerBytes);
+ trailers.push(position);
+ position += skipUntil(buffer, position, startxrefBytes);
+ } else if (m = objRegExp.exec(token)) {
+ const num = m[1] | 0,
+ gen = m[2] | 0;
+ const startPos = position + token.length;
+ let contentLength,
+ updateEntries = false;
+ if (!this.entries[num]) {
+ updateEntries = true;
+ } else if (this.entries[num].gen === gen) {
+ try {
+ const parser = new Parser({
+ lexer: new Lexer(stream.makeSubStream(startPos))
+ });
+ parser.getObj();
+ updateEntries = true;
+ } catch (ex) {
+ if (ex instanceof ParserEOFException) {
+ warn(`indexObjects -- checking object (${token}): "${ex}".`);
+ } else {
+ updateEntries = true;
+ }
+ }
+ }
+ if (updateEntries) {
+ this.entries[num] = {
+ offset: position - stream.start,
+ gen,
+ uncompressed: true
+ };
+ }
+ gEndobjRegExp.lastIndex = startPos;
+ const match = gEndobjRegExp.exec(bufferStr);
+ if (match) {
+ const endPos = gEndobjRegExp.lastIndex + 1;
+ contentLength = endPos - position;
+ if (match[1] !== "endobj") {
+ warn(`indexObjects: Found "${match[1]}" inside of another "obj", ` + 'caused by missing "endobj" -- trying to recover.');
+ contentLength -= match[1].length + 1;
+ }
+ } else {
+ contentLength = length - position;
+ }
+ const content = buffer.subarray(position, position + contentLength);
+ const xrefTagOffset = skipUntil(content, 0, xrefBytes);
+ if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {
+ xrefStms.push(position - stream.start);
+ this._xrefStms.add(position - stream.start);
+ }
+ position += contentLength;
+ } else if (token.startsWith("trailer") && (token.length === 7 || /\s/.test(token[7]))) {
+ trailers.push(position);
+ const startPos = position + token.length;
+ let contentLength;
+ gStartxrefRegExp.lastIndex = startPos;
+ const match = gStartxrefRegExp.exec(bufferStr);
+ if (match) {
+ const endPos = gStartxrefRegExp.lastIndex + 1;
+ contentLength = endPos - position;
+ if (match[1] !== "startxref") {
+ warn(`indexObjects: Found "${match[1]}" after "trailer", ` + 'caused by missing "startxref" -- trying to recover.');
+ contentLength -= match[1].length + 1;
+ }
+ } else {
+ contentLength = length - position;
+ }
+ position += contentLength;
+ } else {
+ position += token.length + 1;
+ }
+ }
+ for (const xrefStm of xrefStms) {
+ this.startXRefQueue.push(xrefStm);
+ this.readXRef(true);
+ }
+ const trailerDicts = [];
+ let isEncrypted = false;
+ for (const trailer of trailers) {
+ stream.pos = trailer;
+ const parser = new Parser({
+ lexer: new Lexer(stream),
+ xref: this,
+ allowStreams: true,
+ recoveryMode: true
+ });
+ const obj = parser.getObj();
+ if (!isCmd(obj, "trailer")) {
+ continue;
+ }
+ const dict = parser.getObj();
+ if (!(dict instanceof Dict)) {
+ continue;
+ }
+ trailerDicts.push(dict);
+ if (dict.has("Encrypt")) {
+ isEncrypted = true;
+ }
+ }
+ let trailerDict, trailerError;
+ for (const dict of [...trailerDicts, "genFallback", ...trailerDicts]) {
+ if (dict === "genFallback") {
+ if (!trailerError) {
+ break;
+ }
+ this._generationFallback = true;
+ continue;
+ }
+ let validPagesDict = false;
+ try {
+ const rootDict = dict.get("Root");
+ if (!(rootDict instanceof Dict)) {
+ continue;
+ }
+ const pagesDict = rootDict.get("Pages");
+ if (!(pagesDict instanceof Dict)) {
+ continue;
+ }
+ const pagesCount = pagesDict.get("Count");
+ if (Number.isInteger(pagesCount)) {
+ validPagesDict = true;
+ }
+ } catch (ex) {
+ trailerError = ex;
+ continue;
+ }
+ if (validPagesDict && (!isEncrypted || dict.has("Encrypt")) && dict.has("ID")) {
+ return dict;
+ }
+ trailerDict = dict;
+ }
+ if (trailerDict) {
+ return trailerDict;
+ }
+ if (this.topDict) {
+ return this.topDict;
+ }
+ throw new InvalidPDFException("Invalid PDF structure.");
+ }
+ readXRef(recoveryMode = false) {
+ const stream = this.stream;
+ const startXRefParsedCache = new Set();
+ while (this.startXRefQueue.length) {
+ try {
+ const startXRef = this.startXRefQueue[0];
+ if (startXRefParsedCache.has(startXRef)) {
+ warn("readXRef - skipping XRef table since it was already parsed.");
+ this.startXRefQueue.shift();
+ continue;
+ }
+ startXRefParsedCache.add(startXRef);
+ stream.pos = startXRef + stream.start;
+ const parser = new Parser({
+ lexer: new Lexer(stream),
+ xref: this,
+ allowStreams: true
+ });
+ let obj = parser.getObj();
+ let dict;
+ if (isCmd(obj, "xref")) {
+ dict = this.processXRefTable(parser);
+ if (!this.topDict) {
+ this.topDict = dict;
+ }
+ obj = dict.get("XRefStm");
+ if (Number.isInteger(obj) && !this._xrefStms.has(obj)) {
+ this._xrefStms.add(obj);
+ this.startXRefQueue.push(obj);
+ this.#firstXRefStmPos ??= obj;
+ }
+ } else if (Number.isInteger(obj)) {
+ if (!Number.isInteger(parser.getObj()) || !isCmd(parser.getObj(), "obj") || !((obj = parser.getObj()) instanceof BaseStream)) {
+ throw new FormatError("Invalid XRef stream");
+ }
+ dict = this.processXRefStream(obj);
+ if (!this.topDict) {
+ this.topDict = dict;
+ }
+ if (!dict) {
+ throw new FormatError("Failed to read XRef stream");
+ }
+ } else {
+ throw new FormatError("Invalid XRef stream header");
+ }
+ obj = dict.get("Prev");
+ if (Number.isInteger(obj)) {
+ this.startXRefQueue.push(obj);
+ } else if (obj instanceof Ref) {
+ this.startXRefQueue.push(obj.num);
+ }
+ } catch (e) {
+ if (e instanceof MissingDataException) {
+ throw e;
+ }
+ info("(while reading XRef): " + e);
+ }
+ this.startXRefQueue.shift();
+ }
+ if (this.topDict) {
+ return this.topDict;
+ }
+ if (recoveryMode) {
+ return undefined;
+ }
+ throw new XRefParseException();
+ }
+ get lastXRefStreamPos() {
+ return this.#firstXRefStmPos ?? (this._xrefStms.size > 0 ? Math.max(...this._xrefStms) : null);
+ }
+ getEntry(i) {
+ const xrefEntry = this.entries[i];
+ if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {
+ return xrefEntry;
+ }
+ return null;
+ }
+ fetchIfRef(obj, suppressEncryption = false) {
+ if (obj instanceof Ref) {
+ return this.fetch(obj, suppressEncryption);
+ }
+ return obj;
+ }
+ fetch(ref, suppressEncryption = false) {
+ if (!(ref instanceof Ref)) {
+ throw new Error("ref object is not a reference");
+ }
+ const num = ref.num;
+ const cacheEntry = this._cacheMap.get(num);
+ if (cacheEntry !== undefined) {
+ if (cacheEntry instanceof Dict && !cacheEntry.objId) {
+ cacheEntry.objId = ref.toString();
+ }
+ return cacheEntry;
+ }
+ let xrefEntry = this.getEntry(num);
+ if (xrefEntry === null) {
+ this._cacheMap.set(num, xrefEntry);
+ return xrefEntry;
+ }
+ if (this._pendingRefs.has(ref)) {
+ this._pendingRefs.remove(ref);
+ warn(`Ignoring circular reference: ${ref}.`);
+ return CIRCULAR_REF;
+ }
+ this._pendingRefs.put(ref);
+ try {
+ xrefEntry = xrefEntry.uncompressed ? this.fetchUncompressed(ref, xrefEntry, suppressEncryption) : this.fetchCompressed(ref, xrefEntry, suppressEncryption);
+ this._pendingRefs.remove(ref);
+ } catch (ex) {
+ this._pendingRefs.remove(ref);
+ throw ex;
+ }
+ if (xrefEntry instanceof Dict) {
+ xrefEntry.objId = ref.toString();
+ } else if (xrefEntry instanceof BaseStream) {
+ xrefEntry.dict.objId = ref.toString();
+ }
+ return xrefEntry;
+ }
+ fetchUncompressed(ref, xrefEntry, suppressEncryption = false) {
+ const gen = ref.gen;
+ let num = ref.num;
+ if (xrefEntry.gen !== gen) {
+ const msg = `Inconsistent generation in XRef: ${ref}`;
+ if (this._generationFallback && xrefEntry.gen < gen) {
+ warn(msg);
+ return this.fetchUncompressed(Ref.get(num, xrefEntry.gen), xrefEntry, suppressEncryption);
+ }
+ throw new XRefEntryException(msg);
+ }
+ const stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);
+ const parser = new Parser({
+ lexer: new Lexer(stream),
+ xref: this,
+ allowStreams: true
+ });
+ const obj1 = parser.getObj();
+ const obj2 = parser.getObj();
+ const obj3 = parser.getObj();
+ if (obj1 !== num || obj2 !== gen || !(obj3 instanceof Cmd)) {
+ throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
+ }
+ if (obj3.cmd !== "obj") {
+ if (obj3.cmd.startsWith("obj")) {
+ num = parseInt(obj3.cmd.substring(3), 10);
+ if (!Number.isNaN(num)) {
+ return num;
+ }
+ }
+ throw new XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
+ }
+ xrefEntry = this.encrypt && !suppressEncryption ? parser.getObj(this.encrypt.createCipherTransform(num, gen)) : parser.getObj();
+ if (!(xrefEntry instanceof BaseStream)) {
+ this._cacheMap.set(num, xrefEntry);
+ }
+ return xrefEntry;
+ }
+ fetchCompressed(ref, xrefEntry, suppressEncryption = false) {
+ const tableOffset = xrefEntry.offset;
+ const stream = this.fetch(Ref.get(tableOffset, 0));
+ if (!(stream instanceof BaseStream)) {
+ throw new FormatError("bad ObjStm stream");
+ }
+ const first = stream.dict.get("First");
+ const n = stream.dict.get("N");
+ if (!Number.isInteger(first) || !Number.isInteger(n)) {
+ throw new FormatError("invalid first and n parameters for ObjStm stream");
+ }
+ let parser = new Parser({
+ lexer: new Lexer(stream),
+ xref: this,
+ allowStreams: true
+ });
+ const nums = new Array(n);
+ const offsets = new Array(n);
+ for (let i = 0; i < n; ++i) {
+ const num = parser.getObj();
+ if (!Number.isInteger(num)) {
+ throw new FormatError(`invalid object number in the ObjStm stream: ${num}`);
+ }
+ const offset = parser.getObj();
+ if (!Number.isInteger(offset)) {
+ throw new FormatError(`invalid object offset in the ObjStm stream: ${offset}`);
+ }
+ nums[i] = num;
+ offsets[i] = offset;
+ }
+ const start = (stream.start || 0) + first;
+ const entries = new Array(n);
+ for (let i = 0; i < n; ++i) {
+ const length = i < n - 1 ? offsets[i + 1] - offsets[i] : undefined;
+ if (length < 0) {
+ throw new FormatError("Invalid offset in the ObjStm stream.");
+ }
+ parser = new Parser({
+ lexer: new Lexer(stream.makeSubStream(start + offsets[i], length, stream.dict)),
+ xref: this,
+ allowStreams: true
+ });
+ const obj = parser.getObj();
+ entries[i] = obj;
+ if (obj instanceof BaseStream) {
+ continue;
+ }
+ const num = nums[i],
+ entry = this.entries[num];
+ if (entry && entry.offset === tableOffset && entry.gen === i) {
+ this._cacheMap.set(num, obj);
+ }
+ }
+ xrefEntry = entries[xrefEntry.gen];
+ if (xrefEntry === undefined) {
+ throw new XRefEntryException(`Bad (compressed) XRef entry: ${ref}`);
+ }
+ return xrefEntry;
+ }
+ async fetchIfRefAsync(obj, suppressEncryption) {
+ if (obj instanceof Ref) {
+ return this.fetchAsync(obj, suppressEncryption);
+ }
+ return obj;
+ }
+ async fetchAsync(ref, suppressEncryption) {
+ try {
+ return this.fetch(ref, suppressEncryption);
+ } catch (ex) {
+ if (!(ex instanceof MissingDataException)) {
+ throw ex;
+ }
+ await this.pdfManager.requestRange(ex.begin, ex.end);
+ return this.fetchAsync(ref, suppressEncryption);
+ }
+ }
+ getCatalogObj() {
+ return this.root;
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/document.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const DEFAULT_USER_UNIT = 1.0;
+const LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
+class Page {
+ constructor({
+ pdfManager,
+ xref,
+ pageIndex,
+ pageDict,
+ ref,
+ globalIdFactory,
+ fontCache,
+ builtInCMapCache,
+ standardFontDataCache,
+ globalImageCache,
+ systemFontCache,
+ nonBlendModesSet,
+ xfaFactory
+ }) {
+ this.pdfManager = pdfManager;
+ this.pageIndex = pageIndex;
+ this.pageDict = pageDict;
+ this.xref = xref;
+ this.ref = ref;
+ this.fontCache = fontCache;
+ this.builtInCMapCache = builtInCMapCache;
+ this.standardFontDataCache = standardFontDataCache;
+ this.globalImageCache = globalImageCache;
+ this.systemFontCache = systemFontCache;
+ this.nonBlendModesSet = nonBlendModesSet;
+ this.evaluatorOptions = pdfManager.evaluatorOptions;
+ this.resourcesPromise = null;
+ this.xfaFactory = xfaFactory;
+ const idCounters = {
+ obj: 0
+ };
+ this._localIdFactory = class extends globalIdFactory {
+ static createObjId() {
+ return `p${pageIndex}_${++idCounters.obj}`;
+ }
+ static getPageObjId() {
+ return `p${ref.toString()}`;
+ }
+ };
+ }
+ _getInheritableProperty(key, getArray = false) {
+ const value = getInheritableProperty({
+ dict: this.pageDict,
+ key,
+ getArray,
+ stopWhenFound: false
+ });
+ if (!Array.isArray(value)) {
+ return value;
+ }
+ if (value.length === 1 || !(value[0] instanceof Dict)) {
+ return value[0];
+ }
+ return Dict.merge({
+ xref: this.xref,
+ dictArray: value
+ });
+ }
+ get content() {
+ return this.pageDict.getArray("Contents");
+ }
+ get resources() {
+ const resources = this._getInheritableProperty("Resources");
+ return shadow(this, "resources", resources instanceof Dict ? resources : Dict.empty);
+ }
+ _getBoundingBox(name) {
+ if (this.xfaData) {
+ return this.xfaData.bbox;
+ }
+ let box = this._getInheritableProperty(name, true);
+ if (Array.isArray(box) && box.length === 4) {
+ box = Util.normalizeRect(box);
+ if (box[2] - box[0] > 0 && box[3] - box[1] > 0) {
+ return box;
+ }
+ warn(`Empty, or invalid, /${name} entry.`);
+ }
+ return null;
+ }
+ get mediaBox() {
+ return shadow(this, "mediaBox", this._getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX);
+ }
+ get cropBox() {
+ return shadow(this, "cropBox", this._getBoundingBox("CropBox") || this.mediaBox);
+ }
+ get userUnit() {
+ let obj = this.pageDict.get("UserUnit");
+ if (typeof obj !== "number" || obj <= 0) {
+ obj = DEFAULT_USER_UNIT;
+ }
+ return shadow(this, "userUnit", obj);
+ }
+ get view() {
+ const {
+ cropBox,
+ mediaBox
+ } = this;
+ if (cropBox !== mediaBox && !isArrayEqual(cropBox, mediaBox)) {
+ const box = Util.intersect(cropBox, mediaBox);
+ if (box && box[2] - box[0] > 0 && box[3] - box[1] > 0) {
+ return shadow(this, "view", box);
+ }
+ warn("Empty /CropBox and /MediaBox intersection.");
+ }
+ return shadow(this, "view", mediaBox);
+ }
+ get rotate() {
+ let rotate = this._getInheritableProperty("Rotate") || 0;
+ if (rotate % 90 !== 0) {
+ rotate = 0;
+ } else if (rotate >= 360) {
+ rotate %= 360;
+ } else if (rotate < 0) {
+ rotate = (rotate % 360 + 360) % 360;
+ }
+ return shadow(this, "rotate", rotate);
+ }
+ _onSubStreamError(reason, objId) {
+ if (this.evaluatorOptions.ignoreErrors) {
+ warn(`getContentStream - ignoring sub-stream (${objId}): "${reason}".`);
+ return;
+ }
+ throw reason;
+ }
+ getContentStream() {
+ return this.pdfManager.ensure(this, "content").then(content => {
+ if (content instanceof BaseStream) {
+ return content;
+ }
+ if (Array.isArray(content)) {
+ return new StreamsSequenceStream(content, this._onSubStreamError.bind(this));
+ }
+ return new NullStream();
+ });
+ }
+ get xfaData() {
+ return shadow(this, "xfaData", this.xfaFactory ? {
+ bbox: this.xfaFactory.getBoundingBox(this.pageIndex)
+ } : null);
+ }
+ #replaceIdByRef(annotations, deletedAnnotations, existingAnnotations) {
+ for (const annotation of annotations) {
+ if (annotation.id) {
+ const ref = Ref.fromString(annotation.id);
+ if (!ref) {
+ warn(`A non-linked annotation cannot be modified: ${annotation.id}`);
+ continue;
+ }
+ if (annotation.deleted) {
+ deletedAnnotations.put(ref);
+ continue;
+ }
+ existingAnnotations?.put(ref);
+ annotation.ref = ref;
+ delete annotation.id;
+ }
+ }
+ }
+ async saveNewAnnotations(handler, task, annotations, imagePromises) {
+ if (this.xfaFactory) {
+ throw new Error("XFA: Cannot save new annotations.");
+ }
+ const partialEvaluator = new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: this.pageIndex,
+ idFactory: this._localIdFactory,
+ fontCache: this.fontCache,
+ builtInCMapCache: this.builtInCMapCache,
+ standardFontDataCache: this.standardFontDataCache,
+ globalImageCache: this.globalImageCache,
+ systemFontCache: this.systemFontCache,
+ options: this.evaluatorOptions
+ });
+ const deletedAnnotations = new RefSet();
+ const existingAnnotations = new RefSet();
+ this.#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations);
+ const pageDict = this.pageDict;
+ const annotationsArray = this.annotations.filter(a => !(a instanceof Ref && deletedAnnotations.has(a)));
+ const newData = await AnnotationFactory.saveNewAnnotations(partialEvaluator, task, annotations, imagePromises);
+ for (const {
+ ref
+ } of newData.annotations) {
+ if (ref instanceof Ref && !existingAnnotations.has(ref)) {
+ annotationsArray.push(ref);
+ }
+ }
+ const savedDict = pageDict.get("Annots");
+ pageDict.set("Annots", annotationsArray);
+ const buffer = [];
+ await writeObject(this.ref, pageDict, buffer, this.xref);
+ if (savedDict) {
+ pageDict.set("Annots", savedDict);
+ }
+ const objects = newData.dependencies;
+ objects.push({
+ ref: this.ref,
+ data: buffer.join("")
+ }, ...newData.annotations);
+ return objects;
+ }
+ save(handler, task, annotationStorage) {
+ const partialEvaluator = new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: this.pageIndex,
+ idFactory: this._localIdFactory,
+ fontCache: this.fontCache,
+ builtInCMapCache: this.builtInCMapCache,
+ standardFontDataCache: this.standardFontDataCache,
+ globalImageCache: this.globalImageCache,
+ systemFontCache: this.systemFontCache,
+ options: this.evaluatorOptions
+ });
+ return this._parsedAnnotations.then(function (annotations) {
+ const newRefsPromises = [];
+ for (const annotation of annotations) {
+ if (!annotation.mustBePrinted(annotationStorage)) {
+ continue;
+ }
+ newRefsPromises.push(annotation.save(partialEvaluator, task, annotationStorage).catch(function (reason) {
+ warn("save - ignoring annotation data during " + `"${task.name}" task: "${reason}".`);
+ return null;
+ }));
+ }
+ return Promise.all(newRefsPromises).then(function (newRefs) {
+ return newRefs.filter(newRef => !!newRef);
+ });
+ });
+ }
+ loadResources(keys) {
+ if (!this.resourcesPromise) {
+ this.resourcesPromise = this.pdfManager.ensure(this, "resources");
+ }
+ return this.resourcesPromise.then(() => {
+ const objectLoader = new ObjectLoader(this.resources, keys, this.xref);
+ return objectLoader.load();
+ });
+ }
+ getOperatorList({
+ handler,
+ sink,
+ task,
+ intent,
+ cacheKey,
+ annotationStorage = null
+ }) {
+ const contentStreamPromise = this.getContentStream();
+ const resourcesPromise = this.loadResources(["ColorSpace", "ExtGState", "Font", "Pattern", "Properties", "Shading", "XObject"]);
+ const partialEvaluator = new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: this.pageIndex,
+ idFactory: this._localIdFactory,
+ fontCache: this.fontCache,
+ builtInCMapCache: this.builtInCMapCache,
+ standardFontDataCache: this.standardFontDataCache,
+ globalImageCache: this.globalImageCache,
+ systemFontCache: this.systemFontCache,
+ options: this.evaluatorOptions
+ });
+ const newAnnotationsByPage = !this.xfaFactory ? getNewAnnotationsMap(annotationStorage) : null;
+ let deletedAnnotations = null;
+ let newAnnotationsPromise = Promise.resolve(null);
+ if (newAnnotationsByPage) {
+ const newAnnotations = newAnnotationsByPage.get(this.pageIndex);
+ if (newAnnotations) {
+ const annotationGlobalsPromise = this.pdfManager.ensureDoc("annotationGlobals");
+ let imagePromises;
+ const missingBitmaps = new Set();
+ for (const {
+ bitmapId,
+ bitmap
+ } of newAnnotations) {
+ if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) {
+ missingBitmaps.add(bitmapId);
+ }
+ }
+ const {
+ isOffscreenCanvasSupported
+ } = this.evaluatorOptions;
+ if (missingBitmaps.size > 0) {
+ const annotationWithBitmaps = newAnnotations.slice();
+ for (const [key, annotation] of annotationStorage) {
+ if (!key.startsWith(AnnotationEditorPrefix)) {
+ continue;
+ }
+ if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) {
+ annotationWithBitmaps.push(annotation);
+ }
+ }
+ imagePromises = AnnotationFactory.generateImages(annotationWithBitmaps, this.xref, isOffscreenCanvasSupported);
+ } else {
+ imagePromises = AnnotationFactory.generateImages(newAnnotations, this.xref, isOffscreenCanvasSupported);
+ }
+ deletedAnnotations = new RefSet();
+ this.#replaceIdByRef(newAnnotations, deletedAnnotations, null);
+ newAnnotationsPromise = annotationGlobalsPromise.then(annotationGlobals => {
+ if (!annotationGlobals) {
+ return null;
+ }
+ return AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnotations, imagePromises);
+ });
+ }
+ }
+ const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
+ const pageListPromise = dataPromises.then(([contentStream]) => {
+ const opList = new OperatorList(intent, sink);
+ handler.send("StartRenderPage", {
+ transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet),
+ pageIndex: this.pageIndex,
+ cacheKey
+ });
+ return partialEvaluator.getOperatorList({
+ stream: contentStream,
+ task,
+ resources: this.resources,
+ operatorList: opList
+ }).then(function () {
+ return opList;
+ });
+ });
+ return Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]).then(function ([pageOpList, annotations, newAnnotations]) {
+ if (newAnnotations) {
+ annotations = annotations.filter(a => !(a.ref && deletedAnnotations.has(a.ref)));
+ for (let i = 0, ii = newAnnotations.length; i < ii; i++) {
+ const newAnnotation = newAnnotations[i];
+ if (newAnnotation.refToReplace) {
+ const j = annotations.findIndex(a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace));
+ if (j >= 0) {
+ annotations.splice(j, 1, newAnnotation);
+ newAnnotations.splice(i--, 1);
+ ii--;
+ }
+ }
+ }
+ annotations = annotations.concat(newAnnotations);
+ }
+ if (annotations.length === 0 || intent & RenderingIntentFlag.ANNOTATIONS_DISABLE) {
+ pageOpList.flush(true);
+ return {
+ length: pageOpList.totalLength
+ };
+ }
+ const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
+ intentAny = !!(intent & RenderingIntentFlag.ANY),
+ intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
+ intentPrint = !!(intent & RenderingIntentFlag.PRINT);
+ const opListPromises = [];
+ for (const annotation of annotations) {
+ if (intentAny || intentDisplay && annotation.mustBeViewed(annotationStorage, renderForms) || intentPrint && annotation.mustBePrinted(annotationStorage)) {
+ opListPromises.push(annotation.getOperatorList(partialEvaluator, task, intent, renderForms, annotationStorage).catch(function (reason) {
+ warn("getOperatorList - ignoring annotation data during " + `"${task.name}" task: "${reason}".`);
+ return {
+ opList: null,
+ separateForm: false,
+ separateCanvas: false
+ };
+ }));
+ }
+ }
+ return Promise.all(opListPromises).then(function (opLists) {
+ let form = false,
+ canvas = false;
+ for (const {
+ opList,
+ separateForm,
+ separateCanvas
+ } of opLists) {
+ pageOpList.addOpList(opList);
+ form ||= separateForm;
+ canvas ||= separateCanvas;
+ }
+ pageOpList.flush(true, {
+ form,
+ canvas
+ });
+ return {
+ length: pageOpList.totalLength
+ };
+ });
+ });
+ }
+ extractTextContent({
+ handler,
+ task,
+ includeMarkedContent,
+ disableNormalization,
+ sink
+ }) {
+ const contentStreamPromise = this.getContentStream();
+ const resourcesPromise = this.loadResources(["ExtGState", "Font", "Properties", "XObject"]);
+ const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
+ return dataPromises.then(([contentStream]) => {
+ const partialEvaluator = new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: this.pageIndex,
+ idFactory: this._localIdFactory,
+ fontCache: this.fontCache,
+ builtInCMapCache: this.builtInCMapCache,
+ standardFontDataCache: this.standardFontDataCache,
+ globalImageCache: this.globalImageCache,
+ systemFontCache: this.systemFontCache,
+ options: this.evaluatorOptions
+ });
+ return partialEvaluator.getTextContent({
+ stream: contentStream,
+ task,
+ resources: this.resources,
+ includeMarkedContent,
+ disableNormalization,
+ sink,
+ viewBox: this.view
+ });
+ });
+ }
+ async getStructTree() {
+ const structTreeRoot = await this.pdfManager.ensureCatalog("structTreeRoot");
+ if (!structTreeRoot) {
+ return null;
+ }
+ await this._parsedAnnotations;
+ const structTree = await this.pdfManager.ensure(this, "_parseStructTree", [structTreeRoot]);
+ return structTree.serializable;
+ }
+ _parseStructTree(structTreeRoot) {
+ const tree = new StructTreePage(structTreeRoot, this.pageDict);
+ tree.parse(this.ref);
+ return tree;
+ }
+ async getAnnotationsData(handler, task, intent) {
+ const annotations = await this._parsedAnnotations;
+ if (annotations.length === 0) {
+ return annotations;
+ }
+ const annotationsData = [],
+ textContentPromises = [];
+ let partialEvaluator;
+ const intentAny = !!(intent & RenderingIntentFlag.ANY),
+ intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
+ intentPrint = !!(intent & RenderingIntentFlag.PRINT);
+ for (const annotation of annotations) {
+ const isVisible = intentAny || intentDisplay && annotation.viewable;
+ if (isVisible || intentPrint && annotation.printable) {
+ annotationsData.push(annotation.data);
+ }
+ if (annotation.hasTextContent && isVisible) {
+ partialEvaluator ||= new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: this.pageIndex,
+ idFactory: this._localIdFactory,
+ fontCache: this.fontCache,
+ builtInCMapCache: this.builtInCMapCache,
+ standardFontDataCache: this.standardFontDataCache,
+ globalImageCache: this.globalImageCache,
+ systemFontCache: this.systemFontCache,
+ options: this.evaluatorOptions
+ });
+ textContentPromises.push(annotation.extractTextContent(partialEvaluator, task, [-Infinity, -Infinity, Infinity, Infinity]).catch(function (reason) {
+ warn(`getAnnotationsData - ignoring textContent during "${task.name}" task: "${reason}".`);
+ }));
+ }
+ }
+ await Promise.all(textContentPromises);
+ return annotationsData;
+ }
+ get annotations() {
+ const annots = this._getInheritableProperty("Annots");
+ return shadow(this, "annotations", Array.isArray(annots) ? annots : []);
+ }
+ get _parsedAnnotations() {
+ const promise = this.pdfManager.ensure(this, "annotations").then(async annots => {
+ if (annots.length === 0) {
+ return annots;
+ }
+ const annotationGlobals = await this.pdfManager.ensureDoc("annotationGlobals");
+ if (!annotationGlobals) {
+ return [];
+ }
+ const annotationPromises = [];
+ for (const annotationRef of annots) {
+ annotationPromises.push(AnnotationFactory.create(this.xref, annotationRef, annotationGlobals, this._localIdFactory, false, this.ref).catch(function (reason) {
+ warn(`_parsedAnnotations: "${reason}".`);
+ return null;
+ }));
+ }
+ const sortedAnnotations = [];
+ let popupAnnotations;
+ for (const annotation of await Promise.all(annotationPromises)) {
+ if (!annotation) {
+ continue;
+ }
+ if (annotation instanceof PopupAnnotation) {
+ (popupAnnotations ||= []).push(annotation);
+ continue;
+ }
+ sortedAnnotations.push(annotation);
+ }
+ if (popupAnnotations) {
+ sortedAnnotations.push(...popupAnnotations);
+ }
+ return sortedAnnotations;
+ });
+ return shadow(this, "_parsedAnnotations", promise);
+ }
+ get jsActions() {
+ const actions = collectActions(this.xref, this.pageDict, PageActionEventType);
+ return shadow(this, "jsActions", actions);
+ }
+}
+const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
+const STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
+const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
+const FINGERPRINT_FIRST_BYTES = 1024;
+const EMPTY_FINGERPRINT = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+function find(stream, signature, limit = 1024, backwards = false) {
+ const signatureLength = signature.length;
+ const scanBytes = stream.peekBytes(limit);
+ const scanLength = scanBytes.length - signatureLength;
+ if (scanLength <= 0) {
+ return false;
+ }
+ if (backwards) {
+ const signatureEnd = signatureLength - 1;
+ let pos = scanBytes.length - 1;
+ while (pos >= signatureEnd) {
+ let j = 0;
+ while (j < signatureLength && scanBytes[pos - j] === signature[signatureEnd - j]) {
+ j++;
+ }
+ if (j >= signatureLength) {
+ stream.pos += pos - signatureEnd;
+ return true;
+ }
+ pos--;
+ }
+ } else {
+ let pos = 0;
+ while (pos <= scanLength) {
+ let j = 0;
+ while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
+ j++;
+ }
+ if (j >= signatureLength) {
+ stream.pos += pos;
+ return true;
+ }
+ pos++;
+ }
+ }
+ return false;
+}
+class PDFDocument {
+ constructor(pdfManager, stream) {
+ if (stream.length <= 0) {
+ throw new InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");
+ }
+ this.pdfManager = pdfManager;
+ this.stream = stream;
+ this.xref = new XRef(stream, pdfManager);
+ this._pagePromises = new Map();
+ this._version = null;
+ const idCounters = {
+ font: 0
+ };
+ this._globalIdFactory = class {
+ static getDocId() {
+ return `g_${pdfManager.docId}`;
+ }
+ static createFontId() {
+ return `f${++idCounters.font}`;
+ }
+ static createObjId() {
+ unreachable("Abstract method `createObjId` called.");
+ }
+ static getPageObjId() {
+ unreachable("Abstract method `getPageObjId` called.");
+ }
+ };
+ }
+ parse(recoveryMode) {
+ this.xref.parse(recoveryMode);
+ this.catalog = new Catalog(this.pdfManager, this.xref);
+ }
+ get linearization() {
+ let linearization = null;
+ try {
+ linearization = Linearization.create(this.stream);
+ } catch (err) {
+ if (err instanceof MissingDataException) {
+ throw err;
+ }
+ info(err);
+ }
+ return shadow(this, "linearization", linearization);
+ }
+ get startXRef() {
+ const stream = this.stream;
+ let startXRef = 0;
+ if (this.linearization) {
+ stream.reset();
+ if (find(stream, ENDOBJ_SIGNATURE)) {
+ startXRef = stream.pos + 6 - stream.start;
+ }
+ } else {
+ const step = 1024;
+ const startXRefLength = STARTXREF_SIGNATURE.length;
+ let found = false,
+ pos = stream.end;
+ while (!found && pos > 0) {
+ pos -= step - startXRefLength;
+ if (pos < 0) {
+ pos = 0;
+ }
+ stream.pos = pos;
+ found = find(stream, STARTXREF_SIGNATURE, step, true);
+ }
+ if (found) {
+ stream.skip(9);
+ let ch;
+ do {
+ ch = stream.getByte();
+ } while (isWhiteSpace(ch));
+ let str = "";
+ while (ch >= 0x20 && ch <= 0x39) {
+ str += String.fromCharCode(ch);
+ ch = stream.getByte();
+ }
+ startXRef = parseInt(str, 10);
+ if (isNaN(startXRef)) {
+ startXRef = 0;
+ }
+ }
+ }
+ return shadow(this, "startXRef", startXRef);
+ }
+ checkHeader() {
+ const stream = this.stream;
+ stream.reset();
+ if (!find(stream, PDF_HEADER_SIGNATURE)) {
+ return;
+ }
+ stream.moveStart();
+ stream.skip(PDF_HEADER_SIGNATURE.length);
+ let version = "",
+ ch;
+ while ((ch = stream.getByte()) > 0x20 && version.length < 7) {
+ version += String.fromCharCode(ch);
+ }
+ if (PDF_VERSION_REGEXP.test(version)) {
+ this._version = version;
+ } else {
+ warn(`Invalid PDF header version: ${version}`);
+ }
+ }
+ parseStartXRef() {
+ this.xref.setStartXRef(this.startXRef);
+ }
+ get numPages() {
+ let num = 0;
+ if (this.catalog.hasActualNumPages) {
+ num = this.catalog.numPages;
+ } else if (this.xfaFactory) {
+ num = this.xfaFactory.getNumPages();
+ } else if (this.linearization) {
+ num = this.linearization.numPages;
+ } else {
+ num = this.catalog.numPages;
+ }
+ return shadow(this, "numPages", num);
+ }
+ _hasOnlyDocumentSignatures(fields, recursionDepth = 0) {
+ const RECURSION_LIMIT = 10;
+ if (!Array.isArray(fields)) {
+ return false;
+ }
+ return fields.every(field => {
+ field = this.xref.fetchIfRef(field);
+ if (!(field instanceof Dict)) {
+ return false;
+ }
+ if (field.has("Kids")) {
+ if (++recursionDepth > RECURSION_LIMIT) {
+ warn("_hasOnlyDocumentSignatures: maximum recursion depth reached");
+ return false;
+ }
+ return this._hasOnlyDocumentSignatures(field.get("Kids"), recursionDepth);
+ }
+ const isSignature = isName(field.get("FT"), "Sig");
+ const rectangle = field.get("Rect");
+ const isInvisible = Array.isArray(rectangle) && rectangle.every(value => value === 0);
+ return isSignature && isInvisible;
+ });
+ }
+ get _xfaStreams() {
+ const acroForm = this.catalog.acroForm;
+ if (!acroForm) {
+ return null;
+ }
+ const xfa = acroForm.get("XFA");
+ const entries = {
+ "xdp:xdp": "",
+ template: "",
+ datasets: "",
+ config: "",
+ connectionSet: "",
+ localeSet: "",
+ stylesheet: "",
+ "/xdp:xdp": ""
+ };
+ if (xfa instanceof BaseStream && !xfa.isEmpty) {
+ entries["xdp:xdp"] = xfa;
+ return entries;
+ }
+ if (!Array.isArray(xfa) || xfa.length === 0) {
+ return null;
+ }
+ for (let i = 0, ii = xfa.length; i < ii; i += 2) {
+ let name;
+ if (i === 0) {
+ name = "xdp:xdp";
+ } else if (i === ii - 2) {
+ name = "/xdp:xdp";
+ } else {
+ name = xfa[i];
+ }
+ if (!entries.hasOwnProperty(name)) {
+ continue;
+ }
+ const data = this.xref.fetchIfRef(xfa[i + 1]);
+ if (!(data instanceof BaseStream) || data.isEmpty) {
+ continue;
+ }
+ entries[name] = data;
+ }
+ return entries;
+ }
+ get xfaDatasets() {
+ const streams = this._xfaStreams;
+ if (!streams) {
+ return shadow(this, "xfaDatasets", null);
+ }
+ for (const key of ["datasets", "xdp:xdp"]) {
+ const stream = streams[key];
+ if (!stream) {
+ continue;
+ }
+ try {
+ const str = stringToUTF8String(stream.getString());
+ const data = {
+ [key]: str
+ };
+ return shadow(this, "xfaDatasets", new DatasetReader(data));
+ } catch {
+ warn("XFA - Invalid utf-8 string.");
+ break;
+ }
+ }
+ return shadow(this, "xfaDatasets", null);
+ }
+ get xfaData() {
+ const streams = this._xfaStreams;
+ if (!streams) {
+ return null;
+ }
+ const data = Object.create(null);
+ for (const [key, stream] of Object.entries(streams)) {
+ if (!stream) {
+ continue;
+ }
+ try {
+ data[key] = stringToUTF8String(stream.getString());
+ } catch {
+ warn("XFA - Invalid utf-8 string.");
+ return null;
+ }
+ }
+ return data;
+ }
+ get xfaFactory() {
+ let data;
+ if (this.pdfManager.enableXfa && this.catalog.needsRendering && this.formInfo.hasXfa && !this.formInfo.hasAcroForm) {
+ data = this.xfaData;
+ }
+ return shadow(this, "xfaFactory", data ? new XFAFactory(data) : null);
+ }
+ get isPureXfa() {
+ return this.xfaFactory ? this.xfaFactory.isValid() : false;
+ }
+ get htmlForXfa() {
+ return this.xfaFactory ? this.xfaFactory.getPages() : null;
+ }
+ async loadXfaImages() {
+ const xfaImagesDict = await this.pdfManager.ensureCatalog("xfaImages");
+ if (!xfaImagesDict) {
+ return;
+ }
+ const keys = xfaImagesDict.getKeys();
+ const objectLoader = new ObjectLoader(xfaImagesDict, keys, this.xref);
+ await objectLoader.load();
+ const xfaImages = new Map();
+ for (const key of keys) {
+ const stream = xfaImagesDict.get(key);
+ if (stream instanceof BaseStream) {
+ xfaImages.set(key, stream.getBytes());
+ }
+ }
+ this.xfaFactory.setImages(xfaImages);
+ }
+ async loadXfaFonts(handler, task) {
+ const acroForm = await this.pdfManager.ensureCatalog("acroForm");
+ if (!acroForm) {
+ return;
+ }
+ const resources = await acroForm.getAsync("DR");
+ if (!(resources instanceof Dict)) {
+ return;
+ }
+ const objectLoader = new ObjectLoader(resources, ["Font"], this.xref);
+ await objectLoader.load();
+ const fontRes = resources.get("Font");
+ if (!(fontRes instanceof Dict)) {
+ return;
+ }
+ const options = Object.assign(Object.create(null), this.pdfManager.evaluatorOptions);
+ options.useSystemFonts = false;
+ const partialEvaluator = new PartialEvaluator({
+ xref: this.xref,
+ handler,
+ pageIndex: -1,
+ idFactory: this._globalIdFactory,
+ fontCache: this.catalog.fontCache,
+ builtInCMapCache: this.catalog.builtInCMapCache,
+ standardFontDataCache: this.catalog.standardFontDataCache,
+ options
+ });
+ const operatorList = new OperatorList();
+ const pdfFonts = [];
+ const initialState = {
+ get font() {
+ return pdfFonts.at(-1);
+ },
+ set font(font) {
+ pdfFonts.push(font);
+ },
+ clone() {
+ return this;
+ }
+ };
+ const fonts = new Map();
+ fontRes.forEach((fontName, font) => {
+ fonts.set(fontName, font);
+ });
+ const promises = [];
+ for (const [fontName, font] of fonts) {
+ const descriptor = font.get("FontDescriptor");
+ if (!(descriptor instanceof Dict)) {
+ continue;
+ }
+ let fontFamily = descriptor.get("FontFamily");
+ fontFamily = fontFamily.replaceAll(/[ ]+(\d)/g, "$1");
+ const fontWeight = descriptor.get("FontWeight");
+ const italicAngle = -descriptor.get("ItalicAngle");
+ const cssFontInfo = {
+ fontFamily,
+ fontWeight,
+ italicAngle
+ };
+ if (!validateCSSFont(cssFontInfo)) {
+ continue;
+ }
+ promises.push(partialEvaluator.handleSetFont(resources, [Name.get(fontName), 1], null, operatorList, task, initialState, null, cssFontInfo).catch(function (reason) {
+ warn(`loadXfaFonts: "${reason}".`);
+ return null;
+ }));
+ }
+ await Promise.all(promises);
+ const missingFonts = this.xfaFactory.setFonts(pdfFonts);
+ if (!missingFonts) {
+ return;
+ }
+ options.ignoreErrors = true;
+ promises.length = 0;
+ pdfFonts.length = 0;
+ const reallyMissingFonts = new Set();
+ for (const missing of missingFonts) {
+ if (!getXfaFontName(`${missing}-Regular`)) {
+ reallyMissingFonts.add(missing);
+ }
+ }
+ if (reallyMissingFonts.size) {
+ missingFonts.push("PdfJS-Fallback");
+ }
+ for (const missing of missingFonts) {
+ if (reallyMissingFonts.has(missing)) {
+ continue;
+ }
+ for (const fontInfo of [{
+ name: "Regular",
+ fontWeight: 400,
+ italicAngle: 0
+ }, {
+ name: "Bold",
+ fontWeight: 700,
+ italicAngle: 0
+ }, {
+ name: "Italic",
+ fontWeight: 400,
+ italicAngle: 12
+ }, {
+ name: "BoldItalic",
+ fontWeight: 700,
+ italicAngle: 12
+ }]) {
+ const name = `${missing}-${fontInfo.name}`;
+ const dict = getXfaFontDict(name);
+ promises.push(partialEvaluator.handleSetFont(resources, [Name.get(name), 1], null, operatorList, task, initialState, dict, {
+ fontFamily: missing,
+ fontWeight: fontInfo.fontWeight,
+ italicAngle: fontInfo.italicAngle
+ }).catch(function (reason) {
+ warn(`loadXfaFonts: "${reason}".`);
+ return null;
+ }));
+ }
+ }
+ await Promise.all(promises);
+ this.xfaFactory.appendFonts(pdfFonts, reallyMissingFonts);
+ }
+ async serializeXfaData(annotationStorage) {
+ return this.xfaFactory ? this.xfaFactory.serializeData(annotationStorage) : null;
+ }
+ get version() {
+ return this.catalog.version || this._version;
+ }
+ get formInfo() {
+ const formInfo = {
+ hasFields: false,
+ hasAcroForm: false,
+ hasXfa: false,
+ hasSignatures: false
+ };
+ const acroForm = this.catalog.acroForm;
+ if (!acroForm) {
+ return shadow(this, "formInfo", formInfo);
+ }
+ try {
+ const fields = acroForm.get("Fields");
+ const hasFields = Array.isArray(fields) && fields.length > 0;
+ formInfo.hasFields = hasFields;
+ const xfa = acroForm.get("XFA");
+ formInfo.hasXfa = Array.isArray(xfa) && xfa.length > 0 || xfa instanceof BaseStream && !xfa.isEmpty;
+ const sigFlags = acroForm.get("SigFlags");
+ const hasSignatures = !!(sigFlags & 0x1);
+ const hasOnlyDocumentSignatures = hasSignatures && this._hasOnlyDocumentSignatures(fields);
+ formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures;
+ formInfo.hasSignatures = hasSignatures;
+ } catch (ex) {
+ if (ex instanceof MissingDataException) {
+ throw ex;
+ }
+ warn(`Cannot fetch form information: "${ex}".`);
+ }
+ return shadow(this, "formInfo", formInfo);
+ }
+ get documentInfo() {
+ const docInfo = {
+ PDFFormatVersion: this.version,
+ Language: this.catalog.lang,
+ EncryptFilterName: this.xref.encrypt ? this.xref.encrypt.filterName : null,
+ IsLinearized: !!this.linearization,
+ IsAcroFormPresent: this.formInfo.hasAcroForm,
+ IsXFAPresent: this.formInfo.hasXfa,
+ IsCollectionPresent: !!this.catalog.collection,
+ IsSignaturesPresent: this.formInfo.hasSignatures
+ };
+ let infoDict;
+ try {
+ infoDict = this.xref.trailer.get("Info");
+ } catch (err) {
+ if (err instanceof MissingDataException) {
+ throw err;
+ }
+ info("The document information dictionary is invalid.");
+ }
+ if (!(infoDict instanceof Dict)) {
+ return shadow(this, "documentInfo", docInfo);
+ }
+ for (const key of infoDict.getKeys()) {
+ const value = infoDict.get(key);
+ switch (key) {
+ case "Title":
+ case "Author":
+ case "Subject":
+ case "Keywords":
+ case "Creator":
+ case "Producer":
+ case "CreationDate":
+ case "ModDate":
+ if (typeof value === "string") {
+ docInfo[key] = stringToPDFString(value);
+ continue;
+ }
+ break;
+ case "Trapped":
+ if (value instanceof Name) {
+ docInfo[key] = value;
+ continue;
+ }
+ break;
+ default:
+ let customValue;
+ switch (typeof value) {
+ case "string":
+ customValue = stringToPDFString(value);
+ break;
+ case "number":
+ case "boolean":
+ customValue = value;
+ break;
+ default:
+ if (value instanceof Name) {
+ customValue = value;
+ }
+ break;
+ }
+ if (customValue === undefined) {
+ warn(`Bad value, for custom key "${key}", in Info: ${value}.`);
+ continue;
+ }
+ if (!docInfo.Custom) {
+ docInfo.Custom = Object.create(null);
+ }
+ docInfo.Custom[key] = customValue;
+ continue;
+ }
+ warn(`Bad value, for key "${key}", in Info: ${value}.`);
+ }
+ return shadow(this, "documentInfo", docInfo);
+ }
+ get fingerprints() {
+ function validate(data) {
+ return typeof data === "string" && data.length > 0 && data !== EMPTY_FINGERPRINT;
+ }
+ function hexString(hash) {
+ const buf = [];
+ for (const num of hash) {
+ const hex = num.toString(16);
+ buf.push(hex.padStart(2, "0"));
+ }
+ return buf.join("");
+ }
+ const idArray = this.xref.trailer.get("ID");
+ let hashOriginal, hashModified;
+ if (Array.isArray(idArray) && validate(idArray[0])) {
+ hashOriginal = stringToBytes(idArray[0]);
+ if (idArray[1] !== idArray[0] && validate(idArray[1])) {
+ hashModified = stringToBytes(idArray[1]);
+ }
+ } else {
+ hashOriginal = calculateMD5(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
+ }
+ return shadow(this, "fingerprints", [hexString(hashOriginal), hashModified ? hexString(hashModified) : null]);
+ }
+ async _getLinearizationPage(pageIndex) {
+ const {
+ catalog,
+ linearization,
+ xref
+ } = this;
+ const ref = Ref.get(linearization.objectNumberFirst, 0);
+ try {
+ const obj = await xref.fetchAsync(ref);
+ if (obj instanceof Dict) {
+ let type = obj.getRaw("Type");
+ if (type instanceof Ref) {
+ type = await xref.fetchAsync(type);
+ }
+ if (isName(type, "Page") || !obj.has("Type") && !obj.has("Kids")) {
+ if (!catalog.pageKidsCountCache.has(ref)) {
+ catalog.pageKidsCountCache.put(ref, 1);
+ }
+ if (!catalog.pageIndexCache.has(ref)) {
+ catalog.pageIndexCache.put(ref, 0);
+ }
+ return [obj, ref];
+ }
+ }
+ throw new FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.");
+ } catch (reason) {
+ warn(`_getLinearizationPage: "${reason.message}".`);
+ return catalog.getPageDict(pageIndex);
+ }
+ }
+ getPage(pageIndex) {
+ const cachedPromise = this._pagePromises.get(pageIndex);
+ if (cachedPromise) {
+ return cachedPromise;
+ }
+ const {
+ catalog,
+ linearization,
+ xfaFactory
+ } = this;
+ let promise;
+ if (xfaFactory) {
+ promise = Promise.resolve([Dict.empty, null]);
+ } else if (linearization?.pageFirst === pageIndex) {
+ promise = this._getLinearizationPage(pageIndex);
+ } else {
+ promise = catalog.getPageDict(pageIndex);
+ }
+ promise = promise.then(([pageDict, ref]) => {
+ return new Page({
+ pdfManager: this.pdfManager,
+ xref: this.xref,
+ pageIndex,
+ pageDict,
+ ref,
+ globalIdFactory: this._globalIdFactory,
+ fontCache: catalog.fontCache,
+ builtInCMapCache: catalog.builtInCMapCache,
+ standardFontDataCache: catalog.standardFontDataCache,
+ globalImageCache: catalog.globalImageCache,
+ systemFontCache: catalog.systemFontCache,
+ nonBlendModesSet: catalog.nonBlendModesSet,
+ xfaFactory
+ });
+ });
+ this._pagePromises.set(pageIndex, promise);
+ return promise;
+ }
+ async checkFirstPage(recoveryMode = false) {
+ if (recoveryMode) {
+ return;
+ }
+ try {
+ await this.getPage(0);
+ } catch (reason) {
+ if (reason instanceof XRefEntryException) {
+ this._pagePromises.delete(0);
+ await this.cleanup();
+ throw new XRefParseException();
+ }
+ }
+ }
+ async checkLastPage(recoveryMode = false) {
+ const {
+ catalog,
+ pdfManager
+ } = this;
+ catalog.setActualNumPages();
+ let numPages;
+ try {
+ await Promise.all([pdfManager.ensureDoc("xfaFactory"), pdfManager.ensureDoc("linearization"), pdfManager.ensureCatalog("numPages")]);
+ if (this.xfaFactory) {
+ return;
+ } else if (this.linearization) {
+ numPages = this.linearization.numPages;
+ } else {
+ numPages = catalog.numPages;
+ }
+ if (!Number.isInteger(numPages)) {
+ throw new FormatError("Page count is not an integer.");
+ } else if (numPages <= 1) {
+ return;
+ }
+ await this.getPage(numPages - 1);
+ } catch (reason) {
+ this._pagePromises.delete(numPages - 1);
+ await this.cleanup();
+ if (reason instanceof XRefEntryException && !recoveryMode) {
+ throw new XRefParseException();
+ }
+ warn(`checkLastPage - invalid /Pages tree /Count: ${numPages}.`);
+ let pagesTree;
+ try {
+ pagesTree = await catalog.getAllPageDicts(recoveryMode);
+ } catch (reasonAll) {
+ if (reasonAll instanceof XRefEntryException && !recoveryMode) {
+ throw new XRefParseException();
+ }
+ catalog.setActualNumPages(1);
+ return;
+ }
+ for (const [pageIndex, [pageDict, ref]] of pagesTree) {
+ let promise;
+ if (pageDict instanceof Error) {
+ promise = Promise.reject(pageDict);
+ promise.catch(() => {});
+ } else {
+ promise = Promise.resolve(new Page({
+ pdfManager,
+ xref: this.xref,
+ pageIndex,
+ pageDict,
+ ref,
+ globalIdFactory: this._globalIdFactory,
+ fontCache: catalog.fontCache,
+ builtInCMapCache: catalog.builtInCMapCache,
+ standardFontDataCache: catalog.standardFontDataCache,
+ globalImageCache: catalog.globalImageCache,
+ systemFontCache: catalog.systemFontCache,
+ nonBlendModesSet: catalog.nonBlendModesSet,
+ xfaFactory: null
+ }));
+ }
+ this._pagePromises.set(pageIndex, promise);
+ }
+ catalog.setActualNumPages(pagesTree.size);
+ }
+ }
+ fontFallback(id, handler) {
+ return this.catalog.fontFallback(id, handler);
+ }
+ async cleanup(manuallyTriggered = false) {
+ return this.catalog ? this.catalog.cleanup(manuallyTriggered) : clearGlobalCaches();
+ }
+ async #collectFieldObjects(name, fieldRef, promises, annotationGlobals, visitedRefs) {
+ const {
+ xref
+ } = this;
+ if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {
+ return;
+ }
+ visitedRefs.put(fieldRef);
+ const field = await xref.fetchAsync(fieldRef);
+ if (!(field instanceof Dict)) {
+ return;
+ }
+ if (field.has("T")) {
+ const partName = stringToPDFString(await field.getAsync("T"));
+ name = name === "" ? partName : `${name}.${partName}`;
+ } else {
+ let obj = field;
+ while (true) {
+ obj = obj.getRaw("Parent");
+ if (obj instanceof Ref) {
+ if (visitedRefs.has(obj)) {
+ break;
+ }
+ obj = await xref.fetchAsync(obj);
+ }
+ if (!(obj instanceof Dict)) {
+ break;
+ }
+ if (obj.has("T")) {
+ const partName = stringToPDFString(await obj.getAsync("T"));
+ name = name === "" ? partName : `${name}.${partName}`;
+ break;
+ }
+ }
+ }
+ if (!promises.has(name)) {
+ promises.set(name, []);
+ }
+ promises.get(name).push(AnnotationFactory.create(xref, fieldRef, annotationGlobals, null, true, null).then(annotation => annotation?.getFieldObject()).catch(function (reason) {
+ warn(`#collectFieldObjects: "${reason}".`);
+ return null;
+ }));
+ if (!field.has("Kids")) {
+ return;
+ }
+ const kids = await field.getAsync("Kids");
+ if (Array.isArray(kids)) {
+ for (const kid of kids) {
+ await this.#collectFieldObjects(name, kid, promises, annotationGlobals, visitedRefs);
+ }
+ }
+ }
+ get fieldObjects() {
+ if (!this.formInfo.hasFields) {
+ return shadow(this, "fieldObjects", Promise.resolve(null));
+ }
+ const promise = Promise.all([this.pdfManager.ensureDoc("annotationGlobals"), this.pdfManager.ensureCatalog("acroForm")]).then(async ([annotationGlobals, acroForm]) => {
+ if (!annotationGlobals) {
+ return null;
+ }
+ const visitedRefs = new RefSet();
+ const allFields = Object.create(null);
+ const fieldPromises = new Map();
+ for (const fieldRef of await acroForm.getAsync("Fields")) {
+ await this.#collectFieldObjects("", fieldRef, fieldPromises, annotationGlobals, visitedRefs);
+ }
+ const allPromises = [];
+ for (const [name, promises] of fieldPromises) {
+ allPromises.push(Promise.all(promises).then(fields => {
+ fields = fields.filter(field => !!field);
+ if (fields.length > 0) {
+ allFields[name] = fields;
+ }
+ }));
+ }
+ await Promise.all(allPromises);
+ return allFields;
+ });
+ return shadow(this, "fieldObjects", promise);
+ }
+ get hasJSActions() {
+ const promise = this.pdfManager.ensureDoc("_parseHasJSActions");
+ return shadow(this, "hasJSActions", promise);
+ }
+ async _parseHasJSActions() {
+ const [catalogJsActions, fieldObjects] = await Promise.all([this.pdfManager.ensureCatalog("jsActions"), this.pdfManager.ensureDoc("fieldObjects")]);
+ if (catalogJsActions) {
+ return true;
+ }
+ if (fieldObjects) {
+ return Object.values(fieldObjects).some(fieldObject => fieldObject.some(object => object.actions !== null));
+ }
+ return false;
+ }
+ get calculationOrderIds() {
+ const acroForm = this.catalog.acroForm;
+ if (!acroForm?.has("CO")) {
+ return shadow(this, "calculationOrderIds", null);
+ }
+ const calculationOrder = acroForm.get("CO");
+ if (!Array.isArray(calculationOrder) || calculationOrder.length === 0) {
+ return shadow(this, "calculationOrderIds", null);
+ }
+ const ids = [];
+ for (const id of calculationOrder) {
+ if (id instanceof Ref) {
+ ids.push(id.toString());
+ }
+ }
+ if (ids.length === 0) {
+ return shadow(this, "calculationOrderIds", null);
+ }
+ return shadow(this, "calculationOrderIds", ids);
+ }
+ get annotationGlobals() {
+ return shadow(this, "annotationGlobals", AnnotationFactory.createGlobals(this.pdfManager));
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/pdf_manager.js
+
+
+
+
+
+function parseDocBaseUrl(url) {
+ if (url) {
+ const absoluteUrl = createValidAbsoluteUrl(url);
+ if (absoluteUrl) {
+ return absoluteUrl.href;
+ }
+ warn(`Invalid absolute docBaseUrl: "${url}".`);
+ }
+ return null;
+}
+class BasePdfManager {
+ constructor(args) {
+ if (this.constructor === BasePdfManager) {
+ unreachable("Cannot initialize BasePdfManager.");
+ }
+ this._docBaseUrl = parseDocBaseUrl(args.docBaseUrl);
+ this._docId = args.docId;
+ this._password = args.password;
+ this.enableXfa = args.enableXfa;
+ args.evaluatorOptions.isOffscreenCanvasSupported &&= FeatureTest.isOffscreenCanvasSupported;
+ this.evaluatorOptions = args.evaluatorOptions;
+ }
+ get docId() {
+ return this._docId;
+ }
+ get password() {
+ return this._password;
+ }
+ get docBaseUrl() {
+ return this._docBaseUrl;
+ }
+ get catalog() {
+ return this.pdfDocument.catalog;
+ }
+ ensureDoc(prop, args) {
+ return this.ensure(this.pdfDocument, prop, args);
+ }
+ ensureXRef(prop, args) {
+ return this.ensure(this.pdfDocument.xref, prop, args);
+ }
+ ensureCatalog(prop, args) {
+ return this.ensure(this.pdfDocument.catalog, prop, args);
+ }
+ getPage(pageIndex) {
+ return this.pdfDocument.getPage(pageIndex);
+ }
+ fontFallback(id, handler) {
+ return this.pdfDocument.fontFallback(id, handler);
+ }
+ loadXfaFonts(handler, task) {
+ return this.pdfDocument.loadXfaFonts(handler, task);
+ }
+ loadXfaImages() {
+ return this.pdfDocument.loadXfaImages();
+ }
+ serializeXfaData(annotationStorage) {
+ return this.pdfDocument.serializeXfaData(annotationStorage);
+ }
+ cleanup(manuallyTriggered = false) {
+ return this.pdfDocument.cleanup(manuallyTriggered);
+ }
+ async ensure(obj, prop, args) {
+ unreachable("Abstract method `ensure` called");
+ }
+ requestRange(begin, end) {
+ unreachable("Abstract method `requestRange` called");
+ }
+ requestLoadedStream(noFetch = false) {
+ unreachable("Abstract method `requestLoadedStream` called");
+ }
+ sendProgressiveData(chunk) {
+ unreachable("Abstract method `sendProgressiveData` called");
+ }
+ updatePassword(password) {
+ this._password = password;
+ }
+ terminate(reason) {
+ unreachable("Abstract method `terminate` called");
+ }
+}
+class LocalPdfManager extends BasePdfManager {
+ constructor(args) {
+ super(args);
+ const stream = new Stream(args.source);
+ this.pdfDocument = new PDFDocument(this, stream);
+ this._loadedStreamPromise = Promise.resolve(stream);
+ }
+ async ensure(obj, prop, args) {
+ const value = obj[prop];
+ if (typeof value === "function") {
+ return value.apply(obj, args);
+ }
+ return value;
+ }
+ requestRange(begin, end) {
+ return Promise.resolve();
+ }
+ requestLoadedStream(noFetch = false) {
+ return this._loadedStreamPromise;
+ }
+ terminate(reason) {}
+}
+class NetworkPdfManager extends BasePdfManager {
+ constructor(args) {
+ super(args);
+ this.streamManager = new ChunkedStreamManager(args.source, {
+ msgHandler: args.handler,
+ length: args.length,
+ disableAutoFetch: args.disableAutoFetch,
+ rangeChunkSize: args.rangeChunkSize
+ });
+ this.pdfDocument = new PDFDocument(this, this.streamManager.getStream());
+ }
+ async ensure(obj, prop, args) {
+ try {
+ const value = obj[prop];
+ if (typeof value === "function") {
+ return value.apply(obj, args);
+ }
+ return value;
+ } catch (ex) {
+ if (!(ex instanceof MissingDataException)) {
+ throw ex;
+ }
+ await this.requestRange(ex.begin, ex.end);
+ return this.ensure(obj, prop, args);
+ }
+ }
+ requestRange(begin, end) {
+ return this.streamManager.requestRange(begin, end);
+ }
+ requestLoadedStream(noFetch = false) {
+ return this.streamManager.requestAllChunks(noFetch);
+ }
+ sendProgressiveData(chunk) {
+ this.streamManager.onReceiveData({
+ chunk
+ });
+ }
+ terminate(reason) {
+ this.streamManager.abort(reason);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/shared/message_handler.js
+
+const CallbackKind = {
+ UNKNOWN: 0,
+ DATA: 1,
+ ERROR: 2
+};
+const StreamKind = {
+ UNKNOWN: 0,
+ CANCEL: 1,
+ CANCEL_COMPLETE: 2,
+ CLOSE: 3,
+ ENQUEUE: 4,
+ ERROR: 5,
+ PULL: 6,
+ PULL_COMPLETE: 7,
+ START_COMPLETE: 8
+};
+function wrapReason(reason) {
+ if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) {
+ unreachable('wrapReason: Expected "reason" to be a (possibly cloned) Error.');
+ }
+ switch (reason.name) {
+ case "AbortException":
+ return new AbortException(reason.message);
+ case "MissingPDFException":
+ return new MissingPDFException(reason.message);
+ case "PasswordException":
+ return new PasswordException(reason.message, reason.code);
+ case "UnexpectedResponseException":
+ return new UnexpectedResponseException(reason.message, reason.status);
+ case "UnknownErrorException":
+ return new UnknownErrorException(reason.message, reason.details);
+ default:
+ return new UnknownErrorException(reason.message, reason.toString());
+ }
+}
+class MessageHandler {
+ constructor(sourceName, targetName, comObj) {
+ this.sourceName = sourceName;
+ this.targetName = targetName;
+ this.comObj = comObj;
+ this.callbackId = 1;
+ this.streamId = 1;
+ this.streamSinks = Object.create(null);
+ this.streamControllers = Object.create(null);
+ this.callbackCapabilities = Object.create(null);
+ this.actionHandler = Object.create(null);
+ this._onComObjOnMessage = event => {
+ const data = event.data;
+ if (data.targetName !== this.sourceName) {
+ return;
+ }
+ if (data.stream) {
+ this.#processStreamMessage(data);
+ return;
+ }
+ if (data.callback) {
+ const callbackId = data.callbackId;
+ const capability = this.callbackCapabilities[callbackId];
+ if (!capability) {
+ throw new Error(`Cannot resolve callback ${callbackId}`);
+ }
+ delete this.callbackCapabilities[callbackId];
+ if (data.callback === CallbackKind.DATA) {
+ capability.resolve(data.data);
+ } else if (data.callback === CallbackKind.ERROR) {
+ capability.reject(wrapReason(data.reason));
+ } else {
+ throw new Error("Unexpected callback case");
+ }
+ return;
+ }
+ const action = this.actionHandler[data.action];
+ if (!action) {
+ throw new Error(`Unknown action from worker: ${data.action}`);
+ }
+ if (data.callbackId) {
+ const cbSourceName = this.sourceName;
+ const cbTargetName = data.sourceName;
+ new Promise(function (resolve) {
+ resolve(action(data.data));
+ }).then(function (result) {
+ comObj.postMessage({
+ sourceName: cbSourceName,
+ targetName: cbTargetName,
+ callback: CallbackKind.DATA,
+ callbackId: data.callbackId,
+ data: result
+ });
+ }, function (reason) {
+ comObj.postMessage({
+ sourceName: cbSourceName,
+ targetName: cbTargetName,
+ callback: CallbackKind.ERROR,
+ callbackId: data.callbackId,
+ reason: wrapReason(reason)
+ });
+ });
+ return;
+ }
+ if (data.streamId) {
+ this.#createStreamSink(data);
+ return;
+ }
+ action(data.data);
+ };
+ comObj.addEventListener("message", this._onComObjOnMessage);
+ }
+ on(actionName, handler) {
+ const ah = this.actionHandler;
+ if (ah[actionName]) {
+ throw new Error(`There is already an actionName called "${actionName}"`);
+ }
+ ah[actionName] = handler;
+ }
+ send(actionName, data, transfers) {
+ this.comObj.postMessage({
+ sourceName: this.sourceName,
+ targetName: this.targetName,
+ action: actionName,
+ data
+ }, transfers);
+ }
+ sendWithPromise(actionName, data, transfers) {
+ const callbackId = this.callbackId++;
+ const capability = new PromiseCapability();
+ this.callbackCapabilities[callbackId] = capability;
+ try {
+ this.comObj.postMessage({
+ sourceName: this.sourceName,
+ targetName: this.targetName,
+ action: actionName,
+ callbackId,
+ data
+ }, transfers);
+ } catch (ex) {
+ capability.reject(ex);
+ }
+ return capability.promise;
+ }
+ sendWithStream(actionName, data, queueingStrategy, transfers) {
+ const streamId = this.streamId++,
+ sourceName = this.sourceName,
+ targetName = this.targetName,
+ comObj = this.comObj;
+ return new ReadableStream({
+ start: controller => {
+ const startCapability = new PromiseCapability();
+ this.streamControllers[streamId] = {
+ controller,
+ startCall: startCapability,
+ pullCall: null,
+ cancelCall: null,
+ isClosed: false
+ };
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ action: actionName,
+ streamId,
+ data,
+ desiredSize: controller.desiredSize
+ }, transfers);
+ return startCapability.promise;
+ },
+ pull: controller => {
+ const pullCapability = new PromiseCapability();
+ this.streamControllers[streamId].pullCall = pullCapability;
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.PULL,
+ streamId,
+ desiredSize: controller.desiredSize
+ });
+ return pullCapability.promise;
+ },
+ cancel: reason => {
+ assert(reason instanceof Error, "cancel must have a valid reason");
+ const cancelCapability = new PromiseCapability();
+ this.streamControllers[streamId].cancelCall = cancelCapability;
+ this.streamControllers[streamId].isClosed = true;
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.CANCEL,
+ streamId,
+ reason: wrapReason(reason)
+ });
+ return cancelCapability.promise;
+ }
+ }, queueingStrategy);
+ }
+ #createStreamSink(data) {
+ const streamId = data.streamId,
+ sourceName = this.sourceName,
+ targetName = data.sourceName,
+ comObj = this.comObj;
+ const self = this,
+ action = this.actionHandler[data.action];
+ const streamSink = {
+ enqueue(chunk, size = 1, transfers) {
+ if (this.isCancelled) {
+ return;
+ }
+ const lastDesiredSize = this.desiredSize;
+ this.desiredSize -= size;
+ if (lastDesiredSize > 0 && this.desiredSize <= 0) {
+ this.sinkCapability = new PromiseCapability();
+ this.ready = this.sinkCapability.promise;
+ }
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.ENQUEUE,
+ streamId,
+ chunk
+ }, transfers);
+ },
+ close() {
+ if (this.isCancelled) {
+ return;
+ }
+ this.isCancelled = true;
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.CLOSE,
+ streamId
+ });
+ delete self.streamSinks[streamId];
+ },
+ error(reason) {
+ assert(reason instanceof Error, "error must have a valid reason");
+ if (this.isCancelled) {
+ return;
+ }
+ this.isCancelled = true;
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.ERROR,
+ streamId,
+ reason: wrapReason(reason)
+ });
+ },
+ sinkCapability: new PromiseCapability(),
+ onPull: null,
+ onCancel: null,
+ isCancelled: false,
+ desiredSize: data.desiredSize,
+ ready: null
+ };
+ streamSink.sinkCapability.resolve();
+ streamSink.ready = streamSink.sinkCapability.promise;
+ this.streamSinks[streamId] = streamSink;
+ new Promise(function (resolve) {
+ resolve(action(data.data, streamSink));
+ }).then(function () {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.START_COMPLETE,
+ streamId,
+ success: true
+ });
+ }, function (reason) {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.START_COMPLETE,
+ streamId,
+ reason: wrapReason(reason)
+ });
+ });
+ }
+ #processStreamMessage(data) {
+ const streamId = data.streamId,
+ sourceName = this.sourceName,
+ targetName = data.sourceName,
+ comObj = this.comObj;
+ const streamController = this.streamControllers[streamId],
+ streamSink = this.streamSinks[streamId];
+ switch (data.stream) {
+ case StreamKind.START_COMPLETE:
+ if (data.success) {
+ streamController.startCall.resolve();
+ } else {
+ streamController.startCall.reject(wrapReason(data.reason));
+ }
+ break;
+ case StreamKind.PULL_COMPLETE:
+ if (data.success) {
+ streamController.pullCall.resolve();
+ } else {
+ streamController.pullCall.reject(wrapReason(data.reason));
+ }
+ break;
+ case StreamKind.PULL:
+ if (!streamSink) {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.PULL_COMPLETE,
+ streamId,
+ success: true
+ });
+ break;
+ }
+ if (streamSink.desiredSize <= 0 && data.desiredSize > 0) {
+ streamSink.sinkCapability.resolve();
+ }
+ streamSink.desiredSize = data.desiredSize;
+ new Promise(function (resolve) {
+ resolve(streamSink.onPull?.());
+ }).then(function () {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.PULL_COMPLETE,
+ streamId,
+ success: true
+ });
+ }, function (reason) {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.PULL_COMPLETE,
+ streamId,
+ reason: wrapReason(reason)
+ });
+ });
+ break;
+ case StreamKind.ENQUEUE:
+ assert(streamController, "enqueue should have stream controller");
+ if (streamController.isClosed) {
+ break;
+ }
+ streamController.controller.enqueue(data.chunk);
+ break;
+ case StreamKind.CLOSE:
+ assert(streamController, "close should have stream controller");
+ if (streamController.isClosed) {
+ break;
+ }
+ streamController.isClosed = true;
+ streamController.controller.close();
+ this.#deleteStreamController(streamController, streamId);
+ break;
+ case StreamKind.ERROR:
+ assert(streamController, "error should have stream controller");
+ streamController.controller.error(wrapReason(data.reason));
+ this.#deleteStreamController(streamController, streamId);
+ break;
+ case StreamKind.CANCEL_COMPLETE:
+ if (data.success) {
+ streamController.cancelCall.resolve();
+ } else {
+ streamController.cancelCall.reject(wrapReason(data.reason));
+ }
+ this.#deleteStreamController(streamController, streamId);
+ break;
+ case StreamKind.CANCEL:
+ if (!streamSink) {
+ break;
+ }
+ new Promise(function (resolve) {
+ resolve(streamSink.onCancel?.(wrapReason(data.reason)));
+ }).then(function () {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.CANCEL_COMPLETE,
+ streamId,
+ success: true
+ });
+ }, function (reason) {
+ comObj.postMessage({
+ sourceName,
+ targetName,
+ stream: StreamKind.CANCEL_COMPLETE,
+ streamId,
+ reason: wrapReason(reason)
+ });
+ });
+ streamSink.sinkCapability.reject(wrapReason(data.reason));
+ streamSink.isCancelled = true;
+ delete this.streamSinks[streamId];
+ break;
+ default:
+ throw new Error("Unexpected stream case");
+ }
+ }
+ async #deleteStreamController(streamController, streamId) {
+ await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]);
+ delete this.streamControllers[streamId];
+ }
+ destroy() {
+ this.comObj.removeEventListener("message", this._onComObjOnMessage);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/worker_stream.js
+
+class PDFWorkerStream {
+ constructor(msgHandler) {
+ this._msgHandler = msgHandler;
+ this._contentLength = null;
+ this._fullRequestReader = null;
+ this._rangeRequestReaders = [];
+ }
+ getFullReader() {
+ assert(!this._fullRequestReader, "PDFWorkerStream.getFullReader can only be called once.");
+ this._fullRequestReader = new PDFWorkerStreamReader(this._msgHandler);
+ return this._fullRequestReader;
+ }
+ getRangeReader(begin, end) {
+ const reader = new PDFWorkerStreamRangeReader(begin, end, this._msgHandler);
+ this._rangeRequestReaders.push(reader);
+ return reader;
+ }
+ cancelAllRequests(reason) {
+ this._fullRequestReader?.cancel(reason);
+ for (const reader of this._rangeRequestReaders.slice(0)) {
+ reader.cancel(reason);
+ }
+ }
+}
+class PDFWorkerStreamReader {
+ constructor(msgHandler) {
+ this._msgHandler = msgHandler;
+ this.onProgress = null;
+ this._contentLength = null;
+ this._isRangeSupported = false;
+ this._isStreamingSupported = false;
+ const readableStream = this._msgHandler.sendWithStream("GetReader");
+ this._reader = readableStream.getReader();
+ this._headersReady = this._msgHandler.sendWithPromise("ReaderHeadersReady").then(data => {
+ this._isStreamingSupported = data.isStreamingSupported;
+ this._isRangeSupported = data.isRangeSupported;
+ this._contentLength = data.contentLength;
+ });
+ }
+ get headersReady() {
+ return this._headersReady;
+ }
+ get contentLength() {
+ return this._contentLength;
+ }
+ get isStreamingSupported() {
+ return this._isStreamingSupported;
+ }
+ get isRangeSupported() {
+ return this._isRangeSupported;
+ }
+ async read() {
+ const {
+ value,
+ done
+ } = await this._reader.read();
+ if (done) {
+ return {
+ value: undefined,
+ done: true
+ };
+ }
+ return {
+ value: value.buffer,
+ done: false
+ };
+ }
+ cancel(reason) {
+ this._reader.cancel(reason);
+ }
+}
+class PDFWorkerStreamRangeReader {
+ constructor(begin, end, msgHandler) {
+ this._msgHandler = msgHandler;
+ this.onProgress = null;
+ const readableStream = this._msgHandler.sendWithStream("GetRangeReader", {
+ begin,
+ end
+ });
+ this._reader = readableStream.getReader();
+ }
+ get isStreamingSupported() {
+ return false;
+ }
+ async read() {
+ const {
+ value,
+ done
+ } = await this._reader.read();
+ if (done) {
+ return {
+ value: undefined,
+ done: true
+ };
+ }
+ return {
+ value: value.buffer,
+ done: false
+ };
+ }
+ cancel(reason) {
+ this._reader.cancel(reason);
+ }
+}
+
+;// CONCATENATED MODULE: ./src/core/worker.js
+
+
+
+
+
+
+
+
+
+
+class WorkerTask {
+ constructor(name) {
+ this.name = name;
+ this.terminated = false;
+ this._capability = new PromiseCapability();
+ }
+ get finished() {
+ return this._capability.promise;
+ }
+ finish() {
+ this._capability.resolve();
+ }
+ terminate() {
+ this.terminated = true;
+ }
+ ensureNotTerminated() {
+ if (this.terminated) {
+ throw new Error("Worker task was terminated");
+ }
+ }
+}
+class WorkerMessageHandler {
+ static setup(handler, port) {
+ let testMessageProcessed = false;
+ handler.on("test", function (data) {
+ if (testMessageProcessed) {
+ return;
+ }
+ testMessageProcessed = true;
+ handler.send("test", data instanceof Uint8Array);
+ });
+ handler.on("configure", function (data) {
+ setVerbosityLevel(data.verbosity);
+ });
+ handler.on("GetDocRequest", function (data) {
+ return WorkerMessageHandler.createDocumentHandler(data, port);
+ });
+ }
+ static createDocumentHandler(docParams, port) {
+ let pdfManager;
+ let terminated = false;
+ let cancelXHRs = null;
+ const WorkerTasks = new Set();
+ const verbosity = getVerbosityLevel();
+ const {
+ docId,
+ apiVersion
+ } = docParams;
+ const workerVersion = '4.0.379';
+ if (apiVersion !== workerVersion) {
+ throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
+ }
+ const enumerableProperties = [];
+ for (const property in []) {
+ enumerableProperties.push(property);
+ }
+ if (enumerableProperties.length) {
+ throw new Error("The `Array.prototype` contains unexpected enumerable properties: " + enumerableProperties.join(", ") + "; thus breaking e.g. `for...in` iteration of `Array`s.");
+ }
+ const workerHandlerName = docId + "_worker";
+ let handler = new MessageHandler(workerHandlerName, docId, port);
+ function ensureNotTerminated() {
+ if (terminated) {
+ throw new Error("Worker was terminated");
+ }
+ }
+ function startWorkerTask(task) {
+ WorkerTasks.add(task);
+ }
+ function finishWorkerTask(task) {
+ task.finish();
+ WorkerTasks.delete(task);
+ }
+ async function loadDocument(recoveryMode) {
+ await pdfManager.ensureDoc("checkHeader");
+ await pdfManager.ensureDoc("parseStartXRef");
+ await pdfManager.ensureDoc("parse", [recoveryMode]);
+ await pdfManager.ensureDoc("checkFirstPage", [recoveryMode]);
+ await pdfManager.ensureDoc("checkLastPage", [recoveryMode]);
+ const isPureXfa = await pdfManager.ensureDoc("isPureXfa");
+ if (isPureXfa) {
+ const task = new WorkerTask("loadXfaFonts");
+ startWorkerTask(task);
+ await Promise.all([pdfManager.loadXfaFonts(handler, task).catch(reason => {}).then(() => finishWorkerTask(task)), pdfManager.loadXfaImages()]);
+ }
+ const [numPages, fingerprints] = await Promise.all([pdfManager.ensureDoc("numPages"), pdfManager.ensureDoc("fingerprints")]);
+ const htmlForXfa = isPureXfa ? await pdfManager.ensureDoc("htmlForXfa") : null;
+ return {
+ numPages,
+ fingerprints,
+ htmlForXfa
+ };
+ }
+ function getPdfManager({
+ data,
+ password,
+ disableAutoFetch,
+ rangeChunkSize,
+ length,
+ docBaseUrl,
+ enableXfa,
+ evaluatorOptions
+ }) {
+ const pdfManagerArgs = {
+ source: null,
+ disableAutoFetch,
+ docBaseUrl,
+ docId,
+ enableXfa,
+ evaluatorOptions,
+ handler,
+ length,
+ password,
+ rangeChunkSize
+ };
+ const pdfManagerCapability = new PromiseCapability();
+ let newPdfManager;
+ if (data) {
+ try {
+ pdfManagerArgs.source = data;
+ newPdfManager = new LocalPdfManager(pdfManagerArgs);
+ pdfManagerCapability.resolve(newPdfManager);
+ } catch (ex) {
+ pdfManagerCapability.reject(ex);
+ }
+ return pdfManagerCapability.promise;
+ }
+ let pdfStream,
+ cachedChunks = [];
+ try {
+ pdfStream = new PDFWorkerStream(handler);
+ } catch (ex) {
+ pdfManagerCapability.reject(ex);
+ return pdfManagerCapability.promise;
+ }
+ const fullRequest = pdfStream.getFullReader();
+ fullRequest.headersReady.then(function () {
+ if (!fullRequest.isRangeSupported) {
+ return;
+ }
+ pdfManagerArgs.source = pdfStream;
+ pdfManagerArgs.length = fullRequest.contentLength;
+ pdfManagerArgs.disableAutoFetch ||= fullRequest.isStreamingSupported;
+ newPdfManager = new NetworkPdfManager(pdfManagerArgs);
+ for (const chunk of cachedChunks) {
+ newPdfManager.sendProgressiveData(chunk);
+ }
+ cachedChunks = [];
+ pdfManagerCapability.resolve(newPdfManager);
+ cancelXHRs = null;
+ }).catch(function (reason) {
+ pdfManagerCapability.reject(reason);
+ cancelXHRs = null;
+ });
+ let loaded = 0;
+ const flushChunks = function () {
+ const pdfFile = arrayBuffersToBytes(cachedChunks);
+ if (length && pdfFile.length !== length) {
+ warn("reported HTTP length is different from actual");
+ }
+ try {
+ pdfManagerArgs.source = pdfFile;
+ newPdfManager = new LocalPdfManager(pdfManagerArgs);
+ pdfManagerCapability.resolve(newPdfManager);
+ } catch (ex) {
+ pdfManagerCapability.reject(ex);
+ }
+ cachedChunks = [];
+ };
+ new Promise(function (resolve, reject) {
+ const readChunk = function ({
+ value,
+ done
+ }) {
+ try {
+ ensureNotTerminated();
+ if (done) {
+ if (!newPdfManager) {
+ flushChunks();
+ }
+ cancelXHRs = null;
+ return;
+ }
+ loaded += value.byteLength;
+ if (!fullRequest.isStreamingSupported) {
+ handler.send("DocProgress", {
+ loaded,
+ total: Math.max(loaded, fullRequest.contentLength || 0)
+ });
+ }
+ if (newPdfManager) {
+ newPdfManager.sendProgressiveData(value);
+ } else {
+ cachedChunks.push(value);
+ }
+ fullRequest.read().then(readChunk, reject);
+ } catch (e) {
+ reject(e);
+ }
+ };
+ fullRequest.read().then(readChunk, reject);
+ }).catch(function (e) {
+ pdfManagerCapability.reject(e);
+ cancelXHRs = null;
+ });
+ cancelXHRs = function (reason) {
+ pdfStream.cancelAllRequests(reason);
+ };
+ return pdfManagerCapability.promise;
+ }
+ function setupDoc(data) {
+ function onSuccess(doc) {
+ ensureNotTerminated();
+ handler.send("GetDoc", {
+ pdfInfo: doc
+ });
+ }
+ function onFailure(ex) {
+ ensureNotTerminated();
+ if (ex instanceof PasswordException) {
+ const task = new WorkerTask(`PasswordException: response ${ex.code}`);
+ startWorkerTask(task);
+ handler.sendWithPromise("PasswordRequest", ex).then(function ({
+ password
+ }) {
+ finishWorkerTask(task);
+ pdfManager.updatePassword(password);
+ pdfManagerReady();
+ }).catch(function () {
+ finishWorkerTask(task);
+ handler.send("DocException", ex);
+ });
+ } else if (ex instanceof InvalidPDFException || ex instanceof MissingPDFException || ex instanceof UnexpectedResponseException || ex instanceof UnknownErrorException) {
+ handler.send("DocException", ex);
+ } else {
+ handler.send("DocException", new UnknownErrorException(ex.message, ex.toString()));
+ }
+ }
+ function pdfManagerReady() {
+ ensureNotTerminated();
+ loadDocument(false).then(onSuccess, function (reason) {
+ ensureNotTerminated();
+ if (!(reason instanceof XRefParseException)) {
+ onFailure(reason);
+ return;
+ }
+ pdfManager.requestLoadedStream().then(function () {
+ ensureNotTerminated();
+ loadDocument(true).then(onSuccess, onFailure);
+ });
+ });
+ }
+ ensureNotTerminated();
+ getPdfManager(data).then(function (newPdfManager) {
+ if (terminated) {
+ newPdfManager.terminate(new AbortException("Worker was terminated."));
+ throw new Error("Worker was terminated");
+ }
+ pdfManager = newPdfManager;
+ pdfManager.requestLoadedStream(true).then(stream => {
+ handler.send("DataLoaded", {
+ length: stream.bytes.byteLength
+ });
+ });
+ }).then(pdfManagerReady, onFailure);
+ }
+ handler.on("GetPage", function (data) {
+ return pdfManager.getPage(data.pageIndex).then(function (page) {
+ return Promise.all([pdfManager.ensure(page, "rotate"), pdfManager.ensure(page, "ref"), pdfManager.ensure(page, "userUnit"), pdfManager.ensure(page, "view")]).then(function ([rotate, ref, userUnit, view]) {
+ return {
+ rotate,
+ ref,
+ userUnit,
+ view
+ };
+ });
+ });
+ });
+ handler.on("GetPageIndex", function (data) {
+ const pageRef = Ref.get(data.num, data.gen);
+ return pdfManager.ensureCatalog("getPageIndex", [pageRef]);
+ });
+ handler.on("GetDestinations", function (data) {
+ return pdfManager.ensureCatalog("destinations");
+ });
+ handler.on("GetDestination", function (data) {
+ return pdfManager.ensureCatalog("getDestination", [data.id]);
+ });
+ handler.on("GetPageLabels", function (data) {
+ return pdfManager.ensureCatalog("pageLabels");
+ });
+ handler.on("GetPageLayout", function (data) {
+ return pdfManager.ensureCatalog("pageLayout");
+ });
+ handler.on("GetPageMode", function (data) {
+ return pdfManager.ensureCatalog("pageMode");
+ });
+ handler.on("GetViewerPreferences", function (data) {
+ return pdfManager.ensureCatalog("viewerPreferences");
+ });
+ handler.on("GetOpenAction", function (data) {
+ return pdfManager.ensureCatalog("openAction");
+ });
+ handler.on("GetAttachments", function (data) {
+ return pdfManager.ensureCatalog("attachments");
+ });
+ handler.on("GetDocJSActions", function (data) {
+ return pdfManager.ensureCatalog("jsActions");
+ });
+ handler.on("GetPageJSActions", function ({
+ pageIndex
+ }) {
+ return pdfManager.getPage(pageIndex).then(function (page) {
+ return pdfManager.ensure(page, "jsActions");
+ });
+ });
+ handler.on("GetOutline", function (data) {
+ return pdfManager.ensureCatalog("documentOutline");
+ });
+ handler.on("GetOptionalContentConfig", function (data) {
+ return pdfManager.ensureCatalog("optionalContentConfig");
+ });
+ handler.on("GetPermissions", function (data) {
+ return pdfManager.ensureCatalog("permissions");
+ });
+ handler.on("GetMetadata", function (data) {
+ return Promise.all([pdfManager.ensureDoc("documentInfo"), pdfManager.ensureCatalog("metadata")]);
+ });
+ handler.on("GetMarkInfo", function (data) {
+ return pdfManager.ensureCatalog("markInfo");
+ });
+ handler.on("GetData", function (data) {
+ return pdfManager.requestLoadedStream().then(function (stream) {
+ return stream.bytes;
+ });
+ });
+ handler.on("GetAnnotations", function ({
+ pageIndex,
+ intent
+ }) {
+ return pdfManager.getPage(pageIndex).then(function (page) {
+ const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`);
+ startWorkerTask(task);
+ return page.getAnnotationsData(handler, task, intent).then(data => {
+ finishWorkerTask(task);
+ return data;
+ }, reason => {
+ finishWorkerTask(task);
+ throw reason;
+ });
+ });
+ });
+ handler.on("GetFieldObjects", function (data) {
+ return pdfManager.ensureDoc("fieldObjects");
+ });
+ handler.on("HasJSActions", function (data) {
+ return pdfManager.ensureDoc("hasJSActions");
+ });
+ handler.on("GetCalculationOrderIds", function (data) {
+ return pdfManager.ensureDoc("calculationOrderIds");
+ });
+ handler.on("SaveDocument", async function ({
+ isPureXfa,
+ numPages,
+ annotationStorage,
+ filename
+ }) {
+ const globalPromises = [pdfManager.requestLoadedStream(), pdfManager.ensureCatalog("acroForm"), pdfManager.ensureCatalog("acroFormRef"), pdfManager.ensureDoc("startXRef"), pdfManager.ensureDoc("xref"), pdfManager.ensureDoc("linearization"), pdfManager.ensureCatalog("structTreeRoot")];
+ const promises = [];
+ const newAnnotationsByPage = !isPureXfa ? getNewAnnotationsMap(annotationStorage) : null;
+ const [stream, acroForm, acroFormRef, startXRef, xref, linearization, _structTreeRoot] = await Promise.all(globalPromises);
+ const catalogRef = xref.trailer.getRaw("Root") || null;
+ let structTreeRoot;
+ if (newAnnotationsByPage) {
+ if (!_structTreeRoot) {
+ if (await StructTreeRoot.canCreateStructureTree({
+ catalogRef,
+ pdfManager,
+ newAnnotationsByPage
+ })) {
+ structTreeRoot = null;
+ }
+ } else if (await _structTreeRoot.canUpdateStructTree({
+ pdfManager,
+ xref,
+ newAnnotationsByPage
+ })) {
+ structTreeRoot = _structTreeRoot;
+ }
+ const imagePromises = AnnotationFactory.generateImages(annotationStorage.values(), xref, pdfManager.evaluatorOptions.isOffscreenCanvasSupported);
+ const newAnnotationPromises = structTreeRoot === undefined ? promises : [];
+ for (const [pageIndex, annotations] of newAnnotationsByPage) {
+ newAnnotationPromises.push(pdfManager.getPage(pageIndex).then(page => {
+ const task = new WorkerTask(`Save (editor): page ${pageIndex}`);
+ return page.saveNewAnnotations(handler, task, annotations, imagePromises).finally(function () {
+ finishWorkerTask(task);
+ });
+ }));
+ }
+ if (structTreeRoot === null) {
+ promises.push(Promise.all(newAnnotationPromises).then(async newRefs => {
+ await StructTreeRoot.createStructureTree({
+ newAnnotationsByPage,
+ xref,
+ catalogRef,
+ pdfManager,
+ newRefs
+ });
+ return newRefs;
+ }));
+ } else if (structTreeRoot) {
+ promises.push(Promise.all(newAnnotationPromises).then(async newRefs => {
+ await structTreeRoot.updateStructureTree({
+ newAnnotationsByPage,
+ pdfManager,
+ newRefs
+ });
+ return newRefs;
+ }));
+ }
+ }
+ if (isPureXfa) {
+ promises.push(pdfManager.serializeXfaData(annotationStorage));
+ } else {
+ for (let pageIndex = 0; pageIndex < numPages; pageIndex++) {
+ promises.push(pdfManager.getPage(pageIndex).then(function (page) {
+ const task = new WorkerTask(`Save: page ${pageIndex}`);
+ return page.save(handler, task, annotationStorage).finally(function () {
+ finishWorkerTask(task);
+ });
+ }));
+ }
+ }
+ const refs = await Promise.all(promises);
+ let newRefs = [];
+ let xfaData = null;
+ if (isPureXfa) {
+ xfaData = refs[0];
+ if (!xfaData) {
+ return stream.bytes;
+ }
+ } else {
+ newRefs = refs.flat(2);
+ if (newRefs.length === 0) {
+ return stream.bytes;
+ }
+ }
+ const needAppearances = acroFormRef && acroForm instanceof Dict && newRefs.some(ref => ref.needAppearances);
+ const xfa = acroForm instanceof Dict && acroForm.get("XFA") || null;
+ let xfaDatasetsRef = null;
+ let hasXfaDatasetsEntry = false;
+ if (Array.isArray(xfa)) {
+ for (let i = 0, ii = xfa.length; i < ii; i += 2) {
+ if (xfa[i] === "datasets") {
+ xfaDatasetsRef = xfa[i + 1];
+ hasXfaDatasetsEntry = true;
+ }
+ }
+ if (xfaDatasetsRef === null) {
+ xfaDatasetsRef = xref.getNewTemporaryRef();
+ }
+ } else if (xfa) {
+ warn("Unsupported XFA type.");
+ }
+ let newXrefInfo = Object.create(null);
+ if (xref.trailer) {
+ const infoObj = Object.create(null);
+ const xrefInfo = xref.trailer.get("Info") || null;
+ if (xrefInfo instanceof Dict) {
+ xrefInfo.forEach((key, value) => {
+ if (typeof value === "string") {
+ infoObj[key] = stringToPDFString(value);
+ }
+ });
+ }
+ newXrefInfo = {
+ rootRef: catalogRef,
+ encryptRef: xref.trailer.getRaw("Encrypt") || null,
+ newRef: xref.getNewTemporaryRef(),
+ infoRef: xref.trailer.getRaw("Info") || null,
+ info: infoObj,
+ fileIds: xref.trailer.get("ID") || null,
+ startXRef: linearization ? startXRef : xref.lastXRefStreamPos ?? startXRef,
+ filename
+ };
+ }
+ return incrementalUpdate({
+ originalData: stream.bytes,
+ xrefInfo: newXrefInfo,
+ newRefs,
+ xref,
+ hasXfa: !!xfa,
+ xfaDatasetsRef,
+ hasXfaDatasetsEntry,
+ needAppearances,
+ acroFormRef,
+ acroForm,
+ xfaData
+ }).finally(() => {
+ xref.resetNewTemporaryRef();
+ });
+ });
+ handler.on("GetOperatorList", function (data, sink) {
+ const pageIndex = data.pageIndex;
+ pdfManager.getPage(pageIndex).then(function (page) {
+ const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);
+ startWorkerTask(task);
+ const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;
+ page.getOperatorList({
+ handler,
+ sink,
+ task,
+ intent: data.intent,
+ cacheKey: data.cacheKey,
+ annotationStorage: data.annotationStorage
+ }).then(function (operatorListInfo) {
+ finishWorkerTask(task);
+ if (start) {
+ info(`page=${pageIndex + 1} - getOperatorList: time=` + `${Date.now() - start}ms, len=${operatorListInfo.length}`);
+ }
+ sink.close();
+ }, function (reason) {
+ finishWorkerTask(task);
+ if (task.terminated) {
+ return;
+ }
+ sink.error(reason);
+ });
+ });
+ });
+ handler.on("GetTextContent", function (data, sink) {
+ const {
+ pageIndex,
+ includeMarkedContent,
+ disableNormalization
+ } = data;
+ pdfManager.getPage(pageIndex).then(function (page) {
+ const task = new WorkerTask("GetTextContent: page " + pageIndex);
+ startWorkerTask(task);
+ const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;
+ page.extractTextContent({
+ handler,
+ task,
+ sink,
+ includeMarkedContent,
+ disableNormalization
+ }).then(function () {
+ finishWorkerTask(task);
+ if (start) {
+ info(`page=${pageIndex + 1} - getTextContent: time=` + `${Date.now() - start}ms`);
+ }
+ sink.close();
+ }, function (reason) {
+ finishWorkerTask(task);
+ if (task.terminated) {
+ return;
+ }
+ sink.error(reason);
+ });
+ });
+ });
+ handler.on("GetStructTree", function (data) {
+ return pdfManager.getPage(data.pageIndex).then(function (page) {
+ return pdfManager.ensure(page, "getStructTree");
+ });
+ });
+ handler.on("FontFallback", function (data) {
+ return pdfManager.fontFallback(data.id, handler);
+ });
+ handler.on("Cleanup", function (data) {
+ return pdfManager.cleanup(true);
+ });
+ handler.on("Terminate", function (data) {
+ terminated = true;
+ const waitOn = [];
+ if (pdfManager) {
+ pdfManager.terminate(new AbortException("Worker was terminated."));
+ const cleanupPromise = pdfManager.cleanup();
+ waitOn.push(cleanupPromise);
+ pdfManager = null;
+ } else {
+ clearGlobalCaches();
+ }
+ if (cancelXHRs) {
+ cancelXHRs(new AbortException("Worker was terminated."));
+ }
+ for (const task of WorkerTasks) {
+ waitOn.push(task.finished);
+ task.terminate();
+ }
+ return Promise.all(waitOn).then(function () {
+ handler.destroy();
+ handler = null;
+ });
+ });
+ handler.on("Ready", function (data) {
+ setupDoc(docParams);
+ docParams = null;
+ });
+ return workerHandlerName;
+ }
+ static initializeFromPort(port) {
+ const handler = new MessageHandler("worker", "main", port);
+ WorkerMessageHandler.setup(handler, port);
+ handler.send("ready", null);
+ }
+}
+function isMessagePort(maybePort) {
+ return typeof maybePort.postMessage === "function" && "onmessage" in maybePort;
+}
+if (typeof window === "undefined" && !isNodeJS && typeof self !== "undefined" && isMessagePort(self)) {
+ WorkerMessageHandler.initializeFromPort(self);
+}
+
+;// CONCATENATED MODULE: ./src/pdf.worker.js
+
+const pdfjsVersion = '4.0.379';
+const pdfjsBuild = '9e14d04fd';
+
+var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler;
+export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler };
+
+//# sourceMappingURL=pdf.worker.mjs.map
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-EUC-H.bcmap
new file mode 100644
index 000000000..2655fc70a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-EUC-V.bcmap
new file mode 100644
index 000000000..f1ed85382
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-H.bcmap
new file mode 100644
index 000000000..39e89d333
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-H.bcmap
new file mode 100644
index 000000000..e4167cb51
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-V.bcmap
new file mode 100644
index 000000000..50b1646e9
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/78-V.bcmap
new file mode 100644
index 000000000..d7af99b5e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-H.bcmap
new file mode 100644
index 000000000..37077d01e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-V.bcmap
new file mode 100644
index 000000000..acf23231a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/78ms-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/83pv-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/83pv-RKSJ-H.bcmap
new file mode 100644
index 000000000..2359bc529
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/83pv-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-H.bcmap
new file mode 100644
index 000000000..af8293829
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-V.bcmap
new file mode 100644
index 000000000..780549de1
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90ms-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-H.bcmap
new file mode 100644
index 000000000..bfd3119c6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-V.bcmap
new file mode 100644
index 000000000..25ef14ab4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90msp-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-H.bcmap
new file mode 100644
index 000000000..02f713bb8
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-V.bcmap
new file mode 100644
index 000000000..d08e0cc5d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/90pv-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Add-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/Add-H.bcmap
new file mode 100644
index 000000000..59442acaf
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Add-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-H.bcmap
new file mode 100644
index 000000000..a3065e441
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-V.bcmap
new file mode 100644
index 000000000..040014cfc
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Add-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Add-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/Add-V.bcmap
new file mode 100644
index 000000000..2f816d320
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Add-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-0.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-0.bcmap
new file mode 100644
index 000000000..88ec04af4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-0.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-1.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-1.bcmap
new file mode 100644
index 000000000..03a501477
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-1.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-2.bcmap
new file mode 100644
index 000000000..2aa95141f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-3.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-3.bcmap
new file mode 100644
index 000000000..86d8b8c79
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-3.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-4.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-4.bcmap
new file mode 100644
index 000000000..f50fc6c14
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-4.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-5.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-5.bcmap
new file mode 100644
index 000000000..6caf4a831
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-5.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-6.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-6.bcmap
new file mode 100644
index 000000000..b77fb0705
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-6.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-UCS2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-UCS2.bcmap
new file mode 100644
index 000000000..69d79a2c2
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-CNS1-UCS2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-0.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-0.bcmap
new file mode 100644
index 000000000..36101083f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-0.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-1.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-1.bcmap
new file mode 100644
index 000000000..707bb1065
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-1.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-2.bcmap
new file mode 100644
index 000000000..f7648cc3f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-3.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-3.bcmap
new file mode 100644
index 000000000..852145890
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-3.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-4.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-4.bcmap
new file mode 100644
index 000000000..e40c63ab1
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-4.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-5.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-5.bcmap
new file mode 100644
index 000000000..d7623b500
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-5.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-UCS2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-UCS2.bcmap
new file mode 100644
index 000000000..758652593
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-GB1-UCS2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-0.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-0.bcmap
new file mode 100644
index 000000000..f0e94ec19
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-0.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-1.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-1.bcmap
new file mode 100644
index 000000000..dad42c5ad
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-1.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-2.bcmap
new file mode 100644
index 000000000..090819a06
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-3.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-3.bcmap
new file mode 100644
index 000000000..087dfc155
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-3.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-4.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-4.bcmap
new file mode 100644
index 000000000..46aa9bffe
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-4.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-5.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-5.bcmap
new file mode 100644
index 000000000..5b4b65cc6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-5.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-6.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-6.bcmap
new file mode 100644
index 000000000..e77d699ab
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-6.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-UCS2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-UCS2.bcmap
new file mode 100644
index 000000000..128a14107
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Japan1-UCS2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-0.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-0.bcmap
new file mode 100644
index 000000000..cef1a9985
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-0.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-1.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-1.bcmap
new file mode 100644
index 000000000..11ffa36df
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-1.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-2.bcmap
new file mode 100644
index 000000000..3172308c7
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-UCS2.bcmap b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-UCS2.bcmap
new file mode 100644
index 000000000..f3371c0cb
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Adobe-Korea1-UCS2.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/B5-H.bcmap
new file mode 100644
index 000000000..beb4d2281
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/B5-V.bcmap
new file mode 100644
index 000000000..2d4f87d50
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/B5pc-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/B5pc-H.bcmap
new file mode 100644
index 000000000..ce0013167
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/B5pc-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/B5pc-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/B5pc-V.bcmap
new file mode 100644
index 000000000..73b99ff2f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/B5pc-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-H.bcmap
new file mode 100644
index 000000000..61d1d0cb0
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-V.bcmap
new file mode 100644
index 000000000..1a393a51e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/CNS-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS1-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS1-H.bcmap
new file mode 100644
index 000000000..f738e218a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/CNS1-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS1-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS1-V.bcmap
new file mode 100644
index 000000000..9c3169f0d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/CNS1-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS2-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS2-H.bcmap
new file mode 100644
index 000000000..c89b3527f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/CNS2-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/CNS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/CNS2-V.bcmap
new file mode 100644
index 000000000..7588cec83
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/cmaps/CNS2-V.bcmap
@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEáCNS2-H
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-H.bcmap
new file mode 100644
index 000000000..cb29415de
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-V.bcmap
new file mode 100644
index 000000000..f09aec631
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/ETHK-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETen-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETen-B5-H.bcmap
new file mode 100644
index 000000000..c2d77462d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/ETen-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETen-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETen-B5-V.bcmap
new file mode 100644
index 000000000..89bff159e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/ETen-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-H.bcmap
new file mode 100644
index 000000000..a7d69db5e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-H.bcmap
@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEá ETen-B5-H` ^
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-V.bcmap
new file mode 100644
index 000000000..adc5d618d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/ETenms-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/EUC-H.bcmap
new file mode 100644
index 000000000..e92ea5b3b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/EUC-V.bcmap
new file mode 100644
index 000000000..7a7c18322
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Ext-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/Ext-H.bcmap
new file mode 100644
index 000000000..3b5cde44d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Ext-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-H.bcmap
new file mode 100644
index 000000000..ea4d2d97b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-V.bcmap
new file mode 100644
index 000000000..3457c2770
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Ext-RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Ext-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/Ext-V.bcmap
new file mode 100644
index 000000000..4999ca404
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Ext-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GB-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GB-EUC-H.bcmap
new file mode 100644
index 000000000..e39908b98
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GB-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GB-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GB-EUC-V.bcmap
new file mode 100644
index 000000000..d5be5446a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GB-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GB-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GB-H.bcmap
new file mode 100644
index 000000000..39189c54e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/cmaps/GB-H.bcmap
@@ -0,0 +1,4 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSE!!º]aX!!]`21> pz$]‚"R‚d-Uƒ7*„
4„%+ „Z „{/…%…<9K…b1]†."‡‰`]‡,"]ˆ
+"]ˆh"]‰F"]Š$"]‹"]‹`"]Œ>"]"]z"]ŽX"]6"]"]r"]‘P"]’."]“"]“j"]”H"]•&"]–"]–b"]—@"]˜"]˜|"]™Z"]š8"]›"]›t"]œR"]0"]ž"]žl"]ŸJ"] ("]¡"]¡d"]¢B"]£ "X£~']¤W"]¥5"]¦"]¦q"]§O"]¨-"]©"]©i"]ªG"]«%"]¬"]¬a"]?"]®"]®{"]¯Y"]°7"]±"]±s"]²Q"]³/"]´
"]´k"]µI"]¶'"]·"]·c"]¸A"]¹"]¹}"]º["]»9
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/cmaps/GB-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GB-V.bcmap
new file mode 100644
index 000000000..310834512
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GB-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-H.bcmap
new file mode 100644
index 000000000..05fff7e82
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-V.bcmap
new file mode 100644
index 000000000..0cdf6bed6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBK-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBK2K-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBK2K-H.bcmap
new file mode 100644
index 000000000..46f6ba596
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBK2K-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBK2K-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBK2K-V.bcmap
new file mode 100644
index 000000000..d9a947984
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBK2K-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-H.bcmap
new file mode 100644
index 000000000..5cb0af687
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-V.bcmap
new file mode 100644
index 000000000..bca93b8ef
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBKp-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-H.bcmap
new file mode 100644
index 000000000..4b4e2d322
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-V.bcmap
new file mode 100644
index 000000000..38f706699
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBT-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBT-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBT-H.bcmap
new file mode 100644
index 000000000..8437ac337
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBT-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBT-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBT-V.bcmap
new file mode 100644
index 000000000..697ab4a8e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBT-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-H.bcmap
new file mode 100644
index 000000000..f6e50e893
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-V.bcmap
new file mode 100644
index 000000000..6c0d71a2d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBTpc-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-H.bcmap
new file mode 100644
index 000000000..c9edf67cf
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-V.bcmap
new file mode 100644
index 000000000..31450c97f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/GBpc-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/H.bcmap b/www/lib/pdfjs/modern/web/cmaps/H.bcmap
new file mode 100644
index 000000000..7b24ea462
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-H.bcmap
new file mode 100644
index 000000000..7d30c0500
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-V.bcmap
new file mode 100644
index 000000000..78946940d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKdla-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-H.bcmap
new file mode 100644
index 000000000..d829a2310
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-V.bcmap
new file mode 100644
index 000000000..2b572b50a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKdlb-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-H.bcmap
new file mode 100644
index 000000000..971a4f23f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-V.bcmap
new file mode 100644
index 000000000..d353ca256
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKgccs-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-H.bcmap
new file mode 100644
index 000000000..576dc0111
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-V.bcmap
new file mode 100644
index 000000000..0e96d0e22
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKm314-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-H.bcmap
new file mode 100644
index 000000000..11d170c75
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-V.bcmap
new file mode 100644
index 000000000..54959bf9e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKm471-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-H.bcmap
new file mode 100644
index 000000000..6ef7857ad
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-V.bcmap
new file mode 100644
index 000000000..1fb2fa2a2
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/HKscs-B5-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Hankaku.bcmap b/www/lib/pdfjs/modern/web/cmaps/Hankaku.bcmap
new file mode 100644
index 000000000..4b8ec7fce
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Hankaku.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Hiragana.bcmap b/www/lib/pdfjs/modern/web/cmaps/Hiragana.bcmap
new file mode 100644
index 000000000..17e983e77
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Hiragana.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-H.bcmap
new file mode 100644
index 000000000..a45c65f00
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-V.bcmap
new file mode 100644
index 000000000..0e7b21f0a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-H.bcmap
new file mode 100644
index 000000000..b9b22b678
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-H.bcmap
new file mode 100644
index 000000000..2531ffcf4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-V.bcmap
new file mode 100644
index 000000000..367ceb226
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-Johab-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSC-V.bcmap
new file mode 100644
index 000000000..6ae2f0b6b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-H.bcmap
new file mode 100644
index 000000000..a8d4240e6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-H.bcmap
new file mode 100644
index 000000000..8b4ae18fd
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-V.bcmap
new file mode 100644
index 000000000..b655dbcfb
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-HW-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-V.bcmap
new file mode 100644
index 000000000..21f97f65b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCms-UHC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-H.bcmap
new file mode 100644
index 000000000..e06f361eb
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-V.bcmap
new file mode 100644
index 000000000..f3c9113fc
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/KSCpc-EUC-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Katakana.bcmap b/www/lib/pdfjs/modern/web/cmaps/Katakana.bcmap
new file mode 100644
index 000000000..524303c4f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Katakana.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/LICENSE b/www/lib/pdfjs/modern/web/cmaps/LICENSE
new file mode 100644
index 000000000..b1ad168ad
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/cmaps/LICENSE
@@ -0,0 +1,36 @@
+%%Copyright: -----------------------------------------------------------
+%%Copyright: Copyright 1990-2009 Adobe Systems Incorporated.
+%%Copyright: All rights reserved.
+%%Copyright:
+%%Copyright: Redistribution and use in source and binary forms, with or
+%%Copyright: without modification, are permitted provided that the
+%%Copyright: following conditions are met:
+%%Copyright:
+%%Copyright: Redistributions of source code must retain the above
+%%Copyright: copyright notice, this list of conditions and the following
+%%Copyright: disclaimer.
+%%Copyright:
+%%Copyright: Redistributions in binary form must reproduce the above
+%%Copyright: copyright notice, this list of conditions and the following
+%%Copyright: disclaimer in the documentation and/or other materials
+%%Copyright: provided with the distribution.
+%%Copyright:
+%%Copyright: Neither the name of Adobe Systems Incorporated nor the names
+%%Copyright: of its contributors may be used to endorse or promote
+%%Copyright: products derived from this software without specific prior
+%%Copyright: written permission.
+%%Copyright:
+%%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+%%Copyright: CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+%%Copyright: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+%%Copyright: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+%%Copyright: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%%Copyright: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+%%Copyright: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+%%Copyright: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+%%Copyright: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+%%Copyright: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+%%Copyright: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%%Copyright: OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+%%Copyright: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+%%Copyright: -----------------------------------------------------------
diff --git a/www/lib/pdfjs/modern/web/cmaps/NWP-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/NWP-H.bcmap
new file mode 100644
index 000000000..afc5e4b05
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/NWP-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/NWP-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/NWP-V.bcmap
new file mode 100644
index 000000000..bb5785e32
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/NWP-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/RKSJ-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/RKSJ-H.bcmap
new file mode 100644
index 000000000..fb8d298e9
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/RKSJ-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/RKSJ-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/RKSJ-V.bcmap
new file mode 100644
index 000000000..a2555a6c0
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/RKSJ-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/Roman.bcmap b/www/lib/pdfjs/modern/web/cmaps/Roman.bcmap
new file mode 100644
index 000000000..f896dcf1c
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/Roman.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-H.bcmap
new file mode 100644
index 000000000..d5db27c5c
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-V.bcmap
new file mode 100644
index 000000000..1dc9b7a21
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UCS2-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-H.bcmap
new file mode 100644
index 000000000..961afefb6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-V.bcmap
new file mode 100644
index 000000000..df0cffe86
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF16-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-H.bcmap
new file mode 100644
index 000000000..1ab18a143
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-V.bcmap
new file mode 100644
index 000000000..ad14662e2
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-H.bcmap
new file mode 100644
index 000000000..83c6bd7c4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-V.bcmap
new file mode 100644
index 000000000..22a27e4dd
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniCNS-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-H.bcmap
new file mode 100644
index 000000000..5bd6228ce
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-V.bcmap
new file mode 100644
index 000000000..53c534b7f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UCS2-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-H.bcmap
new file mode 100644
index 000000000..b95045b40
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-V.bcmap
new file mode 100644
index 000000000..51f023e0d
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF16-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-H.bcmap
new file mode 100644
index 000000000..f0dbd14f3
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-V.bcmap
new file mode 100644
index 000000000..ce9c30a98
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-H.bcmap
new file mode 100644
index 000000000..982ca462b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-V.bcmap
new file mode 100644
index 000000000..f78020dd4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniGB-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-H.bcmap
new file mode 100644
index 000000000..7daf56afa
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-H.bcmap
new file mode 100644
index 000000000..ac9975c58
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-V.bcmap
new file mode 100644
index 000000000..3da0a1c62
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-HW-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-V.bcmap
new file mode 100644
index 000000000..c50b9ddfd
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UCS2-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-H.bcmap
new file mode 100644
index 000000000..676134463
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-V.bcmap
new file mode 100644
index 000000000..70bf90c0e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF16-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-H.bcmap
new file mode 100644
index 000000000..7a83d53ae
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-V.bcmap
new file mode 100644
index 000000000..7a8713539
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-H.bcmap
new file mode 100644
index 000000000..9f0334cac
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-V.bcmap
new file mode 100644
index 000000000..808a94f0f
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-H.bcmap
new file mode 100644
index 000000000..d768bf811
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-V.bcmap
new file mode 100644
index 000000000..3d5bf6fb4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF16-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-H.bcmap
new file mode 100644
index 000000000..09eee10d4
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-V.bcmap
new file mode 100644
index 000000000..6c5460013
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-H.bcmap
new file mode 100644
index 000000000..1b1a64f50
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-V.bcmap
new file mode 100644
index 000000000..994aa9ef9
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJIS2004-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-HW-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-HW-V.bcmap
new file mode 100644
index 000000000..643f921b6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-HW-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-V.bcmap
new file mode 100644
index 000000000..c148f67f5
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UCS2-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UTF8-V.bcmap
new file mode 100644
index 000000000..1849d809a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISPro-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-H.bcmap
new file mode 100644
index 000000000..a83a677c5
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-V.bcmap
new file mode 100644
index 000000000..f527248ad
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISX0213-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-H.bcmap
new file mode 100644
index 000000000..e1a988dc9
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-V.bcmap
new file mode 100644
index 000000000..47e054a96
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniJISX02132004-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-H.bcmap
new file mode 100644
index 000000000..b5b94852a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-V.bcmap
new file mode 100644
index 000000000..026adcaad
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UCS2-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-H.bcmap
new file mode 100644
index 000000000..fd4e66e81
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-V.bcmap
new file mode 100644
index 000000000..075efb705
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF16-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-H.bcmap
new file mode 100644
index 000000000..769d2142c
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-V.bcmap
new file mode 100644
index 000000000..bdab208b6
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF32-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-H.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-H.bcmap
new file mode 100644
index 000000000..6ff8674af
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-H.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-V.bcmap b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-V.bcmap
new file mode 100644
index 000000000..8dfa76a58
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/UniKS-UTF8-V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/V.bcmap b/www/lib/pdfjs/modern/web/cmaps/V.bcmap
new file mode 100644
index 000000000..fdec99066
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/V.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/cmaps/WP-Symbol.bcmap b/www/lib/pdfjs/modern/web/cmaps/WP-Symbol.bcmap
new file mode 100644
index 000000000..46729bbf3
Binary files /dev/null and b/www/lib/pdfjs/modern/web/cmaps/WP-Symbol.bcmap differ
diff --git a/www/lib/pdfjs/modern/web/compressed.tracemonkey-pldi-09.pdf b/www/lib/pdfjs/modern/web/compressed.tracemonkey-pldi-09.pdf
new file mode 100644
index 000000000..65570184a
Binary files /dev/null and b/www/lib/pdfjs/modern/web/compressed.tracemonkey-pldi-09.pdf differ
diff --git a/www/lib/pdfjs/modern/web/debugger.css b/www/lib/pdfjs/modern/web/debugger.css
new file mode 100644
index 000000000..ba24ad6a0
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/debugger.css
@@ -0,0 +1,111 @@
+/* Copyright 2014 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+:root {
+ --panel-width: 300px;
+}
+
+#PDFBug,
+#PDFBug :is(input, button, select) {
+ font: message-box;
+}
+#PDFBug {
+ background-color: rgb(255 255 255);
+ border: 1px solid rgb(102 102 102);
+ position: fixed;
+ top: 32px;
+ right: 0;
+ bottom: 0;
+ font-size: 10px;
+ padding: 0;
+ width: var(--panel-width);
+}
+#PDFBug .controls {
+ background: rgb(238 238 238);
+ border-bottom: 1px solid rgb(102 102 102);
+ padding: 3px;
+}
+#PDFBug .panels {
+ inset: 27px 0 0;
+ overflow: auto;
+ position: absolute;
+}
+#PDFBug .panels > div {
+ padding: 5px;
+}
+#PDFBug button.active {
+ font-weight: bold;
+}
+.debuggerShowText,
+.debuggerHideText:hover {
+ background-color: rgb(255 255 0);
+}
+#PDFBug .stats {
+ font-family: courier;
+ font-size: 10px;
+ white-space: pre;
+}
+#PDFBug .stats .title {
+ font-weight: bold;
+}
+#PDFBug table {
+ font-size: 10px;
+ white-space: pre;
+}
+#PDFBug table.showText {
+ border-collapse: collapse;
+ text-align: center;
+}
+#PDFBug table.showText,
+#PDFBug table.showText :is(tr, td) {
+ border: 1px solid black;
+ padding: 1px;
+}
+#PDFBug table.showText td.advance {
+ color: grey;
+}
+
+#viewer.textLayer-visible .textLayer {
+ opacity: 1;
+}
+
+#viewer.textLayer-visible .canvasWrapper {
+ background-color: rgb(128 255 128);
+}
+
+#viewer.textLayer-visible .canvasWrapper canvas {
+ mix-blend-mode: screen;
+}
+
+#viewer.textLayer-visible .textLayer span {
+ background-color: rgb(255 255 0 / 0.1);
+ color: rgb(0 0 0);
+ border: solid 1px rgb(255 0 0 / 0.5);
+ box-sizing: border-box;
+}
+
+#viewer.textLayer-visible .textLayer span[aria-owns] {
+ background-color: rgb(255 0 0 / 0.3);
+}
+
+#viewer.textLayer-hover .textLayer span:hover {
+ background-color: rgb(255 255 255);
+ color: rgb(0 0 0);
+}
+
+#viewer.textLayer-shadow .textLayer span {
+ background-color: rgb(255 255 255 / 0.6);
+ color: rgb(0 0 0);
+}
diff --git a/www/lib/pdfjs/modern/web/debugger.mjs b/www/lib/pdfjs/modern/web/debugger.mjs
new file mode 100644
index 000000000..59c1871b3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/debugger.mjs
@@ -0,0 +1,623 @@
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const { OPS } = globalThis.pdfjsLib || (await import("pdfjs-lib"));
+
+const opMap = Object.create(null);
+for (const key in OPS) {
+ opMap[OPS[key]] = key;
+}
+
+const FontInspector = (function FontInspectorClosure() {
+ let fonts;
+ let active = false;
+ const fontAttribute = "data-font-name";
+ function removeSelection() {
+ const divs = document.querySelectorAll(`span[${fontAttribute}]`);
+ for (const div of divs) {
+ div.className = "";
+ }
+ }
+ function resetSelection() {
+ const divs = document.querySelectorAll(`span[${fontAttribute}]`);
+ for (const div of divs) {
+ div.className = "debuggerHideText";
+ }
+ }
+ function selectFont(fontName, show) {
+ const divs = document.querySelectorAll(
+ `span[${fontAttribute}=${fontName}]`
+ );
+ for (const div of divs) {
+ div.className = show ? "debuggerShowText" : "debuggerHideText";
+ }
+ }
+ function textLayerClick(e) {
+ if (
+ !e.target.dataset.fontName ||
+ e.target.tagName.toUpperCase() !== "SPAN"
+ ) {
+ return;
+ }
+ const fontName = e.target.dataset.fontName;
+ const selects = document.getElementsByTagName("input");
+ for (const select of selects) {
+ if (select.dataset.fontName !== fontName) {
+ continue;
+ }
+ select.checked = !select.checked;
+ selectFont(fontName, select.checked);
+ select.scrollIntoView();
+ }
+ }
+ return {
+ // Properties/functions needed by PDFBug.
+ id: "FontInspector",
+ name: "Font Inspector",
+ panel: null,
+ manager: null,
+ init() {
+ const panel = this.panel;
+ const tmp = document.createElement("button");
+ tmp.addEventListener("click", resetSelection);
+ tmp.textContent = "Refresh";
+ panel.append(tmp);
+
+ fonts = document.createElement("div");
+ panel.append(fonts);
+ },
+ cleanup() {
+ fonts.textContent = "";
+ },
+ enabled: false,
+ get active() {
+ return active;
+ },
+ set active(value) {
+ active = value;
+ if (active) {
+ document.body.addEventListener("click", textLayerClick, true);
+ resetSelection();
+ } else {
+ document.body.removeEventListener("click", textLayerClick, true);
+ removeSelection();
+ }
+ },
+ // FontInspector specific functions.
+ fontAdded(fontObj, url) {
+ function properties(obj, list) {
+ const moreInfo = document.createElement("table");
+ for (const entry of list) {
+ const tr = document.createElement("tr");
+ const td1 = document.createElement("td");
+ td1.textContent = entry;
+ tr.append(td1);
+ const td2 = document.createElement("td");
+ td2.textContent = obj[entry].toString();
+ tr.append(td2);
+ moreInfo.append(tr);
+ }
+ return moreInfo;
+ }
+
+ const moreInfo = fontObj.css
+ ? properties(fontObj, ["baseFontName"])
+ : properties(fontObj, ["name", "type"]);
+
+ const fontName = fontObj.loadedName;
+ const font = document.createElement("div");
+ const name = document.createElement("span");
+ name.textContent = fontName;
+ let download;
+ if (!fontObj.css) {
+ download = document.createElement("a");
+ if (url) {
+ url = /url\(['"]?([^)"']+)/.exec(url);
+ download.href = url[1];
+ } else if (fontObj.data) {
+ download.href = URL.createObjectURL(
+ new Blob([fontObj.data], { type: fontObj.mimetype })
+ );
+ }
+ download.textContent = "Download";
+ }
+
+ const logIt = document.createElement("a");
+ logIt.href = "";
+ logIt.textContent = "Log";
+ logIt.addEventListener("click", function (event) {
+ event.preventDefault();
+ console.log(fontObj);
+ });
+ const select = document.createElement("input");
+ select.setAttribute("type", "checkbox");
+ select.dataset.fontName = fontName;
+ select.addEventListener("click", function () {
+ selectFont(fontName, select.checked);
+ });
+ if (download) {
+ font.append(select, name, " ", download, " ", logIt, moreInfo);
+ } else {
+ font.append(select, name, " ", logIt, moreInfo);
+ }
+ fonts.append(font);
+ // Somewhat of a hack, should probably add a hook for when the text layer
+ // is done rendering.
+ setTimeout(() => {
+ if (this.active) {
+ resetSelection();
+ }
+ }, 2000);
+ },
+ };
+})();
+
+// Manages all the page steppers.
+const StepperManager = (function StepperManagerClosure() {
+ let steppers = [];
+ let stepperDiv = null;
+ let stepperControls = null;
+ let stepperChooser = null;
+ let breakPoints = Object.create(null);
+ return {
+ // Properties/functions needed by PDFBug.
+ id: "Stepper",
+ name: "Stepper",
+ panel: null,
+ manager: null,
+ init() {
+ const self = this;
+ stepperControls = document.createElement("div");
+ stepperChooser = document.createElement("select");
+ stepperChooser.addEventListener("change", function (event) {
+ self.selectStepper(this.value);
+ });
+ stepperControls.append(stepperChooser);
+ stepperDiv = document.createElement("div");
+ this.panel.append(stepperControls, stepperDiv);
+ if (sessionStorage.getItem("pdfjsBreakPoints")) {
+ breakPoints = JSON.parse(sessionStorage.getItem("pdfjsBreakPoints"));
+ }
+ },
+ cleanup() {
+ stepperChooser.textContent = "";
+ stepperDiv.textContent = "";
+ steppers = [];
+ },
+ enabled: false,
+ active: false,
+ // Stepper specific functions.
+ create(pageIndex) {
+ const debug = document.createElement("div");
+ debug.id = "stepper" + pageIndex;
+ debug.hidden = true;
+ debug.className = "stepper";
+ stepperDiv.append(debug);
+ const b = document.createElement("option");
+ b.textContent = "Page " + (pageIndex + 1);
+ b.value = pageIndex;
+ stepperChooser.append(b);
+ const initBreakPoints = breakPoints[pageIndex] || [];
+ const stepper = new Stepper(debug, pageIndex, initBreakPoints);
+ steppers.push(stepper);
+ if (steppers.length === 1) {
+ this.selectStepper(pageIndex, false);
+ }
+ return stepper;
+ },
+ selectStepper(pageIndex, selectPanel) {
+ pageIndex |= 0;
+ if (selectPanel) {
+ this.manager.selectPanel(this);
+ }
+ for (const stepper of steppers) {
+ stepper.panel.hidden = stepper.pageIndex !== pageIndex;
+ }
+ for (const option of stepperChooser.options) {
+ option.selected = (option.value | 0) === pageIndex;
+ }
+ },
+ saveBreakPoints(pageIndex, bps) {
+ breakPoints[pageIndex] = bps;
+ sessionStorage.setItem("pdfjsBreakPoints", JSON.stringify(breakPoints));
+ },
+ };
+})();
+
+// The stepper for each page's operatorList.
+class Stepper {
+ // Shorter way to create element and optionally set textContent.
+ #c(tag, textContent) {
+ const d = document.createElement(tag);
+ if (textContent) {
+ d.textContent = textContent;
+ }
+ return d;
+ }
+
+ #simplifyArgs(args) {
+ if (typeof args === "string") {
+ const MAX_STRING_LENGTH = 75;
+ return args.length <= MAX_STRING_LENGTH
+ ? args
+ : args.substring(0, MAX_STRING_LENGTH) + "...";
+ }
+ if (typeof args !== "object" || args === null) {
+ return args;
+ }
+ if ("length" in args) {
+ // array
+ const MAX_ITEMS = 10,
+ simpleArgs = [];
+ let i, ii;
+ for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
+ simpleArgs.push(this.#simplifyArgs(args[i]));
+ }
+ if (i < args.length) {
+ simpleArgs.push("...");
+ }
+ return simpleArgs;
+ }
+ const simpleObj = {};
+ for (const key in args) {
+ simpleObj[key] = this.#simplifyArgs(args[key]);
+ }
+ return simpleObj;
+ }
+
+ constructor(panel, pageIndex, initialBreakPoints) {
+ this.panel = panel;
+ this.breakPoint = 0;
+ this.nextBreakPoint = null;
+ this.pageIndex = pageIndex;
+ this.breakPoints = initialBreakPoints;
+ this.currentIdx = -1;
+ this.operatorListIdx = 0;
+ this.indentLevel = 0;
+ }
+
+ init(operatorList) {
+ const panel = this.panel;
+ const content = this.#c("div", "c=continue, s=step");
+ const table = this.#c("table");
+ content.append(table);
+ table.cellSpacing = 0;
+ const headerRow = this.#c("tr");
+ table.append(headerRow);
+ headerRow.append(
+ this.#c("th", "Break"),
+ this.#c("th", "Idx"),
+ this.#c("th", "fn"),
+ this.#c("th", "args")
+ );
+ panel.append(content);
+ this.table = table;
+ this.updateOperatorList(operatorList);
+ }
+
+ updateOperatorList(operatorList) {
+ const self = this;
+
+ function cboxOnClick() {
+ const x = +this.dataset.idx;
+ if (this.checked) {
+ self.breakPoints.push(x);
+ } else {
+ self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
+ }
+ StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
+ }
+
+ const MAX_OPERATORS_COUNT = 15000;
+ if (this.operatorListIdx > MAX_OPERATORS_COUNT) {
+ return;
+ }
+
+ const chunk = document.createDocumentFragment();
+ const operatorsToDisplay = Math.min(
+ MAX_OPERATORS_COUNT,
+ operatorList.fnArray.length
+ );
+ for (let i = this.operatorListIdx; i < operatorsToDisplay; i++) {
+ const line = this.#c("tr");
+ line.className = "line";
+ line.dataset.idx = i;
+ chunk.append(line);
+ const checked = this.breakPoints.includes(i);
+ const args = operatorList.argsArray[i] || [];
+
+ const breakCell = this.#c("td");
+ const cbox = this.#c("input");
+ cbox.type = "checkbox";
+ cbox.className = "points";
+ cbox.checked = checked;
+ cbox.dataset.idx = i;
+ cbox.onclick = cboxOnClick;
+
+ breakCell.append(cbox);
+ line.append(breakCell, this.#c("td", i.toString()));
+ const fn = opMap[operatorList.fnArray[i]];
+ let decArgs = args;
+ if (fn === "showText") {
+ const glyphs = args[0];
+ const charCodeRow = this.#c("tr");
+ const fontCharRow = this.#c("tr");
+ const unicodeRow = this.#c("tr");
+ for (const glyph of glyphs) {
+ if (typeof glyph === "object" && glyph !== null) {
+ charCodeRow.append(this.#c("td", glyph.originalCharCode));
+ fontCharRow.append(this.#c("td", glyph.fontChar));
+ unicodeRow.append(this.#c("td", glyph.unicode));
+ } else {
+ // null or number
+ const advanceEl = this.#c("td", glyph);
+ advanceEl.classList.add("advance");
+ charCodeRow.append(advanceEl);
+ fontCharRow.append(this.#c("td"));
+ unicodeRow.append(this.#c("td"));
+ }
+ }
+ decArgs = this.#c("td");
+ const table = this.#c("table");
+ table.classList.add("showText");
+ decArgs.append(table);
+ table.append(charCodeRow, fontCharRow, unicodeRow);
+ } else if (fn === "restore" && this.indentLevel > 0) {
+ this.indentLevel--;
+ }
+ line.append(this.#c("td", " ".repeat(this.indentLevel * 2) + fn));
+ if (fn === "save") {
+ this.indentLevel++;
+ }
+
+ if (decArgs instanceof HTMLElement) {
+ line.append(decArgs);
+ } else {
+ line.append(this.#c("td", JSON.stringify(this.#simplifyArgs(decArgs))));
+ }
+ }
+ if (operatorsToDisplay < operatorList.fnArray.length) {
+ const lastCell = this.#c("td", "...");
+ lastCell.colspan = 4;
+ chunk.append(lastCell);
+ }
+ this.operatorListIdx = operatorList.fnArray.length;
+ this.table.append(chunk);
+ }
+
+ getNextBreakPoint() {
+ this.breakPoints.sort(function (a, b) {
+ return a - b;
+ });
+ for (const breakPoint of this.breakPoints) {
+ if (breakPoint > this.currentIdx) {
+ return breakPoint;
+ }
+ }
+ return null;
+ }
+
+ breakIt(idx, callback) {
+ StepperManager.selectStepper(this.pageIndex, true);
+ this.currentIdx = idx;
+
+ const listener = evt => {
+ switch (evt.keyCode) {
+ case 83: // step
+ document.removeEventListener("keydown", listener);
+ this.nextBreakPoint = this.currentIdx + 1;
+ this.goTo(-1);
+ callback();
+ break;
+ case 67: // continue
+ document.removeEventListener("keydown", listener);
+ this.nextBreakPoint = this.getNextBreakPoint();
+ this.goTo(-1);
+ callback();
+ break;
+ }
+ };
+ document.addEventListener("keydown", listener);
+ this.goTo(idx);
+ }
+
+ goTo(idx) {
+ const allRows = this.panel.getElementsByClassName("line");
+ for (const row of allRows) {
+ if ((row.dataset.idx | 0) === idx) {
+ row.style.backgroundColor = "rgb(251,250,207)";
+ row.scrollIntoView();
+ } else {
+ row.style.backgroundColor = null;
+ }
+ }
+ }
+}
+
+const Stats = (function Stats() {
+ let stats = [];
+ function clear(node) {
+ node.textContent = ""; // Remove any `node` contents from the DOM.
+ }
+ function getStatIndex(pageNumber) {
+ for (const [i, stat] of stats.entries()) {
+ if (stat.pageNumber === pageNumber) {
+ return i;
+ }
+ }
+ return false;
+ }
+ return {
+ // Properties/functions needed by PDFBug.
+ id: "Stats",
+ name: "Stats",
+ panel: null,
+ manager: null,
+ init() {},
+ enabled: false,
+ active: false,
+ // Stats specific functions.
+ add(pageNumber, stat) {
+ if (!stat) {
+ return;
+ }
+ const statsIndex = getStatIndex(pageNumber);
+ if (statsIndex !== false) {
+ stats[statsIndex].div.remove();
+ stats.splice(statsIndex, 1);
+ }
+ const wrapper = document.createElement("div");
+ wrapper.className = "stats";
+ const title = document.createElement("div");
+ title.className = "title";
+ title.textContent = "Page: " + pageNumber;
+ const statsDiv = document.createElement("div");
+ statsDiv.textContent = stat.toString();
+ wrapper.append(title, statsDiv);
+ stats.push({ pageNumber, div: wrapper });
+ stats.sort(function (a, b) {
+ return a.pageNumber - b.pageNumber;
+ });
+ clear(this.panel);
+ for (const entry of stats) {
+ this.panel.append(entry.div);
+ }
+ },
+ cleanup() {
+ stats = [];
+ clear(this.panel);
+ },
+ };
+})();
+
+// Manages all the debugging tools.
+class PDFBug {
+ static #buttons = [];
+
+ static #activePanel = null;
+
+ static tools = [FontInspector, StepperManager, Stats];
+
+ static enable(ids) {
+ const all = ids.length === 1 && ids[0] === "all";
+ const tools = this.tools;
+ for (const tool of tools) {
+ if (all || ids.includes(tool.id)) {
+ tool.enabled = true;
+ }
+ }
+ if (!all) {
+ // Sort the tools by the order they are enabled.
+ tools.sort(function (a, b) {
+ let indexA = ids.indexOf(a.id);
+ indexA = indexA < 0 ? tools.length : indexA;
+ let indexB = ids.indexOf(b.id);
+ indexB = indexB < 0 ? tools.length : indexB;
+ return indexA - indexB;
+ });
+ }
+ }
+
+ static init(container, ids) {
+ this.loadCSS();
+ this.enable(ids);
+ /*
+ * Basic Layout:
+ * PDFBug
+ * Controls
+ * Panels
+ * Panel
+ * Panel
+ * ...
+ */
+ const ui = document.createElement("div");
+ ui.id = "PDFBug";
+
+ const controls = document.createElement("div");
+ controls.setAttribute("class", "controls");
+ ui.append(controls);
+
+ const panels = document.createElement("div");
+ panels.setAttribute("class", "panels");
+ ui.append(panels);
+
+ container.append(ui);
+ container.style.right = "var(--panel-width)";
+
+ // Initialize all the debugging tools.
+ for (const tool of this.tools) {
+ const panel = document.createElement("div");
+ const panelButton = document.createElement("button");
+ panelButton.textContent = tool.name;
+ panelButton.addEventListener("click", event => {
+ event.preventDefault();
+ this.selectPanel(tool);
+ });
+ controls.append(panelButton);
+ panels.append(panel);
+ tool.panel = panel;
+ tool.manager = this;
+ if (tool.enabled) {
+ tool.init();
+ } else {
+ panel.textContent =
+ `${tool.name} is disabled. To enable add "${tool.id}" to ` +
+ "the pdfBug parameter and refresh (separate multiple by commas).";
+ }
+ this.#buttons.push(panelButton);
+ }
+ this.selectPanel(0);
+ }
+
+ static loadCSS() {
+ const { url } = import.meta;
+
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = url.replace(/\.mjs$/, ".css");
+
+ document.head.append(link);
+ }
+
+ static cleanup() {
+ for (const tool of this.tools) {
+ if (tool.enabled) {
+ tool.cleanup();
+ }
+ }
+ }
+
+ static selectPanel(index) {
+ if (typeof index !== "number") {
+ index = this.tools.indexOf(index);
+ }
+ if (index === this.#activePanel) {
+ return;
+ }
+ this.#activePanel = index;
+ for (const [j, tool] of this.tools.entries()) {
+ const isActive = j === index;
+ this.#buttons[j].classList.toggle("active", isActive);
+ tool.active = isActive;
+ tool.panel.hidden = !isActive;
+ }
+ }
+}
+
+globalThis.FontInspector = FontInspector;
+globalThis.StepperManager = StepperManager;
+globalThis.Stats = Stats;
+
+export { PDFBug };
diff --git a/www/lib/pdfjs/modern/web/images/altText_add.svg b/www/lib/pdfjs/modern/web/images/altText_add.svg
new file mode 100644
index 000000000..3451b536c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/altText_add.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/altText_done.svg b/www/lib/pdfjs/modern/web/images/altText_done.svg
new file mode 100644
index 000000000..f54924ebf
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/altText_done.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-check.svg b/www/lib/pdfjs/modern/web/images/annotation-check.svg
new file mode 100644
index 000000000..71cd16df5
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-check.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-comment.svg b/www/lib/pdfjs/modern/web/images/annotation-comment.svg
new file mode 100644
index 000000000..86f1f1724
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-comment.svg
@@ -0,0 +1,16 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-help.svg b/www/lib/pdfjs/modern/web/images/annotation-help.svg
new file mode 100644
index 000000000..00938fefe
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-help.svg
@@ -0,0 +1,26 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-insert.svg b/www/lib/pdfjs/modern/web/images/annotation-insert.svg
new file mode 100644
index 000000000..519ef6826
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-insert.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-key.svg b/www/lib/pdfjs/modern/web/images/annotation-key.svg
new file mode 100644
index 000000000..8d09d5378
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-key.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-newparagraph.svg b/www/lib/pdfjs/modern/web/images/annotation-newparagraph.svg
new file mode 100644
index 000000000..38d2497da
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-newparagraph.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-noicon.svg b/www/lib/pdfjs/modern/web/images/annotation-noicon.svg
new file mode 100644
index 000000000..c07d10808
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-noicon.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-note.svg b/www/lib/pdfjs/modern/web/images/annotation-note.svg
new file mode 100644
index 000000000..70173651c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-note.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-paperclip.svg b/www/lib/pdfjs/modern/web/images/annotation-paperclip.svg
new file mode 100644
index 000000000..2bed2250a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-paperclip.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-paragraph.svg b/www/lib/pdfjs/modern/web/images/annotation-paragraph.svg
new file mode 100644
index 000000000..6ae5212b7
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-paragraph.svg
@@ -0,0 +1,16 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/annotation-pushpin.svg b/www/lib/pdfjs/modern/web/images/annotation-pushpin.svg
new file mode 100644
index 000000000..6e0896cf4
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/annotation-pushpin.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/cursor-editorFreeText.svg b/www/lib/pdfjs/modern/web/images/cursor-editorFreeText.svg
new file mode 100644
index 000000000..de2838ef1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/cursor-editorFreeText.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/cursor-editorInk.svg b/www/lib/pdfjs/modern/web/images/cursor-editorInk.svg
new file mode 100644
index 000000000..1dadb5c01
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/cursor-editorInk.svg
@@ -0,0 +1,4 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/editor-toolbar-delete.svg b/www/lib/pdfjs/modern/web/images/editor-toolbar-delete.svg
new file mode 100644
index 000000000..f84520d85
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/editor-toolbar-delete.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/images/findbarButton-next.svg b/www/lib/pdfjs/modern/web/images/findbarButton-next.svg
new file mode 100644
index 000000000..8cb39bec6
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/findbarButton-next.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/findbarButton-previous.svg b/www/lib/pdfjs/modern/web/images/findbarButton-previous.svg
new file mode 100644
index 000000000..b610879da
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/findbarButton-previous.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/gv-toolbarButton-download.svg b/www/lib/pdfjs/modern/web/images/gv-toolbarButton-download.svg
new file mode 100644
index 000000000..d56cf3ce7
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/gv-toolbarButton-download.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/gv-toolbarButton-openinapp.svg b/www/lib/pdfjs/modern/web/images/gv-toolbarButton-openinapp.svg
new file mode 100644
index 000000000..80ec891aa
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/gv-toolbarButton-openinapp.svg
@@ -0,0 +1,11 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/loading-icon.gif b/www/lib/pdfjs/modern/web/images/loading-icon.gif
new file mode 100644
index 000000000..1c72ebb55
Binary files /dev/null and b/www/lib/pdfjs/modern/web/images/loading-icon.gif differ
diff --git a/www/lib/pdfjs/modern/web/images/loading.svg b/www/lib/pdfjs/modern/web/images/loading.svg
new file mode 100644
index 000000000..0a15ff688
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/loading.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-documentProperties.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-documentProperties.svg
new file mode 100644
index 000000000..dd3917b91
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-documentProperties.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-firstPage.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-firstPage.svg
new file mode 100644
index 000000000..f5c917f12
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-firstPage.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-handTool.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-handTool.svg
new file mode 100644
index 000000000..b7073b598
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-handTool.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-lastPage.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-lastPage.svg
new file mode 100644
index 000000000..c04f65079
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-lastPage.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCcw.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCcw.svg
new file mode 100644
index 000000000..da73a1b16
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCcw.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCw.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCw.svg
new file mode 100644
index 000000000..c41ce7365
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-rotateCw.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollHorizontal.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollHorizontal.svg
new file mode 100644
index 000000000..fb440b946
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollHorizontal.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollPage.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollPage.svg
new file mode 100644
index 000000000..64a9f5007
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollPage.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollVertical.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollVertical.svg
new file mode 100644
index 000000000..dc7e80520
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollVertical.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollWrapped.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollWrapped.svg
new file mode 100644
index 000000000..75fe26bcf
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-scrollWrapped.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-selectTool.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-selectTool.svg
new file mode 100644
index 000000000..94d51410d
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-selectTool.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadEven.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadEven.svg
new file mode 100644
index 000000000..ce201e33c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadEven.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadNone.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadNone.svg
new file mode 100644
index 000000000..e8d487fa3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadNone.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadOdd.svg b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadOdd.svg
new file mode 100644
index 000000000..9211a427b
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/secondaryToolbarButton-spreadOdd.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-bookmark.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-bookmark.svg
new file mode 100644
index 000000000..c4c37c905
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-bookmark.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-currentOutlineItem.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-currentOutlineItem.svg
new file mode 100644
index 000000000..01e67623b
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-currentOutlineItem.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-download.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-download.svg
new file mode 100644
index 000000000..e2e850adf
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-download.svg
@@ -0,0 +1,4 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-editorFreeText.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-editorFreeText.svg
new file mode 100644
index 000000000..e4db3a57c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-editorFreeText.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-editorHighlight.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-editorHighlight.svg
new file mode 100644
index 000000000..b3cd7fda9
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-editorHighlight.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-editorInk.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-editorInk.svg
new file mode 100644
index 000000000..b579eec7e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-editorInk.svg
@@ -0,0 +1,4 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-editorStamp.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-editorStamp.svg
new file mode 100644
index 000000000..f0469b1b1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-editorStamp.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-menuArrow.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-menuArrow.svg
new file mode 100644
index 000000000..82ffeaabb
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-menuArrow.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-openFile.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-openFile.svg
new file mode 100644
index 000000000..e773781d6
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-openFile.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-pageDown.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-pageDown.svg
new file mode 100644
index 000000000..1fc12e733
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-pageDown.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-pageUp.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-pageUp.svg
new file mode 100644
index 000000000..0936b9a57
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-pageUp.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-presentationMode.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-presentationMode.svg
new file mode 100644
index 000000000..901d5672b
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-presentationMode.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-print.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-print.svg
new file mode 100644
index 000000000..97a390474
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-print.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-search.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-search.svg
new file mode 100644
index 000000000..0cc7ae21a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-search.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-secondaryToolbarToggle.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-secondaryToolbarToggle.svg
new file mode 100644
index 000000000..cace86372
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-secondaryToolbarToggle.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-sidebarToggle.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-sidebarToggle.svg
new file mode 100644
index 000000000..1d8d0e4b2
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-sidebarToggle.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-viewAttachments.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-viewAttachments.svg
new file mode 100644
index 000000000..ab73f6e6e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-viewAttachments.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-viewLayers.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-viewLayers.svg
new file mode 100644
index 000000000..1d7266826
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-viewLayers.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-viewOutline.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-viewOutline.svg
new file mode 100644
index 000000000..7ed1bd97f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-viewOutline.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-viewThumbnail.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-viewThumbnail.svg
new file mode 100644
index 000000000..040d12326
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-viewThumbnail.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-zoomIn.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-zoomIn.svg
new file mode 100644
index 000000000..30ec51a2f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-zoomIn.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/toolbarButton-zoomOut.svg b/www/lib/pdfjs/modern/web/images/toolbarButton-zoomOut.svg
new file mode 100644
index 000000000..f273b5995
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/toolbarButton-zoomOut.svg
@@ -0,0 +1,3 @@
+
diff --git a/www/lib/pdfjs/modern/web/images/treeitem-collapsed.svg b/www/lib/pdfjs/modern/web/images/treeitem-collapsed.svg
new file mode 100644
index 000000000..831cddfc8
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/treeitem-collapsed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/images/treeitem-expanded.svg b/www/lib/pdfjs/modern/web/images/treeitem-expanded.svg
new file mode 100644
index 000000000..2d45f0c8d
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/images/treeitem-expanded.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/locale/ach/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ach/viewer.ftl
new file mode 100644
index 000000000..36769b708
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ach/viewer.ftl
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pot buk mukato
+pdfjs-previous-button-label = Mukato
+pdfjs-next-button =
+ .title = Pot buk malubo
+pdfjs-next-button-label = Malubo
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pot buk
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = pi { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } me { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Jwik Matidi
+pdfjs-zoom-out-button-label = Jwik Matidi
+pdfjs-zoom-in-button =
+ .title = Kwot Madit
+pdfjs-zoom-in-button-label = Kwot Madit
+pdfjs-zoom-select =
+ .title = Kwoti
+pdfjs-presentation-mode-button =
+ .title = Lokke i kit me tyer
+pdfjs-presentation-mode-button-label = Kit me tyer
+pdfjs-open-file-button =
+ .title = Yab Pwail
+pdfjs-open-file-button-label = Yab
+pdfjs-print-button =
+ .title = Go
+pdfjs-print-button-label = Go
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Gintic
+pdfjs-tools-button-label = Gintic
+pdfjs-first-page-button =
+ .title = Cit i pot buk mukwongo
+pdfjs-first-page-button-label = Cit i pot buk mukwongo
+pdfjs-last-page-button =
+ .title = Cit i pot buk magiko
+pdfjs-last-page-button-label = Cit i pot buk magiko
+pdfjs-page-rotate-cw-button =
+ .title = Wire i tung lacuc
+pdfjs-page-rotate-cw-button-label = Wire i tung lacuc
+pdfjs-page-rotate-ccw-button =
+ .title = Wire i tung lacam
+pdfjs-page-rotate-ccw-button-label = Wire i tung lacam
+pdfjs-cursor-text-select-tool-button =
+ .title = Cak gitic me yero coc
+pdfjs-cursor-text-select-tool-button-label = Gitic me yero coc
+pdfjs-cursor-hand-tool-button =
+ .title = Cak gitic me cing
+pdfjs-cursor-hand-tool-button-label = Gitic cing
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Jami me gin acoya…
+pdfjs-document-properties-button-label = Jami me gin acoya…
+pdfjs-document-properties-file-name = Nying pwail:
+pdfjs-document-properties-file-size = Dit pa pwail:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Wiye:
+pdfjs-document-properties-author = Ngat mucoyo:
+pdfjs-document-properties-subject = Subjek:
+pdfjs-document-properties-keywords = Lok mapire tek:
+pdfjs-document-properties-creation-date = Nino dwe me cwec:
+pdfjs-document-properties-modification-date = Nino dwe me yub:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Lacwec:
+pdfjs-document-properties-producer = Layub PDF:
+pdfjs-document-properties-version = Kit PDF:
+pdfjs-document-properties-page-count = Kwan me pot buk:
+pdfjs-document-properties-page-size = Dit pa potbuk:
+pdfjs-document-properties-page-size-unit-inches = i
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = atir
+pdfjs-document-properties-page-size-orientation-landscape = arii
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Waraga
+pdfjs-document-properties-page-size-name-legal = Cik
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = Eyo
+pdfjs-document-properties-linearized-no = Pe
+pdfjs-document-properties-close-button = Lor
+
+## Print
+
+pdfjs-print-progress-message = Yubo coc me agoya…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Juki
+pdfjs-printing-not-supported = Ciko: Layeny ma pe teno goyo liweng.
+pdfjs-printing-not-ready = Ciko: PDF pe ocane weng me agoya.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Lok gintic ma inget
+pdfjs-toggle-sidebar-button-label = Lok gintic ma inget
+pdfjs-document-outline-button =
+ .title = Nyut Wiyewiye me Gin acoya (dii-kiryo me yaro/kano jami weng)
+pdfjs-document-outline-button-label = Pek pa gin acoya
+pdfjs-attachments-button =
+ .title = Nyut twec
+pdfjs-attachments-button-label = Twec
+pdfjs-thumbs-button =
+ .title = Nyut cal
+pdfjs-thumbs-button-label = Cal
+pdfjs-findbar-button =
+ .title = Nong iye gin acoya
+pdfjs-findbar-button-label = Nong
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pot buk { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Cal me pot buk { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Nong
+ .placeholder = Nong i dokumen…
+pdfjs-find-previous-button =
+ .title = Nong timme pa lok mukato
+pdfjs-find-previous-button-label = Mukato
+pdfjs-find-next-button =
+ .title = Nong timme pa lok malubo
+pdfjs-find-next-button-label = Malubo
+pdfjs-find-highlight-checkbox = Ket Lanyut I Weng
+pdfjs-find-match-case-checkbox-label = Lok marwate
+pdfjs-find-reached-top = Oo iwi gin acoya, omede ki i tere
+pdfjs-find-reached-bottom = Oo i agiki me gin acoya, omede ki iwiye
+pdfjs-find-not-found = Lok pe ononge
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lac me iye pot buk
+pdfjs-page-scale-fit = Porre me pot buk
+pdfjs-page-scale-auto = Kwot pire kene
+pdfjs-page-scale-actual = Dite kikome
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Bal otime kun cano PDF.
+pdfjs-invalid-file-error = Pwail me PDF ma pe atir onyo obale woko.
+pdfjs-missing-file-error = Pwail me PDF tye ka rem.
+pdfjs-unexpected-response-error = Lagam mape kigeno pa lapok tic.
+pdfjs-rendering-error = Bal otime i kare me nyuto pot buk.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Lok angea manok]
+
+## Password
+
+pdfjs-password-label = Ket mung me donyo me yabo pwail me PDF man.
+pdfjs-password-invalid = Mung me donyo pe atir. Tim ber i tem doki.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Juki
+pdfjs-web-fonts-disabled = Kijuko dit pa coc me kakube woko: pe romo tic ki dit pa coc me PDF ma kiketo i kine.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/af/viewer.ftl b/www/lib/pdfjs/modern/web/locale/af/viewer.ftl
new file mode 100644
index 000000000..7c4346fe0
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/af/viewer.ftl
@@ -0,0 +1,212 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Vorige bladsy
+pdfjs-previous-button-label = Vorige
+pdfjs-next-button =
+ .title = Volgende bladsy
+pdfjs-next-button-label = Volgende
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Bladsy
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = van { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } van { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoem uit
+pdfjs-zoom-out-button-label = Zoem uit
+pdfjs-zoom-in-button =
+ .title = Zoem in
+pdfjs-zoom-in-button-label = Zoem in
+pdfjs-zoom-select =
+ .title = Zoem
+pdfjs-presentation-mode-button =
+ .title = Wissel na voorleggingsmodus
+pdfjs-presentation-mode-button-label = Voorleggingsmodus
+pdfjs-open-file-button =
+ .title = Open lêer
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Druk
+pdfjs-print-button-label = Druk
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Nutsgoed
+pdfjs-tools-button-label = Nutsgoed
+pdfjs-first-page-button =
+ .title = Gaan na eerste bladsy
+pdfjs-first-page-button-label = Gaan na eerste bladsy
+pdfjs-last-page-button =
+ .title = Gaan na laaste bladsy
+pdfjs-last-page-button-label = Gaan na laaste bladsy
+pdfjs-page-rotate-cw-button =
+ .title = Roteer kloksgewys
+pdfjs-page-rotate-cw-button-label = Roteer kloksgewys
+pdfjs-page-rotate-ccw-button =
+ .title = Roteer anti-kloksgewys
+pdfjs-page-rotate-ccw-button-label = Roteer anti-kloksgewys
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktiveer gereedskap om teks te merk
+pdfjs-cursor-text-select-tool-button-label = Teksmerkgereedskap
+pdfjs-cursor-hand-tool-button =
+ .title = Aktiveer handjie
+pdfjs-cursor-hand-tool-button-label = Handjie
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumenteienskappe…
+pdfjs-document-properties-button-label = Dokumenteienskappe…
+pdfjs-document-properties-file-name = Lêernaam:
+pdfjs-document-properties-file-size = Lêergrootte:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kG ({ $size_b } grepe)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MG ({ $size_b } grepe)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Outeur:
+pdfjs-document-properties-subject = Onderwerp:
+pdfjs-document-properties-keywords = Sleutelwoorde:
+pdfjs-document-properties-creation-date = Skeppingsdatum:
+pdfjs-document-properties-modification-date = Wysigingsdatum:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Skepper:
+pdfjs-document-properties-producer = PDF-vervaardiger:
+pdfjs-document-properties-version = PDF-weergawe:
+pdfjs-document-properties-page-count = Aantal bladsye:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = Sluit
+
+## Print
+
+pdfjs-print-progress-message = Berei tans dokument voor om te druk…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Kanselleer
+pdfjs-printing-not-supported = Waarskuwing: Dié blaaier ondersteun nie drukwerk ten volle nie.
+pdfjs-printing-not-ready = Waarskuwing: Die PDF is nog nie volledig gelaai vir drukwerk nie.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Sypaneel aan/af
+pdfjs-toggle-sidebar-button-label = Sypaneel aan/af
+pdfjs-document-outline-button =
+ .title = Wys dokumentskema (dubbelklik om alle items oop/toe te vou)
+pdfjs-document-outline-button-label = Dokumentoorsig
+pdfjs-attachments-button =
+ .title = Wys aanhegsels
+pdfjs-attachments-button-label = Aanhegsels
+pdfjs-thumbs-button =
+ .title = Wys duimnaels
+pdfjs-thumbs-button-label = Duimnaels
+pdfjs-findbar-button =
+ .title = Soek in dokument
+pdfjs-findbar-button-label = Vind
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Bladsy { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Duimnael van bladsy { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Vind
+ .placeholder = Soek in dokument…
+pdfjs-find-previous-button =
+ .title = Vind die vorige voorkoms van die frase
+pdfjs-find-previous-button-label = Vorige
+pdfjs-find-next-button =
+ .title = Vind die volgende voorkoms van die frase
+pdfjs-find-next-button-label = Volgende
+pdfjs-find-highlight-checkbox = Verlig almal
+pdfjs-find-match-case-checkbox-label = Kassensitief
+pdfjs-find-reached-top = Bokant van dokument is bereik; gaan voort van onder af
+pdfjs-find-reached-bottom = Einde van dokument is bereik; gaan voort van bo af
+pdfjs-find-not-found = Frase nie gevind nie
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Bladsywydte
+pdfjs-page-scale-fit = Pas bladsy
+pdfjs-page-scale-auto = Outomatiese zoem
+pdfjs-page-scale-actual = Werklike grootte
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = 'n Fout het voorgekom met die laai van die PDF.
+pdfjs-invalid-file-error = Ongeldige of korrupte PDF-lêer.
+pdfjs-missing-file-error = PDF-lêer is weg.
+pdfjs-unexpected-response-error = Onverwagse antwoord van bediener.
+pdfjs-rendering-error = 'n Fout het voorgekom toe die bladsy weergegee is.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-annotasie]
+
+## Password
+
+pdfjs-password-label = Gee die wagwoord om dié PDF-lêer mee te open.
+pdfjs-password-invalid = Ongeldige wagwoord. Probeer gerus weer.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Kanselleer
+pdfjs-web-fonts-disabled = Webfonte is gedeaktiveer: kan nie PDF-fonte wat ingebed is, gebruik nie.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/an/viewer.ftl b/www/lib/pdfjs/modern/web/locale/an/viewer.ftl
new file mode 100644
index 000000000..673314778
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/an/viewer.ftl
@@ -0,0 +1,257 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pachina anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Pachina siguient
+pdfjs-next-button-label = Siguient
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pachina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Achiquir
+pdfjs-zoom-out-button-label = Achiquir
+pdfjs-zoom-in-button =
+ .title = Agrandir
+pdfjs-zoom-in-button-label = Agrandir
+pdfjs-zoom-select =
+ .title = Grandaria
+pdfjs-presentation-mode-button =
+ .title = Cambear t'o modo de presentación
+pdfjs-presentation-mode-button-label = Modo de presentación
+pdfjs-open-file-button =
+ .title = Ubrir o fichero
+pdfjs-open-file-button-label = Ubrir
+pdfjs-print-button =
+ .title = Imprentar
+pdfjs-print-button-label = Imprentar
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ferramientas
+pdfjs-tools-button-label = Ferramientas
+pdfjs-first-page-button =
+ .title = Ir ta la primer pachina
+pdfjs-first-page-button-label = Ir ta la primer pachina
+pdfjs-last-page-button =
+ .title = Ir ta la zaguer pachina
+pdfjs-last-page-button-label = Ir ta la zaguer pachina
+pdfjs-page-rotate-cw-button =
+ .title = Chirar enta la dreita
+pdfjs-page-rotate-cw-button-label = Chira enta la dreita
+pdfjs-page-rotate-ccw-button =
+ .title = Chirar enta la zurda
+pdfjs-page-rotate-ccw-button-label = Chirar enta la zurda
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar la ferramienta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Ferramienta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar la ferramienta man
+pdfjs-cursor-hand-tool-button-label = Ferramienta man
+pdfjs-scroll-vertical-button =
+ .title = Usar lo desplazamiento vertical
+pdfjs-scroll-vertical-button-label = Desplazamiento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar lo desplazamiento horizontal
+pdfjs-scroll-horizontal-button-label = Desplazamiento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Activaar lo desplazamiento contino
+pdfjs-scroll-wrapped-button-label = Desplazamiento contino
+pdfjs-spread-none-button =
+ .title = No unir vistas de pachinas
+pdfjs-spread-none-button-label = Una pachina nomás
+pdfjs-spread-odd-button =
+ .title = Mostrar vista de pachinas, con as impars a la zurda
+pdfjs-spread-odd-button-label = Doble pachina, impar a la zurda
+pdfjs-spread-even-button =
+ .title = Amostrar vista de pachinas, con as pars a la zurda
+pdfjs-spread-even-button-label = Doble pachina, para a la zurda
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedatz d'o documento...
+pdfjs-document-properties-button-label = Propiedatz d'o documento...
+pdfjs-document-properties-file-name = Nombre de fichero:
+pdfjs-document-properties-file-size = Grandaria d'o fichero:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titol:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Afer:
+pdfjs-document-properties-keywords = Parolas clau:
+pdfjs-document-properties-creation-date = Calendata de creyación:
+pdfjs-document-properties-modification-date = Calendata de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creyador:
+pdfjs-document-properties-producer = Creyador de PDF:
+pdfjs-document-properties-version = Versión de PDF:
+pdfjs-document-properties-page-count = Numero de pachinas:
+pdfjs-document-properties-page-size = Mida de pachina:
+pdfjs-document-properties-page-size-unit-inches = pulgadas
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } x { $height } { $unit } { $orientation }
+pdfjs-document-properties-page-size-dimension-name-string = { $width } x { $height } { $unit } { $name }, { $orientation }
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web rapida:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Zarrar
+
+## Print
+
+pdfjs-print-progress-message = Se ye preparando la documentación pa imprentar…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Pare cuenta: Iste navegador no maneya totalment as impresions.
+pdfjs-printing-not-ready = Aviso: Encara no se ha cargau completament o PDF ta imprentar-lo.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Amostrar u amagar a barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Cambiar barra lateral (lo documento contiene esquema/adchuntos/capas)
+pdfjs-toggle-sidebar-button-label = Amostrar a barra lateral
+pdfjs-document-outline-button =
+ .title = Amostrar esquema d'o documento (fer doble clic pa expandir/compactar totz los items)
+pdfjs-document-outline-button-label = Esquema d'o documento
+pdfjs-attachments-button =
+ .title = Amostrar os adchuntos
+pdfjs-attachments-button-label = Adchuntos
+pdfjs-layers-button =
+ .title = Amostrar capas (doble clic para reiniciar totas las capas a lo estau per defecto)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Amostrar as miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-findbar-button =
+ .title = Trobar en o documento
+pdfjs-findbar-button-label = Trobar
+pdfjs-additional-layers = Capas adicionals
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pachina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura d'a pachina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Trobar
+ .placeholder = Trobar en o documento…
+pdfjs-find-previous-button =
+ .title = Trobar l'anterior coincidencia d'a frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Trobar a siguient coincidencia d'a frase
+pdfjs-find-next-button-label = Siguient
+pdfjs-find-highlight-checkbox = Resaltar-lo tot
+pdfjs-find-match-case-checkbox-label = Coincidencia de mayusclas/minusclas
+pdfjs-find-entire-word-checkbox-label = Parolas completas
+pdfjs-find-reached-top = S'ha plegau a l'inicio d'o documento, se contina dende baixo
+pdfjs-find-reached-bottom = S'ha plegau a la fin d'o documento, se contina dende alto
+pdfjs-find-not-found = No s'ha trobau a frase
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Amplaria d'a pachina
+pdfjs-page-scale-fit = Achuste d'a pachina
+pdfjs-page-scale-auto = Grandaria automatica
+pdfjs-page-scale-actual = Grandaria actual
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = S'ha produciu una error en cargar o PDF.
+pdfjs-invalid-file-error = O PDF no ye valido u ye estorbau.
+pdfjs-missing-file-error = No i ha fichero PDF.
+pdfjs-unexpected-response-error = Respuesta a lo servicio inasperada.
+pdfjs-rendering-error = Ha ocurriu una error en renderizar a pachina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotación { $type }]
+
+## Password
+
+pdfjs-password-label = Introduzca a clau ta ubrir iste fichero PDF.
+pdfjs-password-invalid = Clau invalida. Torna a intentar-lo.
+pdfjs-password-ok-button = Acceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = As fuents web son desactivadas: no se puet incrustar fichers PDF.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ar/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ar/viewer.ftl
new file mode 100644
index 000000000..40b3d2e14
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ar/viewer.ftl
@@ -0,0 +1,264 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = الصÙØØ© السابقة
+pdfjs-previous-button-label = السابقة
+pdfjs-next-button =
+ .title = الصÙØØ© التالية
+pdfjs-next-button-label = التالية
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = صÙØØ©
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = من { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } من { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = بعّد
+pdfjs-zoom-out-button-label = بعّد
+pdfjs-zoom-in-button =
+ .title = قرّب
+pdfjs-zoom-in-button-label = قرّب
+pdfjs-zoom-select =
+ .title = التقريب
+pdfjs-presentation-mode-button =
+ .title = انتقل لوضع العرض التقديمي
+pdfjs-presentation-mode-button-label = وضع العرض التقديمي
+pdfjs-open-file-button =
+ .title = اÙØªØ Ù…Ù„Ùًا
+pdfjs-open-file-button-label = اÙتØ
+pdfjs-print-button =
+ .title = اطبع
+pdfjs-print-button-label = اطبع
+pdfjs-bookmark-button =
+ .title = الصÙØØ© الØالية (عرض URL من الصÙØØ© الØالية)
+pdfjs-bookmark-button-label = الصÙØØ© الØالية
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = الأدوات
+pdfjs-tools-button-label = الأدوات
+pdfjs-first-page-button =
+ .title = انتقل إلى الصÙØØ© الأولى
+pdfjs-first-page-button-label = انتقل إلى الصÙØØ© الأولى
+pdfjs-last-page-button =
+ .title = انتقل إلى الصÙØØ© الأخيرة
+pdfjs-last-page-button-label = انتقل إلى الصÙØØ© الأخيرة
+pdfjs-page-rotate-cw-button =
+ .title = أدر باتجاه عقارب الساعة
+pdfjs-page-rotate-cw-button-label = أدر باتجاه عقارب الساعة
+pdfjs-page-rotate-ccw-button =
+ .title = أدر بعكس اتجاه عقارب الساعة
+pdfjs-page-rotate-ccw-button-label = أدر بعكس اتجاه عقارب الساعة
+pdfjs-cursor-text-select-tool-button =
+ .title = Ùعّل أداة اختيار النص
+pdfjs-cursor-text-select-tool-button-label = أداة اختيار النص
+pdfjs-cursor-hand-tool-button =
+ .title = Ùعّل أداة اليد
+pdfjs-cursor-hand-tool-button-label = أداة اليد
+pdfjs-scroll-vertical-button =
+ .title = استخدم التمرير الرأسي
+pdfjs-scroll-vertical-button-label = التمرير الرأسي
+pdfjs-scroll-horizontal-button =
+ .title = استخدم التمرير الأÙقي
+pdfjs-scroll-horizontal-button-label = التمرير الأÙقي
+pdfjs-scroll-wrapped-button =
+ .title = استخدم التمرير الملتÙ
+pdfjs-scroll-wrapped-button-label = التمرير الملتÙ
+pdfjs-spread-none-button =
+ .title = لا تدمج هوامش الصÙØات مع بعضها البعض
+pdfjs-spread-none-button-label = بلا هوامش
+pdfjs-spread-odd-button =
+ .title = ادمج هوامش الصÙØات الÙردية
+pdfjs-spread-odd-button-label = هوامش الصÙØات الÙردية
+pdfjs-spread-even-button =
+ .title = ادمج هوامش الصÙØات الزوجية
+pdfjs-spread-even-button-label = هوامش الصÙØات الزوجية
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = خصائص المستند…
+pdfjs-document-properties-button-label = خصائص المستند…
+pdfjs-document-properties-file-name = اسم الملÙ:
+pdfjs-document-properties-file-size = Øجم الملÙ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } ك.بايت ({ $size_b } بايت)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } م.بايت ({ $size_b } بايت)
+pdfjs-document-properties-title = العنوان:
+pdfjs-document-properties-author = المؤلÙ:
+pdfjs-document-properties-subject = الموضوع:
+pdfjs-document-properties-keywords = الكلمات الأساسية:
+pdfjs-document-properties-creation-date = تاريخ الإنشاء:
+pdfjs-document-properties-modification-date = تاريخ التعديل:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }، { $time }
+pdfjs-document-properties-creator = المنشئ:
+pdfjs-document-properties-producer = منتج PDF:
+pdfjs-document-properties-version = إصدارة PDF:
+pdfjs-document-properties-page-count = عدد الصÙØات:
+pdfjs-document-properties-page-size = مقاس الورقة:
+pdfjs-document-properties-page-size-unit-inches = بوصة
+pdfjs-document-properties-page-size-unit-millimeters = ملم
+pdfjs-document-properties-page-size-orientation-portrait = طوليّ
+pdfjs-document-properties-page-size-orientation-landscape = عرضيّ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = خطاب
+pdfjs-document-properties-page-size-name-legal = قانونيّ
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = â€{ $width } × â€{ $height } â€{ $unit } (â€{ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = â€{ $width } × â€{ $height } â€{ $unit } (â€{ $name }ØŒ { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = العرض السريع عبر الوÙب:
+pdfjs-document-properties-linearized-yes = نعم
+pdfjs-document-properties-linearized-no = لا
+pdfjs-document-properties-close-button = أغلق
+
+## Print
+
+pdfjs-print-progress-message = ÙŠÙØضّر المستند للطباعة…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }Ùª
+pdfjs-print-progress-close-button = ألغÙ
+pdfjs-printing-not-supported = تØذير: لا يدعم هذا المتصÙØ Ø§Ù„Ø·Ø¨Ø§Ø¹Ø© بشكل كامل.
+pdfjs-printing-not-ready = تØذير: مل٠PDF لم ÙŠÙØمّل كاملًا للطباعة.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = بدّل ظهور الشريط الجانبي
+pdfjs-toggle-sidebar-notification-button =
+ .title = بدّل ظهور الشريط الجانبي (ÙŠØتوي المستند على مخطط أو مرÙقات أو طبقات)
+pdfjs-toggle-sidebar-button-label = بدّل ظهور الشريط الجانبي
+pdfjs-document-outline-button =
+ .title = اعرض Ùهرس المستند (نقر مزدوج لتمديد أو تقليص كل العناصر)
+pdfjs-document-outline-button-label = مخطط المستند
+pdfjs-attachments-button =
+ .title = اعرض المرÙقات
+pdfjs-attachments-button-label = المÙرÙقات
+pdfjs-layers-button =
+ .title = اعرض الطبقات (انقر مرتين لتصÙير كل الطبقات إلى الØالة المبدئية)
+pdfjs-layers-button-label = â€â€Ø§Ù„طبقات
+pdfjs-thumbs-button =
+ .title = اعرض Ù…Ùصغرات
+pdfjs-thumbs-button-label = Ù…Ùصغّرات
+pdfjs-findbar-button =
+ .title = ابØØ« ÙÙŠ المستند
+pdfjs-findbar-button-label = ابØØ«
+pdfjs-additional-layers = الطبقات الإضاÙية
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = صÙØØ© { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = مصغّرة صÙØØ© { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ابØØ«
+ .placeholder = ابØØ« ÙÙŠ المستند…
+pdfjs-find-previous-button =
+ .title = ابØØ« عن التّواجد السّابق للعبارة
+pdfjs-find-previous-button-label = السابق
+pdfjs-find-next-button =
+ .title = ابØØ« عن التّواجد التّالي للعبارة
+pdfjs-find-next-button-label = التالي
+pdfjs-find-highlight-checkbox = أبرÙز الكل
+pdfjs-find-match-case-checkbox-label = طابق Øالة الأØرÙ
+pdfjs-find-entire-word-checkbox-label = كلمات كاملة
+pdfjs-find-reached-top = تابعت من الأسÙÙ„ بعدما وصلت إلى بداية المستند
+pdfjs-find-reached-bottom = تابعت من الأعلى بعدما وصلت إلى نهاية المستند
+pdfjs-find-not-found = لا وجود للعبارة
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = عرض الصÙØØ©
+pdfjs-page-scale-fit = ملائمة الصÙØØ©
+pdfjs-page-scale-auto = تقريب تلقائي
+pdfjs-page-scale-actual = الØجم الÙعلي
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }Ùª
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = صÙØØ© { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Øدث عطل أثناء تØميل مل٠PDF.
+pdfjs-invalid-file-error = مل٠PDF تال٠أو غير صØÙŠØ.
+pdfjs-missing-file-error = مل٠PDF غير موجود.
+pdfjs-unexpected-response-error = استجابة خادوم غير متوقعة.
+pdfjs-rendering-error = Øدث خطأ أثناء عرض الصÙØØ©.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }، { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [تعليق { $type }]
+
+## Password
+
+pdfjs-password-label = أدخل لكلمة السر Ù„ÙØªØ Ù‡Ø°Ø§ الملÙ.
+pdfjs-password-invalid = كلمة سر خطأ. من Ùضلك أعد المØاولة.
+pdfjs-password-ok-button = Øسنا
+pdfjs-password-cancel-button = ألغÙ
+pdfjs-web-fonts-disabled = خطوط الوب Ù…Ùعطّلة: تعذّر استخدام خطوط PDF المÙضمّنة.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ast/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ast/viewer.ftl
new file mode 100644
index 000000000..2503cafce
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ast/viewer.ftl
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Páxina anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Páxina siguiente
+pdfjs-next-button-label = Siguiente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Páxina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Alloñar
+pdfjs-zoom-out-button-label = Alloña
+pdfjs-zoom-in-button =
+ .title = Averar
+pdfjs-zoom-in-button-label = Avera
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Cambiar al mou de presentación
+pdfjs-presentation-mode-button-label = Mou de presentación
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprentar
+pdfjs-print-button-label = Imprentar
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ferramientes
+pdfjs-tools-button-label = Ferramientes
+pdfjs-first-page-button-label = Dir a la primer páxina
+pdfjs-last-page-button-label = Dir a la última páxina
+pdfjs-page-rotate-cw-button =
+ .title = Voltia a la derecha
+pdfjs-page-rotate-cw-button-label = Voltiar a la derecha
+pdfjs-page-rotate-ccw-button =
+ .title = Voltia a la esquierda
+pdfjs-page-rotate-ccw-button-label = Voltiar a la esquierda
+pdfjs-cursor-text-select-tool-button =
+ .title = Activa la ferramienta d'esbilla de testu
+pdfjs-cursor-text-select-tool-button-label = Ferramienta d'esbilla de testu
+pdfjs-cursor-hand-tool-button =
+ .title = Activa la ferramienta de mano
+pdfjs-cursor-hand-tool-button-label = Ferramienta de mano
+pdfjs-scroll-vertical-button =
+ .title = Usa'l desplazamientu vertical
+pdfjs-scroll-vertical-button-label = Desplazamientu vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usa'l desplazamientu horizontal
+pdfjs-scroll-horizontal-button-label = Desplazamientu horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usa'l desplazamientu continuu
+pdfjs-scroll-wrapped-button-label = Desplazamientu continuu
+pdfjs-spread-none-button-label = Fueyes individuales
+pdfjs-spread-odd-button-label = Fueyes pares
+pdfjs-spread-even-button-label = Fueyes impares
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedaes del documentu…
+pdfjs-document-properties-button-label = Propiedaes del documentu…
+pdfjs-document-properties-file-name = Nome del ficheru:
+pdfjs-document-properties-file-size = Tamañu del ficheru:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulu:
+pdfjs-document-properties-keywords = Pallabres clave:
+pdfjs-document-properties-creation-date = Data de creación:
+pdfjs-document-properties-modification-date = Data de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-producer = Productor del PDF:
+pdfjs-document-properties-version = Versión del PDF:
+pdfjs-document-properties-page-count = Númberu de páxines:
+pdfjs-document-properties-page-size = Tamañu de páxina:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web rápida:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = Non
+pdfjs-document-properties-close-button = Zarrar
+
+## Print
+
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Encaboxar
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Alternar la barra llateral
+pdfjs-attachments-button =
+ .title = Amosar los axuntos
+pdfjs-attachments-button-label = Axuntos
+pdfjs-layers-button-label = Capes
+pdfjs-thumbs-button =
+ .title = Amosar les miniatures
+pdfjs-thumbs-button-label = Miniatures
+pdfjs-findbar-button-label = Atopar
+pdfjs-additional-layers = Capes adicionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Páxina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button-label = Siguiente
+pdfjs-find-entire-word-checkbox-label = Pallabres completes
+pdfjs-find-reached-top = Algamóse'l comienzu de la páxina, sÃguese dende abaxo
+pdfjs-find-reached-bottom = Algamóse la fin del documentu, sÃguese dende arriba
+
+## Predefined zoom values
+
+pdfjs-page-scale-auto = Zoom automáticu
+pdfjs-page-scale-actual = Tamañu real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Páxina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Asocedió un fallu mentanto se cargaba'l PDF.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+## Password
+
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Encaboxar
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/az/viewer.ftl b/www/lib/pdfjs/modern/web/locale/az/viewer.ftl
new file mode 100644
index 000000000..773aae4d6
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/az/viewer.ftl
@@ -0,0 +1,257 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ÆvvÉ™lki sÉ™hifÉ™
+pdfjs-previous-button-label = ÆvvÉ™lkini tap
+pdfjs-next-button =
+ .title = Növbəti səhifə
+pdfjs-next-button-label = İrəli
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Səhifə
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = UzaqlaÅŸ
+pdfjs-zoom-out-button-label = UzaqlaÅŸ
+pdfjs-zoom-in-button =
+ .title = Yaxınlaş
+pdfjs-zoom-in-button-label = Yaxınlaş
+pdfjs-zoom-select =
+ .title = Yaxınlaşdırma
+pdfjs-presentation-mode-button =
+ .title = Təqdimat Rejiminə Keç
+pdfjs-presentation-mode-button-label = Təqdimat Rejimi
+pdfjs-open-file-button =
+ .title = Fayl Aç
+pdfjs-open-file-button-label = Aç
+pdfjs-print-button =
+ .title = Yazdır
+pdfjs-print-button-label = Yazdır
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Alətlər
+pdfjs-tools-button-label = Alətlər
+pdfjs-first-page-button =
+ .title = İlk Səhifəyə get
+pdfjs-first-page-button-label = İlk Səhifəyə get
+pdfjs-last-page-button =
+ .title = Son Səhifəyə get
+pdfjs-last-page-button-label = Son Səhifəyə get
+pdfjs-page-rotate-cw-button =
+ .title = Saat İstiqamətində Fırlat
+pdfjs-page-rotate-cw-button-label = Saat İstiqamətində Fırlat
+pdfjs-page-rotate-ccw-button =
+ .title = Saat Ä°stiqamÉ™tinin ÆksinÉ™ Fırlat
+pdfjs-page-rotate-ccw-button-label = Saat Ä°stiqamÉ™tinin ÆksinÉ™ Fırlat
+pdfjs-cursor-text-select-tool-button =
+ .title = Yazı seçmə alətini aktivləşdir
+pdfjs-cursor-text-select-tool-button-label = Yazı seçmə aləti
+pdfjs-cursor-hand-tool-button =
+ .title = Æl alÉ™tini aktivləşdir
+pdfjs-cursor-hand-tool-button-label = Æl alÉ™ti
+pdfjs-scroll-vertical-button =
+ .title = Şaquli sürüşdürmə işlət
+pdfjs-scroll-vertical-button-label = Şaquli sürüşdürmə
+pdfjs-scroll-horizontal-button =
+ .title = Üfüqi sürüşdürmə işlət
+pdfjs-scroll-horizontal-button-label = Üfüqi sürüşdürmə
+pdfjs-scroll-wrapped-button =
+ .title = Bükülü sürüşdürmə işlət
+pdfjs-scroll-wrapped-button-label = Bükülü sürüşdürmə
+pdfjs-spread-none-button =
+ .title = Yan-yana birləşdirilmiş səhifələri işlətmə
+pdfjs-spread-none-button-label = Birləşdirmə
+pdfjs-spread-odd-button =
+ .title = Yan-yana birləşdirilmiş səhifələri tək nömrəli səhifələrdən başlat
+pdfjs-spread-odd-button-label = Tək nömrəli
+pdfjs-spread-even-button =
+ .title = Yan-yana birləşdirilmiş səhifələri cüt nömrəli səhifələrdən başlat
+pdfjs-spread-even-button-label = Cüt nömrəli
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Sənəd xüsusiyyətləri…
+pdfjs-document-properties-button-label = Sənəd xüsusiyyətləri…
+pdfjs-document-properties-file-name = Fayl adı:
+pdfjs-document-properties-file-size = Fayl ölçüsü:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bayt)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bayt)
+pdfjs-document-properties-title = Başlık:
+pdfjs-document-properties-author = Müəllif:
+pdfjs-document-properties-subject = Mövzu:
+pdfjs-document-properties-keywords = Açar sözlər:
+pdfjs-document-properties-creation-date = Yaradılış Tarixi :
+pdfjs-document-properties-modification-date = Dəyişdirilmə Tarixi :
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Yaradan:
+pdfjs-document-properties-producer = PDF yaradıcısı:
+pdfjs-document-properties-version = PDF versiyası:
+pdfjs-document-properties-page-count = Səhifə sayı:
+pdfjs-document-properties-page-size = Səhifə Ölçüsü:
+pdfjs-document-properties-page-size-unit-inches = inç
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portret
+pdfjs-document-properties-page-size-orientation-landscape = albom
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Məktub
+pdfjs-document-properties-page-size-name-legal = Hüquqi
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Bəli
+pdfjs-document-properties-linearized-no = Xeyr
+pdfjs-document-properties-close-button = Qapat
+
+## Print
+
+pdfjs-print-progress-message = Sənəd çap üçün hazırlanır…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Ləğv et
+pdfjs-printing-not-supported = Xəbərdarlıq: Çap bu səyyah tərəfindən tam olaraq dəstəklənmir.
+pdfjs-printing-not-ready = Xəbərdarlıq: PDF çap üçün tam yüklənməyib.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Yan Paneli Aç/Bağla
+pdfjs-toggle-sidebar-notification-button =
+ .title = Yan paneli çevir (sənəddə icmal/bağlamalar/laylar mövcuddur)
+pdfjs-toggle-sidebar-button-label = Yan Paneli Aç/Bağla
+pdfjs-document-outline-button =
+ .title = Sənədin eskizini göstər (bütün bəndləri açmaq/yığmaq üçün iki dəfə klikləyin)
+pdfjs-document-outline-button-label = Sənəd strukturu
+pdfjs-attachments-button =
+ .title = Bağlamaları göstər
+pdfjs-attachments-button-label = BaÄŸlamalar
+pdfjs-layers-button =
+ .title = Layları göstər (bütün layları ilkin halına sıfırlamaq üçün iki dəfə klikləyin)
+pdfjs-layers-button-label = Laylar
+pdfjs-thumbs-button =
+ .title = Kiçik şəkilləri göstər
+pdfjs-thumbs-button-label = Kiçik şəkillər
+pdfjs-findbar-button =
+ .title = Sənəddə Tap
+pdfjs-findbar-button-label = Tap
+pdfjs-additional-layers = ÆlavÉ™ laylar
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Səhifə{ $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } səhifəsinin kiçik vəziyyəti
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Tap
+ .placeholder = Sənəddə tap…
+pdfjs-find-previous-button =
+ .title = Bir öncəki uyğun gələn sözü tapır
+pdfjs-find-previous-button-label = Geri
+pdfjs-find-next-button =
+ .title = Bir sonrakı uyğun gələn sözü tapır
+pdfjs-find-next-button-label = İrəli
+pdfjs-find-highlight-checkbox = İşarələ
+pdfjs-find-match-case-checkbox-label = Böyük/kiçik hərfə həssaslıq
+pdfjs-find-entire-word-checkbox-label = Tam sözlər
+pdfjs-find-reached-top = Sənədin yuxarısına çatdı, aşağıdan davam edir
+pdfjs-find-reached-bottom = Sənədin sonuna çatdı, yuxarıdan davam edir
+pdfjs-find-not-found = Uyğunlaşma tapılmadı
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Səhifə genişliyi
+pdfjs-page-scale-fit = Səhifəni sığdır
+pdfjs-page-scale-auto = Avtomatik yaxınlaşdır
+pdfjs-page-scale-actual = Hazırkı Həcm
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF yüklenərkən bir səhv yarandı.
+pdfjs-invalid-file-error = Səhv və ya zədələnmiş olmuş PDF fayl.
+pdfjs-missing-file-error = PDF fayl yoxdur.
+pdfjs-unexpected-response-error = Gözlənilməz server cavabı.
+pdfjs-rendering-error = Səhifə göstərilərkən səhv yarandı.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotasiyası]
+
+## Password
+
+pdfjs-password-label = Bu PDF faylı açmaq üçün parolu daxil edin.
+pdfjs-password-invalid = Parol səhvdir. Bir daha yoxlayın.
+pdfjs-password-ok-button = Tamam
+pdfjs-password-cancel-button = Ləğv et
+pdfjs-web-fonts-disabled = Web Şriftlər söndürülüb: yerləşdirilmiş PDF şriftlərini istifadə etmək mümkün deyil.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/be/viewer.ftl b/www/lib/pdfjs/modern/web/locale/be/viewer.ftl
new file mode 100644
index 000000000..8610474ca
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/be/viewer.ftl
@@ -0,0 +1,386 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ПапÑÑ€ÑднÑÑ Ñтаронка
+pdfjs-previous-button-label = ПапÑÑ€ÑднÑÑ
+pdfjs-next-button =
+ .title = ÐаÑÑ‚ÑƒÐ¿Ð½Ð°Ñ Ñтаронка
+pdfjs-next-button-label = ÐаÑтупнаÑ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Старонка
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = з { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } з { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Паменшыць
+pdfjs-zoom-out-button-label = Паменшыць
+pdfjs-zoom-in-button =
+ .title = ПавÑлічыць
+pdfjs-zoom-in-button-label = ПавÑлічыць
+pdfjs-zoom-select =
+ .title = ПавÑлічÑнне Ñ‚ÑкÑту
+pdfjs-presentation-mode-button =
+ .title = Пераключыцца Ñž Ñ€Ñжым паказу
+pdfjs-presentation-mode-button-label = Ð Ñжым паказу
+pdfjs-open-file-button =
+ .title = Ðдкрыць файл
+pdfjs-open-file-button-label = Ðдкрыць
+pdfjs-print-button =
+ .title = Друкаваць
+pdfjs-print-button-label = Друкаваць
+pdfjs-save-button =
+ .title = Захаваць
+pdfjs-save-button-label = Захаваць
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = СцÑгнуць
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = СцÑгнуць
+pdfjs-bookmark-button =
+ .title = Ð”Ð·ÐµÐ¹Ð½Ð°Ñ Ñтаронка (паглÑдзець URL-Ð°Ð´Ñ€Ð°Ñ Ð· дзейнай Ñтаронкі)
+pdfjs-bookmark-button-label = ЦÑперашнÑÑ Ñтаронка
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ðдкрыць у праграме
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ðдкрыць у праграме
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Прылады
+pdfjs-tools-button-label = Прылады
+pdfjs-first-page-button =
+ .title = ПерайÑці на першую Ñтаронку
+pdfjs-first-page-button-label = ПерайÑці на першую Ñтаронку
+pdfjs-last-page-button =
+ .title = ПерайÑці на апошнюю Ñтаронку
+pdfjs-last-page-button-label = ПерайÑці на апошнюю Ñтаронку
+pdfjs-page-rotate-cw-button =
+ .title = ПавÑрнуць па Ñонцу
+pdfjs-page-rotate-cw-button-label = ПавÑрнуць па Ñонцу
+pdfjs-page-rotate-ccw-button =
+ .title = ПавÑрнуць Ñупраць Ñонца
+pdfjs-page-rotate-ccw-button-label = ПавÑрнуць Ñупраць Ñонца
+pdfjs-cursor-text-select-tool-button =
+ .title = Уключыць прыладу выбару Ñ‚ÑкÑту
+pdfjs-cursor-text-select-tool-button-label = Прылада выбару Ñ‚ÑкÑту
+pdfjs-cursor-hand-tool-button =
+ .title = Уключыць ручную прыладу
+pdfjs-cursor-hand-tool-button-label = Ð ÑƒÑ‡Ð½Ð°Ñ Ð¿Ñ€Ñ‹Ð»Ð°Ð´Ð°
+pdfjs-scroll-page-button =
+ .title = ВыкарыÑтоўваць пракрутку Ñтаронкi
+pdfjs-scroll-page-button-label = Пракрутка Ñтаронкi
+pdfjs-scroll-vertical-button =
+ .title = Ужываць вертыкальную пракрутку
+pdfjs-scroll-vertical-button-label = Ð’ÐµÑ€Ñ‚Ñ‹ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð°ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-scroll-horizontal-button =
+ .title = Ужываць гарызантальную пракрутку
+pdfjs-scroll-horizontal-button-label = Ð“Ð°Ñ€Ñ‹Ð·Ð°Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð°ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-scroll-wrapped-button =
+ .title = Ужываць маштабавальную пракрутку
+pdfjs-scroll-wrapped-button-label = ÐœÐ°ÑˆÑ‚Ð°Ð±Ð°Ð²Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð°ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-spread-none-button =
+ .title = Ðе выкарыÑтоўваць Ñ€Ð°Ð·Ð³Ð¾Ñ€Ð½ÑƒÑ‚Ñ‹Ñ Ñтаронкі
+pdfjs-spread-none-button-label = Без разгорнутых Ñтаронак
+pdfjs-spread-odd-button =
+ .title = Ð Ð°Ð·Ð³Ð¾Ñ€Ð½ÑƒÑ‚Ñ‹Ñ Ñтаронкі пачынаючы з нÑцотных нумароў
+pdfjs-spread-odd-button-label = ÐÑÑ†Ð¾Ñ‚Ð½Ñ‹Ñ Ñтаронкі злева
+pdfjs-spread-even-button =
+ .title = Ð Ð°Ð·Ð³Ð¾Ñ€Ð½ÑƒÑ‚Ñ‹Ñ Ñтаронкі пачынаючы з цотных нумароў
+pdfjs-spread-even-button-label = Ð¦Ð¾Ñ‚Ð½Ñ‹Ñ Ñтаронкі злева
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = УлаÑціваÑці дакумента…
+pdfjs-document-properties-button-label = УлаÑціваÑці дакумента…
+pdfjs-document-properties-file-name = Ðазва файла:
+pdfjs-document-properties-file-size = Памер файла:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } байт)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } байт)
+pdfjs-document-properties-title = Загаловак:
+pdfjs-document-properties-author = Ðўтар:
+pdfjs-document-properties-subject = ТÑма:
+pdfjs-document-properties-keywords = ÐšÐ»ÑŽÑ‡Ð°Ð²Ñ‹Ñ Ñловы:
+pdfjs-document-properties-creation-date = Дата ÑтварÑннÑ:
+pdfjs-document-properties-modification-date = Дата змÑненнÑ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Стваральнік:
+pdfjs-document-properties-producer = Вырабнік PDF:
+pdfjs-document-properties-version = ВерÑÑ–Ñ PDF:
+pdfjs-document-properties-page-count = КолькаÑць Ñтаронак:
+pdfjs-document-properties-page-size = Памер Ñтаронкі:
+pdfjs-document-properties-page-size-unit-inches = цалÑÑž
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = кніжнаÑ
+pdfjs-document-properties-page-size-orientation-landscape = альбомнаÑ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Хуткі праглÑд у ІнтÑрнÑце:
+pdfjs-document-properties-linearized-yes = Так
+pdfjs-document-properties-linearized-no = Ðе
+pdfjs-document-properties-close-button = Закрыць
+
+## Print
+
+pdfjs-print-progress-message = Падрыхтоўка дакумента да друку…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = СкаÑаваць
+pdfjs-printing-not-supported = ПапÑÑ€Ñджанне: друк не падтрымліваецца цалкам гÑтым браўзерам.
+pdfjs-printing-not-ready = Увага: PDF не ÑцÑгнуты цалкам Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÐ°Ð²Ð°Ð½Ð½Ñ.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Паказаць/Ñхаваць бакавую панÑль
+pdfjs-toggle-sidebar-notification-button =
+ .title = Паказаць/Ñхаваць бакавую панÑль (дакумент мае змеÑÑ‚/укладанні/плаÑÑ‚Ñ‹)
+pdfjs-toggle-sidebar-button-label = Паказаць/Ñхаваць бакавую панÑль
+pdfjs-document-outline-button =
+ .title = Паказаць Ñтруктуру дакумента (Ð´Ð²Ð°Ð¹Ð½Ð°Ñ Ð¿Ñтрычка, каб разгарнуць /згарнуць уÑе Ñлементы)
+pdfjs-document-outline-button-label = Структура дакумента
+pdfjs-attachments-button =
+ .title = Паказаць далучÑнні
+pdfjs-attachments-button-label = ДалучÑнні
+pdfjs-layers-button =
+ .title = Паказаць плаÑÑ‚Ñ‹ (націÑніце двойчы, каб Ñкінуць уÑе плаÑÑ‚Ñ‹ да прадвызначанага Ñтану)
+pdfjs-layers-button-label = ПлаÑÑ‚Ñ‹
+pdfjs-thumbs-button =
+ .title = Паказ мініÑцюр
+pdfjs-thumbs-button-label = МініÑцюры
+pdfjs-current-outline-item-button =
+ .title = ЗнайÑці бÑгучы Ñлемент Ñтруктуры
+pdfjs-current-outline-item-button-label = БÑгучы Ñлемент Ñтруктуры
+pdfjs-findbar-button =
+ .title = Пошук у дакуменце
+pdfjs-findbar-button-label = ЗнайÑці
+pdfjs-additional-layers = Ð”Ð°Ð´Ð°Ñ‚ÐºÐ¾Ð²Ñ‹Ñ Ð¿Ð»Ð°ÑÑ‚Ñ‹
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Старонка { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = МініÑцюра Ñтаронкі { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Шукаць
+ .placeholder = Шукаць у дакуменце…
+pdfjs-find-previous-button =
+ .title = ЗнайÑці папÑÑ€Ñдні выпадак выразу
+pdfjs-find-previous-button-label = ПапÑÑ€Ñдні
+pdfjs-find-next-button =
+ .title = ЗнайÑці наÑтупны выпадак выразу
+pdfjs-find-next-button-label = ÐаÑтупны
+pdfjs-find-highlight-checkbox = Падфарбаваць уÑе
+pdfjs-find-match-case-checkbox-label = Ðдрозніваць вÑлікіÑ/Ð¼Ð°Ð»Ñ‹Ñ Ð»Ñ–Ñ‚Ð°Ñ€Ñ‹
+pdfjs-find-match-diacritics-checkbox-label = З улікам дыÑкрытык
+pdfjs-find-entire-word-checkbox-label = Словы цалкам
+pdfjs-find-reached-top = ДаÑÑгнуты пачатак дакумента, працÑг з канца
+pdfjs-find-reached-bottom = ДаÑÑгнуты канец дакумента, працÑг з пачатку
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } з { $total } ÑупадзеннÑÑž
+ [few] { $current } з { $total } ÑупадзеннÑÑž
+ *[many] { $current } з { $total } ÑупадзеннÑÑž
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Больш за { $limit } Ñупадзенне
+ [few] Больш за { $limit } Ñупадзенні
+ *[many] Больш за { $limit } ÑупадзеннÑÑž
+ }
+pdfjs-find-not-found = Выраз не знойдзены
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ð¨Ñ‹Ñ€Ñ‹Ð½Ñ Ñтаронкі
+pdfjs-page-scale-fit = УціÑненне Ñтаронкі
+pdfjs-page-scale-auto = Ðўтаматычнае павелічÑнне
+pdfjs-page-scale-actual = Сапраўдны памер
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Старонка { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = ЗдарылаÑÑ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° ў чаÑе загрузкі PDF.
+pdfjs-invalid-file-error = ÐÑÑпраўны або пашкоджаны файл PDF.
+pdfjs-missing-file-error = ÐдÑутны файл PDF.
+pdfjs-unexpected-response-error = Ðечаканы адказ Ñервера.
+pdfjs-rendering-error = ЗдарылаÑÑ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ° Ð¿Ð°Ð´Ñ‡Ð°Ñ Ð°Ð´Ð»ÑŽÑÑ‚Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ñтаронкі.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = УвÑдзіце пароль, каб адкрыць гÑÑ‚Ñ‹ файл PDF.
+pdfjs-password-invalid = ÐÑдзейÑны пароль. ПаÑпрабуйце зноў.
+pdfjs-password-ok-button = Добра
+pdfjs-password-cancel-button = СкаÑаваць
+pdfjs-web-fonts-disabled = Шрыфты Сеціва забаронены: немагчыма ўжываць ÑƒÐºÐ»Ð°Ð´Ð·ÐµÐ½Ñ‹Ñ ÑˆÑ€Ñ‹Ñ„Ñ‚Ñ‹ PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ТÑкÑÑ‚
+pdfjs-editor-free-text-button-label = ТÑкÑÑ‚
+pdfjs-editor-ink-button =
+ .title = МалÑваць
+pdfjs-editor-ink-button-label = МалÑваць
+pdfjs-editor-stamp-button =
+ .title = Дадаць або змÑніць выÑвы
+pdfjs-editor-stamp-button-label = Дадаць або змÑніць выÑвы
+pdfjs-editor-remove-button =
+ .title = Выдаліць
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Выдаліць малюнак
+pdfjs-editor-remove-freetext-button =
+ .title = Выдаліць Ñ‚ÑкÑÑ‚
+pdfjs-editor-remove-stamp-button =
+ .title = Выдаліць выÑву
+pdfjs-editor-remove-highlight-button =
+ .title = Выдаліць падфарбоўку
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Колер
+pdfjs-editor-free-text-size-input = Памер
+pdfjs-editor-ink-color-input = Колер
+pdfjs-editor-ink-thickness-input = ТаўшчынÑ
+pdfjs-editor-ink-opacity-input = ÐепразрыÑтаÑць
+pdfjs-editor-stamp-add-image-button =
+ .title = Дадаць выÑву
+pdfjs-editor-stamp-add-image-button-label = Дадаць выÑву
+pdfjs-free-text =
+ .aria-label = ТÑкÑтавы Ñ€Ñдактар
+pdfjs-free-text-default-content = Пачніце набор Ñ‚ÑкÑту…
+pdfjs-ink =
+ .aria-label = Графічны Ñ€Ñдактар
+pdfjs-ink-canvas =
+ .aria-label = Ð’Ñ‹Ñва, ÑÑ‚Ð²Ð¾Ñ€Ð°Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‹Ñтальнікам
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = ÐльтÑрнатыўны Ñ‚ÑкÑÑ‚
+pdfjs-editor-alt-text-edit-button-label = ЗмÑніць альтÑрнатыўны Ñ‚ÑкÑÑ‚
+pdfjs-editor-alt-text-dialog-label = Выберыце варыÑнт
+pdfjs-editor-alt-text-dialog-description = ÐльтÑрнатыўны Ñ‚ÑкÑÑ‚ дапамагае, калі людзі не бачаць выÑву або калі Ñна не загружаецца.
+pdfjs-editor-alt-text-add-description-label = Дадаць апіÑанне
+pdfjs-editor-alt-text-add-description-description = СтарайцеÑÑ ÑклаÑці 1-2 Ñказы, ÑÐºÑ–Ñ Ð°Ð¿Ñ–Ñваюць прадмет, абÑтаноўку або дзеÑнні.
+pdfjs-editor-alt-text-mark-decorative-label = Пазначыць Ñк дÑкаратыўны
+pdfjs-editor-alt-text-mark-decorative-description = ВыкарыÑтоўваецца Ð´Ð»Ñ Ð´Ñкаратыўных выÑваў, такіх Ñк рамкі або вадзÑÐ½Ñ‹Ñ Ð·Ð½Ð°ÐºÑ–.
+pdfjs-editor-alt-text-cancel-button = СкаÑаваць
+pdfjs-editor-alt-text-save-button = Захаваць
+pdfjs-editor-alt-text-decorative-tooltip = Пазначаны Ñк дÑкаратыўны
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Ðапрыклад, «Малады чалавек Ñадзіцца за Ñтол еÑці»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Верхні левы кут — змÑніць памер
+pdfjs-editor-resizer-label-top-middle = УверÑе паÑÑÑ€Ñдзіне — змÑніць памер
+pdfjs-editor-resizer-label-top-right = Верхні правы кут — змÑніць памер
+pdfjs-editor-resizer-label-middle-right = ПаÑÑÑ€Ñдзіне Ñправа — змÑніць памер
+pdfjs-editor-resizer-label-bottom-right = Правы ніжні кут — змÑніць памер
+pdfjs-editor-resizer-label-bottom-middle = ПаÑÑÑ€Ñдзіне ўнізе — змÑніць памер
+pdfjs-editor-resizer-label-bottom-left = Левы ніжні кут — змÑніць памер
+pdfjs-editor-resizer-label-middle-left = ПаÑÑÑ€Ñдзіне злева — змÑніць памер
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Колер падфарбоўкі
+pdfjs-editor-colorpicker-button =
+ .title = ЗмÑніць колер
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Выбар колеру
+pdfjs-editor-colorpicker-yellow =
+ .title = Жоўты
+pdfjs-editor-colorpicker-green =
+ .title = ЗÑлёны
+pdfjs-editor-colorpicker-blue =
+ .title = Блакітны
+pdfjs-editor-colorpicker-pink =
+ .title = Ружовы
+pdfjs-editor-colorpicker-red =
+ .title = Чырвоны
diff --git a/www/lib/pdfjs/modern/web/locale/bg/viewer.ftl b/www/lib/pdfjs/modern/web/locale/bg/viewer.ftl
new file mode 100644
index 000000000..d58e343f5
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/bg/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Предишна Ñтраница
+pdfjs-previous-button-label = Предишна
+pdfjs-next-button =
+ .title = Следваща Ñтраница
+pdfjs-next-button-label = Следваща
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Страница
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = от { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } от { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ÐамалÑване
+pdfjs-zoom-out-button-label = ÐамалÑване
+pdfjs-zoom-in-button =
+ .title = Увеличаване
+pdfjs-zoom-in-button-label = Увеличаване
+pdfjs-zoom-select =
+ .title = Мащабиране
+pdfjs-presentation-mode-button =
+ .title = Превключване към режим на предÑтавÑне
+pdfjs-presentation-mode-button-label = Режим на предÑтавÑне
+pdfjs-open-file-button =
+ .title = ОтварÑне на файл
+pdfjs-open-file-button-label = ОтварÑне
+pdfjs-print-button =
+ .title = Отпечатване
+pdfjs-print-button-label = Отпечатване
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ИнÑтрументи
+pdfjs-tools-button-label = ИнÑтрументи
+pdfjs-first-page-button =
+ .title = Към първата Ñтраница
+pdfjs-first-page-button-label = Към първата Ñтраница
+pdfjs-last-page-button =
+ .title = Към поÑледната Ñтраница
+pdfjs-last-page-button-label = Към поÑледната Ñтраница
+pdfjs-page-rotate-cw-button =
+ .title = Завъртане по чаÑ. Ñтрелка
+pdfjs-page-rotate-cw-button-label = Завъртане по чаÑовниковата Ñтрелка
+pdfjs-page-rotate-ccw-button =
+ .title = Завъртане обратно на чаÑ. Ñтрелка
+pdfjs-page-rotate-ccw-button-label = Завъртане обратно на чаÑовниковата Ñтрелка
+pdfjs-cursor-text-select-tool-button =
+ .title = Включване на инÑтрумента за избор на текÑÑ‚
+pdfjs-cursor-text-select-tool-button-label = ИнÑтрумент за избор на текÑÑ‚
+pdfjs-cursor-hand-tool-button =
+ .title = Включване на инÑтрумента ръка
+pdfjs-cursor-hand-tool-button-label = ИнÑтрумент ръка
+pdfjs-scroll-vertical-button =
+ .title = Използване на вертикално плъзгане
+pdfjs-scroll-vertical-button-label = Вертикално плъзгане
+pdfjs-scroll-horizontal-button =
+ .title = Използване на хоризонтално
+pdfjs-scroll-horizontal-button-label = Хоризонтално плъзгане
+pdfjs-scroll-wrapped-button =
+ .title = Използване на мащабируемо плъзгане
+pdfjs-scroll-wrapped-button-label = Мащабируемо плъзгане
+pdfjs-spread-none-button =
+ .title = Режимът на ÑдвоÑване е изключен
+pdfjs-spread-none-button-label = Без ÑдвоÑване
+pdfjs-spread-odd-button =
+ .title = СдвоÑване, започвайки от нечетните Ñтраници
+pdfjs-spread-odd-button-label = Ðечетните отлÑво
+pdfjs-spread-even-button =
+ .title = СдвоÑване, започвайки от четните Ñтраници
+pdfjs-spread-even-button-label = Четните отлÑво
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = СвойÑтва на документа…
+pdfjs-document-properties-button-label = СвойÑтва на документа…
+pdfjs-document-properties-file-name = Име на файл:
+pdfjs-document-properties-file-size = Големина на файл:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } байта)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } байта)
+pdfjs-document-properties-title = Заглавие:
+pdfjs-document-properties-author = Ðвтор:
+pdfjs-document-properties-subject = Тема:
+pdfjs-document-properties-keywords = Ключови думи:
+pdfjs-document-properties-creation-date = Дата на Ñъздаване:
+pdfjs-document-properties-modification-date = Дата на промÑна:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Създател:
+pdfjs-document-properties-producer = PDF произведен от:
+pdfjs-document-properties-version = Издание на PDF:
+pdfjs-document-properties-page-count = Брой Ñтраници:
+pdfjs-document-properties-page-size = Размер на Ñтраницата:
+pdfjs-document-properties-page-size-unit-inches = инч
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = портрет
+pdfjs-document-properties-page-size-orientation-landscape = пейзаж
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Правни въпроÑи
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Бърз преглед:
+pdfjs-document-properties-linearized-yes = Да
+pdfjs-document-properties-linearized-no = Ðе
+pdfjs-document-properties-close-button = ЗатварÑне
+
+## Print
+
+pdfjs-print-progress-message = ПодготвÑне на документа за отпечатване…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Отказ
+pdfjs-printing-not-supported = Внимание: Този четец нÑма пълна поддръжка на отпечатване.
+pdfjs-printing-not-ready = Внимание: Този PDF файл не е напълно зареден за печат.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Превключване на Ñтраничната лента
+pdfjs-toggle-sidebar-button-label = Превключване на Ñтраничната лента
+pdfjs-document-outline-button =
+ .title = Показване на Ñтруктурата на документа (двукратно щракване за Ñвиване/разгъване на вÑичко)
+pdfjs-document-outline-button-label = Структура на документа
+pdfjs-attachments-button =
+ .title = Показване на притурките
+pdfjs-attachments-button-label = Притурки
+pdfjs-thumbs-button =
+ .title = Показване на миниатюрите
+pdfjs-thumbs-button-label = Миниатюри
+pdfjs-findbar-button =
+ .title = Ðамиране в документа
+pdfjs-findbar-button-label = ТърÑене
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Страница { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Миниатюра на Ñтраница { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ТърÑене
+ .placeholder = ТърÑене в документа…
+pdfjs-find-previous-button =
+ .title = Ðамиране на предишно Ñъвпадение на фразата
+pdfjs-find-previous-button-label = Предишна
+pdfjs-find-next-button =
+ .title = Ðамиране на Ñледващо Ñъвпадение на фразата
+pdfjs-find-next-button-label = Следваща
+pdfjs-find-highlight-checkbox = ОткроÑване на вÑички
+pdfjs-find-match-case-checkbox-label = Съвпадение на региÑтъра
+pdfjs-find-entire-word-checkbox-label = Цели думи
+pdfjs-find-reached-top = ДоÑтигнато е началото на документа, продължаване от краÑ
+pdfjs-find-reached-bottom = ДоÑтигнат е краÑÑ‚ на документа, продължаване от началото
+pdfjs-find-not-found = Фразата не е намерена
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ширина на Ñтраницата
+pdfjs-page-scale-fit = ВмеÑтване в Ñтраницата
+pdfjs-page-scale-auto = Ðвтоматично мащабиране
+pdfjs-page-scale-actual = ДейÑтвителен размер
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Получи Ñе грешка при зареждане на PDF-а.
+pdfjs-invalid-file-error = Ðевалиден или повреден PDF файл.
+pdfjs-missing-file-error = ЛипÑващ PDF файл.
+pdfjs-unexpected-response-error = Ðеочакван отговор от Ñървъра.
+pdfjs-rendering-error = Грешка при изчертаване на Ñтраницата.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ { $type }]
+
+## Password
+
+pdfjs-password-label = Въведете парола за отварÑне на този PDF файл.
+pdfjs-password-invalid = Ðевалидна парола. МолÑ, опитайте отново.
+pdfjs-password-ok-button = Добре
+pdfjs-password-cancel-button = Отказ
+pdfjs-web-fonts-disabled = Уеб-шрифтовете Ñа забранени: разрешаване на използването на вградените PDF шрифтове.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/bn/viewer.ftl b/www/lib/pdfjs/modern/web/locale/bn/viewer.ftl
new file mode 100644
index 000000000..1e20ecb83
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/bn/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = পূরà§à¦¬à¦¬à¦°à§à¦¤à§€ পাতা
+pdfjs-previous-button-label = পূরà§à¦¬à¦¬à¦°à§à¦¤à§€
+pdfjs-next-button =
+ .title = পরবরà§à¦¤à§€ পাতা
+pdfjs-next-button-label = পরবরà§à¦¤à§€
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = পাতা
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } à¦à¦°
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } à¦à¦° { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = ছোট আকারে পà§à¦°à¦¦à¦°à§à¦¶à¦¨
+pdfjs-zoom-out-button-label = ছোট আকারে পà§à¦°à¦¦à¦°à§à¦¶à¦¨
+pdfjs-zoom-in-button =
+ .title = বড় আকারে পà§à¦°à¦¦à¦°à§à¦¶à¦¨
+pdfjs-zoom-in-button-label = বড় আকারে পà§à¦°à¦¦à¦°à§à¦¶à¦¨
+pdfjs-zoom-select =
+ .title = বড় আকারে পà§à¦°à¦¦à¦°à§à¦¶à¦¨
+pdfjs-presentation-mode-button =
+ .title = উপসà§à¦¥à¦¾à¦ªà¦¨à¦¾ মোডে সà§à¦¯à§à¦‡à¦š করà§à¦¨
+pdfjs-presentation-mode-button-label = উপসà§à¦¥à¦¾à¦ªà¦¨à¦¾ মোড
+pdfjs-open-file-button =
+ .title = ফাইল খà§à¦²à§à¦¨
+pdfjs-open-file-button-label = খà§à¦²à§à¦¨
+pdfjs-print-button =
+ .title = মà§à¦¦à§à¦°à¦£
+pdfjs-print-button-label = মà§à¦¦à§à¦°à¦£
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = টà§à¦²
+pdfjs-tools-button-label = টà§à¦²
+pdfjs-first-page-button =
+ .title = পà§à¦°à¦¥à¦® পাতায় যাও
+pdfjs-first-page-button-label = পà§à¦°à¦¥à¦® পাতায় যাও
+pdfjs-last-page-button =
+ .title = শেষ পাতায় যাও
+pdfjs-last-page-button-label = শেষ পাতায় যাও
+pdfjs-page-rotate-cw-button =
+ .title = ঘড়ির কাà¦à¦Ÿà¦¾à¦° দিকে ঘোরাও
+pdfjs-page-rotate-cw-button-label = ঘড়ির কাà¦à¦Ÿà¦¾à¦° দিকে ঘোরাও
+pdfjs-page-rotate-ccw-button =
+ .title = ঘড়ির কাà¦à¦Ÿà¦¾à¦° বিপরীতে ঘোরাও
+pdfjs-page-rotate-ccw-button-label = ঘড়ির কাà¦à¦Ÿà¦¾à¦° বিপরীতে ঘোরাও
+pdfjs-cursor-text-select-tool-button =
+ .title = লেখা নিরà§à¦¬à¦¾à¦šà¦• টà§à¦² সকà§à¦°à¦¿à§Ÿ করà§à¦¨
+pdfjs-cursor-text-select-tool-button-label = লেখা নিরà§à¦¬à¦¾à¦šà¦• টà§à¦²
+pdfjs-cursor-hand-tool-button =
+ .title = হà§à¦¯à¦¾à¦¨à§à¦¡ টà§à¦² সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨
+pdfjs-cursor-hand-tool-button-label = হà§à¦¯à¦¾à¦¨à§à¦¡ টà§à¦²
+pdfjs-scroll-vertical-button =
+ .title = উলমà§à¦¬ সà§à¦•à§à¦°à¦²à¦¿à¦‚ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨
+pdfjs-scroll-vertical-button-label = উলমà§à¦¬ সà§à¦•à§à¦°à¦²à¦¿à¦‚
+pdfjs-scroll-horizontal-button =
+ .title = অনà§à¦à§‚মিক সà§à¦•à§à¦°à¦²à¦¿à¦‚ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨
+pdfjs-scroll-horizontal-button-label = অনà§à¦à§‚মিক সà§à¦•à§à¦°à¦²à¦¿à¦‚
+pdfjs-scroll-wrapped-button =
+ .title = Wrapped সà§à¦•à§à¦°à§‹à¦²à¦¿à¦‚ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨
+pdfjs-scroll-wrapped-button-label = Wrapped সà§à¦•à§à¦°à§‹à¦²à¦¿à¦‚
+pdfjs-spread-none-button =
+ .title = পেজ সà§à¦ªà§à¦°à§‡à¦¡à¦—à§à¦²à§‹à¦¤à§‡ যোগদান করবেন না
+pdfjs-spread-none-button-label = Spreads নেই
+pdfjs-spread-odd-button-label = বিজোড় Spreads
+pdfjs-spread-even-button-label = জোড় Spreads
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = নথি বৈশিষà§à¦Ÿà§à¦¯â€¦
+pdfjs-document-properties-button-label = নথি বৈশিষà§à¦Ÿà§à¦¯â€¦
+pdfjs-document-properties-file-name = ফাইলের নাম:
+pdfjs-document-properties-file-size = ফাইলের আকার:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } কেবি ({ $size_b } বাইট)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } à¦à¦®à¦¬à¦¿ ({ $size_b } বাইট)
+pdfjs-document-properties-title = শিরোনাম:
+pdfjs-document-properties-author = লেখক:
+pdfjs-document-properties-subject = বিষয়:
+pdfjs-document-properties-keywords = কীওয়ারà§à¦¡:
+pdfjs-document-properties-creation-date = তৈরির তারিখ:
+pdfjs-document-properties-modification-date = পরিবরà§à¦¤à¦¨à§‡à¦° তারিখ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = পà§à¦°à¦¸à§à¦¤à§à¦¤à¦•à¦¾à¦°à¦•:
+pdfjs-document-properties-producer = পিডিà¦à¦« পà§à¦°à¦¸à§à¦¤à§à¦¤à¦•à¦¾à¦°à¦•:
+pdfjs-document-properties-version = পিডিà¦à¦« সংষà§à¦•à¦°à¦£:
+pdfjs-document-properties-page-count = মোট পাতা:
+pdfjs-document-properties-page-size = পাতার সাইজ:
+pdfjs-document-properties-page-size-unit-inches = à¦à¦° মধà§à¦¯à§‡
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = উলমà§à¦¬
+pdfjs-document-properties-page-size-orientation-landscape = অনà§à¦à§‚মিক
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = লেটার
+pdfjs-document-properties-page-size-name-legal = লীগাল
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = হà§à¦¯à¦¾à¦
+pdfjs-document-properties-linearized-no = না
+pdfjs-document-properties-close-button = বনà§à¦§
+
+## Print
+
+pdfjs-print-progress-message = মà§à¦¦à§à¦°à¦£à§‡à¦° জনà§à¦¯ নথি পà§à¦°à¦¸à§à¦¤à§à¦¤ করা হচà§à¦›à§‡â€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = বাতিল
+pdfjs-printing-not-supported = সতরà§à¦•à¦¤à¦¾: à¦à¦‡ বà§à¦°à¦¾à¦‰à¦œà¦¾à¦°à§‡ মà§à¦¦à§à¦°à¦£ সমà§à¦ªà§‚রà§à¦£à¦à¦¾à¦¬à§‡ সমরà§à¦¥à¦¿à¦¤ নয়।
+pdfjs-printing-not-ready = সতরà§à¦•à§€à¦•à¦°à¦£: পিডিà¦à¦«à¦Ÿà¦¿ মà§à¦¦à§à¦°à¦£à§‡à¦° জনà§à¦¯ সমà§à¦ªà§‚রà§à¦£ লোড হয়নি।
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = সাইডবার টগল করà§à¦¨
+pdfjs-toggle-sidebar-button-label = সাইডবার টগল করà§à¦¨
+pdfjs-document-outline-button =
+ .title = নথির আউটলাইন দেখাও (সব আইটেম পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤/সঙà§à¦•à§à¦šà¦¿à¦¤ করতে ডবল কà§à¦²à¦¿à¦• করà§à¦¨)
+pdfjs-document-outline-button-label = নথির রূপরেখা
+pdfjs-attachments-button =
+ .title = সংযà§à¦•à§à¦¤à¦¿ দেখাও
+pdfjs-attachments-button-label = সংযà§à¦•à§à¦¤à¦¿
+pdfjs-thumbs-button =
+ .title = থামà§à¦¬à¦¨à§‡à¦‡à¦² সমূহ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨
+pdfjs-thumbs-button-label = থামà§à¦¬à¦¨à§‡à¦‡à¦² সমূহ
+pdfjs-findbar-button =
+ .title = নথির মধà§à¦¯à§‡ খà§à¦à¦œà§à¦¨
+pdfjs-findbar-button-label = খà§à¦à¦œà§à¦¨
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = পাতা { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } পাতার থামà§à¦¬à¦¨à§‡à¦‡à¦²
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = খà§à¦à¦œà§à¦¨
+ .placeholder = নথির মধà§à¦¯à§‡ খà§à¦à¦œà§à¦¨â€¦
+pdfjs-find-previous-button =
+ .title = বাকà§à¦¯à¦¾à¦‚শের পূরà§à¦¬à¦¬à¦°à§à¦¤à§€ উপসà§à¦¥à¦¿à¦¤à¦¿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨
+pdfjs-find-previous-button-label = পূরà§à¦¬à¦¬à¦°à§à¦¤à§€
+pdfjs-find-next-button =
+ .title = বাকà§à¦¯à¦¾à¦‚শের পরবরà§à¦¤à§€ উপসà§à¦¥à¦¿à¦¤à¦¿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨
+pdfjs-find-next-button-label = পরবরà§à¦¤à§€
+pdfjs-find-highlight-checkbox = সব হাইলাইট করà§à¦¨
+pdfjs-find-match-case-checkbox-label = অকà§à¦·à¦°à§‡à¦° ছাà¦à¦¦ মেলানো
+pdfjs-find-entire-word-checkbox-label = সমà§à¦ªà§‚রà§à¦£ শবà§à¦¦
+pdfjs-find-reached-top = পাতার শà§à¦°à§à¦¤à§‡ পৌছে গেছে, নীচ থেকে আরমà§à¦ করা হয়েছে
+pdfjs-find-reached-bottom = পাতার শেষে পৌছে গেছে, উপর থেকে আরমà§à¦ করা হয়েছে
+pdfjs-find-not-found = বাকà§à¦¯à¦¾à¦‚শ পাওয়া যায়নি
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = পাতার পà§à¦°à¦¸à§à¦¥
+pdfjs-page-scale-fit = পাতা ফিট করà§à¦¨
+pdfjs-page-scale-auto = সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿ জà§à¦®
+pdfjs-page-scale-actual = পà§à¦°à¦•à§ƒà¦¤ আকার
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = পিডিà¦à¦« লোড করার সময় তà§à¦°à§à¦Ÿà¦¿ দেখা দিয়েছে।
+pdfjs-invalid-file-error = অকারà§à¦¯à¦•à¦° অথবা কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ পিডিà¦à¦« ফাইল।
+pdfjs-missing-file-error = নিখোà¦à¦œ PDF ফাইল।
+pdfjs-unexpected-response-error = অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à§€à¦¤ সারà§à¦à¦¾à¦° পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à§Ÿà¦¾à¥¤
+pdfjs-rendering-error = পাতা উপসà§à¦¥à¦¾à¦ªà¦¨à¦¾à¦° সময় তà§à¦°à§à¦Ÿà¦¿ দেখা দিয়েছে।
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } টীকা]
+
+## Password
+
+pdfjs-password-label = পিডিà¦à¦« ফাইলটি ওপেন করতে পাসওয়ারà§à¦¡ দিন।
+pdfjs-password-invalid = à¦à§à¦² পাসওয়ারà§à¦¡à¥¤ অনà§à¦—à§à¦°à¦¹ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à¥¤
+pdfjs-password-ok-button = ঠিক আছে
+pdfjs-password-cancel-button = বাতিল
+pdfjs-web-fonts-disabled = ওয়েব ফনà§à¦Ÿ নিষà§à¦•à§à¦°à¦¿à§Ÿ: সংযà§à¦•à§à¦¤ পিডিà¦à¦« ফনà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যাচà§à¦›à§‡ না।
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/bo/viewer.ftl b/www/lib/pdfjs/modern/web/locale/bo/viewer.ftl
new file mode 100644
index 000000000..824eab4ff
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/bo/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = དྲ་ངོས་སྔོན་མ
+pdfjs-previous-button-label = སྔོན་མ
+pdfjs-next-button =
+ .title = དྲ་ངོས་རྗེས་མ
+pdfjs-next-button-label = རྗེས་མ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ཤོག་ངོས
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = of { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom Out
+pdfjs-zoom-out-button-label = Zoom Out
+pdfjs-zoom-in-button =
+ .title = Zoom In
+pdfjs-zoom-in-button-label = Zoom In
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Switch to Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Open File
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Print
+pdfjs-print-button-label = Print
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Go to First Page
+pdfjs-first-page-button-label = Go to First Page
+pdfjs-last-page-button =
+ .title = Go to Last Page
+pdfjs-last-page-button-label = Go to Last Page
+pdfjs-page-rotate-cw-button =
+ .title = Rotate Clockwise
+pdfjs-page-rotate-cw-button-label = Rotate Clockwise
+pdfjs-page-rotate-ccw-button =
+ .title = Rotate Counterclockwise
+pdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise
+pdfjs-cursor-text-select-tool-button =
+ .title = Enable Text Selection Tool
+pdfjs-cursor-text-select-tool-button-label = Text Selection Tool
+pdfjs-cursor-hand-tool-button =
+ .title = Enable Hand Tool
+pdfjs-cursor-hand-tool-button-label = Hand Tool
+pdfjs-scroll-vertical-button =
+ .title = Use Vertical Scrolling
+pdfjs-scroll-vertical-button-label = Vertical Scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Use Horizontal Scrolling
+pdfjs-scroll-horizontal-button-label = Horizontal Scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Use Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = Do not join page spreads
+pdfjs-spread-none-button-label = No Spreads
+pdfjs-spread-odd-button =
+ .title = Join page spreads starting with odd-numbered pages
+pdfjs-spread-odd-button-label = Odd Spreads
+pdfjs-spread-even-button =
+ .title = Join page spreads starting with even-numbered pages
+pdfjs-spread-even-button-label = Even Spreads
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Document Properties…
+pdfjs-document-properties-button-label = Document Properties…
+pdfjs-document-properties-file-name = File name:
+pdfjs-document-properties-file-size = File size:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Title:
+pdfjs-document-properties-author = Author:
+pdfjs-document-properties-subject = Subject:
+pdfjs-document-properties-keywords = Keywords:
+pdfjs-document-properties-creation-date = Creation Date:
+pdfjs-document-properties-modification-date = Modification Date:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creator:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Page Count:
+pdfjs-document-properties-page-size = Page Size:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = landscape
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Yes
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Close
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancel
+pdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.
+pdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggle Sidebar
+pdfjs-toggle-sidebar-button-label = Toggle Sidebar
+pdfjs-document-outline-button =
+ .title = Show Document Outline (double-click to expand/collapse all items)
+pdfjs-document-outline-button-label = Document Outline
+pdfjs-attachments-button =
+ .title = Show Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-thumbs-button =
+ .title = Show Thumbnails
+pdfjs-thumbs-button-label = Thumbnails
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = Find
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail of Page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find in document…
+pdfjs-find-previous-button =
+ .title = Find the previous occurrence of the phrase
+pdfjs-find-previous-button-label = Previous
+pdfjs-find-next-button =
+ .title = Find the next occurrence of the phrase
+pdfjs-find-next-button-label = Next
+pdfjs-find-highlight-checkbox = Highlight all
+pdfjs-find-match-case-checkbox-label = Match case
+pdfjs-find-entire-word-checkbox-label = Whole words
+pdfjs-find-reached-top = Reached top of document, continued from bottom
+pdfjs-find-reached-bottom = Reached end of document, continued from top
+pdfjs-find-not-found = Phrase not found
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Page Width
+pdfjs-page-scale-fit = Page Fit
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Actual Size
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = An error occurred while loading the PDF.
+pdfjs-invalid-file-error = Invalid or corrupted PDF file.
+pdfjs-missing-file-error = Missing PDF file.
+pdfjs-unexpected-response-error = Unexpected server response.
+pdfjs-rendering-error = An error occurred while rendering the page.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Enter the password to open this PDF file.
+pdfjs-password-invalid = Invalid password. Please try again.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancel
+pdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/br/viewer.ftl b/www/lib/pdfjs/modern/web/locale/br/viewer.ftl
new file mode 100644
index 000000000..0399ec987
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/br/viewer.ftl
@@ -0,0 +1,291 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pajenn a-raok
+pdfjs-previous-button-label = A-raok
+pdfjs-next-button =
+ .title = Pajenn war-lerc'h
+pdfjs-next-button-label = War-lerc'h
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pajenn
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = eus { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } war { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoum bihanaat
+pdfjs-zoom-out-button-label = Zoum bihanaat
+pdfjs-zoom-in-button =
+ .title = Zoum brasaat
+pdfjs-zoom-in-button-label = Zoum brasaat
+pdfjs-zoom-select =
+ .title = Zoum
+pdfjs-presentation-mode-button =
+ .title = Trec'haoliñ etrezek ar mod kinnigadenn
+pdfjs-presentation-mode-button-label = Mod kinnigadenn
+pdfjs-open-file-button =
+ .title = Digeriñ ur restr
+pdfjs-open-file-button-label = Digeriñ ur restr
+pdfjs-print-button =
+ .title = Moullañ
+pdfjs-print-button-label = Moullañ
+pdfjs-save-button =
+ .title = Enrollañ
+pdfjs-save-button-label = Enrollañ
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Pellgargañ
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Pellgargañ
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ostilhoù
+pdfjs-tools-button-label = Ostilhoù
+pdfjs-first-page-button =
+ .title = Mont d'ar bajenn gentañ
+pdfjs-first-page-button-label = Mont d'ar bajenn gentañ
+pdfjs-last-page-button =
+ .title = Mont d'ar bajenn diwezhañ
+pdfjs-last-page-button-label = Mont d'ar bajenn diwezhañ
+pdfjs-page-rotate-cw-button =
+ .title = C'hwelañ gant roud ar bizied
+pdfjs-page-rotate-cw-button-label = C'hwelañ gant roud ar bizied
+pdfjs-page-rotate-ccw-button =
+ .title = C'hwelañ gant roud gin ar bizied
+pdfjs-page-rotate-ccw-button-label = C'hwelañ gant roud gin ar bizied
+pdfjs-cursor-text-select-tool-button =
+ .title = Gweredekaat an ostilh diuzañ testenn
+pdfjs-cursor-text-select-tool-button-label = Ostilh diuzañ testenn
+pdfjs-cursor-hand-tool-button =
+ .title = Gweredekaat an ostilh dorn
+pdfjs-cursor-hand-tool-button-label = Ostilh dorn
+pdfjs-scroll-vertical-button =
+ .title = Arverañ an dibunañ a-blom
+pdfjs-scroll-vertical-button-label = Dibunañ a-serzh
+pdfjs-scroll-horizontal-button =
+ .title = Arverañ an dibunañ a-blaen
+pdfjs-scroll-horizontal-button-label = Dibunañ a-blaen
+pdfjs-scroll-wrapped-button =
+ .title = Arverañ an dibunañ paket
+pdfjs-scroll-wrapped-button-label = Dibunañ paket
+pdfjs-spread-none-button =
+ .title = Chom hep stagañ ar skignadurioù
+pdfjs-spread-none-button-label = Skignadenn ebet
+pdfjs-spread-odd-button =
+ .title = Lakaat ar pajennadoù en ur gregiñ gant ar pajennoù ampar
+pdfjs-spread-odd-button-label = Pajennoù ampar
+pdfjs-spread-even-button =
+ .title = Lakaat ar pajennadoù en ur gregiñ gant ar pajennoù par
+pdfjs-spread-even-button-label = Pajennoù par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Perzhioù an teul…
+pdfjs-document-properties-button-label = Perzhioù an teul…
+pdfjs-document-properties-file-name = Anv restr:
+pdfjs-document-properties-file-size = Ment ar restr:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } Ke ({ $size_b } eizhbit)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } Me ({ $size_b } eizhbit)
+pdfjs-document-properties-title = Titl:
+pdfjs-document-properties-author = Aozer:
+pdfjs-document-properties-subject = Danvez:
+pdfjs-document-properties-keywords = Gerioù-alc'hwez:
+pdfjs-document-properties-creation-date = Deiziad krouiñ:
+pdfjs-document-properties-modification-date = Deiziad kemmañ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Krouer:
+pdfjs-document-properties-producer = Kenderc'her PDF:
+pdfjs-document-properties-version = Handelv PDF:
+pdfjs-document-properties-page-count = Niver a bajennoù:
+pdfjs-document-properties-page-size = Ment ar bajenn:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = poltred
+pdfjs-document-properties-page-size-orientation-landscape = gweledva
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Lizher
+pdfjs-document-properties-page-size-name-legal = Lezennel
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Gwel Web Herrek:
+pdfjs-document-properties-linearized-yes = Ya
+pdfjs-document-properties-linearized-no = Ket
+pdfjs-document-properties-close-button = Serriñ
+
+## Print
+
+pdfjs-print-progress-message = O prientiñ an teul evit moullañ...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Nullañ
+pdfjs-printing-not-supported = Kemenn: N'eo ket skoret penn-da-benn ar moullañ gant ar merdeer-mañ.
+pdfjs-printing-not-ready = Kemenn: N'hall ket bezañ moullet ar restr PDF rak n'eo ket karget penn-da-benn.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Diskouez/kuzhat ar varrenn gostez
+pdfjs-toggle-sidebar-notification-button =
+ .title = Trec'haoliñ ar varrenn-gostez (ur steuñv pe stagadennoù a zo en teul)
+pdfjs-toggle-sidebar-button-label = Diskouez/kuzhat ar varrenn gostez
+pdfjs-document-outline-button =
+ .title = Diskouez steuñv an teul (daouglikit evit brasaat/bihanaat an holl elfennoù)
+pdfjs-document-outline-button-label = Sinedoù an teuliad
+pdfjs-attachments-button =
+ .title = Diskouez ar c'henstagadurioù
+pdfjs-attachments-button-label = Kenstagadurioù
+pdfjs-layers-button =
+ .title = Diskouez ar gwiskadoù (daou-glikañ evit adderaouekaat an holl gwiskadoù d'o stad dre ziouer)
+pdfjs-layers-button-label = Gwiskadoù
+pdfjs-thumbs-button =
+ .title = Diskouez ar melvennoù
+pdfjs-thumbs-button-label = Melvennoù
+pdfjs-findbar-button =
+ .title = Klask e-barzh an teuliad
+pdfjs-findbar-button-label = Klask
+pdfjs-additional-layers = Gwiskadoù ouzhpenn
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pajenn { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Melvenn ar bajenn { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Klask
+ .placeholder = Klask e-barzh an teuliad
+pdfjs-find-previous-button =
+ .title = Kavout an tamm frazenn kent o klotañ ganti
+pdfjs-find-previous-button-label = Kent
+pdfjs-find-next-button =
+ .title = Kavout an tamm frazenn war-lerc'h o klotañ ganti
+pdfjs-find-next-button-label = War-lerc'h
+pdfjs-find-highlight-checkbox = Usskediñ pep tra
+pdfjs-find-match-case-checkbox-label = Teurel evezh ouzh ar pennlizherennoù
+pdfjs-find-entire-word-checkbox-label = Gerioù a-bezh
+pdfjs-find-reached-top = Tizhet eo bet derou ar bajenn, kenderc'hel diouzh an diaz
+pdfjs-find-reached-bottom = Tizhet eo bet dibenn ar bajenn, kenderc'hel diouzh ar c'hrec'h
+pdfjs-find-not-found = N'haller ket kavout ar frazenn
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Led ar bajenn
+pdfjs-page-scale-fit = Pajenn a-bezh
+pdfjs-page-scale-auto = Zoum emgefreek
+pdfjs-page-scale-actual = Ment wir
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pajenn { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Degouezhet ez eus bet ur fazi e-pad kargañ ar PDF.
+pdfjs-invalid-file-error = Restr PDF didalvoudek pe kontronet.
+pdfjs-missing-file-error = Restr PDF o vankout.
+pdfjs-unexpected-response-error = Respont dic'hortoz a-berzh an dafariad
+pdfjs-rendering-error = Degouezhet ez eus bet ur fazi e-pad skrammañ ar bajennad.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Notennañ]
+
+## Password
+
+pdfjs-password-label = Enankit ar ger-tremen evit digeriñ ar restr PDF-mañ.
+pdfjs-password-invalid = Ger-tremen didalvoudek. Klaskit en-dro mar plij.
+pdfjs-password-ok-button = Mat eo
+pdfjs-password-cancel-button = Nullañ
+pdfjs-web-fonts-disabled = Diweredekaet eo an nodrezhoù web: n'haller ket arverañ an nodrezhoù PDF enframmet.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Testenn
+pdfjs-editor-free-text-button-label = Testenn
+pdfjs-editor-ink-button =
+ .title = Tresañ
+pdfjs-editor-ink-button-label = Tresañ
+
+## Remove button for the various kind of editor.
+
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Liv
+pdfjs-editor-free-text-size-input = Ment
+pdfjs-editor-ink-color-input = Liv
+
+## Alt-text dialog
+
+pdfjs-editor-alt-text-cancel-button = Nullañ
+pdfjs-editor-alt-text-save-button = Enrollañ
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+
+## Color picker
+
diff --git a/www/lib/pdfjs/modern/web/locale/brx/viewer.ftl b/www/lib/pdfjs/modern/web/locale/brx/viewer.ftl
new file mode 100644
index 000000000..53ff72c56
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/brx/viewer.ftl
@@ -0,0 +1,218 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = आगोलनि बिलाइ
+pdfjs-previous-button-label = आगोलनि
+pdfjs-next-button =
+ .title = उननि बिलाइ
+pdfjs-next-button-label = उननि
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = बिलाइ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } नि
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } नि { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = फिसायै जà¥à¤® खालाम
+pdfjs-zoom-out-button-label = फिसायै जà¥à¤® खालाम
+pdfjs-zoom-in-button =
+ .title = गेदेरै जà¥à¤® खालाम
+pdfjs-zoom-in-button-label = गेदेरै जà¥à¤® खालाम
+pdfjs-zoom-select =
+ .title = जà¥à¤® खालाम
+pdfjs-presentation-mode-button =
+ .title = दिनà¥à¤¥à¤¿à¤«à¥à¤‚नाय म'डआव थां
+pdfjs-presentation-mode-button-label = दिनà¥à¤¥à¤¿à¤«à¥à¤‚नाय म'ड
+pdfjs-open-file-button =
+ .title = फाइलखौ खेव
+pdfjs-open-file-button-label = खेव
+pdfjs-print-button =
+ .title = साफाय
+pdfjs-print-button-label = साफाय
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = टà¥à¤²
+pdfjs-tools-button-label = टà¥à¤²
+pdfjs-first-page-button =
+ .title = गिबि बिलाइआव थां
+pdfjs-first-page-button-label = गिबि बिलाइआव थां
+pdfjs-last-page-button =
+ .title = जोबथा बिलाइआव थां
+pdfjs-last-page-button-label = जोबथा बिलाइआव थां
+pdfjs-page-rotate-cw-button =
+ .title = घरि गिदिंनाय फारà¥à¤¸à¥‡ फिदिं
+pdfjs-page-rotate-cw-button-label = घरि गिदिंनाय फारà¥à¤¸à¥‡ फिदिं
+pdfjs-page-rotate-ccw-button =
+ .title = घरि गिदिंनाय उलà¥à¤¥à¤¾ फारà¥à¤¸à¥‡ फिदिं
+pdfjs-page-rotate-ccw-button-label = घरि गिदिंनाय उलà¥à¤¥à¤¾ फारà¥à¤¸à¥‡ फिदिं
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = फोरमान बिलाइनि आखà¥à¤¥à¤¾à¤¯...
+pdfjs-document-properties-button-label = फोरमान बिलाइनि आखà¥à¤¥à¤¾à¤¯...
+pdfjs-document-properties-file-name = फाइलनि मà¥à¤‚:
+pdfjs-document-properties-file-size = फाइलनि महर:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } बाइट)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } बाइट)
+pdfjs-document-properties-title = बिमà¥à¤‚:
+pdfjs-document-properties-author = लिरगिरि:
+pdfjs-document-properties-subject = आयदा:
+pdfjs-document-properties-keywords = गाहाय सोदोब:
+pdfjs-document-properties-creation-date = सोरजिनाय अकà¥à¤Ÿ':
+pdfjs-document-properties-modification-date = सà¥à¤¦à¥à¤°à¤¾à¤¯à¤¨à¤¾à¤¯ अकà¥à¤Ÿ':
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = सोरजिगà¥à¤°à¤¾:
+pdfjs-document-properties-producer = PDF दिहà¥à¤¨à¤—à¥à¤°à¤¾:
+pdfjs-document-properties-version = PDF बिसान:
+pdfjs-document-properties-page-count = बिलाइनि हिसाब:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = प'रà¥à¤Ÿà¥à¤°à¥‡à¤Ÿ
+pdfjs-document-properties-page-size-orientation-landscape = लेणà¥à¤¡à¤¸à¥à¤•à¥‡à¤ª
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = लायजाम
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = नंगौ
+pdfjs-document-properties-linearized-no = नङा
+pdfjs-document-properties-close-button = बनà¥à¤¦ खालाम
+
+## Print
+
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = नेवसि
+pdfjs-printing-not-supported = सांगà¥à¤°à¤¾à¤‚थि: साफायनाया बे बà¥à¤°à¤¾à¤‰à¤œà¤¾à¤°à¤œà¥‹à¤‚ आबà¥à¤™à¥ˆ हेफाजाब होजाया।
+pdfjs-printing-not-ready = सांगà¥à¤°à¤¾à¤‚थि: PDF खौ साफायनायनि थाखाय फà¥à¤°à¤¾à¤¯à¥ˆ ल'ड खालामाखै।
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = टगà¥à¤—ल साइडबार
+pdfjs-toggle-sidebar-button-label = टगà¥à¤—ल साइडबार
+pdfjs-document-outline-button-label = फोरमान बिलाइ सिमा हांखो
+pdfjs-attachments-button =
+ .title = नांजाब होनायखौ दिनà¥à¤¥à¤¿
+pdfjs-attachments-button-label = नांजाब होनाय
+pdfjs-thumbs-button =
+ .title = थामनेइलखौ दिनà¥à¤¥à¤¿
+pdfjs-thumbs-button-label = थामनेइल
+pdfjs-findbar-button =
+ .title = फोरमान बिलाइआव नागिरना दिहà¥à¤¨
+pdfjs-findbar-button-label = नायगिरना दिहà¥à¤¨
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = बिलाइ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = बिलाइ { $page } नि थामनेइल
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = नायगिरना दिहà¥à¤¨
+ .placeholder = फोरमान बिलाइआव नागिरना दिहà¥à¤¨...
+pdfjs-find-previous-button =
+ .title = बाथà¥à¤°à¤¾ खोनà¥à¤¦à¥‹à¤¬à¤¨à¤¿ सिगांनि नà¥à¤œà¤¾à¤¥à¤¿à¤¨à¤¾à¤¯à¤–ौ नागिर
+pdfjs-find-previous-button-label = आगोलनि
+pdfjs-find-next-button =
+ .title = बाथà¥à¤°à¤¾ खोनà¥à¤¦à¥‹à¤¬à¤¨à¤¿ उननि नà¥à¤œà¤¾à¤¥à¤¿à¤¨à¤¾à¤¯à¤–ौ नागिर
+pdfjs-find-next-button-label = उननि
+pdfjs-find-highlight-checkbox = गासैखौबो हाइलाइट खालाम
+pdfjs-find-match-case-checkbox-label = गोरोबनाय केस
+pdfjs-find-reached-top = थालो निफà¥à¤°à¤¾à¤¯ जागायनानै फोरमान बिलाइनि बिजौआव सौहैबाय
+pdfjs-find-reached-bottom = बिजौ निफà¥à¤°à¤¾à¤¯ जागायनानै फोरमान बिलाइनि बिजौआव सौहैबाय
+pdfjs-find-not-found = बाथà¥à¤°à¤¾ खोनà¥à¤¦à¥‹à¤¬ मोनाखै
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = बिलाइनि गà¥à¤µà¤¾à¤°
+pdfjs-page-scale-fit = बिलाइ गोरोबनाय
+pdfjs-page-scale-auto = गावनोगाव जà¥à¤®
+pdfjs-page-scale-actual = थार महर
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ल'ड खालामनाय समाव मोनसे गोरोनà¥à¤¥à¤¿ जाबाय।
+pdfjs-invalid-file-error = बाहायजायै à¤à¤¬à¤¾ गाजà¥à¤°à¤¿ जानाय PDF फाइल
+pdfjs-missing-file-error = गोमानाय PDF फाइल
+pdfjs-unexpected-response-error = मिजिंथियै सारà¥à¤à¤¾à¤° फिननाय।
+pdfjs-rendering-error = बिलाइखौ राव सोलायनाय समाव मोनसे गोरोनà¥à¤¥à¤¿ जादों।
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } सोदोब बेखेवनाय]
+
+## Password
+
+pdfjs-password-label = बे PDF फाइलखौ खेवनो पासवारà¥à¤¡ हाबहो।
+pdfjs-password-invalid = बाहायजायै पासवारà¥à¤¡à¥¤ अननानै फिन नाजा।
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = नेवसि
+pdfjs-web-fonts-disabled = वेब फनà¥à¤Ÿà¤–ौ लोरबां खालामबाय: अरजाबहोनाय PDF फनà¥à¤Ÿà¤–ौ बाहायनो हायाखै।
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/bs/viewer.ftl b/www/lib/pdfjs/modern/web/locale/bs/viewer.ftl
new file mode 100644
index 000000000..39440424f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/bs/viewer.ftl
@@ -0,0 +1,223 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Prethodna strana
+pdfjs-previous-button-label = Prethodna
+pdfjs-next-button =
+ .title = Sljedeća strna
+pdfjs-next-button-label = Sljedeća
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Strana
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = od { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } od { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Umanji
+pdfjs-zoom-out-button-label = Umanji
+pdfjs-zoom-in-button =
+ .title = Uvećaj
+pdfjs-zoom-in-button-label = Uvećaj
+pdfjs-zoom-select =
+ .title = Uvećanje
+pdfjs-presentation-mode-button =
+ .title = Prebaci se u prezentacijski režim
+pdfjs-presentation-mode-button-label = Prezentacijski režim
+pdfjs-open-file-button =
+ .title = Otvori fajl
+pdfjs-open-file-button-label = Otvori
+pdfjs-print-button =
+ .title = Å tampaj
+pdfjs-print-button-label = Å tampaj
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Alati
+pdfjs-tools-button-label = Alati
+pdfjs-first-page-button =
+ .title = Idi na prvu stranu
+pdfjs-first-page-button-label = Idi na prvu stranu
+pdfjs-last-page-button =
+ .title = Idi na zadnju stranu
+pdfjs-last-page-button-label = Idi na zadnju stranu
+pdfjs-page-rotate-cw-button =
+ .title = Rotiraj u smjeru kazaljke na satu
+pdfjs-page-rotate-cw-button-label = Rotiraj u smjeru kazaljke na satu
+pdfjs-page-rotate-ccw-button =
+ .title = Rotiraj suprotno smjeru kazaljke na satu
+pdfjs-page-rotate-ccw-button-label = Rotiraj suprotno smjeru kazaljke na satu
+pdfjs-cursor-text-select-tool-button =
+ .title = Omogući alat za oznaÄavanje teksta
+pdfjs-cursor-text-select-tool-button-label = Alat za oznaÄavanje teksta
+pdfjs-cursor-hand-tool-button =
+ .title = Omogući ruÄni alat
+pdfjs-cursor-hand-tool-button-label = RuÄni alat
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Svojstva dokumenta...
+pdfjs-document-properties-button-label = Svojstva dokumenta...
+pdfjs-document-properties-file-name = Naziv fajla:
+pdfjs-document-properties-file-size = VeliÄina fajla:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajta)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajta)
+pdfjs-document-properties-title = Naslov:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Predmet:
+pdfjs-document-properties-keywords = KljuÄne rijeÄi:
+pdfjs-document-properties-creation-date = Datum kreiranja:
+pdfjs-document-properties-modification-date = Datum promjene:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Kreator:
+pdfjs-document-properties-producer = PDF stvaratelj:
+pdfjs-document-properties-version = PDF verzija:
+pdfjs-document-properties-page-count = Broj stranica:
+pdfjs-document-properties-page-size = VeliÄina stranice:
+pdfjs-document-properties-page-size-unit-inches = u
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = uspravno
+pdfjs-document-properties-page-size-orientation-landscape = vodoravno
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Pismo
+pdfjs-document-properties-page-size-name-legal = Pravni
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-close-button = Zatvori
+
+## Print
+
+pdfjs-print-progress-message = Pripremam dokument za štampu…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Otkaži
+pdfjs-printing-not-supported = Upozorenje: Štampanje nije u potpunosti podržano u ovom browseru.
+pdfjs-printing-not-ready = Upozorenje: PDF nije u potpunosti uÄitan za Å¡tampanje.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = UkljuÄi/iskljuÄi boÄnu traku
+pdfjs-toggle-sidebar-button-label = UkljuÄi/iskljuÄi boÄnu traku
+pdfjs-document-outline-button =
+ .title = Prikaži outline dokumenta (dvoklik za skupljanje/širenje svih stavki)
+pdfjs-document-outline-button-label = Konture dokumenta
+pdfjs-attachments-button =
+ .title = Prikaži priloge
+pdfjs-attachments-button-label = Prilozi
+pdfjs-thumbs-button =
+ .title = Prikaži thumbnailove
+pdfjs-thumbs-button-label = Thumbnailovi
+pdfjs-findbar-button =
+ .title = Pronađi u dokumentu
+pdfjs-findbar-button-label = Pronađi
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Strana { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail strane { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Pronađi
+ .placeholder = Pronađi u dokumentu…
+pdfjs-find-previous-button =
+ .title = Pronađi prethodno pojavljivanje fraze
+pdfjs-find-previous-button-label = Prethodno
+pdfjs-find-next-button =
+ .title = Pronađi sljedeće pojavljivanje fraze
+pdfjs-find-next-button-label = Sljedeće
+pdfjs-find-highlight-checkbox = OznaÄi sve
+pdfjs-find-match-case-checkbox-label = Osjetljivost na karaktere
+pdfjs-find-reached-top = Dostigao sam vrh dokumenta, nastavljam sa dna
+pdfjs-find-reached-bottom = Dostigao sam kraj dokumenta, nastavljam sa vrha
+pdfjs-find-not-found = Fraza nije pronađena
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Å irina strane
+pdfjs-page-scale-fit = Uklopi stranu
+pdfjs-page-scale-auto = Automatsko uvećanje
+pdfjs-page-scale-actual = Stvarna veliÄina
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = DoÅ¡lo je do greÅ¡ke prilikom uÄitavanja PDF-a.
+pdfjs-invalid-file-error = Neispravan ili oštećen PDF fajl.
+pdfjs-missing-file-error = Nedostaje PDF fajl.
+pdfjs-unexpected-response-error = NeoÄekivani odgovor servera.
+pdfjs-rendering-error = Došlo je do greške prilikom renderiranja strane.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } pribilješka]
+
+## Password
+
+pdfjs-password-label = Upišite lozinku da biste otvorili ovaj PDF fajl.
+pdfjs-password-invalid = Pogrešna lozinka. Pokušajte ponovo.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Otkaži
+pdfjs-web-fonts-disabled = Web fontovi su onemogućeni: nemoguće koristiti ubaÄene PDF fontove.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ca/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ca/viewer.ftl
new file mode 100644
index 000000000..575dc5fb3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ca/viewer.ftl
@@ -0,0 +1,299 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = PÃ gina anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Pà gina següent
+pdfjs-next-button-label = Següent
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = PÃ gina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Redueix
+pdfjs-zoom-out-button-label = Redueix
+pdfjs-zoom-in-button =
+ .title = Amplia
+pdfjs-zoom-in-button-label = Amplia
+pdfjs-zoom-select =
+ .title = Escala
+pdfjs-presentation-mode-button =
+ .title = Canvia al mode de presentació
+pdfjs-presentation-mode-button-label = Mode de presentació
+pdfjs-open-file-button =
+ .title = Obre el fitxer
+pdfjs-open-file-button-label = Obre
+pdfjs-print-button =
+ .title = Imprimeix
+pdfjs-print-button-label = Imprimeix
+pdfjs-save-button =
+ .title = Desa
+pdfjs-save-button-label = Desa
+pdfjs-bookmark-button =
+ .title = Pà gina actual (mostra l'URL de la pà gina actual)
+pdfjs-bookmark-button-label = PÃ gina actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Obre en una aplicació
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Obre en una aplicació
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Eines
+pdfjs-tools-button-label = Eines
+pdfjs-first-page-button =
+ .title = Vés a la primera pà gina
+pdfjs-first-page-button-label = Vés a la primera pà gina
+pdfjs-last-page-button =
+ .title = Vés a l'última pà gina
+pdfjs-last-page-button-label = Vés a l'última pà gina
+pdfjs-page-rotate-cw-button =
+ .title = Gira cap a la dreta
+pdfjs-page-rotate-cw-button-label = Gira cap a la dreta
+pdfjs-page-rotate-ccw-button =
+ .title = Gira cap a l'esquerra
+pdfjs-page-rotate-ccw-button-label = Gira cap a l'esquerra
+pdfjs-cursor-text-select-tool-button =
+ .title = Habilita l'eina de selecció de text
+pdfjs-cursor-text-select-tool-button-label = Eina de selecció de text
+pdfjs-cursor-hand-tool-button =
+ .title = Habilita l'eina de mÃ
+pdfjs-cursor-hand-tool-button-label = Eina de mÃ
+pdfjs-scroll-page-button =
+ .title = Usa el desplaçament de pà gina
+pdfjs-scroll-page-button-label = Desplaçament de pà gina
+pdfjs-scroll-vertical-button =
+ .title = Utilitza el desplaçament vertical
+pdfjs-scroll-vertical-button-label = Desplaçament vertical
+pdfjs-scroll-horizontal-button =
+ .title = Utilitza el desplaçament horitzontal
+pdfjs-scroll-horizontal-button-label = Desplaçament horitzontal
+pdfjs-scroll-wrapped-button =
+ .title = Activa el desplaçament continu
+pdfjs-scroll-wrapped-button-label = Desplaçament continu
+pdfjs-spread-none-button =
+ .title = No agrupis les pà gines de dues en dues
+pdfjs-spread-none-button-label = Una sola pà gina
+pdfjs-spread-odd-button =
+ .title = Mostra dues pà gines començant per les pà gines de numeració senar
+pdfjs-spread-odd-button-label = Doble pà gina (senar)
+pdfjs-spread-even-button =
+ .title = Mostra dues pà gines començant per les pà gines de numeració parell
+pdfjs-spread-even-button-label = Doble pà gina (parell)
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propietats del document…
+pdfjs-document-properties-button-label = Propietats del document…
+pdfjs-document-properties-file-name = Nom del fitxer:
+pdfjs-document-properties-file-size = Mida del fitxer:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtol:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Assumpte:
+pdfjs-document-properties-keywords = Paraules clau:
+pdfjs-document-properties-creation-date = Data de creació:
+pdfjs-document-properties-modification-date = Data de modificació:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creador:
+pdfjs-document-properties-producer = Generador de PDF:
+pdfjs-document-properties-version = Versió de PDF:
+pdfjs-document-properties-page-count = Nombre de pà gines:
+pdfjs-document-properties-page-size = Mida de la pà gina:
+pdfjs-document-properties-page-size-unit-inches = polzades
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = apaïsat
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web rà pida:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Tanca
+
+## Print
+
+pdfjs-print-progress-message = S'està preparant la impressió del document…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancel·la
+pdfjs-printing-not-supported = AvÃs: la impressió no és plenament funcional en aquest navegador.
+pdfjs-printing-not-ready = Atenció: el PDF no s'ha acabat de carregar per imprimir-lo.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Mostra/amaga la barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Mostra/amaga la barra lateral (el document conté un esquema, adjuncions o capes)
+pdfjs-toggle-sidebar-button-label = Mostra/amaga la barra lateral
+pdfjs-document-outline-button =
+ .title = Mostra l'esquema del document (doble clic per ampliar/reduir tots els elements)
+pdfjs-document-outline-button-label = Esquema del document
+pdfjs-attachments-button =
+ .title = Mostra les adjuncions
+pdfjs-attachments-button-label = Adjuncions
+pdfjs-layers-button =
+ .title = Mostra les capes (doble clic per restablir totes les capes al seu estat per defecte)
+pdfjs-layers-button-label = Capes
+pdfjs-thumbs-button =
+ .title = Mostra les miniatures
+pdfjs-thumbs-button-label = Miniatures
+pdfjs-current-outline-item-button =
+ .title = Cerca l'element d'esquema actual
+pdfjs-current-outline-item-button-label = Element d'esquema actual
+pdfjs-findbar-button =
+ .title = Cerca al document
+pdfjs-findbar-button-label = Cerca
+pdfjs-additional-layers = Capes addicionals
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = PÃ gina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de la pà gina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Cerca
+ .placeholder = Cerca al document…
+pdfjs-find-previous-button =
+ .title = Cerca l'anterior coincidència de l'expressió
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Cerca la següent coincidència de l'expressió
+pdfjs-find-next-button-label = Següent
+pdfjs-find-highlight-checkbox = Ressalta-ho tot
+pdfjs-find-match-case-checkbox-label = Distingeix entre majúscules i minúscules
+pdfjs-find-match-diacritics-checkbox-label = Respecta els diacrÃtics
+pdfjs-find-entire-word-checkbox-label = Paraules senceres
+pdfjs-find-reached-top = S'ha arribat al principi del document, es continua pel final
+pdfjs-find-reached-bottom = S'ha arribat al final del document, es continua pel principi
+pdfjs-find-not-found = No s'ha trobat l'expressió
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Amplada de la pà gina
+pdfjs-page-scale-fit = Ajusta la pà gina
+pdfjs-page-scale-auto = Zoom automà tic
+pdfjs-page-scale-actual = Mida real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = PÃ gina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = S'ha produït un error en carregar el PDF.
+pdfjs-invalid-file-error = El fitxer PDF no és và lid o està malmès.
+pdfjs-missing-file-error = Falta el fitxer PDF.
+pdfjs-unexpected-response-error = Resposta inesperada del servidor.
+pdfjs-rendering-error = S'ha produït un error mentre es renderitzava la pà gina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotació { $type }]
+
+## Password
+
+pdfjs-password-label = Introduïu la contrasenya per obrir aquest fitxer PDF.
+pdfjs-password-invalid = La contrasenya no és và lida. Torneu-ho a provar.
+pdfjs-password-ok-button = D'acord
+pdfjs-password-cancel-button = Cancel·la
+pdfjs-web-fonts-disabled = Els tipus de lletra web estan desactivats: no es poden utilitzar els tipus de lletra incrustats al PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Dibuixa
+pdfjs-editor-ink-button-label = Dibuixa
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Mida
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Gruix
+pdfjs-editor-ink-opacity-input = Opacitat
+pdfjs-free-text =
+ .aria-label = Editor de text
+pdfjs-free-text-default-content = Escriviu…
+pdfjs-ink =
+ .aria-label = Editor de dibuix
+pdfjs-ink-canvas =
+ .aria-label = Imatge creada per l'usuari
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/cak/viewer.ftl b/www/lib/pdfjs/modern/web/locale/cak/viewer.ftl
new file mode 100644
index 000000000..f40c1e92a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/cak/viewer.ftl
@@ -0,0 +1,291 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Jun kan ruxaq
+pdfjs-previous-button-label = Jun kan
+pdfjs-next-button =
+ .title = Jun chik ruxaq
+pdfjs-next-button-label = Jun chik
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Ruxaq
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = richin { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } richin { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Tich'utinirisäx
+pdfjs-zoom-out-button-label = Tich'utinirisäx
+pdfjs-zoom-in-button =
+ .title = Tinimirisäx
+pdfjs-zoom-in-button-label = Tinimirisäx
+pdfjs-zoom-select =
+ .title = Sum
+pdfjs-presentation-mode-button =
+ .title = Tijal ri rub'anikil niwachin
+pdfjs-presentation-mode-button-label = Pa rub'eyal niwachin
+pdfjs-open-file-button =
+ .title = Tijaq Yakb'äl
+pdfjs-open-file-button-label = Tijaq
+pdfjs-print-button =
+ .title = Titz'ajb'äx
+pdfjs-print-button-label = Titz'ajb'äx
+pdfjs-save-button =
+ .title = Tiyak
+pdfjs-save-button-label = Tiyak
+pdfjs-bookmark-button-label = Ruxaq k'o wakami
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Samajib'äl
+pdfjs-tools-button-label = Samajib'äl
+pdfjs-first-page-button =
+ .title = Tib'e pa nab'ey ruxaq
+pdfjs-first-page-button-label = Tib'e pa nab'ey ruxaq
+pdfjs-last-page-button =
+ .title = Tib'e pa ruk'isib'äl ruxaq
+pdfjs-last-page-button-label = Tib'e pa ruk'isib'äl ruxaq
+pdfjs-page-rotate-cw-button =
+ .title = Tisutïx pan ajkiq'a'
+pdfjs-page-rotate-cw-button-label = Tisutïx pan ajkiq'a'
+pdfjs-page-rotate-ccw-button =
+ .title = Tisutïx pan ajxokon
+pdfjs-page-rotate-ccw-button-label = Tisutïx pan ajxokon
+pdfjs-cursor-text-select-tool-button =
+ .title = Titzij ri rusamajib'al Rucha'ik Rucholajem Tzij
+pdfjs-cursor-text-select-tool-button-label = Rusamajib'al Rucha'ik Rucholajem Tzij
+pdfjs-cursor-hand-tool-button =
+ .title = Titzij ri q'ab'aj samajib'äl
+pdfjs-cursor-hand-tool-button-label = Q'ab'aj Samajib'äl
+pdfjs-scroll-page-button =
+ .title = Tokisäx Ruxaq Q'axanem
+pdfjs-scroll-page-button-label = Ruxaq Q'axanem
+pdfjs-scroll-vertical-button =
+ .title = Tokisäx Pa'äl Q'axanem
+pdfjs-scroll-vertical-button-label = Pa'äl Q'axanem
+pdfjs-scroll-horizontal-button =
+ .title = Tokisäx Kotz'öl Q'axanem
+pdfjs-scroll-horizontal-button-label = Kotz'öl Q'axanem
+pdfjs-scroll-wrapped-button =
+ .title = Tokisäx Tzub'aj Q'axanem
+pdfjs-scroll-wrapped-button-label = Tzub'aj Q'axanem
+pdfjs-spread-none-button =
+ .title = Man ketun taq ruxaq pa rub'eyal wuj
+pdfjs-spread-none-button-label = Majun Rub'eyal
+pdfjs-spread-odd-button =
+ .title = Ke'atunu' ri taq ruxaq rik'in natikirisaj rik'in jun man k'ulaj ta rajilab'al
+pdfjs-spread-odd-button-label = Man K'ulaj Ta Rub'eyal
+pdfjs-spread-even-button =
+ .title = Ke'atunu' ri taq ruxaq rik'in natikirisaj rik'in jun k'ulaj rajilab'al
+pdfjs-spread-even-button-label = K'ulaj Rub'eyal
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Taq richinil wuj…
+pdfjs-document-properties-button-label = Taq richinil wuj…
+pdfjs-document-properties-file-name = Rub'i' yakb'äl:
+pdfjs-document-properties-file-size = Runimilem yakb'äl:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = B'i'aj:
+pdfjs-document-properties-author = B'anel:
+pdfjs-document-properties-subject = Taqikil:
+pdfjs-document-properties-keywords = Kixe'el taq tzij:
+pdfjs-document-properties-creation-date = Ruq'ijul xtz'uk:
+pdfjs-document-properties-modification-date = Ruq'ijul xjalwachïx:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Q'inonel:
+pdfjs-document-properties-producer = PDF b'anöy:
+pdfjs-document-properties-version = PDF ruwäch:
+pdfjs-document-properties-page-count = Jarupe' ruxaq:
+pdfjs-document-properties-page-size = Runimilem ri Ruxaq:
+pdfjs-document-properties-page-size-unit-inches = pa
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = rupalem
+pdfjs-document-properties-page-size-orientation-landscape = rukotz'olem
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Loman wuj
+pdfjs-document-properties-page-size-name-legal = Taqanel tzijol
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Anin Rutz'etik Ajk'amaya'l:
+pdfjs-document-properties-linearized-yes = Ja'
+pdfjs-document-properties-linearized-no = Mani
+pdfjs-document-properties-close-button = Titz'apïx
+
+## Print
+
+pdfjs-print-progress-message = Ruchojmirisaxik wuj richin nitz'ajb'äx…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Tiq'at
+pdfjs-printing-not-supported = Rutzijol k'ayewal: Ri rutz'ajb'axik man koch'el ta ronojel pa re okik'amaya'l re'.
+pdfjs-printing-not-ready = Rutzijol k'ayewal: Ri PDF man xusamajij ta ronojel richin nitz'ajb'äx.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Tijal ri ajxikin kajtz'ik
+pdfjs-toggle-sidebar-notification-button =
+ .title = Tik'ex ri ajxikin yuqkajtz'ik (ri wuj eruk'wan taq ruchi'/taqo/kuchuj)
+pdfjs-toggle-sidebar-button-label = Tijal ri ajxikin kajtz'ik
+pdfjs-document-outline-button =
+ .title = Tik'ut pe ruch'akulal wuj (kamul-pitz'oj richin nirik'/nich'utinirisäx ronojel ruch'akulal)
+pdfjs-document-outline-button-label = Ruch'akulal wuj
+pdfjs-attachments-button =
+ .title = Kek'ut pe ri taq taqoj
+pdfjs-attachments-button-label = Taq taqoj
+pdfjs-layers-button =
+ .title = Kek'ut taq Kuchuj (ka'i'-pitz' richin yetzolïx ronojel ri taq kuchuj e k'o wi)
+pdfjs-layers-button-label = Taq kuchuj
+pdfjs-thumbs-button =
+ .title = Kek'ut pe taq ch'utiq
+pdfjs-thumbs-button-label = Koköj
+pdfjs-current-outline-item-button =
+ .title = Kekanöx Taq Ch'akulal Kik'wan Chib'äl
+pdfjs-current-outline-item-button-label = Taq Ch'akulal Kik'wan Chib'äl
+pdfjs-findbar-button =
+ .title = Tikanöx chupam ri wuj
+pdfjs-findbar-button-label = Tikanöx
+pdfjs-additional-layers = Tz'aqat ta Kuchuj
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Ruxaq { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Ruch'utinirisaxik ruxaq { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Tikanöx
+ .placeholder = Tikanöx pa wuj…
+pdfjs-find-previous-button =
+ .title = Tib'an b'enam pa ri jun kan q'aptzij xilitäj
+pdfjs-find-previous-button-label = Jun kan
+pdfjs-find-next-button =
+ .title = Tib'e pa ri jun chik pajtzij xilitäj
+pdfjs-find-next-button-label = Jun chik
+pdfjs-find-highlight-checkbox = Tiya' retal ronojel
+pdfjs-find-match-case-checkbox-label = Tuk'äm ri' kik'in taq nimatz'ib' chuqa' taq ch'utitz'ib'
+pdfjs-find-match-diacritics-checkbox-label = Tiya' Kikojol Tz'aqat taq Tz'ib'
+pdfjs-find-entire-word-checkbox-label = Tz'aqät taq tzij
+pdfjs-find-reached-top = Xb'eq'i' ri rutikirib'al wuj, xtikanöx k'a pa ruk'isib'äl
+pdfjs-find-reached-bottom = Xb'eq'i' ri ruk'isib'äl wuj, xtikanöx pa rutikirib'al
+pdfjs-find-not-found = Man xilitäj ta ri pajtzij
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ruwa ruxaq
+pdfjs-page-scale-fit = Tinuk' ruxaq
+pdfjs-page-scale-auto = Yonil chi nimilem
+pdfjs-page-scale-actual = Runimilem Wakami
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Ruxaq { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Xk'ulwachitäj jun sach'oj toq xnuk'ux ri PDF .
+pdfjs-invalid-file-error = Man oke ta o yujtajinäq ri PDF yakb'äl.
+pdfjs-missing-file-error = Man xilitäj ta ri PDF yakb'äl.
+pdfjs-unexpected-response-error = Man oyob'en ta tz'olin rutzij ruk'u'x samaj.
+pdfjs-rendering-error = Xk'ulwachitäj jun sachoj toq ninuk'wachij ri ruxaq.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Tz'ib'anïk]
+
+## Password
+
+pdfjs-password-label = Tatz'ib'aj ri ewan tzij richin najäq re yakb'äl re' pa PDF.
+pdfjs-password-invalid = Man okel ta ri ewan tzij: Tatojtob'ej chik.
+pdfjs-password-ok-button = Ãœtz
+pdfjs-password-cancel-button = Tiq'at
+pdfjs-web-fonts-disabled = E chupül ri taq ajk'amaya'l tz'ib': man tikirel ta nokisäx ri taq tz'ib' PDF pa ch'ikenïk
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Rucholajem tz'ib'
+pdfjs-editor-free-text-button-label = Rucholajem tz'ib'
+pdfjs-editor-ink-button =
+ .title = Tiwachib'ëx
+pdfjs-editor-ink-button-label = Tiwachib'ëx
+# Editor Parameters
+pdfjs-editor-free-text-color-input = B'onil
+pdfjs-editor-free-text-size-input = Nimilem
+pdfjs-editor-ink-color-input = B'onil
+pdfjs-editor-ink-thickness-input = Rupimil
+pdfjs-editor-ink-opacity-input = Q'equmal
+pdfjs-free-text =
+ .aria-label = Nuk'unel tz'ib'atzij
+pdfjs-free-text-default-content = Titikitisäx rutz'ib'axik…
+pdfjs-ink =
+ .aria-label = Nuk'unel wachib'äl
+pdfjs-ink-canvas =
+ .aria-label = Wachib'äl nuk'un ruma okisaxel
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ckb/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ckb/viewer.ftl
new file mode 100644
index 000000000..ae87335b8
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ckb/viewer.ftl
@@ -0,0 +1,242 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = پەڕەی پێشوو
+pdfjs-previous-button-label = پێشوو
+pdfjs-next-button =
+ .title = پەڕەی دوواتر
+pdfjs-next-button-label = دوواتر
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = پەرە
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = Ù„Û• { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } Ù„Û• { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ڕۆچوونی
+pdfjs-zoom-out-button-label = ڕۆچوونی
+pdfjs-zoom-in-button =
+ .title = هێنانەپێش
+pdfjs-zoom-in-button-label = هێنانەپێش
+pdfjs-zoom-select =
+ .title = زووم
+pdfjs-presentation-mode-button =
+ .title = گۆڕین بۆ دۆخی پێشکەشکردن
+pdfjs-presentation-mode-button-label = دۆخی پێشکەشکردن
+pdfjs-open-file-button =
+ .title = پەڕگە بکەرەوە
+pdfjs-open-file-button-label = کردنەوە
+pdfjs-print-button =
+ .title = چاپکردن
+pdfjs-print-button-label = چاپکردن
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ئامرازەکان
+pdfjs-tools-button-label = ئامرازەکان
+pdfjs-first-page-button =
+ .title = برۆ بۆ یەکەم پەڕە
+pdfjs-first-page-button-label = بڕۆ بۆ یەکەم پەڕە
+pdfjs-last-page-button =
+ .title = بڕۆ بۆ کۆتا پەڕە
+pdfjs-last-page-button-label = بڕۆ بۆ کۆتا پەڕە
+pdfjs-page-rotate-cw-button =
+ .title = ئاڕاستەی میلی کاتژمێر
+pdfjs-page-rotate-cw-button-label = ئاڕاستەی میلی کاتژمێر
+pdfjs-page-rotate-ccw-button =
+ .title = پێچەوانەی میلی کاتژمێر
+pdfjs-page-rotate-ccw-button-label = پێچەوانەی میلی کاتژمێر
+pdfjs-cursor-text-select-tool-button =
+ .title = توڵامرازی نیشانکەری دەق چالاک بکە
+pdfjs-cursor-text-select-tool-button-label = توڵامرازی نیشانکەری دەق
+pdfjs-cursor-hand-tool-button =
+ .title = توڵامرازی دەستی چالاک بکە
+pdfjs-cursor-hand-tool-button-label = توڵامرازی دەستی
+pdfjs-scroll-vertical-button =
+ .title = ناردنی ئەستوونی بەکاربێنە
+pdfjs-scroll-vertical-button-label = ناردنی ئەستوونی
+pdfjs-scroll-horizontal-button =
+ .title = ناردنی ئاسۆیی بەکاربێنە
+pdfjs-scroll-horizontal-button-label = ناردنی ئاسۆیی
+pdfjs-scroll-wrapped-button =
+ .title = ناردنی لوولکراو بەکاربێنە
+pdfjs-scroll-wrapped-button-label = ناردنی لوولکراو
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = تایبەتمەندییەکانی بەڵگەنامە...
+pdfjs-document-properties-button-label = تایبەتمەندییەکانی بەڵگەنامە...
+pdfjs-document-properties-file-name = ناوی پەڕگە:
+pdfjs-document-properties-file-size = قەبارەی پەڕگە:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } کب ({ $size_b } بایت)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } مب ({ $size_b } بایت)
+pdfjs-document-properties-title = سەردێڕ:
+pdfjs-document-properties-author = نووسەر
+pdfjs-document-properties-subject = بابەت:
+pdfjs-document-properties-keywords = کلیلەوشە:
+pdfjs-document-properties-creation-date = بەرواری درووستکردن:
+pdfjs-document-properties-modification-date = بەرواری دەستکاریکردن:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = درووستکەر:
+pdfjs-document-properties-producer = بەرهەمهێنەری PDF:
+pdfjs-document-properties-version = وەشانی PDF:
+pdfjs-document-properties-page-count = ژمارەی پەرەکان:
+pdfjs-document-properties-page-size = قەبارەی پەڕە:
+pdfjs-document-properties-page-size-unit-inches = ئینچ
+pdfjs-document-properties-page-size-unit-millimeters = ملم
+pdfjs-document-properties-page-size-orientation-portrait = پۆرترەیت(درێژ)
+pdfjs-document-properties-page-size-orientation-landscape = پانیی
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = نامە
+pdfjs-document-properties-page-size-name-legal = یاسایی
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = پیشاندانی وێبی خێرا:
+pdfjs-document-properties-linearized-yes = بەڵێ
+pdfjs-document-properties-linearized-no = نەخێر
+pdfjs-document-properties-close-button = داخستن
+
+## Print
+
+pdfjs-print-progress-message = بەڵگەنامە ئامادەدەکرێت بۆ چاپکردن...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = پاشگەزبوونەوە
+pdfjs-printing-not-supported = ئاگاداربە: چاپکردن بە تەواوی پشتگیر ناکرێت لەم وێبگەڕە.
+pdfjs-printing-not-ready = ئاگاداربە: PDF بە تەواوی بارنەبووە بۆ چاپکردن.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = لاتەنیشت پیشاندان/شاردنەوە
+pdfjs-toggle-sidebar-button-label = لاتەنیشت پیشاندان/شاردنەوە
+pdfjs-document-outline-button-label = سنووری چوارچێوە
+pdfjs-attachments-button =
+ .title = پاشکۆکان پیشان بدە
+pdfjs-attachments-button-label = پاشکۆکان
+pdfjs-layers-button-label = چینەکان
+pdfjs-thumbs-button =
+ .title = وێنۆچکە پیشان بدە
+pdfjs-thumbs-button-label = ÙˆÛŽÙ†Û†Ú†Ú©Û•
+pdfjs-findbar-button =
+ .title = لە بەڵگەنامە بگەرێ
+pdfjs-findbar-button-label = دۆزینەوە
+pdfjs-additional-layers = چینی زیاتر
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = پەڕەی { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = وێنۆچکەی پەڕەی { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = دۆزینەوە
+ .placeholder = لە بەڵگەنامە بگەرێ...
+pdfjs-find-previous-button =
+ .title = هەبوونی پێشوو بدۆزرەوە لە ڕستەکەدا
+pdfjs-find-previous-button-label = پێشوو
+pdfjs-find-next-button =
+ .title = هەبوونی داهاتوو بدۆزەرەوە لە ڕستەکەدا
+pdfjs-find-next-button-label = دوواتر
+pdfjs-find-highlight-checkbox = هەمووی نیشانە بکە
+pdfjs-find-match-case-checkbox-label = دۆخی لەیەکچوون
+pdfjs-find-entire-word-checkbox-label = هەموو وشەکان
+pdfjs-find-reached-top = گەشتیتە سەرەوەی بەڵگەنامە، لە خوارەوە دەستت پێکرد
+pdfjs-find-reached-bottom = گەشتیتە کۆتایی بەڵگەنامە. لەسەرەوە دەستت پێکرد
+pdfjs-find-not-found = نووسین نەدۆزرایەوە
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = پانی پەڕە
+pdfjs-page-scale-fit = پڕبوونی پەڕە
+pdfjs-page-scale-auto = زوومی خۆکار
+pdfjs-page-scale-actual = قەبارەی ڕاستی
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = هەڵەیەک ڕوویدا لە کاتی بارکردنی PDF.
+pdfjs-invalid-file-error = پەڕگەی pdf تێکچووە یان نەگونجاوە.
+pdfjs-missing-file-error = پەڕگەی pdf بوونی نیە.
+pdfjs-unexpected-response-error = وەڵامی ڕاژەخوازی نەخوازراو.
+pdfjs-rendering-error = هەڵەیەک ڕوویدا لە کاتی پوختەکردنی (ڕێندەر) پەڕە.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } سەرنج]
+
+## Password
+
+pdfjs-password-label = وشەی تێپەڕ بنووسە بۆ کردنەوەی پەڕگەی pdf.
+pdfjs-password-invalid = وشەی تێپەڕ هەڵەیە. تکایە دووبارە هەوڵ بدەرەوە.
+pdfjs-password-ok-button = باشە
+pdfjs-password-cancel-button = پاشگەزبوونەوە
+pdfjs-web-fonts-disabled = جۆرەپیتی وێب ناچالاکە: نەتوانی جۆرەپیتی تێخراوی ناو pdfـەکە بەکاربێت.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/cs/viewer.ftl b/www/lib/pdfjs/modern/web/locale/cs/viewer.ftl
new file mode 100644
index 000000000..13b8f49bb
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/cs/viewer.ftl
@@ -0,0 +1,388 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Přejde na předchozà stránku
+pdfjs-previous-button-label = PÅ™edchozÃ
+pdfjs-next-button =
+ .title = PÅ™ejde na následujÃcà stránku
+pdfjs-next-button-label = DalÅ¡Ã
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Stránka
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = z { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } z { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zmenšà velikost
+pdfjs-zoom-out-button-label = Zmenšit
+pdfjs-zoom-in-button =
+ .title = Zvětšà velikost
+pdfjs-zoom-in-button-label = Zvětšit
+pdfjs-zoom-select =
+ .title = Nastavà velikost
+pdfjs-presentation-mode-button =
+ .title = Přepne do režimu prezentace
+pdfjs-presentation-mode-button-label = Režim prezentace
+pdfjs-open-file-button =
+ .title = Otevře soubor
+pdfjs-open-file-button-label = OtevÅ™Ãt
+pdfjs-print-button =
+ .title = Vytiskne dokument
+pdfjs-print-button-label = Vytisknout
+pdfjs-save-button =
+ .title = Uložit
+pdfjs-save-button-label = Uložit
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Stáhnout
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Stáhnout
+pdfjs-bookmark-button =
+ .title = Aktuálnà stránka (zobrazit URL od aktuálnà stránky)
+pdfjs-bookmark-button-label = Aktuálnà stránka
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = OtevÅ™Ãt v aplikaci
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = OtevÅ™Ãt v aplikaci
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Nástroje
+pdfjs-tools-button-label = Nástroje
+pdfjs-first-page-button =
+ .title = Přejde na prvnà stránku
+pdfjs-first-page-button-label = PÅ™ejÃt na prvnà stránku
+pdfjs-last-page-button =
+ .title = Přejde na poslednà stránku
+pdfjs-last-page-button-label = PÅ™ejÃt na poslednà stránku
+pdfjs-page-rotate-cw-button =
+ .title = OtoÄà po smÄ›ru hodin
+pdfjs-page-rotate-cw-button-label = OtoÄit po smÄ›ru hodin
+pdfjs-page-rotate-ccw-button =
+ .title = OtoÄà proti smÄ›ru hodin
+pdfjs-page-rotate-ccw-button-label = OtoÄit proti smÄ›ru hodin
+pdfjs-cursor-text-select-tool-button =
+ .title = Povolà výběr textu
+pdfjs-cursor-text-select-tool-button-label = Výběr textu
+pdfjs-cursor-hand-tool-button =
+ .title = Povolà nástroj ruÄiÄka
+pdfjs-cursor-hand-tool-button-label = Nástroj ruÄiÄka
+pdfjs-scroll-page-button =
+ .title = Posouvat po stránkách
+pdfjs-scroll-page-button-label = Posouvánà po stránkách
+pdfjs-scroll-vertical-button =
+ .title = PoužÃt svislé posouvánÃ
+pdfjs-scroll-vertical-button-label = Svislé posouvánÃ
+pdfjs-scroll-horizontal-button =
+ .title = PoužÃt vodorovné posouvánÃ
+pdfjs-scroll-horizontal-button-label = Vodorovné posouvánÃ
+pdfjs-scroll-wrapped-button =
+ .title = PoužÃt postupné posouvánÃ
+pdfjs-scroll-wrapped-button-label = Postupné posouvánÃ
+pdfjs-spread-none-button =
+ .title = Nesdružovat stránky
+pdfjs-spread-none-button-label = Žádné sdruženÃ
+pdfjs-spread-odd-button =
+ .title = Sdružà stránky s umÃstÄ›nÃm lichých vlevo
+pdfjs-spread-odd-button-label = Sdruženà stránek (liché vlevo)
+pdfjs-spread-even-button =
+ .title = Sdružà stránky s umÃstÄ›nÃm sudých vlevo
+pdfjs-spread-even-button-label = Sdruženà stránek (sudé vlevo)
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Vlastnosti dokumentu…
+pdfjs-document-properties-button-label = Vlastnosti dokumentu…
+pdfjs-document-properties-file-name = Název souboru:
+pdfjs-document-properties-file-size = Velikost souboru:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajtů)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtů)
+pdfjs-document-properties-title = Název stránky:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Předmět:
+pdfjs-document-properties-keywords = KlÃÄová slova:
+pdfjs-document-properties-creation-date = Datum vytvoÅ™enÃ:
+pdfjs-document-properties-modification-date = Datum úpravy:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Vytvořil:
+pdfjs-document-properties-producer = Tvůrce PDF:
+pdfjs-document-properties-version = Verze PDF:
+pdfjs-document-properties-page-count = PoÄet stránek:
+pdfjs-document-properties-page-size = Velikost stránky:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = na výšku
+pdfjs-document-properties-page-size-orientation-landscape = na Å¡ÃÅ™ku
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Dopis
+pdfjs-document-properties-page-size-name-legal = Právnà dokument
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Rychlé zobrazovánà z webu:
+pdfjs-document-properties-linearized-yes = Ano
+pdfjs-document-properties-linearized-no = Ne
+pdfjs-document-properties-close-button = ZavÅ™Ãt
+
+## Print
+
+pdfjs-print-progress-message = PÅ™Ãprava dokumentu pro tisk…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress } %
+pdfjs-print-progress-close-button = Zrušit
+pdfjs-printing-not-supported = UpozornÄ›nÃ: Tisk nenà v tomto prohlÞeÄi plnÄ› podporován.
+pdfjs-printing-not-ready = UpozornÄ›nÃ: Dokument PDF nenà kompletnÄ› naÄten.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Postrannà lišta
+pdfjs-toggle-sidebar-notification-button =
+ .title = PÅ™epnout postrannà liÅ¡tu (dokument obsahuje osnovu/pÅ™Ãlohy/vrstvy)
+pdfjs-toggle-sidebar-button-label = Postrannà lišta
+pdfjs-document-outline-button =
+ .title = Zobrazà osnovu dokumentu (poklepánà přepne zobrazenà všech položek)
+pdfjs-document-outline-button-label = Osnova dokumentu
+pdfjs-attachments-button =
+ .title = Zobrazà pÅ™Ãlohy
+pdfjs-attachments-button-label = PÅ™Ãlohy
+pdfjs-layers-button =
+ .title = Zobrazit vrstvy (poklepánÃm obnovÃte vÅ¡echny vrstvy do výchozÃho stavu)
+pdfjs-layers-button-label = Vrstvy
+pdfjs-thumbs-button =
+ .title = Zobrazà náhledy
+pdfjs-thumbs-button-label = Náhledy
+pdfjs-current-outline-item-button =
+ .title = NajÃt aktuálnà položku v osnovÄ›
+pdfjs-current-outline-item-button-label = Aktuálnà položka v osnově
+pdfjs-findbar-button =
+ .title = Najde v dokumentu
+pdfjs-findbar-button-label = NajÃt
+pdfjs-additional-layers = Dalšà vrstvy
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Strana { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Náhled strany { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = NajÃt
+ .placeholder = NajÃt v dokumentu…
+pdfjs-find-previous-button =
+ .title = Najde předchozà výskyt hledaného textu
+pdfjs-find-previous-button-label = PÅ™edchozÃ
+pdfjs-find-next-button =
+ .title = Najde dalšà výskyt hledaného textu
+pdfjs-find-next-button-label = DalÅ¡Ã
+pdfjs-find-highlight-checkbox = Zvýraznit
+pdfjs-find-match-case-checkbox-label = Rozlišovat velikost
+pdfjs-find-match-diacritics-checkbox-label = Rozlišovat diakritiku
+pdfjs-find-entire-word-checkbox-label = Celá slova
+pdfjs-find-reached-top = Dosažen zaÄátek dokumentu, pokraÄuje se od konce
+pdfjs-find-reached-bottom = Dosažen konec dokumentu, pokraÄuje se od zaÄátku
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current }. z { $total } výskytu
+ [few] { $current }. z { $total } výskytů
+ [many] { $current }. z { $total } výskytů
+ *[other] { $current }. z { $total } výskytů
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] VÃce než { $limit } výskyt
+ [few] VÃce než { $limit } výskyty
+ [many] VÃce než { $limit } výskytů
+ *[other] VÃce než { $limit } výskytů
+ }
+pdfjs-find-not-found = Hledaný text nenalezen
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Podle Å¡ÃÅ™ky
+pdfjs-page-scale-fit = Podle výšky
+pdfjs-page-scale-auto = Automatická velikost
+pdfjs-page-scale-actual = SkuteÄná velikost
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Strana { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Při nahrávánà PDF nastala chyba.
+pdfjs-invalid-file-error = Neplatný nebo chybný soubor PDF.
+pdfjs-missing-file-error = Chybà soubor PDF.
+pdfjs-unexpected-response-error = NeoÄekávaná odpovÄ›Ä serveru.
+pdfjs-rendering-error = Při vykreslovánà stránky nastala chyba.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotace typu { $type }]
+
+## Password
+
+pdfjs-password-label = Pro otevřenà PDF souboru vložte heslo.
+pdfjs-password-invalid = Neplatné heslo. Zkuste to znovu.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Zrušit
+pdfjs-web-fonts-disabled = Webová pÃsma jsou zakázána, proto nenà možné použÃt vložená pÃsma PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = KreslenÃ
+pdfjs-editor-ink-button-label = KreslenÃ
+pdfjs-editor-stamp-button =
+ .title = PÅ™idánà Äi úprava obrázků
+pdfjs-editor-stamp-button-label = PÅ™idánà Äi úprava obrázků
+pdfjs-editor-remove-button =
+ .title = Odebrat
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Odebrat kresbu
+pdfjs-editor-remove-freetext-button =
+ .title = Odebrat text
+pdfjs-editor-remove-stamp-button =
+ .title = Odebrat obrázek
+pdfjs-editor-remove-highlight-button =
+ .title = Odebrat zvýraznÄ›nÃ
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Barva
+pdfjs-editor-free-text-size-input = Velikost
+pdfjs-editor-ink-color-input = Barva
+pdfjs-editor-ink-thickness-input = Tloušťka
+pdfjs-editor-ink-opacity-input = Průhlednost
+pdfjs-editor-stamp-add-image-button =
+ .title = Přidat obrázek
+pdfjs-editor-stamp-add-image-button-label = Přidat obrázek
+pdfjs-free-text =
+ .aria-label = Textový editor
+pdfjs-free-text-default-content = ZaÄnÄ›te psát…
+pdfjs-ink =
+ .aria-label = Editor kreslenÃ
+pdfjs-ink-canvas =
+ .aria-label = Uživatelem vytvořený obrázek
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Náhradnà popis
+pdfjs-editor-alt-text-edit-button-label = Upravit náhradnà popis
+pdfjs-editor-alt-text-dialog-label = Vyberte možnost
+pdfjs-editor-alt-text-dialog-description = Náhradnà popis pomáhá, když lidé obrázek nevidà nebo když se nenaÄÃtá.
+pdfjs-editor-alt-text-add-description-label = Přidat popis
+pdfjs-editor-alt-text-add-description-description = Snažte se o 1-2 vÄ›ty, které popisujà pÅ™edmÄ›t, prostÅ™edà nebo Äinnosti.
+pdfjs-editor-alt-text-mark-decorative-label = OznaÄit jako dekorativnÃ
+pdfjs-editor-alt-text-mark-decorative-description = PoužÃvá se pro okrasné obrázky, jako jsou rámeÄky nebo vodoznaky.
+pdfjs-editor-alt-text-cancel-button = Zrušit
+pdfjs-editor-alt-text-save-button = Uložit
+pdfjs-editor-alt-text-decorative-tooltip = OznaÄen jako dekorativnÃ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = NapÅ™Ãklad: “Mladý muž si sedá ke stolu, aby se najedl.â€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Levý hornà roh — změna velikosti
+pdfjs-editor-resizer-label-top-middle = Hornà střed — změna velikosti
+pdfjs-editor-resizer-label-top-right = Pravý hornà roh — změna velikosti
+pdfjs-editor-resizer-label-middle-right = Vpravo uprostřed — změna velikosti
+pdfjs-editor-resizer-label-bottom-right = Pravý dolnà roh — změna velikosti
+pdfjs-editor-resizer-label-bottom-middle = Střed dole — změna velikosti
+pdfjs-editor-resizer-label-bottom-left = Levý dolnà roh — změna velikosti
+pdfjs-editor-resizer-label-middle-left = Vlevo uprostřed — změna velikosti
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Barva zvýraznÄ›nÃ
+pdfjs-editor-colorpicker-button =
+ .title = Změna barvy
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Výběr barev
+pdfjs-editor-colorpicker-yellow =
+ .title = Žlutá
+pdfjs-editor-colorpicker-green =
+ .title = Zelená
+pdfjs-editor-colorpicker-blue =
+ .title = Modrá
+pdfjs-editor-colorpicker-pink =
+ .title = Růžová
+pdfjs-editor-colorpicker-red =
+ .title = Červená
diff --git a/www/lib/pdfjs/modern/web/locale/cy/viewer.ftl b/www/lib/pdfjs/modern/web/locale/cy/viewer.ftl
new file mode 100644
index 000000000..993162927
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/cy/viewer.ftl
@@ -0,0 +1,392 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Tudalen Flaenorol
+pdfjs-previous-button-label = Blaenorol
+pdfjs-next-button =
+ .title = Tudalen Nesaf
+pdfjs-next-button-label = Nesaf
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Tudalen
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = o { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } o { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Chwyddo Allan
+pdfjs-zoom-out-button-label = Chwyddo Allan
+pdfjs-zoom-in-button =
+ .title = Chwyddo Mewn
+pdfjs-zoom-in-button-label = Chwyddo Mewn
+pdfjs-zoom-select =
+ .title = Chwyddo
+pdfjs-presentation-mode-button =
+ .title = Newid i'r Modd Cyflwyno
+pdfjs-presentation-mode-button-label = Modd Cyflwyno
+pdfjs-open-file-button =
+ .title = Agor Ffeil
+pdfjs-open-file-button-label = Agor
+pdfjs-print-button =
+ .title = Argraffu
+pdfjs-print-button-label = Argraffu
+pdfjs-save-button =
+ .title = Cadw
+pdfjs-save-button-label = Cadw
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Llwytho i Lawr
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Llwytho i Lawr
+pdfjs-bookmark-button =
+ .title = Tudalen Gyfredol (Gweld URL o'r Dudalen Gyfredol)
+pdfjs-bookmark-button-label = Tudalen Gyfredol
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Agor yn yr ap
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Agor yn yr ap
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Offer
+pdfjs-tools-button-label = Offer
+pdfjs-first-page-button =
+ .title = Mynd i'r Dudalen Gyntaf
+pdfjs-first-page-button-label = Mynd i'r Dudalen Gyntaf
+pdfjs-last-page-button =
+ .title = Mynd i'r Dudalen Olaf
+pdfjs-last-page-button-label = Mynd i'r Dudalen Olaf
+pdfjs-page-rotate-cw-button =
+ .title = Cylchdroi Clocwedd
+pdfjs-page-rotate-cw-button-label = Cylchdroi Clocwedd
+pdfjs-page-rotate-ccw-button =
+ .title = Cylchdroi Gwrthglocwedd
+pdfjs-page-rotate-ccw-button-label = Cylchdroi Gwrthglocwedd
+pdfjs-cursor-text-select-tool-button =
+ .title = Galluogi Dewis Offeryn Testun
+pdfjs-cursor-text-select-tool-button-label = Offeryn Dewis Testun
+pdfjs-cursor-hand-tool-button =
+ .title = Galluogi Offeryn Llaw
+pdfjs-cursor-hand-tool-button-label = Offeryn Llaw
+pdfjs-scroll-page-button =
+ .title = Defnyddio Sgrolio Tudalen
+pdfjs-scroll-page-button-label = Sgrolio Tudalen
+pdfjs-scroll-vertical-button =
+ .title = Defnyddio Sgrolio Fertigol
+pdfjs-scroll-vertical-button-label = Sgrolio Fertigol
+pdfjs-scroll-horizontal-button =
+ .title = Defnyddio Sgrolio Llorweddol
+pdfjs-scroll-horizontal-button-label = Sgrolio Llorweddol
+pdfjs-scroll-wrapped-button =
+ .title = Defnyddio Sgrolio Amlapio
+pdfjs-scroll-wrapped-button-label = Sgrolio Amlapio
+pdfjs-spread-none-button =
+ .title = Peidio uno trawsdaleniadau
+pdfjs-spread-none-button-label = Dim Trawsdaleniadau
+pdfjs-spread-odd-button =
+ .title = Uno trawsdaleniadau gan gychwyn gyda thudalennau odrif
+pdfjs-spread-odd-button-label = Trawsdaleniadau Odrif
+pdfjs-spread-even-button =
+ .title = Uno trawsdaleniadau gan gychwyn gyda thudalennau eilrif
+pdfjs-spread-even-button-label = Trawsdaleniadau Eilrif
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Priodweddau Dogfen…
+pdfjs-document-properties-button-label = Priodweddau Dogfen…
+pdfjs-document-properties-file-name = Enw ffeil:
+pdfjs-document-properties-file-size = Maint ffeil:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } beit)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } beit)
+pdfjs-document-properties-title = Teitl:
+pdfjs-document-properties-author = Awdur:
+pdfjs-document-properties-subject = Pwnc:
+pdfjs-document-properties-keywords = Allweddair:
+pdfjs-document-properties-creation-date = Dyddiad Creu:
+pdfjs-document-properties-modification-date = Dyddiad Addasu:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Crewr:
+pdfjs-document-properties-producer = Cynhyrchydd PDF:
+pdfjs-document-properties-version = Fersiwn PDF:
+pdfjs-document-properties-page-count = Cyfrif Tudalen:
+pdfjs-document-properties-page-size = Maint Tudalen:
+pdfjs-document-properties-page-size-unit-inches = o fewn
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portread
+pdfjs-document-properties-page-size-orientation-landscape = tirlun
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Llythyr
+pdfjs-document-properties-page-size-name-legal = Cyfreithiol
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Golwg Gwe Cyflym:
+pdfjs-document-properties-linearized-yes = Iawn
+pdfjs-document-properties-linearized-no = Na
+pdfjs-document-properties-close-button = Cau
+
+## Print
+
+pdfjs-print-progress-message = Paratoi dogfen ar gyfer ei hargraffu…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Diddymu
+pdfjs-printing-not-supported = Rhybudd: Nid yw argraffu yn cael ei gynnal yn llawn gan y porwr.
+pdfjs-printing-not-ready = Rhybudd: Nid yw'r PDF wedi ei lwytho'n llawn ar gyfer argraffu.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toglo'r Bar Ochr
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toglo'r Bar Ochr (mae'r ddogfen yn cynnwys amlinelliadau/atodiadau/haenau)
+pdfjs-toggle-sidebar-button-label = Toglo'r Bar Ochr
+pdfjs-document-outline-button =
+ .title = Dangos Amlinell Dogfen (clic dwbl i ymestyn/cau pob eitem)
+pdfjs-document-outline-button-label = Amlinelliad Dogfen
+pdfjs-attachments-button =
+ .title = Dangos Atodiadau
+pdfjs-attachments-button-label = Atodiadau
+pdfjs-layers-button =
+ .title = Dangos Haenau (cliciwch ddwywaith i ailosod yr holl haenau i'r cyflwr rhagosodedig)
+pdfjs-layers-button-label = Haenau
+pdfjs-thumbs-button =
+ .title = Dangos Lluniau Bach
+pdfjs-thumbs-button-label = Lluniau Bach
+pdfjs-current-outline-item-button =
+ .title = Canfod yr Eitem Amlinellol Gyfredol
+pdfjs-current-outline-item-button-label = Yr Eitem Amlinellol Gyfredol
+pdfjs-findbar-button =
+ .title = Canfod yn y Ddogfen
+pdfjs-findbar-button-label = Canfod
+pdfjs-additional-layers = Haenau Ychwanegol
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Tudalen { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Llun Bach Tudalen { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Canfod
+ .placeholder = Canfod yn y ddogfen…
+pdfjs-find-previous-button =
+ .title = Canfod enghraifft flaenorol o'r ymadrodd
+pdfjs-find-previous-button-label = Blaenorol
+pdfjs-find-next-button =
+ .title = Canfod enghraifft nesaf yr ymadrodd
+pdfjs-find-next-button-label = Nesaf
+pdfjs-find-highlight-checkbox = Amlygu Popeth
+pdfjs-find-match-case-checkbox-label = Cydweddu Maint
+pdfjs-find-match-diacritics-checkbox-label = Diacritigau Cyfatebol
+pdfjs-find-entire-word-checkbox-label = Geiriau Cyfan
+pdfjs-find-reached-top = Wedi cyrraedd brig y dudalen, parhau o'r gwaelod
+pdfjs-find-reached-bottom = Wedi cyrraedd diwedd y dudalen, parhau o'r brig
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [zero] { $current } o { $total } cydweddiadau
+ [one] { $current } o { $total } cydweddiad
+ [two] { $current } o { $total } gydweddiad
+ [few] { $current } o { $total } cydweddiad
+ [many] { $current } o { $total } chydweddiad
+ *[other] { $current } o { $total } cydweddiad
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [zero] Mwy nag { $limit } cydweddiadau
+ [one] Mwy nag { $limit } cydweddiad
+ [two] Mwy nag { $limit } gydweddiad
+ [few] Mwy nag { $limit } cydweddiad
+ [many] Mwy nag { $limit } chydweddiad
+ *[other] Mwy nag { $limit } cydweddiad
+ }
+pdfjs-find-not-found = Heb ganfod ymadrodd
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lled Tudalen
+pdfjs-page-scale-fit = Ffit Tudalen
+pdfjs-page-scale-auto = Chwyddo Awtomatig
+pdfjs-page-scale-actual = Maint Gwirioneddol
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Tudalen { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Digwyddodd gwall wrth lwytho'r PDF.
+pdfjs-invalid-file-error = Ffeil PDF annilys neu llwgr.
+pdfjs-missing-file-error = Ffeil PDF coll.
+pdfjs-unexpected-response-error = Ymateb annisgwyl gan y gweinydd.
+pdfjs-rendering-error = Digwyddodd gwall wrth adeiladu'r dudalen.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anodiad { $type } ]
+
+## Password
+
+pdfjs-password-label = Rhowch gyfrinair i agor y PDF.
+pdfjs-password-invalid = Cyfrinair annilys. Ceisiwch eto.
+pdfjs-password-ok-button = Iawn
+pdfjs-password-cancel-button = Diddymu
+pdfjs-web-fonts-disabled = Ffontiau gwe wedi eu hanalluogi: methu defnyddio ffontiau PDF mewnblanedig.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Testun
+pdfjs-editor-free-text-button-label = Testun
+pdfjs-editor-ink-button =
+ .title = Lluniadu
+pdfjs-editor-ink-button-label = Lluniadu
+pdfjs-editor-stamp-button =
+ .title = Ychwanegu neu olygu delweddau
+pdfjs-editor-stamp-button-label = Ychwanegu neu olygu delweddau
+pdfjs-editor-remove-button =
+ .title = Tynnu
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Dileu lluniad
+pdfjs-editor-remove-freetext-button =
+ .title = Dileu testun
+pdfjs-editor-remove-stamp-button =
+ .title = Dileu delwedd
+pdfjs-editor-remove-highlight-button =
+ .title = Tynnu amlygiad
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Lliw
+pdfjs-editor-free-text-size-input = Maint
+pdfjs-editor-ink-color-input = Lliw
+pdfjs-editor-ink-thickness-input = Trwch
+pdfjs-editor-ink-opacity-input = Didreiddedd
+pdfjs-editor-stamp-add-image-button =
+ .title = Ychwanegu delwedd
+pdfjs-editor-stamp-add-image-button-label = Ychwanegu delwedd
+pdfjs-free-text =
+ .aria-label = Golygydd Testun
+pdfjs-free-text-default-content = Cychwyn teipio…
+pdfjs-ink =
+ .aria-label = Golygydd Lluniadu
+pdfjs-ink-canvas =
+ .aria-label = Delwedd wedi'i chreu gan ddefnyddwyr
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Testun amgen (alt)
+pdfjs-editor-alt-text-edit-button-label = Golygu testun amgen
+pdfjs-editor-alt-text-dialog-label = Dewisiadau
+pdfjs-editor-alt-text-dialog-description = Mae testun amgen (testun alt) yn helpu pan na all pobl weld y ddelwedd neu pan nad yw'n llwytho.
+pdfjs-editor-alt-text-add-description-label = Ychwanegu disgrifiad
+pdfjs-editor-alt-text-add-description-description = Anelwch at 1-2 frawddeg sy'n disgrifio'r pwnc, y cefndir neu'r gweithredoedd.
+pdfjs-editor-alt-text-mark-decorative-label = Marcio fel addurniadol
+pdfjs-editor-alt-text-mark-decorative-description = Mae'n cael ei ddefnyddio ar gyfer delweddau addurniadol, fel borderi neu farciau dŵr.
+pdfjs-editor-alt-text-cancel-button = Diddymu
+pdfjs-editor-alt-text-save-button = Cadw
+pdfjs-editor-alt-text-decorative-tooltip = Marcio fel addurniadol
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Er enghraifft, “Mae dyn ifanc yn eistedd wrth fwrdd i fwyta pryd bwydâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Y gornel chwith uchaf — newid maint
+pdfjs-editor-resizer-label-top-middle = Canol uchaf - newid maint
+pdfjs-editor-resizer-label-top-right = Y gornel dde uchaf - newid maint
+pdfjs-editor-resizer-label-middle-right = De canol - newid maint
+pdfjs-editor-resizer-label-bottom-right = Y gornel dde isaf — newid maint
+pdfjs-editor-resizer-label-bottom-middle = Canol gwaelod — newid maint
+pdfjs-editor-resizer-label-bottom-left = Y gornel chwith isaf — newid maint
+pdfjs-editor-resizer-label-middle-left = Chwith canol — newid maint
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Lliw amlygu
+pdfjs-editor-colorpicker-button =
+ .title = Newid lliw
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Dewisiadau lliw
+pdfjs-editor-colorpicker-yellow =
+ .title = Melyn
+pdfjs-editor-colorpicker-green =
+ .title = Gwyrdd
+pdfjs-editor-colorpicker-blue =
+ .title = Glas
+pdfjs-editor-colorpicker-pink =
+ .title = Pinc
+pdfjs-editor-colorpicker-red =
+ .title = Coch
diff --git a/www/lib/pdfjs/modern/web/locale/da/viewer.ftl b/www/lib/pdfjs/modern/web/locale/da/viewer.ftl
new file mode 100644
index 000000000..f592ad706
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/da/viewer.ftl
@@ -0,0 +1,363 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Forrige side
+pdfjs-previous-button-label = Forrige
+pdfjs-next-button =
+ .title = Næste side
+pdfjs-next-button-label = Næste
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Side
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = af { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } af { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom ud
+pdfjs-zoom-out-button-label = Zoom ud
+pdfjs-zoom-in-button =
+ .title = Zoom ind
+pdfjs-zoom-in-button-label = Zoom ind
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Skift til fuldskærmsvisning
+pdfjs-presentation-mode-button-label = Fuldskærmsvisning
+pdfjs-open-file-button =
+ .title = Ã…bn fil
+pdfjs-open-file-button-label = Ã…bn
+pdfjs-print-button =
+ .title = Udskriv
+pdfjs-print-button-label = Udskriv
+pdfjs-save-button =
+ .title = Gem
+pdfjs-save-button-label = Gem
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Hent
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Hent
+pdfjs-bookmark-button =
+ .title = Aktuel side (vis URL fra den aktuelle side)
+pdfjs-bookmark-button-label = Aktuel side
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ã…bn i app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ã…bn i app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Funktioner
+pdfjs-tools-button-label = Funktioner
+pdfjs-first-page-button =
+ .title = Gå til første side
+pdfjs-first-page-button-label = Gå til første side
+pdfjs-last-page-button =
+ .title = GÃ¥ til sidste side
+pdfjs-last-page-button-label = GÃ¥ til sidste side
+pdfjs-page-rotate-cw-button =
+ .title = Roter med uret
+pdfjs-page-rotate-cw-button-label = Roter med uret
+pdfjs-page-rotate-ccw-button =
+ .title = Roter mod uret
+pdfjs-page-rotate-ccw-button-label = Roter mod uret
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktiver markeringsværktøj
+pdfjs-cursor-text-select-tool-button-label = Markeringsværktøj
+pdfjs-cursor-hand-tool-button =
+ .title = Aktiver håndværktøj
+pdfjs-cursor-hand-tool-button-label = Håndværktøj
+pdfjs-scroll-page-button =
+ .title = Brug sidescrolling
+pdfjs-scroll-page-button-label = Sidescrolling
+pdfjs-scroll-vertical-button =
+ .title = Brug vertikal scrolling
+pdfjs-scroll-vertical-button-label = Vertikal scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Brug horisontal scrolling
+pdfjs-scroll-horizontal-button-label = Horisontal scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Brug ombrudt scrolling
+pdfjs-scroll-wrapped-button-label = Ombrudt scrolling
+pdfjs-spread-none-button =
+ .title = Vis enkeltsider
+pdfjs-spread-none-button-label = Enkeltsider
+pdfjs-spread-odd-button =
+ .title = Vis opslag med ulige sidenumre til venstre
+pdfjs-spread-odd-button-label = Opslag med forside
+pdfjs-spread-even-button =
+ .title = Vis opslag med lige sidenumre til venstre
+pdfjs-spread-even-button-label = Opslag uden forside
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentegenskaber…
+pdfjs-document-properties-button-label = Dokumentegenskaber…
+pdfjs-document-properties-file-name = Filnavn:
+pdfjs-document-properties-file-size = Filstørrelse:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Forfatter:
+pdfjs-document-properties-subject = Emne:
+pdfjs-document-properties-keywords = Nøgleord:
+pdfjs-document-properties-creation-date = Oprettet:
+pdfjs-document-properties-modification-date = Redigeret:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Program:
+pdfjs-document-properties-producer = PDF-producent:
+pdfjs-document-properties-version = PDF-version:
+pdfjs-document-properties-page-count = Antal sider:
+pdfjs-document-properties-page-size = Sidestørrelse:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = stående
+pdfjs-document-properties-page-size-orientation-landscape = liggende
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Hurtig web-visning:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nej
+pdfjs-document-properties-close-button = Luk
+
+## Print
+
+pdfjs-print-progress-message = Forbereder dokument til udskrivning…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Annuller
+pdfjs-printing-not-supported = Advarsel: Udskrivning er ikke fuldt understøttet af browseren.
+pdfjs-printing-not-ready = Advarsel: PDF-filen er ikke fuldt indlæst til udskrivning.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Slå sidepanel til eller fra
+pdfjs-toggle-sidebar-notification-button =
+ .title = Slå sidepanel til eller fra (dokumentet indeholder disposition/vedhæftede filer/lag)
+pdfjs-toggle-sidebar-button-label = Slå sidepanel til eller fra
+pdfjs-document-outline-button =
+ .title = Vis dokumentets disposition (dobbeltklik for at vise/skjule alle elementer)
+pdfjs-document-outline-button-label = Dokument-disposition
+pdfjs-attachments-button =
+ .title = Vis vedhæftede filer
+pdfjs-attachments-button-label = Vedhæftede filer
+pdfjs-layers-button =
+ .title = Vis lag (dobbeltklik for at nulstille alle lag til standard-tilstanden)
+pdfjs-layers-button-label = Lag
+pdfjs-thumbs-button =
+ .title = Vis miniaturer
+pdfjs-thumbs-button-label = Miniaturer
+pdfjs-current-outline-item-button =
+ .title = Find det aktuelle dispositions-element
+pdfjs-current-outline-item-button-label = Aktuelt dispositions-element
+pdfjs-findbar-button =
+ .title = Find i dokument
+pdfjs-findbar-button-label = Find
+pdfjs-additional-layers = Yderligere lag
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Side { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniature af side { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find i dokument…
+pdfjs-find-previous-button =
+ .title = Find den forrige forekomst
+pdfjs-find-previous-button-label = Forrige
+pdfjs-find-next-button =
+ .title = Find den næste forekomst
+pdfjs-find-next-button-label = Næste
+pdfjs-find-highlight-checkbox = Fremhæv alle
+pdfjs-find-match-case-checkbox-label = Forskel på store og små bogstaver
+pdfjs-find-match-diacritics-checkbox-label = Diakritiske tegn
+pdfjs-find-entire-word-checkbox-label = Hele ord
+pdfjs-find-reached-top = Toppen af siden blev nået, fortsatte fra bunden
+pdfjs-find-reached-bottom = Bunden af siden blev nået, fortsatte fra toppen
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } af { $total } forekomst
+ *[other] { $current } af { $total } forekomster
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mere end { $limit } forekomst
+ *[other] Mere end { $limit } forekomster
+ }
+pdfjs-find-not-found = Der blev ikke fundet noget
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sidebredde
+pdfjs-page-scale-fit = Tilpas til side
+pdfjs-page-scale-auto = Automatisk zoom
+pdfjs-page-scale-actual = Faktisk størrelse
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Side { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Der opstod en fejl ved indlæsning af PDF-filen.
+pdfjs-invalid-file-error = PDF-filen er ugyldig eller ødelagt.
+pdfjs-missing-file-error = Manglende PDF-fil.
+pdfjs-unexpected-response-error = Uventet svar fra serveren.
+pdfjs-rendering-error = Der opstod en fejl ved generering af siden.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }kommentar]
+
+## Password
+
+pdfjs-password-label = Angiv adgangskode til at åbne denne PDF-fil.
+pdfjs-password-invalid = Ugyldig adgangskode. Prøv igen.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Fortryd
+pdfjs-web-fonts-disabled = Webskrifttyper er deaktiverede. De indlejrede skrifttyper i PDF-filen kan ikke anvendes.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Tegn
+pdfjs-editor-ink-button-label = Tegn
+pdfjs-editor-stamp-button =
+ .title = Tilføj eller rediger billeder
+pdfjs-editor-stamp-button-label = Tilføj eller rediger billeder
+pdfjs-editor-remove-button =
+ .title = Fjern
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Fjern tegning
+pdfjs-editor-remove-freetext-button =
+ .title = Fjern tekst
+pdfjs-editor-remove-stamp-button =
+ .title = Fjern billede
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Farve
+pdfjs-editor-free-text-size-input = Størrelse
+pdfjs-editor-ink-color-input = Farve
+pdfjs-editor-ink-thickness-input = Tykkelse
+pdfjs-editor-ink-opacity-input = Uigennemsigtighed
+pdfjs-editor-stamp-add-image-button =
+ .title = Tilføj billede
+pdfjs-editor-stamp-add-image-button-label = Tilføj billede
+pdfjs-free-text =
+ .aria-label = Teksteditor
+pdfjs-free-text-default-content = Begynd at skrive…
+pdfjs-ink =
+ .aria-label = Tegnings-editor
+pdfjs-ink-canvas =
+ .aria-label = Brugeroprettet billede
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternativ tekst
+pdfjs-editor-alt-text-edit-button-label = Rediger alternativ tekst
+pdfjs-editor-alt-text-dialog-label = Vælg en indstilling
+pdfjs-editor-alt-text-dialog-description = Alternativ tekst hjælper folk, som ikke kan se billedet eller når det ikke indlæses.
+pdfjs-editor-alt-text-add-description-label = Tilføj en beskrivelse
+pdfjs-editor-alt-text-add-description-description = Sigt efter en eller to sætninger, der beskriver emnet, omgivelserne eller handlinger.
+pdfjs-editor-alt-text-mark-decorative-label = Marker som dekorativ
+pdfjs-editor-alt-text-mark-decorative-description = Dette bruges for dekorative billeder som rammer eller vandmærker.
+pdfjs-editor-alt-text-cancel-button = Annuller
+pdfjs-editor-alt-text-save-button = Gem
+pdfjs-editor-alt-text-decorative-tooltip = Markeret som dekorativ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = For eksempel: "En ung mand sætter sig ved et bord for at spise et måltid mad"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Øverste venstre hjørne — tilpas størrelse
+pdfjs-editor-resizer-label-top-middle = Øverste i midten — tilpas størrelse
+pdfjs-editor-resizer-label-top-right = Øverste højre hjørne — tilpas størrelse
+pdfjs-editor-resizer-label-middle-right = Midten til højre — tilpas størrelse
+pdfjs-editor-resizer-label-bottom-right = Nederste højre hjørne - tilpas størrelse
+pdfjs-editor-resizer-label-bottom-middle = Nederst i midten - tilpas størrelse
+pdfjs-editor-resizer-label-bottom-left = Nederste venstre hjørne - tilpas størrelse
+pdfjs-editor-resizer-label-middle-left = Midten til venstre — tilpas størrelse
diff --git a/www/lib/pdfjs/modern/web/locale/de/viewer.ftl b/www/lib/pdfjs/modern/web/locale/de/viewer.ftl
new file mode 100644
index 000000000..ba4d2fa5b
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/de/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Eine Seite zurück
+pdfjs-previous-button-label = Zurück
+pdfjs-next-button =
+ .title = Eine Seite vor
+pdfjs-next-button-label = Vor
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Seite
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = von { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } von { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Verkleinern
+pdfjs-zoom-out-button-label = Verkleinern
+pdfjs-zoom-in-button =
+ .title = Vergrößern
+pdfjs-zoom-in-button-label = Vergrößern
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = In Präsentationsmodus wechseln
+pdfjs-presentation-mode-button-label = Präsentationsmodus
+pdfjs-open-file-button =
+ .title = Datei öffnen
+pdfjs-open-file-button-label = Öffnen
+pdfjs-print-button =
+ .title = Drucken
+pdfjs-print-button-label = Drucken
+pdfjs-save-button =
+ .title = Speichern
+pdfjs-save-button-label = Speichern
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Herunterladen
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Herunterladen
+pdfjs-bookmark-button =
+ .title = Aktuelle Seite (URL von aktueller Seite anzeigen)
+pdfjs-bookmark-button-label = Aktuelle Seite
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Mit App öffnen
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Mit App öffnen
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Werkzeuge
+pdfjs-tools-button-label = Werkzeuge
+pdfjs-first-page-button =
+ .title = Erste Seite anzeigen
+pdfjs-first-page-button-label = Erste Seite anzeigen
+pdfjs-last-page-button =
+ .title = Letzte Seite anzeigen
+pdfjs-last-page-button-label = Letzte Seite anzeigen
+pdfjs-page-rotate-cw-button =
+ .title = Im Uhrzeigersinn drehen
+pdfjs-page-rotate-cw-button-label = Im Uhrzeigersinn drehen
+pdfjs-page-rotate-ccw-button =
+ .title = Gegen Uhrzeigersinn drehen
+pdfjs-page-rotate-ccw-button-label = Gegen Uhrzeigersinn drehen
+pdfjs-cursor-text-select-tool-button =
+ .title = Textauswahl-Werkzeug aktivieren
+pdfjs-cursor-text-select-tool-button-label = Textauswahl-Werkzeug
+pdfjs-cursor-hand-tool-button =
+ .title = Hand-Werkzeug aktivieren
+pdfjs-cursor-hand-tool-button-label = Hand-Werkzeug
+pdfjs-scroll-page-button =
+ .title = Seiten einzeln anordnen
+pdfjs-scroll-page-button-label = Einzelseitenanordnung
+pdfjs-scroll-vertical-button =
+ .title = Seiten übereinander anordnen
+pdfjs-scroll-vertical-button-label = Vertikale Seitenanordnung
+pdfjs-scroll-horizontal-button =
+ .title = Seiten nebeneinander anordnen
+pdfjs-scroll-horizontal-button-label = Horizontale Seitenanordnung
+pdfjs-scroll-wrapped-button =
+ .title = Seiten neben- und übereinander anordnen, abhängig vom Platz
+pdfjs-scroll-wrapped-button-label = Kombinierte Seitenanordnung
+pdfjs-spread-none-button =
+ .title = Seiten nicht nebeneinander anzeigen
+pdfjs-spread-none-button-label = Einzelne Seiten
+pdfjs-spread-odd-button =
+ .title = Jeweils eine ungerade und eine gerade Seite nebeneinander anzeigen
+pdfjs-spread-odd-button-label = Ungerade + gerade Seite
+pdfjs-spread-even-button =
+ .title = Jeweils eine gerade und eine ungerade Seite nebeneinander anzeigen
+pdfjs-spread-even-button-label = Gerade + ungerade Seite
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumenteigenschaften
+pdfjs-document-properties-button-label = Dokumenteigenschaften…
+pdfjs-document-properties-file-name = Dateiname:
+pdfjs-document-properties-file-size = Dateigröße:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } Bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } Bytes)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Thema:
+pdfjs-document-properties-keywords = Stichwörter:
+pdfjs-document-properties-creation-date = Erstelldatum:
+pdfjs-document-properties-modification-date = Bearbeitungsdatum:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } { $time }
+pdfjs-document-properties-creator = Anwendung:
+pdfjs-document-properties-producer = PDF erstellt mit:
+pdfjs-document-properties-version = PDF-Version:
+pdfjs-document-properties-page-count = Seitenzahl:
+pdfjs-document-properties-page-size = Seitengröße:
+pdfjs-document-properties-page-size-unit-inches = Zoll
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = Hochformat
+pdfjs-document-properties-page-size-orientation-landscape = Querformat
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Schnelle Webanzeige:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nein
+pdfjs-document-properties-close-button = Schließen
+
+## Print
+
+pdfjs-print-progress-message = Dokument wird für Drucken vorbereitet…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress } %
+pdfjs-print-progress-close-button = Abbrechen
+pdfjs-printing-not-supported = Warnung: Die Drucken-Funktion wird durch diesen Browser nicht vollständig unterstützt.
+pdfjs-printing-not-ready = Warnung: Die PDF-Datei ist nicht vollständig geladen, dies ist für das Drucken aber empfohlen.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Sidebar umschalten
+pdfjs-toggle-sidebar-notification-button =
+ .title = Sidebar umschalten (Dokument enthält Dokumentstruktur/Anhänge/Ebenen)
+pdfjs-toggle-sidebar-button-label = Sidebar umschalten
+pdfjs-document-outline-button =
+ .title = Dokumentstruktur anzeigen (Doppelklicken, um alle Einträge aus- bzw. einzuklappen)
+pdfjs-document-outline-button-label = Dokumentstruktur
+pdfjs-attachments-button =
+ .title = Anhänge anzeigen
+pdfjs-attachments-button-label = Anhänge
+pdfjs-layers-button =
+ .title = Ebenen anzeigen (Doppelklicken, um alle Ebenen auf den Standardzustand zurückzusetzen)
+pdfjs-layers-button-label = Ebenen
+pdfjs-thumbs-button =
+ .title = Miniaturansichten anzeigen
+pdfjs-thumbs-button-label = Miniaturansichten
+pdfjs-current-outline-item-button =
+ .title = Aktuelles Struktur-Element finden
+pdfjs-current-outline-item-button-label = Aktuelles Struktur-Element
+pdfjs-findbar-button =
+ .title = Dokument durchsuchen
+pdfjs-findbar-button-label = Suchen
+pdfjs-additional-layers = Zusätzliche Ebenen
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Seite { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniaturansicht von Seite { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Suchen
+ .placeholder = Dokument durchsuchen…
+pdfjs-find-previous-button =
+ .title = Vorheriges Vorkommen des Suchbegriffs finden
+pdfjs-find-previous-button-label = Zurück
+pdfjs-find-next-button =
+ .title = Nächstes Vorkommen des Suchbegriffs finden
+pdfjs-find-next-button-label = Weiter
+pdfjs-find-highlight-checkbox = Alle hervorheben
+pdfjs-find-match-case-checkbox-label = Groß-/Kleinschreibung beachten
+pdfjs-find-match-diacritics-checkbox-label = Akzente
+pdfjs-find-entire-word-checkbox-label = Ganze Wörter
+pdfjs-find-reached-top = Anfang des Dokuments erreicht, fahre am Ende fort
+pdfjs-find-reached-bottom = Ende des Dokuments erreicht, fahre am Anfang fort
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } von { $total } Ãœbereinstimmung
+ *[other] { $current } von { $total } Ãœbereinstimmungen
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mehr als { $limit } Ãœbereinstimmung
+ *[other] Mehr als { $limit } Ãœbereinstimmungen
+ }
+pdfjs-find-not-found = Suchbegriff nicht gefunden
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Seitenbreite
+pdfjs-page-scale-fit = Seitengröße
+pdfjs-page-scale-auto = Automatischer Zoom
+pdfjs-page-scale-actual = Originalgröße
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Seite { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Beim Laden der PDF-Datei trat ein Fehler auf.
+pdfjs-invalid-file-error = Ungültige oder beschädigte PDF-Datei
+pdfjs-missing-file-error = Fehlende PDF-Datei
+pdfjs-unexpected-response-error = Unerwartete Antwort des Servers
+pdfjs-rendering-error = Beim Darstellen der Seite trat ein Fehler auf.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anlage: { $type }]
+
+## Password
+
+pdfjs-password-label = Geben Sie zum Öffnen der PDF-Datei deren Passwort ein.
+pdfjs-password-invalid = Falsches Passwort. Bitte versuchen Sie es erneut.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Abbrechen
+pdfjs-web-fonts-disabled = Web-Schriftarten sind deaktiviert: Eingebettete PDF-Schriftarten konnten nicht geladen werden.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Zeichnen
+pdfjs-editor-ink-button-label = Zeichnen
+pdfjs-editor-stamp-button =
+ .title = Grafiken hinzufügen oder bearbeiten
+pdfjs-editor-stamp-button-label = Grafiken hinzufügen oder bearbeiten
+pdfjs-editor-remove-button =
+ .title = Entfernen
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Zeichnung entfernen
+pdfjs-editor-remove-freetext-button =
+ .title = Text entfernen
+pdfjs-editor-remove-stamp-button =
+ .title = Grafik entfernen
+pdfjs-editor-remove-highlight-button =
+ .title = Hervorhebung entfernen
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Farbe
+pdfjs-editor-free-text-size-input = Größe
+pdfjs-editor-ink-color-input = Farbe
+pdfjs-editor-ink-thickness-input = Dicke
+pdfjs-editor-ink-opacity-input = Deckkraft
+pdfjs-editor-stamp-add-image-button =
+ .title = Grafik hinzufügen
+pdfjs-editor-stamp-add-image-button-label = Grafik hinzufügen
+pdfjs-free-text =
+ .aria-label = Texteditor
+pdfjs-free-text-default-content = Schreiben beginnen…
+pdfjs-ink =
+ .aria-label = Zeichnungseditor
+pdfjs-ink-canvas =
+ .aria-label = Vom Benutzer erstelltes Bild
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternativ-Text
+pdfjs-editor-alt-text-edit-button-label = Alternativ-Text bearbeiten
+pdfjs-editor-alt-text-dialog-label = Option wählen
+pdfjs-editor-alt-text-dialog-description = Alt-Text (Alternativtext) hilft, wenn Personen die Grafik nicht sehen können oder wenn sie nicht geladen wird.
+pdfjs-editor-alt-text-add-description-label = Beschreibung hinzufügen
+pdfjs-editor-alt-text-add-description-description = Ziel sind 1-2 Sätze, die das Thema, das Szenario oder Aktionen beschreiben.
+pdfjs-editor-alt-text-mark-decorative-label = Als dekorativ markieren
+pdfjs-editor-alt-text-mark-decorative-description = Dies wird für Ziergrafiken wie Ränder oder Wasserzeichen verwendet.
+pdfjs-editor-alt-text-cancel-button = Abbrechen
+pdfjs-editor-alt-text-save-button = Speichern
+pdfjs-editor-alt-text-decorative-tooltip = Als dekorativ markiert
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Zum Beispiel: "Ein junger Mann setzt sich an einen Tisch, um zu essen."
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Linke obere Ecke - Größe ändern
+pdfjs-editor-resizer-label-top-middle = Oben mittig - Größe ändern
+pdfjs-editor-resizer-label-top-right = Rechts oben - Größe ändern
+pdfjs-editor-resizer-label-middle-right = Mitte rechts - Größe ändern
+pdfjs-editor-resizer-label-bottom-right = Rechte untere Ecke - Größe ändern
+pdfjs-editor-resizer-label-bottom-middle = Unten mittig - Größe ändern
+pdfjs-editor-resizer-label-bottom-left = Linke untere Ecke - Größe ändern
+pdfjs-editor-resizer-label-middle-left = Mitte links - Größe ändern
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Hervorhebungsfarbe
+pdfjs-editor-colorpicker-button =
+ .title = Farbe ändern
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Farbauswahl
+pdfjs-editor-colorpicker-yellow =
+ .title = Gelb
+pdfjs-editor-colorpicker-green =
+ .title = Grün
+pdfjs-editor-colorpicker-blue =
+ .title = Blau
+pdfjs-editor-colorpicker-pink =
+ .title = Pink
+pdfjs-editor-colorpicker-red =
+ .title = Rot
diff --git a/www/lib/pdfjs/modern/web/locale/dsb/viewer.ftl b/www/lib/pdfjs/modern/web/locale/dsb/viewer.ftl
new file mode 100644
index 000000000..cc2fb8937
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/dsb/viewer.ftl
@@ -0,0 +1,388 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pjerwjejšny bok
+pdfjs-previous-button-label = Slědk
+pdfjs-next-button =
+ .title = Pśiducy bok
+pdfjs-next-button-label = Dalej
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Bok
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = z { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } z { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Pómjeńšyś
+pdfjs-zoom-out-button-label = Pómjeńšyś
+pdfjs-zoom-in-button =
+ .title = Pówětšyś
+pdfjs-zoom-in-button-label = Pówětšyś
+pdfjs-zoom-select =
+ .title = Skalěrowanje
+pdfjs-presentation-mode-button =
+ .title = Do prezentaciskego modusa pśejś
+pdfjs-presentation-mode-button-label = Prezentaciski modus
+pdfjs-open-file-button =
+ .title = Dataju wócyniś
+pdfjs-open-file-button-label = Wócyniś
+pdfjs-print-button =
+ .title = Śišćaś
+pdfjs-print-button-label = Śišćaś
+pdfjs-save-button =
+ .title = Składowaś
+pdfjs-save-button-label = Składowaś
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Ześěgnuś
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Ześěgnuś
+pdfjs-bookmark-button =
+ .title = Aktualny bok (URL z aktualnego boka pokazaÅ›)
+pdfjs-bookmark-button-label = Aktualny bok
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = W nałoženju wócyniś
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = W nałoženju wócyniś
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Rědy
+pdfjs-tools-button-label = Rědy
+pdfjs-first-page-button =
+ .title = K prědnemu bokoju
+pdfjs-first-page-button-label = K prědnemu bokoju
+pdfjs-last-page-button =
+ .title = K slědnemu bokoju
+pdfjs-last-page-button-label = K slědnemu bokoju
+pdfjs-page-rotate-cw-button =
+ .title = Wobwjertnuś ako špěra źo
+pdfjs-page-rotate-cw-button-label = Wobwjertnuś ako špěra źo
+pdfjs-page-rotate-ccw-button =
+ .title = Wobwjertnuś nawopaki ako špěra źo
+pdfjs-page-rotate-ccw-button-label = Wobwjertnuś nawopaki ako špěra źo
+pdfjs-cursor-text-select-tool-button =
+ .title = Rěd za wuběranje teksta zmóžniś
+pdfjs-cursor-text-select-tool-button-label = Rěd za wuběranje teksta
+pdfjs-cursor-hand-tool-button =
+ .title = Rucny rěd zmóžniś
+pdfjs-cursor-hand-tool-button-label = Rucny rěd
+pdfjs-scroll-page-button =
+ .title = Kulanje boka wužywaś
+pdfjs-scroll-page-button-label = Kulanje boka
+pdfjs-scroll-vertical-button =
+ .title = Wertikalne suwanje wužywaś
+pdfjs-scroll-vertical-button-label = Wertikalne suwanje
+pdfjs-scroll-horizontal-button =
+ .title = Horicontalne suwanje wužywaś
+pdfjs-scroll-horizontal-button-label = Horicontalne suwanje
+pdfjs-scroll-wrapped-button =
+ .title = Pózlažke suwanje wužywaś
+pdfjs-scroll-wrapped-button-label = Pózlažke suwanje
+pdfjs-spread-none-button =
+ .title = Boki njezwězaś
+pdfjs-spread-none-button-label = Žeden dwójny bok
+pdfjs-spread-odd-button =
+ .title = Boki zachopinajucy z njerownymi bokami zwězaś
+pdfjs-spread-odd-button-label = Njerowne boki
+pdfjs-spread-even-button =
+ .title = Boki zachopinajucy z rownymi bokami zwězaś
+pdfjs-spread-even-button-label = Rowne boki
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentowe kakosći…
+pdfjs-document-properties-button-label = Dokumentowe kakosći…
+pdfjs-document-properties-file-name = MÄ› dataje:
+pdfjs-document-properties-file-size = Wjelikosć dataje:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajtow)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtow)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Awtor:
+pdfjs-document-properties-subject = Tema:
+pdfjs-document-properties-keywords = Klucowe słowa:
+pdfjs-document-properties-creation-date = Datum napóranja:
+pdfjs-document-properties-modification-date = Datum změny:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Awtor:
+pdfjs-document-properties-producer = PDF-gótowaŕ:
+pdfjs-document-properties-version = PDF-wersija:
+pdfjs-document-properties-page-count = Licba bokow:
+pdfjs-document-properties-page-size = Wjelikosć boka:
+pdfjs-document-properties-page-size-unit-inches = col
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = wusoki format
+pdfjs-document-properties-page-size-orientation-landscape = prěcny format
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Jo
+pdfjs-document-properties-linearized-no = NÄ›
+pdfjs-document-properties-close-button = ZacyniÅ›
+
+## Print
+
+pdfjs-print-progress-message = Dokument pśigótujo se za śišćanje…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Pśetergnuś
+pdfjs-printing-not-supported = Warnowanje: Śišćanje njepódpěra se połnje pśez toś ten wobglědowak.
+pdfjs-printing-not-ready = Warnowanje: PDF njejo se za śišćanje dopołnje zacytał.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Bócnicu pokazaś/schowaś
+pdfjs-toggle-sidebar-notification-button =
+ .title = Bocnicu pśešaltowaś (dokument rozrědowanje/pśipiski/warstwy wopśimujo)
+pdfjs-toggle-sidebar-button-label = Bócnicu pokazaś/schowaś
+pdfjs-document-outline-button =
+ .title = Dokumentowe naraźenje pokazaś (dwójne kliknjenje, aby se wšykne zapiski pokazali/schowali)
+pdfjs-document-outline-button-label = Dokumentowa struktura
+pdfjs-attachments-button =
+ .title = Pśidanki pokazaś
+pdfjs-attachments-button-label = Pśidanki
+pdfjs-layers-button =
+ .title = Warstwy pokazaś (klikniśo dwójcy, aby wšykne warstwy na standardny staw slědk stajił)
+pdfjs-layers-button-label = Warstwy
+pdfjs-thumbs-button =
+ .title = Miniatury pokazaÅ›
+pdfjs-thumbs-button-label = Miniatury
+pdfjs-current-outline-item-button =
+ .title = Aktualny rozrědowański zapisk pytaś
+pdfjs-current-outline-item-button-label = Aktualny rozrědowański zapisk
+pdfjs-findbar-button =
+ .title = W dokumenśe pytaś
+pdfjs-findbar-button-label = PytaÅ›
+pdfjs-additional-layers = Dalšne warstwy
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Bok { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura boka { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = PytaÅ›
+ .placeholder = W dokumenśe pytaś…
+pdfjs-find-previous-button =
+ .title = Pjerwjejšne wustupowanje pytańskego wuraza pytaś
+pdfjs-find-previous-button-label = Slědk
+pdfjs-find-next-button =
+ .title = Pśidujuce wustupowanje pytańskego wuraza pytaś
+pdfjs-find-next-button-label = Dalej
+pdfjs-find-highlight-checkbox = WÅ¡ykne wuzwignuÅ›
+pdfjs-find-match-case-checkbox-label = Na wjelikopisanje źiwaś
+pdfjs-find-match-diacritics-checkbox-label = Diakritiske znamuška wužywaś
+pdfjs-find-entire-word-checkbox-label = Cełe słowa
+pdfjs-find-reached-top = Zachopjeńk dokumenta dostany, pókšacujo se z kóńcom
+pdfjs-find-reached-bottom = Kóńc dokumenta dostany, pókšacujo se ze zachopjeńkom
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } z { $total } wótpowědnika
+ [two] { $current } z { $total } wótpowědnikowu
+ [few] { $current } z { $total } wótpowědnikow
+ *[other] { $current } z { $total } wótpowědnikow
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Wušej { $limit } wótpowědnik
+ [two] Wušej { $limit } wótpowědnika
+ [few] Wušej { $limit } wótpowědniki
+ *[other] Wušej { $limit } wótpowědniki
+ }
+pdfjs-find-not-found = Pytański wuraz njejo se namakał
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Šyrokosć boka
+pdfjs-page-scale-fit = Wjelikosć boka
+pdfjs-page-scale-auto = Awtomatiske skalěrowanje
+pdfjs-page-scale-actual = Aktualna wjelikosć
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Bok { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Pśi zacytowanju PDF jo zmólka nastała.
+pdfjs-invalid-file-error = Njepłaśiwa abo wobškóźona PDF-dataja.
+pdfjs-missing-file-error = Felujuca PDF-dataja.
+pdfjs-unexpected-response-error = Njewócakane serwerowe wótegrono.
+pdfjs-rendering-error = Pśi zwobraznjanju boka jo zmólka nastała.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Typ pśipiskow: { $type }]
+
+## Password
+
+pdfjs-password-label = Zapódajśo gronidło, aby PDF-dataju wócynił.
+pdfjs-password-invalid = Njepłaśiwe gronidło. Pšosym wopytajśo hyšći raz.
+pdfjs-password-ok-button = W pórěźe
+pdfjs-password-cancel-button = Pśetergnuś
+pdfjs-web-fonts-disabled = Webpisma su znjemóžnjone: njejo móžno, zasajźone PDF-pisma wužywaś.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = KresliÅ›
+pdfjs-editor-ink-button-label = KresliÅ›
+pdfjs-editor-stamp-button =
+ .title = Wobraze pśidaś abo wobźěłaś
+pdfjs-editor-stamp-button-label = Wobraze pśidaś abo wobźěłaś
+pdfjs-editor-remove-button =
+ .title = Wótwónoźeś
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Kreslanku wótwónoźeś
+pdfjs-editor-remove-freetext-button =
+ .title = Tekst wótwónoźeś
+pdfjs-editor-remove-stamp-button =
+ .title = Wobraz wótwónoźeś
+pdfjs-editor-remove-highlight-button =
+ .title = Wuzwignjenje wótpóraś
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Barwa
+pdfjs-editor-free-text-size-input = Wjelikosć
+pdfjs-editor-ink-color-input = Barwa
+pdfjs-editor-ink-thickness-input = Tłustosć
+pdfjs-editor-ink-opacity-input = Opacita
+pdfjs-editor-stamp-add-image-button =
+ .title = Wobraz pśidaś
+pdfjs-editor-stamp-add-image-button-label = Wobraz pśidaś
+pdfjs-free-text =
+ .aria-label = Tekstowy editor
+pdfjs-free-text-default-content = Zachopśo pisaś…
+pdfjs-ink =
+ .aria-label = Kresleński editor
+pdfjs-ink-canvas =
+ .aria-label = Wobraz napórany wót wužywarja
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternatiwny tekst
+pdfjs-editor-alt-text-edit-button-label = Alternatiwny tekst wobźěłaś
+pdfjs-editor-alt-text-dialog-label = Nastajenje wubraÅ›
+pdfjs-editor-alt-text-dialog-description = Alternatiwny tekst pomaga, gaž luźe njamógu wobraz wiźeś abo gaž se wobraz njezacytajo.
+pdfjs-editor-alt-text-add-description-label = Wopisanje pśidaś
+pdfjs-editor-alt-text-add-description-description = Pišćo 1 sadu abo 2 saźe, kótarejž temu, nastajenje abo akcije wopisujotej.
+pdfjs-editor-alt-text-mark-decorative-label = Ako dekoratiwny markěrowaś
+pdfjs-editor-alt-text-mark-decorative-description = To se za pyšnjece wobraze wužywa, na pśikład ramiki abo wódowe znamjenja.
+pdfjs-editor-alt-text-cancel-button = Pśetergnuś
+pdfjs-editor-alt-text-save-button = Składowaś
+pdfjs-editor-alt-text-decorative-tooltip = Ako dekoratiwny markěrowany
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Na pśikład, „Młody muski za blidom sejźi, aby jěź jědł“
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Górjejce nalěwo – wjelikosć změniś
+pdfjs-editor-resizer-label-top-middle = Górjejce wesrjejź – wjelikosć změniś
+pdfjs-editor-resizer-label-top-right = Górjejce napšawo – wjelikosć změniś
+pdfjs-editor-resizer-label-middle-right = Wesrjejź napšawo – wjelikosć změniś
+pdfjs-editor-resizer-label-bottom-right = Dołojce napšawo – wjelikosć změniś
+pdfjs-editor-resizer-label-bottom-middle = Dołojce wesrjejź – wjelikosć změniś
+pdfjs-editor-resizer-label-bottom-left = Dołojce nalěwo – wjelikosć změniś
+pdfjs-editor-resizer-label-middle-left = Wesrjejź nalěwo – wjelikosć změniś
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Barwa wuzwignjenja
+pdfjs-editor-colorpicker-button =
+ .title = Barwu změniś
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Wuběrk barwow
+pdfjs-editor-colorpicker-yellow =
+ .title = Žołty
+pdfjs-editor-colorpicker-green =
+ .title = Zeleny
+pdfjs-editor-colorpicker-blue =
+ .title = Módry
+pdfjs-editor-colorpicker-pink =
+ .title = Pink
+pdfjs-editor-colorpicker-red =
+ .title = Cerwjeny
diff --git a/www/lib/pdfjs/modern/web/locale/el/viewer.ftl b/www/lib/pdfjs/modern/web/locale/el/viewer.ftl
new file mode 100644
index 000000000..b88067da3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/el/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Î ÏοηγοÏμενη σελίδα
+pdfjs-previous-button-label = Î ÏοηγοÏμενη
+pdfjs-next-button =
+ .title = Επόμενη σελίδα
+pdfjs-next-button-label = Επόμενη
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Σελίδα
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = από { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } από { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ΣμίκÏυνση
+pdfjs-zoom-out-button-label = ΣμίκÏυνση
+pdfjs-zoom-in-button =
+ .title = ΜεγÎθυνση
+pdfjs-zoom-in-button-label = ΜεγÎθυνση
+pdfjs-zoom-select =
+ .title = Ζουμ
+pdfjs-presentation-mode-button =
+ .title = Εναλλαγή σε λειτουÏγία παÏουσίασης
+pdfjs-presentation-mode-button-label = ΛειτουÏγία παÏουσίασης
+pdfjs-open-file-button =
+ .title = Άνοιγμα αÏχείου
+pdfjs-open-file-button-label = Άνοιγμα
+pdfjs-print-button =
+ .title = ΕκτÏπωση
+pdfjs-print-button-label = ΕκτÏπωση
+pdfjs-save-button =
+ .title = Αποθήκευση
+pdfjs-save-button-label = Αποθήκευση
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Λήψη
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Λήψη
+pdfjs-bookmark-button =
+ .title = ΤÏÎχουσα σελίδα (Î Ïοβολή URL από Ï„ÏÎχουσα σελίδα)
+pdfjs-bookmark-button-label = ΤÏÎχουσα σελίδα
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Άνοιγμα σε εφαÏμογή
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Άνοιγμα σε εφαÏμογή
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ΕÏγαλεία
+pdfjs-tools-button-label = ΕÏγαλεία
+pdfjs-first-page-button =
+ .title = Μετάβαση στην Ï€Ïώτη σελίδα
+pdfjs-first-page-button-label = Μετάβαση στην Ï€Ïώτη σελίδα
+pdfjs-last-page-button =
+ .title = Μετάβαση στην τελευταία σελίδα
+pdfjs-last-page-button-label = Μετάβαση στην τελευταία σελίδα
+pdfjs-page-rotate-cw-button =
+ .title = ΔεξιόστÏοφη πεÏιστÏοφή
+pdfjs-page-rotate-cw-button-label = ΔεξιόστÏοφη πεÏιστÏοφή
+pdfjs-page-rotate-ccw-button =
+ .title = ΑÏιστεÏόστÏοφη πεÏιστÏοφή
+pdfjs-page-rotate-ccw-button-label = ΑÏιστεÏόστÏοφη πεÏιστÏοφή
+pdfjs-cursor-text-select-tool-button =
+ .title = ΕνεÏγοποίηση εÏγαλείου επιλογής κειμÎνου
+pdfjs-cursor-text-select-tool-button-label = ΕÏγαλείο επιλογής κειμÎνου
+pdfjs-cursor-hand-tool-button =
+ .title = ΕνεÏγοποίηση εÏγαλείου χεÏιοÏ
+pdfjs-cursor-hand-tool-button-label = ΕÏγαλείο χεÏιοÏ
+pdfjs-scroll-page-button =
+ .title = ΧÏήση κÏλισης σελίδας
+pdfjs-scroll-page-button-label = ΚÏλιση σελίδας
+pdfjs-scroll-vertical-button =
+ .title = ΧÏήση κάθετης κÏλισης
+pdfjs-scroll-vertical-button-label = Κάθετη κÏλιση
+pdfjs-scroll-horizontal-button =
+ .title = ΧÏήση οÏιζόντιας κÏλισης
+pdfjs-scroll-horizontal-button-label = ΟÏιζόντια κÏλιση
+pdfjs-scroll-wrapped-button =
+ .title = ΧÏήση κυκλικής κÏλισης
+pdfjs-scroll-wrapped-button-label = Κυκλική κÏλιση
+pdfjs-spread-none-button =
+ .title = Îα μη γίνει σÏνδεση επεκτάσεων σελίδων
+pdfjs-spread-none-button-label = ΧωÏίς επεκτάσεις
+pdfjs-spread-odd-button =
+ .title = ΣÏνδεση επεκτάσεων σελίδων ξεκινώντας από τις μονÎÏ‚ σελίδες
+pdfjs-spread-odd-button-label = ΜονÎÏ‚ επεκτάσεις
+pdfjs-spread-even-button =
+ .title = ΣÏνδεση επεκτάσεων σελίδων ξεκινώντας από τις ζυγÎÏ‚ σελίδες
+pdfjs-spread-even-button-label = ΖυγÎÏ‚ επεκτάσεις
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Ιδιότητες εγγÏάφου…
+pdfjs-document-properties-button-label = Ιδιότητες εγγÏάφου…
+pdfjs-document-properties-file-name = Όνομα αÏχείου:
+pdfjs-document-properties-file-size = ÎœÎγεθος αÏχείου:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Τίτλος:
+pdfjs-document-properties-author = ΣυγγÏαφÎας:
+pdfjs-document-properties-subject = ΘÎμα:
+pdfjs-document-properties-keywords = ΛÎξεις-κλειδιά:
+pdfjs-document-properties-creation-date = ΗμεÏομηνία δημιουÏγίας:
+pdfjs-document-properties-modification-date = ΗμεÏομηνία Ï„Ïοποποίησης:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ΔημιουÏγός:
+pdfjs-document-properties-producer = ΠαÏαγωγός PDF:
+pdfjs-document-properties-version = Έκδοση PDF:
+pdfjs-document-properties-page-count = ΑÏιθμός σελίδων:
+pdfjs-document-properties-page-size = ÎœÎγεθος σελίδας:
+pdfjs-document-properties-page-size-unit-inches = ίντσες
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = κατακόÏυφα
+pdfjs-document-properties-page-size-orientation-landscape = οÏιζόντια
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Επιστολή
+pdfjs-document-properties-page-size-name-legal = ΤÏπου Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Ταχεία Ï€Ïοβολή ιστοÏ:
+pdfjs-document-properties-linearized-yes = Îαι
+pdfjs-document-properties-linearized-no = Όχι
+pdfjs-document-properties-close-button = Κλείσιμο
+
+## Print
+
+pdfjs-print-progress-message = Î Ïοετοιμασία του εγγÏάφου για εκτÏπωση…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ΑκÏÏωση
+pdfjs-printing-not-supported = Î Ïοειδοποίηση: Η εκτÏπωση δεν υποστηÏίζεται πλήÏως από το Ï€ÏόγÏαμμα πεÏιήγησης.
+pdfjs-printing-not-ready = Î Ïοειδοποίηση: Το PDF δεν φοÏτώθηκε πλήÏως για εκτÏπωση.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = (Απ)ενεÏγοποίηση πλαϊνής γÏαμμής
+pdfjs-toggle-sidebar-notification-button =
+ .title = (Απ)ενεÏγοποίηση πλαϊνής γÏαμμής (το ÎγγÏαφο πεÏιÎχει πεÏίγÏαμμα/συνημμÎνα/επίπεδα)
+pdfjs-toggle-sidebar-button-label = (Απ)ενεÏγοποίηση πλαϊνής γÏαμμής
+pdfjs-document-outline-button =
+ .title = Εμφάνιση διάÏθÏωσης εγγÏάφου (διπλό κλικ για ανάπτυξη/σÏμπτυξη όλων των στοιχείων)
+pdfjs-document-outline-button-label = ΔιάÏθÏωση εγγÏάφου
+pdfjs-attachments-button =
+ .title = Εμφάνιση συνημμÎνων
+pdfjs-attachments-button-label = ΣυνημμÎνα
+pdfjs-layers-button =
+ .title = Εμφάνιση επιπÎδων (διπλό κλικ για επαναφοÏά όλων των επιπÎδων στην Ï€ÏοεπιλεγμÎνη κατάσταση)
+pdfjs-layers-button-label = Επίπεδα
+pdfjs-thumbs-button =
+ .title = Εμφάνιση μικÏογÏαφιών
+pdfjs-thumbs-button-label = ΜικÏογÏαφίες
+pdfjs-current-outline-item-button =
+ .title = ΕÏÏεση Ï„ÏÎχοντος στοιχείου διάÏθÏωσης
+pdfjs-current-outline-item-button-label = ΤÏÎχον στοιχείο διάÏθÏωσης
+pdfjs-findbar-button =
+ .title = ΕÏÏεση στο ÎγγÏαφο
+pdfjs-findbar-button-label = ΕÏÏεση
+pdfjs-additional-layers = ΕπιπÏόσθετα επίπεδα
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Σελίδα { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ΜικÏογÏαφία σελίδας { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ΕÏÏεση
+ .placeholder = ΕÏÏεση στο ÎγγÏαφο…
+pdfjs-find-previous-button =
+ .title = ΕÏÏεση της Ï€ÏοηγοÏμενης εμφάνισης της φÏάσης
+pdfjs-find-previous-button-label = Î ÏοηγοÏμενο
+pdfjs-find-next-button =
+ .title = ΕÏÏεση της επόμενης εμφάνισης της φÏάσης
+pdfjs-find-next-button-label = Επόμενο
+pdfjs-find-highlight-checkbox = Επισήμανση όλων
+pdfjs-find-match-case-checkbox-label = Συμφωνία πεζών/κεφαλαίων
+pdfjs-find-match-diacritics-checkbox-label = Αντιστοίχιση διακÏιτικών
+pdfjs-find-entire-word-checkbox-label = ΟλόκληÏες λÎξεις
+pdfjs-find-reached-top = Φτάσατε στην αÏχή του εγγÏάφου, συνÎχεια από το Ï„Îλος
+pdfjs-find-reached-bottom = Φτάσατε στο Ï„Îλος του εγγÏάφου, συνÎχεια από την αÏχή
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } από { $total } αντιστοιχία
+ *[other] { $current } από { $total } αντιστοιχίες
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] ΠεÏισσότεÏες από { $limit } αντιστοιχία
+ *[other] ΠεÏισσότεÏες από { $limit } αντιστοιχίες
+ }
+pdfjs-find-not-found = Η φÏάση δεν βÏÎθηκε
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Πλάτος σελίδας
+pdfjs-page-scale-fit = ÎœÎγεθος σελίδας
+pdfjs-page-scale-auto = Αυτόματο ζουμ
+pdfjs-page-scale-actual = Î Ïαγματικό μÎγεθος
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Σελίδα { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Î ÏοÎκυψε σφάλμα κατά τη φόÏτωση του PDF.
+pdfjs-invalid-file-error = Μη ÎγκυÏο ή κατεστÏαμμÎνο αÏχείο PDF.
+pdfjs-missing-file-error = Λείπει αÏχείο PDF.
+pdfjs-unexpected-response-error = Μη αναμενόμενη απόκÏιση από το διακομιστή.
+pdfjs-rendering-error = Î ÏοÎκυψε σφάλμα κατά την εμφάνιση της σελίδας.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Σχόλιο «{ $type }»]
+
+## Password
+
+pdfjs-password-label = Εισαγάγετε τον κωδικό Ï€Ïόσβασης για να ανοίξετε αυτό το αÏχείο PDF.
+pdfjs-password-invalid = Μη ÎγκυÏος κωδικός Ï€Ïόσβασης. ΠαÏακαλώ δοκιμάστε ξανά.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = ΑκÏÏωση
+pdfjs-web-fonts-disabled = Οι γÏαμματοσειÏÎÏ‚ Î¹ÏƒÏ„Î¿Ï ÎµÎ¯Î½Î±Î¹ ανενεÏγÎÏ‚: δεν είναι δυνατή η χÏήση των ενσωματωμÎνων γÏαμματοσειÏών PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Κείμενο
+pdfjs-editor-free-text-button-label = Κείμενο
+pdfjs-editor-ink-button =
+ .title = ΣχÎδιο
+pdfjs-editor-ink-button-label = ΣχÎδιο
+pdfjs-editor-stamp-button =
+ .title = Î Ïοσθήκη ή επεξεÏγασία εικόνων
+pdfjs-editor-stamp-button-label = Î Ïοσθήκη ή επεξεÏγασία εικόνων
+pdfjs-editor-remove-button =
+ .title = ΑφαίÏεση
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = ΑφαίÏεση σχεδίου
+pdfjs-editor-remove-freetext-button =
+ .title = ΑφαίÏεση κειμÎνου
+pdfjs-editor-remove-stamp-button =
+ .title = ΑφαίÏεση εικόνας
+pdfjs-editor-remove-highlight-button =
+ .title = ΑφαίÏεση επισήμανσης
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ΧÏώμα
+pdfjs-editor-free-text-size-input = ÎœÎγεθος
+pdfjs-editor-ink-color-input = ΧÏώμα
+pdfjs-editor-ink-thickness-input = Πάχος
+pdfjs-editor-ink-opacity-input = Αδιαφάνεια
+pdfjs-editor-stamp-add-image-button =
+ .title = Î Ïοσθήκη εικόνας
+pdfjs-editor-stamp-add-image-button-label = Î Ïοσθήκη εικόνας
+pdfjs-free-text =
+ .aria-label = ΕπεξεÏγασία κειμÎνου
+pdfjs-free-text-default-content = Ξεκινήστε να πληκτÏολογείτε…
+pdfjs-ink =
+ .aria-label = ΕπεξεÏγασία σχεδίων
+pdfjs-ink-canvas =
+ .aria-label = Εικόνα από τον χÏήστη
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Εναλλακτικό κείμενο
+pdfjs-editor-alt-text-edit-button-label = ΕπεξεÏγασία ÎµÎ½Î±Î»Î»Î±ÎºÏ„Î¹ÎºÎ¿Ï ÎºÎµÎ¹Î¼Îνου
+pdfjs-editor-alt-text-dialog-label = ΔιαλÎξτε μια επιλογή
+pdfjs-editor-alt-text-dialog-description = Το εναλλακτικό κείμενο είναι χÏήσιμο όταν οι άνθÏωποι δεν μποÏοÏν να δουν την εικόνα ή όταν αυτή δεν φοÏτώνεται.
+pdfjs-editor-alt-text-add-description-label = Î Ïοσθήκη πεÏιγÏαφής
+pdfjs-editor-alt-text-add-description-description = ΣτοχεÏστε σε μία ή δÏο Ï€Ïοτάσεις που πεÏιγÏάφουν το θÎμα, τη ÏÏθμιση ή τις ενÎÏγειες.
+pdfjs-editor-alt-text-mark-decorative-label = Επισήμανση ως διακοσμητικό
+pdfjs-editor-alt-text-mark-decorative-description = ΧÏησιμοποιείται για διακοσμητικÎÏ‚ εικόνες, όπως πεÏιγÏάμματα ή υδατογÏαφήματα.
+pdfjs-editor-alt-text-cancel-button = ΑκÏÏωση
+pdfjs-editor-alt-text-save-button = Αποθήκευση
+pdfjs-editor-alt-text-decorative-tooltip = ΕπισημασμÎνο ως διακοσμητικό
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Για παÏάδειγμα, «Ένας νεαÏός άνδÏας κάθεται σε Îνα Ï„ÏαπÎζι για να φάει Îνα γεÏμα»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Επάνω αÏιστεÏή γωνία — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-top-middle = ÎœÎσο επάνω πλευÏάς — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-top-right = Επάνω δεξιά γωνία — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-middle-right = ÎœÎσο δεξιάς πλευÏάς — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-bottom-right = Κάτω δεξιά γωνία — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-bottom-middle = ÎœÎσο κάτω πλευÏάς — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-bottom-left = Κάτω αÏιστεÏή γωνία — αλλαγή μεγÎθους
+pdfjs-editor-resizer-label-middle-left = ÎœÎσο αÏιστεÏής πλευÏάς — αλλαγή μεγÎθους
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = ΧÏώμα επισήμανσης
+pdfjs-editor-colorpicker-button =
+ .title = Αλλαγή χÏώματος
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = ΕπιλογÎÏ‚ χÏωμάτων
+pdfjs-editor-colorpicker-yellow =
+ .title = ΚίτÏινο
+pdfjs-editor-colorpicker-green =
+ .title = Î Ïάσινο
+pdfjs-editor-colorpicker-blue =
+ .title = Μπλε
+pdfjs-editor-colorpicker-pink =
+ .title = Ροζ
+pdfjs-editor-colorpicker-red =
+ .title = Κόκκινο
diff --git a/www/lib/pdfjs/modern/web/locale/en-CA/viewer.ftl b/www/lib/pdfjs/modern/web/locale/en-CA/viewer.ftl
new file mode 100644
index 000000000..e95afe96a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/en-CA/viewer.ftl
@@ -0,0 +1,311 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Previous Page
+pdfjs-previous-button-label = Previous
+pdfjs-next-button =
+ .title = Next Page
+pdfjs-next-button-label = Next
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Page
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = of { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom Out
+pdfjs-zoom-out-button-label = Zoom Out
+pdfjs-zoom-in-button =
+ .title = Zoom In
+pdfjs-zoom-in-button-label = Zoom In
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Switch to Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Open File
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Print
+pdfjs-print-button-label = Print
+pdfjs-save-button =
+ .title = Save
+pdfjs-save-button-label = Save
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Download
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Download
+pdfjs-bookmark-button =
+ .title = Current Page (View URL from Current Page)
+pdfjs-bookmark-button-label = Current Page
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Open in app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Open in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Go to First Page
+pdfjs-first-page-button-label = Go to First Page
+pdfjs-last-page-button =
+ .title = Go to Last Page
+pdfjs-last-page-button-label = Go to Last Page
+pdfjs-page-rotate-cw-button =
+ .title = Rotate Clockwise
+pdfjs-page-rotate-cw-button-label = Rotate Clockwise
+pdfjs-page-rotate-ccw-button =
+ .title = Rotate Counterclockwise
+pdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise
+pdfjs-cursor-text-select-tool-button =
+ .title = Enable Text Selection Tool
+pdfjs-cursor-text-select-tool-button-label = Text Selection Tool
+pdfjs-cursor-hand-tool-button =
+ .title = Enable Hand Tool
+pdfjs-cursor-hand-tool-button-label = Hand Tool
+pdfjs-scroll-page-button =
+ .title = Use Page Scrolling
+pdfjs-scroll-page-button-label = Page Scrolling
+pdfjs-scroll-vertical-button =
+ .title = Use Vertical Scrolling
+pdfjs-scroll-vertical-button-label = Vertical Scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Use Horizontal Scrolling
+pdfjs-scroll-horizontal-button-label = Horizontal Scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Use Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = Do not join page spreads
+pdfjs-spread-none-button-label = No Spreads
+pdfjs-spread-odd-button =
+ .title = Join page spreads starting with odd-numbered pages
+pdfjs-spread-odd-button-label = Odd Spreads
+pdfjs-spread-even-button =
+ .title = Join page spreads starting with even-numbered pages
+pdfjs-spread-even-button-label = Even Spreads
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Document Properties…
+pdfjs-document-properties-button-label = Document Properties…
+pdfjs-document-properties-file-name = File name:
+pdfjs-document-properties-file-size = File size:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Title:
+pdfjs-document-properties-author = Author:
+pdfjs-document-properties-subject = Subject:
+pdfjs-document-properties-keywords = Keywords:
+pdfjs-document-properties-creation-date = Creation Date:
+pdfjs-document-properties-modification-date = Modification Date:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creator:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Page Count:
+pdfjs-document-properties-page-size = Page Size:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = landscape
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Yes
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Close
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancel
+pdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.
+pdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggle Sidebar
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toggle Sidebar (document contains outline/attachments/layers)
+pdfjs-toggle-sidebar-button-label = Toggle Sidebar
+pdfjs-document-outline-button =
+ .title = Show Document Outline (double-click to expand/collapse all items)
+pdfjs-document-outline-button-label = Document Outline
+pdfjs-attachments-button =
+ .title = Show Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-layers-button =
+ .title = Show Layers (double-click to reset all layers to the default state)
+pdfjs-layers-button-label = Layers
+pdfjs-thumbs-button =
+ .title = Show Thumbnails
+pdfjs-thumbs-button-label = Thumbnails
+pdfjs-current-outline-item-button =
+ .title = Find Current Outline Item
+pdfjs-current-outline-item-button-label = Current Outline Item
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = Find
+pdfjs-additional-layers = Additional Layers
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail of Page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find in document…
+pdfjs-find-previous-button =
+ .title = Find the previous occurrence of the phrase
+pdfjs-find-previous-button-label = Previous
+pdfjs-find-next-button =
+ .title = Find the next occurrence of the phrase
+pdfjs-find-next-button-label = Next
+pdfjs-find-highlight-checkbox = Highlight All
+pdfjs-find-match-case-checkbox-label = Match Case
+pdfjs-find-match-diacritics-checkbox-label = Match Diacritics
+pdfjs-find-entire-word-checkbox-label = Whole Words
+pdfjs-find-reached-top = Reached top of document, continued from bottom
+pdfjs-find-reached-bottom = Reached end of document, continued from top
+pdfjs-find-not-found = Phrase not found
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Page Width
+pdfjs-page-scale-fit = Page Fit
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Actual Size
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Page { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = An error occurred while loading the PDF.
+pdfjs-invalid-file-error = Invalid or corrupted PDF file.
+pdfjs-missing-file-error = Missing PDF file.
+pdfjs-unexpected-response-error = Unexpected server response.
+pdfjs-rendering-error = An error occurred while rendering the page.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Enter the password to open this PDF file.
+pdfjs-password-invalid = Invalid password. Please try again.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancel
+pdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Draw
+pdfjs-editor-ink-button-label = Draw
+pdfjs-editor-stamp-button =
+ .title = Add or edit images
+pdfjs-editor-stamp-button-label = Add or edit images
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colour
+pdfjs-editor-free-text-size-input = Size
+pdfjs-editor-ink-color-input = Colour
+pdfjs-editor-ink-thickness-input = Thickness
+pdfjs-editor-ink-opacity-input = Opacity
+pdfjs-editor-stamp-add-image-button =
+ .title = Add image
+pdfjs-editor-stamp-add-image-button-label = Add image
+pdfjs-free-text =
+ .aria-label = Text Editor
+pdfjs-free-text-default-content = Start typing…
+pdfjs-ink =
+ .aria-label = Draw Editor
+pdfjs-ink-canvas =
+ .aria-label = User-created image
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/en-GB/viewer.ftl b/www/lib/pdfjs/modern/web/locale/en-GB/viewer.ftl
new file mode 100644
index 000000000..b581d7237
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/en-GB/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Previous Page
+pdfjs-previous-button-label = Previous
+pdfjs-next-button =
+ .title = Next Page
+pdfjs-next-button-label = Next
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Page
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = of { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom Out
+pdfjs-zoom-out-button-label = Zoom Out
+pdfjs-zoom-in-button =
+ .title = Zoom In
+pdfjs-zoom-in-button-label = Zoom In
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Switch to Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Open File
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Print
+pdfjs-print-button-label = Print
+pdfjs-save-button =
+ .title = Save
+pdfjs-save-button-label = Save
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Download
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Download
+pdfjs-bookmark-button =
+ .title = Current Page (View URL from Current Page)
+pdfjs-bookmark-button-label = Current Page
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Open in app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Open in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Go to First Page
+pdfjs-first-page-button-label = Go to First Page
+pdfjs-last-page-button =
+ .title = Go to Last Page
+pdfjs-last-page-button-label = Go to Last Page
+pdfjs-page-rotate-cw-button =
+ .title = Rotate Clockwise
+pdfjs-page-rotate-cw-button-label = Rotate Clockwise
+pdfjs-page-rotate-ccw-button =
+ .title = Rotate Anti-Clockwise
+pdfjs-page-rotate-ccw-button-label = Rotate Anti-Clockwise
+pdfjs-cursor-text-select-tool-button =
+ .title = Enable Text Selection Tool
+pdfjs-cursor-text-select-tool-button-label = Text Selection Tool
+pdfjs-cursor-hand-tool-button =
+ .title = Enable Hand Tool
+pdfjs-cursor-hand-tool-button-label = Hand Tool
+pdfjs-scroll-page-button =
+ .title = Use Page Scrolling
+pdfjs-scroll-page-button-label = Page Scrolling
+pdfjs-scroll-vertical-button =
+ .title = Use Vertical Scrolling
+pdfjs-scroll-vertical-button-label = Vertical Scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Use Horizontal Scrolling
+pdfjs-scroll-horizontal-button-label = Horizontal Scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Use Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = Do not join page spreads
+pdfjs-spread-none-button-label = No Spreads
+pdfjs-spread-odd-button =
+ .title = Join page spreads starting with odd-numbered pages
+pdfjs-spread-odd-button-label = Odd Spreads
+pdfjs-spread-even-button =
+ .title = Join page spreads starting with even-numbered pages
+pdfjs-spread-even-button-label = Even Spreads
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Document Properties…
+pdfjs-document-properties-button-label = Document Properties…
+pdfjs-document-properties-file-name = File name:
+pdfjs-document-properties-file-size = File size:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Title:
+pdfjs-document-properties-author = Author:
+pdfjs-document-properties-subject = Subject:
+pdfjs-document-properties-keywords = Keywords:
+pdfjs-document-properties-creation-date = Creation Date:
+pdfjs-document-properties-modification-date = Modification Date:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creator:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Page Count:
+pdfjs-document-properties-page-size = Page Size:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = landscape
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Yes
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Close
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancel
+pdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.
+pdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggle Sidebar
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toggle Sidebar (document contains outline/attachments/layers)
+pdfjs-toggle-sidebar-button-label = Toggle Sidebar
+pdfjs-document-outline-button =
+ .title = Show Document Outline (double-click to expand/collapse all items)
+pdfjs-document-outline-button-label = Document Outline
+pdfjs-attachments-button =
+ .title = Show Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-layers-button =
+ .title = Show Layers (double-click to reset all layers to the default state)
+pdfjs-layers-button-label = Layers
+pdfjs-thumbs-button =
+ .title = Show Thumbnails
+pdfjs-thumbs-button-label = Thumbnails
+pdfjs-current-outline-item-button =
+ .title = Find Current Outline Item
+pdfjs-current-outline-item-button-label = Current Outline Item
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = Find
+pdfjs-additional-layers = Additional Layers
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail of Page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find in document…
+pdfjs-find-previous-button =
+ .title = Find the previous occurrence of the phrase
+pdfjs-find-previous-button-label = Previous
+pdfjs-find-next-button =
+ .title = Find the next occurrence of the phrase
+pdfjs-find-next-button-label = Next
+pdfjs-find-highlight-checkbox = Highlight All
+pdfjs-find-match-case-checkbox-label = Match Case
+pdfjs-find-match-diacritics-checkbox-label = Match Diacritics
+pdfjs-find-entire-word-checkbox-label = Whole Words
+pdfjs-find-reached-top = Reached top of document, continued from bottom
+pdfjs-find-reached-bottom = Reached end of document, continued from top
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } of { $total } match
+ *[other] { $current } of { $total } matches
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] More than { $limit } match
+ *[other] More than { $limit } matches
+ }
+pdfjs-find-not-found = Phrase not found
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Page Width
+pdfjs-page-scale-fit = Page Fit
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Actual Size
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Page { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = An error occurred while loading the PDF.
+pdfjs-invalid-file-error = Invalid or corrupted PDF file.
+pdfjs-missing-file-error = Missing PDF file.
+pdfjs-unexpected-response-error = Unexpected server response.
+pdfjs-rendering-error = An error occurred while rendering the page.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Enter the password to open this PDF file.
+pdfjs-password-invalid = Invalid password. Please try again.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancel
+pdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Draw
+pdfjs-editor-ink-button-label = Draw
+pdfjs-editor-stamp-button =
+ .title = Add or edit images
+pdfjs-editor-stamp-button-label = Add or edit images
+pdfjs-editor-remove-button =
+ .title = Remove
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Remove drawing
+pdfjs-editor-remove-freetext-button =
+ .title = Remove text
+pdfjs-editor-remove-stamp-button =
+ .title = Remove image
+pdfjs-editor-remove-highlight-button =
+ .title = Remove highlight
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colour
+pdfjs-editor-free-text-size-input = Size
+pdfjs-editor-ink-color-input = Colour
+pdfjs-editor-ink-thickness-input = Thickness
+pdfjs-editor-ink-opacity-input = Opacity
+pdfjs-editor-stamp-add-image-button =
+ .title = Add image
+pdfjs-editor-stamp-add-image-button-label = Add image
+pdfjs-free-text =
+ .aria-label = Text Editor
+pdfjs-free-text-default-content = Start typing…
+pdfjs-ink =
+ .aria-label = Draw Editor
+pdfjs-ink-canvas =
+ .aria-label = User-created image
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alt text
+pdfjs-editor-alt-text-edit-button-label = Edit alt text
+pdfjs-editor-alt-text-dialog-label = Choose an option
+pdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
+pdfjs-editor-alt-text-add-description-label = Add a description
+pdfjs-editor-alt-text-add-description-description = Aim for 1-2 sentences that describe the subject, setting, or actions.
+pdfjs-editor-alt-text-mark-decorative-label = Mark as decorative
+pdfjs-editor-alt-text-mark-decorative-description = This is used for ornamental images, like borders or watermarks.
+pdfjs-editor-alt-text-cancel-button = Cancel
+pdfjs-editor-alt-text-save-button = Save
+pdfjs-editor-alt-text-decorative-tooltip = Marked as decorative
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = For example, “A young man sits down at a table to eat a mealâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Top left corner — resize
+pdfjs-editor-resizer-label-top-middle = Top middle — resize
+pdfjs-editor-resizer-label-top-right = Top right corner — resize
+pdfjs-editor-resizer-label-middle-right = Middle right — resize
+pdfjs-editor-resizer-label-bottom-right = Bottom right corner — resize
+pdfjs-editor-resizer-label-bottom-middle = Bottom middle — resize
+pdfjs-editor-resizer-label-bottom-left = Bottom left corner — resize
+pdfjs-editor-resizer-label-middle-left = Middle left — resize
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Highlight colour
+pdfjs-editor-colorpicker-button =
+ .title = Change colour
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Colour choices
+pdfjs-editor-colorpicker-yellow =
+ .title = Yellow
+pdfjs-editor-colorpicker-green =
+ .title = Green
+pdfjs-editor-colorpicker-blue =
+ .title = Blue
+pdfjs-editor-colorpicker-pink =
+ .title = Pink
+pdfjs-editor-colorpicker-red =
+ .title = Red
diff --git a/www/lib/pdfjs/modern/web/locale/en-US/viewer.ftl b/www/lib/pdfjs/modern/web/locale/en-US/viewer.ftl
new file mode 100644
index 000000000..a40842a65
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/en-US/viewer.ftl
@@ -0,0 +1,411 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Previous Page
+pdfjs-previous-button-label = Previous
+pdfjs-next-button =
+ .title = Next Page
+pdfjs-next-button-label = Next
+
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Page
+
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = of { $pagesCount }
+
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+
+pdfjs-zoom-out-button =
+ .title = Zoom Out
+pdfjs-zoom-out-button-label = Zoom Out
+pdfjs-zoom-in-button =
+ .title = Zoom In
+pdfjs-zoom-in-button-label = Zoom In
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Switch to Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Open File
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Print
+pdfjs-print-button-label = Print
+pdfjs-save-button =
+ .title = Save
+pdfjs-save-button-label = Save
+
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Download
+
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Download
+
+pdfjs-bookmark-button =
+ .title = Current Page (View URL from Current Page)
+pdfjs-bookmark-button-label = Current Page
+
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Open in app
+
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Open in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Go to First Page
+pdfjs-first-page-button-label = Go to First Page
+pdfjs-last-page-button =
+ .title = Go to Last Page
+pdfjs-last-page-button-label = Go to Last Page
+pdfjs-page-rotate-cw-button =
+ .title = Rotate Clockwise
+pdfjs-page-rotate-cw-button-label = Rotate Clockwise
+pdfjs-page-rotate-ccw-button =
+ .title = Rotate Counterclockwise
+pdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise
+pdfjs-cursor-text-select-tool-button =
+ .title = Enable Text Selection Tool
+pdfjs-cursor-text-select-tool-button-label = Text Selection Tool
+pdfjs-cursor-hand-tool-button =
+ .title = Enable Hand Tool
+pdfjs-cursor-hand-tool-button-label = Hand Tool
+pdfjs-scroll-page-button =
+ .title = Use Page Scrolling
+pdfjs-scroll-page-button-label = Page Scrolling
+pdfjs-scroll-vertical-button =
+ .title = Use Vertical Scrolling
+pdfjs-scroll-vertical-button-label = Vertical Scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Use Horizontal Scrolling
+pdfjs-scroll-horizontal-button-label = Horizontal Scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Use Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = Do not join page spreads
+pdfjs-spread-none-button-label = No Spreads
+pdfjs-spread-odd-button =
+ .title = Join page spreads starting with odd-numbered pages
+pdfjs-spread-odd-button-label = Odd Spreads
+pdfjs-spread-even-button =
+ .title = Join page spreads starting with even-numbered pages
+pdfjs-spread-even-button-label = Even Spreads
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Document Properties…
+pdfjs-document-properties-button-label = Document Properties…
+pdfjs-document-properties-file-name = File name:
+pdfjs-document-properties-file-size = File size:
+
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+
+pdfjs-document-properties-title = Title:
+pdfjs-document-properties-author = Author:
+pdfjs-document-properties-subject = Subject:
+pdfjs-document-properties-keywords = Keywords:
+pdfjs-document-properties-creation-date = Creation Date:
+pdfjs-document-properties-modification-date = Modification Date:
+
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+
+pdfjs-document-properties-creator = Creator:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Page Count:
+pdfjs-document-properties-page-size = Page Size:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = landscape
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Yes
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Close
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+
+pdfjs-print-progress-close-button = Cancel
+pdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.
+pdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggle Sidebar
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toggle Sidebar (document contains outline/attachments/layers)
+pdfjs-toggle-sidebar-button-label = Toggle Sidebar
+pdfjs-document-outline-button =
+ .title = Show Document Outline (double-click to expand/collapse all items)
+pdfjs-document-outline-button-label = Document Outline
+pdfjs-attachments-button =
+ .title = Show Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-layers-button =
+ .title = Show Layers (double-click to reset all layers to the default state)
+pdfjs-layers-button-label = Layers
+pdfjs-thumbs-button =
+ .title = Show Thumbnails
+pdfjs-thumbs-button-label = Thumbnails
+pdfjs-current-outline-item-button =
+ .title = Find Current Outline Item
+pdfjs-current-outline-item-button-label = Current Outline Item
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = Find
+pdfjs-additional-layers = Additional Layers
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail of Page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find in document…
+pdfjs-find-previous-button =
+ .title = Find the previous occurrence of the phrase
+pdfjs-find-previous-button-label = Previous
+pdfjs-find-next-button =
+ .title = Find the next occurrence of the phrase
+pdfjs-find-next-button-label = Next
+pdfjs-find-highlight-checkbox = Highlight All
+pdfjs-find-match-case-checkbox-label = Match Case
+pdfjs-find-match-diacritics-checkbox-label = Match Diacritics
+pdfjs-find-entire-word-checkbox-label = Whole Words
+pdfjs-find-reached-top = Reached top of document, continued from bottom
+pdfjs-find-reached-bottom = Reached end of document, continued from top
+
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } of { $total } match
+ *[other] { $current } of { $total } matches
+ }
+
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] More than { $limit } match
+ *[other] More than { $limit } matches
+ }
+
+pdfjs-find-not-found = Phrase not found
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Page Width
+pdfjs-page-scale-fit = Page Fit
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Actual Size
+
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Page { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = An error occurred while loading the PDF.
+pdfjs-invalid-file-error = Invalid or corrupted PDF file.
+pdfjs-missing-file-error = Missing PDF file.
+pdfjs-unexpected-response-error = Unexpected server response.
+pdfjs-rendering-error = An error occurred while rendering the page.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Enter the password to open this PDF file.
+pdfjs-password-invalid = Invalid password. Please try again.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancel
+pdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Draw
+pdfjs-editor-ink-button-label = Draw
+pdfjs-editor-stamp-button =
+ .title = Add or edit images
+pdfjs-editor-stamp-button-label = Add or edit images
+pdfjs-editor-highlight-button =
+ .title = Highlight
+pdfjs-editor-highlight-button-label = Highlight
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Remove drawing
+pdfjs-editor-remove-freetext-button =
+ .title = Remove text
+pdfjs-editor-remove-stamp-button =
+ .title = Remove image
+pdfjs-editor-remove-highlight-button =
+ .title = Remove highlight
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Size
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Thickness
+pdfjs-editor-ink-opacity-input = Opacity
+pdfjs-editor-stamp-add-image-button =
+ .title = Add image
+pdfjs-editor-stamp-add-image-button-label = Add image
+
+pdfjs-free-text =
+ .aria-label = Text Editor
+pdfjs-free-text-default-content = Start typing…
+pdfjs-ink =
+ .aria-label = Draw Editor
+pdfjs-ink-canvas =
+ .aria-label = User-created image
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alt text
+
+pdfjs-editor-alt-text-edit-button-label = Edit alt text
+pdfjs-editor-alt-text-dialog-label = Choose an option
+pdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
+pdfjs-editor-alt-text-add-description-label = Add a description
+pdfjs-editor-alt-text-add-description-description = Aim for 1-2 sentences that describe the subject, setting, or actions.
+pdfjs-editor-alt-text-mark-decorative-label = Mark as decorative
+pdfjs-editor-alt-text-mark-decorative-description = This is used for ornamental images, like borders or watermarks.
+pdfjs-editor-alt-text-cancel-button = Cancel
+pdfjs-editor-alt-text-save-button = Save
+pdfjs-editor-alt-text-decorative-tooltip = Marked as decorative
+
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = For example, “A young man sits down at a table to eat a mealâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Top left corner — resize
+pdfjs-editor-resizer-label-top-middle = Top middle — resize
+pdfjs-editor-resizer-label-top-right = Top right corner — resize
+pdfjs-editor-resizer-label-middle-right = Middle right — resize
+pdfjs-editor-resizer-label-bottom-right = Bottom right corner — resize
+pdfjs-editor-resizer-label-bottom-middle = Bottom middle — resize
+pdfjs-editor-resizer-label-bottom-left = Bottom left corner — resize
+pdfjs-editor-resizer-label-middle-left = Middle left — resize
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Highlight color
+
+pdfjs-editor-colorpicker-button =
+ .title = Change color
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Color choices
+pdfjs-editor-colorpicker-yellow =
+ .title = Yellow
+pdfjs-editor-colorpicker-green =
+ .title = Green
+pdfjs-editor-colorpicker-blue =
+ .title = Blue
+pdfjs-editor-colorpicker-pink =
+ .title = Pink
+pdfjs-editor-colorpicker-red =
+ .title = Red
diff --git a/www/lib/pdfjs/modern/web/locale/eo/viewer.ftl b/www/lib/pdfjs/modern/web/locale/eo/viewer.ftl
new file mode 100644
index 000000000..22c473cb2
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/eo/viewer.ftl
@@ -0,0 +1,349 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = AntaÅa paÄo
+pdfjs-previous-button-label = MalantaÅen
+pdfjs-next-button =
+ .title = Venonta paÄo
+pdfjs-next-button-label = AntaÅen
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = PaÄo
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = el { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } el { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Malpligrandigi
+pdfjs-zoom-out-button-label = Malpligrandigi
+pdfjs-zoom-in-button =
+ .title = Pligrandigi
+pdfjs-zoom-in-button-label = Pligrandigi
+pdfjs-zoom-select =
+ .title = Pligrandigilo
+pdfjs-presentation-mode-button =
+ .title = Iri al prezenta reÄimo
+pdfjs-presentation-mode-button-label = Prezenta reÄimo
+pdfjs-open-file-button =
+ .title = Malfermi dosieron
+pdfjs-open-file-button-label = Malfermi
+pdfjs-print-button =
+ .title = Presi
+pdfjs-print-button-label = Presi
+pdfjs-save-button =
+ .title = Konservi
+pdfjs-save-button-label = Konservi
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ElÅuti
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ElÅuti
+pdfjs-bookmark-button =
+ .title = Nuna paÄo (Montri adreson de la nuna paÄo)
+pdfjs-bookmark-button-label = Nuna paÄo
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Malfermi en programo
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Malfermi en programo
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Iloj
+pdfjs-tools-button-label = Iloj
+pdfjs-first-page-button =
+ .title = Iri al la unua paÄo
+pdfjs-first-page-button-label = Iri al la unua paÄo
+pdfjs-last-page-button =
+ .title = Iri al la lasta paÄo
+pdfjs-last-page-button-label = Iri al la lasta paÄo
+pdfjs-page-rotate-cw-button =
+ .title = Rotaciigi dekstrume
+pdfjs-page-rotate-cw-button-label = Rotaciigi dekstrume
+pdfjs-page-rotate-ccw-button =
+ .title = Rotaciigi maldekstrume
+pdfjs-page-rotate-ccw-button-label = Rotaciigi maldekstrume
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktivigi tekstan elektilon
+pdfjs-cursor-text-select-tool-button-label = Teksta elektilo
+pdfjs-cursor-hand-tool-button =
+ .title = Aktivigi ilon de mano
+pdfjs-cursor-hand-tool-button-label = Ilo de mano
+pdfjs-scroll-page-button =
+ .title = Uzi Åovadon de paÄo
+pdfjs-scroll-page-button-label = Åœovado de paÄo
+pdfjs-scroll-vertical-button =
+ .title = Uzi vertikalan Åovadon
+pdfjs-scroll-vertical-button-label = Vertikala Åovado
+pdfjs-scroll-horizontal-button =
+ .title = Uzi horizontalan Åovadon
+pdfjs-scroll-horizontal-button-label = Horizontala Åovado
+pdfjs-scroll-wrapped-button =
+ .title = Uzi ambaÅdirektan Åovadon
+pdfjs-scroll-wrapped-button-label = AmbaÅdirekta Åovado
+pdfjs-spread-none-button =
+ .title = Ne montri paÄojn po du
+pdfjs-spread-none-button-label = UnupaÄa vido
+pdfjs-spread-odd-button =
+ .title = Kunigi paÄojn komencante per nepara paÄo
+pdfjs-spread-odd-button-label = Po du paÄoj, neparaj maldekstre
+pdfjs-spread-even-button =
+ .title = Kunigi paÄojn komencante per para paÄo
+pdfjs-spread-even-button-label = Po du paÄoj, paraj maldekstre
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Atributoj de dokumento…
+pdfjs-document-properties-button-label = Atributoj de dokumento…
+pdfjs-document-properties-file-name = Nomo de dosiero:
+pdfjs-document-properties-file-size = Grando de dosiero:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KO ({ $size_b } oktetoj)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MO ({ $size_b } oktetoj)
+pdfjs-document-properties-title = Titolo:
+pdfjs-document-properties-author = AÅtoro:
+pdfjs-document-properties-subject = Temo:
+pdfjs-document-properties-keywords = Åœlosilvorto:
+pdfjs-document-properties-creation-date = Dato de kreado:
+pdfjs-document-properties-modification-date = Dato de modifo:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Kreinto:
+pdfjs-document-properties-producer = Produktinto de PDF:
+pdfjs-document-properties-version = Versio de PDF:
+pdfjs-document-properties-page-count = Nombro de paÄoj:
+pdfjs-document-properties-page-size = Grando de paÄo:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertikala
+pdfjs-document-properties-page-size-orientation-landscape = horizontala
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letera
+pdfjs-document-properties-page-size-name-legal = Jura
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Rapida tekstaĵa vido:
+pdfjs-document-properties-linearized-yes = Jes
+pdfjs-document-properties-linearized-no = Ne
+pdfjs-document-properties-close-button = Fermi
+
+## Print
+
+pdfjs-print-progress-message = Preparo de dokumento por presi Äin …
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Nuligi
+pdfjs-printing-not-supported = Averto: tiu ĉi retumilo ne plene subtenas presadon.
+pdfjs-printing-not-ready = Averto: la PDF dosiero ne estas plene Åargita por presado.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Montri/kaÅi flankan strion
+pdfjs-toggle-sidebar-notification-button =
+ .title = Montri/kaÅi flankan strion (la dokumento enhavas konturon/kunsendaĵojn/tavolojn)
+pdfjs-toggle-sidebar-button-label = Montri/kaÅi flankan strion
+pdfjs-document-outline-button =
+ .title = Montri la konturon de dokumento (alklaku duoble por faldi/malfaldi ĉiujn elementojn)
+pdfjs-document-outline-button-label = Konturo de dokumento
+pdfjs-attachments-button =
+ .title = Montri kunsendaĵojn
+pdfjs-attachments-button-label = Kunsendaĵojn
+pdfjs-layers-button =
+ .title = Montri tavolojn (duoble alklaku por remeti ĉiujn tavolojn en la norman staton)
+pdfjs-layers-button-label = Tavoloj
+pdfjs-thumbs-button =
+ .title = Montri miniaturojn
+pdfjs-thumbs-button-label = Miniaturoj
+pdfjs-current-outline-item-button =
+ .title = Trovi nunan konturan elementon
+pdfjs-current-outline-item-button-label = Nuna kontura elemento
+pdfjs-findbar-button =
+ .title = Serĉi en dokumento
+pdfjs-findbar-button-label = Serĉi
+pdfjs-additional-layers = Aldonaj tavoloj
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = PaÄo { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniaturo de paÄo { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Serĉi
+ .placeholder = Serĉi en dokumento…
+pdfjs-find-previous-button =
+ .title = Serĉi la antaÅan aperon de la frazo
+pdfjs-find-previous-button-label = MalantaÅen
+pdfjs-find-next-button =
+ .title = Serĉi la venontan aperon de la frazo
+pdfjs-find-next-button-label = AntaÅen
+pdfjs-find-highlight-checkbox = Elstarigi ĉiujn
+pdfjs-find-match-case-checkbox-label = Distingi inter majuskloj kaj minuskloj
+pdfjs-find-match-diacritics-checkbox-label = Respekti supersignojn
+pdfjs-find-entire-word-checkbox-label = Tutaj vortoj
+pdfjs-find-reached-top = Komenco de la dokumento atingita, daÅrigado ekde la fino
+pdfjs-find-reached-bottom = Fino de la dokumento atingita, daÅrigado ekde la komenco
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } el { $total } kongruo
+ *[other] { $current } el { $total } kongruoj
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Pli ol { $limit } kongruo
+ *[other] Pli ol { $limit } kongruoj
+ }
+pdfjs-find-not-found = Frazo ne trovita
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = LarÄo de paÄo
+pdfjs-page-scale-fit = Adapti paÄon
+pdfjs-page-scale-auto = AÅtomata skalo
+pdfjs-page-scale-actual = Reala grando
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = PaÄo { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Okazis eraro dum la Åargado de la PDF dosiero.
+pdfjs-invalid-file-error = Nevalida aÅ difektita PDF dosiero.
+pdfjs-missing-file-error = Mankas dosiero PDF.
+pdfjs-unexpected-response-error = Neatendita respondo de servilo.
+pdfjs-rendering-error = Okazis eraro dum la montro de la paÄo.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Prinoto: { $type }]
+
+## Password
+
+pdfjs-password-label = Tajpu pasvorton por malfermi tiun ĉi dosieron PDF.
+pdfjs-password-invalid = Nevalida pasvorto. Bonvolu provi denove.
+pdfjs-password-ok-button = Akcepti
+pdfjs-password-cancel-button = Nuligi
+pdfjs-web-fonts-disabled = Neaktivaj teksaĵaj tiparoj: ne elbas uzi enmetitajn tiparojn de PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Teksto
+pdfjs-editor-free-text-button-label = Teksto
+pdfjs-editor-ink-button =
+ .title = Desegni
+pdfjs-editor-ink-button-label = Desegni
+pdfjs-editor-stamp-button =
+ .title = Aldoni aÅ modifi bildojn
+pdfjs-editor-stamp-button-label = Aldoni aÅ modifi bildojn
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Koloro
+pdfjs-editor-free-text-size-input = Grando
+pdfjs-editor-ink-color-input = Koloro
+pdfjs-editor-ink-thickness-input = Dikeco
+pdfjs-editor-ink-opacity-input = Maldiafaneco
+pdfjs-editor-stamp-add-image-button =
+ .title = Aldoni bildon
+pdfjs-editor-stamp-add-image-button-label = Aldoni bildon
+pdfjs-free-text =
+ .aria-label = Tekstan redaktilon
+pdfjs-free-text-default-content = Ektajpi…
+pdfjs-ink =
+ .aria-label = Desegnan redaktilon
+pdfjs-ink-canvas =
+ .aria-label = Bildo kreita de uzanto
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternativa teksto
+pdfjs-editor-alt-text-edit-button-label = Redakti alternativan tekston
+pdfjs-editor-alt-text-dialog-label = Elektu eblon
+pdfjs-editor-alt-text-dialog-description = Alternativa teksto helpas personojn, en la okazoj kiam ili ne povas vidi aÅ Åargi la bildon.
+pdfjs-editor-alt-text-add-description-label = Aldoni priskribon
+pdfjs-editor-alt-text-add-description-description = La celo estas unu aÅ du frazoj, kiuj priskribas la temon, etoson aÅ agojn.
+pdfjs-editor-alt-text-mark-decorative-label = Marki kiel ornaman
+pdfjs-editor-alt-text-mark-decorative-description = Tio ĉi estas uzita por ornamaj bildoj, kiel randoj aŠfonaj bildoj.
+pdfjs-editor-alt-text-cancel-button = Nuligi
+pdfjs-editor-alt-text-save-button = Konservi
+pdfjs-editor-alt-text-decorative-tooltip = Markita kiel ornama
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Ekzemple: “Juna persono sidiÄas ĉetable por ekmanÄiâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Supra maldekstra angulo — Åangi grandon
+pdfjs-editor-resizer-label-top-middle = Supra mezo — ÅanÄi grandon
+pdfjs-editor-resizer-label-top-right = Supran dekstran angulon — ÅanÄi grandon
+pdfjs-editor-resizer-label-middle-right = Dekstra mezo — ÅanÄi grandon
+pdfjs-editor-resizer-label-bottom-right = Malsupra deksta angulo — ÅanÄi grandon
+pdfjs-editor-resizer-label-bottom-middle = Malsupra mezo — ÅanÄi grandon
+pdfjs-editor-resizer-label-bottom-left = Malsupra maldekstra angulo — ÅanÄi grandon
+pdfjs-editor-resizer-label-middle-left = Maldekstra mezo — ÅanÄi grandon
diff --git a/www/lib/pdfjs/modern/web/locale/es-AR/viewer.ftl b/www/lib/pdfjs/modern/web/locale/es-AR/viewer.ftl
new file mode 100644
index 000000000..4865a5339
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/es-AR/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Página siguiente
+pdfjs-next-button-label = Siguiente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ( { $pageNumber } de { $pagesCount } )
+pdfjs-zoom-out-button =
+ .title = Alejar
+pdfjs-zoom-out-button-label = Alejar
+pdfjs-zoom-in-button =
+ .title = Acercar
+pdfjs-zoom-in-button-label = Acercar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Cambiar a modo presentación
+pdfjs-presentation-mode-button-label = Modo presentación
+pdfjs-open-file-button =
+ .title = Abrir archivo
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Guardar
+pdfjs-save-button-label = Guardar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Descargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Descargar
+pdfjs-bookmark-button =
+ .title = Página actual (Ver URL de la página actual)
+pdfjs-bookmark-button-label = Página actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir en la aplicación
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir en la aplicación
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Herramientas
+pdfjs-tools-button-label = Herramientas
+pdfjs-first-page-button =
+ .title = Ir a primera página
+pdfjs-first-page-button-label = Ir a primera página
+pdfjs-last-page-button =
+ .title = Ir a última página
+pdfjs-last-page-button-label = Ir a última página
+pdfjs-page-rotate-cw-button =
+ .title = Rotar horario
+pdfjs-page-rotate-cw-button-label = Rotar horario
+pdfjs-page-rotate-ccw-button =
+ .title = Rotar antihorario
+pdfjs-page-rotate-ccw-button-label = Rotar antihorario
+pdfjs-cursor-text-select-tool-button =
+ .title = Habilitar herramienta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Herramienta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Habilitar herramienta mano
+pdfjs-cursor-hand-tool-button-label = Herramienta mano
+pdfjs-scroll-page-button =
+ .title = Usar desplazamiento de página
+pdfjs-scroll-page-button-label = Desplazamiento de página
+pdfjs-scroll-vertical-button =
+ .title = Usar desplazamiento vertical
+pdfjs-scroll-vertical-button-label = Desplazamiento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar desplazamiento vertical
+pdfjs-scroll-horizontal-button-label = Desplazamiento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar desplazamiento encapsulado
+pdfjs-scroll-wrapped-button-label = Desplazamiento encapsulado
+pdfjs-spread-none-button =
+ .title = No unir páginas dobles
+pdfjs-spread-none-button-label = Sin dobles
+pdfjs-spread-odd-button =
+ .title = Unir páginas dobles comenzando con las impares
+pdfjs-spread-odd-button-label = Dobles impares
+pdfjs-spread-even-button =
+ .title = Unir páginas dobles comenzando con las pares
+pdfjs-spread-even-button-label = Dobles pares
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades del documento…
+pdfjs-document-properties-button-label = Propiedades del documento…
+pdfjs-document-properties-file-name = Nombre de archivo:
+pdfjs-document-properties-file-size = Tamaño de archovo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Asunto:
+pdfjs-document-properties-keywords = Palabras clave:
+pdfjs-document-properties-creation-date = Fecha de creación:
+pdfjs-document-properties-modification-date = Fecha de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creador:
+pdfjs-document-properties-producer = PDF Productor:
+pdfjs-document-properties-version = Versión de PDF:
+pdfjs-document-properties-page-count = Cantidad de páginas:
+pdfjs-document-properties-page-size = Tamaño de página:
+pdfjs-document-properties-page-size-unit-inches = en
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = normal
+pdfjs-document-properties-page-size-orientation-landscape = apaisado
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista rápida de la Web:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Cerrar
+
+## Print
+
+pdfjs-print-progress-message = Preparando documento para imprimir…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Advertencia: La impresión no está totalmente soportada por este navegador.
+pdfjs-printing-not-ready = Advertencia: El PDF no está completamente cargado para impresión.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Alternar barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Alternar barra lateral (el documento contiene esquemas/adjuntos/capas)
+pdfjs-toggle-sidebar-button-label = Alternar barra lateral
+pdfjs-document-outline-button =
+ .title = Mostrar esquema del documento (doble clic para expandir/colapsar todos los Ãtems)
+pdfjs-document-outline-button-label = Esquema del documento
+pdfjs-attachments-button =
+ .title = Mostrar adjuntos
+pdfjs-attachments-button-label = Adjuntos
+pdfjs-layers-button =
+ .title = Mostrar capas (doble clic para restablecer todas las capas al estado predeterminado)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Buscar elemento de esquema actual
+pdfjs-current-outline-item-button-label = Elemento de esquema actual
+pdfjs-findbar-button =
+ .title = Buscar en documento
+pdfjs-findbar-button-label = Buscar
+pdfjs-additional-layers = Capas adicionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Buscar
+ .placeholder = Buscar en documento…
+pdfjs-find-previous-button =
+ .title = Buscar la aparición anterior de la frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Buscar la siguiente aparición de la frase
+pdfjs-find-next-button-label = Siguiente
+pdfjs-find-highlight-checkbox = Resaltar todo
+pdfjs-find-match-case-checkbox-label = Coincidir mayúsculas
+pdfjs-find-match-diacritics-checkbox-label = Coincidir diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palabras completas
+pdfjs-find-reached-top = Inicio de documento alcanzado, continuando desde abajo
+pdfjs-find-reached-bottom = Fin de documento alcanzando, continuando desde arriba
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } de { $total } coincidencia
+ *[other] { $current } de { $total } coincidencias
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Más de { $limit } coincidencia
+ *[other] Más de { $limit } coincidencias
+ }
+pdfjs-find-not-found = Frase no encontrada
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ancho de página
+pdfjs-page-scale-fit = Ajustar página
+pdfjs-page-scale-auto = Zoom automático
+pdfjs-page-scale-actual = Tamaño real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ocurrió un error al cargar el PDF.
+pdfjs-invalid-file-error = Archivo PDF no válido o cocrrupto.
+pdfjs-missing-file-error = Archivo PDF faltante.
+pdfjs-unexpected-response-error = Respuesta del servidor inesperada.
+pdfjs-rendering-error = Ocurrió un error al dibujar la página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Anotación]
+
+## Password
+
+pdfjs-password-label = Ingrese la contraseña para abrir este archivo PDF
+pdfjs-password-invalid = Contraseña inválida. Intente nuevamente.
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = TipografÃa web deshabilitada: no se pueden usar tipos incrustados en PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Dibujar
+pdfjs-editor-ink-button-label = Dibujar
+pdfjs-editor-stamp-button =
+ .title = Agregar o editar imágenes
+pdfjs-editor-stamp-button-label = Agregar o editar imágenes
+pdfjs-editor-remove-button =
+ .title = Eliminar
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Eliminar dibujo
+pdfjs-editor-remove-freetext-button =
+ .title = Eliminar texto
+pdfjs-editor-remove-stamp-button =
+ .title = Eliminar imagen
+pdfjs-editor-remove-highlight-button =
+ .title = Eliminar resaltado
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Tamaño
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Espesor
+pdfjs-editor-ink-opacity-input = Opacidad
+pdfjs-editor-stamp-add-image-button =
+ .title = Agregar una imagen
+pdfjs-editor-stamp-add-image-button-label = Agregar una imagen
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Empezar a tipear…
+pdfjs-ink =
+ .aria-label = Editor de dibujos
+pdfjs-ink-canvas =
+ .aria-label = Imagen creada por el usuario
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar el texto alternativo
+pdfjs-editor-alt-text-dialog-label = Eligir una opción
+pdfjs-editor-alt-text-dialog-description = El texto alternativo (texto alternativo) ayuda cuando las personas no pueden ver la imagen o cuando no se carga.
+pdfjs-editor-alt-text-add-description-label = Agregar una descripción
+pdfjs-editor-alt-text-add-description-description = Intente escribir 1 o 2 oraciones que describan el tema, el entorno o las acciones.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativo
+pdfjs-editor-alt-text-mark-decorative-description = Esto se usa para imágenes ornamentales, como bordes o marcas de agua.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Guardar
+pdfjs-editor-alt-text-decorative-tooltip = Marcado como decorativo
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por ejemplo: “Un joven se sienta a la mesa a comerâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Esquina superior izquierda — cambiar el tamaño
+pdfjs-editor-resizer-label-top-middle = Arriba en el medio — cambiar el tamaño
+pdfjs-editor-resizer-label-top-right = Esquina superior derecha — cambiar el tamaño
+pdfjs-editor-resizer-label-middle-right = Al centro a la derecha — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-right = Esquina inferior derecha — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-middle = Abajo en el medio — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-left = Esquina inferior izquierda — cambiar el tamaño
+pdfjs-editor-resizer-label-middle-left = Al centro a la izquierda — cambiar el tamaño
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Color de resaltado
+pdfjs-editor-colorpicker-button =
+ .title = Cambiar el color
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Opciones de color
+pdfjs-editor-colorpicker-yellow =
+ .title = Amarillo
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Azul
+pdfjs-editor-colorpicker-pink =
+ .title = Rosado
+pdfjs-editor-colorpicker-red =
+ .title = Rojo
diff --git a/www/lib/pdfjs/modern/web/locale/es-CL/viewer.ftl b/www/lib/pdfjs/modern/web/locale/es-CL/viewer.ftl
new file mode 100644
index 000000000..095f7dee0
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/es-CL/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Página siguiente
+pdfjs-next-button-label = Siguiente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Alejar
+pdfjs-zoom-out-button-label = Alejar
+pdfjs-zoom-in-button =
+ .title = Acercar
+pdfjs-zoom-in-button-label = Acercar
+pdfjs-zoom-select =
+ .title = Ampliación
+pdfjs-presentation-mode-button =
+ .title = Cambiar al modo de presentación
+pdfjs-presentation-mode-button-label = Modo de presentación
+pdfjs-open-file-button =
+ .title = Abrir archivo
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Guardar
+pdfjs-save-button-label = Guardar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Descargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Descargar
+pdfjs-bookmark-button =
+ .title = Página actual (Ver URL de la página actual)
+pdfjs-bookmark-button-label = Página actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir en una aplicación
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir en una aplicación
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Herramientas
+pdfjs-tools-button-label = Herramientas
+pdfjs-first-page-button =
+ .title = Ir a la primera página
+pdfjs-first-page-button-label = Ir a la primera página
+pdfjs-last-page-button =
+ .title = Ir a la última página
+pdfjs-last-page-button-label = Ir a la última página
+pdfjs-page-rotate-cw-button =
+ .title = Girar a la derecha
+pdfjs-page-rotate-cw-button-label = Girar a la derecha
+pdfjs-page-rotate-ccw-button =
+ .title = Girar a la izquierda
+pdfjs-page-rotate-ccw-button-label = Girar a la izquierda
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar la herramienta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Herramienta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar la herramienta de mano
+pdfjs-cursor-hand-tool-button-label = Herramienta de mano
+pdfjs-scroll-page-button =
+ .title = Usar desplazamiento de página
+pdfjs-scroll-page-button-label = Desplazamiento de página
+pdfjs-scroll-vertical-button =
+ .title = Usar desplazamiento vertical
+pdfjs-scroll-vertical-button-label = Desplazamiento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar desplazamiento horizontal
+pdfjs-scroll-horizontal-button-label = Desplazamiento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar desplazamiento en bloque
+pdfjs-scroll-wrapped-button-label = Desplazamiento en bloque
+pdfjs-spread-none-button =
+ .title = No juntar páginas a modo de libro
+pdfjs-spread-none-button-label = Vista de una página
+pdfjs-spread-odd-button =
+ .title = Junta las páginas partiendo con una de número impar
+pdfjs-spread-odd-button-label = Vista de libro impar
+pdfjs-spread-even-button =
+ .title = Junta las páginas partiendo con una de número par
+pdfjs-spread-even-button-label = Vista de libro par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades del documento…
+pdfjs-document-properties-button-label = Propiedades del documento…
+pdfjs-document-properties-file-name = Nombre de archivo:
+pdfjs-document-properties-file-size = Tamaño del archivo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Asunto:
+pdfjs-document-properties-keywords = Palabras clave:
+pdfjs-document-properties-creation-date = Fecha de creación:
+pdfjs-document-properties-modification-date = Fecha de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creador:
+pdfjs-document-properties-producer = Productor del PDF:
+pdfjs-document-properties-version = Versión de PDF:
+pdfjs-document-properties-page-count = Cantidad de páginas:
+pdfjs-document-properties-page-size = Tamaño de la página:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Oficio
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista rápida en Web:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Cerrar
+
+## Print
+
+pdfjs-print-progress-message = Preparando documento para impresión…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Advertencia: Imprimir no está soportado completamente por este navegador.
+pdfjs-printing-not-ready = Advertencia: El PDF no está completamente cargado para ser impreso.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Cambiar barra lateral (Ãndice de contenidos del documento/adjuntos/capas)
+pdfjs-toggle-sidebar-button-label = Mostrar u ocultar la barra lateral
+pdfjs-document-outline-button =
+ .title = Mostrar esquema del documento (doble clic para expandir/contraer todos los elementos)
+pdfjs-document-outline-button-label = Esquema del documento
+pdfjs-attachments-button =
+ .title = Mostrar adjuntos
+pdfjs-attachments-button-label = Adjuntos
+pdfjs-layers-button =
+ .title = Mostrar capas (doble clic para restablecer todas las capas al estado predeterminado)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Buscar elemento de esquema actual
+pdfjs-current-outline-item-button-label = Elemento de esquema actual
+pdfjs-findbar-button =
+ .title = Buscar en el documento
+pdfjs-findbar-button-label = Buscar
+pdfjs-additional-layers = Capas adicionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de la página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Encontrar
+ .placeholder = Encontrar en el documento…
+pdfjs-find-previous-button =
+ .title = Buscar la aparición anterior de la frase
+pdfjs-find-previous-button-label = Previo
+pdfjs-find-next-button =
+ .title = Buscar la siguiente aparición de la frase
+pdfjs-find-next-button-label = Siguiente
+pdfjs-find-highlight-checkbox = Destacar todos
+pdfjs-find-match-case-checkbox-label = Coincidir mayús./minús.
+pdfjs-find-match-diacritics-checkbox-label = Coincidir diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palabras completas
+pdfjs-find-reached-top = Se alcanzó el inicio del documento, continuando desde el final
+pdfjs-find-reached-bottom = Se alcanzó el final del documento, continuando desde el inicio
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] Coincidencia { $current } de { $total }
+ *[other] Coincidencia { $current } de { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Más de { $limit } coincidencia
+ *[other] Más de { $limit } coincidencias
+ }
+pdfjs-find-not-found = Frase no encontrada
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ancho de página
+pdfjs-page-scale-fit = Ajuste de página
+pdfjs-page-scale-auto = Aumento automático
+pdfjs-page-scale-actual = Tamaño actual
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ocurrió un error al cargar el PDF.
+pdfjs-invalid-file-error = Archivo PDF inválido o corrupto.
+pdfjs-missing-file-error = Falta el archivo PDF.
+pdfjs-unexpected-response-error = Respuesta del servidor inesperada.
+pdfjs-rendering-error = Ocurrió un error al renderizar la página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Anotación]
+
+## Password
+
+pdfjs-password-label = Ingrese la contraseña para abrir este archivo PDF.
+pdfjs-password-invalid = Contraseña inválida. Por favor, vuelve a intentarlo.
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = Las tipografÃas web están desactivadas: imposible usar las fuentes PDF embebidas.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Dibujar
+pdfjs-editor-ink-button-label = Dibujar
+pdfjs-editor-stamp-button =
+ .title = Añadir o editar imágenes
+pdfjs-editor-stamp-button-label = Añadir o editar imágenes
+pdfjs-editor-remove-button =
+ .title = Eliminar
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Eliminar dibujo
+pdfjs-editor-remove-freetext-button =
+ .title = Eliminar texto
+pdfjs-editor-remove-stamp-button =
+ .title = Eliminar imagen
+pdfjs-editor-remove-highlight-button =
+ .title = Quitar resaltado
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Tamaño
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Grosor
+pdfjs-editor-ink-opacity-input = Opacidad
+pdfjs-editor-stamp-add-image-button =
+ .title = Añadir imagen
+pdfjs-editor-stamp-add-image-button-label = Añadir imagen
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Empieza a escribir…
+pdfjs-ink =
+ .aria-label = Editor de dibujos
+pdfjs-ink-canvas =
+ .aria-label = Imagen creada por el usuario
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar texto alternativo
+pdfjs-editor-alt-text-dialog-label = Elige una opción
+pdfjs-editor-alt-text-dialog-description = El texto alternativo (alt text) ayuda cuando las personas no pueden ver la imagen o cuando no se carga.
+pdfjs-editor-alt-text-add-description-label = Añade una descripción
+pdfjs-editor-alt-text-add-description-description = Intenta escribir 1 o 2 oraciones que describan el tema, el ambiente o las acciones.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativa
+pdfjs-editor-alt-text-mark-decorative-description = Se utiliza para imágenes ornamentales, como bordes o marcas de agua.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Guardar
+pdfjs-editor-alt-text-decorative-tooltip = Marcada como decorativa
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por ejemplo: “Un joven se sienta a la mesa a comerâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Esquina superior izquierda — cambiar el tamaño
+pdfjs-editor-resizer-label-top-middle = Borde superior en el medio — cambiar el tamaño
+pdfjs-editor-resizer-label-top-right = Esquina superior derecha — cambiar el tamaño
+pdfjs-editor-resizer-label-middle-right = Borde derecho en el medio — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-right = Esquina inferior derecha — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-middle = Borde inferior en el medio — cambiar el tamaño
+pdfjs-editor-resizer-label-bottom-left = Esquina inferior izquierda — cambiar el tamaño
+pdfjs-editor-resizer-label-middle-left = Borde izquierdo en el medio — cambiar el tamaño
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Color de resaltado
+pdfjs-editor-colorpicker-button =
+ .title = Cambiar color
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Opciones de color
+pdfjs-editor-colorpicker-yellow =
+ .title = Amarillo
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Azul
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Rojo
diff --git a/www/lib/pdfjs/modern/web/locale/es-ES/viewer.ftl b/www/lib/pdfjs/modern/web/locale/es-ES/viewer.ftl
new file mode 100644
index 000000000..6647abc0d
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/es-ES/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Página siguiente
+pdfjs-next-button-label = Siguiente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Reducir
+pdfjs-zoom-out-button-label = Reducir
+pdfjs-zoom-in-button =
+ .title = Aumentar
+pdfjs-zoom-in-button-label = Aumentar
+pdfjs-zoom-select =
+ .title = Tamaño
+pdfjs-presentation-mode-button =
+ .title = Cambiar al modo presentación
+pdfjs-presentation-mode-button-label = Modo presentación
+pdfjs-open-file-button =
+ .title = Abrir archivo
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Guardar
+pdfjs-save-button-label = Guardar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Descargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Descargar
+pdfjs-bookmark-button =
+ .title = Página actual (Ver URL de la página actual)
+pdfjs-bookmark-button-label = Página actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir en aplicación
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir en aplicación
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Herramientas
+pdfjs-tools-button-label = Herramientas
+pdfjs-first-page-button =
+ .title = Ir a la primera página
+pdfjs-first-page-button-label = Ir a la primera página
+pdfjs-last-page-button =
+ .title = Ir a la última página
+pdfjs-last-page-button-label = Ir a la última página
+pdfjs-page-rotate-cw-button =
+ .title = Rotar en sentido horario
+pdfjs-page-rotate-cw-button-label = Rotar en sentido horario
+pdfjs-page-rotate-ccw-button =
+ .title = Rotar en sentido antihorario
+pdfjs-page-rotate-ccw-button-label = Rotar en sentido antihorario
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar herramienta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Herramienta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar herramienta de mano
+pdfjs-cursor-hand-tool-button-label = Herramienta de mano
+pdfjs-scroll-page-button =
+ .title = Usar desplazamiento de página
+pdfjs-scroll-page-button-label = Desplazamiento de página
+pdfjs-scroll-vertical-button =
+ .title = Usar desplazamiento vertical
+pdfjs-scroll-vertical-button-label = Desplazamiento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar desplazamiento horizontal
+pdfjs-scroll-horizontal-button-label = Desplazamiento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar desplazamiento en bloque
+pdfjs-scroll-wrapped-button-label = Desplazamiento en bloque
+pdfjs-spread-none-button =
+ .title = No juntar páginas en vista de libro
+pdfjs-spread-none-button-label = Vista de libro
+pdfjs-spread-odd-button =
+ .title = Juntar las páginas partiendo de una con número impar
+pdfjs-spread-odd-button-label = Vista de libro impar
+pdfjs-spread-even-button =
+ .title = Juntar las páginas partiendo de una con número par
+pdfjs-spread-even-button-label = Vista de libro par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades del documento…
+pdfjs-document-properties-button-label = Propiedades del documento…
+pdfjs-document-properties-file-name = Nombre de archivo:
+pdfjs-document-properties-file-size = Tamaño de archivo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Asunto:
+pdfjs-document-properties-keywords = Palabras clave:
+pdfjs-document-properties-creation-date = Fecha de creación:
+pdfjs-document-properties-modification-date = Fecha de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creador:
+pdfjs-document-properties-producer = Productor PDF:
+pdfjs-document-properties-version = Versión PDF:
+pdfjs-document-properties-page-count = Número de páginas:
+pdfjs-document-properties-page-size = Tamaño de la página:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista rápida de la web:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Cerrar
+
+## Print
+
+pdfjs-print-progress-message = Preparando documento para impresión…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Advertencia: Imprimir no está totalmente soportado por este navegador.
+pdfjs-printing-not-ready = Advertencia: Este PDF no se ha cargado completamente para poder imprimirse.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Cambiar barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Alternar barra lateral (el documento contiene esquemas/adjuntos/capas)
+pdfjs-toggle-sidebar-button-label = Cambiar barra lateral
+pdfjs-document-outline-button =
+ .title = Mostrar resumen del documento (doble clic para expandir/contraer todos los elementos)
+pdfjs-document-outline-button-label = Resumen de documento
+pdfjs-attachments-button =
+ .title = Mostrar adjuntos
+pdfjs-attachments-button-label = Adjuntos
+pdfjs-layers-button =
+ .title = Mostrar capas (doble clic para restablecer todas las capas al estado predeterminado)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Encontrar elemento de esquema actual
+pdfjs-current-outline-item-button-label = Elemento de esquema actual
+pdfjs-findbar-button =
+ .title = Buscar en el documento
+pdfjs-findbar-button-label = Buscar
+pdfjs-additional-layers = Capas adicionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de la página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Buscar
+ .placeholder = Buscar en el documento…
+pdfjs-find-previous-button =
+ .title = Encontrar la anterior aparición de la frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Encontrar la siguiente aparición de esta frase
+pdfjs-find-next-button-label = Siguiente
+pdfjs-find-highlight-checkbox = Resaltar todos
+pdfjs-find-match-case-checkbox-label = Coincidencia de mayús./minús.
+pdfjs-find-match-diacritics-checkbox-label = Coincidir diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palabras completas
+pdfjs-find-reached-top = Se alcanzó el inicio del documento, se continúa desde el final
+pdfjs-find-reached-bottom = Se alcanzó el final del documento, se continúa desde el inicio
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } de { $total } coincidencia
+ *[other] { $current } de { $total } coincidencias
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Más de { $limit } coincidencia
+ *[other] Más de { $limit } coincidencias
+ }
+pdfjs-find-not-found = Frase no encontrada
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Anchura de la página
+pdfjs-page-scale-fit = Ajuste de la página
+pdfjs-page-scale-auto = Tamaño automático
+pdfjs-page-scale-actual = Tamaño real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ocurrió un error al cargar el PDF.
+pdfjs-invalid-file-error = Fichero PDF no válido o corrupto.
+pdfjs-missing-file-error = No hay fichero PDF.
+pdfjs-unexpected-response-error = Respuesta inesperada del servidor.
+pdfjs-rendering-error = Ocurrió un error al renderizar la página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotación { $type }]
+
+## Password
+
+pdfjs-password-label = Introduzca la contraseña para abrir este archivo PDF.
+pdfjs-password-invalid = Contraseña no válida. Vuelva a intentarlo.
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = Las tipografÃas web están desactivadas: es imposible usar las tipografÃas PDF embebidas.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Dibujar
+pdfjs-editor-ink-button-label = Dibujar
+pdfjs-editor-stamp-button =
+ .title = Añadir o editar imágenes
+pdfjs-editor-stamp-button-label = Añadir o editar imágenes
+pdfjs-editor-remove-button =
+ .title = Eliminar
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Eliminar dibujo
+pdfjs-editor-remove-freetext-button =
+ .title = Eliminar texto
+pdfjs-editor-remove-stamp-button =
+ .title = Eliminar imagen
+pdfjs-editor-remove-highlight-button =
+ .title = Quitar resaltado
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Tamaño
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Grosor
+pdfjs-editor-ink-opacity-input = Opacidad
+pdfjs-editor-stamp-add-image-button =
+ .title = Añadir imagen
+pdfjs-editor-stamp-add-image-button-label = Añadir imagen
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Empezar a escribir…
+pdfjs-ink =
+ .aria-label = Editor de dibujos
+pdfjs-ink-canvas =
+ .aria-label = Imagen creada por el usuario
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar el texto alternativo
+pdfjs-editor-alt-text-dialog-label = Eligir una opción
+pdfjs-editor-alt-text-dialog-description = El texto alternativo (texto alternativo) ayuda cuando las personas no pueden ver la imagen o cuando no se carga.
+pdfjs-editor-alt-text-add-description-label = Añadir una descripción
+pdfjs-editor-alt-text-add-description-description = Intente escribir 1 o 2 frases que describan el tema, el entorno o las acciones.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativa
+pdfjs-editor-alt-text-mark-decorative-description = Se utiliza para imágenes ornamentales, como bordes o marcas de agua.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Guardar
+pdfjs-editor-alt-text-decorative-tooltip = Marcada como decorativa
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por ejemplo: “Un joven se sienta a la mesa a comerâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Esquina superior izquierda — redimensionar
+pdfjs-editor-resizer-label-top-middle = Borde superior en el medio — redimensionar
+pdfjs-editor-resizer-label-top-right = Esquina superior derecha — redimensionar
+pdfjs-editor-resizer-label-middle-right = Borde derecho en el medio — redimensionar
+pdfjs-editor-resizer-label-bottom-right = Esquina inferior derecha — redimensionar
+pdfjs-editor-resizer-label-bottom-middle = Borde inferior en el medio — redimensionar
+pdfjs-editor-resizer-label-bottom-left = Esquina inferior izquierda — redimensionar
+pdfjs-editor-resizer-label-middle-left = Borde izquierdo en el medio — redimensionar
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Color de resaltado
+pdfjs-editor-colorpicker-button =
+ .title = Cambiar color
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Opciones de color
+pdfjs-editor-colorpicker-yellow =
+ .title = Amarillo
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Azul
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Rojo
diff --git a/www/lib/pdfjs/modern/web/locale/es-MX/viewer.ftl b/www/lib/pdfjs/modern/web/locale/es-MX/viewer.ftl
new file mode 100644
index 000000000..0069c6eb5
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/es-MX/viewer.ftl
@@ -0,0 +1,299 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Página siguiente
+pdfjs-next-button-label = Siguiente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Reducir
+pdfjs-zoom-out-button-label = Reducir
+pdfjs-zoom-in-button =
+ .title = Aumentar
+pdfjs-zoom-in-button-label = Aumentar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Cambiar al modo presentación
+pdfjs-presentation-mode-button-label = Modo presentación
+pdfjs-open-file-button =
+ .title = Abrir archivo
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Guardar
+pdfjs-save-button-label = Guardar
+pdfjs-bookmark-button =
+ .title = Página actual (Ver URL de la página actual)
+pdfjs-bookmark-button-label = Página actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir en la aplicación
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir en la aplicación
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Herramientas
+pdfjs-tools-button-label = Herramientas
+pdfjs-first-page-button =
+ .title = Ir a la primera página
+pdfjs-first-page-button-label = Ir a la primera página
+pdfjs-last-page-button =
+ .title = Ir a la última página
+pdfjs-last-page-button-label = Ir a la última página
+pdfjs-page-rotate-cw-button =
+ .title = Girar a la derecha
+pdfjs-page-rotate-cw-button-label = Girar a la derecha
+pdfjs-page-rotate-ccw-button =
+ .title = Girar a la izquierda
+pdfjs-page-rotate-ccw-button-label = Girar a la izquierda
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar la herramienta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Herramienta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar la herramienta de mano
+pdfjs-cursor-hand-tool-button-label = Herramienta de mano
+pdfjs-scroll-page-button =
+ .title = Usar desplazamiento de página
+pdfjs-scroll-page-button-label = Desplazamiento de página
+pdfjs-scroll-vertical-button =
+ .title = Usar desplazamiento vertical
+pdfjs-scroll-vertical-button-label = Desplazamiento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar desplazamiento horizontal
+pdfjs-scroll-horizontal-button-label = Desplazamiento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar desplazamiento encapsulado
+pdfjs-scroll-wrapped-button-label = Desplazamiento encapsulado
+pdfjs-spread-none-button =
+ .title = No unir páginas separadas
+pdfjs-spread-none-button-label = Vista de una página
+pdfjs-spread-odd-button =
+ .title = Unir las páginas partiendo con una de número impar
+pdfjs-spread-odd-button-label = Vista de libro impar
+pdfjs-spread-even-button =
+ .title = Juntar las páginas partiendo con una de número par
+pdfjs-spread-even-button-label = Vista de libro par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades del documento…
+pdfjs-document-properties-button-label = Propiedades del documento…
+pdfjs-document-properties-file-name = Nombre del archivo:
+pdfjs-document-properties-file-size = Tamaño del archivo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Asunto:
+pdfjs-document-properties-keywords = Palabras claves:
+pdfjs-document-properties-creation-date = Fecha de creación:
+pdfjs-document-properties-modification-date = Fecha de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creador:
+pdfjs-document-properties-producer = Productor PDF:
+pdfjs-document-properties-version = Versión PDF:
+pdfjs-document-properties-page-count = Número de páginas:
+pdfjs-document-properties-page-size = Tamaño de la página:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Oficio
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista rápida de la web:
+pdfjs-document-properties-linearized-yes = SÃ
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Cerrar
+
+## Print
+
+pdfjs-print-progress-message = Preparando documento para impresión…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Advertencia: La impresión no esta completamente soportada por este navegador.
+pdfjs-printing-not-ready = Advertencia: El PDF no cargo completamente para impresión.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Cambiar barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Alternar barra lateral (el documento contiene esquemas/adjuntos/capas)
+pdfjs-toggle-sidebar-button-label = Cambiar barra lateral
+pdfjs-document-outline-button =
+ .title = Mostrar esquema del documento (doble clic para expandir/contraer todos los elementos)
+pdfjs-document-outline-button-label = Esquema del documento
+pdfjs-attachments-button =
+ .title = Mostrar adjuntos
+pdfjs-attachments-button-label = Adjuntos
+pdfjs-layers-button =
+ .title = Mostrar capas (doble clic para restablecer todas las capas al estado predeterminado)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Buscar elemento de esquema actual
+pdfjs-current-outline-item-button-label = Elemento de esquema actual
+pdfjs-findbar-button =
+ .title = Buscar en el documento
+pdfjs-findbar-button-label = Buscar
+pdfjs-additional-layers = Capas adicionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de la página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Buscar
+ .placeholder = Buscar en el documento…
+pdfjs-find-previous-button =
+ .title = Ir a la anterior frase encontrada
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Ir a la siguiente frase encontrada
+pdfjs-find-next-button-label = Siguiente
+pdfjs-find-highlight-checkbox = Resaltar todo
+pdfjs-find-match-case-checkbox-label = Coincidir con mayúsculas y minúsculas
+pdfjs-find-match-diacritics-checkbox-label = Coincidir diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palabras completas
+pdfjs-find-reached-top = Se alcanzó el inicio del documento, se buscará al final
+pdfjs-find-reached-bottom = Se alcanzó el final del documento, se buscará al inicio
+pdfjs-find-not-found = No se encontró la frase
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ancho de página
+pdfjs-page-scale-fit = Ajustar página
+pdfjs-page-scale-auto = Zoom automático
+pdfjs-page-scale-actual = Tamaño real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Un error ocurrió al cargar el PDF.
+pdfjs-invalid-file-error = Archivo PDF invalido o dañado.
+pdfjs-missing-file-error = Archivo PDF no encontrado.
+pdfjs-unexpected-response-error = Respuesta inesperada del servidor.
+pdfjs-rendering-error = Un error ocurrió al renderizar la página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } anotación]
+
+## Password
+
+pdfjs-password-label = Ingresa la contraseña para abrir este archivo PDF.
+pdfjs-password-invalid = Contraseña inválida. Por favor intenta de nuevo.
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = Las fuentes web están desactivadas: es imposible usar las fuentes PDF embebidas.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Dibujar
+pdfjs-editor-ink-button-label = Dibujar
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Tamaño
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Grossor
+pdfjs-editor-ink-opacity-input = Opacidad
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Empieza a escribir…
+pdfjs-ink =
+ .aria-label = Editor de dibujo
+pdfjs-ink-canvas =
+ .aria-label = Imagen creada por el usuario
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/et/viewer.ftl b/www/lib/pdfjs/modern/web/locale/et/viewer.ftl
new file mode 100644
index 000000000..b28c6d504
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/et/viewer.ftl
@@ -0,0 +1,268 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Eelmine lehekülg
+pdfjs-previous-button-label = Eelmine
+pdfjs-next-button =
+ .title = Järgmine lehekülg
+pdfjs-next-button-label = Järgmine
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Leht
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber }/{ $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Vähenda
+pdfjs-zoom-out-button-label = Vähenda
+pdfjs-zoom-in-button =
+ .title = Suurenda
+pdfjs-zoom-in-button-label = Suurenda
+pdfjs-zoom-select =
+ .title = Suurendamine
+pdfjs-presentation-mode-button =
+ .title = Lülitu esitlusrežiimi
+pdfjs-presentation-mode-button-label = Esitlusrežiim
+pdfjs-open-file-button =
+ .title = Ava fail
+pdfjs-open-file-button-label = Ava
+pdfjs-print-button =
+ .title = Prindi
+pdfjs-print-button-label = Prindi
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tööriistad
+pdfjs-tools-button-label = Tööriistad
+pdfjs-first-page-button =
+ .title = Mine esimesele leheküljele
+pdfjs-first-page-button-label = Mine esimesele leheküljele
+pdfjs-last-page-button =
+ .title = Mine viimasele leheküljele
+pdfjs-last-page-button-label = Mine viimasele leheküljele
+pdfjs-page-rotate-cw-button =
+ .title = Pööra päripäeva
+pdfjs-page-rotate-cw-button-label = Pööra päripäeva
+pdfjs-page-rotate-ccw-button =
+ .title = Pööra vastupäeva
+pdfjs-page-rotate-ccw-button-label = Pööra vastupäeva
+pdfjs-cursor-text-select-tool-button =
+ .title = Luba teksti valimise tööriist
+pdfjs-cursor-text-select-tool-button-label = Teksti valimise tööriist
+pdfjs-cursor-hand-tool-button =
+ .title = Luba sirvimistööriist
+pdfjs-cursor-hand-tool-button-label = Sirvimistööriist
+pdfjs-scroll-page-button =
+ .title = Kasutatakse lehe kaupa kerimist
+pdfjs-scroll-page-button-label = Lehe kaupa kerimine
+pdfjs-scroll-vertical-button =
+ .title = Kasuta vertikaalset kerimist
+pdfjs-scroll-vertical-button-label = Vertikaalne kerimine
+pdfjs-scroll-horizontal-button =
+ .title = Kasuta horisontaalset kerimist
+pdfjs-scroll-horizontal-button-label = Horisontaalne kerimine
+pdfjs-scroll-wrapped-button =
+ .title = Kasuta rohkem mahutavat kerimist
+pdfjs-scroll-wrapped-button-label = Rohkem mahutav kerimine
+pdfjs-spread-none-button =
+ .title = Ära kõrvuta lehekülgi
+pdfjs-spread-none-button-label = Lehtede kõrvutamine puudub
+pdfjs-spread-odd-button =
+ .title = Kõrvuta leheküljed, alustades paaritute numbritega lehekülgedega
+pdfjs-spread-odd-button-label = Kõrvutamine paaritute numbritega alustades
+pdfjs-spread-even-button =
+ .title = Kõrvuta leheküljed, alustades paarisnumbritega lehekülgedega
+pdfjs-spread-even-button-label = Kõrvutamine paarisnumbritega alustades
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumendi omadused…
+pdfjs-document-properties-button-label = Dokumendi omadused…
+pdfjs-document-properties-file-name = Faili nimi:
+pdfjs-document-properties-file-size = Faili suurus:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KiB ({ $size_b } baiti)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MiB ({ $size_b } baiti)
+pdfjs-document-properties-title = Pealkiri:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Teema:
+pdfjs-document-properties-keywords = Märksõnad:
+pdfjs-document-properties-creation-date = Loodud:
+pdfjs-document-properties-modification-date = Muudetud:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } { $time }
+pdfjs-document-properties-creator = Looja:
+pdfjs-document-properties-producer = Generaator:
+pdfjs-document-properties-version = Generaatori versioon:
+pdfjs-document-properties-page-count = Lehekülgi:
+pdfjs-document-properties-page-size = Lehe suurus:
+pdfjs-document-properties-page-size-unit-inches = tolli
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertikaalpaigutus
+pdfjs-document-properties-page-size-orientation-landscape = rõhtpaigutus
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = "Fast Web View" tugi:
+pdfjs-document-properties-linearized-yes = Jah
+pdfjs-document-properties-linearized-no = Ei
+pdfjs-document-properties-close-button = Sulge
+
+## Print
+
+pdfjs-print-progress-message = Dokumendi ettevalmistamine printimiseks…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Loobu
+pdfjs-printing-not-supported = Hoiatus: printimine pole selle brauseri poolt täielikult toetatud.
+pdfjs-printing-not-ready = Hoiatus: PDF pole printimiseks täielikult laaditud.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Näita külgriba
+pdfjs-toggle-sidebar-notification-button =
+ .title = Näita külgriba (dokument sisaldab sisukorda/manuseid/kihte)
+pdfjs-toggle-sidebar-button-label = Näita külgriba
+pdfjs-document-outline-button =
+ .title = Näita sisukorda (kõigi punktide laiendamiseks/ahendamiseks topeltklõpsa)
+pdfjs-document-outline-button-label = Näita sisukorda
+pdfjs-attachments-button =
+ .title = Näita manuseid
+pdfjs-attachments-button-label = Manused
+pdfjs-layers-button =
+ .title = Näita kihte (kõikide kihtide vaikeolekusse lähtestamiseks topeltklõpsa)
+pdfjs-layers-button-label = Kihid
+pdfjs-thumbs-button =
+ .title = Näita pisipilte
+pdfjs-thumbs-button-label = Pisipildid
+pdfjs-current-outline-item-button =
+ .title = Otsi üles praegune kontuuriüksus
+pdfjs-current-outline-item-button-label = Praegune kontuuriüksus
+pdfjs-findbar-button =
+ .title = Otsi dokumendist
+pdfjs-findbar-button-label = Otsi
+pdfjs-additional-layers = Täiendavad kihid
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page }. lehekülg
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page }. lehekülje pisipilt
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Otsi
+ .placeholder = Otsi dokumendist…
+pdfjs-find-previous-button =
+ .title = Otsi fraasi eelmine esinemiskoht
+pdfjs-find-previous-button-label = Eelmine
+pdfjs-find-next-button =
+ .title = Otsi fraasi järgmine esinemiskoht
+pdfjs-find-next-button-label = Järgmine
+pdfjs-find-highlight-checkbox = Too kõik esile
+pdfjs-find-match-case-checkbox-label = Tõstutundlik
+pdfjs-find-match-diacritics-checkbox-label = Otsitakse diakriitiliselt
+pdfjs-find-entire-word-checkbox-label = Täissõnad
+pdfjs-find-reached-top = Jõuti dokumendi algusesse, jätkati lõpust
+pdfjs-find-reached-bottom = Jõuti dokumendi lõppu, jätkati algusest
+pdfjs-find-not-found = Fraasi ei leitud
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Mahuta laiusele
+pdfjs-page-scale-fit = Mahuta leheküljele
+pdfjs-page-scale-auto = Automaatne suurendamine
+pdfjs-page-scale-actual = Tegelik suurus
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Lehekülg { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDFi laadimisel esines viga.
+pdfjs-invalid-file-error = Vigane või rikutud PDF-fail.
+pdfjs-missing-file-error = PDF-fail puudub.
+pdfjs-unexpected-response-error = Ootamatu vastus serverilt.
+pdfjs-rendering-error = Lehe renderdamisel esines viga.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = PDF-faili avamiseks sisesta parool.
+pdfjs-password-invalid = Vigane parool. Palun proovi uuesti.
+pdfjs-password-ok-button = Sobib
+pdfjs-password-cancel-button = Loobu
+pdfjs-web-fonts-disabled = Veebifondid on keelatud: PDFiga kaasatud fonte pole võimalik kasutada.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/eu/viewer.ftl b/www/lib/pdfjs/modern/web/locale/eu/viewer.ftl
new file mode 100644
index 000000000..559863a64
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/eu/viewer.ftl
@@ -0,0 +1,349 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Aurreko orria
+pdfjs-previous-button-label = Aurrekoa
+pdfjs-next-button =
+ .title = Hurrengo orria
+pdfjs-next-button-label = Hurrengoa
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Orria
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = { $pagesCount }/{ $pageNumber }
+pdfjs-zoom-out-button =
+ .title = Urrundu zooma
+pdfjs-zoom-out-button-label = Urrundu zooma
+pdfjs-zoom-in-button =
+ .title = Gerturatu zooma
+pdfjs-zoom-in-button-label = Gerturatu zooma
+pdfjs-zoom-select =
+ .title = Zooma
+pdfjs-presentation-mode-button =
+ .title = Aldatu aurkezpen modura
+pdfjs-presentation-mode-button-label = Arkezpen modua
+pdfjs-open-file-button =
+ .title = Ireki fitxategia
+pdfjs-open-file-button-label = Ireki
+pdfjs-print-button =
+ .title = Inprimatu
+pdfjs-print-button-label = Inprimatu
+pdfjs-save-button =
+ .title = Gorde
+pdfjs-save-button-label = Gorde
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Deskargatu
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Deskargatu
+pdfjs-bookmark-button =
+ .title = Uneko orria (ikusi uneko orriaren URLa)
+pdfjs-bookmark-button-label = Uneko orria
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ireki aplikazioan
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ireki aplikazioan
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tresnak
+pdfjs-tools-button-label = Tresnak
+pdfjs-first-page-button =
+ .title = Joan lehen orrira
+pdfjs-first-page-button-label = Joan lehen orrira
+pdfjs-last-page-button =
+ .title = Joan azken orrira
+pdfjs-last-page-button-label = Joan azken orrira
+pdfjs-page-rotate-cw-button =
+ .title = Biratu erlojuaren norantzan
+pdfjs-page-rotate-cw-button-label = Biratu erlojuaren norantzan
+pdfjs-page-rotate-ccw-button =
+ .title = Biratu erlojuaren aurkako norantzan
+pdfjs-page-rotate-ccw-button-label = Biratu erlojuaren aurkako norantzan
+pdfjs-cursor-text-select-tool-button =
+ .title = Gaitu testuaren hautapen tresna
+pdfjs-cursor-text-select-tool-button-label = Testuaren hautapen tresna
+pdfjs-cursor-hand-tool-button =
+ .title = Gaitu eskuaren tresna
+pdfjs-cursor-hand-tool-button-label = Eskuaren tresna
+pdfjs-scroll-page-button =
+ .title = Erabili orriaren korritzea
+pdfjs-scroll-page-button-label = Orriaren korritzea
+pdfjs-scroll-vertical-button =
+ .title = Erabili korritze bertikala
+pdfjs-scroll-vertical-button-label = Korritze bertikala
+pdfjs-scroll-horizontal-button =
+ .title = Erabili korritze horizontala
+pdfjs-scroll-horizontal-button-label = Korritze horizontala
+pdfjs-scroll-wrapped-button =
+ .title = Erabili korritze egokitua
+pdfjs-scroll-wrapped-button-label = Korritze egokitua
+pdfjs-spread-none-button =
+ .title = Ez elkartu barreiatutako orriak
+pdfjs-spread-none-button-label = Barreiatzerik ez
+pdfjs-spread-odd-button =
+ .title = Elkartu barreiatutako orriak bakoiti zenbakidunekin hasita
+pdfjs-spread-odd-button-label = Barreiatze bakoitia
+pdfjs-spread-even-button =
+ .title = Elkartu barreiatutako orriak bikoiti zenbakidunekin hasita
+pdfjs-spread-even-button-label = Barreiatze bikoitia
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentuaren propietateak…
+pdfjs-document-properties-button-label = Dokumentuaren propietateak…
+pdfjs-document-properties-file-name = Fitxategi-izena:
+pdfjs-document-properties-file-size = Fitxategiaren tamaina:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Izenburua:
+pdfjs-document-properties-author = Egilea:
+pdfjs-document-properties-subject = Gaia:
+pdfjs-document-properties-keywords = Gako-hitzak:
+pdfjs-document-properties-creation-date = Sortze-data:
+pdfjs-document-properties-modification-date = Aldatze-data:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Sortzailea:
+pdfjs-document-properties-producer = PDFaren ekoizlea:
+pdfjs-document-properties-version = PDF bertsioa:
+pdfjs-document-properties-page-count = Orrialde kopurua:
+pdfjs-document-properties-page-size = Orriaren tamaina:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = bertikala
+pdfjs-document-properties-page-size-orientation-landscape = horizontala
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Gutuna
+pdfjs-document-properties-page-size-name-legal = Legala
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Webeko ikuspegi bizkorra:
+pdfjs-document-properties-linearized-yes = Bai
+pdfjs-document-properties-linearized-no = Ez
+pdfjs-document-properties-close-button = Itxi
+
+## Print
+
+pdfjs-print-progress-message = Dokumentua inprimatzeko prestatzen…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = %{ $progress }
+pdfjs-print-progress-close-button = Utzi
+pdfjs-printing-not-supported = Abisua: inprimatzeko euskarria ez da erabatekoa nabigatzaile honetan.
+pdfjs-printing-not-ready = Abisua: PDFa ez dago erabat kargatuta inprimatzeko.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Txandakatu alboko barra
+pdfjs-toggle-sidebar-notification-button =
+ .title = Txandakatu alboko barra (dokumentuak eskema/eranskinak/geruzak ditu)
+pdfjs-toggle-sidebar-button-label = Txandakatu alboko barra
+pdfjs-document-outline-button =
+ .title = Erakutsi dokumentuaren eskema (klik bikoitza elementu guztiak zabaltzeko/tolesteko)
+pdfjs-document-outline-button-label = Dokumentuaren eskema
+pdfjs-attachments-button =
+ .title = Erakutsi eranskinak
+pdfjs-attachments-button-label = Eranskinak
+pdfjs-layers-button =
+ .title = Erakutsi geruzak (klik bikoitza geruza guztiak egoera lehenetsira berrezartzeko)
+pdfjs-layers-button-label = Geruzak
+pdfjs-thumbs-button =
+ .title = Erakutsi koadro txikiak
+pdfjs-thumbs-button-label = Koadro txikiak
+pdfjs-current-outline-item-button =
+ .title = Bilatu uneko eskemaren elementua
+pdfjs-current-outline-item-button-label = Uneko eskemaren elementua
+pdfjs-findbar-button =
+ .title = Bilatu dokumentuan
+pdfjs-findbar-button-label = Bilatu
+pdfjs-additional-layers = Geruza gehigarriak
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page }. orria
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page }. orriaren koadro txikia
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Bilatu
+ .placeholder = Bilatu dokumentuan…
+pdfjs-find-previous-button =
+ .title = Bilatu esaldiaren aurreko parekatzea
+pdfjs-find-previous-button-label = Aurrekoa
+pdfjs-find-next-button =
+ .title = Bilatu esaldiaren hurrengo parekatzea
+pdfjs-find-next-button-label = Hurrengoa
+pdfjs-find-highlight-checkbox = Nabarmendu guztia
+pdfjs-find-match-case-checkbox-label = Bat etorri maiuskulekin/minuskulekin
+pdfjs-find-match-diacritics-checkbox-label = Bereizi diakritikoak
+pdfjs-find-entire-word-checkbox-label = Hitz osoak
+pdfjs-find-reached-top = Dokumentuaren hasierara heldu da, bukaeratik jarraitzen
+pdfjs-find-reached-bottom = Dokumentuaren bukaerara heldu da, hasieratik jarraitzen
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $total }/{ $current }. bat-etortzea
+ *[other] { $total }/{ $current }. bat-etortzea
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Bat datorren { $limit } baino gehiago
+ *[other] Bat datozen { $limit } baino gehiago
+ }
+pdfjs-find-not-found = Esaldia ez da aurkitu
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Orriaren zabalera
+pdfjs-page-scale-fit = Doitu orrira
+pdfjs-page-scale-auto = Zoom automatikoa
+pdfjs-page-scale-actual = Benetako tamaina
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = %{ $scale }
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page }. orria
+
+## Loading indicator messages
+
+pdfjs-loading-error = Errorea gertatu da PDFa kargatzean.
+pdfjs-invalid-file-error = PDF fitxategi baliogabe edo hondatua.
+pdfjs-missing-file-error = PDF fitxategia falta da.
+pdfjs-unexpected-response-error = Espero gabeko zerbitzariaren erantzuna.
+pdfjs-rendering-error = Errorea gertatu da orria errendatzean.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ohartarazpena]
+
+## Password
+
+pdfjs-password-label = Idatzi PDF fitxategi hau irekitzeko pasahitza.
+pdfjs-password-invalid = Pasahitz baliogabea. Saiatu berriro mesedez.
+pdfjs-password-ok-button = Ados
+pdfjs-password-cancel-button = Utzi
+pdfjs-web-fonts-disabled = Webeko letra-tipoak desgaituta daude: ezin dira kapsulatutako PDF letra-tipoak erabili.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Testua
+pdfjs-editor-free-text-button-label = Testua
+pdfjs-editor-ink-button =
+ .title = Marrazkia
+pdfjs-editor-ink-button-label = Marrazkia
+pdfjs-editor-stamp-button =
+ .title = Gehitu edo editatu irudiak
+pdfjs-editor-stamp-button-label = Gehitu edo editatu irudiak
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Kolorea
+pdfjs-editor-free-text-size-input = Tamaina
+pdfjs-editor-ink-color-input = Kolorea
+pdfjs-editor-ink-thickness-input = Loditasuna
+pdfjs-editor-ink-opacity-input = Opakutasuna
+pdfjs-editor-stamp-add-image-button =
+ .title = Gehitu irudia
+pdfjs-editor-stamp-add-image-button-label = Gehitu irudia
+pdfjs-free-text =
+ .aria-label = Testu-editorea
+pdfjs-free-text-default-content = Hasi idazten…
+pdfjs-ink =
+ .aria-label = Marrazki-editorea
+pdfjs-ink-canvas =
+ .aria-label = Erabiltzaileak sortutako irudia
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Testu alternatiboa
+pdfjs-editor-alt-text-edit-button-label = Editatu testu alternatiboa
+pdfjs-editor-alt-text-dialog-label = Aukeratu aukera
+pdfjs-editor-alt-text-dialog-description = Testu alternatiboak laguntzen du jendeak ezin duenean irudia ikusi edo ez denean kargatzen.
+pdfjs-editor-alt-text-add-description-label = Gehitu azalpena
+pdfjs-editor-alt-text-add-description-description = Saiatu idazten gaia, ezarpena edo ekintzak deskribatzen dituen esaldi 1 edo 2.
+pdfjs-editor-alt-text-mark-decorative-label = Markatu apaingarri gisa
+pdfjs-editor-alt-text-mark-decorative-description = Irudiak apaingarrientzat erabiltzen da, adibidez ertz edo ur-marketarako.
+pdfjs-editor-alt-text-cancel-button = Utzi
+pdfjs-editor-alt-text-save-button = Gorde
+pdfjs-editor-alt-text-decorative-tooltip = Apaingarri gisa markatuta
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Adibidez, "gizon gaztea mahaian eserita dago bazkaltzeko"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Goiko ezkerreko izkina — aldatu tamaina
+pdfjs-editor-resizer-label-top-middle = Goian erdian — aldatu tamaina
+pdfjs-editor-resizer-label-top-right = Goiko eskuineko izkina — aldatu tamaina
+pdfjs-editor-resizer-label-middle-right = Erdian eskuinean — aldatu tamaina
+pdfjs-editor-resizer-label-bottom-right = Beheko eskuineko izkina — aldatu tamaina
+pdfjs-editor-resizer-label-bottom-middle = Behean erdian — aldatu tamaina
+pdfjs-editor-resizer-label-bottom-left = Beheko ezkerreko izkina — aldatu tamaina
+pdfjs-editor-resizer-label-middle-left = Erdian ezkerrean — aldatu tamaina
diff --git a/www/lib/pdfjs/modern/web/locale/fa/viewer.ftl b/www/lib/pdfjs/modern/web/locale/fa/viewer.ftl
new file mode 100644
index 000000000..f367e3c64
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/fa/viewer.ftl
@@ -0,0 +1,246 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = صÙØÙ‡Ù” قبلی
+pdfjs-previous-button-label = قبلی
+pdfjs-next-button =
+ .title = صÙØÙ‡Ù” بعدی
+pdfjs-next-button-label = بعدی
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = صÙØÙ‡
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = از { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber }از { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = کوچک‌نمایی
+pdfjs-zoom-out-button-label = کوچک‌نمایی
+pdfjs-zoom-in-button =
+ .title = بزرگ‌نمایی
+pdfjs-zoom-in-button-label = بزرگ‌نمایی
+pdfjs-zoom-select =
+ .title = زوم
+pdfjs-presentation-mode-button =
+ .title = تغییر به Øالت ارائه
+pdfjs-presentation-mode-button-label = Øالت ارائه
+pdfjs-open-file-button =
+ .title = باز کردن پرونده
+pdfjs-open-file-button-label = باز کردن
+pdfjs-print-button =
+ .title = چاپ
+pdfjs-print-button-label = چاپ
+pdfjs-save-button-label = ذخیره
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ابزارها
+pdfjs-tools-button-label = ابزارها
+pdfjs-first-page-button =
+ .title = برو به اولین صÙØÙ‡
+pdfjs-first-page-button-label = برو به اولین صÙØÙ‡
+pdfjs-last-page-button =
+ .title = برو به آخرین صÙØÙ‡
+pdfjs-last-page-button-label = برو به آخرین صÙØÙ‡
+pdfjs-page-rotate-cw-button =
+ .title = چرخش ساعتگرد
+pdfjs-page-rotate-cw-button-label = چرخش ساعتگرد
+pdfjs-page-rotate-ccw-button =
+ .title = چرخش پاد ساعتگرد
+pdfjs-page-rotate-ccw-button-label = چرخش پاد ساعتگرد
+pdfjs-cursor-text-select-tool-button =
+ .title = Ùعال کردن ابزار٠انتخاب٠متن
+pdfjs-cursor-text-select-tool-button-label = ابزار٠انتخاب٠متن
+pdfjs-cursor-hand-tool-button =
+ .title = Ùعال کردن ابزار٠دست
+pdfjs-cursor-hand-tool-button-label = ابزار دست
+pdfjs-scroll-vertical-button =
+ .title = استÙاده از پیمایش عمودی
+pdfjs-scroll-vertical-button-label = پیمایش عمودی
+pdfjs-scroll-horizontal-button =
+ .title = استÙاده از پیمایش اÙÙ‚ÛŒ
+pdfjs-scroll-horizontal-button-label = پیمایش اÙÙ‚ÛŒ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = خصوصیات سند...
+pdfjs-document-properties-button-label = خصوصیات سند...
+pdfjs-document-properties-file-name = نام Ùایل:
+pdfjs-document-properties-file-size = Øجم پرونده:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } کیلوبایت ({ $size_b } بایت)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } مگابایت ({ $size_b } بایت)
+pdfjs-document-properties-title = عنوان:
+pdfjs-document-properties-author = نویسنده:
+pdfjs-document-properties-subject = موضوع:
+pdfjs-document-properties-keywords = کلیدواژه‌ها:
+pdfjs-document-properties-creation-date = تاریخ ایجاد:
+pdfjs-document-properties-modification-date = تاریخ ویرایش:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }، { $time }
+pdfjs-document-properties-creator = ایجاد کننده:
+pdfjs-document-properties-producer = ایجاد کننده PDF:
+pdfjs-document-properties-version = نسخه PDF:
+pdfjs-document-properties-page-count = تعداد صÙØات:
+pdfjs-document-properties-page-size = اندازه صÙØÙ‡:
+pdfjs-document-properties-page-size-unit-inches = اینچ
+pdfjs-document-properties-page-size-unit-millimeters = میلی‌متر
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = نامه
+pdfjs-document-properties-page-size-name-legal = Øقوقی
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = بله
+pdfjs-document-properties-linearized-no = خیر
+pdfjs-document-properties-close-button = بستن
+
+## Print
+
+pdfjs-print-progress-message = آماده سازی مدارک برای چاپ کردن…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = لغو
+pdfjs-printing-not-supported = هشدار: قابلیت چاپ به‌طور کامل در این مرورگر پشتیبانی نمی‌شود.
+pdfjs-printing-not-ready = اخطار: پرونده PDF بطور کامل بارگیری نشده و امکان چاپ وجود ندارد.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = باز و بسته کردن نوار کناری
+pdfjs-toggle-sidebar-button-label = تغییرØالت نوارکناری
+pdfjs-document-outline-button =
+ .title = نمایش رئوس مطالب مدارک(برای بازشدن/جمع شدن همه موارد دوبار کلیک کنید)
+pdfjs-document-outline-button-label = Ø·Ø±Ø Ù†ÙˆØ´ØªØ§Ø±
+pdfjs-attachments-button =
+ .title = نمایش پیوست‌ها
+pdfjs-attachments-button-label = پیوست‌ها
+pdfjs-layers-button-label = لایه‌ها
+pdfjs-thumbs-button =
+ .title = نمایش تصاویر بندانگشتی
+pdfjs-thumbs-button-label = تصاویر بندانگشتی
+pdfjs-findbar-button =
+ .title = جستجو در سند
+pdfjs-findbar-button-label = پیدا کردن
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = صÙØÙ‡ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = تصویر بند‌ انگشتی صÙØÙ‡ { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = پیدا کردن
+ .placeholder = پیدا کردن در سند…
+pdfjs-find-previous-button =
+ .title = پیدا کردن رخداد قبلی عبارت
+pdfjs-find-previous-button-label = قبلی
+pdfjs-find-next-button =
+ .title = پیدا کردن رخداد بعدی عبارت
+pdfjs-find-next-button-label = بعدی
+pdfjs-find-highlight-checkbox = برجسته و هایلایت کردن همه موارد
+pdfjs-find-match-case-checkbox-label = تطبیق Ú©ÙˆÚ†Ú©ÛŒ Ùˆ بزرگی ØروÙ
+pdfjs-find-entire-word-checkbox-label = تمام کلمه‌ها
+pdfjs-find-reached-top = به بالای صÙØÙ‡ رسیدیم، از پایین ادامه می‌دهیم
+pdfjs-find-reached-bottom = به آخر صÙØÙ‡ رسیدیم، از بالا ادامه می‌دهیم
+pdfjs-find-not-found = عبارت پیدا نشد
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = عرض صÙØÙ‡
+pdfjs-page-scale-fit = اندازه کردن صÙØÙ‡
+pdfjs-page-scale-auto = بزرگنمایی خودکار
+pdfjs-page-scale-actual = اندازه واقعی‌
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = صÙØÙ‡Ù” { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = هنگام بارگیری پرونده PDF خطایی رخ داد.
+pdfjs-invalid-file-error = پرونده PDF نامعتبر یامعیوب می‌باشد.
+pdfjs-missing-file-error = پرونده PDF یاÙت نشد.
+pdfjs-unexpected-response-error = پاسخ پیش بینی نشده سرور
+pdfjs-rendering-error = هنگام بارگیری صÙØÙ‡ خطایی رخ داد.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = جهت باز کردن پرونده PDF گذرواژه را وارد نمائید.
+pdfjs-password-invalid = گذرواژه نامعتبر. لطÙا مجددا تلاش کنید.
+pdfjs-password-ok-button = تأیید
+pdfjs-password-cancel-button = لغو
+pdfjs-web-fonts-disabled = Ùونت های تØت وب غیر Ùعال شده اند: امکان استÙاده از نمایش دهنده داخلی PDF وجود ندارد.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = متن
+pdfjs-editor-free-text-button-label = متن
+pdfjs-editor-ink-button =
+ .title = کشیدن
+pdfjs-editor-ink-button-label = کشیدن
+# Editor Parameters
+pdfjs-editor-free-text-color-input = رنگ
+pdfjs-editor-free-text-size-input = اندازه
+pdfjs-editor-ink-color-input = رنگ
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ff/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ff/viewer.ftl
new file mode 100644
index 000000000..d1419f543
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ff/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Hello Æennungo
+pdfjs-previous-button-label = ÆennuÉ—o
+pdfjs-next-button =
+ .title = Hello faango
+pdfjs-next-button-label = Yeeso
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Hello
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = e nder { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Lonngo WoÉ—É—a
+pdfjs-zoom-out-button-label = Lonngo WoÉ—É—a
+pdfjs-zoom-in-button =
+ .title = Lonngo Ara
+pdfjs-zoom-in-button-label = Lonngo Ara
+pdfjs-zoom-select =
+ .title = Lonngo
+pdfjs-presentation-mode-button =
+ .title = Faytu to Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Uddit Fiilde
+pdfjs-open-file-button-label = Uddit
+pdfjs-print-button =
+ .title = Winndito
+pdfjs-print-button-label = Winndito
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = KuutorÉ—e
+pdfjs-tools-button-label = KuutorÉ—e
+pdfjs-first-page-button =
+ .title = Yah to hello adanngo
+pdfjs-first-page-button-label = Yah to hello adanngo
+pdfjs-last-page-button =
+ .title = Yah to hello wattindiingo
+pdfjs-last-page-button-label = Yah to hello wattindiingo
+pdfjs-page-rotate-cw-button =
+ .title = Yiiltu Faya Ñaamo
+pdfjs-page-rotate-cw-button-label = Yiiltu Faya Ñaamo
+pdfjs-page-rotate-ccw-button =
+ .title = Yiiltu Faya Nano
+pdfjs-page-rotate-ccw-button-label = Yiiltu Faya Nano
+pdfjs-cursor-text-select-tool-button =
+ .title = Gollin kaɓirgel cuɓirgel binndi
+pdfjs-cursor-text-select-tool-button-label = Kaɓirgel cuɓirgel binndi
+pdfjs-cursor-hand-tool-button =
+ .title = Hurmin kuutorgal junngo
+pdfjs-cursor-hand-tool-button-label = Kaɓirgel junngo
+pdfjs-scroll-vertical-button =
+ .title = Huutoro gorwitol daringol
+pdfjs-scroll-vertical-button-label = Gorwitol daringol
+pdfjs-scroll-horizontal-button =
+ .title = Huutoro gorwitol lelingol
+pdfjs-scroll-horizontal-button-label = Gorwitol daringol
+pdfjs-scroll-wrapped-button =
+ .title = Huutoro gorwitol coomingol
+pdfjs-scroll-wrapped-button-label = Gorwitol coomingol
+pdfjs-spread-none-button =
+ .title = Hoto tawtu kelle kelle
+pdfjs-spread-none-button-label = Alaa Spreads
+pdfjs-spread-odd-button =
+ .title = Tawtu kelle puÉ—É—ortooÉ—e kelle teelÉ—e
+pdfjs-spread-odd-button-label = Kelle teelÉ—e
+pdfjs-spread-even-button =
+ .title = Tawtu É—ereeji kelle puÉ—É—oriiÉ—i kelle teeltuÉ—e
+pdfjs-spread-even-button-label = Kelle teeltuÉ—e
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Keeroraaɗi Winndannde…
+pdfjs-document-properties-button-label = Keeroraaɗi Winndannde…
+pdfjs-document-properties-file-name = Innde fiilde:
+pdfjs-document-properties-file-size = Æetol fiilde:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bite)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bite)
+pdfjs-document-properties-title = Tiitoonde:
+pdfjs-document-properties-author = BinnduÉ—o:
+pdfjs-document-properties-subject = Toɓɓere:
+pdfjs-document-properties-keywords = Kelmekele jiytirÉ—e:
+pdfjs-document-properties-creation-date = Ñalnde Sosaa:
+pdfjs-document-properties-modification-date = Ñalnde Waylaa:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = CosÉ—o:
+pdfjs-document-properties-producer = PaggiiÉ—o PDF:
+pdfjs-document-properties-version = Yamre PDF:
+pdfjs-document-properties-page-count = Limoore Kelle:
+pdfjs-document-properties-page-size = Æeto Hello:
+pdfjs-document-properties-page-size-unit-inches = nder
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = dariingo
+pdfjs-document-properties-page-size-orientation-landscape = wertiingo
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Æataake
+pdfjs-document-properties-page-size-name-legal = Laawol
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ÆŠisngo geese yaawngo:
+pdfjs-document-properties-linearized-yes = Eey
+pdfjs-document-properties-linearized-no = Alaa
+pdfjs-document-properties-close-button = Uddu
+
+## Print
+
+pdfjs-print-progress-message = Nana heboo winnditaade fiilannde…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Haaytu
+pdfjs-printing-not-supported = Reentino: Winnditagol tammbitaaka no feewi e ndee wanngorde.
+pdfjs-printing-not-ready = Reentino: PDF oo loowaaki haa timmi ngam winnditagol.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggilo Palal Sawndo
+pdfjs-toggle-sidebar-button-label = Toggilo Palal Sawndo
+pdfjs-document-outline-button =
+ .title = Hollu Ƴiyal Fiilannde (dobdobo ngam wertude/taggude teme fof)
+pdfjs-document-outline-button-label = Toɓɓe Fiilannde
+pdfjs-attachments-button =
+ .title = Hollu ÆŠisanÉ—e
+pdfjs-attachments-button-label = ÆŠisanÉ—e
+pdfjs-thumbs-button =
+ .title = Hollu Dooɓe
+pdfjs-thumbs-button-label = Dooɓe
+pdfjs-findbar-button =
+ .title = Yiylo e fiilannde
+pdfjs-findbar-button-label = Yiytu
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Hello { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Dooɓre Hello { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Yiytu
+ .placeholder = Yiylo nder dokimaa
+pdfjs-find-previous-button =
+ .title = Yiylo cilol É“ennugol konngol ngol
+pdfjs-find-previous-button-label = ÆennuÉ—o
+pdfjs-find-next-button =
+ .title = Yiylo cilol garowol konngol ngol
+pdfjs-find-next-button-label = Yeeso
+pdfjs-find-highlight-checkbox = Jalbin fof
+pdfjs-find-match-case-checkbox-label = Jaaɓnu darnde
+pdfjs-find-entire-word-checkbox-label = Kelme timmuÉ—e tan
+pdfjs-find-reached-top = Heɓii fuɗɗorde fiilannde, jokku faya les
+pdfjs-find-reached-bottom = Heɓii hoore fiilannde, jokku faya les
+pdfjs-find-not-found = Konngi njiyataa
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Njaajeendi Hello
+pdfjs-page-scale-fit = KeÆ´eendi Hello
+pdfjs-page-scale-auto = Loongorde Jaajol
+pdfjs-page-scale-actual = Æetol Jaati
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Juumre waÉ—ii tuma nde loowata PDF oo.
+pdfjs-invalid-file-error = Fiilde PDF moÆ´Æ´aani walla jiibii.
+pdfjs-missing-file-error = Fiilde PDF ena Å‹akki.
+pdfjs-unexpected-response-error = Jaabtol sarworde tijjinooka.
+pdfjs-rendering-error = Juumre waɗii tuma nde yoŋkittoo hello.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Siiftannde]
+
+## Password
+
+pdfjs-password-label = Naatu finnde ngam uddite ndee fiilde PDF.
+pdfjs-password-invalid = Finnde moÆ´Æ´aani. TiiÉ—no eto kadi.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Haaytu
+pdfjs-web-fonts-disabled = Ponte geese ko daaÆ´aaÉ—e: horiima huutoraade ponte PDF coomtoraaÉ—e.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/fi/viewer.ftl b/www/lib/pdfjs/modern/web/locale/fi/viewer.ftl
new file mode 100644
index 000000000..db465a7c3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/fi/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Edellinen sivu
+pdfjs-previous-button-label = Edellinen
+pdfjs-next-button =
+ .title = Seuraava sivu
+pdfjs-next-button-label = Seuraava
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Sivu
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Loitonna
+pdfjs-zoom-out-button-label = Loitonna
+pdfjs-zoom-in-button =
+ .title = Lähennä
+pdfjs-zoom-in-button-label = Lähennä
+pdfjs-zoom-select =
+ .title = Suurennus
+pdfjs-presentation-mode-button =
+ .title = Siirry esitystilaan
+pdfjs-presentation-mode-button-label = Esitystila
+pdfjs-open-file-button =
+ .title = Avaa tiedosto
+pdfjs-open-file-button-label = Avaa
+pdfjs-print-button =
+ .title = Tulosta
+pdfjs-print-button-label = Tulosta
+pdfjs-save-button =
+ .title = Tallenna
+pdfjs-save-button-label = Tallenna
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Lataa
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Lataa
+pdfjs-bookmark-button =
+ .title = Nykyinen sivu (Näytä URL-osoite nykyiseltä sivulta)
+pdfjs-bookmark-button-label = Nykyinen sivu
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Avaa sovelluksessa
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Avaa sovelluksessa
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Siirry ensimmäiselle sivulle
+pdfjs-first-page-button-label = Siirry ensimmäiselle sivulle
+pdfjs-last-page-button =
+ .title = Siirry viimeiselle sivulle
+pdfjs-last-page-button-label = Siirry viimeiselle sivulle
+pdfjs-page-rotate-cw-button =
+ .title = Kierrä oikealle
+pdfjs-page-rotate-cw-button-label = Kierrä oikealle
+pdfjs-page-rotate-ccw-button =
+ .title = Kierrä vasemmalle
+pdfjs-page-rotate-ccw-button-label = Kierrä vasemmalle
+pdfjs-cursor-text-select-tool-button =
+ .title = Käytä tekstinvalintatyökalua
+pdfjs-cursor-text-select-tool-button-label = Tekstinvalintatyökalu
+pdfjs-cursor-hand-tool-button =
+ .title = Käytä käsityökalua
+pdfjs-cursor-hand-tool-button-label = Käsityökalu
+pdfjs-scroll-page-button =
+ .title = Käytä sivun vieritystä
+pdfjs-scroll-page-button-label = Sivun vieritys
+pdfjs-scroll-vertical-button =
+ .title = Käytä pystysuuntaista vieritystä
+pdfjs-scroll-vertical-button-label = Pystysuuntainen vieritys
+pdfjs-scroll-horizontal-button =
+ .title = Käytä vaakasuuntaista vieritystä
+pdfjs-scroll-horizontal-button-label = Vaakasuuntainen vieritys
+pdfjs-scroll-wrapped-button =
+ .title = Käytä rivittyvää vieritystä
+pdfjs-scroll-wrapped-button-label = Rivittyvä vieritys
+pdfjs-spread-none-button =
+ .title = Älä yhdistä sivuja aukeamiksi
+pdfjs-spread-none-button-label = Ei aukeamia
+pdfjs-spread-odd-button =
+ .title = Yhdistä sivut aukeamiksi alkaen parittomalta sivulta
+pdfjs-spread-odd-button-label = Parittomalta alkavat aukeamat
+pdfjs-spread-even-button =
+ .title = Yhdistä sivut aukeamiksi alkaen parilliselta sivulta
+pdfjs-spread-even-button-label = Parilliselta alkavat aukeamat
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentin ominaisuudet…
+pdfjs-document-properties-button-label = Dokumentin ominaisuudet…
+pdfjs-document-properties-file-name = Tiedoston nimi:
+pdfjs-document-properties-file-size = Tiedoston koko:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kt ({ $size_b } tavua)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } Mt ({ $size_b } tavua)
+pdfjs-document-properties-title = Otsikko:
+pdfjs-document-properties-author = Tekijä:
+pdfjs-document-properties-subject = Aihe:
+pdfjs-document-properties-keywords = Avainsanat:
+pdfjs-document-properties-creation-date = Luomispäivämäärä:
+pdfjs-document-properties-modification-date = Muokkauspäivämäärä:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Luoja:
+pdfjs-document-properties-producer = PDF-tuottaja:
+pdfjs-document-properties-version = PDF-versio:
+pdfjs-document-properties-page-count = Sivujen määrä:
+pdfjs-document-properties-page-size = Sivun koko:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = pysty
+pdfjs-document-properties-page-size-orientation-landscape = vaaka
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Nopea web-katselu:
+pdfjs-document-properties-linearized-yes = Kyllä
+pdfjs-document-properties-linearized-no = Ei
+pdfjs-document-properties-close-button = Sulje
+
+## Print
+
+pdfjs-print-progress-message = Valmistellaan dokumenttia tulostamista varten…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }Â %
+pdfjs-print-progress-close-button = Peruuta
+pdfjs-printing-not-supported = Varoitus: Selain ei tue kaikkia tulostustapoja.
+pdfjs-printing-not-ready = Varoitus: PDF-tiedosto ei ole vielä latautunut kokonaan, eikä sitä voi vielä tulostaa.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Näytä/piilota sivupaneeli
+pdfjs-toggle-sidebar-notification-button =
+ .title = Näytä/piilota sivupaneeli (dokumentissa on sisällys/liitteitä/tasoja)
+pdfjs-toggle-sidebar-button-label = Näytä/piilota sivupaneeli
+pdfjs-document-outline-button =
+ .title = Näytä dokumentin sisällys (laajenna tai kutista kohdat kaksoisnapsauttamalla)
+pdfjs-document-outline-button-label = Dokumentin sisällys
+pdfjs-attachments-button =
+ .title = Näytä liitteet
+pdfjs-attachments-button-label = Liitteet
+pdfjs-layers-button =
+ .title = Näytä tasot (kaksoisnapsauta palauttaaksesi kaikki tasot oletustilaan)
+pdfjs-layers-button-label = Tasot
+pdfjs-thumbs-button =
+ .title = Näytä pienoiskuvat
+pdfjs-thumbs-button-label = Pienoiskuvat
+pdfjs-current-outline-item-button =
+ .title = Etsi nykyinen sisällyksen kohta
+pdfjs-current-outline-item-button-label = Nykyinen sisällyksen kohta
+pdfjs-findbar-button =
+ .title = Etsi dokumentista
+pdfjs-findbar-button-label = Etsi
+pdfjs-additional-layers = Lisätasot
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Sivu { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Pienoiskuva sivusta { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Etsi
+ .placeholder = Etsi dokumentista…
+pdfjs-find-previous-button =
+ .title = Etsi hakusanan edellinen osuma
+pdfjs-find-previous-button-label = Edellinen
+pdfjs-find-next-button =
+ .title = Etsi hakusanan seuraava osuma
+pdfjs-find-next-button-label = Seuraava
+pdfjs-find-highlight-checkbox = Korosta kaikki
+pdfjs-find-match-case-checkbox-label = Huomioi kirjainkoko
+pdfjs-find-match-diacritics-checkbox-label = Erota tarkkeet
+pdfjs-find-entire-word-checkbox-label = Kokonaiset sanat
+pdfjs-find-reached-top = Päästiin dokumentin alkuun, jatketaan lopusta
+pdfjs-find-reached-bottom = Päästiin dokumentin loppuun, jatketaan alusta
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } / { $total } osuma
+ *[other] { $current } / { $total } osumaa
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Yli { $limit } osuma
+ *[other] Yli { $limit } osumaa
+ }
+pdfjs-find-not-found = Hakusanaa ei löytynyt
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sivun leveys
+pdfjs-page-scale-fit = Koko sivu
+pdfjs-page-scale-auto = Automaattinen suurennus
+pdfjs-page-scale-actual = Todellinen koko
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Sivu { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Tapahtui virhe ladattaessa PDF-tiedostoa.
+pdfjs-invalid-file-error = Virheellinen tai vioittunut PDF-tiedosto.
+pdfjs-missing-file-error = Puuttuva PDF-tiedosto.
+pdfjs-unexpected-response-error = Odottamaton vastaus palvelimelta.
+pdfjs-rendering-error = Tapahtui virhe piirrettäessä sivua.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-merkintä]
+
+## Password
+
+pdfjs-password-label = Kirjoita PDF-tiedoston salasana.
+pdfjs-password-invalid = Virheellinen salasana. Yritä uudestaan.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Peruuta
+pdfjs-web-fonts-disabled = Verkkosivujen omat kirjasinlajit on estetty: ei voida käyttää upotettuja PDF-kirjasinlajeja.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Teksti
+pdfjs-editor-free-text-button-label = Teksti
+pdfjs-editor-ink-button =
+ .title = Piirros
+pdfjs-editor-ink-button-label = Piirros
+pdfjs-editor-stamp-button =
+ .title = Lisää tai muokkaa kuvia
+pdfjs-editor-stamp-button-label = Lisää tai muokkaa kuvia
+pdfjs-editor-remove-button =
+ .title = Poista
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Poista piirros
+pdfjs-editor-remove-freetext-button =
+ .title = Poista teksti
+pdfjs-editor-remove-stamp-button =
+ .title = Poista kuva
+pdfjs-editor-remove-highlight-button =
+ .title = Poista korostus
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Väri
+pdfjs-editor-free-text-size-input = Koko
+pdfjs-editor-ink-color-input = Väri
+pdfjs-editor-ink-thickness-input = Paksuus
+pdfjs-editor-ink-opacity-input = Peittävyys
+pdfjs-editor-stamp-add-image-button =
+ .title = Lisää kuva
+pdfjs-editor-stamp-add-image-button-label = Lisää kuva
+pdfjs-free-text =
+ .aria-label = Tekstimuokkain
+pdfjs-free-text-default-content = Aloita kirjoittaminen…
+pdfjs-ink =
+ .aria-label = Piirrustusmuokkain
+pdfjs-ink-canvas =
+ .aria-label = Käyttäjän luoma kuva
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Vaihtoehtoinen teksti
+pdfjs-editor-alt-text-edit-button-label = Muokkaa vaihtoehtoista tekstiä
+pdfjs-editor-alt-text-dialog-label = Valitse vaihtoehto
+pdfjs-editor-alt-text-dialog-description = Vaihtoehtoinen teksti ("alt-teksti") auttaa ihmisiä, jotka eivät näe kuvaa tai kun kuva ei lataudu.
+pdfjs-editor-alt-text-add-description-label = Lisää kuvaus
+pdfjs-editor-alt-text-add-description-description = Pyri 1-2 lauseeseen, jotka kuvaavat aihetta, ympäristöä tai toimintaa.
+pdfjs-editor-alt-text-mark-decorative-label = Merkitse koristeelliseksi
+pdfjs-editor-alt-text-mark-decorative-description = Tätä käytetään koristekuville, kuten reunuksille tai vesileimoille.
+pdfjs-editor-alt-text-cancel-button = Peruuta
+pdfjs-editor-alt-text-save-button = Tallenna
+pdfjs-editor-alt-text-decorative-tooltip = Merkitty koristeelliseksi
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Esimerkiksi "Nuori mies istuu pöytään syömään aterian"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Vasen yläkulma - muuta kokoa
+pdfjs-editor-resizer-label-top-middle = Ylhäällä keskellä - muuta kokoa
+pdfjs-editor-resizer-label-top-right = Oikea yläkulma - muuta kokoa
+pdfjs-editor-resizer-label-middle-right = Keskellä oikealla - muuta kokoa
+pdfjs-editor-resizer-label-bottom-right = Oikea alakulma - muuta kokoa
+pdfjs-editor-resizer-label-bottom-middle = Alhaalla keskellä - muuta kokoa
+pdfjs-editor-resizer-label-bottom-left = Vasen alakulma - muuta kokoa
+pdfjs-editor-resizer-label-middle-left = Keskellä vasemmalla - muuta kokoa
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Korostusväri
+pdfjs-editor-colorpicker-button =
+ .title = Vaihda väri
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Värivalinnat
+pdfjs-editor-colorpicker-yellow =
+ .title = Keltainen
+pdfjs-editor-colorpicker-green =
+ .title = Vihreä
+pdfjs-editor-colorpicker-blue =
+ .title = Sininen
+pdfjs-editor-colorpicker-pink =
+ .title = Pinkki
+pdfjs-editor-colorpicker-red =
+ .title = Punainen
diff --git a/www/lib/pdfjs/modern/web/locale/fr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/fr/viewer.ftl
new file mode 100644
index 000000000..47c3d3a55
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/fr/viewer.ftl
@@ -0,0 +1,380 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Page précédente
+pdfjs-previous-button-label = Précédent
+pdfjs-next-button =
+ .title = Page suivante
+pdfjs-next-button-label = Suivant
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Page
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = sur { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } sur { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom arrière
+pdfjs-zoom-out-button-label = Zoom arrière
+pdfjs-zoom-in-button =
+ .title = Zoom avant
+pdfjs-zoom-in-button-label = Zoom avant
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Basculer en mode présentation
+pdfjs-presentation-mode-button-label = Mode présentation
+pdfjs-open-file-button =
+ .title = Ouvrir le fichier
+pdfjs-open-file-button-label = Ouvrir le fichier
+pdfjs-print-button =
+ .title = Imprimer
+pdfjs-print-button-label = Imprimer
+pdfjs-save-button =
+ .title = Enregistrer
+pdfjs-save-button-label = Enregistrer
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Télécharger
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Télécharger
+pdfjs-bookmark-button =
+ .title = Page courante (montrer l’adresse de la page courante)
+pdfjs-bookmark-button-label = Page courante
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ouvrir dans une application
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ouvrir dans une application
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Outils
+pdfjs-tools-button-label = Outils
+pdfjs-first-page-button =
+ .title = Aller à la première page
+pdfjs-first-page-button-label = Aller à la première page
+pdfjs-last-page-button =
+ .title = Aller à la dernière page
+pdfjs-last-page-button-label = Aller à la dernière page
+pdfjs-page-rotate-cw-button =
+ .title = Rotation horaire
+pdfjs-page-rotate-cw-button-label = Rotation horaire
+pdfjs-page-rotate-ccw-button =
+ .title = Rotation antihoraire
+pdfjs-page-rotate-ccw-button-label = Rotation antihoraire
+pdfjs-cursor-text-select-tool-button =
+ .title = Activer l’outil de sélection de texte
+pdfjs-cursor-text-select-tool-button-label = Outil de sélection de texte
+pdfjs-cursor-hand-tool-button =
+ .title = Activer l’outil main
+pdfjs-cursor-hand-tool-button-label = Outil main
+pdfjs-scroll-page-button =
+ .title = Utiliser le défilement par page
+pdfjs-scroll-page-button-label = Défilement par page
+pdfjs-scroll-vertical-button =
+ .title = Utiliser le défilement vertical
+pdfjs-scroll-vertical-button-label = Défilement vertical
+pdfjs-scroll-horizontal-button =
+ .title = Utiliser le défilement horizontal
+pdfjs-scroll-horizontal-button-label = Défilement horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Utiliser le défilement par bloc
+pdfjs-scroll-wrapped-button-label = Défilement par bloc
+pdfjs-spread-none-button =
+ .title = Ne pas afficher les pages deux à deux
+pdfjs-spread-none-button-label = Pas de double affichage
+pdfjs-spread-odd-button =
+ .title = Afficher les pages par deux, impaires à gauche
+pdfjs-spread-odd-button-label = Doubles pages, impaires à gauche
+pdfjs-spread-even-button =
+ .title = Afficher les pages par deux, paires à gauche
+pdfjs-spread-even-button-label = Doubles pages, paires à gauche
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propriétés du document…
+pdfjs-document-properties-button-label = Propriétés du document…
+pdfjs-document-properties-file-name = Nom du fichier :
+pdfjs-document-properties-file-size = Taille du fichier :
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb }Â Ko ({ $size_b } octets)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb }Â Mo ({ $size_b } octets)
+pdfjs-document-properties-title = Titre :
+pdfjs-document-properties-author = Auteur :
+pdfjs-document-properties-subject = Sujet :
+pdfjs-document-properties-keywords = Mots-clés :
+pdfjs-document-properties-creation-date = Date de création :
+pdfjs-document-properties-modification-date = Modifié le :
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } Ã { $time }
+pdfjs-document-properties-creator = Créé par :
+pdfjs-document-properties-producer = Outil de conversion PDFÂ :
+pdfjs-document-properties-version = Version PDFÂ :
+pdfjs-document-properties-page-count = Nombre de pages :
+pdfjs-document-properties-page-size = Taille de la page :
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = paysage
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = lettre
+pdfjs-document-properties-page-size-name-legal = document juridique
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Affichage rapide des pages web :
+pdfjs-document-properties-linearized-yes = Oui
+pdfjs-document-properties-linearized-no = Non
+pdfjs-document-properties-close-button = Fermer
+
+## Print
+
+pdfjs-print-progress-message = Préparation du document pour l’impression…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }Â %
+pdfjs-print-progress-close-button = Annuler
+pdfjs-printing-not-supported = Attention : l’impression n’est pas totalement prise en charge par ce navigateur.
+pdfjs-printing-not-ready = Attention : le PDF n’est pas entièrement chargé pour pouvoir l’imprimer.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Afficher/Masquer le panneau latéral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Afficher/Masquer le panneau latéral (le document contient des signets/pièces jointes/calques)
+pdfjs-toggle-sidebar-button-label = Afficher/Masquer le panneau latéral
+pdfjs-document-outline-button =
+ .title = Afficher les signets du document (double-cliquer pour développer/réduire tous les éléments)
+pdfjs-document-outline-button-label = Signets du document
+pdfjs-attachments-button =
+ .title = Afficher les pièces jointes
+pdfjs-attachments-button-label = Pièces jointes
+pdfjs-layers-button =
+ .title = Afficher les calques (double-cliquer pour réinitialiser tous les calques à l’état par défaut)
+pdfjs-layers-button-label = Calques
+pdfjs-thumbs-button =
+ .title = Afficher les vignettes
+pdfjs-thumbs-button-label = Vignettes
+pdfjs-current-outline-item-button =
+ .title = Trouver l’élément de plan actuel
+pdfjs-current-outline-item-button-label = Élément de plan actuel
+pdfjs-findbar-button =
+ .title = Rechercher dans le document
+pdfjs-findbar-button-label = Rechercher
+pdfjs-additional-layers = Calques additionnels
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Vignette de la page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Rechercher
+ .placeholder = Rechercher dans le document…
+pdfjs-find-previous-button =
+ .title = Trouver l’occurrence précédente de l’expression
+pdfjs-find-previous-button-label = Précédent
+pdfjs-find-next-button =
+ .title = Trouver la prochaine occurrence de l’expression
+pdfjs-find-next-button-label = Suivant
+pdfjs-find-highlight-checkbox = Tout surligner
+pdfjs-find-match-case-checkbox-label = Respecter la casse
+pdfjs-find-match-diacritics-checkbox-label = Respecter les accents et diacritiques
+pdfjs-find-entire-word-checkbox-label = Mots entiers
+pdfjs-find-reached-top = Haut de la page atteint, poursuite depuis la fin
+pdfjs-find-reached-bottom = Bas de la page atteint, poursuite au début
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = Occurrence { $current } sur { $total }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Plus d’{ $limit } occurrence
+ *[other] Plus de { $limit }Â occurrences
+ }
+pdfjs-find-not-found = Expression non trouvée
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Pleine largeur
+pdfjs-page-scale-fit = Page entière
+pdfjs-page-scale-auto = Zoom automatique
+pdfjs-page-scale-actual = Taille réelle
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }Â %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Page { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Une erreur s’est produite lors du chargement du fichier PDF.
+pdfjs-invalid-file-error = Fichier PDF invalide ou corrompu.
+pdfjs-missing-file-error = Fichier PDF manquant.
+pdfjs-unexpected-response-error = Réponse inattendue du serveur.
+pdfjs-rendering-error = Une erreur s’est produite lors de l’affichage de la page.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } Ã { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Annotation { $type }]
+
+## Password
+
+pdfjs-password-label = Veuillez saisir le mot de passe pour ouvrir ce fichier PDF.
+pdfjs-password-invalid = Mot de passe incorrect. Veuillez réessayer.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Annuler
+pdfjs-web-fonts-disabled = Les polices web sont désactivées : impossible d’utiliser les polices intégrées au PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texte
+pdfjs-editor-free-text-button-label = Texte
+pdfjs-editor-ink-button =
+ .title = Dessiner
+pdfjs-editor-ink-button-label = Dessiner
+pdfjs-editor-stamp-button =
+ .title = Ajouter ou modifier des images
+pdfjs-editor-stamp-button-label = Ajouter ou modifier des images
+pdfjs-editor-remove-button =
+ .title = Supprimer
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Supprimer le dessin
+pdfjs-editor-remove-freetext-button =
+ .title = Supprimer le texte
+pdfjs-editor-remove-stamp-button =
+ .title = Supprimer l’image
+pdfjs-editor-remove-highlight-button =
+ .title = Supprimer le surlignage
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Couleur
+pdfjs-editor-free-text-size-input = Taille
+pdfjs-editor-ink-color-input = Couleur
+pdfjs-editor-ink-thickness-input = Épaisseur
+pdfjs-editor-ink-opacity-input = Opacité
+pdfjs-editor-stamp-add-image-button =
+ .title = Ajouter une image
+pdfjs-editor-stamp-add-image-button-label = Ajouter une image
+pdfjs-free-text =
+ .aria-label = Éditeur de texte
+pdfjs-free-text-default-content = Commencer à écrire…
+pdfjs-ink =
+ .aria-label = Éditeur de dessin
+pdfjs-ink-canvas =
+ .aria-label = Image créée par l’utilisateur·trice
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texte alternatif
+pdfjs-editor-alt-text-edit-button-label = Modifier le texte alternatif
+pdfjs-editor-alt-text-dialog-label = Sélectionnez une option
+pdfjs-editor-alt-text-dialog-description = Le texte alternatif est utile lorsque des personnes ne peuvent pas voir l’image ou que l’image ne se charge pas.
+pdfjs-editor-alt-text-add-description-label = Ajouter une description
+pdfjs-editor-alt-text-add-description-description = Il est conseillé de rédiger une ou deux phrases décrivant le sujet, le cadre ou les actions.
+pdfjs-editor-alt-text-mark-decorative-label = Marquer comme décorative
+pdfjs-editor-alt-text-mark-decorative-description = Cette option est utilisée pour les images décoratives, comme les bordures ou les filigranes.
+pdfjs-editor-alt-text-cancel-button = Annuler
+pdfjs-editor-alt-text-save-button = Enregistrer
+pdfjs-editor-alt-text-decorative-tooltip = Marquée comme décorative
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Par exemple, « Un jeune homme est assis à une table pour prendre un repas »
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Coin supérieur gauche — redimensionner
+pdfjs-editor-resizer-label-top-middle = Milieu haut — redimensionner
+pdfjs-editor-resizer-label-top-right = Coin supérieur droit — redimensionner
+pdfjs-editor-resizer-label-middle-right = Milieu droit — redimensionner
+pdfjs-editor-resizer-label-bottom-right = Coin inférieur droit — redimensionner
+pdfjs-editor-resizer-label-bottom-middle = Centre bas — redimensionner
+pdfjs-editor-resizer-label-bottom-left = Coin inférieur gauche — redimensionner
+pdfjs-editor-resizer-label-middle-left = Milieu gauche — redimensionner
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Couleur de surlignage
+pdfjs-editor-colorpicker-button =
+ .title = Changer de couleur
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Choix de couleurs
+pdfjs-editor-colorpicker-yellow =
+ .title = Jaune
+pdfjs-editor-colorpicker-green =
+ .title = Vert
+pdfjs-editor-colorpicker-blue =
+ .title = Bleu
+pdfjs-editor-colorpicker-pink =
+ .title = Rose
+pdfjs-editor-colorpicker-red =
+ .title = Rouge
diff --git a/www/lib/pdfjs/modern/web/locale/fur/viewer.ftl b/www/lib/pdfjs/modern/web/locale/fur/viewer.ftl
new file mode 100644
index 000000000..4990ef4e4
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/fur/viewer.ftl
@@ -0,0 +1,363 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagjine precedente
+pdfjs-previous-button-label = Indaûr
+pdfjs-next-button =
+ .title = Prossime pagjine
+pdfjs-next-button-label = Indevant
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagjine
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = di { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } di { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Impiçulìs
+pdfjs-zoom-out-button-label = Impiçulìs
+pdfjs-zoom-in-button =
+ .title = Ingrandìs
+pdfjs-zoom-in-button-label = Ingrandìs
+pdfjs-zoom-select =
+ .title = Ingrandiment
+pdfjs-presentation-mode-button =
+ .title = Passe ae modalitât presentazion
+pdfjs-presentation-mode-button-label = Modalitât presentazion
+pdfjs-open-file-button =
+ .title = Vierç un file
+pdfjs-open-file-button-label = Vierç
+pdfjs-print-button =
+ .title = Stampe
+pdfjs-print-button-label = Stampe
+pdfjs-save-button =
+ .title = Salve
+pdfjs-save-button-label = Salve
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Discjame
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Discjame
+pdfjs-bookmark-button =
+ .title = Pagjine corinte (mostre URL de pagjine atuâl)
+pdfjs-bookmark-button-label = Pagjine corinte
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Vierç te aplicazion
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Vierç te aplicazion
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Struments
+pdfjs-tools-button-label = Struments
+pdfjs-first-page-button =
+ .title = Va ae prime pagjine
+pdfjs-first-page-button-label = Va ae prime pagjine
+pdfjs-last-page-button =
+ .title = Va ae ultime pagjine
+pdfjs-last-page-button-label = Va ae ultime pagjine
+pdfjs-page-rotate-cw-button =
+ .title = Zire in sens orari
+pdfjs-page-rotate-cw-button-label = Zire in sens orari
+pdfjs-page-rotate-ccw-button =
+ .title = Zire in sens antiorari
+pdfjs-page-rotate-ccw-button-label = Zire in sens antiorari
+pdfjs-cursor-text-select-tool-button =
+ .title = Ative il strument di selezion dal test
+pdfjs-cursor-text-select-tool-button-label = Strument di selezion dal test
+pdfjs-cursor-hand-tool-button =
+ .title = Ative il strument manute
+pdfjs-cursor-hand-tool-button-label = Strument manute
+pdfjs-scroll-page-button =
+ .title = Dopre il scoriment des pagjinis
+pdfjs-scroll-page-button-label = Scoriment pagjinis
+pdfjs-scroll-vertical-button =
+ .title = Dopre scoriment verticâl
+pdfjs-scroll-vertical-button-label = Scoriment verticâl
+pdfjs-scroll-horizontal-button =
+ .title = Dopre scoriment orizontâl
+pdfjs-scroll-horizontal-button-label = Scoriment orizontâl
+pdfjs-scroll-wrapped-button =
+ .title = Dopre scoriment par blocs
+pdfjs-scroll-wrapped-button-label = Scoriment par blocs
+pdfjs-spread-none-button =
+ .title = No sta meti dongje pagjinis in cubie
+pdfjs-spread-none-button-label = No cubiis di pagjinis
+pdfjs-spread-odd-button =
+ .title = Met dongje cubiis di pagjinis scomençant des pagjinis dispar
+pdfjs-spread-odd-button-label = Cubiis di pagjinis, dispar a çampe
+pdfjs-spread-even-button =
+ .title = Met dongje cubiis di pagjinis scomençant des pagjinis pâr
+pdfjs-spread-even-button-label = Cubiis di pagjinis, pâr a çampe
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Proprietâts dal document…
+pdfjs-document-properties-button-label = Proprietâts dal document…
+pdfjs-document-properties-file-name = Non dal file:
+pdfjs-document-properties-file-size = Dimension dal file:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titul:
+pdfjs-document-properties-author = Autôr:
+pdfjs-document-properties-subject = Ogjet:
+pdfjs-document-properties-keywords = Peraulis clâf:
+pdfjs-document-properties-creation-date = Date di creazion:
+pdfjs-document-properties-modification-date = Date di modifiche:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creatôr
+pdfjs-document-properties-producer = Gjeneradôr PDF:
+pdfjs-document-properties-version = Version PDF:
+pdfjs-document-properties-page-count = Numar di pagjinis:
+pdfjs-document-properties-page-size = Dimension de pagjine:
+pdfjs-document-properties-page-size-unit-inches = oncis
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = verticâl
+pdfjs-document-properties-page-size-orientation-landscape = orizontâl
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letare
+pdfjs-document-properties-page-size-name-legal = Legâl
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Visualizazion web svelte:
+pdfjs-document-properties-linearized-yes = Sì
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Siere
+
+## Print
+
+pdfjs-print-progress-message = Daûr a prontâ il document pe stampe…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Anule
+pdfjs-printing-not-supported = Atenzion: la stampe no je supuartade ad implen di chest navigadôr.
+pdfjs-printing-not-ready = Atenzion: il PDF nol è stât cjamât dal dut pe stampe.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Ative/Disative sbare laterâl
+pdfjs-toggle-sidebar-notification-button =
+ .title = Ative/Disative sbare laterâl (il document al conten struture/zontis/strâts)
+pdfjs-toggle-sidebar-button-label = Ative/Disative sbare laterâl
+pdfjs-document-outline-button =
+ .title = Mostre la struture dal document (dopli clic par slargjâ/strenzi ducj i elements)
+pdfjs-document-outline-button-label = Struture dal document
+pdfjs-attachments-button =
+ .title = Mostre lis zontis
+pdfjs-attachments-button-label = Zontis
+pdfjs-layers-button =
+ .title = Mostre i strâts (dopli clic par ristabilî ducj i strâts al stât predefinît)
+pdfjs-layers-button-label = Strâts
+pdfjs-thumbs-button =
+ .title = Mostre miniaturis
+pdfjs-thumbs-button-label = Miniaturis
+pdfjs-current-outline-item-button =
+ .title = Cjate l'element de struture atuâl
+pdfjs-current-outline-item-button-label = Element de struture atuâl
+pdfjs-findbar-button =
+ .title = Cjate tal document
+pdfjs-findbar-button-label = Cjate
+pdfjs-additional-layers = Strâts adizionâi
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagjine { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniature de pagjine { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Cjate
+ .placeholder = Cjate tal document…
+pdfjs-find-previous-button =
+ .title = Cjate il câs precedent dal test
+pdfjs-find-previous-button-label = Precedent
+pdfjs-find-next-button =
+ .title = Cjate il câs sucessîf dal test
+pdfjs-find-next-button-label = Sucessîf
+pdfjs-find-highlight-checkbox = Evidenzie dut
+pdfjs-find-match-case-checkbox-label = Fâs distinzion tra maiusculis e minusculis
+pdfjs-find-match-diacritics-checkbox-label = Corispondence diacritiche
+pdfjs-find-entire-word-checkbox-label = Peraulis interiis
+pdfjs-find-reached-top = Si è rivâts al inizi dal document e si à continuât de fin
+pdfjs-find-reached-bottom = Si è rivât ae fin dal document e si à continuât dal inizi
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } di { $total } corispondence
+ *[other] { $current } di { $total } corispondencis
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Plui di { $limit } corispondence
+ *[other] Plui di { $limit } corispondencis
+ }
+pdfjs-find-not-found = Test no cjatât
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Largjece de pagjine
+pdfjs-page-scale-fit = Pagjine interie
+pdfjs-page-scale-auto = Ingrandiment automatic
+pdfjs-page-scale-actual = Dimension reâl
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagjine { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Al è vignût fûr un erôr intant che si cjariave il PDF.
+pdfjs-invalid-file-error = File PDF no valit o ruvinât.
+pdfjs-missing-file-error = Al mancje il file PDF.
+pdfjs-unexpected-response-error = Rispueste dal servidôr inspietade.
+pdfjs-rendering-error = Al è vignût fûr un erôr tal realizâ la visualizazion de pagjine.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotazion { $type }]
+
+## Password
+
+pdfjs-password-label = Inserìs la password par vierzi chest file PDF.
+pdfjs-password-invalid = Password no valide. Par plasê torne prove.
+pdfjs-password-ok-button = Va ben
+pdfjs-password-cancel-button = Anule
+pdfjs-web-fonts-disabled = I caratars dal Web a son disativâts: Impussibil doprâ i caratars PDF incorporâts.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Test
+pdfjs-editor-free-text-button-label = Test
+pdfjs-editor-ink-button =
+ .title = Dissen
+pdfjs-editor-ink-button-label = Dissen
+pdfjs-editor-stamp-button =
+ .title = Zonte o modifiche imagjins
+pdfjs-editor-stamp-button-label = Zonte o modifiche imagjins
+pdfjs-editor-remove-button =
+ .title = Gjave
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Gjave dissen
+pdfjs-editor-remove-freetext-button =
+ .title = Gjave test
+pdfjs-editor-remove-stamp-button =
+ .title = Gjave imagjin
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colôr
+pdfjs-editor-free-text-size-input = Dimension
+pdfjs-editor-ink-color-input = Colôr
+pdfjs-editor-ink-thickness-input = Spessôr
+pdfjs-editor-ink-opacity-input = Opacitât
+pdfjs-editor-stamp-add-image-button =
+ .title = Zonte imagjin
+pdfjs-editor-stamp-add-image-button-label = Zonte imagjin
+pdfjs-free-text =
+ .aria-label = Editôr di test
+pdfjs-free-text-default-content = Scomence a scrivi…
+pdfjs-ink =
+ .aria-label = Editôr dissens
+pdfjs-ink-canvas =
+ .aria-label = Imagjin creade dal utent
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Test alternatîf
+pdfjs-editor-alt-text-edit-button-label = Modifiche test alternatîf
+pdfjs-editor-alt-text-dialog-label = Sielç une opzion
+pdfjs-editor-alt-text-dialog-description = Il test alternatîf (“alt textâ€) al jude cuant che lis personis no puedin viodi la imagjin o cuant che la imagjine no ven cjariade.
+pdfjs-editor-alt-text-add-description-label = Zonte une descrizion
+pdfjs-editor-alt-text-add-description-description = Ponte a une o dôs frasis che a descrivin l’argoment, la ambientazion o lis azions.
+pdfjs-editor-alt-text-mark-decorative-label = Segne come decorative
+pdfjs-editor-alt-text-mark-decorative-description = Chest al ven doprât pes imagjins ornamentâls, come i ôrs o lis filigranis.
+pdfjs-editor-alt-text-cancel-button = Anule
+pdfjs-editor-alt-text-save-button = Salve
+pdfjs-editor-alt-text-decorative-tooltip = Segnade come decorative
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Par esempli, “Un zovin si sente a taule par mangjââ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Cjanton in alt a çampe — ridimensione
+pdfjs-editor-resizer-label-top-middle = Bande superiôr tal mieç — ridimensione
+pdfjs-editor-resizer-label-top-right = Cjanton in alt a diestre — ridimensione
+pdfjs-editor-resizer-label-middle-right = Bande diestre tal mieç — ridimensione
+pdfjs-editor-resizer-label-bottom-right = Cjanton in bas a diestre — ridimensione
+pdfjs-editor-resizer-label-bottom-middle = Bande inferiôr tal mieç — ridimensione
+pdfjs-editor-resizer-label-bottom-left = Cjanton in bas a çampe — ridimensione
+pdfjs-editor-resizer-label-middle-left = Bande di çampe tal mieç — ridimensione
diff --git a/www/lib/pdfjs/modern/web/locale/fy-NL/viewer.ftl b/www/lib/pdfjs/modern/web/locale/fy-NL/viewer.ftl
new file mode 100644
index 000000000..19eca2b8c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/fy-NL/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Foarige side
+pdfjs-previous-button-label = Foarige
+pdfjs-next-button =
+ .title = Folgjende side
+pdfjs-next-button-label = Folgjende
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Side
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = fan { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } fan { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Utzoome
+pdfjs-zoom-out-button-label = Utzoome
+pdfjs-zoom-in-button =
+ .title = Ynzoome
+pdfjs-zoom-in-button-label = Ynzoome
+pdfjs-zoom-select =
+ .title = Zoome
+pdfjs-presentation-mode-button =
+ .title = Wikselje nei presintaasjemodus
+pdfjs-presentation-mode-button-label = Presintaasjemodus
+pdfjs-open-file-button =
+ .title = Bestân iepenje
+pdfjs-open-file-button-label = Iepenje
+pdfjs-print-button =
+ .title = Ofdrukke
+pdfjs-print-button-label = Ofdrukke
+pdfjs-save-button =
+ .title = Bewarje
+pdfjs-save-button-label = Bewarje
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Downloade
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Downloade
+pdfjs-bookmark-button =
+ .title = Aktuele side (URL fan aktuele side besjen)
+pdfjs-bookmark-button-label = Aktuele side
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Iepenje yn app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Iepenje yn app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ark
+pdfjs-tools-button-label = Ark
+pdfjs-first-page-button =
+ .title = Gean nei earste side
+pdfjs-first-page-button-label = Gean nei earste side
+pdfjs-last-page-button =
+ .title = Gean nei lêste side
+pdfjs-last-page-button-label = Gean nei lêste side
+pdfjs-page-rotate-cw-button =
+ .title = Rjochtsom draaie
+pdfjs-page-rotate-cw-button-label = Rjochtsom draaie
+pdfjs-page-rotate-ccw-button =
+ .title = Linksom draaie
+pdfjs-page-rotate-ccw-button-label = Linksom draaie
+pdfjs-cursor-text-select-tool-button =
+ .title = Tekstseleksjehelpmiddel ynskeakelje
+pdfjs-cursor-text-select-tool-button-label = Tekstseleksjehelpmiddel
+pdfjs-cursor-hand-tool-button =
+ .title = Hânhelpmiddel ynskeakelje
+pdfjs-cursor-hand-tool-button-label = Hânhelpmiddel
+pdfjs-scroll-page-button =
+ .title = Sideskowen brûke
+pdfjs-scroll-page-button-label = Sideskowen
+pdfjs-scroll-vertical-button =
+ .title = Fertikaal skowe brûke
+pdfjs-scroll-vertical-button-label = Fertikaal skowe
+pdfjs-scroll-horizontal-button =
+ .title = Horizontaal skowe brûke
+pdfjs-scroll-horizontal-button-label = Horizontaal skowe
+pdfjs-scroll-wrapped-button =
+ .title = Skowe mei oersjoch brûke
+pdfjs-scroll-wrapped-button-label = Skowe mei oersjoch
+pdfjs-spread-none-button =
+ .title = Sidesprieding net gearfetsje
+pdfjs-spread-none-button-label = Gjin sprieding
+pdfjs-spread-odd-button =
+ .title = Sidesprieding gearfetsje te starten mei ûneven nûmers
+pdfjs-spread-odd-button-label = Uneven sprieding
+pdfjs-spread-even-button =
+ .title = Sidesprieding gearfetsje te starten mei even nûmers
+pdfjs-spread-even-button-label = Even sprieding
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokuminteigenskippen…
+pdfjs-document-properties-button-label = Dokuminteigenskippen…
+pdfjs-document-properties-file-name = Bestânsnamme:
+pdfjs-document-properties-file-size = Bestânsgrutte:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Auteur:
+pdfjs-document-properties-subject = Underwerp:
+pdfjs-document-properties-keywords = Kaaiwurden:
+pdfjs-document-properties-creation-date = Oanmaakdatum:
+pdfjs-document-properties-modification-date = Bewurkingsdatum:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Makker:
+pdfjs-document-properties-producer = PDF-makker:
+pdfjs-document-properties-version = PDF-ferzje:
+pdfjs-document-properties-page-count = Siden:
+pdfjs-document-properties-page-size = Sideformaat:
+pdfjs-document-properties-page-size-unit-inches = yn
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = steand
+pdfjs-document-properties-page-size-orientation-landscape = lizzend
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Juridysk
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Flugge webwerjefte:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nee
+pdfjs-document-properties-close-button = Slute
+
+## Print
+
+pdfjs-print-progress-message = Dokumint tariede oar ôfdrukken…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Annulearje
+pdfjs-printing-not-supported = Warning: Printen is net folslein stipe troch dizze browser.
+pdfjs-printing-not-ready = Warning: PDF is net folslein laden om ôf te drukken.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Sidebalke yn-/útskeakelje
+pdfjs-toggle-sidebar-notification-button =
+ .title = Sidebalke yn-/útskeakelje (dokumint befettet oersjoch/bylagen/lagen)
+pdfjs-toggle-sidebar-button-label = Sidebalke yn-/útskeakelje
+pdfjs-document-outline-button =
+ .title = Dokumintoersjoch toane (dûbelklik om alle items út/yn te klappen)
+pdfjs-document-outline-button-label = Dokumintoersjoch
+pdfjs-attachments-button =
+ .title = Bylagen toane
+pdfjs-attachments-button-label = Bylagen
+pdfjs-layers-button =
+ .title = Lagen toane (dûbelklik om alle lagen nei de standertsteat werom te setten)
+pdfjs-layers-button-label = Lagen
+pdfjs-thumbs-button =
+ .title = Foarbylden toane
+pdfjs-thumbs-button-label = Foarbylden
+pdfjs-current-outline-item-button =
+ .title = Aktueel item yn ynhâldsopjefte sykje
+pdfjs-current-outline-item-button-label = Aktueel item yn ynhâldsopjefte
+pdfjs-findbar-button =
+ .title = Sykje yn dokumint
+pdfjs-findbar-button-label = Sykje
+pdfjs-additional-layers = Oanfoljende lagen
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Side { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Foarbyld fan side { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Sykje
+ .placeholder = Sykje yn dokumint…
+pdfjs-find-previous-button =
+ .title = It foarige foarkommen fan de tekst sykje
+pdfjs-find-previous-button-label = Foarige
+pdfjs-find-next-button =
+ .title = It folgjende foarkommen fan de tekst sykje
+pdfjs-find-next-button-label = Folgjende
+pdfjs-find-highlight-checkbox = Alles markearje
+pdfjs-find-match-case-checkbox-label = Haadlettergefoelich
+pdfjs-find-match-diacritics-checkbox-label = Diakrityske tekens brûke
+pdfjs-find-entire-word-checkbox-label = Hiele wurden
+pdfjs-find-reached-top = Boppekant fan dokumint berikt, trochgien fan ûnder ôf
+pdfjs-find-reached-bottom = Ein fan dokumint berikt, trochgien fan boppe ôf
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } fan { $total } oerienkomst
+ *[other] { $current } fan { $total } oerienkomsten
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mear as { $limit } oerienkomst
+ *[other] Mear as { $limit } oerienkomsten
+ }
+pdfjs-find-not-found = Tekst net fûn
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sidebreedte
+pdfjs-page-scale-fit = Hiele side
+pdfjs-page-scale-auto = Automatysk zoome
+pdfjs-page-scale-actual = Werklike grutte
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Side { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Der is in flater bard by it laden fan de PDF.
+pdfjs-invalid-file-error = Ynfalide of korruptearre PDF-bestân.
+pdfjs-missing-file-error = PDF-bestân ûntbrekt.
+pdfjs-unexpected-response-error = Unferwacht serverantwurd.
+pdfjs-rendering-error = Der is in flater bard by it renderjen fan de side.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-annotaasje]
+
+## Password
+
+pdfjs-password-label = Jou it wachtwurd om dit PDF-bestân te iepenjen.
+pdfjs-password-invalid = Ferkeard wachtwurd. Probearje opnij.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Annulearje
+pdfjs-web-fonts-disabled = Weblettertypen binne útskeakele: gebrûk fan ynsluten PDF-lettertypen is net mooglik.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Tekenje
+pdfjs-editor-ink-button-label = Tekenje
+pdfjs-editor-stamp-button =
+ .title = Ofbyldingen tafoegje of bewurkje
+pdfjs-editor-stamp-button-label = Ofbyldingen tafoegje of bewurkje
+pdfjs-editor-remove-button =
+ .title = Fuortsmite
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Tekening fuortsmite
+pdfjs-editor-remove-freetext-button =
+ .title = Tekst fuortsmite
+pdfjs-editor-remove-stamp-button =
+ .title = Ofbylding fuortsmite
+pdfjs-editor-remove-highlight-button =
+ .title = Markearring fuortsmite
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Kleur
+pdfjs-editor-free-text-size-input = Grutte
+pdfjs-editor-ink-color-input = Kleur
+pdfjs-editor-ink-thickness-input = Tsjokte
+pdfjs-editor-ink-opacity-input = Transparânsje
+pdfjs-editor-stamp-add-image-button =
+ .title = Ofbylding tafoegje
+pdfjs-editor-stamp-add-image-button-label = Ofbylding tafoegje
+pdfjs-free-text =
+ .aria-label = Tekstbewurker
+pdfjs-free-text-default-content = Begjin mei typen…
+pdfjs-ink =
+ .aria-label = Tekeningbewurker
+pdfjs-ink-canvas =
+ .aria-label = Troch brûker makke ôfbylding
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternative tekst
+pdfjs-editor-alt-text-edit-button-label = Alternative tekst bewurkje
+pdfjs-editor-alt-text-dialog-label = Kies in opsje
+pdfjs-editor-alt-text-dialog-description = Alternative tekst helpt wannear’t minsken de ôfbylding net sjen kinne of wannear’t dizze net laden wurdt.
+pdfjs-editor-alt-text-add-description-label = Foegje in beskriuwing ta
+pdfjs-editor-alt-text-add-description-description = Stribje nei 1-2 sinnen dy’t it ûnderwerp, de omjouwing of de aksjes beskriuwe.
+pdfjs-editor-alt-text-mark-decorative-label = As dekoratyf markearje
+pdfjs-editor-alt-text-mark-decorative-description = Dit wurdt brûkt foar sierlike ôfbyldingen, lykas rânen of wettermerken.
+pdfjs-editor-alt-text-cancel-button = Annulearje
+pdfjs-editor-alt-text-save-button = Bewarje
+pdfjs-editor-alt-text-decorative-tooltip = As dekoratyf markearre
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Bygelyks, ‘In jonge man sit oan in tafel om te iten’
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Linkerboppehoek – formaat wizigje
+pdfjs-editor-resizer-label-top-middle = Midden boppe – formaat wizigje
+pdfjs-editor-resizer-label-top-right = Rjochterboppehoek – formaat wizigje
+pdfjs-editor-resizer-label-middle-right = Midden rjochts – formaat wizigje
+pdfjs-editor-resizer-label-bottom-right = Rjochterûnderhoek – formaat wizigje
+pdfjs-editor-resizer-label-bottom-middle = Midden ûnder – formaat wizigje
+pdfjs-editor-resizer-label-bottom-left = Linkerûnderhoek – formaat wizigje
+pdfjs-editor-resizer-label-middle-left = Links midden – formaat wizigje
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Markearringskleur
+pdfjs-editor-colorpicker-button =
+ .title = Kleur wizigje
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Kleurkarren
+pdfjs-editor-colorpicker-yellow =
+ .title = Giel
+pdfjs-editor-colorpicker-green =
+ .title = Grien
+pdfjs-editor-colorpicker-blue =
+ .title = Blau
+pdfjs-editor-colorpicker-pink =
+ .title = Roze
+pdfjs-editor-colorpicker-red =
+ .title = Read
diff --git a/www/lib/pdfjs/modern/web/locale/ga-IE/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ga-IE/viewer.ftl
new file mode 100644
index 000000000..cb5930890
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ga-IE/viewer.ftl
@@ -0,0 +1,213 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = An Leathanach Roimhe Seo
+pdfjs-previous-button-label = Roimhe Seo
+pdfjs-next-button =
+ .title = An Chéad Leathanach Eile
+pdfjs-next-button-label = Ar Aghaidh
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Leathanach
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = as { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } as { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Súmáil Amach
+pdfjs-zoom-out-button-label = Súmáil Amach
+pdfjs-zoom-in-button =
+ .title = Súmáil Isteach
+pdfjs-zoom-in-button-label = Súmáil Isteach
+pdfjs-zoom-select =
+ .title = Súmáil
+pdfjs-presentation-mode-button =
+ .title = Úsáid an Mód Láithreoireachta
+pdfjs-presentation-mode-button-label = Mód Láithreoireachta
+pdfjs-open-file-button =
+ .title = Oscail Comhad
+pdfjs-open-file-button-label = Oscail
+pdfjs-print-button =
+ .title = Priontáil
+pdfjs-print-button-label = Priontáil
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = UirlisÃ
+pdfjs-tools-button-label = UirlisÃ
+pdfjs-first-page-button =
+ .title = Go dtà an chéad leathanach
+pdfjs-first-page-button-label = Go dtà an chéad leathanach
+pdfjs-last-page-button =
+ .title = Go dtà an leathanach deiridh
+pdfjs-last-page-button-label = Go dtà an leathanach deiridh
+pdfjs-page-rotate-cw-button =
+ .title = Rothlaigh ar deiseal
+pdfjs-page-rotate-cw-button-label = Rothlaigh ar deiseal
+pdfjs-page-rotate-ccw-button =
+ .title = Rothlaigh ar tuathal
+pdfjs-page-rotate-ccw-button-label = Rothlaigh ar tuathal
+pdfjs-cursor-text-select-tool-button =
+ .title = Cumasaigh an Uirlis Roghnaithe Téacs
+pdfjs-cursor-text-select-tool-button-label = Uirlis Roghnaithe Téacs
+pdfjs-cursor-hand-tool-button =
+ .title = Cumasaigh an Uirlis Láimhe
+pdfjs-cursor-hand-tool-button-label = Uirlis Láimhe
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = AirÃonna na Cáipéise…
+pdfjs-document-properties-button-label = AirÃonna na Cáipéise…
+pdfjs-document-properties-file-name = Ainm an chomhaid:
+pdfjs-document-properties-file-size = Méid an chomhaid:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } beart)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } beart)
+pdfjs-document-properties-title = Teideal:
+pdfjs-document-properties-author = Údar:
+pdfjs-document-properties-subject = Ãbhar:
+pdfjs-document-properties-keywords = Eochairfhocail:
+pdfjs-document-properties-creation-date = Dáta Cruthaithe:
+pdfjs-document-properties-modification-date = Dáta Athraithe:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Cruthaitheoir:
+pdfjs-document-properties-producer = Cruthaitheoir an PDF:
+pdfjs-document-properties-version = Leagan PDF:
+pdfjs-document-properties-page-count = LÃon Leathanach:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = Dún
+
+## Print
+
+pdfjs-print-progress-message = Cáipéis á hullmhú le priontáil…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cealaigh
+pdfjs-printing-not-supported = Rabhadh: Nà thacaÃonn an brabhsálaà le priontáil go hiomlán.
+pdfjs-printing-not-ready = Rabhadh: Nà féidir an PDF a phriontáil go dtà go mbeidh an cháipéis iomlán lódáilte.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Scoránaigh an Barra Taoibh
+pdfjs-toggle-sidebar-button-label = Scoránaigh an Barra Taoibh
+pdfjs-document-outline-button =
+ .title = Taispeáin ImlÃne na Cáipéise (déchliceáil chun chuile rud a leathnú nó a laghdú)
+pdfjs-document-outline-button-label = Creatlach na Cáipéise
+pdfjs-attachments-button =
+ .title = Taispeáin Iatáin
+pdfjs-attachments-button-label = Iatáin
+pdfjs-thumbs-button =
+ .title = Taispeáin Mionsamhlacha
+pdfjs-thumbs-button-label = Mionsamhlacha
+pdfjs-findbar-button =
+ .title = Aimsigh sa Cháipéis
+pdfjs-findbar-button-label = Aimsigh
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Leathanach { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Mionsamhail Leathanaigh { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Aimsigh
+ .placeholder = Aimsigh sa cháipéis…
+pdfjs-find-previous-button =
+ .title = Aimsigh an sampla roimhe seo den nath seo
+pdfjs-find-previous-button-label = Roimhe seo
+pdfjs-find-next-button =
+ .title = Aimsigh an chéad sampla eile den nath sin
+pdfjs-find-next-button-label = Ar aghaidh
+pdfjs-find-highlight-checkbox = Aibhsigh uile
+pdfjs-find-match-case-checkbox-label = CásÃogair
+pdfjs-find-entire-word-checkbox-label = Focail iomlána
+pdfjs-find-reached-top = Ag barr na cáipéise, ag leanúint ón mbun
+pdfjs-find-reached-bottom = Ag bun na cáipéise, ag leanúint ón mbarr
+pdfjs-find-not-found = Frása gan aimsiú
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Leithead Leathanaigh
+pdfjs-page-scale-fit = Laghdaigh go dtà an Leathanach
+pdfjs-page-scale-auto = Súmáil UathoibrÃoch
+pdfjs-page-scale-actual = FÃormhéid
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Tharla earráid agus an cháipéis PDF á lódáil.
+pdfjs-invalid-file-error = Comhad neamhbhailà nó truaillithe PDF.
+pdfjs-missing-file-error = Comhad PDF ar iarraidh.
+pdfjs-unexpected-response-error = Freagra ón bhfreastalaà nach rabhthas ag súil leis.
+pdfjs-rendering-error = Tharla earráid agus an leathanach á leagan amach.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anótáil { $type }]
+
+## Password
+
+pdfjs-password-label = Cuir an focal faire isteach chun an comhad PDF seo a oscailt.
+pdfjs-password-invalid = Focal faire mÃcheart. Déan iarracht eile.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cealaigh
+pdfjs-web-fonts-disabled = Tá clófhoirne Gréasáin dÃchumasaithe: nà féidir clófhoirne leabaithe PDF a úsáid.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/gd/viewer.ftl b/www/lib/pdfjs/modern/web/locale/gd/viewer.ftl
new file mode 100644
index 000000000..cc67391a1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/gd/viewer.ftl
@@ -0,0 +1,299 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = An duilleag roimhe
+pdfjs-previous-button-label = Air ais
+pdfjs-next-button =
+ .title = An ath-dhuilleag
+pdfjs-next-button-label = Air adhart
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Duilleag
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = Ã { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } Ã { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Sùm a-mach
+pdfjs-zoom-out-button-label = Sùm a-mach
+pdfjs-zoom-in-button =
+ .title = Sùm a-steach
+pdfjs-zoom-in-button-label = Sùm a-steach
+pdfjs-zoom-select =
+ .title = Sùm
+pdfjs-presentation-mode-button =
+ .title = Gearr leum dhan mhodh taisbeanaidh
+pdfjs-presentation-mode-button-label = Am modh taisbeanaidh
+pdfjs-open-file-button =
+ .title = Fosgail faidhle
+pdfjs-open-file-button-label = Fosgail
+pdfjs-print-button =
+ .title = Clò-bhuail
+pdfjs-print-button-label = Clò-bhuail
+pdfjs-save-button =
+ .title = SÃ bhail
+pdfjs-save-button-label = SÃ bhail
+pdfjs-bookmark-button =
+ .title = An duilleag là ithreach (Seall an URL on duilleag là ithreach)
+pdfjs-bookmark-button-label = An duilleag là ithreach
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Fosgail san aplacaid
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Fosgail san aplacaid
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Innealan
+pdfjs-tools-button-label = Innealan
+pdfjs-first-page-button =
+ .title = Rach gun chiad duilleag
+pdfjs-first-page-button-label = Rach gun chiad duilleag
+pdfjs-last-page-button =
+ .title = Rach gun duilleag mu dheireadh
+pdfjs-last-page-button-label = Rach gun duilleag mu dheireadh
+pdfjs-page-rotate-cw-button =
+ .title = Cuairtich gu deiseil
+pdfjs-page-rotate-cw-button-label = Cuairtich gu deiseil
+pdfjs-page-rotate-ccw-button =
+ .title = Cuairtich gu tuathail
+pdfjs-page-rotate-ccw-button-label = Cuairtich gu tuathail
+pdfjs-cursor-text-select-tool-button =
+ .title = Cuir an comas inneal taghadh an teacsa
+pdfjs-cursor-text-select-tool-button-label = Inneal taghadh an teacsa
+pdfjs-cursor-hand-tool-button =
+ .title = Cuir inneal na là imhe an comas
+pdfjs-cursor-hand-tool-button-label = Inneal na là imhe
+pdfjs-scroll-page-button =
+ .title = Cleachd sgroladh duilleige
+pdfjs-scroll-page-button-label = Sgroladh duilleige
+pdfjs-scroll-vertical-button =
+ .title = Cleachd sgroladh inghearach
+pdfjs-scroll-vertical-button-label = Sgroladh inghearach
+pdfjs-scroll-horizontal-button =
+ .title = Cleachd sgroladh còmhnard
+pdfjs-scroll-horizontal-button-label = Sgroladh còmhnard
+pdfjs-scroll-wrapped-button =
+ .title = Cleachd sgroladh paisgte
+pdfjs-scroll-wrapped-button-label = Sgroladh paisgte
+pdfjs-spread-none-button =
+ .title = Na cuir còmhla sgoileadh dhuilleagan
+pdfjs-spread-none-button-label = Gun sgaoileadh dhuilleagan
+pdfjs-spread-odd-button =
+ .title = Cuir còmhla duilleagan sgaoilte a thòisicheas le duilleagan aig a bheil à ireamh chorr
+pdfjs-spread-odd-button-label = Sgaoileadh dhuilleagan corra
+pdfjs-spread-even-button =
+ .title = Cuir còmhla duilleagan sgaoilte a thòisicheas le duilleagan aig a bheil à ireamh chothrom
+pdfjs-spread-even-button-label = Sgaoileadh dhuilleagan cothrom
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Roghainnean na sgrìobhainne…
+pdfjs-document-properties-button-label = Roghainnean na sgrìobhainne…
+pdfjs-document-properties-file-name = Ainm an fhaidhle:
+pdfjs-document-properties-file-size = Meud an fhaidhle:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Tiotal:
+pdfjs-document-properties-author = Ùghdar:
+pdfjs-document-properties-subject = Cuspair:
+pdfjs-document-properties-keywords = Faclan-luirg:
+pdfjs-document-properties-creation-date = Latha a chruthachaidh:
+pdfjs-document-properties-modification-date = Latha atharrachaidh:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Cruthadair:
+pdfjs-document-properties-producer = Saothraiche a' PDF:
+pdfjs-document-properties-version = Tionndadh a' PDF:
+pdfjs-document-properties-page-count = Àireamh de dhuilleagan:
+pdfjs-document-properties-page-size = Meud na duilleige:
+pdfjs-document-properties-page-size-unit-inches = ann an
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portraid
+pdfjs-document-properties-page-size-orientation-landscape = dreach-tìre
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Litir
+pdfjs-document-properties-page-size-name-legal = Laghail
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Grad shealladh-lìn:
+pdfjs-document-properties-linearized-yes = Tha
+pdfjs-document-properties-linearized-no = Chan eil
+pdfjs-document-properties-close-button = Dùin
+
+## Print
+
+pdfjs-print-progress-message = Ag ullachadh na sgrìobhainn airson clò-bhualadh…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Sguir dheth
+pdfjs-printing-not-supported = Rabhadh: Chan eil am brabhsair seo a' cur là n-taic ri clò-bhualadh.
+pdfjs-printing-not-ready = Rabhadh: Cha deach am PDF a luchdadh gu tur airson clò-bhualadh.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toglaich am bà r-taoibh
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toglaich am bà r-taoibh (tha oir-loidhne/ceanglachain/breathan aig an sgrìobhainn)
+pdfjs-toggle-sidebar-button-label = Toglaich am bà r-taoibh
+pdfjs-document-outline-button =
+ .title = Seall oir-loidhne na sgrìobhainn (dèan briogadh dùbailte airson a h-uile nì a leudachadh/a cho-theannadh)
+pdfjs-document-outline-button-label = Oir-loidhne na sgrìobhainne
+pdfjs-attachments-button =
+ .title = Seall na ceanglachain
+pdfjs-attachments-button-label = Ceanglachain
+pdfjs-layers-button =
+ .title = Seall na breathan (dèan briogadh dùbailte airson a h-uile breath ath-shuidheachadh dhan staid bhunaiteach)
+pdfjs-layers-button-label = Breathan
+pdfjs-thumbs-button =
+ .title = Seall na dealbhagan
+pdfjs-thumbs-button-label = Dealbhagan
+pdfjs-current-outline-item-button =
+ .title = Lorg nì là ithreach na h-oir-loidhne
+pdfjs-current-outline-item-button-label = Nì là ithreach na h-oir-loidhne
+pdfjs-findbar-button =
+ .title = Lorg san sgrìobhainn
+pdfjs-findbar-button-label = Lorg
+pdfjs-additional-layers = Barrachd breathan
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Duilleag a { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Dealbhag duilleag a { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Lorg
+ .placeholder = Lorg san sgrìobhainn...
+pdfjs-find-previous-button =
+ .title = Lorg là thair roimhe na h-abairt seo
+pdfjs-find-previous-button-label = Air ais
+pdfjs-find-next-button =
+ .title = Lorg ath-là thair na h-abairt seo
+pdfjs-find-next-button-label = Air adhart
+pdfjs-find-highlight-checkbox = Soillsich a h-uile
+pdfjs-find-match-case-checkbox-label = Aire do litrichean mòra is beaga
+pdfjs-find-match-diacritics-checkbox-label = Aire do strà can
+pdfjs-find-entire-word-checkbox-label = Faclan-slà na
+pdfjs-find-reached-top = RÃ inig sinn barr na duilleige, a' leantainn air adhart o bhonn na duilleige
+pdfjs-find-reached-bottom = RÃ inig sinn bonn na duilleige, a' leantainn air adhart o bharr na duilleige
+pdfjs-find-not-found = Cha deach an abairt a lorg
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Leud na duilleige
+pdfjs-page-scale-fit = Freagair ri meud na duilleige
+pdfjs-page-scale-auto = Sùm fèin-obrachail
+pdfjs-page-scale-actual = Am fìor-mheud
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Duilleag { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Thachair mearachd rè luchdadh a' PDF.
+pdfjs-invalid-file-error = Faidhle PDF a tha mì-dhligheach no coirbte.
+pdfjs-missing-file-error = Faidhle PDF a tha a dhìth.
+pdfjs-unexpected-response-error = Freagairt on fhrithealaiche ris nach robh dùil.
+pdfjs-rendering-error = Thachair mearachd rè reandaradh na duilleige.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Nòtachadh { $type }]
+
+## Password
+
+pdfjs-password-label = Cuir a-steach am facal-faire gus am faidhle PDF seo fhosgladh.
+pdfjs-password-invalid = Tha am facal-faire cearr. Nach fheuch thu ris a-rithist?
+pdfjs-password-ok-button = Ceart ma-thÃ
+pdfjs-password-cancel-button = Sguir dheth
+pdfjs-web-fonts-disabled = Tha cruthan-clò lìn à comas: Chan urrainn dhuinn cruthan-clò PDF leabaichte a chleachdadh.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Teacsa
+pdfjs-editor-free-text-button-label = Teacsa
+pdfjs-editor-ink-button =
+ .title = Tarraing
+pdfjs-editor-ink-button-label = Tarraing
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Dath
+pdfjs-editor-free-text-size-input = Meud
+pdfjs-editor-ink-color-input = Dath
+pdfjs-editor-ink-thickness-input = Tighead
+pdfjs-editor-ink-opacity-input = Trìd-dhoilleireachd
+pdfjs-free-text =
+ .aria-label = An deasaiche teacsa
+pdfjs-free-text-default-content = Tòisich air sgrìobhadh…
+pdfjs-ink =
+ .aria-label = An deasaiche tharraingean
+pdfjs-ink-canvas =
+ .aria-label = Dealbh a chruthaich cleachdaiche
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/gl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/gl/viewer.ftl
new file mode 100644
index 000000000..1b732fd4c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/gl/viewer.ftl
@@ -0,0 +1,347 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Páxina anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Seguinte páxina
+pdfjs-next-button-label = Seguinte
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Páxina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Reducir
+pdfjs-zoom-out-button-label = Reducir
+pdfjs-zoom-in-button =
+ .title = Ampliar
+pdfjs-zoom-in-button-label = Ampliar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Cambiar ao modo presentación
+pdfjs-presentation-mode-button-label = Modo presentación
+pdfjs-open-file-button =
+ .title = Abrir ficheiro
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Gardar
+pdfjs-save-button-label = Gardar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Descargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Descargar
+pdfjs-bookmark-button =
+ .title = Páxina actual (ver o URL da páxina actual)
+pdfjs-bookmark-button-label = Páxina actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir cunha aplicación
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir cunha aplicación
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ferramentas
+pdfjs-tools-button-label = Ferramentas
+pdfjs-first-page-button =
+ .title = Ir á primeira páxina
+pdfjs-first-page-button-label = Ir á primeira páxina
+pdfjs-last-page-button =
+ .title = Ir á última páxina
+pdfjs-last-page-button-label = Ir á última páxina
+pdfjs-page-rotate-cw-button =
+ .title = Rotar no sentido das agullas do reloxo
+pdfjs-page-rotate-cw-button-label = Rotar no sentido das agullas do reloxo
+pdfjs-page-rotate-ccw-button =
+ .title = Rotar no sentido contrario ás agullas do reloxo
+pdfjs-page-rotate-ccw-button-label = Rotar no sentido contrario ás agullas do reloxo
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar a ferramenta de selección de texto
+pdfjs-cursor-text-select-tool-button-label = Ferramenta de selección de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar a ferramenta de man
+pdfjs-cursor-hand-tool-button-label = Ferramenta de man
+pdfjs-scroll-page-button =
+ .title = Usar o desprazamento da páxina
+pdfjs-scroll-page-button-label = Desprazamento da páxina
+pdfjs-scroll-vertical-button =
+ .title = Usar o desprazamento vertical
+pdfjs-scroll-vertical-button-label = Desprazamento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar o desprazamento horizontal
+pdfjs-scroll-horizontal-button-label = Desprazamento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar o desprazamento en bloque
+pdfjs-scroll-wrapped-button-label = Desprazamento por bloque
+pdfjs-spread-none-button =
+ .title = Non agrupar páxinas
+pdfjs-spread-none-button-label = Ningún agrupamento
+pdfjs-spread-odd-button =
+ .title = Crea grupo de páxinas que comezan con números de páxina impares
+pdfjs-spread-odd-button-label = Agrupamento impar
+pdfjs-spread-even-button =
+ .title = Crea grupo de páxinas que comezan con números de páxina pares
+pdfjs-spread-even-button-label = Agrupamento par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades do documento…
+pdfjs-document-properties-button-label = Propiedades do documento…
+pdfjs-document-properties-file-name = Nome do ficheiro:
+pdfjs-document-properties-file-size = Tamaño do ficheiro:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Asunto:
+pdfjs-document-properties-keywords = Palabras clave:
+pdfjs-document-properties-creation-date = Data de creación:
+pdfjs-document-properties-modification-date = Data de modificación:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creado por:
+pdfjs-document-properties-producer = Xenerador do PDF:
+pdfjs-document-properties-version = Versión de PDF:
+pdfjs-document-properties-page-count = Número de páxinas:
+pdfjs-document-properties-page-size = Tamaño da páxina:
+pdfjs-document-properties-page-size-unit-inches = pol
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Visualización rápida das páxinas web:
+pdfjs-document-properties-linearized-yes = Si
+pdfjs-document-properties-linearized-no = Non
+pdfjs-document-properties-close-button = Pechar
+
+## Print
+
+pdfjs-print-progress-message = Preparando o documento para imprimir…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Aviso: A impresión non é compatÃbel de todo con este navegador.
+pdfjs-printing-not-ready = Aviso: O PDF non se cargou completamente para imprimirse.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Amosar/agochar a barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Alternar barra lateral (o documento contén esquema/anexos/capas)
+pdfjs-toggle-sidebar-button-label = Amosar/agochar a barra lateral
+pdfjs-document-outline-button =
+ .title = Amosar a estrutura do documento (dobre clic para expandir/contraer todos os elementos)
+pdfjs-document-outline-button-label = Estrutura do documento
+pdfjs-attachments-button =
+ .title = Amosar anexos
+pdfjs-attachments-button-label = Anexos
+pdfjs-layers-button =
+ .title = Mostrar capas (prema dúas veces para restaurar todas as capas o estado predeterminado)
+pdfjs-layers-button-label = Capas
+pdfjs-thumbs-button =
+ .title = Amosar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Atopar o elemento delimitado actualmente
+pdfjs-current-outline-item-button-label = Elemento delimitado actualmente
+pdfjs-findbar-button =
+ .title = Atopar no documento
+pdfjs-findbar-button-label = Atopar
+pdfjs-additional-layers = Capas adicionais
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Páxina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura da páxina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Atopar
+ .placeholder = Atopar no documento…
+pdfjs-find-previous-button =
+ .title = Atopar a anterior aparición da frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Atopar a seguinte aparición da frase
+pdfjs-find-next-button-label = Seguinte
+pdfjs-find-highlight-checkbox = Realzar todo
+pdfjs-find-match-case-checkbox-label = Diferenciar maiúsculas de minúsculas
+pdfjs-find-match-diacritics-checkbox-label = Distinguir os diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palabras completas
+pdfjs-find-reached-top = Chegouse ao inicio do documento, continuar desde o final
+pdfjs-find-reached-bottom = Chegouse ao final do documento, continuar desde o inicio
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] Coincidencia { $current } de { $total }
+ *[other] Coincidencia { $current } de { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Máis de { $limit } coincidencia
+ *[other] Máis de { $limit } coincidencias
+ }
+pdfjs-find-not-found = Non se atopou a frase
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Largura da páxina
+pdfjs-page-scale-fit = Axuste de páxina
+pdfjs-page-scale-auto = Zoom automático
+pdfjs-page-scale-actual = Tamaño actual
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Páxina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Produciuse un erro ao cargar o PDF.
+pdfjs-invalid-file-error = Ficheiro PDF danado ou non válido.
+pdfjs-missing-file-error = Falta o ficheiro PDF.
+pdfjs-unexpected-response-error = Resposta inesperada do servidor.
+pdfjs-rendering-error = Produciuse un erro ao representar a páxina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotación { $type }]
+
+## Password
+
+pdfjs-password-label = Escriba o contrasinal para abrir este ficheiro PDF.
+pdfjs-password-invalid = Contrasinal incorrecto. Tente de novo.
+pdfjs-password-ok-button = Aceptar
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = Desactiváronse as fontes web: foi imposÃbel usar as fontes incrustadas no PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Debuxo
+pdfjs-editor-ink-button-label = Debuxo
+pdfjs-editor-stamp-button =
+ .title = Engadir ou editar imaxes
+pdfjs-editor-stamp-button-label = Engadir ou editar imaxes
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Cor
+pdfjs-editor-free-text-size-input = Tamaño
+pdfjs-editor-ink-color-input = Cor
+pdfjs-editor-ink-thickness-input = Grosor
+pdfjs-editor-ink-opacity-input = Opacidade
+pdfjs-editor-stamp-add-image-button =
+ .title = Engadir imaxe
+pdfjs-editor-stamp-add-image-button-label = Engadir imaxe
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Comezar a teclear…
+pdfjs-ink =
+ .aria-label = Editor de debuxos
+pdfjs-ink-canvas =
+ .aria-label = Imaxe creada por unha usuaria
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar o texto alternativo
+pdfjs-editor-alt-text-dialog-label = Escoller unha opción
+pdfjs-editor-alt-text-add-description-label = Engadir unha descrición
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativo
+pdfjs-editor-alt-text-mark-decorative-description = UtilÃzase para imaxes ornamentais, como bordos ou marcas de auga.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Gardar
+pdfjs-editor-alt-text-decorative-tooltip = Marcado como decorativo
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por exemplo, «Un mozo séntase á mesa para comer»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Esquina superior esquerda: cambia o tamaño
+pdfjs-editor-resizer-label-top-middle = Medio superior: cambia o tamaño
+pdfjs-editor-resizer-label-top-right = Esquina superior dereita: cambia o tamaño
+pdfjs-editor-resizer-label-middle-right = Medio dereito: cambia o tamaño
+pdfjs-editor-resizer-label-bottom-right = Esquina inferior dereita: cambia o tamaño
+pdfjs-editor-resizer-label-bottom-middle = Abaixo medio: cambia o tamaño
+pdfjs-editor-resizer-label-bottom-left = Esquina inferior esquerda: cambia o tamaño
+pdfjs-editor-resizer-label-middle-left = Medio esquerdo: cambia o tamaño
diff --git a/www/lib/pdfjs/modern/web/locale/gn/viewer.ftl b/www/lib/pdfjs/modern/web/locale/gn/viewer.ftl
new file mode 100644
index 000000000..238cd2427
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/gn/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Kuatiarogue mboyvegua
+pdfjs-previous-button-label = Mboyvegua
+pdfjs-next-button =
+ .title = Kuatiarogue upeigua
+pdfjs-next-button-label = Upeigua
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Kuatiarogue
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } gui
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Momichĩ
+pdfjs-zoom-out-button-label = Momichĩ
+pdfjs-zoom-in-button =
+ .title = Mbotuicha
+pdfjs-zoom-in-button-label = Mbotuicha
+pdfjs-zoom-select =
+ .title = Tuichakue
+pdfjs-presentation-mode-button =
+ .title = Jehechauka reko moambue
+pdfjs-presentation-mode-button-label = Jehechauka reko
+pdfjs-open-file-button =
+ .title = Marandurendápe jeike
+pdfjs-open-file-button-label = Jeike
+pdfjs-print-button =
+ .title = Monguatia
+pdfjs-print-button-label = Monguatia
+pdfjs-save-button =
+ .title = Ñongatu
+pdfjs-save-button-label = Ñongatu
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Mboguejy
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Mboguejy
+pdfjs-bookmark-button =
+ .title = Kuatiarogue ag̃agua (Ehecha URL kuatiarogue ag̃agua)
+pdfjs-bookmark-button-label = Kuatiarogue Ag̃agua
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Embojuruja tembiporu’Ãpe
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Embojuruja tembiporu’Ãpe
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tembiporu
+pdfjs-tools-button-label = Tembiporu
+pdfjs-first-page-button =
+ .title = Kuatiarogue ñepyrũme jeho
+pdfjs-first-page-button-label = Kuatiarogue ñepyrũme jeho
+pdfjs-last-page-button =
+ .title = Kuatiarogue pahápe jeho
+pdfjs-last-page-button-label = Kuatiarogue pahápe jeho
+pdfjs-page-rotate-cw-button =
+ .title = Aravóicha mbojere
+pdfjs-page-rotate-cw-button-label = Aravóicha mbojere
+pdfjs-page-rotate-ccw-button =
+ .title = Aravo rapykue gotyo mbojere
+pdfjs-page-rotate-ccw-button-label = Aravo rapykue gotyo mbojere
+pdfjs-cursor-text-select-tool-button =
+ .title = Emyandy moñe’ẽrã jeporavo rembiporu
+pdfjs-cursor-text-select-tool-button-label = Moñe’ẽrã jeporavo rembiporu
+pdfjs-cursor-hand-tool-button =
+ .title = Tembiporu po pegua myandy
+pdfjs-cursor-hand-tool-button-label = Tembiporu po pegua
+pdfjs-scroll-page-button =
+ .title = Eiporu kuatiarogue jeku’e
+pdfjs-scroll-page-button-label = Kuatiarogue jeku’e
+pdfjs-scroll-vertical-button =
+ .title = Eiporu jeku’e ykeguáva
+pdfjs-scroll-vertical-button-label = Jeku’e ykeguáva
+pdfjs-scroll-horizontal-button =
+ .title = Eiporu jeku’e yvate gotyo
+pdfjs-scroll-horizontal-button-label = Jeku’e yvate gotyo
+pdfjs-scroll-wrapped-button =
+ .title = Eiporu jeku’e mbohyrupyre
+pdfjs-scroll-wrapped-button-label = Jeku’e mbohyrupyre
+pdfjs-spread-none-button =
+ .title = Ani ejuaju spreads kuatiarogue ndive
+pdfjs-spread-none-button-label = Spreads ỹre
+pdfjs-spread-odd-button =
+ .title = Embojuaju kuatiarogue jepysokue eñepyrũvo kuatiarogue impar-vagui
+pdfjs-spread-odd-button-label = Spreads impar
+pdfjs-spread-even-button =
+ .title = Embojuaju kuatiarogue jepysokue eñepyrũvo kuatiarogue par-vagui
+pdfjs-spread-even-button-label = Ipukuve uvei
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Kuatia mba’etee…
+pdfjs-document-properties-button-label = Kuatia mba’etee…
+pdfjs-document-properties-file-name = Marandurenda réra:
+pdfjs-document-properties-file-size = Marandurenda tuichakue:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Teratee:
+pdfjs-document-properties-author = Apohára:
+pdfjs-document-properties-subject = Mba’egua:
+pdfjs-document-properties-keywords = Jehero:
+pdfjs-document-properties-creation-date = Teñoihague arange:
+pdfjs-document-properties-modification-date = Iñambue hague arange:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Apo’ypyha:
+pdfjs-document-properties-producer = PDF mbosako’iha:
+pdfjs-document-properties-version = PDF mbojuehegua:
+pdfjs-document-properties-page-count = Kuatiarogue papapy:
+pdfjs-document-properties-page-size = Kuatiarogue tuichakue:
+pdfjs-document-properties-page-size-unit-inches = Amo
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = Oĩháicha
+pdfjs-document-properties-page-size-orientation-landscape = apaisado
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Kuatiañe’ẽ
+pdfjs-document-properties-page-size-name-legal = Tee
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Ñanduti jahecha pya’e:
+pdfjs-document-properties-linearized-yes = Añete
+pdfjs-document-properties-linearized-no = Ahániri
+pdfjs-document-properties-close-button = Mboty
+
+## Print
+
+pdfjs-print-progress-message = Embosako’i kuatia emonguatia hag̃ua…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Heja
+pdfjs-printing-not-supported = Kyhyjerã: Ñembokuatia ndojokupytypái ko kundahára ndive.
+pdfjs-printing-not-ready = Kyhyjerã: Ko PDF nahenyhẽmbái oñembokuatia hag̃uáicha.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Tenda yke moambue
+pdfjs-toggle-sidebar-notification-button =
+ .title = Embojopyru tenda ykegua (kuatia oguereko kuaakaha/moirũha/ñuãha)
+pdfjs-toggle-sidebar-button-label = Tenda yke moambue
+pdfjs-document-outline-button =
+ .title = Ehechauka kuatia rape (eikutu mokõi jey embotuicha/emomichĩ hag̃ua opavavete mba’eporu)
+pdfjs-document-outline-button-label = Kuatia apopyre
+pdfjs-attachments-button =
+ .title = Moirũha jehechauka
+pdfjs-attachments-button-label = Moirũha
+pdfjs-layers-button =
+ .title = Ehechauka ñuãha (eikutu jo’a emomba’apo hag̃ua opaite ñuãha tekoypýpe)
+pdfjs-layers-button-label = Ñuãha
+pdfjs-thumbs-button =
+ .title = Mba’emirĩ jehechauka
+pdfjs-thumbs-button-label = Mba’emirĩ
+pdfjs-current-outline-item-button =
+ .title = Eheka mba’eporu ag̃aguaitéva
+pdfjs-current-outline-item-button-label = Mba’eporu ag̃aguaitéva
+pdfjs-findbar-button =
+ .title = Kuatiápe jeheka
+pdfjs-findbar-button-label = Juhu
+pdfjs-additional-layers = Ñuãha moirũguáva
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Kuatiarogue { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Kuatiarogue mba’emirĩ { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Juhu
+ .placeholder = Kuatiápe jejuhu…
+pdfjs-find-previous-button =
+ .title = Ejuhu ñe’ẽrysýi osẽ’ypy hague
+pdfjs-find-previous-button-label = Mboyvegua
+pdfjs-find-next-button =
+ .title = Eho ñe’ẽ juhupyre upeiguávape
+pdfjs-find-next-button-label = Upeigua
+pdfjs-find-highlight-checkbox = Embojekuaavepa
+pdfjs-find-match-case-checkbox-label = Ejesareko taiguasu/taimichĩre
+pdfjs-find-match-diacritics-checkbox-label = DiacrÃtico moñondive
+pdfjs-find-entire-word-checkbox-label = Ñe’ẽ oĩmbáva
+pdfjs-find-reached-top = Ojehupyty kuatia ñepyrũ, oku’ejeýta kuatia paha guive
+pdfjs-find-reached-bottom = Ojehupyty kuatia paha, oku’ejeýta kuatia ñepyrũ guive
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } ha { $total } ojueheguáva
+ *[other] { $current } ha { $total } ojueheguáva
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Hetave { $limit } ojueheguáva
+ *[other] Hetave { $limit } ojueheguáva
+ }
+pdfjs-find-not-found = Ñe’ẽrysýi ojejuhu’ỹva
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Kuatiarogue pekue
+pdfjs-page-scale-fit = Kuatiarogue ñemoĩporã
+pdfjs-page-scale-auto = Tuichakue ijeheguÃva
+pdfjs-page-scale-actual = Tuichakue ag̃agua
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Kuatiarogue { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Oiko jejavy PDF oñemyeñyhẽnguévo.
+pdfjs-invalid-file-error = PDF marandurenda ndoikóiva térã ivaipyréva.
+pdfjs-missing-file-error = Ndaipóri PDF marandurenda
+pdfjs-unexpected-response-error = Mohendahavusu mbohovái eha’ãrõ’ỹva.
+pdfjs-rendering-error = Oiko jejavy ehechaukasévo kuatiarogue.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Jehaipy { $type }]
+
+## Password
+
+pdfjs-password-label = Emoinge ñe’ẽñemi eipe’a hag̃ua ko marandurenda PDF.
+pdfjs-password-invalid = Ñe’ẽñemi ndoikóiva. Eha’ã jey.
+pdfjs-password-ok-button = MONEĨ
+pdfjs-password-cancel-button = Heja
+pdfjs-web-fonts-disabled = Ñanduti taity oñemongéma: ndaikatumo’ãi eiporu PDF jehai’Ãva taity.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Moñe’ẽrã
+pdfjs-editor-free-text-button-label = Moñe’ẽrã
+pdfjs-editor-ink-button =
+ .title = Moha’ãnga
+pdfjs-editor-ink-button-label = Moha’ãnga
+pdfjs-editor-stamp-button =
+ .title = Embojuaju térã embosako’i ta’ãnga
+pdfjs-editor-stamp-button-label = Embojuaju térã embosako’i ta’ãnga
+pdfjs-editor-remove-button =
+ .title = Mboguete
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Emboguete ta’ãnga
+pdfjs-editor-remove-freetext-button =
+ .title = Emboguete moñe’ẽrã
+pdfjs-editor-remove-stamp-button =
+ .title = Emboguete ta’ãnga
+pdfjs-editor-remove-highlight-button =
+ .title = Eipe’a jehechaveha
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Sa’y
+pdfjs-editor-free-text-size-input = Tuichakue
+pdfjs-editor-ink-color-input = Sa’y
+pdfjs-editor-ink-thickness-input = Anambusu
+pdfjs-editor-ink-opacity-input = Pytũngy
+pdfjs-editor-stamp-add-image-button =
+ .title = Embojuaju ta’ãnga
+pdfjs-editor-stamp-add-image-button-label = Embojuaju ta’ãnga
+pdfjs-free-text =
+ .aria-label = Moñe’ẽrã moheñoiha
+pdfjs-free-text-default-content = Ehai ñepyrũ…
+pdfjs-ink =
+ .aria-label = Ta’ãnga moheñoiha
+pdfjs-ink-canvas =
+ .aria-label = Ta’ãnga omoheñóiva poruhára
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Moñe’ẽrã mokõiháva
+pdfjs-editor-alt-text-edit-button-label = Embojuruja moñe’ẽrã mokõiháva
+pdfjs-editor-alt-text-dialog-label = Eiporavo poravorã
+pdfjs-editor-alt-text-dialog-description = Moñe’ẽrã ykepegua (moñe’ẽrã ykepegua) nepytyvõ nderehecháiramo ta’ãnga térã nahenyhẽiramo.
+pdfjs-editor-alt-text-add-description-label = Embojuaju ñemoha’ãnga
+pdfjs-editor-alt-text-add-description-description = Ehaimi 1 térã 2 ñe’ẽjuaju oñe’ẽva pe téma rehe, ijere térã mba’eapóre.
+pdfjs-editor-alt-text-mark-decorative-label = Emongurusu jeguakárõ
+pdfjs-editor-alt-text-mark-decorative-description = Ojeporu ta’ãnga jeguakarã, tembe’y térã ta’ãnga ruguarãramo.
+pdfjs-editor-alt-text-cancel-button = Heja
+pdfjs-editor-alt-text-save-button = Ñongatu
+pdfjs-editor-alt-text-decorative-tooltip = Jeguakárõ mongurusupyre
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Techapyrã: “PeteÄ© mitãrusu oguapy mesápe okaru hag̃uaâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Yvate asu gotyo — emoambue tuichakue
+pdfjs-editor-resizer-label-top-middle = Yvate mbytépe — emoambue tuichakue
+pdfjs-editor-resizer-label-top-right = Yvate akatúape — emoambue tuichakue
+pdfjs-editor-resizer-label-middle-right = Mbyte akatúape — emoambue tuichakue
+pdfjs-editor-resizer-label-bottom-right = Yvy gotyo akatúape — emoambue tuichakue
+pdfjs-editor-resizer-label-bottom-middle = Yvy gotyo mbytépe — emoambue tuichakue
+pdfjs-editor-resizer-label-bottom-left = Iguýpe asu gotyo — emoambue tuichakue
+pdfjs-editor-resizer-label-middle-left = Mbyte asu gotyo — emoambue tuichakue
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Jehechaveha sa’y
+pdfjs-editor-colorpicker-button =
+ .title = Emoambue sa’y
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Sa’y poravopyrã
+pdfjs-editor-colorpicker-yellow =
+ .title = Sa’yju
+pdfjs-editor-colorpicker-green =
+ .title = Hovyũ
+pdfjs-editor-colorpicker-blue =
+ .title = Hovy
+pdfjs-editor-colorpicker-pink =
+ .title = Pytãngy
+pdfjs-editor-colorpicker-red =
+ .title = Pyha
diff --git a/www/lib/pdfjs/modern/web/locale/gu-IN/viewer.ftl b/www/lib/pdfjs/modern/web/locale/gu-IN/viewer.ftl
new file mode 100644
index 000000000..5d8bb549f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/gu-IN/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = પહેલાનૠપાનà«àª‚
+pdfjs-previous-button-label = પહેલાનà«
+pdfjs-next-button =
+ .title = આગળનૠપાનà«àª‚
+pdfjs-next-button-label = આગળનà«àª‚
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = પાનà«àª‚
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = નો { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } નો { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = મોટૠકરો
+pdfjs-zoom-out-button-label = મોટૠકરો
+pdfjs-zoom-in-button =
+ .title = નાનà«àª‚ કરો
+pdfjs-zoom-in-button-label = નાનà«àª‚ કરો
+pdfjs-zoom-select =
+ .title = નાનà«àª‚ મોટૠકરો
+pdfjs-presentation-mode-button =
+ .title = રજૂઆત સà«àª¥àª¿àª¤àª¿àª®àª¾àª‚ જાવ
+pdfjs-presentation-mode-button-label = રજૂઆત સà«àª¥àª¿àª¤àª¿
+pdfjs-open-file-button =
+ .title = ફાઇલ ખોલો
+pdfjs-open-file-button-label = ખોલો
+pdfjs-print-button =
+ .title = છાપો
+pdfjs-print-button-label = છારો
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = સાધનો
+pdfjs-tools-button-label = સાધનો
+pdfjs-first-page-button =
+ .title = પહેલાં પાનામાં જાવ
+pdfjs-first-page-button-label = પà«àª°àª¥àª® પાનાં પર જાવ
+pdfjs-last-page-button =
+ .title = છેલà«àª²àª¾ પાનાં પર જાવ
+pdfjs-last-page-button-label = છેલà«àª²àª¾ પાનાં પર જાવ
+pdfjs-page-rotate-cw-button =
+ .title = ઘડિયાળનાં કાંટા તરફ ફેરવો
+pdfjs-page-rotate-cw-button-label = ઘડિયાળનાં કાંટા તરફ ફેરવો
+pdfjs-page-rotate-ccw-button =
+ .title = ઘડિયાળનાં કાંટાની ઉલટી દિશામાં ફેરવો
+pdfjs-page-rotate-ccw-button-label = ઘડિયાળનાં કાંટાની વિરà«àª¦à«àª¦ ફેરવો
+pdfjs-cursor-text-select-tool-button =
+ .title = ટેકà«àª¸à«àªŸ પસંદગી ટૂલ સકà«àª·àª® કરો
+pdfjs-cursor-text-select-tool-button-label = ટેકà«àª¸à«àªŸ પસંદગી ટૂલ
+pdfjs-cursor-hand-tool-button =
+ .title = હાથનાં સાધનને સકà«àª°àª¿àª¯ કરો
+pdfjs-cursor-hand-tool-button-label = હેનà«àª¡ ટૂલ
+pdfjs-scroll-vertical-button =
+ .title = ઊàªà«€ સà«àª•à«àª°à«‹àª²àª¿àª‚ગનો ઉપયોગ કરો
+pdfjs-scroll-vertical-button-label = ઊàªà«€ સà«àª•à«àª°à«‹àª²àª¿àª‚ગ
+pdfjs-scroll-horizontal-button =
+ .title = આડી સà«àª•à«àª°à«‹àª²àª¿àª‚ગનો ઉપયોગ કરો
+pdfjs-scroll-horizontal-button-label = આડી સà«àª•à«àª°à«‹àª²àª¿àª‚ગ
+pdfjs-scroll-wrapped-button =
+ .title = આવરિત સà«àª•à«àª°à«‹àª²àª¿àª‚ગનો ઉપયોગ કરો
+pdfjs-scroll-wrapped-button-label = આવરિત સà«àª•à«àª°à«‹àª²àª¿àª‚ગ
+pdfjs-spread-none-button =
+ .title = પૃષà«àª સà«àªªà«àª°à«‡àª¡àª®àª¾àª‚ જોડાવશો નહીં
+pdfjs-spread-none-button-label = કોઈ સà«àªªà«àª°à«‡àª¡ નથી
+pdfjs-spread-odd-button =
+ .title = àªàª•à«€-કà«àª°àª®àª¾àª‚કિત પૃષà«àª à«‹ સાથે પà«àª°àª¾àª°àª‚ઠથતાં પૃષà«àª સà«àªªà«àª°à«‡àª¡àª®àª¾àª‚ જોડાઓ
+pdfjs-spread-odd-button-label = àªàª•à«€ સà«àªªà«àª°à«‡àª¡à«àª¸
+pdfjs-spread-even-button =
+ .title = નંબર-કà«àª°àª®àª¾àª‚કિત પૃષà«àª ોથી શરૂ થતાં પૃષà«àª સà«àªªà«àª°à«‡àª¡àª®àª¾àª‚ જોડાઓ
+pdfjs-spread-even-button-label = સરખà«àª‚ ફેલાવવà«àª‚
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = દસà«àª¤àª¾àªµà«‡àªœ ગà«àª£àª§àª°à«àª®à«‹â€¦
+pdfjs-document-properties-button-label = દસà«àª¤àª¾àªµà«‡àªœ ગà«àª£àª§àª°à«àª®à«‹â€¦
+pdfjs-document-properties-file-name = ફાઇલ નામ:
+pdfjs-document-properties-file-size = ફાઇલ માપ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } બાઇટ)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } બાઇટ)
+pdfjs-document-properties-title = શીરà«àª·àª•:
+pdfjs-document-properties-author = લેખક:
+pdfjs-document-properties-subject = વિષય:
+pdfjs-document-properties-keywords = કિવરà«àª¡:
+pdfjs-document-properties-creation-date = નિરà«àª®àª¾àª£ તારીખ:
+pdfjs-document-properties-modification-date = ફેરફાર તારીખ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = નિરà«àª®àª¾àª¤àª¾:
+pdfjs-document-properties-producer = PDF નિરà«àª®àª¾àª¤àª¾:
+pdfjs-document-properties-version = PDF આવૃતà«àª¤àª¿:
+pdfjs-document-properties-page-count = પાનાં ગણતરી:
+pdfjs-document-properties-page-size = પૃષà«àª નà«àª‚ કદ:
+pdfjs-document-properties-page-size-unit-inches = ઇંચ
+pdfjs-document-properties-page-size-unit-millimeters = મીમી
+pdfjs-document-properties-page-size-orientation-portrait = ઉàªà«àª‚
+pdfjs-document-properties-page-size-orientation-landscape = આડà«
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = પતà«àª°
+pdfjs-document-properties-page-size-name-legal = કાયદાકીય
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = àªàª¡àªªà«€ વૅબ દૃશà«àª¯:
+pdfjs-document-properties-linearized-yes = હા
+pdfjs-document-properties-linearized-no = ના
+pdfjs-document-properties-close-button = બંધ કરો
+
+## Print
+
+pdfjs-print-progress-message = છાપકામ માટે દસà«àª¤àª¾àªµà«‡àªœ તૈયાર કરી રહà«àª¯àª¾ છે…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = રદ કરો
+pdfjs-printing-not-supported = ચેતવણી: છાપવાનà«àª‚ આ બà«àª°àª¾àª‰àªàª° દà«àª¦àª¾àª°àª¾ સંપૂરà«àª£àªªàª£à«‡ આધારàªà«‚ત નથી.
+pdfjs-printing-not-ready = Warning: PDF ઠછાપવા માટે સંપૂરà«àª£àªªàª£à«‡ લાવેલ છે.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ટૉગલ બાજà«àªªàªŸà«àªŸà«€
+pdfjs-toggle-sidebar-button-label = ટૉગલ બાજà«àªªàªŸà«àªŸà«€
+pdfjs-document-outline-button =
+ .title = દસà«àª¤àª¾àªµà«‡àªœàª¨à«€ રૂપરેખા બતાવો(બધી આઇટમà«àª¸àª¨à«‡ વિસà«àª¤à«ƒàª¤/સંકà«àªšàª¿àª¤ કરવા માટે ડબલ-કà«àª²àª¿àª• કરો)
+pdfjs-document-outline-button-label = દસà«àª¤àª¾àªµà«‡àªœ રૂપરેખા
+pdfjs-attachments-button =
+ .title = જોડાણોને બતાવો
+pdfjs-attachments-button-label = જોડાણો
+pdfjs-thumbs-button =
+ .title = થંબનેલà«àª¸ બતાવો
+pdfjs-thumbs-button-label = થંબનેલà«àª¸
+pdfjs-findbar-button =
+ .title = દસà«àª¤àª¾àªµà«‡àªœàª®àª¾àª‚ શોધો
+pdfjs-findbar-button-label = શોધો
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = પાનà«àª‚ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = પાનાં { $page } નà«àª‚ થંબનેલà«àª¸
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = શોધો
+ .placeholder = દસà«àª¤àª¾àªµà«‡àªœàª®àª¾àª‚ શોધો…
+pdfjs-find-previous-button =
+ .title = શબà«àª¦àª¸àª®à«‚હની પાછલી ઘટનાને શોધો
+pdfjs-find-previous-button-label = પહેલાંનà«
+pdfjs-find-next-button =
+ .title = શબà«àª¦àª¸àª®à«‚હની આગળની ઘટનાને શોધો
+pdfjs-find-next-button-label = આગળનà«àª‚
+pdfjs-find-highlight-checkbox = બધૠપà«àª°àª•àª¾àª¶àª¿àª¤ કરો
+pdfjs-find-match-case-checkbox-label = કેસ બંધબેસાડો
+pdfjs-find-entire-word-checkbox-label = સંપૂરà«àª£ શબà«àª¦à«‹
+pdfjs-find-reached-top = દસà«àª¤àª¾àªµà«‡àªœàª¨àª¾àª‚ ટોચે પહોંચી ગયા, તળિયેથી ચાલૠકરેલ હતà«
+pdfjs-find-reached-bottom = દસà«àª¤àª¾àªµà«‡àªœàª¨àª¾àª‚ અંતે પહોંચી ગયા, ઉપરથી ચાલૠકરેલ હતà«
+pdfjs-find-not-found = શબà«àª¦àª¸àª®à«‚હ મળà«àª¯à« નથી
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = પાનાની પહોળાઇ
+pdfjs-page-scale-fit = પાનà«àª‚ બંધબેસતà«
+pdfjs-page-scale-auto = આપમેળે નાનà«àª‚મોટૠકરો
+pdfjs-page-scale-actual = ચોકà«àª•àª¸ માપ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = àªà«‚લ ઉદà«àªàªµà«€ જà«àª¯àª¾àª°à«‡ PDF ને લાવી રહà«àª¯àª¾ હોય.
+pdfjs-invalid-file-error = અયોગà«àª¯ અથવા àªàª¾àª‚ગેલ PDF ફાઇલ.
+pdfjs-missing-file-error = ગà«àª® થયેલ PDF ફાઇલ.
+pdfjs-unexpected-response-error = અનપેકà«àª·àª¿àª¤ સરà«àªµàª° પà«àª°àª¤àª¿àª¸àª¾àª¦.
+pdfjs-rendering-error = àªà«‚લ ઉદà«àªàªµà«€ જà«àª¯àª¾àª°à«‡ પાનાંનૠરેનà«àª¡ કરી રહà«àª¯àª¾ હોય.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = આ PDF ફાઇલને ખોલવા પાસવરà«àª¡àª¨à«‡ દાખલ કરો.
+pdfjs-password-invalid = અયોગà«àª¯ પાસવરà«àª¡. મહેરબાની કરીને ફરી પà«àª°àª¯àª¤à«àª¨ કરો.
+pdfjs-password-ok-button = બરાબર
+pdfjs-password-cancel-button = રદ કરો
+pdfjs-web-fonts-disabled = વેબ ફોનà«àªŸ નિષà«àª•à«àª°àª¿àª¯ થયેલ છે: àªàª®à«àª¬à«‡àª¡ થયેલ PDF ફોનà«àªŸàª¨à«‡ વાપરવાનà«àª‚ અસમરà«àª¥.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/he/viewer.ftl b/www/lib/pdfjs/modern/web/locale/he/viewer.ftl
new file mode 100644
index 000000000..16ad86a4a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/he/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = דף קוד×
+pdfjs-previous-button-label = קוד×
+pdfjs-next-button =
+ .title = דף הב×
+pdfjs-next-button-label = הב×
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = דף
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = מתוך { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } מתוך { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = התרחקות
+pdfjs-zoom-out-button-label = התרחקות
+pdfjs-zoom-in-button =
+ .title = התקרבות
+pdfjs-zoom-in-button-label = התקרבות
+pdfjs-zoom-select =
+ .title = מרחק מתצוגה
+pdfjs-presentation-mode-button =
+ .title = מעבר למצב מצגת
+pdfjs-presentation-mode-button-label = מצב מצגת
+pdfjs-open-file-button =
+ .title = פתיחת קובץ
+pdfjs-open-file-button-label = פתיחה
+pdfjs-print-button =
+ .title = הדפסה
+pdfjs-print-button-label = הדפסה
+pdfjs-save-button =
+ .title = שמירה
+pdfjs-save-button-label = שמירה
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = הורדה
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = הורדה
+pdfjs-bookmark-button =
+ .title = עמוד × ×•×›×—×™ (הצגת כתובת ×”×תר מהעמוד ×”× ×•×›×—×™)
+pdfjs-bookmark-button-label = עמוד × ×•×›×—×™
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = פתיחה ביישו×
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = פתיחה ביישו×
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = כלי×
+pdfjs-tools-button-label = כלי×
+pdfjs-first-page-button =
+ .title = מעבר לעמוד הר×שון
+pdfjs-first-page-button-label = מעבר לעמוד הר×שון
+pdfjs-last-page-button =
+ .title = מעבר לעמוד ×”×חרון
+pdfjs-last-page-button-label = מעבר לעמוד ×”×חרון
+pdfjs-page-rotate-cw-button =
+ .title = הטיה ×¢× ×›×™×•×•×Ÿ השעון
+pdfjs-page-rotate-cw-button-label = הטיה ×¢× ×›×™×•×•×Ÿ השעון
+pdfjs-page-rotate-ccw-button =
+ .title = הטיה ×›× ×’×“ כיוון השעון
+pdfjs-page-rotate-ccw-button-label = הטיה ×›× ×’×“ כיוון השעון
+pdfjs-cursor-text-select-tool-button =
+ .title = הפעלת כלי בחירת טקסט
+pdfjs-cursor-text-select-tool-button-label = כלי בחירת טקסט
+pdfjs-cursor-hand-tool-button =
+ .title = הפעלת כלי היד
+pdfjs-cursor-hand-tool-button-label = כלי יד
+pdfjs-scroll-page-button =
+ .title = שימוש בגלילת עמוד
+pdfjs-scroll-page-button-label = גלילת עמוד
+pdfjs-scroll-vertical-button =
+ .title = שימוש בגלילה ×× ×›×™×ª
+pdfjs-scroll-vertical-button-label = גלילה ×× ×›×™×ª
+pdfjs-scroll-horizontal-button =
+ .title = שימוש בגלילה ×ופקית
+pdfjs-scroll-horizontal-button-label = גלילה ×ופקית
+pdfjs-scroll-wrapped-button =
+ .title = שימוש בגלילה רציפה
+pdfjs-scroll-wrapped-button-label = גלילה רציפה
+pdfjs-spread-none-button =
+ .title = ×œ× ×œ×¦×¨×£ מפתחי עמודי×
+pdfjs-spread-none-button-label = ×œ×œ× ×ž×¤×ª×—×™×
+pdfjs-spread-odd-button =
+ .title = צירוף מפתחי ×¢×ž×•×“×™× ×©×ž×ª×—×™×œ×™× ×‘×“×¤×™× ×¢× ×ž×¡×¤×¨×™× ×י־זוגיי×
+pdfjs-spread-odd-button-label = ×ž×¤×ª×—×™× ×י־זוגיי×
+pdfjs-spread-even-button =
+ .title = צירוף מפתחי ×¢×ž×•×“×™× ×©×ž×ª×—×™×œ×™× ×‘×“×¤×™× ×¢× ×ž×¡×¤×¨×™× ×–×•×’×™×™×
+pdfjs-spread-even-button-label = ×ž×¤×ª×—×™× ×–×•×’×™×™×
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = מ××¤×™×™× ×™ מסמך…
+pdfjs-document-properties-button-label = מ××¤×™×™× ×™ מסמך…
+pdfjs-document-properties-file-name = ×©× ×§×•×‘×¥:
+pdfjs-document-properties-file-size = גודל הקובץ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } ק״ב ({ $size_b } בתי×)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } מ״ב ({ $size_b } בתי×)
+pdfjs-document-properties-title = כותרת:
+pdfjs-document-properties-author = מחבר:
+pdfjs-document-properties-subject = × ×•×©×:
+pdfjs-document-properties-keywords = מילות מפתח:
+pdfjs-document-properties-creation-date = ת×ריך יצירה:
+pdfjs-document-properties-modification-date = ת×ריך ×©×™× ×•×™:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = יוצר:
+pdfjs-document-properties-producer = יצרן PDF:
+pdfjs-document-properties-version = גרסת PDF:
+pdfjs-document-properties-page-count = מספר דפי×:
+pdfjs-document-properties-page-size = גודל העמוד:
+pdfjs-document-properties-page-size-unit-inches = ××™× ×³
+pdfjs-document-properties-page-size-unit-millimeters = מ״מ
+pdfjs-document-properties-page-size-orientation-portrait = ל×ורך
+pdfjs-document-properties-page-size-orientation-landscape = לרוחב
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = מכתב
+pdfjs-document-properties-page-size-name-legal = דף משפטי
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = תצוגת דף מהירה:
+pdfjs-document-properties-linearized-yes = כן
+pdfjs-document-properties-linearized-no = ל×
+pdfjs-document-properties-close-button = סגירה
+
+## Print
+
+pdfjs-print-progress-message = מסמך ×‘×”×›× ×” להדפסה…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ביטול
+pdfjs-printing-not-supported = ×זהרה: הדפסה ××™× ×” × ×ª×ž×›×ª במלו××” בדפדפן ×–×”.
+pdfjs-printing-not-ready = ×זהרה: מסמך ×”Ö¾PDF ×œ× × ×˜×¢×Ÿ לחלוטין עד מצב שמ×פשר הדפסה.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = הצגה/הסתרה של סרגל הצד
+pdfjs-toggle-sidebar-notification-button =
+ .title = החלפת תצוגת סרגל צד (מסמך שמכיל תוכן ×¢× ×™×™× ×™×/×§×‘×¦×™× ×ž×¦×•×¨×¤×™×/שכבות)
+pdfjs-toggle-sidebar-button-label = הצגה/הסתרה של סרגל הצד
+pdfjs-document-outline-button =
+ .title = הצגת תוכן ×”×¢× ×™×™× ×™× ×©×œ המסמך (לחיצה כפולה כדי להרחיב ×ו ×œ×¦×ž×¦× ×ת כל הפריטי×)
+pdfjs-document-outline-button-label = תוכן ×”×¢× ×™×™× ×™× ×©×œ המסמך
+pdfjs-attachments-button =
+ .title = הצגת צרופות
+pdfjs-attachments-button-label = צרופות
+pdfjs-layers-button =
+ .title = הצגת שכבות (יש ללחוץ לחיצה כפולה כדי ל×פס ×ת כל השכבות למצב ברירת המחדל)
+pdfjs-layers-button-label = שכבות
+pdfjs-thumbs-button =
+ .title = הצגת תצוגה מקדימה
+pdfjs-thumbs-button-label = תצוגה מקדימה
+pdfjs-current-outline-item-button =
+ .title = מצי×ת פריט תוכן ×”×¢× ×™×™× ×™× ×”× ×•×›×—×™
+pdfjs-current-outline-item-button-label = פריט תוכן ×”×¢× ×™×™× ×™× ×”× ×•×›×—×™
+pdfjs-findbar-button =
+ .title = חיפוש במסמך
+pdfjs-findbar-button-label = חיפוש
+pdfjs-additional-layers = שכבות × ×•×¡×¤×•×ª
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = עמוד { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = תצוגה מקדימה של עמוד { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = חיפוש
+ .placeholder = חיפוש במסמך…
+pdfjs-find-previous-button =
+ .title = מצי×ת המופע ×”×§×•×“× ×©×œ הביטוי
+pdfjs-find-previous-button-label = קוד×
+pdfjs-find-next-button =
+ .title = מצי×ת המופע ×”×‘× ×©×œ הביטוי
+pdfjs-find-next-button-label = הב×
+pdfjs-find-highlight-checkbox = הדגשת הכול
+pdfjs-find-match-case-checkbox-label = הת×מת ×ותיות
+pdfjs-find-match-diacritics-checkbox-label = הת×מה די×קריטית
+pdfjs-find-entire-word-checkbox-label = ×ž×™×œ×™× ×©×œ×ž×•×ª
+pdfjs-find-reached-top = ×”×’×™×¢ לר×ש הדף, ממשיך מלמטה
+pdfjs-find-reached-bottom = הגיע לסוף הדף, ממשיך מלמעלה
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } מתוך { $total } תוצ×ות
+ *[other] { $current } מתוך { $total } תוצ×ות
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] יותר מתוצ××” ×חת
+ *[other] יותר מ־{ $limit } תוצ×ות
+ }
+pdfjs-find-not-found = הביטוי ×œ× × ×ž×¦×
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = רוחב העמוד
+pdfjs-page-scale-fit = הת×מה לעמוד
+pdfjs-page-scale-auto = מרחק מתצוגה ×וטומטי
+pdfjs-page-scale-actual = גודל ×מיתי
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = עמוד { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = ×ירעה שגי××” בעת ×˜×¢×™× ×ª ×”Ö¾PDF.
+pdfjs-invalid-file-error = קובץ PDF ×¤×’×•× ×ו ×œ× ×ª×§×™×Ÿ.
+pdfjs-missing-file-error = קובץ PDF חסר.
+pdfjs-unexpected-response-error = תגובת שרת ×œ× ×¦×¤×•×™×”.
+pdfjs-rendering-error = ×ירעה שגי××” בעת עיבוד הדף.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [הערת { $type }]
+
+## Password
+
+pdfjs-password-label = × × ×œ×”×›× ×™×¡ ×ת הססמה לפתיחת קובץ PDF ×–×”.
+pdfjs-password-invalid = ססמה שגויה. × × ×œ× ×¡×•×ª ×©× ×™×ª.
+pdfjs-password-ok-button = ×ישור
+pdfjs-password-cancel-button = ביטול
+pdfjs-web-fonts-disabled = ×’×•×¤× ×™ רשת ×ž× ×•×˜×¨×œ×™×: ×œ× × ×™×ª×Ÿ להשתמש ×‘×’×•×¤× ×™ PDF מוטבעי×.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = טקסט
+pdfjs-editor-free-text-button-label = טקסט
+pdfjs-editor-ink-button =
+ .title = ציור
+pdfjs-editor-ink-button-label = ציור
+pdfjs-editor-stamp-button =
+ .title = הוספה ×ו עריכת ×ª×ž×•× ×•×ª
+pdfjs-editor-stamp-button-label = הוספה ×ו עריכת ×ª×ž×•× ×•×ª
+pdfjs-editor-remove-button =
+ .title = הסרה
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = הסרת ציור
+pdfjs-editor-remove-freetext-button =
+ .title = הסרת טקסט
+pdfjs-editor-remove-stamp-button =
+ .title = הסרת ×ª×ž×•× ×”
+pdfjs-editor-remove-highlight-button =
+ .title = הסרת הדגשה
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = צבע
+pdfjs-editor-free-text-size-input = גודל
+pdfjs-editor-ink-color-input = צבע
+pdfjs-editor-ink-thickness-input = עובי
+pdfjs-editor-ink-opacity-input = ×טימות
+pdfjs-editor-stamp-add-image-button =
+ .title = הוספת ×ª×ž×•× ×”
+pdfjs-editor-stamp-add-image-button-label = הוספת ×ª×ž×•× ×”
+pdfjs-free-text =
+ .aria-label = עורך טקסט
+pdfjs-free-text-default-content = להתחיל להקליד…
+pdfjs-ink =
+ .aria-label = עורך ציור
+pdfjs-ink-canvas =
+ .aria-label = ×ª×ž×•× ×” ×©× ×•×¦×¨×” על־ידי משתמש
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = טקסט חלופי
+pdfjs-editor-alt-text-edit-button-label = עריכת טקסט חלופי
+pdfjs-editor-alt-text-dialog-label = בחירת ×פשרות
+pdfjs-editor-alt-text-dialog-description = טקסט חלופי עוזר כש×× ×©×™× ×œ× ×™×›×•×œ×™× ×œ×¨×ות ×ת ×”×ª×ž×•× ×” ×ו ×›×©×”×™× ×œ× × ×˜×¢× ×ª.
+pdfjs-editor-alt-text-add-description-label = הוספת תי×ור
+pdfjs-editor-alt-text-add-description-description = כד××™ לת×ר במשפט ×חד ×ו ×©× ×™×™× ×ת ×”× ×•×©×, התפ×ורה ×ו הפעולות.
+pdfjs-editor-alt-text-mark-decorative-label = סימון כדקורטיבי
+pdfjs-editor-alt-text-mark-decorative-description = ×–×” משמש ×œ×ª×ž×•× ×•×ª × ×•×™, כמו גבולות ×ו ×¡×™×ž× ×™ מי×.
+pdfjs-editor-alt-text-cancel-button = ביטול
+pdfjs-editor-alt-text-save-button = שמירה
+pdfjs-editor-alt-text-decorative-tooltip = מסומן כדקורטיבי
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = לדוגמה, ״גבר צעיר מתיישב ליד שולחן ל×כול ×רוחה״
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = ×¤×™× ×” שמ×לית ×¢×œ×™×•× ×” - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-top-middle = למעלה ב×מצע - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-top-right = ×¤×™× ×” ×™×ž× ×™×ª ×¢×œ×™×•× ×” - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-middle-right = ×™×ž×™× ×” ב×מצע - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-bottom-right = ×¤×™× ×” ×™×ž× ×™×ª ×ª×—×ª×•× ×” - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-bottom-middle = למטה ב×מצע - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-bottom-left = ×¤×™× ×” שמ×לית ×ª×—×ª×•× ×” - ×©×™× ×•×™ גודל
+pdfjs-editor-resizer-label-middle-left = שמ×לה ב×מצע - ×©×™× ×•×™ גודל
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = צבע הדגשה
+pdfjs-editor-colorpicker-button =
+ .title = ×©×™× ×•×™ צבע
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = בחירת צבע
+pdfjs-editor-colorpicker-yellow =
+ .title = צהוב
+pdfjs-editor-colorpicker-green =
+ .title = ירוק
+pdfjs-editor-colorpicker-blue =
+ .title = כחול
+pdfjs-editor-colorpicker-pink =
+ .title = ורוד
+pdfjs-editor-colorpicker-red =
+ .title = ×דו×
diff --git a/www/lib/pdfjs/modern/web/locale/hi-IN/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hi-IN/viewer.ftl
new file mode 100644
index 000000000..1ead59306
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hi-IN/viewer.ftl
@@ -0,0 +1,253 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = पिछला पृषà¥à¤
+pdfjs-previous-button-label = पिछला
+pdfjs-next-button =
+ .title = अगला पृषà¥à¤
+pdfjs-next-button-label = आगे
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = पृषà¥à¤ :
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } का
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = छोटा करें
+pdfjs-zoom-out-button-label = छोटा करें
+pdfjs-zoom-in-button =
+ .title = बड़ा करें
+pdfjs-zoom-in-button-label = बड़ा करें
+pdfjs-zoom-select =
+ .title = बड़ा-छोटा करें
+pdfjs-presentation-mode-button =
+ .title = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿ अवसà¥à¤¥à¤¾ में जाà¤à¤
+pdfjs-presentation-mode-button-label = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿ अवसà¥à¤¥à¤¾
+pdfjs-open-file-button =
+ .title = फ़ाइल खोलें
+pdfjs-open-file-button-label = खोलें
+pdfjs-print-button =
+ .title = छापें
+pdfjs-print-button-label = छापें
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = à¤à¤ª में खोलें
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = à¤à¤ª में खोलें
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = औज़ार
+pdfjs-tools-button-label = औज़ार
+pdfjs-first-page-button =
+ .title = पà¥à¤°à¤¥à¤® पृषà¥à¤ पर जाà¤à¤
+pdfjs-first-page-button-label = पà¥à¤°à¤¥à¤® पृषà¥à¤ पर जाà¤à¤
+pdfjs-last-page-button =
+ .title = अंतिम पृषà¥à¤ पर जाà¤à¤
+pdfjs-last-page-button-label = अंतिम पृषà¥à¤ पर जाà¤à¤
+pdfjs-page-rotate-cw-button =
+ .title = घड़ी की दिशा में घà¥à¤®à¤¾à¤à¤
+pdfjs-page-rotate-cw-button-label = घड़ी की दिशा में घà¥à¤®à¤¾à¤à¤
+pdfjs-page-rotate-ccw-button =
+ .title = घड़ी की दिशा से उलà¥à¤Ÿà¤¾ घà¥à¤®à¤¾à¤à¤
+pdfjs-page-rotate-ccw-button-label = घड़ी की दिशा से उलà¥à¤Ÿà¤¾ घà¥à¤®à¤¾à¤à¤
+pdfjs-cursor-text-select-tool-button =
+ .title = पाठचयन उपकरण सकà¥à¤·à¤® करें
+pdfjs-cursor-text-select-tool-button-label = पाठचयन उपकरण
+pdfjs-cursor-hand-tool-button =
+ .title = हसà¥à¤¤ उपकरण सकà¥à¤·à¤® करें
+pdfjs-cursor-hand-tool-button-label = हसà¥à¤¤ उपकरण
+pdfjs-scroll-vertical-button =
+ .title = लंबवत सà¥à¤•à¥à¤°à¥‰à¤²à¤¿à¤‚ग का उपयोग करें
+pdfjs-scroll-vertical-button-label = लंबवत सà¥à¤•à¥à¤°à¥‰à¤²à¤¿à¤‚ग
+pdfjs-scroll-horizontal-button =
+ .title = कà¥à¤·à¤¿à¤¤à¤¿à¤œà¤¿à¤¯ सà¥à¤•à¥à¤°à¥‰à¤²à¤¿à¤‚ग का उपयोग करें
+pdfjs-scroll-horizontal-button-label = कà¥à¤·à¤¿à¤¤à¤¿à¤œà¤¿à¤¯ सà¥à¤•à¥à¤°à¥‰à¤²à¤¿à¤‚ग
+pdfjs-scroll-wrapped-button =
+ .title = वà¥à¤°à¤¾à¤ªà¥à¤ªà¥‡à¤¡ सà¥à¤•à¥à¤°à¥‰à¤²à¤¿à¤‚ग का उपयोग करें
+pdfjs-spread-none-button-label = कोई सà¥à¤ªà¥à¤°à¥‡à¤¡ उपलबà¥à¤§ नहीं
+pdfjs-spread-odd-button =
+ .title = विषम-कà¥à¤°à¤®à¤¾à¤‚कित पृषà¥à¤ ों से पà¥à¤°à¤¾à¤°à¤‚ठहोने वाले पृषà¥à¤ सà¥à¤ªà¥à¤°à¥‡à¤¡ में शामिल हों
+pdfjs-spread-odd-button-label = विषम फैलाव
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ विशेषता...
+pdfjs-document-properties-button-label = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ विशेषता...
+pdfjs-document-properties-file-name = फ़ाइल नाम:
+pdfjs-document-properties-file-size = फाइल आकारः
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = शीरà¥à¤·à¤•:
+pdfjs-document-properties-author = लेखकः
+pdfjs-document-properties-subject = विषय:
+pdfjs-document-properties-keywords = कà¥à¤‚जी-शबà¥à¤¦:
+pdfjs-document-properties-creation-date = निरà¥à¤®à¤¾à¤£ दिनांक:
+pdfjs-document-properties-modification-date = संशोधन दिनांक:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = निरà¥à¤®à¤¾à¤¤à¤¾:
+pdfjs-document-properties-producer = PDF उतà¥à¤ªà¤¾à¤¦à¤•:
+pdfjs-document-properties-version = PDF संसà¥à¤•à¤°à¤£:
+pdfjs-document-properties-page-count = पृषà¥à¤ गिनती:
+pdfjs-document-properties-page-size = पृषà¥à¤ आकार:
+pdfjs-document-properties-page-size-unit-inches = इंच
+pdfjs-document-properties-page-size-unit-millimeters = मिमी
+pdfjs-document-properties-page-size-orientation-portrait = पोरà¥à¤Ÿà¥à¤°à¥‡à¤Ÿ
+pdfjs-document-properties-page-size-orientation-landscape = लैंडसà¥à¤•à¥‡à¤ª
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = पतà¥à¤°
+pdfjs-document-properties-page-size-name-legal = क़ानूनी
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = तीवà¥à¤° वेब वà¥à¤¯à¥‚:
+pdfjs-document-properties-linearized-yes = हाà¤
+pdfjs-document-properties-linearized-no = नहीं
+pdfjs-document-properties-close-button = बंद करें
+
+## Print
+
+pdfjs-print-progress-message = छपाई के लिठदसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ को तैयार किया जा रहा है...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = रदà¥à¤¦ करें
+pdfjs-printing-not-supported = चेतावनी: इस बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° पर छपाई पूरी तरह से समरà¥à¤¥à¤¿à¤¤ नहीं है.
+pdfjs-printing-not-ready = चेतावनी: PDF छपाई के लिठपूरी तरह से लोड नहीं है.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = सà¥à¤²à¤¾à¤‡à¤¡à¤° टॉगल करें
+pdfjs-toggle-sidebar-button-label = सà¥à¤²à¤¾à¤‡à¤¡à¤° टॉगल करें
+pdfjs-document-outline-button =
+ .title = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ की रूपरेखा दिखाइठ(सारी वसà¥à¤¤à¥à¤“ं को फलने अथवा समेटने के लिठदो बार कà¥à¤²à¤¿à¤• करें)
+pdfjs-document-outline-button-label = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ आउटलाइन
+pdfjs-attachments-button =
+ .title = संलगà¥à¤¨à¤• दिखायें
+pdfjs-attachments-button-label = संलगà¥à¤¨à¤•
+pdfjs-thumbs-button =
+ .title = लघà¥à¤›à¤µà¤¿à¤¯à¤¾à¤ दिखाà¤à¤
+pdfjs-thumbs-button-label = लघॠछवि
+pdfjs-findbar-button =
+ .title = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ में ढूà¤à¤¢à¤¼à¥‡à¤‚
+pdfjs-findbar-button-label = ढूà¤à¤¢à¥‡à¤‚
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = पृषà¥à¤ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = पृषà¥à¤ { $page } की लघà¥-छवि
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ढूà¤à¤¢à¥‡à¤‚
+ .placeholder = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ में खोजें...
+pdfjs-find-previous-button =
+ .title = वाकà¥à¤¯à¤¾à¤‚श की पिछली उपसà¥à¤¥à¤¿à¤¤à¤¿ ढूà¤à¤¢à¤¼à¥‡à¤‚
+pdfjs-find-previous-button-label = पिछला
+pdfjs-find-next-button =
+ .title = वाकà¥à¤¯à¤¾à¤‚श की अगली उपसà¥à¤¥à¤¿à¤¤à¤¿ ढूà¤à¤¢à¤¼à¥‡à¤‚
+pdfjs-find-next-button-label = अगला
+pdfjs-find-highlight-checkbox = सà¤à¥€ आलोकित करें
+pdfjs-find-match-case-checkbox-label = मिलान सà¥à¤¥à¤¿à¤¤à¤¿
+pdfjs-find-entire-word-checkbox-label = संपूरà¥à¤£ शबà¥à¤¦
+pdfjs-find-reached-top = पृषà¥à¤ के ऊपर पहà¥à¤‚च गया, नीचे से जारी रखें
+pdfjs-find-reached-bottom = पृषà¥à¤ के नीचे में जा पहà¥à¤à¤šà¤¾, ऊपर से जारी
+pdfjs-find-not-found = वाकà¥à¤¯à¤¾à¤‚श नहीं मिला
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = पृषà¥à¤ चौड़ाई
+pdfjs-page-scale-fit = पृषà¥à¤ फिट
+pdfjs-page-scale-auto = सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ जूम
+pdfjs-page-scale-actual = वासà¥à¤¤à¤µà¤¿à¤• आकार
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF लोड करते समय à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ.
+pdfjs-invalid-file-error = अमानà¥à¤¯ या à¤à¥à¤°à¤·à¥à¤Ÿ PDF फ़ाइल.
+pdfjs-missing-file-error = अनà¥à¤ªà¤¸à¥à¤¥à¤¿à¤¤ PDF फ़ाइल.
+pdfjs-unexpected-response-error = अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ सरà¥à¤µà¤° पà¥à¤°à¤¤à¤¿à¤•à¥à¤°à¤¿à¤¯à¤¾.
+pdfjs-rendering-error = पृषà¥à¤ रेंडरिंग के दौरान तà¥à¤°à¥à¤Ÿà¤¿ आई.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = इस PDF फ़ाइल को खोलने के लिठकृपया कूटशबà¥à¤¦ à¤à¤°à¥‡à¤‚.
+pdfjs-password-invalid = अवैध कूटशबà¥à¤¦, कृपया फिर कोशिश करें.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = रदà¥à¤¦ करें
+pdfjs-web-fonts-disabled = वेब फॉनà¥à¤Ÿà¥à¤¸ निषà¥à¤•à¥à¤°à¤¿à¤¯ हैं: अंतःसà¥à¤¥à¤¾à¤ªà¤¿à¤¤ PDF फॉनà¥à¤Ÿà¤¸ के उपयोग में असमरà¥à¤¥.
+
+## Editing
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = रंग
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/hr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hr/viewer.ftl
new file mode 100644
index 000000000..23d88e76a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hr/viewer.ftl
@@ -0,0 +1,279 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Prethodna stranica
+pdfjs-previous-button-label = Prethodna
+pdfjs-next-button =
+ .title = Sljedeća stranica
+pdfjs-next-button-label = Sljedeća
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Stranica
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = od { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } od { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Umanji
+pdfjs-zoom-out-button-label = Umanji
+pdfjs-zoom-in-button =
+ .title = Uvećaj
+pdfjs-zoom-in-button-label = Uvećaj
+pdfjs-zoom-select =
+ .title = Zumiranje
+pdfjs-presentation-mode-button =
+ .title = Prebaci u prezentacijski naÄin rada
+pdfjs-presentation-mode-button-label = Prezentacijski naÄin rada
+pdfjs-open-file-button =
+ .title = Otvori datoteku
+pdfjs-open-file-button-label = Otvori
+pdfjs-print-button =
+ .title = Ispiši
+pdfjs-print-button-label = Ispiši
+pdfjs-save-button =
+ .title = Spremi
+pdfjs-save-button-label = Spremi
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Alati
+pdfjs-tools-button-label = Alati
+pdfjs-first-page-button =
+ .title = Idi na prvu stranicu
+pdfjs-first-page-button-label = Idi na prvu stranicu
+pdfjs-last-page-button =
+ .title = Idi na posljednju stranicu
+pdfjs-last-page-button-label = Idi na posljednju stranicu
+pdfjs-page-rotate-cw-button =
+ .title = Rotiraj u smjeru kazaljke na satu
+pdfjs-page-rotate-cw-button-label = Rotiraj u smjeru kazaljke na satu
+pdfjs-page-rotate-ccw-button =
+ .title = Rotiraj obrnutno od smjera kazaljke na satu
+pdfjs-page-rotate-ccw-button-label = Rotiraj obrnutno od smjera kazaljke na satu
+pdfjs-cursor-text-select-tool-button =
+ .title = Omogući alat za oznaÄavanje teksta
+pdfjs-cursor-text-select-tool-button-label = Alat za oznaÄavanje teksta
+pdfjs-cursor-hand-tool-button =
+ .title = Omogući ruÄni alat
+pdfjs-cursor-hand-tool-button-label = RuÄni alat
+pdfjs-scroll-vertical-button =
+ .title = Koristi okomito pomicanje
+pdfjs-scroll-vertical-button-label = Okomito pomicanje
+pdfjs-scroll-horizontal-button =
+ .title = Koristi vodoravno pomicanje
+pdfjs-scroll-horizontal-button-label = Vodoravno pomicanje
+pdfjs-scroll-wrapped-button =
+ .title = Koristi kontinuirani raspored stranica
+pdfjs-scroll-wrapped-button-label = Kontinuirani raspored stranica
+pdfjs-spread-none-button =
+ .title = Ne izrađuj duplerice
+pdfjs-spread-none-button-label = PojedinaÄne stranice
+pdfjs-spread-odd-button =
+ .title = Izradi duplerice koje poÄinju s neparnim stranicama
+pdfjs-spread-odd-button-label = Neparne duplerice
+pdfjs-spread-even-button =
+ .title = Izradi duplerice koje poÄinju s parnim stranicama
+pdfjs-spread-even-button-label = Parne duplerice
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Svojstva dokumenta …
+pdfjs-document-properties-button-label = Svojstva dokumenta …
+pdfjs-document-properties-file-name = Naziv datoteke:
+pdfjs-document-properties-file-size = VeliÄina datoteke:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajtova)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtova)
+pdfjs-document-properties-title = Naslov:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Predmet:
+pdfjs-document-properties-keywords = KljuÄne rijeÄi:
+pdfjs-document-properties-creation-date = Datum stvaranja:
+pdfjs-document-properties-modification-date = Datum promjene:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Stvaratelj:
+pdfjs-document-properties-producer = PDF stvaratelj:
+pdfjs-document-properties-version = PDF verzija:
+pdfjs-document-properties-page-count = Broj stranica:
+pdfjs-document-properties-page-size = Dimenzije stranice:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = uspravno
+pdfjs-document-properties-page-size-orientation-landscape = položeno
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Brzi web pregled:
+pdfjs-document-properties-linearized-yes = Da
+pdfjs-document-properties-linearized-no = Ne
+pdfjs-document-properties-close-button = Zatvori
+
+## Print
+
+pdfjs-print-progress-message = Pripremanje dokumenta za ispis…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Odustani
+pdfjs-printing-not-supported = Upozorenje: Ovaj preglednik ne podržava u potpunosti ispisivanje.
+pdfjs-printing-not-ready = Upozorenje: PDF nije u potpunosti uÄitan za ispis.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Prikaži/sakrij boÄnu traku
+pdfjs-toggle-sidebar-notification-button =
+ .title = Prikazivanje i sklanjanje boÄne trake (dokument sadrži strukturu/privitke/slojeve)
+pdfjs-toggle-sidebar-button-label = Prikaži/sakrij boÄnu traku
+pdfjs-document-outline-button =
+ .title = Prikaži strukturu dokumenta (dvostruki klik za rasklapanje/sklapanje svih stavki)
+pdfjs-document-outline-button-label = Struktura dokumenta
+pdfjs-attachments-button =
+ .title = Prikaži privitke
+pdfjs-attachments-button-label = Privitci
+pdfjs-layers-button =
+ .title = Prikaži slojeve (dvoklik za vraćanje svih slojeva u zadano stanje)
+pdfjs-layers-button-label = Slojevi
+pdfjs-thumbs-button =
+ .title = Prikaži minijature
+pdfjs-thumbs-button-label = Minijature
+pdfjs-current-outline-item-button =
+ .title = PronaÄ‘i trenutaÄni element strukture
+pdfjs-current-outline-item-button-label = TrenutaÄni element strukture
+pdfjs-findbar-button =
+ .title = Pronađi u dokumentu
+pdfjs-findbar-button-label = Pronađi
+pdfjs-additional-layers = Dodatni slojevi
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Stranica { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Minijatura stranice { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Pronađi
+ .placeholder = Pronađi u dokumentu …
+pdfjs-find-previous-button =
+ .title = Pronađi prethodno pojavljivanje ovog izraza
+pdfjs-find-previous-button-label = Prethodno
+pdfjs-find-next-button =
+ .title = Pronađi sljedeće pojavljivanje ovog izraza
+pdfjs-find-next-button-label = Sljedeće
+pdfjs-find-highlight-checkbox = Istankni sve
+pdfjs-find-match-case-checkbox-label = Razlikovanje velikih i malih slova
+pdfjs-find-entire-word-checkbox-label = Cijele rijeÄi
+pdfjs-find-reached-top = Dosegnut poÄetak dokumenta, nastavak s kraja
+pdfjs-find-reached-bottom = Dosegnut kraj dokumenta, nastavak s poÄetka
+pdfjs-find-not-found = Izraz nije pronađen
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Prilagodi Å¡irini prozora
+pdfjs-page-scale-fit = Prilagodi veliÄini prozora
+pdfjs-page-scale-auto = Automatsko zumiranje
+pdfjs-page-scale-actual = Stvarna veliÄina
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Stranica { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = DoÅ¡lo je do greÅ¡ke pri uÄitavanju PDF-a.
+pdfjs-invalid-file-error = Neispravna ili oštećena PDF datoteka.
+pdfjs-missing-file-error = Nedostaje PDF datoteka.
+pdfjs-unexpected-response-error = NeoÄekivani odgovor poslužitelja.
+pdfjs-rendering-error = Došlo je do greške prilikom iscrtavanja stranice.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Bilješka]
+
+## Password
+
+pdfjs-password-label = Za otvoranje ove PDF datoteku upiši lozinku.
+pdfjs-password-invalid = Neispravna lozinka. Pokušaj ponovo.
+pdfjs-password-ok-button = U redu
+pdfjs-password-cancel-button = Odustani
+pdfjs-web-fonts-disabled = Web fontovi su deaktivirani: nije moguće koristiti ugrađene PDF fontove.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Boja
+pdfjs-editor-free-text-size-input = VeliÄina
+pdfjs-editor-ink-color-input = Boja
+pdfjs-editor-ink-thickness-input = Debljina
+pdfjs-editor-ink-opacity-input = Neprozirnost
+pdfjs-free-text =
+ .aria-label = UreÄ‘ivaÄ teksta
+pdfjs-free-text-default-content = PoÄni tipkati …
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/hsb/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hsb/viewer.ftl
new file mode 100644
index 000000000..112855888
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hsb/viewer.ftl
@@ -0,0 +1,388 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Předchadna strona
+pdfjs-previous-button-label = Wróćo
+pdfjs-next-button =
+ .title = Přichodna strona
+pdfjs-next-button-label = Dale
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Strona
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = z { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } z { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Pomjeńšić
+pdfjs-zoom-out-button-label = Pomjeńšić
+pdfjs-zoom-in-button =
+ .title = Powjetšić
+pdfjs-zoom-in-button-label = Powjetšić
+pdfjs-zoom-select =
+ .title = Skalowanje
+pdfjs-presentation-mode-button =
+ .title = Do prezentaciskeho modusa přeńć
+pdfjs-presentation-mode-button-label = Prezentaciski modus
+pdfjs-open-file-button =
+ .title = Dataju woÄinić
+pdfjs-open-file-button-label = WoÄinić
+pdfjs-print-button =
+ .title = Ćišćeć
+pdfjs-print-button-label = Ćišćeć
+pdfjs-save-button =
+ .title = Składować
+pdfjs-save-button-label = Składować
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Sćahnyć
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Sćahnyć
+pdfjs-bookmark-button =
+ .title = Aktualna strona (URL z aktualneje strony pokazać)
+pdfjs-bookmark-button-label = Aktualna strona
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = W naÅ‚oženju woÄinić
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = W naÅ‚oženju woÄinić
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Nastroje
+pdfjs-tools-button-label = Nastroje
+pdfjs-first-page-button =
+ .title = K prěnjej stronje
+pdfjs-first-page-button-label = K prěnjej stronje
+pdfjs-last-page-button =
+ .title = K poslednjej stronje
+pdfjs-last-page-button-label = K poslednjej stronje
+pdfjs-page-rotate-cw-button =
+ .title = K smÄ›rej Äasnika wjerćeć
+pdfjs-page-rotate-cw-button-label = K smÄ›rej Äasnika wjerćeć
+pdfjs-page-rotate-ccw-button =
+ .title = PÅ™ećiwo smÄ›rej Äasnika wjerćeć
+pdfjs-page-rotate-ccw-button-label = PÅ™ećiwo smÄ›rej Äasnika wjerćeć
+pdfjs-cursor-text-select-tool-button =
+ .title = Nastroj za wuběranje teksta zmóžnić
+pdfjs-cursor-text-select-tool-button-label = Nastroj za wuběranje teksta
+pdfjs-cursor-hand-tool-button =
+ .title = RuÄny nastroj zmóžnić
+pdfjs-cursor-hand-tool-button-label = RuÄny nastroj
+pdfjs-scroll-page-button =
+ .title = Kulenje strony wužiwać
+pdfjs-scroll-page-button-label = Kulenje strony
+pdfjs-scroll-vertical-button =
+ .title = Wertikalne suwanje wužiwać
+pdfjs-scroll-vertical-button-label = Wertikalne suwanje
+pdfjs-scroll-horizontal-button =
+ .title = Horicontalne suwanje wužiwać
+pdfjs-scroll-horizontal-button-label = Horicontalne suwanje
+pdfjs-scroll-wrapped-button =
+ .title = Postupne suwanje wužiwać
+pdfjs-scroll-wrapped-button-label = Postupne suwanje
+pdfjs-spread-none-button =
+ .title = Strony njezwjazać
+pdfjs-spread-none-button-label = Žana dwójna strona
+pdfjs-spread-odd-button =
+ .title = Strony zapoÄinajo z njerunymi stronami zwjazać
+pdfjs-spread-odd-button-label = Njerune strony
+pdfjs-spread-even-button =
+ .title = Strony zapoÄinajo z runymi stronami zwjazać
+pdfjs-spread-even-button-label = Rune strony
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentowe kajkosće…
+pdfjs-document-properties-button-label = Dokumentowe kajkosće…
+pdfjs-document-properties-file-name = Mjeno dataje:
+pdfjs-document-properties-file-size = Wulkosć dataje:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajtow)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtow)
+pdfjs-document-properties-title = Titul:
+pdfjs-document-properties-author = Awtor:
+pdfjs-document-properties-subject = Předmjet:
+pdfjs-document-properties-keywords = KluÄowe sÅ‚owa:
+pdfjs-document-properties-creation-date = Datum wutworjenja:
+pdfjs-document-properties-modification-date = Datum změny:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Awtor:
+pdfjs-document-properties-producer = PDF-zhotowjer:
+pdfjs-document-properties-version = PDF-wersija:
+pdfjs-document-properties-page-count = LiÄba stronow:
+pdfjs-document-properties-page-size = Wulkosć strony:
+pdfjs-document-properties-page-size-unit-inches = cól
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = wysoki format
+pdfjs-document-properties-page-size-orientation-landscape = prÄ›Äny format
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Haj
+pdfjs-document-properties-linearized-no = NÄ›
+pdfjs-document-properties-close-button = ZaÄinić
+
+## Print
+
+pdfjs-print-progress-message = Dokument so za ćišćenje přihotuje…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Přetorhnyć
+pdfjs-printing-not-supported = Warnowanje: Ćišćenje so přez tutón wobhladowak połnje njepodpěruje.
+pdfjs-printing-not-ready = Warnowanje: PDF njeje so za ćišćenje dospoÅ‚nje zaÄitaÅ‚.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = BóÄnicu pokazać/schować
+pdfjs-toggle-sidebar-notification-button =
+ .title = BóÄnicu pÅ™epinać (dokument rozrjad/pÅ™iwěški/worÅ¡ty wobsahuje)
+pdfjs-toggle-sidebar-button-label = BóÄnicu pokazać/schować
+pdfjs-document-outline-button =
+ .title = Dokumentowy naćisk pokazać (dwójne kliknjenje, zo bychu so wšě zapiski pokazali/schowali)
+pdfjs-document-outline-button-label = Dokumentowa struktura
+pdfjs-attachments-button =
+ .title = Přiwěški pokazać
+pdfjs-attachments-button-label = Přiwěški
+pdfjs-layers-button =
+ .title = Woršty pokazać (klikńće dwójce, zo byšće wšě woršty na standardny staw wróćo stajił)
+pdfjs-layers-button-label = Woršty
+pdfjs-thumbs-button =
+ .title = Miniatury pokazać
+pdfjs-thumbs-button-label = Miniatury
+pdfjs-current-outline-item-button =
+ .title = Aktualny rozrjadowy zapisk pytać
+pdfjs-current-outline-item-button-label = Aktualny rozrjadowy zapisk
+pdfjs-findbar-button =
+ .title = W dokumenće pytać
+pdfjs-findbar-button-label = Pytać
+pdfjs-additional-layers = Dalše woršty
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Strona { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura strony { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Pytać
+ .placeholder = W dokumenće pytać…
+pdfjs-find-previous-button =
+ .title = Předchadne wustupowanje pytanskeho wuraza pytać
+pdfjs-find-previous-button-label = Wróćo
+pdfjs-find-next-button =
+ .title = Přichodne wustupowanje pytanskeho wuraza pytać
+pdfjs-find-next-button-label = Dale
+pdfjs-find-highlight-checkbox = Wšě wuzběhnyć
+pdfjs-find-match-case-checkbox-label = Wulkopisanje wobkedźbować
+pdfjs-find-match-diacritics-checkbox-label = Diakritiske znamješka wužiwać
+pdfjs-find-entire-word-checkbox-label = Cyłe słowa
+pdfjs-find-reached-top = SpoÄatk dokumenta docpÄ›ty, pokroÄuje so z kóncom
+pdfjs-find-reached-bottom = Kónc dokument docpÄ›ty, pokroÄuje so ze spoÄatkom
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } z { $total } wotpowědnika
+ [two] { $current } z { $total } wotpowědnikow
+ [few] { $current } z { $total } wotpowědnikow
+ *[other] { $current } z { $total } wotpowědnikow
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Wyše { $limit } wotpowědnik
+ [two] Wyše { $limit } wotpowědnikaj
+ [few] Wyše { $limit } wotpowědniki
+ *[other] Wyše { $limit } wotpowědnikow
+ }
+pdfjs-find-not-found = Pytanski wuraz njeje so namakał
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Šěrokosć strony
+pdfjs-page-scale-fit = Wulkosć strony
+pdfjs-page-scale-auto = Awtomatiske skalowanje
+pdfjs-page-scale-actual = Aktualna wulkosć
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Strona { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PÅ™i zaÄitowanju PDF je zmylk wustupiÅ‚.
+pdfjs-invalid-file-error = Njepłaćiwa abo wobškodźena PDF-dataja.
+pdfjs-missing-file-error = Falowaca PDF-dataja.
+pdfjs-unexpected-response-error = NjewoÄakowana serwerowa wotmoÅ‚wa.
+pdfjs-rendering-error = Při zwobraznjenju strony je zmylk wustupił.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Typ přispomnjenki: { $type }]
+
+## Password
+
+pdfjs-password-label = Zapodajće hesÅ‚o, zo byšće PDF-dataju woÄiniÅ‚.
+pdfjs-password-invalid = Njepłaćiwe hesło. Prošu spytajće hišće raz.
+pdfjs-password-ok-button = W porjadku
+pdfjs-password-cancel-button = Přetorhnyć
+pdfjs-web-fonts-disabled = Webpisma su znjemóžnjene: njeje móžno, zasadźene PDF-pisma wužiwać.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Rysować
+pdfjs-editor-ink-button-label = Rysować
+pdfjs-editor-stamp-button =
+ .title = Wobrazy přidać abo wobdźěłać
+pdfjs-editor-stamp-button-label = Wobrazy přidać abo wobdźěłać
+pdfjs-editor-remove-button =
+ .title = Wotstronić
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Rysowanku wotstronić
+pdfjs-editor-remove-freetext-button =
+ .title = Tekst wotstronić
+pdfjs-editor-remove-stamp-button =
+ .title = Wobraz wotstronić
+pdfjs-editor-remove-highlight-button =
+ .title = Wuzběhnjenje wotstronić
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Barba
+pdfjs-editor-free-text-size-input = Wulkosć
+pdfjs-editor-ink-color-input = Barba
+pdfjs-editor-ink-thickness-input = Tołstosć
+pdfjs-editor-ink-opacity-input = Opacita
+pdfjs-editor-stamp-add-image-button =
+ .title = Wobraz přidać
+pdfjs-editor-stamp-add-image-button-label = Wobraz přidać
+pdfjs-free-text =
+ .aria-label = Tekstowy editor
+pdfjs-free-text-default-content = ZapoÄńće pisać…
+pdfjs-ink =
+ .aria-label = Rysowanski editor
+pdfjs-ink-canvas =
+ .aria-label = Wobraz wutworjeny wot wužiwarja
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternatiwny tekst
+pdfjs-editor-alt-text-edit-button-label = Alternatiwny tekst wobdźěłać
+pdfjs-editor-alt-text-dialog-label = Nastajenje wubrać
+pdfjs-editor-alt-text-dialog-description = Alternatiwny tekst pomha, hdyž ludźo njemóža wobraz widźeć abo hdyž so wobraz njezaÄita.
+pdfjs-editor-alt-text-add-description-label = Wopisanje přidać
+pdfjs-editor-alt-text-add-description-description = Pisajće 1 sadu abo 2 sadźe, kotrejž temu, nastajenje abo akcije wopisujetej.
+pdfjs-editor-alt-text-mark-decorative-label = Jako dekoratiwny markěrować
+pdfjs-editor-alt-text-mark-decorative-description = To so za pyšace wobrazy wužiwa, na přikład ramiki abo wodowe znamjenja.
+pdfjs-editor-alt-text-cancel-button = Přetorhnyć
+pdfjs-editor-alt-text-save-button = Składować
+pdfjs-editor-alt-text-decorative-tooltip = Jako dekoratiwny markěrowany
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Na přikład, „Młody muž za blidom sedźi, zo by jědź jědł“
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Horjeka nalěwo – wulkosć změnić
+pdfjs-editor-resizer-label-top-middle = Horjeka wosrjedź – wulkosć změnić
+pdfjs-editor-resizer-label-top-right = Horjeka naprawo – wulkosć změnić
+pdfjs-editor-resizer-label-middle-right = Wosrjedź naprawo – wulkosć změnić
+pdfjs-editor-resizer-label-bottom-right = Deleka naprawo – wulkosć změnić
+pdfjs-editor-resizer-label-bottom-middle = Deleka wosrjedź – wulkosć změnić
+pdfjs-editor-resizer-label-bottom-left = Deleka nalěwo – wulkosć změnić
+pdfjs-editor-resizer-label-middle-left = Wosrjedź nalěwo – wulkosć změnić
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Barba wuzběhnjenja
+pdfjs-editor-colorpicker-button =
+ .title = Barbu změnić
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Wuběr barbow
+pdfjs-editor-colorpicker-yellow =
+ .title = Žołty
+pdfjs-editor-colorpicker-green =
+ .title = Zeleny
+pdfjs-editor-colorpicker-blue =
+ .title = Módry
+pdfjs-editor-colorpicker-pink =
+ .title = Pink
+pdfjs-editor-colorpicker-red =
+ .title = ÄŒerwjeny
diff --git a/www/lib/pdfjs/modern/web/locale/hu/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hu/viewer.ftl
new file mode 100644
index 000000000..44acc1f0a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hu/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Előző oldal
+pdfjs-previous-button-label = Előző
+pdfjs-next-button =
+ .title = Következő oldal
+pdfjs-next-button-label = Tovább
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Oldal
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = összesen: { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = KicsinyÃtés
+pdfjs-zoom-out-button-label = KicsinyÃtés
+pdfjs-zoom-in-button =
+ .title = NagyÃtás
+pdfjs-zoom-in-button-label = NagyÃtás
+pdfjs-zoom-select =
+ .title = NagyÃtás
+pdfjs-presentation-mode-button =
+ .title = Váltás bemutató módba
+pdfjs-presentation-mode-button-label = Bemutató mód
+pdfjs-open-file-button =
+ .title = Fájl megnyitása
+pdfjs-open-file-button-label = Megnyitás
+pdfjs-print-button =
+ .title = Nyomtatás
+pdfjs-print-button-label = Nyomtatás
+pdfjs-save-button =
+ .title = Mentés
+pdfjs-save-button-label = Mentés
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Letöltés
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Letöltés
+pdfjs-bookmark-button =
+ .title = Jelenlegi oldal (webcÃm megtekintése a jelenlegi oldalról)
+pdfjs-bookmark-button-label = Jelenlegi oldal
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Megnyitás alkalmazásban
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Megnyitás alkalmazásban
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Eszközök
+pdfjs-tools-button-label = Eszközök
+pdfjs-first-page-button =
+ .title = Ugrás az első oldalra
+pdfjs-first-page-button-label = Ugrás az első oldalra
+pdfjs-last-page-button =
+ .title = Ugrás az utolsó oldalra
+pdfjs-last-page-button-label = Ugrás az utolsó oldalra
+pdfjs-page-rotate-cw-button =
+ .title = Forgatás az óramutató járásával egyezően
+pdfjs-page-rotate-cw-button-label = Forgatás az óramutató járásával egyezően
+pdfjs-page-rotate-ccw-button =
+ .title = Forgatás az óramutató járásával ellentétesen
+pdfjs-page-rotate-ccw-button-label = Forgatás az óramutató járásával ellentétesen
+pdfjs-cursor-text-select-tool-button =
+ .title = Szövegkijelölő eszköz bekapcsolása
+pdfjs-cursor-text-select-tool-button-label = Szövegkijelölő eszköz
+pdfjs-cursor-hand-tool-button =
+ .title = Kéz eszköz bekapcsolása
+pdfjs-cursor-hand-tool-button-label = Kéz eszköz
+pdfjs-scroll-page-button =
+ .title = Oldalgörgetés használata
+pdfjs-scroll-page-button-label = Oldalgörgetés
+pdfjs-scroll-vertical-button =
+ .title = Függőleges görgetés használata
+pdfjs-scroll-vertical-button-label = Függőleges görgetés
+pdfjs-scroll-horizontal-button =
+ .title = VÃzszintes görgetés használata
+pdfjs-scroll-horizontal-button-label = VÃzszintes görgetés
+pdfjs-scroll-wrapped-button =
+ .title = Rácsos elrendezés használata
+pdfjs-scroll-wrapped-button-label = Rácsos elrendezés
+pdfjs-spread-none-button =
+ .title = Ne tapassza össze az oldalakat
+pdfjs-spread-none-button-label = Nincs összetapasztás
+pdfjs-spread-odd-button =
+ .title = Lapok összetapasztása, a páratlan számú oldalakkal kezdve
+pdfjs-spread-odd-button-label = Összetapasztás: páratlan
+pdfjs-spread-even-button =
+ .title = Lapok összetapasztása, a páros számú oldalakkal kezdve
+pdfjs-spread-even-button-label = Összetapasztás: páros
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentum tulajdonságai…
+pdfjs-document-properties-button-label = Dokumentum tulajdonságai…
+pdfjs-document-properties-file-name = Fájlnév:
+pdfjs-document-properties-file-size = Fájlméret:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bájt)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bájt)
+pdfjs-document-properties-title = CÃm:
+pdfjs-document-properties-author = Szerző:
+pdfjs-document-properties-subject = Tárgy:
+pdfjs-document-properties-keywords = Kulcsszavak:
+pdfjs-document-properties-creation-date = Létrehozás dátuma:
+pdfjs-document-properties-modification-date = MódosÃtás dátuma:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Létrehozta:
+pdfjs-document-properties-producer = PDF előállÃtó:
+pdfjs-document-properties-version = PDF verzió:
+pdfjs-document-properties-page-count = Oldalszám:
+pdfjs-document-properties-page-size = Lapméret:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = álló
+pdfjs-document-properties-page-size-orientation-landscape = fekvő
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Jogi információk
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Gyors webes nézet:
+pdfjs-document-properties-linearized-yes = Igen
+pdfjs-document-properties-linearized-no = Nem
+pdfjs-document-properties-close-button = Bezárás
+
+## Print
+
+pdfjs-print-progress-message = Dokumentum elÅ‘készÃtése nyomtatáshoz…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Mégse
+pdfjs-printing-not-supported = Figyelmeztetés: Ez a böngésző nem teljesen támogatja a nyomtatást.
+pdfjs-printing-not-ready = Figyelmeztetés: A PDF nincs teljesen betöltve a nyomtatáshoz.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Oldalsáv be/ki
+pdfjs-toggle-sidebar-notification-button =
+ .title = Oldalsáv be/ki (a dokumentum vázlatot/mellékleteket/rétegeket tartalmaz)
+pdfjs-toggle-sidebar-button-label = Oldalsáv be/ki
+pdfjs-document-outline-button =
+ .title = Dokumentum megjelenÃtése online (dupla kattintás minden elem kinyitásához/összecsukásához)
+pdfjs-document-outline-button-label = Dokumentumvázlat
+pdfjs-attachments-button =
+ .title = Mellékletek megjelenÃtése
+pdfjs-attachments-button-label = Van melléklet
+pdfjs-layers-button =
+ .title = Rétegek megjelenÃtése (dupla kattintás az összes réteg alapértelmezett állapotra visszaállÃtásához)
+pdfjs-layers-button-label = Rétegek
+pdfjs-thumbs-button =
+ .title = Bélyegképek megjelenÃtése
+pdfjs-thumbs-button-label = Bélyegképek
+pdfjs-current-outline-item-button =
+ .title = Jelenlegi vázlatelem megkeresése
+pdfjs-current-outline-item-button-label = Jelenlegi vázlatelem
+pdfjs-findbar-button =
+ .title = Keresés a dokumentumban
+pdfjs-findbar-button-label = Keresés
+pdfjs-additional-layers = További rétegek
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page }. oldal
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page }. oldal bélyegképe
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Keresés
+ .placeholder = Keresés a dokumentumban…
+pdfjs-find-previous-button =
+ .title = A kifejezés előző előfordulásának keresése
+pdfjs-find-previous-button-label = Előző
+pdfjs-find-next-button =
+ .title = A kifejezés következő előfordulásának keresése
+pdfjs-find-next-button-label = Tovább
+pdfjs-find-highlight-checkbox = Összes kiemelése
+pdfjs-find-match-case-checkbox-label = Kis- és nagybetűk megkülönböztetése
+pdfjs-find-match-diacritics-checkbox-label = Diakritikus jelek
+pdfjs-find-entire-word-checkbox-label = Teljes szavak
+pdfjs-find-reached-top = A dokumentum eleje elérve, folytatás a végétől
+pdfjs-find-reached-bottom = A dokumentum vége elérve, folytatás az elejétől
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } / { $total } találat
+ *[other] { $current } / { $total } találat
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Több mint { $limit } találat
+ *[other] Több mint { $limit } találat
+ }
+pdfjs-find-not-found = A kifejezés nem található
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Oldalszélesség
+pdfjs-page-scale-fit = Teljes oldal
+pdfjs-page-scale-auto = Automatikus nagyÃtás
+pdfjs-page-scale-actual = Valódi méret
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page }. oldal
+
+## Loading indicator messages
+
+pdfjs-loading-error = Hiba történt a PDF betöltésekor.
+pdfjs-invalid-file-error = Érvénytelen vagy sérült PDF fájl.
+pdfjs-missing-file-error = Hiányzó PDF fájl.
+pdfjs-unexpected-response-error = Váratlan kiszolgálóválasz.
+pdfjs-rendering-error = Hiba történt az oldal feldolgozása közben.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } megjegyzés]
+
+## Password
+
+pdfjs-password-label = Adja meg a jelszót a PDF fájl megnyitásához.
+pdfjs-password-invalid = Helytelen jelszó. Próbálja újra.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Mégse
+pdfjs-web-fonts-disabled = Webes betűkészletek letiltva: nem használhatók a beágyazott PDF betűkészletek.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Szöveg
+pdfjs-editor-free-text-button-label = Szöveg
+pdfjs-editor-ink-button =
+ .title = Rajzolás
+pdfjs-editor-ink-button-label = Rajzolás
+pdfjs-editor-stamp-button =
+ .title = Képek hozzáadása vagy szerkesztése
+pdfjs-editor-stamp-button-label = Képek hozzáadása vagy szerkesztése
+pdfjs-editor-remove-button =
+ .title = EltávolÃtás
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Rajz eltávolÃtása
+pdfjs-editor-remove-freetext-button =
+ .title = Szöveg eltávolÃtása
+pdfjs-editor-remove-stamp-button =
+ .title = Kép eltávolÃtása
+pdfjs-editor-remove-highlight-button =
+ .title = Kiemelés eltávolÃtása
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = SzÃn
+pdfjs-editor-free-text-size-input = Méret
+pdfjs-editor-ink-color-input = SzÃn
+pdfjs-editor-ink-thickness-input = Vastagság
+pdfjs-editor-ink-opacity-input = Ãtlátszatlanság
+pdfjs-editor-stamp-add-image-button =
+ .title = Kép hozzáadása
+pdfjs-editor-stamp-add-image-button-label = Kép hozzáadása
+pdfjs-free-text =
+ .aria-label = Szövegszerkesztő
+pdfjs-free-text-default-content = Kezdjen el gépelni…
+pdfjs-ink =
+ .aria-label = Rajzszerkesztő
+pdfjs-ink-canvas =
+ .aria-label = Felhasználó által készÃtett kép
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = AlternatÃv szöveg
+pdfjs-editor-alt-text-edit-button-label = AlternatÃv szöveg szerkesztése
+pdfjs-editor-alt-text-dialog-label = Válasszon egy lehetőséget
+pdfjs-editor-alt-text-dialog-description = Az alternatÃv szöveg segÃt, ha az emberek nem látják a képet, vagy ha az nem töltÅ‘dik be.
+pdfjs-editor-alt-text-add-description-label = LeÃrás hozzáadása
+pdfjs-editor-alt-text-add-description-description = Törekedjen 1-2 mondatra, amely jellemzi a témát, környezetet vagy cselekvést.
+pdfjs-editor-alt-text-mark-decorative-label = Megjelölés dekoratÃvként
+pdfjs-editor-alt-text-mark-decorative-description = Ez a dÃszÃtÅ‘képeknél használatos, mint a szegélyek vagy a vÃzjelek.
+pdfjs-editor-alt-text-cancel-button = Mégse
+pdfjs-editor-alt-text-save-button = Mentés
+pdfjs-editor-alt-text-decorative-tooltip = Megjelölve dekoratÃvként
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Például: „Egy fiatal férfi leül enni egy asztalhozâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Bal felső sarok – átméretezés
+pdfjs-editor-resizer-label-top-middle = Felül középen – átméretezés
+pdfjs-editor-resizer-label-top-right = Jobb felső sarok – átméretezés
+pdfjs-editor-resizer-label-middle-right = Jobbra középen – átméretezés
+pdfjs-editor-resizer-label-bottom-right = Jobb alsó sarok – átméretezés
+pdfjs-editor-resizer-label-bottom-middle = Alul középen – átméretezés
+pdfjs-editor-resizer-label-bottom-left = Bal alsó sarok – átméretezés
+pdfjs-editor-resizer-label-middle-left = Balra középen – átméretezés
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Kiemelés szÃne
+pdfjs-editor-colorpicker-button =
+ .title = SzÃn módosÃtása
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = SzÃnválasztások
+pdfjs-editor-colorpicker-yellow =
+ .title = Sárga
+pdfjs-editor-colorpicker-green =
+ .title = Zöld
+pdfjs-editor-colorpicker-blue =
+ .title = Kék
+pdfjs-editor-colorpicker-pink =
+ .title = RózsaszÃn
+pdfjs-editor-colorpicker-red =
+ .title = Vörös
diff --git a/www/lib/pdfjs/modern/web/locale/hy-AM/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hy-AM/viewer.ftl
new file mode 100644
index 000000000..31f9224e8
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hy-AM/viewer.ftl
@@ -0,0 +1,251 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Õ†Õ¡ÕÕ¸Ö€Õ¤ Õ§Õ»Õ¨
+pdfjs-previous-button-label = Õ†Õ¡ÕÕ¸Ö€Õ¤Õ¨
+pdfjs-next-button =
+ .title = Õ€Õ¡Õ»Õ¸Ö€Õ¤ Õ§Õ»Õ¨
+pdfjs-next-button-label = Õ€Õ¡Õ»Õ¸Ö€Õ¤Õ¨
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Ô·Õ».
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = -Õ¨Õ { $pagesCount }-Õ«Ö
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber }-Õ¨ { $pagesCount })-Õ«Ö
+pdfjs-zoom-out-button =
+ .title = Õ“Õ¸Ö„Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-out-button-label = Õ“Õ¸Ö„Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-in-button =
+ .title = Ô½Õ¸Õ·Õ¸Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-in-button-label = Ô½Õ¸Õ·Õ¸Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-select =
+ .title = Õ„Õ¡Õ½Õ·Õ¿Õ¡Õ¢
+pdfjs-presentation-mode-button =
+ .title = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ†Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ´Õ¡Õ¶ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯Õ«Õ¶
+pdfjs-presentation-mode-button-label = Õ†Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ´Õ¡Õ¶ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯
+pdfjs-open-file-button =
+ .title = Ô²Õ¡ÖÕ¥Õ¬ Õ¶Õ«Õ·Ö„
+pdfjs-open-file-button-label = Ô²Õ¡ÖÕ¥Õ¬
+pdfjs-print-button =
+ .title = ÕÕºÕ¥Õ¬
+pdfjs-print-button-label = ÕÕºÕ¥Õ¬
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ô³Õ¸Ö€Õ®Õ«Ö„Õ¶Õ¥Ö€
+pdfjs-tools-button-label = Ô³Õ¸Ö€Õ®Õ«Ö„Õ¶Õ¥Ö€
+pdfjs-first-page-button =
+ .title = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ§Õ»Õ«Õ¶
+pdfjs-first-page-button-label = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ§Õ»Õ«Õ¶
+pdfjs-last-page-button =
+ .title = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»Õ«Õ¶
+pdfjs-last-page-button-label = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»Õ«Õ¶
+pdfjs-page-rotate-cw-button =
+ .title = ÕŠÕ¿Õ¿Õ¥Õ¬ Õ¨Õ½Õ¿ ÕªÕ¡Õ´Õ¡ÖÕ¸Ö‚ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ«
+pdfjs-page-rotate-cw-button-label = ÕŠÕ¿Õ¿Õ¥Õ¬ Õ¨Õ½Õ¿ ÕªÕ¡Õ´Õ¡ÖÕ¸Ö‚ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ«
+pdfjs-page-rotate-ccw-button =
+ .title = ÕŠÕ¿Õ¿Õ¥Õ¬ Õ°Õ¡Õ¯Õ¡Õ¼Õ¡Õ¯ ÕªÕ¡Õ´Õ¡ÖÕ¸Ö‚ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ«
+pdfjs-page-rotate-ccw-button-label = ÕŠÕ¿Õ¿Õ¥Õ¬ Õ°Õ¡Õ¯Õ¡Õ¼Õ¡Õ¯ ÕªÕ¡Õ´Õ¡ÖÕ¸Ö‚ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ«
+pdfjs-cursor-text-select-tool-button =
+ .title = Õ„Õ«Õ¡ÖÕ¶Õ¥Õ¬ Õ£Ö€Õ¸Ö‚ÕµÕ© Õ¨Õ¶Õ¿Ö€Õ¥Õ¬Õ¸Ö‚ Õ£Õ¸Ö€Õ®Õ«Ö„Õ¨
+pdfjs-cursor-text-select-tool-button-label = Ô³Ö€Õ¸Ö‚ÕµÕ©Õ¨ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬Õ¸Ö‚ Õ£Õ¸Ö€Õ®Õ«Ö„
+pdfjs-cursor-hand-tool-button =
+ .title = Õ„Õ«Õ¡ÖÕ¶Õ¥Õ¬ ÕÕ¥Õ¼Ö„Õ« Õ£Õ¸Ö€Õ®Õ«Ö„Õ¨
+pdfjs-cursor-hand-tool-button-label = ÕÕ¥Õ¼Ö„Õ« Õ£Õ¸Ö€Õ®Õ«Ö„
+pdfjs-scroll-vertical-button =
+ .title = Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¸Ö‚Õ²Õ²Õ¡Õ°Õ¡ÕµÕ¡Ö Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-vertical-button-label = ÕˆÖ‚Õ²Õ²Õ¡Õ°Õ¡ÕµÕ¡Ö Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-horizontal-button =
+ .title = Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ°Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-horizontal-button-label = Õ€Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-wrapped-button =
+ .title = Õ•Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ ÖƒÕ¡Õ©Õ¡Õ©Õ¾Õ¡Õ® Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-wrapped-button-label = Õ“Õ¡Õ©Õ¡Õ©Õ¾Õ¡Õ® Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-spread-none-button =
+ .title = Õ„Õ« Õ´Õ«Õ¡ÖÕ¥Ö„ Õ§Õ»Õ« Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€Õ«Õ¶
+pdfjs-spread-none-button-label = Õ‰Õ¯Õ¡ Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€
+pdfjs-spread-odd-button =
+ .title = Õ„Õ«Õ¡ÖÕ¥Ö„ Õ§Õ»Õ« Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€Õ«Õ¶ Õ½Õ¯Õ½Õ¥Õ¬Õ¸Õ¾Õ Õ¯Õ¥Õ¶Õ¿ Õ°Õ¡Õ´Õ¡Ö€Õ¡Õ¯Õ¡Õ¬Õ¾Õ¡Õ® Õ§Õ»Õ¥Ö€Õ¸Õ¾
+pdfjs-spread-odd-button-label = Ô¿Õ¥Õ¶Õ¿ Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€
+pdfjs-spread-even-button =
+ .title = Õ„Õ«Õ¡ÖÕ¥Ö„ Õ§Õ»Õ« Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€Õ«Õ¶ Õ½Õ¯Õ½Õ¥Õ¬Õ¸Õ¾Õ Õ¦Õ¸Ö‚ÕµÕ£ Õ°Õ¡Õ´Õ¡Ö€Õ¡Õ¯Õ¡Õ¬Õ¾Õ¡Õ® Õ§Õ»Õ¥Ö€Õ¸Õ¾
+pdfjs-spread-even-button-label = Ô¶Õ¸Ö‚ÕµÕ£ Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Փաստաթղթի հատկությունները…
+pdfjs-document-properties-button-label = Փաստաթղթի հատկությունները…
+pdfjs-document-properties-file-name = Õ†Õ«Õ·Ö„Õ« Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨.
+pdfjs-document-properties-file-size = Õ†Õ«Õ·Ö„ Õ¹Õ¡ÖƒÕ¨.
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } Ô¿Ô² ({ $size_b } Õ¢Õ¡ÕµÕ©)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } Õ„Ô² ({ $size_b } Õ¢Õ¡ÕµÕ©)
+pdfjs-document-properties-title = ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€.
+pdfjs-document-properties-author = Հեղինակ․
+pdfjs-document-properties-subject = ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€.
+pdfjs-document-properties-keywords = Õ€Õ«Õ´Õ¶Õ¡Õ¢Õ¡Õ¼.
+pdfjs-document-properties-creation-date = ÕÕ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö‚ Õ¡Õ´Õ½Õ¡Õ©Õ«Õ¾Õ¨.
+pdfjs-document-properties-modification-date = Õ“Õ¸ÖƒÕ¸ÕÕ¥Õ¬Õ¸Ö‚ Õ¡Õ´Õ½Õ¡Õ©Õ«Õ¾Õ¨.
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ÕÕ¿Õ¥Õ²Õ®Õ¸Õ².
+pdfjs-document-properties-producer = PDF-Õ« Õ°Õ¥Õ²Õ«Õ¶Õ¡Õ¯Õ¨.
+pdfjs-document-properties-version = PDF-Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨.
+pdfjs-document-properties-page-count = Ô·Õ»Õ¥Ö€Õ« Ö„Õ¡Õ¶Õ¡Õ¯Õ¨.
+pdfjs-document-properties-page-size = Ô·Õ»Õ« Õ¹Õ¡ÖƒÕ¨.
+pdfjs-document-properties-page-size-unit-inches = Õ¸Ö‚Õ´
+pdfjs-document-properties-page-size-unit-millimeters = Õ´Õ´
+pdfjs-document-properties-page-size-orientation-portrait = Õ¸Ö‚Õ²Õ²Õ¡Õ±Õ«Õ£
+pdfjs-document-properties-page-size-orientation-landscape = Õ°Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Õ†Õ¡Õ´Õ¡Õ¯
+pdfjs-document-properties-page-size-name-legal = Õ•Ö€Õ«Õ¶Õ¡Õ¯Õ¡Õ¶
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Արագ վեբ դիտում․
+pdfjs-document-properties-linearized-yes = Ô±ÕµÕ¸
+pdfjs-document-properties-linearized-no = ÕˆÕ¹
+pdfjs-document-properties-close-button = Õ“Õ¡Õ¯Õ¥Õ¬
+
+## Print
+
+pdfjs-print-progress-message = Õ†Õ¡ÕÕ¡ÕºÕ¡Õ¿Ö€Õ¡Õ½Õ¿Õ¸Ö‚Õ´ Õ§ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ Õ¿ÕºÕ¥Õ¬Õ¸Ö‚Õ¶...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬
+pdfjs-printing-not-supported = Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´. ÕÕºÕ¥Õ¬Õ¨ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸Ö‚Õ´ Õ¤Õ«Õ¿Õ¡Ö€Õ¯Õ«Õ¹Õ« Õ¯Õ¸Õ²Õ´Õ«ÖÖ‰
+pdfjs-printing-not-ready = Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´. PDF-Õ¨ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¹Õ« Õ¢Õ¥Õ¼Õ¶Õ¡Õ¾Õ¸Ö€Õ¾Õ¥Õ¬ Õ¿ÕºÕ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€:
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Ô²Õ¡ÖÕ¥Õ¬/Õ“Õ¡Õ¯Õ¥Õ¬ Ô¿Õ¸Õ²Õ¡ÕµÕ«Õ¶ Õ¾Õ¡Õ°Õ¡Õ¶Õ¡Õ¯Õ¨
+pdfjs-toggle-sidebar-button-label = Ô²Õ¡ÖÕ¥Õ¬/Õ“Õ¡Õ¯Õ¥Õ¬ Ô¿Õ¸Õ²Õ¡ÕµÕ«Õ¶ Õ¾Õ¡Õ°Õ¡Õ¶Õ¡Õ¯Õ¨
+pdfjs-document-outline-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¸Ö‚Ö€Õ¾Õ¡Õ£Õ«Õ®Õ¨ (Õ¯Ö€Õ¯Õ¶Õ¡Õ¯Õ« Õ½Õ¥Õ²Õ´Õ¥Ö„Õ Õ´Õ«Õ¡Õ¾Õ¸Ö€Õ¶Õ¥Ö€Õ¨ Õ¨Õ¶Õ¤Õ¡Ö€Õ±Õ¡Õ¯Õ¥Õ¬Õ¸Ö‚/Õ¯Õ¸Õ®Õ¯Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€)
+pdfjs-document-outline-button-label = Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¢Õ¸Õ¾Õ¡Õ¶Õ¤Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨
+pdfjs-attachments-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¯ÖÕ¸Ö€Õ¤Õ¶Õ¥Ö€Õ¨
+pdfjs-attachments-button-label = Ô¿ÖÕ¸Ö€Õ¤Õ¶Õ¥Ö€
+pdfjs-thumbs-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ„Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¨
+pdfjs-thumbs-button-label = Õ„Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¨
+pdfjs-findbar-button =
+ .title = Ô³Õ¿Õ¶Õ¥Õ¬ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ¸Ö‚Õ´
+pdfjs-findbar-button-label = ÕˆÖ€Õ¸Õ¶Õ¸Ö‚Õ´
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Ô·Õ»Õ¨ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Ô·Õ»Õ« Õ´Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¨ { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ÕˆÖ€Õ¸Õ¶Õ¸Ö‚Õ´
+ .placeholder = Ô³Õ¿Õ¶Õ¥Õ¬ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ¸Ö‚Õ´...
+pdfjs-find-previous-button =
+ .title = Ô³Õ¿Õ¶Õ¥Õ¬ Õ¡Õ¶Ö€Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¶Õ¡ÕÕ¸Ö€Õ¤ Õ°Õ¡Õ¶Õ¤Õ«ÕºÕ¸Ö‚Õ´Õ¨
+pdfjs-find-previous-button-label = Õ†Õ¡ÕÕ¸Ö€Õ¤Õ¨
+pdfjs-find-next-button =
+ .title = Ô³Õ¿Õ«Ö€ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ»Õ¸Ö€Õ¤ Õ°Õ¡Õ¶Õ¤Õ«ÕºÕ¸Ö‚Õ´Õ¨
+pdfjs-find-next-button-label = Õ€Õ¡Õ»Õ¸Ö€Õ¤Õ¨
+pdfjs-find-highlight-checkbox = Ô³Õ¸Ö‚Õ¶Õ¡Õ¶Õ·Õ¥Õ¬ Õ¢Õ¸Õ¬Õ¸Ö€Õ¨
+pdfjs-find-match-case-checkbox-label = Õ„Õ¥Õ®(ÖƒÕ¸Ö„Ö€)Õ¡Õ¿Õ¡Õ¼ Õ°Õ¡Õ·Õ¾Õ« Õ¡Õ¼Õ¶Õ¥Õ¬
+pdfjs-find-entire-word-checkbox-label = Ô±Õ´Õ¢Õ¸Õ²Õ» Õ¢Õ¡Õ¼Õ¥Ö€Õ¨
+pdfjs-find-reached-top = Õ€Õ¡Õ½Õ¥Õ¬ Õ¥Ö„ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¾Õ¥Ö€Ö‡Õ«Õ¶, Õ¯Õ·Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¾Õ« Õ¶Õ¥Ö€Ö„Ö‡Õ«Ö
+pdfjs-find-reached-bottom = Õ€Õ¡Õ½Õ¥Õ¬ Õ¥Ö„ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¾Õ¥Ö€Õ»Õ«Õ¶, Õ¯Õ·Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¾Õ« Õ¾Õ¥Ö€Ö‡Õ«Ö
+pdfjs-find-not-found = Ô±Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¹Õ£Õ¿Õ¶Õ¾Õ¥Ö
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ô·Õ»Õ« Õ¬Õ¡ÕµÕ¶Ö„Õ¨
+pdfjs-page-scale-fit = ÕÕ£Õ¥Õ¬ Õ§Õ»Õ¨
+pdfjs-page-scale-auto = Ô»Õ¶Ö„Õ¶Õ¡Õ·ÕÕ¡Õ¿
+pdfjs-page-scale-actual = Ô»Ö€Õ¡Õ¯Õ¡Õ¶ Õ¹Õ¡ÖƒÕ¨
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = ÕÕÕ¡Õ¬Õ PDF Ö†Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ«Õ½Ö‰
+pdfjs-invalid-file-error = ÕÕÕ¡Õ¬ Õ¯Õ¡Õ´ Õ¾Õ¶Õ¡Õ½Õ¾Õ¡Õ® PDF Ö†Õ¡ÕµÕ¬:
+pdfjs-missing-file-error = PDF Ö†Õ¡ÕµÕ¬Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§:
+pdfjs-unexpected-response-error = ÕÕºÕ¡Õ½Õ¡Ö€Õ¯Õ«Õ¹Õ« Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« ÕºÕ¡Õ¿Õ¡Õ½ÕÕ¡Õ¶:
+pdfjs-rendering-error = ÕÕÕ¡Õ¬Õ Õ§Õ»Õ¨ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ«Õ½:
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Ô¾Õ¡Õ¶Õ¸Õ©Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶]
+
+## Password
+
+pdfjs-password-label = Õ„Õ¸Ö‚Õ¿Ö„Õ¡Õ£Ö€Õ¥Ö„ PDF-Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨:
+pdfjs-password-invalid = Ô³Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Õ½ÕÕ¡Õ¬ Õ§: Ô¿Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Ö„:
+pdfjs-password-ok-button = Ô¼Õ¡Õ¾
+pdfjs-password-cancel-button = Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬
+pdfjs-web-fonts-disabled = ÕŽÕ¥Õ¢-Õ¿Õ¡Õ¼Õ¡Õ¿Õ¥Õ½Õ¡Õ¯Õ¶Õ¥Ö€Õ¨ Õ¡Õ¶Õ»Õ¡Õ¿Õ¾Õ¡Õ® Õ¥Õ¶. Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¶Õ¥Ö€Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¾Õ¡Õ® PDF Õ¿Õ¡Õ¼Õ¡Õ¿Õ¥Õ½Õ¡Õ¯Õ¶Õ¥Ö€Õ¨:
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/hye/viewer.ftl b/www/lib/pdfjs/modern/web/locale/hye/viewer.ftl
new file mode 100644
index 000000000..75cdc0643
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/hye/viewer.ftl
@@ -0,0 +1,268 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Õ†Õ¡ÕÕ¸Ö€Õ¤ Õ§Õ»
+pdfjs-previous-button-label = Õ†Õ¡ÕÕ¸Ö€Õ¤Õ¨
+pdfjs-next-button =
+ .title = Õ…Õ¡Õ»Õ¸Ö€Õ¤ Õ§Õ»
+pdfjs-next-button-label = Õ…Õ¡Õ»Õ¸Ö€Õ¤Õ¨
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Õ§Õ»
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount }-Õ«Ö
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber }-Õ¨ { $pagesCount })-Õ«Ö
+pdfjs-zoom-out-button =
+ .title = Õ“Õ¸Ö„Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-out-button-label = Õ“Õ¸Ö„Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-in-button =
+ .title = Ô½Õ¸Õ·Õ¸Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-in-button-label = Ô½Õ¸Õ·Õ¸Ö€Õ¡ÖÕ¶Õ¥Õ¬
+pdfjs-zoom-select =
+ .title = Ô½Õ¸Õ·Õ¸Ö€Õ¡ÖÕ¸Ö‚Õ´
+pdfjs-presentation-mode-button =
+ .title = Ô±Õ¶ÖÕ¶Õ¥Õ¬ Õ¶Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ´Õ¡Õ¶ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯Õ«Õ¶
+pdfjs-presentation-mode-button-label = Õ†Õ¥Ö€Õ¯Õ¡ÕµÕ¡ÖÕ´Õ¡Õ¶ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯
+pdfjs-open-file-button =
+ .title = Ô²Õ¡ÖÕ¥Õ¬ Õ¶Õ«Õ·Ö„Õ¨
+pdfjs-open-file-button-label = Ô²Õ¡ÖÕ¥Õ¬
+pdfjs-print-button =
+ .title = ÕÕºÕ¥Õ¬
+pdfjs-print-button-label = ÕÕºÕ¥Õ¬
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ô³Õ¸Ö€Õ®Õ«Ö„Õ¶Õ¥Ö€
+pdfjs-tools-button-label = Ô³Õ¸Ö€Õ®Õ«Ö„Õ¶Õ¥Ö€
+pdfjs-first-page-button =
+ .title = Ô³Õ¶Õ¡Õ¬ Õ¤Õ§ÕºÕ« Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ§Õ»
+pdfjs-first-page-button-label = Ô³Õ¶Õ¡Õ¬ Õ¤Õ§ÕºÕ« Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ§Õ»
+pdfjs-last-page-button =
+ .title = Ô³Õ¶Õ¡Õ¬ Õ¤Õ§ÕºÕ« Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»
+pdfjs-last-page-button-label = Ô³Õ¶Õ¡Õ¬ Õ¤Õ§ÕºÕ« Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»
+pdfjs-page-rotate-cw-button =
+ .title = ÕŠÕ¿Õ¿Õ¥Õ¬ ÕªÕ¡Õ´Õ¡ÖÕ¸ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ« Õ¸Ö‚Õ²Õ²Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢
+pdfjs-page-rotate-cw-button-label = ÕŠÕ¿Õ¿Õ¥Õ¬ ÕªÕ¡Õ´Õ¡ÖÕ¸ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ« Õ¸Ö‚Õ²Õ²Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢
+pdfjs-page-rotate-ccw-button =
+ .title = ÕŠÕ¿Õ¿Õ¥Õ¬ ÕªÕ¡Õ´Õ¡ÖÕ¸ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ« Õ°Õ¡Õ¯Õ¡Õ¼Õ¡Õ¯ Õ¸Ö‚Õ²Õ²Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢
+pdfjs-page-rotate-ccw-button-label = ÕŠÕ¿Õ¿Õ¥Õ¬ ÕªÕ¡Õ´Õ¡ÖÕ¸ÕµÖÕ« Õ½Õ¬Õ¡Ö„Õ« Õ°Õ¡Õ¯Õ¡Õ¼Õ¡Õ¯ Õ¸Ö‚Õ²Õ²Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢
+pdfjs-cursor-text-select-tool-button =
+ .title = Õ„Õ«Õ¡ÖÕ¶Õ¥Õ¬ Õ£Ö€Õ¸ÕµÕ© Õ¨Õ¶Õ¿Ö€Õ¥Õ¬Õ¸Ö‚ Õ£Õ¸Ö€Õ®Õ«Ö„Õ¨
+pdfjs-cursor-text-select-tool-button-label = Ô³Ö€Õ¸Ö‚Õ¡Õ®Ö„ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬Õ¸Ö‚ Õ£Õ¸Ö€Õ®Õ«Ö„
+pdfjs-cursor-hand-tool-button =
+ .title = Õ„Õ«Õ¡ÖÕ¶Õ¥Õ¬ Õ±Õ¥Õ¼Ö„Õ« Õ£Õ¸Ö€Õ®Õ«Ö„Õ¨
+pdfjs-cursor-hand-tool-button-label = ÕÕ¥Õ¼Ö„Õ« Õ£Õ¸Ö€Õ®Õ«Ö„
+pdfjs-scroll-page-button =
+ .title = Ô±Ö‚Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ§Õ»Õ« Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-page-button-label = Ô·Õ»Õ« Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-vertical-button =
+ .title = Ô±Ö‚Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¸Ö‚Õ²Õ²Õ¡Õ°Õ¡ÕµÕ¥Õ¡Ö Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-vertical-button-label = ÕˆÖ‚Õ²Õ²Õ¡Õ°Õ¡ÕµÕ¥Õ¡Ö Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-horizontal-button =
+ .title = Ô±Ö‚Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ°Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-horizontal-button-label = Õ€Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-wrapped-button =
+ .title = Ô±Ö‚Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ ÖƒÕ¡Õ©Õ¡Õ©Õ¸Ö‚Õ¡Õ® Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-scroll-wrapped-button-label = Õ“Õ¡Õ©Õ¡Õ©Õ¸Ö‚Õ¡Õ® Õ¸Õ¬Õ¸Ö€Õ¸Ö‚Õ´
+pdfjs-spread-none-button =
+ .title = Õ„Õ« Õ´Õ«Õ¡ÖÕ§Ö„ Õ§Õ»Õ« Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿Õ¸Ö‚Õ´
+pdfjs-spread-none-button-label = Õ‰Õ¯Õ¡Õµ Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿
+pdfjs-spread-odd-button =
+ .title = Õ„Õ«Õ¡ÖÕ§Ö„ Õ§Õ»Õ« Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿Õ«Õ¶ Õ½Õ¯Õ½Õ¥Õ¬Õ¸Õ¾Õ Õ¯Õ¥Õ¶Õ¿ Õ°Õ¡Õ´Õ¡Ö€Õ¡Õ¯Õ¡Õ¬Õ¸Ö‚Õ¡Õ® Õ§Õ»Õ¥Ö€Õ¸Õ¾
+pdfjs-spread-odd-button-label = ÕÕ¡Ö€Õ¡Ö‚Ö€Õ«Õ¶Õ¡Õ¯ Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿
+pdfjs-spread-even-button =
+ .title = Õ„Õ«Õ¡ÖÕ§Ö„ Õ§Õ»Õ« Õ¯Õ¸Õ¶Õ¿Õ¥Ö„Õ½Õ¿Õ«Õ¶ Õ½Õ¯Õ½Õ¥Õ¬Õ¸Õ¾Õ Õ¦Õ¸ÕµÕ£ Õ°Õ¡Õ´Õ¡Ö€Õ¡Õ¯Õ¡Õ¬Õ¸Ö‚Õ¡Õ® Õ§Õ»Õ¥Ö€Õ¸Õ¾
+pdfjs-spread-even-button-label = Õ€Õ¡Ö‚Õ¡Õ½Õ¡Ö€ Õ¾Õ¥Ö€Õ¡Õ®Õ¡Õ®Õ¯Õ¥Ö€
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Փաստաթղթի հատկութիւնները…
+pdfjs-document-properties-button-label = Փաստաթղթի յատկութիւնները…
+pdfjs-document-properties-file-name = Նիշքի անունը․
+pdfjs-document-properties-file-size = Õ†Õ«Õ·Ö„ Õ¹Õ¡ÖƒÕ¨.
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } Ô¿Ô² ({ $size_b } Õ¢Õ¡ÕµÕ©)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } Õ„Ô² ({ $size_b } Õ¢Õ¡ÕµÕ©)
+pdfjs-document-properties-title = ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€
+pdfjs-document-properties-author = Հեղինակ․
+pdfjs-document-properties-subject = Õ¡Õ¼Õ¡Ö€Õ¯Õ¡Õµ
+pdfjs-document-properties-keywords = Õ€Õ«Õ´Õ¶Õ¡Õ¢Õ¡Õ¼Õ¥Ö€
+pdfjs-document-properties-creation-date = ÕÕ¿Õ¥Õ²Õ®Õ´Õ¡Õ¶ Õ¡Õ´Õ½Õ¡Õ©Õ«Ö‚
+pdfjs-document-properties-modification-date = Õ“Õ¸ÖƒÕ¸ÕÕ¸Ö‚Õ©Õ¥Õ¡Õ¶ Õ¡Õ´Õ½Õ¡Õ©Õ«Ö‚.
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ÕÕ¿Õ¥Õ²Õ®Õ¸Õ²
+pdfjs-document-properties-producer = PDF-Õ« Ô±Ö€Õ¿Õ¡Õ¤Ö€Õ¸Õ²Õ¨.
+pdfjs-document-properties-version = PDF-Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨.
+pdfjs-document-properties-page-count = Ô·Õ»Õ¥Ö€Õ« Ö„Õ¡Õ¶Õ¡Õ¯Õ¨.
+pdfjs-document-properties-page-size = Ô·Õ»Õ« Õ¹Õ¡ÖƒÕ¨.
+pdfjs-document-properties-page-size-unit-inches = Õ¸Ö‚Õ´
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = Õ¸Ö‚Õ²Õ²Õ¡Õ±Õ«Õ£
+pdfjs-document-properties-page-size-orientation-landscape = Õ°Õ¸Ö€Õ«Õ¦Õ¸Õ¶Õ¡Õ¯Õ¡Õ¶
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Õ†Õ¡Õ´Õ¡Õ¯
+pdfjs-document-properties-page-size-name-legal = Ô±Ö‚Ö€Õ«Õ¶Õ¡Õ¯Õ¡Õ¶
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Արագ վեբ դիտում․
+pdfjs-document-properties-linearized-yes = Ô±ÕµÕ¸
+pdfjs-document-properties-linearized-no = ÕˆÕ¹
+pdfjs-document-properties-close-button = Õ“Õ¡Õ¯Õ¥Õ¬
+
+## Print
+
+pdfjs-print-progress-message = Õ†Õ¡ÕÕ¡ÕºÕ¡Õ¿Ö€Õ¡Õ½Õ¿Õ¸Ö‚Õ´ Õ§ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ տպելուն…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬
+pdfjs-printing-not-supported = Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´. ÕÕºÕ¥Õ¬Õ¨ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢ Õ¹Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ¸Ö‚Õ´ Õ¦Õ¶Õ¶Õ¡Ö€Õ¯Õ«Õ¹Õ« Õ¯Õ¸Õ²Õ´Õ«ÖÖ‰
+pdfjs-printing-not-ready = Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´. PDFÖŠÕ¨ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¸Ö‚Õ©Õ¥Õ¡Õ´Õ¢ Õ¹Õ« Õ¢Õ¥Õ¼Õ¶Õ¡Ö‚Õ¸Ö€Õ¸Ö‚Õ¥Õ¬ Õ¿ÕºÕ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€Ö‰
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Õ“Õ¸ÕÕ¡Ö€Õ¯Õ¥Õ¬ Õ¯Õ¸Õ²Õ¡ÕµÕ«Õ¶ Õ¾Õ¡Õ°Õ¡Õ¶Õ¡Õ¯Õ¨
+pdfjs-toggle-sidebar-notification-button =
+ .title = Õ“Õ¸ÕÕ¡Õ¶Õ»Õ¡Õ¿Õ¥Õ¬ Õ¯Õ¸Õ²Õ´Õ¶Õ¡Õ½Õ«Ö‚Õ¶Õ¨ (ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ¸Ö‚Õ²Õ©Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ Õ¸Ö‚Ö€Õ¸Ö‚Õ¡Õ£Õ«Õ®/Õ¯ÖÕ¸Ö€Õ¤Õ¶Õ¥Ö€/Õ·Õ¥Ö€Õ¿Õ¥Ö€)
+pdfjs-toggle-sidebar-button-label = Õ“Õ¸ÕÕ¡Ö€Õ¯Õ¥Õ¬ Õ¯Õ¸Õ²Õ¡ÕµÕ«Õ¶ Õ¾Õ¡Õ°Õ¡Õ¶Õ¡Õ¯Õ¨
+pdfjs-document-outline-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¸Ö‚Ö€Õ¸Ö‚Õ¡Õ£Õ«Õ®Õ¨ (Õ¯Ö€Õ¯Õ¶Õ¡Õ¯Õ« Õ½Õ¥Õ²Õ´Õ§Ö„Õ Õ´Õ«Õ¡Ö‚Õ¸Ö€Õ¶Õ¥Ö€Õ¨ Õ¨Õ¶Õ¤Õ¡Ö€Õ±Õ¡Õ¯Õ¥Õ¬Õ¸Ö‚/Õ¯Õ¸Õ®Õ¯Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€)
+pdfjs-document-outline-button-label = Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¸Ö‚Ö€Õ¸Ö‚Õ¡Õ£Õ«Õ®
+pdfjs-attachments-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¯ÖÕ¸Ö€Õ¤Õ¶Õ¥Ö€Õ¨
+pdfjs-attachments-button-label = Ô¿ÖÕ¸Ö€Õ¤Õ¶Õ¥Ö€
+pdfjs-layers-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ·Õ¥Ö€Õ¿Õ¥Ö€Õ¨ (Õ¯Ö€Õ¯Õ¶Õ¡Õ°ÕºÕ¥Õ¬ Õ¾Õ¥Ö€Õ¡Õ¯Õ¡ÕµÕ¥Õ¬Õ¸Ö‚ Õ¢Õ¸Õ¬Õ¸Ö€ Õ·Õ¥Ö€Õ¿Õ¥Ö€Õ¨ Õ½Õ¯Õ¦Õ¢Õ¶Õ¡Õ¤Õ«Ö€ Õ¾Õ«Õ³Õ¡Õ¯Õ«)
+pdfjs-layers-button-label = Õ‡Õ¥Ö€Õ¿Õ¥Ö€
+pdfjs-thumbs-button =
+ .title = Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ´Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¨
+pdfjs-thumbs-button-label = Õ„Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€
+pdfjs-current-outline-item-button =
+ .title = Ô³Õ¿Õ§Ö„ Õ¨Õ¶Õ©Õ¡ÖÕ«Õ¯ Õ£Õ®Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ¿Õ¡Ö€Ö€Õ¨
+pdfjs-current-outline-item-button-label = Ô¸Õ¶Õ©Õ¡ÖÕ«Õ¯ Õ£Õ®Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ¿Õ¡Ö€Ö€
+pdfjs-findbar-button =
+ .title = Ô³Õ¿Õ¶Õ¥Õ¬ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ¸Ö‚Õ´
+pdfjs-findbar-button-label = ÕˆÖ€Õ¸Õ¶Õ¸Ö‚Õ´
+pdfjs-additional-layers = Ô¼Ö€Õ¡ÖÕ¸Ö‚ÖÕ«Õ¹ Õ·Õ¥Ö€Õ¿Õ¥Ö€
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Ô·Õ»Õ¨ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Ô·Õ»Õ« Õ´Õ¡Õ¶Ö€Õ¡ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¨ { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ÕˆÖ€Õ¸Õ¶Õ¸Ö‚Õ´
+ .placeholder = Գտնել փաստաթղթում…
+pdfjs-find-previous-button =
+ .title = Ô³Õ¿Õ¶Õ¥Õ¬ Õ¡Ö€Õ¿Õ¡ÕµÕ¡ÕµÕ¿Õ¸Ö‚Õ©Õ¥Õ¡Õ¶ Õ¶Õ¡ÕÕ¸Ö€Õ¤ Õ¡Ö€Õ¿Õ¡ÕµÕ¡ÕµÕ¿Õ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨
+pdfjs-find-previous-button-label = Õ†Õ¡ÕÕ¸Ö€Õ¤Õ¨
+pdfjs-find-next-button =
+ .title = Ô³Õ¿Õ«Ö€ Õ¡Ö€Õ¿Õ¡ÕµÕ¡ÕµÕ¿Õ¸Ö‚Õ©Õ¥Õ¡Õ¶ ÕµÕ¡Õ»Õ¸Ö€Õ¤ Õ¡Ö€Õ¿Õ¡ÕµÕ¡ÕµÕ¿Õ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨
+pdfjs-find-next-button-label = Õ€Õ¡Õ»Õ¸Ö€Õ¤Õ¨
+pdfjs-find-highlight-checkbox = Ô³Õ¸Ö‚Õ¶Õ¡Õ¶Õ·Õ¥Õ¬ Õ¢Õ¸Õ¬Õ¸Ö€Õ¨
+pdfjs-find-match-case-checkbox-label = Õ€Õ¡Õ·Õ¸Ö‚Õ« Õ¡Õ¼Õ¶Õ¥Õ¬ Õ°Õ¡Õ¶Õ£Õ¡Õ´Õ¡Õ¶Ö„Õ¨
+pdfjs-find-match-diacritics-checkbox-label = Õ€Õ¶Õ¹Õ«Ö‚Õ¶Õ¡Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ«Õ¹ Õ¶Õ·Õ¡Õ¶Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½ÕÕ¡Õ¶Õ¥ÖÕ¸Ö‚Õ´
+pdfjs-find-entire-word-checkbox-label = Ô±Õ´Õ¢Õ¸Õ²Õ» Õ¢Õ¡Õ¼Õ¥Ö€Õ¨
+pdfjs-find-reached-top = Õ€Õ¡Õ½Õ¥Õ¬ Õ¥Ö„ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¾Õ¥Ö€Õ¥Ö‚Õ«Õ¶,Õ·Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬ Õ¶Õ¥Ö€Ö„Õ¥Ö‚Õ«Ö
+pdfjs-find-reached-bottom = Õ€Õ¡Õ½Õ¥Õ¬ Õ§Ö„ ÖƒÕ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ« Õ¾Õ¥Ö€Õ»Õ«Õ¶, Õ·Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬ Õ¾Õ¥Ö€Õ¥Ö‚Õ«Ö
+pdfjs-find-not-found = Ô±Ö€Õ¿Õ¡ÕµÕ¡ÕµÕ¿Õ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨ Õ¹Õ£Õ¿Õ¶Õ¸Ö‚Õ¥Ö
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ô·Õ»Õ« Õ¬Õ¡ÕµÕ¶Õ¸Ö‚Õ©Õ«Ö‚Õ¶
+pdfjs-page-scale-fit = Õ€Õ¡Ö€Õ´Õ¡Ö€Õ¥ÖÕ¶Õ¥Õ¬ Õ§Õ»Õ¨
+pdfjs-page-scale-auto = Ô»Õ¶Ö„Õ¶Õ¡Õ·ÕÕ¡Õ¿ ÕÕ¸Õ·Õ¸Ö€Õ¡ÖÕ¸Ö‚Õ´
+pdfjs-page-scale-actual = Ô»Ö€Õ¡Õ¯Õ¡Õ¶ Õ¹Õ¡ÖƒÕ¨
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Ô·Õ» { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF Õ¶Õ«Õ·Ö„Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ«Õ½ Õ½ÕÕ¡Õ¬ Õ§ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬Ö‰
+pdfjs-invalid-file-error = ÕÕÕ¡Õ¬ Õ¯Õ¡Õ´ Õ¾Õ¶Õ¡Õ½Õ¸Ö‚Õ¡Õ® PDF Õ¶Õ«Õ·Ö„Ö‰
+pdfjs-missing-file-error = PDF Õ¶Õ«Õ·Ö„Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡Õ«Ö‚Õ´ Õ§Ö‰
+pdfjs-unexpected-response-error = ÕÕºÕ¡Õ½Õ¡Ö€Õ¯Õ«Õ¹Õ« Õ¡Õ¶Õ½ÕºÕ¡Õ½Õ¥Õ¬Õ« ÕºÕ¡Õ¿Õ¡Õ½ÕÕ¡Õ¶Ö‰
+pdfjs-rendering-error = ÕÕÕ¡Õ¬ Õ§ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬ Õ§Õ»Õ« Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Ô¾Õ¡Õ¶Õ¸Õ©Õ¸Ö‚Õ©Õ«Ö‚Õ¶]
+
+## Password
+
+pdfjs-password-label = Õ„Õ¸Ö‚Õ¿Ö„Õ¡Õ£Ö€Õ§Ö„ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Õ¡ÕµÕ½ PDF Õ¶Õ«Õ·Ö„Õ¨ Õ¢Õ¡ÖÕ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€
+pdfjs-password-invalid = Ô³Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨ Õ½ÕÕ¡Õ¬ Õ§: Ô¿Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ§Ö„:
+pdfjs-password-ok-button = Ô¼Õ¡Ö‚
+pdfjs-password-cancel-button = Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬
+pdfjs-web-fonts-disabled = ÕŽÕ¥Õ¢-Õ¿Õ¡Õ¼Õ¡Õ¿Õ¥Õ½Õ¡Õ¯Õ¶Õ¥Ö€Õ¨ Õ¡Õ¶Õ»Õ¡Õ¿Õ¸Ö‚Õ¡Õ® Õ¥Õ¶. Õ°Õ¶Õ¡Ö€Õ¡Ö‚Õ¸Ö€ Õ¹Õ§ Õ¡Ö‚Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¶Õ¥Ö€Õ¯Õ¡Õ¼Õ¸Ö‚ÖÕ¸Ö‚Õ¡Õ® PDF Õ¿Õ¡Õ¼Õ¡Õ¿Õ¥Õ½Õ¡Õ¯Õ¶Õ¥Ö€Õ¨Ö‰
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ia/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ia/viewer.ftl
new file mode 100644
index 000000000..5c5a78bf2
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ia/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina previe
+pdfjs-previous-button-label = Previe
+pdfjs-next-button =
+ .title = Pagina sequente
+pdfjs-next-button-label = Sequente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Distantiar
+pdfjs-zoom-out-button-label = Distantiar
+pdfjs-zoom-in-button =
+ .title = Approximar
+pdfjs-zoom-in-button-label = Approximar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Excambiar a modo presentation
+pdfjs-presentation-mode-button-label = Modo presentation
+pdfjs-open-file-button =
+ .title = Aperir le file
+pdfjs-open-file-button-label = Aperir
+pdfjs-print-button =
+ .title = Imprimer
+pdfjs-print-button-label = Imprimer
+pdfjs-save-button =
+ .title = Salvar
+pdfjs-save-button-label = Salvar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Discargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Discargar
+pdfjs-bookmark-button =
+ .title = Pagina actual (vide le URL del pagina actual)
+pdfjs-bookmark-button-label = Pagina actual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Aperir in app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Aperir in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Instrumentos
+pdfjs-tools-button-label = Instrumentos
+pdfjs-first-page-button =
+ .title = Ir al prime pagina
+pdfjs-first-page-button-label = Ir al prime pagina
+pdfjs-last-page-button =
+ .title = Ir al prime pagina
+pdfjs-last-page-button-label = Ir al prime pagina
+pdfjs-page-rotate-cw-button =
+ .title = Rotar in senso horari
+pdfjs-page-rotate-cw-button-label = Rotar in senso horari
+pdfjs-page-rotate-ccw-button =
+ .title = Rotar in senso antihorari
+pdfjs-page-rotate-ccw-button-label = Rotar in senso antihorari
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar le instrumento de selection de texto
+pdfjs-cursor-text-select-tool-button-label = Instrumento de selection de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Activar le instrumento mano
+pdfjs-cursor-hand-tool-button-label = Instrumento mano
+pdfjs-scroll-page-button =
+ .title = Usar rolamento de pagina
+pdfjs-scroll-page-button-label = Rolamento de pagina
+pdfjs-scroll-vertical-button =
+ .title = Usar rolamento vertical
+pdfjs-scroll-vertical-button-label = Rolamento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar rolamento horizontal
+pdfjs-scroll-horizontal-button-label = Rolamento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar rolamento incapsulate
+pdfjs-scroll-wrapped-button-label = Rolamento incapsulate
+pdfjs-spread-none-button =
+ .title = Non junger paginas dual
+pdfjs-spread-none-button-label = Sin paginas dual
+pdfjs-spread-odd-button =
+ .title = Junger paginas dual a partir de paginas con numeros impar
+pdfjs-spread-odd-button-label = Paginas dual impar
+pdfjs-spread-even-button =
+ .title = Junger paginas dual a partir de paginas con numeros par
+pdfjs-spread-even-button-label = Paginas dual par
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Proprietates del documento…
+pdfjs-document-properties-button-label = Proprietates del documento…
+pdfjs-document-properties-file-name = Nomine del file:
+pdfjs-document-properties-file-size = Dimension de file:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Subjecto:
+pdfjs-document-properties-keywords = Parolas clave:
+pdfjs-document-properties-creation-date = Data de creation:
+pdfjs-document-properties-modification-date = Data de modification:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creator:
+pdfjs-document-properties-producer = Productor PDF:
+pdfjs-document-properties-version = Version PDF:
+pdfjs-document-properties-page-count = Numero de paginas:
+pdfjs-document-properties-page-size = Dimension del pagina:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = horizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Littera
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web rapide:
+pdfjs-document-properties-linearized-yes = Si
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Clauder
+
+## Print
+
+pdfjs-print-progress-message = Preparation del documento pro le impression…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancellar
+pdfjs-printing-not-supported = Attention : le impression non es totalmente supportate per ce navigator.
+pdfjs-printing-not-ready = Attention: le file PDF non es integremente cargate pro lo poter imprimer.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Monstrar/celar le barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Monstrar/celar le barra lateral (le documento contine structura/attachamentos/stratos)
+pdfjs-toggle-sidebar-button-label = Monstrar/celar le barra lateral
+pdfjs-document-outline-button =
+ .title = Monstrar le schema del documento (clic duple pro expander/contraher tote le elementos)
+pdfjs-document-outline-button-label = Schema del documento
+pdfjs-attachments-button =
+ .title = Monstrar le annexos
+pdfjs-attachments-button-label = Annexos
+pdfjs-layers-button =
+ .title = Monstrar stratos (clicca duple pro remontar tote le stratos al stato predefinite)
+pdfjs-layers-button-label = Stratos
+pdfjs-thumbs-button =
+ .title = Monstrar le vignettes
+pdfjs-thumbs-button-label = Vignettes
+pdfjs-current-outline-item-button =
+ .title = Trovar le elemento de structura actual
+pdfjs-current-outline-item-button-label = Elemento de structura actual
+pdfjs-findbar-button =
+ .title = Cercar in le documento
+pdfjs-findbar-button-label = Cercar
+pdfjs-additional-layers = Altere stratos
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Vignette del pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Cercar
+ .placeholder = Cercar in le documento…
+pdfjs-find-previous-button =
+ .title = Trovar le previe occurrentia del phrase
+pdfjs-find-previous-button-label = Previe
+pdfjs-find-next-button =
+ .title = Trovar le successive occurrentia del phrase
+pdfjs-find-next-button-label = Sequente
+pdfjs-find-highlight-checkbox = Evidentiar toto
+pdfjs-find-match-case-checkbox-label = Distinguer majusculas/minusculas
+pdfjs-find-match-diacritics-checkbox-label = Differentiar diacriticos
+pdfjs-find-entire-word-checkbox-label = Parolas integre
+pdfjs-find-reached-top = Initio del documento attingite, continuation ab fin
+pdfjs-find-reached-bottom = Fin del documento attingite, continuation ab initio
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } de { $total } correspondentia
+ *[other] { $current } de { $total } correspondentias
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Plus de { $limit } correspondentia
+ *[other] Plus de { $limit } correspondentias
+ }
+pdfjs-find-not-found = Phrase non trovate
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Plen largor del pagina
+pdfjs-page-scale-fit = Pagina integre
+pdfjs-page-scale-auto = Zoom automatic
+pdfjs-page-scale-actual = Dimension real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Un error occurreva durante que on cargava le file PDF.
+pdfjs-invalid-file-error = File PDF corrumpite o non valide.
+pdfjs-missing-file-error = File PDF mancante.
+pdfjs-unexpected-response-error = Responsa del servitor inexpectate.
+pdfjs-rendering-error = Un error occurreva durante que on processava le pagina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Insere le contrasigno pro aperir iste file PDF.
+pdfjs-password-invalid = Contrasigno invalide. Per favor retenta.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancellar
+pdfjs-web-fonts-disabled = Le typos de litteras web es disactivate: impossibile usar le typos de litteras PDF incorporate.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Designar
+pdfjs-editor-ink-button-label = Designar
+pdfjs-editor-stamp-button =
+ .title = Adder o rediger imagines
+pdfjs-editor-stamp-button-label = Adder o rediger imagines
+pdfjs-editor-remove-button =
+ .title = Remover
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Remover le designo
+pdfjs-editor-remove-freetext-button =
+ .title = Remover texto
+pdfjs-editor-remove-stamp-button =
+ .title = Remover imagine
+pdfjs-editor-remove-highlight-button =
+ .title = Remover evidentia
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Dimension
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Spissor
+pdfjs-editor-ink-opacity-input = Opacitate
+pdfjs-editor-stamp-add-image-button =
+ .title = Adder imagine
+pdfjs-editor-stamp-add-image-button-label = Adder imagine
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Comenciar a scriber…
+pdfjs-ink =
+ .aria-label = Editor de designos
+pdfjs-ink-canvas =
+ .aria-label = Imagine create per le usator
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternative
+pdfjs-editor-alt-text-edit-button-label = Rediger texto alternative
+pdfjs-editor-alt-text-dialog-label = Elige un option
+pdfjs-editor-alt-text-dialog-description = Le texto alternative (alt text) adjuta quando le personas non pote vider le imagine o quando illo non carga.
+pdfjs-editor-alt-text-add-description-label = Adder un description
+pdfjs-editor-alt-text-add-description-description = Mira a 1-2 phrases que describe le subjecto, parametro, o actiones.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorative
+pdfjs-editor-alt-text-mark-decorative-description = Isto es usate pro imagines ornamental, como bordaturas o filigranas.
+pdfjs-editor-alt-text-cancel-button = Cancellar
+pdfjs-editor-alt-text-save-button = Salvar
+pdfjs-editor-alt-text-decorative-tooltip = Marcate como decorative
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Per exemplo, “Un juvene sede a un tabula pro mangiar un repastoâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Angulo superior sinistre — redimensionar
+pdfjs-editor-resizer-label-top-middle = Medio superior — redimensionar
+pdfjs-editor-resizer-label-top-right = Angulo superior dextre — redimensionar
+pdfjs-editor-resizer-label-middle-right = Medio dextre — redimensionar
+pdfjs-editor-resizer-label-bottom-right = Angulo inferior dextre — redimensionar
+pdfjs-editor-resizer-label-bottom-middle = Medio inferior — redimensionar
+pdfjs-editor-resizer-label-bottom-left = Angulo inferior sinistre — redimensionar
+pdfjs-editor-resizer-label-middle-left = Medio sinistre — redimensionar
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Color pro evidentiar
+pdfjs-editor-colorpicker-button =
+ .title = Cambiar color
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Electiones del color
+pdfjs-editor-colorpicker-yellow =
+ .title = Jalne
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Blau
+pdfjs-editor-colorpicker-pink =
+ .title = Rosate
+pdfjs-editor-colorpicker-red =
+ .title = Rubie
diff --git a/www/lib/pdfjs/modern/web/locale/id/viewer.ftl b/www/lib/pdfjs/modern/web/locale/id/viewer.ftl
new file mode 100644
index 000000000..fee8d18bf
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/id/viewer.ftl
@@ -0,0 +1,293 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Laman Sebelumnya
+pdfjs-previous-button-label = Sebelumnya
+pdfjs-next-button =
+ .title = Laman Selanjutnya
+pdfjs-next-button-label = Selanjutnya
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Halaman
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = dari { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } dari { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Perkecil
+pdfjs-zoom-out-button-label = Perkecil
+pdfjs-zoom-in-button =
+ .title = Perbesar
+pdfjs-zoom-in-button-label = Perbesar
+pdfjs-zoom-select =
+ .title = Perbesaran
+pdfjs-presentation-mode-button =
+ .title = Ganti ke Mode Presentasi
+pdfjs-presentation-mode-button-label = Mode Presentasi
+pdfjs-open-file-button =
+ .title = Buka Berkas
+pdfjs-open-file-button-label = Buka
+pdfjs-print-button =
+ .title = Cetak
+pdfjs-print-button-label = Cetak
+pdfjs-save-button =
+ .title = Simpan
+pdfjs-save-button-label = Simpan
+pdfjs-bookmark-button =
+ .title = Laman Saat Ini (Lihat URL dari Laman Sekarang)
+pdfjs-bookmark-button-label = Laman Saat Ini
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Alat
+pdfjs-tools-button-label = Alat
+pdfjs-first-page-button =
+ .title = Buka Halaman Pertama
+pdfjs-first-page-button-label = Buka Halaman Pertama
+pdfjs-last-page-button =
+ .title = Buka Halaman Terakhir
+pdfjs-last-page-button-label = Buka Halaman Terakhir
+pdfjs-page-rotate-cw-button =
+ .title = Putar Searah Jarum Jam
+pdfjs-page-rotate-cw-button-label = Putar Searah Jarum Jam
+pdfjs-page-rotate-ccw-button =
+ .title = Putar Berlawanan Arah Jarum Jam
+pdfjs-page-rotate-ccw-button-label = Putar Berlawanan Arah Jarum Jam
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktifkan Alat Seleksi Teks
+pdfjs-cursor-text-select-tool-button-label = Alat Seleksi Teks
+pdfjs-cursor-hand-tool-button =
+ .title = Aktifkan Alat Tangan
+pdfjs-cursor-hand-tool-button-label = Alat Tangan
+pdfjs-scroll-page-button =
+ .title = Gunakan Pengguliran Laman
+pdfjs-scroll-page-button-label = Pengguliran Laman
+pdfjs-scroll-vertical-button =
+ .title = Gunakan Penggeseran Vertikal
+pdfjs-scroll-vertical-button-label = Penggeseran Vertikal
+pdfjs-scroll-horizontal-button =
+ .title = Gunakan Penggeseran Horizontal
+pdfjs-scroll-horizontal-button-label = Penggeseran Horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Gunakan Penggeseran Terapit
+pdfjs-scroll-wrapped-button-label = Penggeseran Terapit
+pdfjs-spread-none-button =
+ .title = Jangan gabungkan lembar halaman
+pdfjs-spread-none-button-label = Tidak Ada Lembaran
+pdfjs-spread-odd-button =
+ .title = Gabungkan lembar lamanan mulai dengan halaman ganjil
+pdfjs-spread-odd-button-label = Lembaran Ganjil
+pdfjs-spread-even-button =
+ .title = Gabungkan lembar halaman dimulai dengan halaman genap
+pdfjs-spread-even-button-label = Lembaran Genap
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Properti Dokumen…
+pdfjs-document-properties-button-label = Properti Dokumen…
+pdfjs-document-properties-file-name = Nama berkas:
+pdfjs-document-properties-file-size = Ukuran berkas:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Judul:
+pdfjs-document-properties-author = Penyusun:
+pdfjs-document-properties-subject = Subjek:
+pdfjs-document-properties-keywords = Kata Kunci:
+pdfjs-document-properties-creation-date = Tanggal Dibuat:
+pdfjs-document-properties-modification-date = Tanggal Dimodifikasi:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Pembuat:
+pdfjs-document-properties-producer = Pemroduksi PDF:
+pdfjs-document-properties-version = Versi PDF:
+pdfjs-document-properties-page-count = Jumlah Halaman:
+pdfjs-document-properties-page-size = Ukuran Laman:
+pdfjs-document-properties-page-size-unit-inches = inci
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = tegak
+pdfjs-document-properties-page-size-orientation-landscape = mendatar
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Tampilan Web Kilat:
+pdfjs-document-properties-linearized-yes = Ya
+pdfjs-document-properties-linearized-no = Tidak
+pdfjs-document-properties-close-button = Tutup
+
+## Print
+
+pdfjs-print-progress-message = Menyiapkan dokumen untuk pencetakan…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Batalkan
+pdfjs-printing-not-supported = Peringatan: Pencetakan tidak didukung secara lengkap pada peramban ini.
+pdfjs-printing-not-ready = Peringatan: Berkas PDF masih belum dimuat secara lengkap untuk dapat dicetak.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Aktif/Nonaktifkan Bilah Samping
+pdfjs-toggle-sidebar-notification-button =
+ .title = Aktif/Nonaktifkan Bilah Samping (dokumen berisi kerangka/lampiran/lapisan)
+pdfjs-toggle-sidebar-button-label = Aktif/Nonaktifkan Bilah Samping
+pdfjs-document-outline-button =
+ .title = Tampilkan Kerangka Dokumen (klik ganda untuk membentangkan/menciutkan semua item)
+pdfjs-document-outline-button-label = Kerangka Dokumen
+pdfjs-attachments-button =
+ .title = Tampilkan Lampiran
+pdfjs-attachments-button-label = Lampiran
+pdfjs-layers-button =
+ .title = Tampilkan Lapisan (klik ganda untuk mengatur ulang semua lapisan ke keadaan baku)
+pdfjs-layers-button-label = Lapisan
+pdfjs-thumbs-button =
+ .title = Tampilkan Miniatur
+pdfjs-thumbs-button-label = Miniatur
+pdfjs-current-outline-item-button =
+ .title = Cari Butir Ikhtisar Saat Ini
+pdfjs-current-outline-item-button-label = Butir Ikhtisar Saat Ini
+pdfjs-findbar-button =
+ .title = Temukan di Dokumen
+pdfjs-findbar-button-label = Temukan
+pdfjs-additional-layers = Lapisan Tambahan
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Laman { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatur Laman { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Temukan
+ .placeholder = Temukan di dokumen…
+pdfjs-find-previous-button =
+ .title = Temukan kata sebelumnya
+pdfjs-find-previous-button-label = Sebelumnya
+pdfjs-find-next-button =
+ .title = Temukan lebih lanjut
+pdfjs-find-next-button-label = Selanjutnya
+pdfjs-find-highlight-checkbox = Sorot semuanya
+pdfjs-find-match-case-checkbox-label = Cocokkan BESAR/kecil
+pdfjs-find-match-diacritics-checkbox-label = Pencocokan Diakritik
+pdfjs-find-entire-word-checkbox-label = Seluruh teks
+pdfjs-find-reached-top = Sampai di awal dokumen, dilanjutkan dari bawah
+pdfjs-find-reached-bottom = Sampai di akhir dokumen, dilanjutkan dari atas
+pdfjs-find-not-found = Frasa tidak ditemukan
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lebar Laman
+pdfjs-page-scale-fit = Muat Laman
+pdfjs-page-scale-auto = Perbesaran Otomatis
+pdfjs-page-scale-actual = Ukuran Asli
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Halaman { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Galat terjadi saat memuat PDF.
+pdfjs-invalid-file-error = Berkas PDF tidak valid atau rusak.
+pdfjs-missing-file-error = Berkas PDF tidak ada.
+pdfjs-unexpected-response-error = Balasan server yang tidak diharapkan.
+pdfjs-rendering-error = Galat terjadi saat merender laman.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotasi { $type }]
+
+## Password
+
+pdfjs-password-label = Masukkan sandi untuk membuka berkas PDF ini.
+pdfjs-password-invalid = Sandi tidak valid. Silakan coba lagi.
+pdfjs-password-ok-button = Oke
+pdfjs-password-cancel-button = Batal
+pdfjs-web-fonts-disabled = Font web dinonaktifkan: tidak dapat menggunakan font PDF yang tersemat.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Teks
+pdfjs-editor-free-text-button-label = Teks
+pdfjs-editor-ink-button =
+ .title = Gambar
+pdfjs-editor-ink-button-label = Gambar
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Warna
+pdfjs-editor-free-text-size-input = Ukuran
+pdfjs-editor-ink-color-input = Warna
+pdfjs-editor-ink-thickness-input = Ketebalan
+pdfjs-editor-ink-opacity-input = Opasitas
+pdfjs-free-text =
+ .aria-label = Editor Teks
+pdfjs-free-text-default-content = Mulai mengetik…
+pdfjs-ink =
+ .aria-label = Editor Gambar
+pdfjs-ink-canvas =
+ .aria-label = Gambar yang dibuat pengguna
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/is/viewer.ftl b/www/lib/pdfjs/modern/web/locale/is/viewer.ftl
new file mode 100644
index 000000000..e874b4001
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/is/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Fyrri sÃða
+pdfjs-previous-button-label = Fyrri
+pdfjs-next-button =
+ .title = Næsta sÃða
+pdfjs-next-button-label = Næsti
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = SÃða
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = af { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } af { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Minnka aðdrátt
+pdfjs-zoom-out-button-label = Minnka aðdrátt
+pdfjs-zoom-in-button =
+ .title = Auka aðdrátt
+pdfjs-zoom-in-button-label = Auka aðdrátt
+pdfjs-zoom-select =
+ .title = Aðdráttur
+pdfjs-presentation-mode-button =
+ .title = Skipta yfir á kynningarham
+pdfjs-presentation-mode-button-label = Kynningarhamur
+pdfjs-open-file-button =
+ .title = Opna skrá
+pdfjs-open-file-button-label = Opna
+pdfjs-print-button =
+ .title = Prenta
+pdfjs-print-button-label = Prenta
+pdfjs-save-button =
+ .title = Vista
+pdfjs-save-button-label = Vista
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Sækja
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Sækja
+pdfjs-bookmark-button =
+ .title = Núverandi sÃða (Skoða vefslóð frá núverandi sÃðu)
+pdfjs-bookmark-button-label = Núverandi sÃða
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Opna à smáforriti
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Opna à smáforriti
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Verkfæri
+pdfjs-tools-button-label = Verkfæri
+pdfjs-first-page-button =
+ .title = Fara á fyrstu sÃðu
+pdfjs-first-page-button-label = Fara á fyrstu sÃðu
+pdfjs-last-page-button =
+ .title = Fara á sÃðustu sÃðu
+pdfjs-last-page-button-label = Fara á sÃðustu sÃðu
+pdfjs-page-rotate-cw-button =
+ .title = Snúa réttsælis
+pdfjs-page-rotate-cw-button-label = Snúa réttsælis
+pdfjs-page-rotate-ccw-button =
+ .title = Snúa rangsælis
+pdfjs-page-rotate-ccw-button-label = Snúa rangsælis
+pdfjs-cursor-text-select-tool-button =
+ .title = Virkja textavalsáhald
+pdfjs-cursor-text-select-tool-button-label = Textavalsáhald
+pdfjs-cursor-hand-tool-button =
+ .title = Virkja handarverkfæri
+pdfjs-cursor-hand-tool-button-label = Handarverkfæri
+pdfjs-scroll-page-button =
+ .title = Nota sÃðuskrun
+pdfjs-scroll-page-button-label = SÃðuskrun
+pdfjs-scroll-vertical-button =
+ .title = Nota lóðrétt skrun
+pdfjs-scroll-vertical-button-label = Lóðrétt skrun
+pdfjs-scroll-horizontal-button =
+ .title = Nota lárétt skrun
+pdfjs-scroll-horizontal-button-label = Lárétt skrun
+pdfjs-scroll-wrapped-button =
+ .title = Nota lÃnuskipt sÃðuskrun
+pdfjs-scroll-wrapped-button-label = LÃnuskipt sÃðuskrun
+pdfjs-spread-none-button =
+ .title = Ekki taka þátt à dreifingu sÃðna
+pdfjs-spread-none-button-label = Engin dreifing
+pdfjs-spread-odd-button =
+ .title = Taka þátt à dreifingu sÃðna með oddatölum
+pdfjs-spread-odd-button-label = Oddatöludreifing
+pdfjs-spread-even-button =
+ .title = Taktu þátt à dreifingu sÃðna með jöfnuntölum
+pdfjs-spread-even-button-label = Jafnatöludreifing
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Eiginleikar skjals…
+pdfjs-document-properties-button-label = Eiginleikar skjals…
+pdfjs-document-properties-file-name = Skráarnafn:
+pdfjs-document-properties-file-size = Skrárstærð:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titill:
+pdfjs-document-properties-author = Hönnuður:
+pdfjs-document-properties-subject = Efni:
+pdfjs-document-properties-keywords = Stikkorð:
+pdfjs-document-properties-creation-date = Búið til:
+pdfjs-document-properties-modification-date = Dags breytingar:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Höfundur:
+pdfjs-document-properties-producer = PDF framleiðandi:
+pdfjs-document-properties-version = PDF útgáfa:
+pdfjs-document-properties-page-count = BlaðsÃðufjöldi:
+pdfjs-document-properties-page-size = Stærð sÃðu:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = skammsnið
+pdfjs-document-properties-page-size-orientation-landscape = langsnið
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fljótleg vefskoðun:
+pdfjs-document-properties-linearized-yes = Já
+pdfjs-document-properties-linearized-no = Nei
+pdfjs-document-properties-close-button = Loka
+
+## Print
+
+pdfjs-print-progress-message = Undirbý skjal fyrir prentun…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Hætta við
+pdfjs-printing-not-supported = Aðvörun: Prentun er ekki með fyllilegan stuðning á þessum vafra.
+pdfjs-printing-not-ready = Aðvörun: Ekki er búið að hlaða inn allri PDF skránni fyrir prentun.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = VÃxla hliðarspjaldi af/á
+pdfjs-toggle-sidebar-notification-button =
+ .title = VÃxla hliðarslá (skjal inniheldur yfirlit/viðhengi/lög)
+pdfjs-toggle-sidebar-button-label = VÃxla hliðarspjaldi af/á
+pdfjs-document-outline-button =
+ .title = Sýna yfirlit skjals (tvÃsmelltu til að opna/loka öllum hlutum)
+pdfjs-document-outline-button-label = Efnisskipan skjals
+pdfjs-attachments-button =
+ .title = Sýna viðhengi
+pdfjs-attachments-button-label = Viðhengi
+pdfjs-layers-button =
+ .title = Birta lög (tvÃsmelltu til að endurstilla öll lög à sjálfgefna stöðu)
+pdfjs-layers-button-label = Lög
+pdfjs-thumbs-button =
+ .title = Sýna smámyndir
+pdfjs-thumbs-button-label = Smámyndir
+pdfjs-current-outline-item-button =
+ .title = Finna núverandi atriði efnisskipunar
+pdfjs-current-outline-item-button-label = Núverandi atriði efnisskipunar
+pdfjs-findbar-button =
+ .title = Leita à skjali
+pdfjs-findbar-button-label = Leita
+pdfjs-additional-layers = Viðbótarlög
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = SÃða { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Smámynd af sÃðu { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Leita
+ .placeholder = Leita à skjali…
+pdfjs-find-previous-button =
+ .title = Leita að fyrra tilfelli þessara orða
+pdfjs-find-previous-button-label = Fyrri
+pdfjs-find-next-button =
+ .title = Leita að næsta tilfelli þessara orða
+pdfjs-find-next-button-label = Næsti
+pdfjs-find-highlight-checkbox = Lita allt
+pdfjs-find-match-case-checkbox-label = Passa við stafstöðu
+pdfjs-find-match-diacritics-checkbox-label = Passa við broddstafi
+pdfjs-find-entire-word-checkbox-label = Heil orð
+pdfjs-find-reached-top = Náði efst à skjal, held áfram neðst
+pdfjs-find-reached-bottom = Náði enda skjals, held áfram efst
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } af { $total } passar við
+ *[other] { $current } af { $total } passa við
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Fleiri en { $limit } passar við
+ *[other] Fleiri en { $limit } passa við
+ }
+pdfjs-find-not-found = Fann ekki orðið
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = SÃðubreidd
+pdfjs-page-scale-fit = Passa á sÃðu
+pdfjs-page-scale-auto = Sjálfvirkur aðdráttur
+pdfjs-page-scale-actual = Raunstærð
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = SÃða { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Villa kom upp við að hlaða inn PDF.
+pdfjs-invalid-file-error = Ógild eða skemmd PDF skrá.
+pdfjs-missing-file-error = Vantar PDF skrá.
+pdfjs-unexpected-response-error = Óvænt svar frá netþjóni.
+pdfjs-rendering-error = Upp kom villa við að birta sÃðuna.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Skýring]
+
+## Password
+
+pdfjs-password-label = Sláðu inn lykilorð til að opna þessa PDF skrá.
+pdfjs-password-invalid = Ógilt lykilorð. Reyndu aftur.
+pdfjs-password-ok-button = Ã lagi
+pdfjs-password-cancel-button = Hætta við
+pdfjs-web-fonts-disabled = Vef leturgerðir eru óvirkar: get ekki notað innbyggðar PDF leturgerðir.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texti
+pdfjs-editor-free-text-button-label = Texti
+pdfjs-editor-ink-button =
+ .title = Teikna
+pdfjs-editor-ink-button-label = Teikna
+pdfjs-editor-stamp-button =
+ .title = Bæta við eða breyta myndum
+pdfjs-editor-stamp-button-label = Bæta við eða breyta myndum
+pdfjs-editor-remove-button =
+ .title = Fjarlægja
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Fjarlægja teikningu
+pdfjs-editor-remove-freetext-button =
+ .title = Fjarlægja texta
+pdfjs-editor-remove-stamp-button =
+ .title = Fjarlægja mynd
+pdfjs-editor-remove-highlight-button =
+ .title = Fjarlægja áherslulit
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Litur
+pdfjs-editor-free-text-size-input = Stærð
+pdfjs-editor-ink-color-input = Litur
+pdfjs-editor-ink-thickness-input = Þykkt
+pdfjs-editor-ink-opacity-input = Ógegnsæi
+pdfjs-editor-stamp-add-image-button =
+ .title = Bæta við mynd
+pdfjs-editor-stamp-add-image-button-label = Bæta við mynd
+pdfjs-free-text =
+ .aria-label = Textaritill
+pdfjs-free-text-default-content = Byrjaðu að skrifa…
+pdfjs-ink =
+ .aria-label = Teikniritill
+pdfjs-ink-canvas =
+ .aria-label = Mynd gerð af notanda
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alt-varatexti
+pdfjs-editor-alt-text-edit-button-label = Breyta alt-varatexta
+pdfjs-editor-alt-text-dialog-label = Veldu valkost
+pdfjs-editor-alt-text-dialog-description = Alt-varatexti (auka-myndatexti) hjálpar þegar fólk getur ekki séð myndina eða þegar hún hleðst ekki inn.
+pdfjs-editor-alt-text-add-description-label = Bættu við lýsingu
+pdfjs-editor-alt-text-add-description-description = Reyndu að takmarka þetta við 1-2 setningar sem lýsa efninu, umhverfi eða aðgerðum.
+pdfjs-editor-alt-text-mark-decorative-label = Merkja sem skraut
+pdfjs-editor-alt-text-mark-decorative-description = Þetta er notað fyrir skrautmyndir, eins og borða eða vatnsmerki.
+pdfjs-editor-alt-text-cancel-button = Hætta við
+pdfjs-editor-alt-text-save-button = Vista
+pdfjs-editor-alt-text-decorative-tooltip = Merkt sem skraut
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Til dæmis: „Ungur maður sest við borð til að snæða máltÃð“
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Efst à vinstra horni - breyta stærð
+pdfjs-editor-resizer-label-top-middle = Efst á miðju - breyta stærð
+pdfjs-editor-resizer-label-top-right = Efst à hægra horni - breyta stærð
+pdfjs-editor-resizer-label-middle-right = Miðja til hægri - breyta stærð
+pdfjs-editor-resizer-label-bottom-right = Neðst à hægra horni - breyta stærð
+pdfjs-editor-resizer-label-bottom-middle = Neðst á miðju - breyta stærð
+pdfjs-editor-resizer-label-bottom-left = Neðst à vinstra horni - breyta stærð
+pdfjs-editor-resizer-label-middle-left = Miðja til vinstri - breyta stærð
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Ãherslulitur
+pdfjs-editor-colorpicker-button =
+ .title = Skipta um lit
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Val lita
+pdfjs-editor-colorpicker-yellow =
+ .title = Gult
+pdfjs-editor-colorpicker-green =
+ .title = Grænt
+pdfjs-editor-colorpicker-blue =
+ .title = Blátt
+pdfjs-editor-colorpicker-pink =
+ .title = Bleikt
+pdfjs-editor-colorpicker-red =
+ .title = Rautt
diff --git a/www/lib/pdfjs/modern/web/locale/it/viewer.ftl b/www/lib/pdfjs/modern/web/locale/it/viewer.ftl
new file mode 100644
index 000000000..18bef2ed1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/it/viewer.ftl
@@ -0,0 +1,389 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina precedente
+pdfjs-previous-button-label = Precedente
+pdfjs-next-button =
+ .title = Pagina successiva
+pdfjs-next-button-label = Successiva
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = di { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } di { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Riduci zoom
+pdfjs-zoom-out-button-label = Riduci zoom
+pdfjs-zoom-in-button =
+ .title = Aumenta zoom
+pdfjs-zoom-in-button-label = Aumenta zoom
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Passa alla modalità presentazione
+pdfjs-presentation-mode-button-label = Modalità presentazione
+pdfjs-open-file-button =
+ .title = Apri file
+pdfjs-open-file-button-label = Apri
+pdfjs-print-button =
+ .title = Stampa
+pdfjs-print-button-label = Stampa
+pdfjs-save-button =
+ .title = Salva
+pdfjs-save-button-label = Salva
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Scarica
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Scarica
+pdfjs-bookmark-button =
+ .title = Pagina corrente (mostra URL della pagina corrente)
+pdfjs-bookmark-button-label = Pagina corrente
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Apri in app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Apri in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Strumenti
+pdfjs-tools-button-label = Strumenti
+pdfjs-first-page-button =
+ .title = Vai alla prima pagina
+pdfjs-first-page-button-label = Vai alla prima pagina
+pdfjs-last-page-button =
+ .title = Vai all’ultima pagina
+pdfjs-last-page-button-label = Vai all’ultima pagina
+pdfjs-page-rotate-cw-button =
+ .title = Ruota in senso orario
+pdfjs-page-rotate-cw-button-label = Ruota in senso orario
+pdfjs-page-rotate-ccw-button =
+ .title = Ruota in senso antiorario
+pdfjs-page-rotate-ccw-button-label = Ruota in senso antiorario
+pdfjs-cursor-text-select-tool-button =
+ .title = Attiva strumento di selezione testo
+pdfjs-cursor-text-select-tool-button-label = Strumento di selezione testo
+pdfjs-cursor-hand-tool-button =
+ .title = Attiva strumento mano
+pdfjs-cursor-hand-tool-button-label = Strumento mano
+pdfjs-scroll-page-button =
+ .title = Utilizza scorrimento pagine
+pdfjs-scroll-page-button-label = Scorrimento pagine
+pdfjs-scroll-vertical-button =
+ .title = Scorri le pagine in verticale
+pdfjs-scroll-vertical-button-label = Scorrimento verticale
+pdfjs-scroll-horizontal-button =
+ .title = Scorri le pagine in orizzontale
+pdfjs-scroll-horizontal-button-label = Scorrimento orizzontale
+pdfjs-scroll-wrapped-button =
+ .title = Scorri le pagine in verticale, disponendole da sinistra a destra e andando a capo automaticamente
+pdfjs-scroll-wrapped-button-label = Scorrimento con a capo automatico
+pdfjs-spread-none-button =
+ .title = Non raggruppare pagine
+pdfjs-spread-none-button-label = Nessun raggruppamento
+pdfjs-spread-odd-button =
+ .title = Crea gruppi di pagine che iniziano con numeri di pagina dispari
+pdfjs-spread-odd-button-label = Raggruppamento dispari
+pdfjs-spread-even-button =
+ .title = Crea gruppi di pagine che iniziano con numeri di pagina pari
+pdfjs-spread-even-button-label = Raggruppamento pari
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Proprietà del documento…
+pdfjs-document-properties-button-label = Proprietà del documento…
+pdfjs-document-properties-file-name = Nome file:
+pdfjs-document-properties-file-size = Dimensione file:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Titolo:
+pdfjs-document-properties-author = Autore:
+pdfjs-document-properties-subject = Oggetto:
+pdfjs-document-properties-keywords = Parole chiave:
+pdfjs-document-properties-creation-date = Data creazione:
+pdfjs-document-properties-modification-date = Data modifica:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Autore originale:
+pdfjs-document-properties-producer = Produttore PDF:
+pdfjs-document-properties-version = Versione PDF:
+pdfjs-document-properties-page-count = Conteggio pagine:
+pdfjs-document-properties-page-size = Dimensioni pagina:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = verticale
+pdfjs-document-properties-page-size-orientation-landscape = orizzontale
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Lettera
+pdfjs-document-properties-page-size-name-legal = Legale
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Visualizzazione web veloce:
+pdfjs-document-properties-linearized-yes = Sì
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Chiudi
+
+## Print
+
+pdfjs-print-progress-message = Preparazione documento per la stampa…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Annulla
+pdfjs-printing-not-supported = Attenzione: la stampa non è completamente supportata da questo browser.
+pdfjs-printing-not-ready = Attenzione: il PDF non è ancora stato caricato completamente per la stampa.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Attiva/disattiva barra laterale
+pdfjs-toggle-sidebar-notification-button =
+ .title = Attiva/disattiva barra laterale (il documento contiene struttura/allegati/livelli)
+pdfjs-toggle-sidebar-button-label = Attiva/disattiva barra laterale
+pdfjs-document-outline-button =
+ .title = Visualizza la struttura del documento (doppio clic per visualizzare/comprimere tutti gli elementi)
+pdfjs-document-outline-button-label = Struttura documento
+pdfjs-attachments-button =
+ .title = Visualizza allegati
+pdfjs-attachments-button-label = Allegati
+pdfjs-layers-button =
+ .title = Visualizza livelli (doppio clic per ripristinare tutti i livelli allo stato predefinito)
+pdfjs-layers-button-label = Livelli
+pdfjs-thumbs-button =
+ .title = Mostra le miniature
+pdfjs-thumbs-button-label = Miniature
+pdfjs-current-outline-item-button =
+ .title = Trova elemento struttura corrente
+pdfjs-current-outline-item-button-label = Elemento struttura corrente
+pdfjs-findbar-button =
+ .title = Trova nel documento
+pdfjs-findbar-button-label = Trova
+pdfjs-additional-layers = Livelli aggiuntivi
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura della pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Trova
+ .placeholder = Trova nel documento…
+pdfjs-find-previous-button =
+ .title = Trova l’occorrenza precedente del testo da cercare
+pdfjs-find-previous-button-label = Precedente
+pdfjs-find-next-button =
+ .title = Trova l’occorrenza successiva del testo da cercare
+pdfjs-find-next-button-label = Successivo
+pdfjs-find-highlight-checkbox = Evidenzia
+pdfjs-find-match-case-checkbox-label = Maiuscole/minuscole
+pdfjs-find-match-diacritics-checkbox-label = Segni diacritici
+pdfjs-find-entire-word-checkbox-label = Parole intere
+pdfjs-find-reached-top = Raggiunto l’inizio della pagina, continua dalla fine
+pdfjs-find-reached-bottom = Raggiunta la fine della pagina, continua dall’inizio
+
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } di { $total } corrispondenza
+ *[other] { $current } di { $total } corrispondenze
+ }
+
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Più di una { $limit } corrispondenza
+ *[other] Più di { $limit } corrispondenze
+ }
+
+pdfjs-find-not-found = Testo non trovato
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Larghezza pagina
+pdfjs-page-scale-fit = Adatta a una pagina
+pdfjs-page-scale-auto = Zoom automatico
+pdfjs-page-scale-actual = Dimensioni effettive
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Si è verificato un errore durante il caricamento del PDF.
+pdfjs-invalid-file-error = File PDF non valido o danneggiato.
+pdfjs-missing-file-error = File PDF non disponibile.
+pdfjs-unexpected-response-error = Risposta imprevista del server
+pdfjs-rendering-error = Si è verificato un errore durante il rendering della pagina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Annotazione: { $type }]
+
+## Password
+
+pdfjs-password-label = Inserire la password per aprire questo file PDF.
+pdfjs-password-invalid = Password non corretta. Riprovare.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Annulla
+pdfjs-web-fonts-disabled = I web font risultano disattivati: impossibile utilizzare i caratteri incorporati nel PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Testo
+pdfjs-editor-free-text-button-label = Testo
+pdfjs-editor-ink-button =
+ .title = Disegno
+pdfjs-editor-ink-button-label = Disegno
+pdfjs-editor-stamp-button =
+ .title = Aggiungi o rimuovi immagine
+pdfjs-editor-stamp-button-label = Aggiungi o rimuovi immagine
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Rimuovi disegno
+pdfjs-editor-remove-freetext-button =
+ .title = Rimuovi testo
+pdfjs-editor-remove-stamp-button =
+ .title = Rimuovi immagine
+pdfjs-editor-remove-highlight-button =
+ .title = Rimuovi evidenziazione
+
+##
+
+pdfjs-editor-remove-button =
+ .title = Rimuovi
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colore
+pdfjs-editor-free-text-size-input = Dimensione
+pdfjs-editor-ink-color-input = Colore
+pdfjs-editor-ink-thickness-input = Spessore
+pdfjs-editor-ink-opacity-input = OpacitÃ
+pdfjs-editor-stamp-add-image-button =
+ .title = Aggiungi immagine
+pdfjs-editor-stamp-add-image-button-label = Aggiungi immagine
+pdfjs-free-text =
+ .aria-label = Editor di testo
+pdfjs-free-text-default-content = Inizia a digitare…
+pdfjs-ink =
+ .aria-label = Editor disegni
+pdfjs-ink-canvas =
+ .aria-label = Immagine creata dall’utente
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Testo alternativo
+pdfjs-editor-alt-text-edit-button-label = Modifica testo alternativo
+pdfjs-editor-alt-text-dialog-label = Scegli un’opzione
+pdfjs-editor-alt-text-dialog-description = Il testo alternativo (“alt textâ€) aiuta quando le persone non possono vedere l’immagine o quando l’immagine non viene caricata.
+pdfjs-editor-alt-text-add-description-label = Aggiungi una descrizione
+pdfjs-editor-alt-text-add-description-description = Punta a una o due frasi che descrivono l’argomento, l’ambientazione o le azioni.
+pdfjs-editor-alt-text-mark-decorative-label = Contrassegna come decorativa
+pdfjs-editor-alt-text-mark-decorative-description = Viene utilizzato per immagini ornamentali, come bordi o filigrane.
+pdfjs-editor-alt-text-cancel-button = Annulla
+pdfjs-editor-alt-text-save-button = Salva
+pdfjs-editor-alt-text-decorative-tooltip = Contrassegnata come decorativa
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Ad esempio, “Un giovane si siede a tavola per mangiareâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Angolo in alto a sinistra — ridimensiona
+pdfjs-editor-resizer-label-top-middle = Lato superiore nel mezzo — ridimensiona
+pdfjs-editor-resizer-label-top-right = Angolo in alto a destra — ridimensiona
+pdfjs-editor-resizer-label-middle-right = Lato destro nel mezzo — ridimensiona
+pdfjs-editor-resizer-label-bottom-right = Angolo in basso a destra — ridimensiona
+pdfjs-editor-resizer-label-bottom-middle = Lato inferiore nel mezzo — ridimensiona
+pdfjs-editor-resizer-label-bottom-left = Angolo in basso a sinistra — ridimensiona
+pdfjs-editor-resizer-label-middle-left = Lato sinistro nel mezzo — ridimensiona
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Colore evidenziatore
+
+pdfjs-editor-colorpicker-button =
+ .title = Cambia colore
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Colori disponibili
+pdfjs-editor-colorpicker-yellow =
+ .title = Giallo
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Blu
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Rosso
+
diff --git a/www/lib/pdfjs/modern/web/locale/ja/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ja/viewer.ftl
new file mode 100644
index 000000000..a378c7a50
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ja/viewer.ftl
@@ -0,0 +1,363 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = å‰ã®ãƒšãƒ¼ã‚¸ã¸æˆ»ã‚Šã¾ã™
+pdfjs-previous-button-label = å‰ã¸
+pdfjs-next-button =
+ .title = 次ã®ãƒšãƒ¼ã‚¸ã¸é€²ã¿ã¾ã™
+pdfjs-next-button-label = 次ã¸
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ページ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = 表示を縮å°ã—ã¾ã™
+pdfjs-zoom-out-button-label = 縮å°
+pdfjs-zoom-in-button =
+ .title = 表示を拡大ã—ã¾ã™
+pdfjs-zoom-in-button-label = 拡大
+pdfjs-zoom-select =
+ .title = 拡大/縮å°
+pdfjs-presentation-mode-button =
+ .title = プレゼンテーションモードã«åˆ‡ã‚Šæ›¿ãˆã¾ã™
+pdfjs-presentation-mode-button-label = プレゼンテーションモード
+pdfjs-open-file-button =
+ .title = ファイルを開ãã¾ã™
+pdfjs-open-file-button-label = é–‹ã
+pdfjs-print-button =
+ .title = å°åˆ·ã—ã¾ã™
+pdfjs-print-button-label = å°åˆ·
+pdfjs-save-button =
+ .title = ä¿å˜ã—ã¾ã™
+pdfjs-save-button-label = ä¿å˜
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ダウンãƒãƒ¼ãƒ‰ã—ã¾ã™
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ダウンãƒãƒ¼ãƒ‰
+pdfjs-bookmark-button =
+ .title = ç¾åœ¨ã®ãƒšãƒ¼ã‚¸ã® URL ã§ã™ (ç¾åœ¨ã®ãƒšãƒ¼ã‚¸ã‚’表示ã™ã‚‹ URL)
+pdfjs-bookmark-button-label = ç¾åœ¨ã®ãƒšãƒ¼ã‚¸
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = アプリã§é–‹ã
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = アプリã§é–‹ã
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ツール
+pdfjs-tools-button-label = ツール
+pdfjs-first-page-button =
+ .title = 最åˆã®ãƒšãƒ¼ã‚¸ã¸ç§»å‹•ã—ã¾ã™
+pdfjs-first-page-button-label = 最åˆã®ãƒšãƒ¼ã‚¸ã¸ç§»å‹•
+pdfjs-last-page-button =
+ .title = 最後ã®ãƒšãƒ¼ã‚¸ã¸ç§»å‹•ã—ã¾ã™
+pdfjs-last-page-button-label = 最後ã®ãƒšãƒ¼ã‚¸ã¸ç§»å‹•
+pdfjs-page-rotate-cw-button =
+ .title = ページをå³ã¸å›žè»¢ã—ã¾ã™
+pdfjs-page-rotate-cw-button-label = å³å›žè»¢
+pdfjs-page-rotate-ccw-button =
+ .title = ページを左ã¸å›žè»¢ã—ã¾ã™
+pdfjs-page-rotate-ccw-button-label = 左回転
+pdfjs-cursor-text-select-tool-button =
+ .title = テã‚ストé¸æŠžãƒ„ールを有効ã«ã—ã¾ã™
+pdfjs-cursor-text-select-tool-button-label = テã‚ストé¸æŠžãƒ„ール
+pdfjs-cursor-hand-tool-button =
+ .title = 手ã®ã²ã‚‰ãƒ„ールを有効ã«ã—ã¾ã™
+pdfjs-cursor-hand-tool-button-label = 手ã®ã²ã‚‰ãƒ„ール
+pdfjs-scroll-page-button =
+ .title = ページå˜ä½ã§ã‚¹ã‚¯ãƒãƒ¼ãƒ«ã—ã¾ã™
+pdfjs-scroll-page-button-label = ページå˜ä½ã§ã‚¹ã‚¯ãƒãƒ¼ãƒ«
+pdfjs-scroll-vertical-button =
+ .title = 縦スクãƒãƒ¼ãƒ«ã«ã—ã¾ã™
+pdfjs-scroll-vertical-button-label = 縦スクãƒãƒ¼ãƒ«
+pdfjs-scroll-horizontal-button =
+ .title = 横スクãƒãƒ¼ãƒ«ã«ã—ã¾ã™
+pdfjs-scroll-horizontal-button-label = 横スクãƒãƒ¼ãƒ«
+pdfjs-scroll-wrapped-button =
+ .title = 折り返ã—スクãƒãƒ¼ãƒ«ã«ã—ã¾ã™
+pdfjs-scroll-wrapped-button-label = 折り返ã—スクãƒãƒ¼ãƒ«
+pdfjs-spread-none-button =
+ .title = 見開ãã«ã—ã¾ã›ã‚“
+pdfjs-spread-none-button-label = 見開ãã«ã—ãªã„
+pdfjs-spread-odd-button =
+ .title = 奇数ページ開始ã§è¦‹é–‹ãã«ã—ã¾ã™
+pdfjs-spread-odd-button-label = 奇数ページ見開ã
+pdfjs-spread-even-button =
+ .title = å¶æ•°ãƒšãƒ¼ã‚¸é–‹å§‹ã§è¦‹é–‹ãã«ã—ã¾ã™
+pdfjs-spread-even-button-label = å¶æ•°ãƒšãƒ¼ã‚¸è¦‹é–‹ã
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = 文書ã®ãƒ—ãƒãƒ‘ティ...
+pdfjs-document-properties-button-label = 文書ã®ãƒ—ãƒãƒ‘ティ...
+pdfjs-document-properties-file-name = ファイルå:
+pdfjs-document-properties-file-size = ファイルサイズ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ãƒã‚¤ãƒˆ)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ãƒã‚¤ãƒˆ)
+pdfjs-document-properties-title = タイトル:
+pdfjs-document-properties-author = 作æˆè€…:
+pdfjs-document-properties-subject = 件å:
+pdfjs-document-properties-keywords = ã‚ーワード:
+pdfjs-document-properties-creation-date = 作æˆæ—¥:
+pdfjs-document-properties-modification-date = æ›´æ–°æ—¥:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = アプリケーション:
+pdfjs-document-properties-producer = PDF 作æˆ:
+pdfjs-document-properties-version = PDF ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³:
+pdfjs-document-properties-page-count = ページ数:
+pdfjs-document-properties-page-size = ページサイズ:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = 縦
+pdfjs-document-properties-page-size-orientation-landscape = 横
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = レター
+pdfjs-document-properties-page-size-name-legal = リーガル
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ウェブ表示用ã«æœ€é©åŒ–:
+pdfjs-document-properties-linearized-yes = ã¯ã„
+pdfjs-document-properties-linearized-no = ã„ã„ãˆ
+pdfjs-document-properties-close-button = é–‰ã˜ã‚‹
+
+## Print
+
+pdfjs-print-progress-message = 文書ã®å°åˆ·ã‚’準備ã—ã¦ã„ã¾ã™...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ã‚ャンセル
+pdfjs-printing-not-supported = è¦å‘Š: ã“ã®ãƒ–ラウザーã§ã¯å°åˆ·ãŒå®Œå…¨ã«ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。
+pdfjs-printing-not-ready = è¦å‘Š: PDF ã‚’å°åˆ·ã™ã‚‹ãŸã‚ã®èªã¿è¾¼ã¿ãŒçµ‚了ã—ã¦ã„ã¾ã›ã‚“。
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = サイドãƒãƒ¼è¡¨ç¤ºã‚’切り替ãˆã¾ã™
+pdfjs-toggle-sidebar-notification-button =
+ .title = サイドãƒãƒ¼è¡¨ç¤ºã‚’切り替ãˆã¾ã™ (文書ã«å«ã¾ã‚Œã‚‹ã‚¢ã‚¦ãƒˆãƒ©ã‚¤ãƒ³ / 添付 / レイヤー)
+pdfjs-toggle-sidebar-button-label = サイドãƒãƒ¼ã®åˆ‡ã‚Šæ›¿ãˆ
+pdfjs-document-outline-button =
+ .title = 文書ã®ç›®æ¬¡ã‚’表示ã—ã¾ã™ (ダブルクリックã§é …目を開閉ã—ã¾ã™)
+pdfjs-document-outline-button-label = 文書ã®ç›®æ¬¡
+pdfjs-attachments-button =
+ .title = 添付ファイルを表示ã—ã¾ã™
+pdfjs-attachments-button-label = 添付ファイル
+pdfjs-layers-button =
+ .title = レイヤーを表示ã—ã¾ã™ (ダブルクリックã§ã™ã¹ã¦ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ãŒåˆæœŸçŠ¶æ…‹ã«æˆ»ã‚Šã¾ã™)
+pdfjs-layers-button-label = レイヤー
+pdfjs-thumbs-button =
+ .title = 縮å°ç‰ˆã‚’表示ã—ã¾ã™
+pdfjs-thumbs-button-label = 縮å°ç‰ˆ
+pdfjs-current-outline-item-button =
+ .title = ç¾åœ¨ã®ã‚¢ã‚¦ãƒˆãƒ©ã‚¤ãƒ³é …目を検索
+pdfjs-current-outline-item-button-label = ç¾åœ¨ã®ã‚¢ã‚¦ãƒˆãƒ©ã‚¤ãƒ³é …ç›®
+pdfjs-findbar-button =
+ .title = 文書内を検索ã—ã¾ã™
+pdfjs-findbar-button-label = 検索
+pdfjs-additional-layers = è¿½åŠ ãƒ¬ã‚¤ãƒ¤ãƒ¼
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } ページ
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } ページã®ç¸®å°ç‰ˆ
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = 検索
+ .placeholder = 文書内を検索...
+pdfjs-find-previous-button =
+ .title = ç¾åœ¨ã‚ˆã‚Šå‰ã®ä½ç½®ã§æŒ‡å®šæ–‡å—列ãŒç¾ã‚Œã‚‹éƒ¨åˆ†ã‚’検索ã—ã¾ã™
+pdfjs-find-previous-button-label = å‰ã¸
+pdfjs-find-next-button =
+ .title = ç¾åœ¨ã‚ˆã‚Šå¾Œã®ä½ç½®ã§æŒ‡å®šæ–‡å—列ãŒç¾ã‚Œã‚‹éƒ¨åˆ†ã‚’検索ã—ã¾ã™
+pdfjs-find-next-button-label = 次ã¸
+pdfjs-find-highlight-checkbox = ã™ã¹ã¦å¼·èª¿è¡¨ç¤º
+pdfjs-find-match-case-checkbox-label = 大文å—/å°æ–‡å—を区別
+pdfjs-find-match-diacritics-checkbox-label = 発音区別符å·ã‚’区別
+pdfjs-find-entire-word-checkbox-label = å˜èªžä¸€è‡´
+pdfjs-find-reached-top = 文書先é ã«åˆ°é”ã—ãŸã®ã§æœ«å°¾ã‹ã‚‰ç¶šã‘ã¦æ¤œç´¢ã—ã¾ã™
+pdfjs-find-reached-bottom = 文書末尾ã«åˆ°é”ã—ãŸã®ã§å…ˆé ã‹ã‚‰ç¶šã‘ã¦æ¤œç´¢ã—ã¾ã™
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $total } ä»¶ä¸ { $current } 件目
+ *[other] { $total } ä»¶ä¸ { $current } 件目
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] { $limit } 件以上一致
+ *[other] { $limit } 件以上一致
+ }
+pdfjs-find-not-found = 見ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = å¹…ã«åˆã‚ã›ã‚‹
+pdfjs-page-scale-fit = ページã®ã‚µã‚¤ã‚ºã«åˆã‚ã›ã‚‹
+pdfjs-page-scale-auto = 自動ズーãƒ
+pdfjs-page-scale-actual = 実際ã®ã‚µã‚¤ã‚º
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page } ページ
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ã®èªã¿è¾¼ã¿ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+pdfjs-invalid-file-error = 無効ã¾ãŸã¯ç ´æã—㟠PDF ファイル。
+pdfjs-missing-file-error = PDF ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+pdfjs-unexpected-response-error = サーãƒãƒ¼ã‹ã‚‰äºˆæœŸã›ã¬å¿œç”ãŒã‚ã‚Šã¾ã—ãŸã€‚
+pdfjs-rendering-error = ページã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } 注釈]
+
+## Password
+
+pdfjs-password-label = ã“ã® PDF ファイルを開ããŸã‚ã®ãƒ‘スワードを入力ã—ã¦ãã ã•ã„。
+pdfjs-password-invalid = 無効ãªãƒ‘スワードã§ã™ã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = ã‚ャンセル
+pdfjs-web-fonts-disabled = ウェブフォントãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™: 埋ã‚è¾¼ã¾ã‚ŒãŸ PDF ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’使用ã§ãã¾ã›ã‚“。
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = フリーテã‚スト注釈
+pdfjs-editor-free-text-button-label = フリーテã‚スト注釈
+pdfjs-editor-ink-button =
+ .title = インク注釈
+pdfjs-editor-ink-button-label = インク注釈
+pdfjs-editor-stamp-button =
+ .title = ç”»åƒã‚’è¿½åŠ ã¾ãŸã¯ç·¨é›†ã—ã¾ã™
+pdfjs-editor-stamp-button-label = ç”»åƒã‚’è¿½åŠ ã¾ãŸã¯ç·¨é›†
+pdfjs-editor-remove-button =
+ .title = 削除
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = インク注釈を削除ã—ã¾ã™
+pdfjs-editor-remove-freetext-button =
+ .title = テã‚ストを削除ã—ã¾ã™
+pdfjs-editor-remove-stamp-button =
+ .title = ç”»åƒã‚’削除ã—ã¾ã™
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = 色
+pdfjs-editor-free-text-size-input = サイズ
+pdfjs-editor-ink-color-input = 色
+pdfjs-editor-ink-thickness-input = 太ã•
+pdfjs-editor-ink-opacity-input = ä¸é€æ˜Žåº¦
+pdfjs-editor-stamp-add-image-button =
+ .title = ç”»åƒã‚’è¿½åŠ ã—ã¾ã™
+pdfjs-editor-stamp-add-image-button-label = ç”»åƒã‚’追åŠ
+pdfjs-free-text =
+ .aria-label = フリーテã‚スト注釈エディター
+pdfjs-free-text-default-content = テã‚ストを入力ã—ã¦ãã ã•ã„...
+pdfjs-ink =
+ .aria-label = インク注釈エディター
+pdfjs-ink-canvas =
+ .aria-label = ユーザー作æˆç”»åƒ
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = 代替テã‚スト
+pdfjs-editor-alt-text-edit-button-label = 代替テã‚ストを編集
+pdfjs-editor-alt-text-dialog-label = オプションã®é¸æŠž
+pdfjs-editor-alt-text-dialog-description = 代替テã‚ストã¯ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„å ´åˆã‚„èªã¿è¾¼ã¾ã‚Œãªã„å ´åˆã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®åŠ©ã‘ã«ãªã‚Šã¾ã™ã€‚
+pdfjs-editor-alt-text-add-description-label = 説明を追åŠ
+pdfjs-editor-alt-text-add-description-description = 対象やè¨å®šã€å‹•ä½œã‚’説明ã™ã‚‹çŸã„æ–‡ç« ã‚’è¨˜å…¥ã—ã¦ãã ã•ã„。
+pdfjs-editor-alt-text-mark-decorative-label = 装飾マークを付ã‘ã‚‹
+pdfjs-editor-alt-text-mark-decorative-description = ã“ã‚Œã¯åŒºåˆ‡ã‚Šç·šã‚„ウォーターマークãªã©ã®è£…飾画åƒã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚
+pdfjs-editor-alt-text-cancel-button = ã‚ャンセル
+pdfjs-editor-alt-text-save-button = ä¿å˜
+pdfjs-editor-alt-text-decorative-tooltip = 装飾マークãŒä»˜ã„ã¦ã„ã¾ã™
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = 例:「若ã„人ãŒãƒ†ãƒ¼ãƒ–ルã®å¸ã«ã¤ã„ã¦é£Ÿäº‹ã‚’ã—ã¦ã„ã¾ã™ã€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = 左上隅 — サイズ変更
+pdfjs-editor-resizer-label-top-middle = 上ä¸å¤® — サイズ変更
+pdfjs-editor-resizer-label-top-right = å³ä¸Šéš… — サイズ変更
+pdfjs-editor-resizer-label-middle-right = å³ä¸å¤® — サイズ変更
+pdfjs-editor-resizer-label-bottom-right = å³ä¸‹éš… — サイズ変更
+pdfjs-editor-resizer-label-bottom-middle = 下ä¸å¤® — サイズ変更
+pdfjs-editor-resizer-label-bottom-left = 左下隅 — サイズ変更
+pdfjs-editor-resizer-label-middle-left = å·¦ä¸å¤® — サイズ変更
diff --git a/www/lib/pdfjs/modern/web/locale/ka/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ka/viewer.ftl
new file mode 100644
index 000000000..790e61bd3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ka/viewer.ftl
@@ -0,0 +1,351 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = წინრგვერდი
+pdfjs-previous-button-label = წინáƒ
+pdfjs-next-button =
+ .title = შემდეგი გვერდი
+pdfjs-next-button-label = შემდეგი
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = გვერდი
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount }-დáƒáƒœ
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } { $pagesCount }-დáƒáƒœ)
+pdfjs-zoom-out-button =
+ .title = ზáƒáƒ›áƒ˜áƒ¡ შემცირებáƒ
+pdfjs-zoom-out-button-label = დáƒáƒ¨áƒáƒ ებáƒ
+pdfjs-zoom-in-button =
+ .title = ზáƒáƒ›áƒ˜áƒ¡ გáƒáƒ–რდáƒ
+pdfjs-zoom-in-button-label = მáƒáƒáƒ®áƒšáƒáƒ”ბáƒ
+pdfjs-zoom-select =
+ .title = ზáƒáƒ›áƒ
+pdfjs-presentation-mode-button =
+ .title = ჩვენების რეჟიმზე გáƒáƒ“áƒáƒ თვáƒ
+pdfjs-presentation-mode-button-label = ჩვენების რეჟიმი
+pdfjs-open-file-button =
+ .title = ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ®áƒ¡áƒœáƒ
+pdfjs-open-file-button-label = გáƒáƒ®áƒ¡áƒœáƒ
+pdfjs-print-button =
+ .title = áƒáƒ›áƒáƒ‘ეáƒáƒ“ვáƒ
+pdfjs-print-button-label = áƒáƒ›áƒáƒ‘ეáƒáƒ“ვáƒ
+pdfjs-save-button =
+ .title = შენáƒáƒ®áƒ•áƒ
+pdfjs-save-button-label = შენáƒáƒ®áƒ•áƒ
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ჩáƒáƒ›áƒáƒ¢áƒ•áƒ˜áƒ თვáƒ
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ჩáƒáƒ›áƒáƒ¢áƒ•áƒ˜áƒ თვáƒ
+pdfjs-bookmark-button =
+ .title = მიმდინáƒáƒ ე გვერდი (ბმული áƒáƒ› გვერდისთვის)
+pdfjs-bookmark-button-label = მიმდინáƒáƒ ე გვერდი
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = გáƒáƒ®áƒ¡áƒœáƒ პრáƒáƒ’რáƒáƒ›áƒ˜áƒ—
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = გáƒáƒ®áƒ¡áƒœáƒ პრáƒáƒ’რáƒáƒ›áƒ˜áƒ—
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ხელსáƒáƒ¬áƒ§áƒáƒ”ბი
+pdfjs-tools-button-label = ხელსáƒáƒ¬áƒ§áƒáƒ”ბი
+pdfjs-first-page-button =
+ .title = პირველ გვერდზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ
+pdfjs-first-page-button-label = პირველ გვერდზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ
+pdfjs-last-page-button =
+ .title = ბáƒáƒšáƒ გვერდზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ
+pdfjs-last-page-button-label = ბáƒáƒšáƒ გვერდზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ
+pdfjs-page-rotate-cw-button =
+ .title = სáƒáƒáƒ—ის ისრის მიმáƒáƒ თულებით შებრუნებáƒ
+pdfjs-page-rotate-cw-button-label = მáƒáƒ ჯვნივ გáƒáƒ“áƒáƒ‘რუნებáƒ
+pdfjs-page-rotate-ccw-button =
+ .title = სáƒáƒáƒ—ის ისრის სáƒáƒžáƒ˜áƒ ისპირáƒáƒ“ შებრუნებáƒ
+pdfjs-page-rotate-ccw-button-label = მáƒáƒ ცხნივ გáƒáƒ“áƒáƒ‘რუნებáƒ
+pdfjs-cursor-text-select-tool-button =
+ .title = მáƒáƒ¡áƒáƒœáƒ˜áƒ¨áƒœáƒ˜ მáƒáƒ©áƒ•áƒ”ნებლის გáƒáƒ›áƒáƒ§áƒ”ნებáƒ
+pdfjs-cursor-text-select-tool-button-label = მáƒáƒ¡áƒáƒœáƒ˜áƒ¨áƒœáƒ˜ მáƒáƒ©áƒ•áƒ”ნებელი
+pdfjs-cursor-hand-tool-button =
+ .title = გáƒáƒ“áƒáƒ¡áƒáƒáƒ“გილებელი მáƒáƒ©áƒ•áƒ”ნებლის გáƒáƒ›áƒáƒ§áƒ”ნებáƒ
+pdfjs-cursor-hand-tool-button-label = გáƒáƒ“áƒáƒ¡áƒáƒáƒ“გილებელი
+pdfjs-scroll-page-button =
+ .title = გვერდზე გáƒáƒ“áƒáƒáƒ“გილების გáƒáƒ›áƒáƒ§áƒ”ნებáƒ
+pdfjs-scroll-page-button-label = გვერდშივე გáƒáƒ“áƒáƒáƒ“გილებáƒ
+pdfjs-scroll-vertical-button =
+ .title = გვერდების შვეულáƒáƒ“ ჩვენებáƒ
+pdfjs-scroll-vertical-button-label = შვეული გáƒáƒ“áƒáƒáƒ“გილებáƒ
+pdfjs-scroll-horizontal-button =
+ .title = გვერდების თáƒáƒ áƒáƒ–ულáƒáƒ“ ჩვენებáƒ
+pdfjs-scroll-horizontal-button-label = გáƒáƒœáƒ˜áƒ•áƒ˜ გáƒáƒ“áƒáƒáƒ“გილებáƒ
+pdfjs-scroll-wrapped-button =
+ .title = გვერდების ცხრილურáƒáƒ“ ჩვენებáƒ
+pdfjs-scroll-wrapped-button-label = ცხრილური გáƒáƒ“áƒáƒáƒ“გილებáƒ
+pdfjs-spread-none-button =
+ .title = áƒáƒ გვერდზე გáƒáƒ¨áƒšáƒ˜áƒ¡ გáƒáƒ ეშე
+pdfjs-spread-none-button-label = ცáƒáƒšáƒ’ვერდიáƒáƒœáƒ˜ ჩვენებáƒ
+pdfjs-spread-odd-button =
+ .title = áƒáƒ გვერდზე გáƒáƒ¨áƒšáƒ კენტი გვერდიდáƒáƒœ
+pdfjs-spread-odd-button-label = áƒáƒ გვერდზე კენტიდáƒáƒœ
+pdfjs-spread-even-button =
+ .title = áƒáƒ გვერდზე გáƒáƒ¨áƒšáƒ ლუწი გვერდიდáƒáƒœ
+pdfjs-spread-even-button-label = áƒáƒ გვერდზე ლუწიდáƒáƒœ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = დáƒáƒ™áƒ£áƒ›áƒ”ნტის შესáƒáƒ®áƒ”ბ…
+pdfjs-document-properties-button-label = დáƒáƒ™áƒ£áƒ›áƒ”ნტის შესáƒáƒ®áƒ”ბ…
+pdfjs-document-properties-file-name = ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლი:
+pdfjs-document-properties-file-size = ფáƒáƒ˜áƒšáƒ˜áƒ¡ მáƒáƒªáƒ£áƒšáƒáƒ‘áƒ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } კბ ({ $size_b } ბáƒáƒ˜áƒ¢áƒ˜)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } მბ ({ $size_b } ბáƒáƒ˜áƒ¢áƒ˜)
+pdfjs-document-properties-title = სáƒáƒ—áƒáƒ£áƒ ი:
+pdfjs-document-properties-author = შემქმნელი:
+pdfjs-document-properties-subject = თემáƒ:
+pdfjs-document-properties-keywords = სáƒáƒ™áƒ•áƒáƒœáƒ«áƒ სიტყვები:
+pdfjs-document-properties-creation-date = შექმნის დრáƒ:
+pdfjs-document-properties-modification-date = ჩáƒáƒ¡áƒ¬áƒáƒ ების დრáƒ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = შემდგენელი:
+pdfjs-document-properties-producer = PDF-შემდგენელი:
+pdfjs-document-properties-version = PDF-ვერსიáƒ:
+pdfjs-document-properties-page-count = გვერდები:
+pdfjs-document-properties-page-size = გვერდის ზáƒáƒ›áƒ:
+pdfjs-document-properties-page-size-unit-inches = დუიმი
+pdfjs-document-properties-page-size-unit-millimeters = მმ
+pdfjs-document-properties-page-size-orientation-portrait = შვეულáƒáƒ“
+pdfjs-document-properties-page-size-orientation-landscape = თáƒáƒ áƒáƒ–ულáƒáƒ“
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = მსუბუქი ვებჩვენებáƒ:
+pdfjs-document-properties-linearized-yes = დიáƒáƒ®
+pdfjs-document-properties-linearized-no = áƒáƒ áƒ
+pdfjs-document-properties-close-button = დáƒáƒ®áƒ£áƒ ვáƒ
+
+## Print
+
+pdfjs-print-progress-message = დáƒáƒ™áƒ£áƒ›áƒ”ნტი მზáƒáƒ“დებრáƒáƒ›áƒáƒ¡áƒáƒ‘ეáƒáƒ“áƒáƒ“…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = გáƒáƒ£áƒ¥áƒ›áƒ”ბáƒ
+pdfjs-printing-not-supported = გáƒáƒ¤áƒ თხილებáƒ: áƒáƒ›áƒáƒ‘ეáƒáƒ“ვრáƒáƒ› ბრáƒáƒ£áƒ–ერში áƒáƒ áƒáƒ სრულáƒáƒ“ მხáƒáƒ დáƒáƒáƒ”რილი.
+pdfjs-printing-not-ready = გáƒáƒ¤áƒ თხილებáƒ: PDF სრულáƒáƒ“ ჩáƒáƒ¢áƒ•áƒ˜áƒ თული áƒáƒ áƒáƒ, áƒáƒ›áƒáƒ‘ეáƒáƒ“ვის დáƒáƒ¡áƒáƒ¬áƒ§áƒ”ბáƒáƒ“.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = გვერდითრზáƒáƒšáƒ˜áƒ¡ გáƒáƒ›áƒáƒ©áƒ”ნáƒ/დáƒáƒ›áƒáƒšáƒ•áƒ
+pdfjs-toggle-sidebar-notification-button =
+ .title = გვერდითი ზáƒáƒšáƒ˜áƒ¡ გáƒáƒ›áƒáƒ©áƒ”ნრ(შეიცáƒáƒ•áƒ¡ სáƒáƒ ჩევს/დáƒáƒœáƒáƒ თს/ფენებს)
+pdfjs-toggle-sidebar-button-label = გვერდითრზáƒáƒšáƒ˜áƒ¡ გáƒáƒ›áƒáƒ©áƒ”ნáƒ/დáƒáƒ›áƒáƒšáƒ•áƒ
+pdfjs-document-outline-button =
+ .title = დáƒáƒ™áƒ£áƒ›áƒ”ნტის სáƒáƒ ჩევის ჩვენებრ(áƒáƒ მáƒáƒ’ი წკáƒáƒžáƒ˜áƒ— თითáƒáƒ”ულის ჩáƒáƒ›áƒáƒ¨áƒšáƒ/áƒáƒ™áƒ”ცვáƒ)
+pdfjs-document-outline-button-label = დáƒáƒ™áƒ£áƒ›áƒ”ნტის სáƒáƒ ჩევი
+pdfjs-attachments-button =
+ .title = დáƒáƒœáƒáƒ თების ჩვენებáƒ
+pdfjs-attachments-button-label = დáƒáƒœáƒáƒ თები
+pdfjs-layers-button =
+ .title = ფენების გáƒáƒ›áƒáƒ©áƒ”ნრ(áƒáƒ მáƒáƒ’ი წკáƒáƒžáƒ˜áƒ— ყველრფენის ნáƒáƒ’ულისხმევზე დáƒáƒ‘რუნებáƒ)
+pdfjs-layers-button-label = ფენები
+pdfjs-thumbs-button =
+ .title = შეთვáƒáƒšáƒ˜áƒ”რებáƒ
+pdfjs-thumbs-button-label = ესკიზები
+pdfjs-current-outline-item-button =
+ .title = მიმდინáƒáƒ ე გვერდის მáƒáƒœáƒáƒ®áƒ•áƒ სáƒáƒ ჩევში
+pdfjs-current-outline-item-button-label = მიმდინáƒáƒ ე გვერდი სáƒáƒ ჩევში
+pdfjs-findbar-button =
+ .title = პáƒáƒ•áƒœáƒ დáƒáƒ™áƒ£áƒ›áƒ”ნტში
+pdfjs-findbar-button-label = ძიებáƒ
+pdfjs-additional-layers = დáƒáƒ›áƒáƒ¢áƒ”ბითი ფენები
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = გვერდი { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = გვერდის შეთვáƒáƒšáƒ˜áƒ”რებრ{ $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ძიებáƒ
+ .placeholder = პáƒáƒ•áƒœáƒ დáƒáƒ™áƒ£áƒ›áƒ”ნტში…
+pdfjs-find-previous-button =
+ .title = ფრáƒáƒ–ის წინრკáƒáƒœáƒ¢áƒ”ქსტის პáƒáƒ•áƒœáƒ
+pdfjs-find-previous-button-label = წინáƒ
+pdfjs-find-next-button =
+ .title = ფრáƒáƒ–ის შემდეგი კáƒáƒœáƒ¢áƒ”ქსტის პáƒáƒ•áƒœáƒ
+pdfjs-find-next-button-label = შემდეგი
+pdfjs-find-highlight-checkbox = ყველáƒáƒ¡ მáƒáƒœáƒ˜áƒ¨áƒ•áƒœáƒ
+pdfjs-find-match-case-checkbox-label = მთáƒáƒ•áƒ ულით
+pdfjs-find-match-diacritics-checkbox-label = ნიშნებით
+pdfjs-find-entire-word-checkbox-label = მთლიáƒáƒœáƒ˜ სიტყვები
+pdfjs-find-reached-top = მიღწეულირდáƒáƒ™áƒ£áƒ›áƒ”ნტის დáƒáƒ¡áƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜, გრძელდებრბáƒáƒšáƒáƒ“áƒáƒœ
+pdfjs-find-reached-bottom = მიღწეულირდáƒáƒ™áƒ£áƒ›áƒ”ნტის ბáƒáƒšáƒ, გრძელდებრდáƒáƒ¡áƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜áƒ“áƒáƒœ
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] თáƒáƒœáƒ®áƒ•áƒ”დრრ{ $current }, სულ { $total }
+ *[other] თáƒáƒœáƒ®áƒ•áƒ”დრრ{ $current }, სულ { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] áƒáƒ áƒáƒœáƒáƒ™áƒšáƒ”ბ { $limit } თáƒáƒœáƒ®áƒ•áƒ”დრáƒ
+ *[other] áƒáƒ áƒáƒœáƒáƒ™áƒšáƒ”ბ { $limit } თáƒáƒœáƒ®áƒ•áƒ”დრáƒ
+ }
+pdfjs-find-not-found = ფრáƒáƒ–რვერმáƒáƒ˜áƒ«áƒ”ბნáƒ
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = გვერდის სიგáƒáƒœáƒ”ზე
+pdfjs-page-scale-fit = მთლიáƒáƒœáƒ˜ გვერდი
+pdfjs-page-scale-auto = áƒáƒ•áƒ¢áƒáƒ›áƒáƒ¢áƒ£áƒ ი
+pdfjs-page-scale-actual = სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜ ზáƒáƒ›áƒ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = გვერდი { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = შეცდáƒáƒ›áƒ, PDF-ფáƒáƒ˜áƒšáƒ˜áƒ¡ ჩáƒáƒ¢áƒ•áƒ˜áƒ თვისáƒáƒ¡.
+pdfjs-invalid-file-error = áƒáƒ áƒáƒ›áƒáƒ თებული áƒáƒœ დáƒáƒ–იáƒáƒœáƒ”ბული PDF-ფáƒáƒ˜áƒšáƒ˜.
+pdfjs-missing-file-error = ნáƒáƒ™áƒšáƒ£áƒšáƒ˜ PDF-ფáƒáƒ˜áƒšáƒ˜.
+pdfjs-unexpected-response-error = სერვერის მáƒáƒ£áƒšáƒáƒ“ნელი პáƒáƒ¡áƒ£áƒ®áƒ˜.
+pdfjs-rendering-error = შეცდáƒáƒ›áƒ, გვერდის ჩვენებისáƒáƒ¡.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } შენიშვნáƒ]
+
+## Password
+
+pdfjs-password-label = შეიყვáƒáƒœáƒ”თ პáƒáƒ áƒáƒšáƒ˜ PDF-ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ¡áƒáƒ®áƒ¡áƒœáƒ”ლáƒáƒ“.
+pdfjs-password-invalid = áƒáƒ áƒáƒ¡áƒ¬áƒáƒ ი პáƒáƒ áƒáƒšáƒ˜. გთხáƒáƒ•áƒ—, სცáƒáƒ“áƒáƒ— ხელáƒáƒ®áƒšáƒ.
+pdfjs-password-ok-button = კáƒáƒ გი
+pdfjs-password-cancel-button = გáƒáƒ£áƒ¥áƒ›áƒ”ბáƒ
+pdfjs-web-fonts-disabled = ვებშრიფტები გáƒáƒ›áƒáƒ თულიáƒ: ჩáƒáƒ¨áƒ”ნებული PDF-შრიფტების გáƒáƒ›áƒáƒ§áƒ”ნებრვერხერხდებáƒ.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = წáƒáƒ წერáƒ
+pdfjs-editor-free-text-button-label = ტექსტი
+pdfjs-editor-ink-button =
+ .title = ხáƒáƒ–ვáƒ
+pdfjs-editor-ink-button-label = ხáƒáƒ–ვáƒ
+pdfjs-editor-stamp-button =
+ .title = სურáƒáƒ—ების დáƒáƒ თვრáƒáƒœ ჩáƒáƒ¡áƒ¬áƒáƒ ებáƒ
+pdfjs-editor-stamp-button-label = სურáƒáƒ—ების დáƒáƒ თვრáƒáƒœ ჩáƒáƒ¡áƒ¬áƒáƒ ებáƒ
+pdfjs-editor-remove-button =
+ .title = მáƒáƒªáƒ˜áƒšáƒ”ბáƒ
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ფერი
+pdfjs-editor-free-text-size-input = ზáƒáƒ›áƒ
+pdfjs-editor-ink-color-input = ფერი
+pdfjs-editor-ink-thickness-input = სისქე
+pdfjs-editor-ink-opacity-input = გáƒáƒ£áƒ›áƒáƒ•áƒ˜áƒ ვáƒáƒšáƒáƒ‘áƒ
+pdfjs-editor-stamp-add-image-button =
+ .title = სურáƒáƒ—ის დáƒáƒ›áƒáƒ¢áƒ”ბáƒ
+pdfjs-editor-stamp-add-image-button-label = სურáƒáƒ—ის დáƒáƒ›áƒáƒ¢áƒ”ბáƒ
+pdfjs-free-text =
+ .aria-label = ნáƒáƒ¬áƒ”რის ჩáƒáƒ¡áƒ¬áƒáƒ ებáƒ
+pdfjs-free-text-default-content = áƒáƒ™áƒ იფეთ…
+pdfjs-ink =
+ .aria-label = ნáƒáƒ®áƒáƒ¢áƒ˜áƒ¡ ჩáƒáƒ¡áƒ¬áƒáƒ ებáƒ
+pdfjs-ink-canvas =
+ .aria-label = მáƒáƒ›áƒ®áƒ›áƒáƒ ებლის შექმნილი სურáƒáƒ—ი
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = დáƒáƒ თული წáƒáƒ წერáƒ
+pdfjs-editor-alt-text-edit-button-label = დáƒáƒ თული წáƒáƒ წერის ჩáƒáƒ¡áƒ¬áƒáƒ ებáƒ
+pdfjs-editor-alt-text-dialog-label = áƒáƒ ჩევáƒ
+pdfjs-editor-alt-text-dialog-description = დáƒáƒ თული წáƒáƒ წერრ(შემნáƒáƒªáƒ•áƒšáƒ”ბელი ტექსტი) გáƒáƒ›áƒáƒ¡áƒáƒ“ეგირმáƒáƒ—თვის, ვინც ვერხედáƒáƒ•áƒ¡ სურáƒáƒ—ებს áƒáƒœ რáƒáƒªáƒ სურáƒáƒ—ი ვერიტვირთებáƒ.
+pdfjs-editor-alt-text-add-description-label = áƒáƒ¦áƒ¬áƒ”რილáƒáƒ‘ის დáƒáƒ›áƒáƒ¢áƒ”ბáƒ
+pdfjs-editor-alt-text-add-description-description = გáƒáƒœáƒ™áƒ£áƒ—ვნილირ1-2 წინáƒáƒ“áƒáƒ“ებით სáƒáƒ’ნის, მáƒáƒ®áƒáƒ¡áƒ˜áƒáƒ—ებლის áƒáƒœ მáƒáƒ¥áƒ›áƒ”დების áƒáƒ¦áƒ¡áƒáƒ¬áƒ”რáƒáƒ“.
+pdfjs-editor-alt-text-mark-decorative-label = მáƒáƒ˜áƒœáƒ˜áƒ¨áƒœáƒáƒ¡ მáƒáƒ¡áƒáƒ თáƒáƒ•áƒáƒ“
+pdfjs-editor-alt-text-mark-decorative-description = გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნებრშესáƒáƒ›áƒ™áƒáƒ‘ი სურáƒáƒ—ებისთვის, გáƒáƒ სშემáƒáƒ¡áƒáƒ•áƒšáƒ”ბი ჩáƒáƒ ჩáƒáƒ”ბისრდრáƒáƒ•áƒ˜áƒ ნიშნებისთვის.
+pdfjs-editor-alt-text-cancel-button = გáƒáƒ£áƒ¥áƒ›áƒ”ბáƒ
+pdfjs-editor-alt-text-save-button = შენáƒáƒ®áƒ•áƒ
+pdfjs-editor-alt-text-decorative-tooltip = მáƒáƒ˜áƒœáƒ˜áƒ¨áƒœáƒáƒ¡ მáƒáƒ¡áƒáƒ თáƒáƒ•áƒáƒ“
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = მáƒáƒ’áƒáƒšáƒ˜áƒ—áƒáƒ“, „áƒáƒ®áƒáƒšáƒ’áƒáƒ–რდრმáƒáƒ›áƒáƒ™áƒáƒªáƒ˜ მáƒáƒ’იდáƒáƒ¡áƒ—áƒáƒœ ზის დრსáƒáƒ“ილáƒáƒ‘ს“
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = ზევით მáƒáƒ ცხნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-top-middle = ზევით შუáƒáƒ¨áƒ˜ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-top-right = ზევით მáƒáƒ ჯვნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-middle-right = შუáƒáƒ¨áƒ˜ მáƒáƒ ჯვნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-bottom-right = ქვევით მáƒáƒ ჯვნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-bottom-middle = ქვევით შუáƒáƒ¨áƒ˜ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-bottom-left = ზვევით მáƒáƒ ცხნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
+pdfjs-editor-resizer-label-middle-left = შუáƒáƒ¨áƒ˜ მáƒáƒ ცხნივ — ზáƒáƒ›áƒáƒªáƒ•áƒšáƒ
diff --git a/www/lib/pdfjs/modern/web/locale/kab/viewer.ftl b/www/lib/pdfjs/modern/web/locale/kab/viewer.ftl
new file mode 100644
index 000000000..5f16478e3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/kab/viewer.ftl
@@ -0,0 +1,337 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Asebter azewwar
+pdfjs-previous-button-label = Azewwar
+pdfjs-next-button =
+ .title = Asebter d-iteddun
+pdfjs-next-button-label = Ddu ɣer zdat
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Asebter
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = ɣef { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } n { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Semẓi
+pdfjs-zoom-out-button-label = Semẓi
+pdfjs-zoom-in-button =
+ .title = Semɣeṛ
+pdfjs-zoom-in-button-label = Semɣeṛ
+pdfjs-zoom-select =
+ .title = Semɣeṛ/Semẓi
+pdfjs-presentation-mode-button =
+ .title = Uɣal ɣer Uskar Tihawt
+pdfjs-presentation-mode-button-label = Askar Tihawt
+pdfjs-open-file-button =
+ .title = Ldi Afaylu
+pdfjs-open-file-button-label = Ldi
+pdfjs-print-button =
+ .title = Siggez
+pdfjs-print-button-label = Siggez
+pdfjs-save-button =
+ .title = Sekles
+pdfjs-save-button-label = Sekles
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Sader
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Sader
+pdfjs-bookmark-button =
+ .title = Asebter amiran (Sken-d tansa URL seg usebter amiran)
+pdfjs-bookmark-button-label = Asebter amiran
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ldi deg usnas
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ldi deg usnas
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ifecka
+pdfjs-tools-button-label = Ifecka
+pdfjs-first-page-button =
+ .title = Ddu ɣer usebter amezwaru
+pdfjs-first-page-button-label = Ddu ɣer usebter amezwaru
+pdfjs-last-page-button =
+ .title = Ddu ɣer usebter aneggaru
+pdfjs-last-page-button-label = Ddu ɣer usebter aneggaru
+pdfjs-page-rotate-cw-button =
+ .title = Tuzzya tusrigt
+pdfjs-page-rotate-cw-button-label = Tuzzya tusrigt
+pdfjs-page-rotate-ccw-button =
+ .title = Tuzzya amgal-usrig
+pdfjs-page-rotate-ccw-button-label = Tuzzya amgal-usrig
+pdfjs-cursor-text-select-tool-button =
+ .title = Rmed afecku n tefrant n uá¸ris
+pdfjs-cursor-text-select-tool-button-label = Afecku n tefrant n uá¸ris
+pdfjs-cursor-hand-tool-button =
+ .title = Rmed afecku afus
+pdfjs-cursor-hand-tool-button-label = Afecku afus
+pdfjs-scroll-page-button =
+ .title = Seqdec adrurem n usebter
+pdfjs-scroll-page-button-label = Adrurem n usebter
+pdfjs-scroll-vertical-button =
+ .title = Seqdec adrurem ubdid
+pdfjs-scroll-vertical-button-label = Adrurem ubdid
+pdfjs-scroll-horizontal-button =
+ .title = Seqdec adrurem aglawan
+pdfjs-scroll-horizontal-button-label = Adrurem aglawan
+pdfjs-scroll-wrapped-button =
+ .title = Seqdec adrurem yuẓen
+pdfjs-scroll-wrapped-button-label = Adrurem yuẓen
+pdfjs-spread-none-button =
+ .title = Ur sedday ara isiɣzaf n usebter
+pdfjs-spread-none-button-label = Ulac isiɣzaf
+pdfjs-spread-odd-button =
+ .title = Seddu isiɣzaf n usebter ibeddun s yisebtar irayuganen
+pdfjs-spread-odd-button-label = Isiɣzaf irayuganen
+pdfjs-spread-even-button =
+ .title = Seddu isiɣzaf n usebter ibeddun s yisebtar iyuganen
+pdfjs-spread-even-button-label = Isiɣzaf iyuganen
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Taɣaṛa n isemli…
+pdfjs-document-properties-button-label = Taɣaṛa n isemli…
+pdfjs-document-properties-file-name = Isem n ufaylu:
+pdfjs-document-properties-file-size = Teɣzi n ufaylu:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KAṬ ({ $size_b } ibiten)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MAṬ ({ $size_b } iá¹amá¸anen)
+pdfjs-document-properties-title = Azwel:
+pdfjs-document-properties-author = Ameskar:
+pdfjs-document-properties-subject = Amgay:
+pdfjs-document-properties-keywords = Awalen n tsaruţ
+pdfjs-document-properties-creation-date = Azemz n tmerna:
+pdfjs-document-properties-modification-date = Azemz n usnifel:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Yerna-t:
+pdfjs-document-properties-producer = Afecku n uselket PDF:
+pdfjs-document-properties-version = Lqem PDF:
+pdfjs-document-properties-page-count = Amá¸an n yisebtar:
+pdfjs-document-properties-page-size = Tuγzi n usebter:
+pdfjs-document-properties-page-size-unit-inches = deg
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = s teɣzi
+pdfjs-document-properties-page-size-orientation-landscape = s tehri
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Asekkil
+pdfjs-document-properties-page-size-name-legal = Usá¸if
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Taskant Web taruradt:
+pdfjs-document-properties-linearized-yes = Ih
+pdfjs-document-properties-linearized-no = Ala
+pdfjs-document-properties-close-button = Mdel
+
+## Print
+
+pdfjs-print-progress-message = Aheggi i usiggez n isemli…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Sefsex
+pdfjs-printing-not-supported = Ɣuṛ-k: Asiggez ur ittusefrak ara yakan imaṛṛa deg iminig-a.
+pdfjs-printing-not-ready = Ɣuṛ-k: Afaylu PDF ur d-yuli ara imeṛṛa akken ad ittusiggez.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Sken/Fer agalis adisan
+pdfjs-toggle-sidebar-notification-button =
+ .title = Ffer/Sekn agalis adisan (isemli yegber aɣawas/ticeqqufin yeddan/tissiwin)
+pdfjs-toggle-sidebar-button-label = Sken/Fer agalis adisan
+pdfjs-document-outline-button =
+ .title = Sken isemli (Senned snat tikal i wesemɣer/Afneẓ n iferdisen meṛṛa)
+pdfjs-document-outline-button-label = Isɣalen n isebtar
+pdfjs-attachments-button =
+ .title = Sken ticeqqufin yeddan
+pdfjs-attachments-button-label = Ticeqqufin yeddan
+pdfjs-layers-button =
+ .title = Skeen tissiwin (sit sin yiberdan i uwennez n meṛṛa tissiwin ɣer waddad amezwer)
+pdfjs-layers-button-label = Tissiwin
+pdfjs-thumbs-button =
+ .title = Sken tanfult.
+pdfjs-thumbs-button-label = Tinfulin
+pdfjs-current-outline-item-button =
+ .title = Af-d aferdis n uɣawas amiran
+pdfjs-current-outline-item-button-label = Aferdis n uɣawas amiran
+pdfjs-findbar-button =
+ .title = Nadi deg isemli
+pdfjs-findbar-button-label = Nadi
+pdfjs-additional-layers = Tissiwin-nniá¸en
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Asebter { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Tanfult n usebter { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Nadi
+ .placeholder = Nadi deg isemli…
+pdfjs-find-previous-button =
+ .title = Aff-d tamseá¸riwt n twinest n deffir
+pdfjs-find-previous-button-label = Azewwar
+pdfjs-find-next-button =
+ .title = Aff-d timseá¸riwt n twinest d-iteddun
+pdfjs-find-next-button-label = Ddu ɣer zdat
+pdfjs-find-highlight-checkbox = Err izirig imaṛṛa
+pdfjs-find-match-case-checkbox-label = Qadeá¹› amasal n isekkilen
+pdfjs-find-match-diacritics-checkbox-label = Qadeá¹› ifeskilen
+pdfjs-find-entire-word-checkbox-label = Awalen iÄÄuranen
+pdfjs-find-reached-top = YabbeḠs afella n usebter, tuɣalin s wadda
+pdfjs-find-reached-bottom = Tebá¸eḠs adda n usebter, tuÉ£alin s afella
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] Timeá¸riwt { $current } É£ef { $total }
+ *[other] Timeá¸riwin { $current } É£ef { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Ugar n { $limit } umá¹£ada
+ *[other] Ugar n { $limit } yimá¹£adayen
+ }
+pdfjs-find-not-found = Ulac tawinest
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Tehri n usebter
+pdfjs-page-scale-fit = Asebter imaṛṛa
+pdfjs-page-scale-auto = Asemɣeṛ/Asemẓi awurman
+pdfjs-page-scale-actual = Teɣzi tilawt
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Asebter { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Teá¸ra-d tuccá¸a deg alluy n PDF:
+pdfjs-invalid-file-error = Afaylu PDF arameɣtu neɣ yexṣeṛ.
+pdfjs-missing-file-error = Ulac afaylu PDF.
+pdfjs-unexpected-response-error = Aqeddac yerra-d yir tiririt ur nettwaṛǧi ara.
+pdfjs-rendering-error = Teá¸ra-d tuccá¸a deg uskan n usebter.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Tabzimt { $type }]
+
+## Password
+
+pdfjs-password-label = Sekcem awal uffir akken ad ldiḠafaylu-yagi PDF
+pdfjs-password-invalid = Awal uffir maÄÄi d ameÉ£tu, ÆreḠtikelt-nniá¸en.
+pdfjs-password-ok-button = IH
+pdfjs-password-cancel-button = Sefsex
+pdfjs-web-fonts-disabled = Tisefsiyin web ttwassensent; D awezɣi useqdec n tsefsiyin yettwarnan ɣer PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Aá¸ris
+pdfjs-editor-free-text-button-label = Aá¸ris
+pdfjs-editor-ink-button =
+ .title = Suneɣ
+pdfjs-editor-ink-button-label = Suneɣ
+pdfjs-editor-stamp-button =
+ .title = Rnu neɣ ẓreg tugniwin
+pdfjs-editor-stamp-button-label = Rnu neɣ ẓreg tugniwin
+pdfjs-editor-remove-button =
+ .title = Kkes
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Initen
+pdfjs-editor-free-text-size-input = Teɣzi
+pdfjs-editor-ink-color-input = Ini
+pdfjs-editor-ink-thickness-input = Tuzert
+pdfjs-editor-ink-opacity-input = Tebrek
+pdfjs-editor-stamp-add-image-button =
+ .title = Rnu tawlaft
+pdfjs-editor-stamp-add-image-button-label = Rnu tawlaft
+pdfjs-free-text =
+ .aria-label = Amaẓrag n uá¸ris
+pdfjs-free-text-default-content = Bdu tira...
+pdfjs-ink =
+ .aria-label = Amaẓrag n usuneɣ
+pdfjs-ink-canvas =
+ .aria-label = Tugna yettwarnan sɣur useqdac
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Aá¸ris amaskal
+pdfjs-editor-alt-text-edit-button-label = Ẓreg aá¸ris amaskal
+pdfjs-editor-alt-text-dialog-label = Fren taxtirt
+pdfjs-editor-alt-text-add-description-label = Rnu aglam
+pdfjs-editor-alt-text-mark-decorative-label = CreḠd adlag
+pdfjs-editor-alt-text-cancel-button = Sefsex
+pdfjs-editor-alt-text-save-button = Sekles
+pdfjs-editor-alt-text-decorative-tooltip = YettwacreḠd adlag
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/kk/viewer.ftl b/www/lib/pdfjs/modern/web/locale/kk/viewer.ftl
new file mode 100644
index 000000000..cbac1b618
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/kk/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Ðлдыңғы парақ
+pdfjs-previous-button-label = ÐлдыңғыÑÑ‹
+pdfjs-next-button =
+ .title = КелеÑÑ– парақ
+pdfjs-next-button-label = КелеÑÑ–
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Парақ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } ішінен
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = (парақ { $pageNumber }, { $pagesCount } ішінен)
+pdfjs-zoom-out-button =
+ .title = Кішірейту
+pdfjs-zoom-out-button-label = Кішірейту
+pdfjs-zoom-in-button =
+ .title = Үлкейту
+pdfjs-zoom-in-button-label = Үлкейту
+pdfjs-zoom-select =
+ .title = МаÑштаб
+pdfjs-presentation-mode-button =
+ .title = ÐŸÑ€ÐµÐ·ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð½Ðµ ауыÑу
+pdfjs-presentation-mode-button-label = ÐŸÑ€ÐµÐ·ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–
+pdfjs-open-file-button =
+ .title = Файлды ашу
+pdfjs-open-file-button-label = Ðшу
+pdfjs-print-button =
+ .title = БаÑпаға шығару
+pdfjs-print-button-label = БаÑпаға шығару
+pdfjs-save-button =
+ .title = Сақтау
+pdfjs-save-button-label = Сақтау
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Жүктеп алу
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Жүктеп алу
+pdfjs-bookmark-button =
+ .title = Ðғымдағы бет (Ðғымдағы беттен URL адреÑін көру)
+pdfjs-bookmark-button-label = Ðғымдағы бет
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Қолданбада ашу
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Қолданбада ашу
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Құралдар
+pdfjs-tools-button-label = Құралдар
+pdfjs-first-page-button =
+ .title = Ðлғашқы параққа өту
+pdfjs-first-page-button-label = Ðлғашқы параққа өту
+pdfjs-last-page-button =
+ .title = Соңғы параққа өту
+pdfjs-last-page-button-label = Соңғы параққа өту
+pdfjs-page-rotate-cw-button =
+ .title = Сағат тілі бағытымен айналдыру
+pdfjs-page-rotate-cw-button-label = Сағат тілі бағытымен бұру
+pdfjs-page-rotate-ccw-button =
+ .title = Сағат тілі бағытына қарÑÑ‹ бұру
+pdfjs-page-rotate-ccw-button-label = Сағат тілі бағытына қарÑÑ‹ бұру
+pdfjs-cursor-text-select-tool-button =
+ .title = Мәтінді таңдау құралын Ñ–Ñке қоÑу
+pdfjs-cursor-text-select-tool-button-label = Мәтінді таңдау құралы
+pdfjs-cursor-hand-tool-button =
+ .title = Қол құралын Ñ–Ñке қоÑу
+pdfjs-cursor-hand-tool-button-label = Қол құралы
+pdfjs-scroll-page-button =
+ .title = Беттерді айналдыруды пайдалану
+pdfjs-scroll-page-button-label = Беттерді айналдыру
+pdfjs-scroll-vertical-button =
+ .title = Вертикалды айналдыруды қолдану
+pdfjs-scroll-vertical-button-label = Вертикалды айналдыру
+pdfjs-scroll-horizontal-button =
+ .title = Горизонталды айналдыруды қолдану
+pdfjs-scroll-horizontal-button-label = Горизонталды айналдыру
+pdfjs-scroll-wrapped-button =
+ .title = МаÑштабталатын айналдыруды қолдану
+pdfjs-scroll-wrapped-button-label = МаÑштабталатын айналдыру
+pdfjs-spread-none-button =
+ .title = Жазық беттер режимін қолданбау
+pdfjs-spread-none-button-label = Жазық беттер режимÑіз
+pdfjs-spread-odd-button =
+ .title = Жазық беттер тақ нөмірлі беттерден баÑталады
+pdfjs-spread-odd-button-label = Тақ нөмірлі беттер Ñол жақтан
+pdfjs-spread-even-button =
+ .title = Жазық беттер жұп нөмірлі беттерден баÑталады
+pdfjs-spread-even-button-label = Жұп нөмірлі беттер Ñол жақтан
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Құжат қаÑиеттері…
+pdfjs-document-properties-button-label = Құжат қаÑиеттері…
+pdfjs-document-properties-file-name = Файл аты:
+pdfjs-document-properties-file-size = Файл өлшемі:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } байт)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } байт)
+pdfjs-document-properties-title = Тақырыбы:
+pdfjs-document-properties-author = Ðвторы:
+pdfjs-document-properties-subject = Тақырыбы:
+pdfjs-document-properties-keywords = Кілт Ñөздер:
+pdfjs-document-properties-creation-date = ЖаÑалған күні:
+pdfjs-document-properties-modification-date = Түзету күні:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ЖаÑаған:
+pdfjs-document-properties-producer = PDF өндірген:
+pdfjs-document-properties-version = PDF нұÑқаÑÑ‹:
+pdfjs-document-properties-page-count = Беттер Ñаны:
+pdfjs-document-properties-page-size = Бет өлшемі:
+pdfjs-document-properties-page-size-unit-inches = дюйм
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = тік
+pdfjs-document-properties-page-size-orientation-landscape = жатық
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Жылдам Web көрініÑÑ–:
+pdfjs-document-properties-linearized-yes = Иә
+pdfjs-document-properties-linearized-no = Жоқ
+pdfjs-document-properties-close-button = Жабу
+
+## Print
+
+pdfjs-print-progress-message = Құжатты баÑпаға шығару үшін дайындау…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Ð‘Ð°Ñ Ñ‚Ð°Ñ€Ñ‚Ñƒ
+pdfjs-printing-not-supported = ЕÑкерту: БаÑпаға шығаруды бұл браузер толығымен қолдамайды.
+pdfjs-printing-not-ready = ЕÑкерту: БаÑпаға шығару үшін, бұл PDF толығымен жүктеліп алынбады.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Бүйір панелін көрÑету/жаÑыру
+pdfjs-toggle-sidebar-notification-button =
+ .title = Бүйір панелін көрÑету/жаÑыру (құжатта құрылымы/Ñалынымдар/қабаттар бар)
+pdfjs-toggle-sidebar-button-label = Бүйір панелін көрÑету/жаÑыру
+pdfjs-document-outline-button =
+ .title = Құжат құрылымын көрÑету (барлық нәрÑелерді жазық қылу/жинау үшін Ò›Ð¾Ñ ÑˆÐµÑ€Ñ‚Ñƒ керек)
+pdfjs-document-outline-button-label = Құжат құрамаÑÑ‹
+pdfjs-attachments-button =
+ .title = Салынымдарды көрÑету
+pdfjs-attachments-button-label = Салынымдар
+pdfjs-layers-button =
+ .title = Қабаттарды көрÑету (барлық қабаттарды баÑтапқы күйге келтіру үшін екі рет шертіңіз)
+pdfjs-layers-button-label = Қабаттар
+pdfjs-thumbs-button =
+ .title = Кіші көрініÑтерді көрÑету
+pdfjs-thumbs-button-label = Кіші көрініÑтер
+pdfjs-current-outline-item-button =
+ .title = Құрылымның ағымдағы Ñлементін табу
+pdfjs-current-outline-item-button-label = Құрылымның ағымдағы Ñлементі
+pdfjs-findbar-button =
+ .title = Құжаттан табу
+pdfjs-findbar-button-label = Табу
+pdfjs-additional-layers = ҚоÑымша қабаттар
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } парағы
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } парағы үшін кіші көрініÑÑ–
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Табу
+ .placeholder = Құжаттан табу…
+pdfjs-find-previous-button =
+ .title = ОÑÑ‹ Ñөздердің мәтіннен алдыңғы кездеÑуін табу
+pdfjs-find-previous-button-label = ÐлдыңғыÑÑ‹
+pdfjs-find-next-button =
+ .title = ОÑÑ‹ Ñөздердің мәтіннен келеÑÑ– кездеÑуін табу
+pdfjs-find-next-button-label = КелеÑÑ–
+pdfjs-find-highlight-checkbox = Барлығын Ñ‚Ò¯Ñпен ерекшелеу
+pdfjs-find-match-case-checkbox-label = РегиÑтрді еÑкеру
+pdfjs-find-match-diacritics-checkbox-label = Диакритиканы еÑкеру
+pdfjs-find-entire-word-checkbox-label = Сөздер толығымен
+pdfjs-find-reached-top = Құжаттың баÑына жеттік, Ñоңынан баÑтап жалғаÑтырамыз
+pdfjs-find-reached-bottom = Құжаттың Ñоңына жеттік, баÑынан баÑтап жалғаÑтырамыз
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } ÑәйкеÑтік, барлығы { $total }
+ *[other] { $current } ÑәйкеÑтік, барлығы { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] { $limit } ÑәйкеÑтіктен көп
+ *[other] { $limit } ÑәйкеÑтіктен көп
+ }
+pdfjs-find-not-found = Сөз(дер) табылмады
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Парақ ені
+pdfjs-page-scale-fit = Парақты Ñыйдыру
+pdfjs-page-scale-auto = ÐвтомаÑштабтау
+pdfjs-page-scale-actual = Ðақты өлшемі
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Бет { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF жүктеу кезінде қате кетті.
+pdfjs-invalid-file-error = Зақымдалған немеÑе қате PDF файл.
+pdfjs-missing-file-error = PDF файлы жоқ.
+pdfjs-unexpected-response-error = Сервердің күтпеген жауабы.
+pdfjs-rendering-error = Парақты өңдеу кезінде қате кетті.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } аңдатпаÑÑ‹]
+
+## Password
+
+pdfjs-password-label = Бұл PDF файлын ашу үшін парольді енгізіңіз.
+pdfjs-password-invalid = Пароль Ð´Ò±Ñ€Ñ‹Ñ ÐµÐ¼ÐµÑ. Қайталап көріңіз.
+pdfjs-password-ok-button = ОК
+pdfjs-password-cancel-button = Ð‘Ð°Ñ Ñ‚Ð°Ñ€Ñ‚Ñƒ
+pdfjs-web-fonts-disabled = Веб қаріптері Ñөндірілген: құрамына енгізілген PDF қаріптерін қолдану мүмкін емеÑ.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Мәтін
+pdfjs-editor-free-text-button-label = Мәтін
+pdfjs-editor-ink-button =
+ .title = Сурет Ñалу
+pdfjs-editor-ink-button-label = Сурет Ñалу
+pdfjs-editor-stamp-button =
+ .title = Суреттерді қоÑу немеÑе түзету
+pdfjs-editor-stamp-button-label = Суреттерді қоÑу немеÑе түзету
+pdfjs-editor-remove-button =
+ .title = Өшіру
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Сызбаны өшіру
+pdfjs-editor-remove-freetext-button =
+ .title = Мәтінді өшіру
+pdfjs-editor-remove-stamp-button =
+ .title = Суретті өшіру
+pdfjs-editor-remove-highlight-button =
+ .title = ТүÑпен ерекшелеуді өшіру
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ТүÑ
+pdfjs-editor-free-text-size-input = Өлшемі
+pdfjs-editor-ink-color-input = ТүÑ
+pdfjs-editor-ink-thickness-input = Қалыңдығы
+pdfjs-editor-ink-opacity-input = МөлдірÑіздігі
+pdfjs-editor-stamp-add-image-button =
+ .title = Суретті қоÑу
+pdfjs-editor-stamp-add-image-button-label = Суретті қоÑу
+pdfjs-free-text =
+ .aria-label = Мәтін түзеткіші
+pdfjs-free-text-default-content = Теруді баÑтау…
+pdfjs-ink =
+ .aria-label = Сурет түзеткіші
+pdfjs-ink-canvas =
+ .aria-label = Пайдаланушы жаÑаған Ñурет
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Балама мәтін
+pdfjs-editor-alt-text-edit-button-label = Балама мәтінді өңдеу
+pdfjs-editor-alt-text-dialog-label = ОпциÑны таңдау
+pdfjs-editor-alt-text-dialog-description = Балама мәтін адамдар Ñуретті көре алмағанда немеÑе ол жүктелмегенде көмектеÑеді.
+pdfjs-editor-alt-text-add-description-label = Сипаттаманы қоÑу
+pdfjs-editor-alt-text-add-description-description = Тақырыпты, баптауды немеÑе әрекетті Ñипаттайтын 1-2 Ñөйлемді қолдануға тырыÑыңыз.
+pdfjs-editor-alt-text-mark-decorative-label = Декоративті деп белгілеу
+pdfjs-editor-alt-text-mark-decorative-description = Бұл жиектер немеÑе Ñу белгілері ÑиÑқты оюлық Ñуреттер үшін пайдаланылады.
+pdfjs-editor-alt-text-cancel-button = Ð‘Ð°Ñ Ñ‚Ð°Ñ€Ñ‚Ñƒ
+pdfjs-editor-alt-text-save-button = Сақтау
+pdfjs-editor-alt-text-decorative-tooltip = Декоративті деп белгіленген
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = МыÑалы, "Ð–Ð°Ñ Ð¶Ñ–Ð³Ñ–Ñ‚ тамақ ішу үшін Ò¯Ñтел баÑына отырады"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Жоғарғы Ñол жақ бұрыш — өлшемін өзгерту
+pdfjs-editor-resizer-label-top-middle = Жоғарғы ортаÑÑ‹ — өлшемін өзгерту
+pdfjs-editor-resizer-label-top-right = Жоғарғы оң жақ бұрыш — өлшемін өзгерту
+pdfjs-editor-resizer-label-middle-right = Ортаңғы оң жақ — өлшемін өзгерту
+pdfjs-editor-resizer-label-bottom-right = Төменгі оң жақ бұрыш — өлшемін өзгерту
+pdfjs-editor-resizer-label-bottom-middle = Төменгі ортаÑÑ‹ — өлшемін өзгерту
+pdfjs-editor-resizer-label-bottom-left = Төменгі Ñол жақ бұрыш — өлшемін өзгерту
+pdfjs-editor-resizer-label-middle-left = Ортаңғы Ñол жақ — өлшемін өзгерту
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Ерекшелеу Ñ‚Ò¯ÑÑ–
+pdfjs-editor-colorpicker-button =
+ .title = ТүÑÑ‚Ñ– өзгерту
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Ð¢Ò¯Ñ Ñ‚Ð°Ò£Ð´Ð°ÑƒÐ»Ð°Ñ€Ñ‹
+pdfjs-editor-colorpicker-yellow =
+ .title = Сары
+pdfjs-editor-colorpicker-green =
+ .title = ЖаÑыл
+pdfjs-editor-colorpicker-blue =
+ .title = Көк
+pdfjs-editor-colorpicker-pink =
+ .title = Қызғылт
+pdfjs-editor-colorpicker-red =
+ .title = Қызыл
diff --git a/www/lib/pdfjs/modern/web/locale/km/viewer.ftl b/www/lib/pdfjs/modern/web/locale/km/viewer.ftl
new file mode 100644
index 000000000..6efd10546
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/km/viewer.ftl
@@ -0,0 +1,223 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ទំពáŸážšâ€‹áž˜áž»áž“
+pdfjs-previous-button-label = មុន
+pdfjs-next-button =
+ .title = ទំពáŸážšâ€‹áž”ន្ទាប់
+pdfjs-next-button-label = បន្ទាប់
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ទំពáŸážš
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = នៃ { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } នៃ { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ​បង្រួម
+pdfjs-zoom-out-button-label = ​បង្រួម
+pdfjs-zoom-in-button =
+ .title = ​ពង្រីក
+pdfjs-zoom-in-button-label = ​ពង្រីក
+pdfjs-zoom-select =
+ .title = ពង្រីក
+pdfjs-presentation-mode-button =
+ .title = ប្ដូរ​ទៅ​របៀប​បទ​បង្ហាញ
+pdfjs-presentation-mode-button-label = របៀប​បទ​បង្ហាញ
+pdfjs-open-file-button =
+ .title = បើក​ឯកសារ
+pdfjs-open-file-button-label = បើក
+pdfjs-print-button =
+ .title = បោះពុម្ព
+pdfjs-print-button-label = បោះពុម្ព
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ឧបករណáŸ
+pdfjs-tools-button-label = ឧបករណáŸ
+pdfjs-first-page-button =
+ .title = ទៅកាន់​ទំពáŸážšâ€‹ážŠáŸ†áž”ូង​
+pdfjs-first-page-button-label = ទៅកាន់​ទំពáŸážšâ€‹ážŠáŸ†áž”ូង​
+pdfjs-last-page-button =
+ .title = ទៅកាន់​ទំពáŸážšâ€‹áž…ុងក្រោយ​
+pdfjs-last-page-button-label = ទៅកាន់​ទំពáŸážšâ€‹áž…ុងក្រោយ
+pdfjs-page-rotate-cw-button =
+ .title = បង្វិល​ស្រប​ទ្រនិច​នាឡិកា
+pdfjs-page-rotate-cw-button-label = បង្វិល​ស្រប​ទ្រនិច​នាឡិកា
+pdfjs-page-rotate-ccw-button =
+ .title = បង្វិល​ច្រាស​ទ្រនិច​នាឡិកា​​
+pdfjs-page-rotate-ccw-button-label = បង្វិល​ច្រាស​ទ្រនិច​នាឡិកា​​
+pdfjs-cursor-text-select-tool-button =
+ .title = បើក​ឧបករណáŸâ€‹áž‡áŸ’រើស​អážáŸ’ážáž”áž‘
+pdfjs-cursor-text-select-tool-button-label = ឧបករណáŸâ€‹áž‡áŸ’រើស​អážáŸ’ážáž”áž‘
+pdfjs-cursor-hand-tool-button =
+ .title = បើក​ឧបករណáŸâ€‹ážŠáŸƒ
+pdfjs-cursor-hand-tool-button-label = ឧបករណáŸâ€‹ážŠáŸƒ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = លក្ážážŽâ€‹ážŸáž˜áŸ’áž”ážáŸ’ážáž·â€‹áž¯áž€ážŸáž¶ážšâ€¦
+pdfjs-document-properties-button-label = លក្ážážŽâ€‹ážŸáž˜áŸ’áž”ážáŸ’ážáž·â€‹áž¯áž€ážŸáž¶ážšâ€¦
+pdfjs-document-properties-file-name = ឈ្មោះ​ឯកសារ៖
+pdfjs-document-properties-file-size = ទំហំ​ឯកសារ៖
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } បៃ)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } បៃ)
+pdfjs-document-properties-title = ចំណងជើង៖
+pdfjs-document-properties-author = អ្នក​និពន្ធ៖
+pdfjs-document-properties-subject = ប្រធានបទ៖
+pdfjs-document-properties-keywords = ពាក្យ​គន្លឹះ៖
+pdfjs-document-properties-creation-date = កាលបរិច្ឆáŸáž‘​បង្កើážáŸ–
+pdfjs-document-properties-modification-date = កាលបរិច្ឆáŸáž‘​កែប្រែ៖
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = អ្នក​បង្កើážáŸ–
+pdfjs-document-properties-producer = កម្មវិធី​បង្កើហPDF ៖
+pdfjs-document-properties-version = កំណែ PDF ៖
+pdfjs-document-properties-page-count = ចំនួន​ទំពáŸážšáŸ–
+pdfjs-document-properties-page-size-unit-inches = អ៊ីញ
+pdfjs-document-properties-page-size-unit-millimeters = មម
+pdfjs-document-properties-page-size-orientation-portrait = បញ្ឈរ
+pdfjs-document-properties-page-size-orientation-landscape = ផ្ážáŸáž€
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = សំបុážáŸ’ážš
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = បាទ/ចាស
+pdfjs-document-properties-linearized-no = áž‘áŸ
+pdfjs-document-properties-close-button = បិទ
+
+## Print
+
+pdfjs-print-progress-message = កំពុង​រៀបចំ​ឯកសារ​សម្រាប់​បោះពុម្ព…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = បោះបង់
+pdfjs-printing-not-supported = ការ​ព្រមាន ៖ កា​រ​បោះពុម្ព​មិន​ážáŸ’រូវ​បាន​គាំទ្រ​ពáŸáž‰áž›áŸáž‰â€‹ážŠáŸ„យ​កម្មវិធី​រុករក​នáŸáŸ‡â€‹áž‘áŸÂ ។
+pdfjs-printing-not-ready = ព្រមាន៖ PDF មិន​ážáŸ’រូវ​បាន​ផ្ទុក​ទាំងស្រុង​ដើម្បី​បោះពុម្ព​ទáŸáŸ”
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = បិទ/បើក​គ្រាប់​រំកិល
+pdfjs-toggle-sidebar-button-label = បិទ/បើក​គ្រាប់​រំកិល
+pdfjs-document-outline-button =
+ .title = បង្ហាញ​គ្រោង​ឯកសារ (ចុច​ទ្វáŸâ€‹ážŠáž„​ដើម្បី​ពង្រីក/បង្រួម​ធាážáž»â€‹áž‘ាំងអស់)
+pdfjs-document-outline-button-label = គ្រោង​ឯកសារ
+pdfjs-attachments-button =
+ .title = បង្ហាញ​ឯកសារ​ភ្ជាប់
+pdfjs-attachments-button-label = ឯកសារ​ភ្ជាប់
+pdfjs-thumbs-button =
+ .title = បង្ហាញ​រូបភាព​ážáž¼áž…ៗ
+pdfjs-thumbs-button-label = រួបភាព​ážáž¼áž…ៗ
+pdfjs-findbar-button =
+ .title = រក​នៅ​ក្នុង​ឯកសារ
+pdfjs-findbar-button-label = រក
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = ទំពáŸážš { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = រូបភាព​ážáž¼áž…​របស់​ទំពáŸážš { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = រក
+ .placeholder = រក​នៅ​ក្នុង​ឯកសារ...
+pdfjs-find-previous-button =
+ .title = រក​ពាក្យ ឬ​ឃ្លា​ដែល​បាន​ជួប​មុន
+pdfjs-find-previous-button-label = មុន
+pdfjs-find-next-button =
+ .title = រក​ពាក្យ ឬ​ឃ្លា​ដែល​បាន​ជួប​បន្ទាប់
+pdfjs-find-next-button-label = បន្ទាប់
+pdfjs-find-highlight-checkbox = បន្លិច​ទាំងអស់
+pdfjs-find-match-case-checkbox-label = ករណី​ដំណូច
+pdfjs-find-reached-top = បាន​បន្ážâ€‹áž–ី​ážáž¶áž„​ក្រោម ទៅ​ដល់​ážáž¶áž„​​លើ​នៃ​ឯកសារ
+pdfjs-find-reached-bottom = បាន​បន្ážâ€‹áž–ី​ážáž¶áž„លើ ទៅដល់​ចុង​​នៃ​ឯកសារ
+pdfjs-find-not-found = រក​មិន​ឃើញ​ពាក្យ ឬ​ឃ្លា
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ទទឹង​ទំពáŸážš
+pdfjs-page-scale-fit = សម​ទំពáŸážš
+pdfjs-page-scale-auto = ពង្រីក​ស្វáŸáž™áž”្រវážáŸ’ážáž·
+pdfjs-page-scale-actual = ទំហំ​ជាក់ស្ដែង
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = មាន​កំហុស​បាន​កើážáž¡áž¾áž„​ពáŸáž›â€‹áž€áŸ†áž–ុង​ផ្ទុក PDF ។
+pdfjs-invalid-file-error = ឯកសារ PDF ážáž¼áž… ឬ​មិន​ážáŸ’រឹមážáŸ’រូវ ។
+pdfjs-missing-file-error = បាážáŸ‹â€‹áž¯áž€ážŸáž¶ážš PDF
+pdfjs-unexpected-response-error = ការ​ឆ្លើយ​ážáž˜â€‹áž˜áŸ‰áž¶ážŸáŸŠáž¸áž“​មáŸâ€‹ážŠáŸ‚ល​មិន​បាន​រំពឹង។
+pdfjs-rendering-error = មាន​កំហុស​បាន​កើážáž¡áž¾áž„​ពáŸáž›â€‹áž”ង្ហាញ​ទំពáŸážšÂ ។
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ចំណារ​ពន្យល់]
+
+## Password
+
+pdfjs-password-label = បញ្ចូល​ពាក្យសម្ងាážáŸ‹â€‹ážŠáž¾áž˜áŸ’បី​បើក​ឯកសារ PDF áž“áŸáŸ‡áŸ”
+pdfjs-password-invalid = ពាក្យសម្ងាážáŸ‹â€‹áž˜áž·áž“​ážáŸ’រឹមážáŸ’រូវ។ សូម​ព្យាយាម​ម្ដងទៀážáŸ”
+pdfjs-password-ok-button = យល់​ព្រម
+pdfjs-password-cancel-button = បោះបង់
+pdfjs-web-fonts-disabled = បាន​បិទ​ពុម្ពអក្សរ​បណ្ដាញ ៖ មិន​អាច​ប្រើ​ពុម្ពអក្សរ PDF ដែល​បាន​បង្កប់​បាន​ទáŸÂ ។
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/kn/viewer.ftl b/www/lib/pdfjs/modern/web/locale/kn/viewer.ftl
new file mode 100644
index 000000000..03322555e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/kn/viewer.ftl
@@ -0,0 +1,213 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ಹಿಂದಿನ ಪà³à²Ÿ
+pdfjs-previous-button-label = ಹಿಂದಿನ
+pdfjs-next-button =
+ .title = ಮà³à²‚ದಿನ ಪà³à²Ÿ
+pdfjs-next-button-label = ಮà³à²‚ದಿನ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ಪà³à²Ÿ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } ರಲà³à²²à²¿
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } ರಲà³à²²à²¿ { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = ಕಿರಿದಾಗಿಸà³
+pdfjs-zoom-out-button-label = ಕಿರಿದಾಗಿಸಿ
+pdfjs-zoom-in-button =
+ .title = ಹಿರಿದಾಗಿಸà³
+pdfjs-zoom-in-button-label = ಹಿರಿದಾಗಿಸಿ
+pdfjs-zoom-select =
+ .title = ಗಾತà³à²°à²¬à²¦à²²à²¿à²¸à³
+pdfjs-presentation-mode-button =
+ .title = ಪà³à²°à²¸à³à²¤à³à²¤à²¿ (ಪà³à²°à²¸à³†à²‚ಟೇಶನà³) ಕà³à²°à²®à²•à³à²•à³† ಬದಲಾಯಿಸà³
+pdfjs-presentation-mode-button-label = ಪà³à²°à²¸à³à²¤à³à²¤à²¿ (ಪà³à²°à²¸à³†à²‚ಟೇಶನà³) ಕà³à²°à²®
+pdfjs-open-file-button =
+ .title = ಕಡತವನà³à²¨à³ ತೆರೆ
+pdfjs-open-file-button-label = ತೆರೆಯಿರಿ
+pdfjs-print-button =
+ .title = ಮà³à²¦à³à²°à²¿à²¸à³
+pdfjs-print-button-label = ಮà³à²¦à³à²°à²¿à²¸à²¿
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ಉಪಕರಣಗಳà³
+pdfjs-tools-button-label = ಉಪಕರಣಗಳà³
+pdfjs-first-page-button =
+ .title = ಮೊದಲ ಪà³à²Ÿà²•à³à²•à³† ತೆರಳà³
+pdfjs-first-page-button-label = ಮೊದಲ ಪà³à²Ÿà²•à³à²•à³† ತೆರಳà³
+pdfjs-last-page-button =
+ .title = ಕೊನೆಯ ಪà³à²Ÿà²•à³à²•à³† ತೆರಳà³
+pdfjs-last-page-button-label = ಕೊನೆಯ ಪà³à²Ÿà²•à³à²•à³† ತೆರಳà³
+pdfjs-page-rotate-cw-button =
+ .title = ಪà³à²°à²¦à²•à³à²·à²¿à²£à³†à²¯à²²à³à²²à²¿ ತಿರà³à²—ಿಸà³
+pdfjs-page-rotate-cw-button-label = ಪà³à²°à²¦à²•à³à²·à²¿à²£à³†à²¯à²²à³à²²à²¿ ತಿರà³à²—ಿಸà³
+pdfjs-page-rotate-ccw-button =
+ .title = ಅಪà³à²°à²¦à²•à³à²·à²¿à²£à³†à²¯à²²à³à²²à²¿ ತಿರà³à²—ಿಸà³
+pdfjs-page-rotate-ccw-button-label = ಅಪà³à²°à²¦à²•à³à²·à²¿à²£à³†à²¯à²²à³à²²à²¿ ತಿರà³à²—ಿಸà³
+pdfjs-cursor-text-select-tool-button =
+ .title = ಪಠà³à²¯ ಆಯà³à²•à³† ಉಪಕರಣವನà³à²¨à³ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಿ
+pdfjs-cursor-text-select-tool-button-label = ಪಠà³à²¯ ಆಯà³à²•à³†à²¯ ಉಪಕರಣ
+pdfjs-cursor-hand-tool-button =
+ .title = ಕೈ ಉಪಕರಣವನà³à²¨à³ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಿ
+pdfjs-cursor-hand-tool-button-label = ಕೈ ಉಪಕರಣ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ಡಾಕà³à²¯à³à²®à³†à²‚ಟà³â€Œ ಗà³à²£à²—ಳà³...
+pdfjs-document-properties-button-label = ಡಾಕà³à²¯à³à²®à³†à²‚ಟà³â€Œ ಗà³à²£à²—ಳà³...
+pdfjs-document-properties-file-name = ಕಡತದ ಹೆಸರà³:
+pdfjs-document-properties-file-size = ಕಡತದ ಗಾತà³à²°:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ಬೈಟà³â€à²—ಳà³)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ಬೈಟà³â€à²—ಳà³)
+pdfjs-document-properties-title = ಶೀರà³à²·à²¿à²•à³†:
+pdfjs-document-properties-author = ಕರà³à²¤à³ƒ:
+pdfjs-document-properties-subject = ವಿಷಯ:
+pdfjs-document-properties-keywords = ಮà³à²–à³à²¯à²ªà²¦à²—ಳà³:
+pdfjs-document-properties-creation-date = ರಚಿಸಿದ ದಿನಾಂಕ:
+pdfjs-document-properties-modification-date = ಮಾರà³à²ªà²¡à²¿à²¸à²²à²¾à²¦ ದಿನಾಂಕ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ರಚಿಸಿದವರà³:
+pdfjs-document-properties-producer = PDF ಉತà³à²ªà²¾à²¦à²•:
+pdfjs-document-properties-version = PDF ಆವೃತà³à²¤à²¿:
+pdfjs-document-properties-page-count = ಪà³à²Ÿà²¦ ಎಣಿಕೆ:
+pdfjs-document-properties-page-size-unit-inches = ಇದರಲà³à²²à²¿
+pdfjs-document-properties-page-size-orientation-portrait = à²à²¾à²µà²šà²¿à²¤à³à²°
+pdfjs-document-properties-page-size-orientation-landscape = ಪà³à²°à²•à³ƒà²¤à²¿ ಚಿತà³à²°
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = ಮà³à²šà³à²šà³
+
+## Print
+
+pdfjs-print-progress-message = ಮà³à²¦à³à²°à²¿à²¸à³à²µà³à²¦à²•à³à²•à²¾à²—ಿ ದಸà³à²¤à²¾à²µà³‡à²œà²¨à³à²¨à³ ಸಿದà³à²§à²—ೊಳಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†â€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ರದà³à²¦à³ ಮಾಡà³
+pdfjs-printing-not-supported = ಎಚà³à²šà²°à²¿à²•à³†: ಈ ಜಾಲವೀಕà³à²·à²•à²¦à²²à³à²²à²¿ ಮà³à²¦à³à²°à²£à²•à³à²•à³† ಸಂಪೂರà³à²£ ಬೆಂಬಲವಿಲà³à²².
+pdfjs-printing-not-ready = ಎಚà³à²šà²°à²¿à²•à³†: PDF ಕಡತವೠಮà³à²¦à³à²°à²¿à²¸à²²à³ ಸಂಪೂರà³à²£à²µà²¾à²—ಿ ಲೋಡೠಆಗಿಲà³à²².
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ಬದಿಪಟà³à²Ÿà²¿à²¯à²¨à³à²¨à³ ಹೊರಳಿಸà³
+pdfjs-toggle-sidebar-button-label = ಬದಿಪಟà³à²Ÿà²¿à²¯à²¨à³à²¨à³ ಹೊರಳಿಸà³
+pdfjs-document-outline-button-label = ದಸà³à²¤à²¾à²µà³‡à²œà²¿à²¨ ಹೊರರೇಖೆ
+pdfjs-attachments-button =
+ .title = ಲಗತà³à²¤à³à²—ಳನà³à²¨à³ ತೋರಿಸà³
+pdfjs-attachments-button-label = ಲಗತà³à²¤à³à²—ಳà³
+pdfjs-thumbs-button =
+ .title = ಚಿಕà³à²•à²šà²¿à²¤à³à²°à²¦à²‚ತೆ ತೋರಿಸà³
+pdfjs-thumbs-button-label = ಚಿಕà³à²•à²šà²¿à²¤à³à²°à²—ಳà³
+pdfjs-findbar-button =
+ .title = ದಸà³à²¤à²¾à²µà³‡à²œà²¿à²¨à²²à³à²²à²¿ ಹà³à²¡à³à²•à³
+pdfjs-findbar-button-label = ಹà³à²¡à³à²•à³
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = ಪà³à²Ÿ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ಪà³à²Ÿà²µà²¨à³à²¨à³ ಚಿಕà³à²•à²šà²¿à²¤à³à²°à²¦à²‚ತೆ ತೋರಿಸೠ{ $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ಹà³à²¡à³à²•à³
+ .placeholder = ದಸà³à²¤à²¾à²µà³‡à²œà²¿à²¨à²²à³à²²à²¿ ಹà³à²¡à³à²•à³â€¦
+pdfjs-find-previous-button =
+ .title = ವಾಕà³à²¯à²¦ ಹಿಂದಿನ ಇರà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಹà³à²¡à³à²•à³
+pdfjs-find-previous-button-label = ಹಿಂದಿನ
+pdfjs-find-next-button =
+ .title = ವಾಕà³à²¯à²¦ ಮà³à²‚ದಿನ ಇರà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಹà³à²¡à³à²•à³
+pdfjs-find-next-button-label = ಮà³à²‚ದಿನ
+pdfjs-find-highlight-checkbox = ಎಲà³à²²à²µà²¨à³à²¨à³ ಹೈಲೈಟೠಮಾಡà³
+pdfjs-find-match-case-checkbox-label = ಕೇಸನà³à²¨à³ ಹೊಂದಿಸà³
+pdfjs-find-reached-top = ದಸà³à²¤à²¾à²µà³‡à²œà²¿à²¨ ಮೇಲà³à²à²¾à²—ವನà³à²¨à³ ತಲà³à²ªà²¿à²¦à³†, ಕೆಳಗಿನಿಂದ ಆರಂà²à²¿à²¸à³
+pdfjs-find-reached-bottom = ದಸà³à²¤à²¾à²µà³‡à²œà²¿à²¨ ಕೊನೆಯನà³à²¨à³ ತಲà³à²ªà²¿à²¦à³†, ಮೇಲಿನಿಂದ ಆರಂà²à²¿à²¸à³
+pdfjs-find-not-found = ವಾಕà³à²¯à²µà³ ಕಂಡೠಬಂದಿಲà³à²²
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ಪà³à²Ÿà²¦ ಅಗಲ
+pdfjs-page-scale-fit = ಪà³à²Ÿà²¦ ಸರಿಹೊಂದಿಕೆ
+pdfjs-page-scale-auto = ಸà³à²µà²¯à²‚ಚಾಲಿತ ಗಾತà³à²°à²¬à²¦à²²à²¾à²µà²£à³†
+pdfjs-page-scale-actual = ನಿಜವಾದ ಗಾತà³à²°
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ಅನà³à²¨à³ ಲೋಡೠಮಾಡà³à²µà²¾à²— ಒಂದೠದೋಷ ಎದà³à²°à²¾à²—ಿದೆ.
+pdfjs-invalid-file-error = ಅಮಾನà³à²¯à²µà²¾à²¦ ಅಥವ ಹಾಳಾದ PDF ಕಡತ.
+pdfjs-missing-file-error = PDF ಕಡತ ಇಲà³à²².
+pdfjs-unexpected-response-error = ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²¦ ಪೂರೈಕೆಗಣಕದ ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à³†.
+pdfjs-rendering-error = ಪà³à²Ÿà²µà²¨à³à²¨à³ ನಿರೂಪಿಸà³à²µà²¾à²— ಒಂದೠದೋಷ ಎದà³à²°à²¾à²—ಿದೆ.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ಟಿಪà³à²ªà²£à²¿]
+
+## Password
+
+pdfjs-password-label = PDF ಅನà³à²¨à³ ತೆರೆಯಲೠಗà³à²ªà³à²¤à²ªà²¦à²µà²¨à³à²¨à³ ನಮೂದಿಸಿ.
+pdfjs-password-invalid = ಅಮಾನà³à²¯à²µà²¾à²¦ ಗà³à²ªà³à²¤à²ªà²¦, ದಯವಿಟà³à²Ÿà³ ಇನà³à²¨à³Šà²®à³à²®à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = ರದà³à²¦à³ ಮಾಡà³
+pdfjs-web-fonts-disabled = ಜಾಲ ಅಕà³à²·à²°à²¶à³ˆà²²à²¿à²¯à²¨à³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿದೆ: ಅಡಕಗೊಳಿಸಿದ PDF ಅಕà³à²·à²°à²¶à³ˆà²²à²¿à²—ಳನà³à²¨à³ ಬಳಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಿಲà³à²².
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ko/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ko/viewer.ftl
new file mode 100644
index 000000000..618f2c244
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ko/viewer.ftl
@@ -0,0 +1,376 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ì´ì „ 페ì´ì§€
+pdfjs-previous-button-label = ì´ì „
+pdfjs-next-button =
+ .title = ë‹¤ìŒ íŽ˜ì´ì§€
+pdfjs-next-button-label = 다ìŒ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = 페ì´ì§€
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = 축소
+pdfjs-zoom-out-button-label = 축소
+pdfjs-zoom-in-button =
+ .title = 확대
+pdfjs-zoom-in-button-label = 확대
+pdfjs-zoom-select =
+ .title = 확대/축소
+pdfjs-presentation-mode-button =
+ .title = í”„ë ˆì í…Œì´ì…˜ 모드로 ì „í™˜
+pdfjs-presentation-mode-button-label = í”„ë ˆì í…Œì´ì…˜ 모드
+pdfjs-open-file-button =
+ .title = íŒŒì¼ ì—´ê¸°
+pdfjs-open-file-button-label = 열기
+pdfjs-print-button =
+ .title = ì¸ì‡„
+pdfjs-print-button-label = ì¸ì‡„
+pdfjs-save-button =
+ .title = ì €ìž¥
+pdfjs-save-button-label = ì €ìž¥
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = 다운로드
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = 다운로드
+pdfjs-bookmark-button =
+ .title = 현재 페ì´ì§€ (현재 페ì´ì§€ì—ì„œ URL 보기)
+pdfjs-bookmark-button-label = 현재 페ì´ì§€
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = 앱ì—ì„œ 열기
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = 앱ì—ì„œ 열기
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ë„구
+pdfjs-tools-button-label = ë„구
+pdfjs-first-page-button =
+ .title = 첫 페ì´ì§€ë¡œ ì´ë™
+pdfjs-first-page-button-label = 첫 페ì´ì§€ë¡œ ì´ë™
+pdfjs-last-page-button =
+ .title = 마지막 페ì´ì§€ë¡œ ì´ë™
+pdfjs-last-page-button-label = 마지막 페ì´ì§€ë¡œ ì´ë™
+pdfjs-page-rotate-cw-button =
+ .title = 시계방향으로 íšŒì „
+pdfjs-page-rotate-cw-button-label = 시계방향으로 íšŒì „
+pdfjs-page-rotate-ccw-button =
+ .title = 시계 반대방향으로 íšŒì „
+pdfjs-page-rotate-ccw-button-label = 시계 반대방향으로 íšŒì „
+pdfjs-cursor-text-select-tool-button =
+ .title = í…스트 ì„ íƒ ë„구 활성화
+pdfjs-cursor-text-select-tool-button-label = í…스트 ì„ íƒ ë„구
+pdfjs-cursor-hand-tool-button =
+ .title = ì† ë„구 활성화
+pdfjs-cursor-hand-tool-button-label = ì† ë„구
+pdfjs-scroll-page-button =
+ .title = 페ì´ì§€ 스í¬ë¡¤ 사용
+pdfjs-scroll-page-button-label = 페ì´ì§€ 스í¬ë¡¤
+pdfjs-scroll-vertical-button =
+ .title = 세로 스í¬ë¡¤ 사용
+pdfjs-scroll-vertical-button-label = 세로 스í¬ë¡¤
+pdfjs-scroll-horizontal-button =
+ .title = 가로 스í¬ë¡¤ 사용
+pdfjs-scroll-horizontal-button-label = 가로 스í¬ë¡¤
+pdfjs-scroll-wrapped-button =
+ .title = 래핑(ìžë™ 줄 바꿈) 스í¬ë¡¤ 사용
+pdfjs-scroll-wrapped-button-label = 래핑 스í¬ë¡¤
+pdfjs-spread-none-button =
+ .title = í•œ 페ì´ì§€ 보기
+pdfjs-spread-none-button-label = 펼침 ì—†ìŒ
+pdfjs-spread-odd-button =
+ .title = 홀수 페ì´ì§€ë¡œ 시작하는 ë‘ íŽ˜ì´ì§€ 보기
+pdfjs-spread-odd-button-label = 홀수 펼침
+pdfjs-spread-even-button =
+ .title = ì§ìˆ˜ 페ì´ì§€ë¡œ 시작하는 ë‘ íŽ˜ì´ì§€ 보기
+pdfjs-spread-even-button-label = ì§ìˆ˜ 펼침
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = 문서 ì†ì„±â€¦
+pdfjs-document-properties-button-label = 문서 ì†ì„±â€¦
+pdfjs-document-properties-file-name = íŒŒì¼ ì´ë¦„:
+pdfjs-document-properties-file-size = íŒŒì¼ í¬ê¸°:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b }ë°”ì´íŠ¸)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b }ë°”ì´íŠ¸)
+pdfjs-document-properties-title = ì œëª©:
+pdfjs-document-properties-author = 작성ìž:
+pdfjs-document-properties-subject = ì£¼ì œ:
+pdfjs-document-properties-keywords = 키워드:
+pdfjs-document-properties-creation-date = 작성 ë‚ ì§œ:
+pdfjs-document-properties-modification-date = ìˆ˜ì • ë‚ ì§œ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = 작성 프로그램:
+pdfjs-document-properties-producer = PDF 변환 소프트웨어:
+pdfjs-document-properties-version = PDF ë²„ì „:
+pdfjs-document-properties-page-count = 페ì´ì§€ 수:
+pdfjs-document-properties-page-size = 페ì´ì§€ í¬ê¸°:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = 세로 방향
+pdfjs-document-properties-page-size-orientation-landscape = 가로 방향
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ë ˆí„°
+pdfjs-document-properties-page-size-name-legal = 리걸
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ë¹ ë¥¸ 웹 보기:
+pdfjs-document-properties-linearized-yes = 예
+pdfjs-document-properties-linearized-no = 아니요
+pdfjs-document-properties-close-button = 닫기
+
+## Print
+
+pdfjs-print-progress-message = ì¸ì‡„ 문서 준비 중…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = 취소
+pdfjs-printing-not-supported = ê²½ê³ : ì´ ë¸Œë¼ìš°ì €ëŠ” ì¸ì‡„를 ì™„ì „ížˆ 지ì›í•˜ì§€ 않습니다.
+pdfjs-printing-not-ready = ê²½ê³ : ì´ PDF를 ì¸ì‡„를 í• ìˆ˜ ìžˆì„ ì •ë„ë¡œ ì½ì–´ë“¤ì´ì§€ 못했습니다.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = 사ì´ë“œë°” 표시/숨기기
+pdfjs-toggle-sidebar-notification-button =
+ .title = 사ì´ë“œë°” 표시/숨기기 (ë¬¸ì„œì— ì•„ì›ƒë¼ì¸/첨부파ì¼/ë ˆì´ì–´ í¬í•¨ë¨)
+pdfjs-toggle-sidebar-button-label = 사ì´ë“œë°” 표시/숨기기
+pdfjs-document-outline-button =
+ .title = 문서 아웃ë¼ì¸ 보기 (ë”블 í´ë¦í•´ì„œ ëª¨ë“ í•ëª© 펼치기/ì ‘ê¸°)
+pdfjs-document-outline-button-label = 문서 아웃ë¼ì¸
+pdfjs-attachments-button =
+ .title = ì²¨ë¶€íŒŒì¼ ë³´ê¸°
+pdfjs-attachments-button-label = 첨부파ì¼
+pdfjs-layers-button =
+ .title = ë ˆì´ì–´ 보기 (ë”블 í´ë¦í•´ì„œ ëª¨ë“ ë ˆì´ì–´ë¥¼ 기본 ìƒíƒœë¡œ ìž¬ì„¤ì •)
+pdfjs-layers-button-label = ë ˆì´ì–´
+pdfjs-thumbs-button =
+ .title = 미리보기
+pdfjs-thumbs-button-label = 미리보기
+pdfjs-current-outline-item-button =
+ .title = 현재 아웃ë¼ì¸ í•ëª© 찾기
+pdfjs-current-outline-item-button-label = 현재 아웃ë¼ì¸ í•ëª©
+pdfjs-findbar-button =
+ .title = 검색
+pdfjs-findbar-button-label = 검색
+pdfjs-additional-layers = 추가 ë ˆì´ì–´
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } 페ì´ì§€
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } 페ì´ì§€ 미리보기
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = 찾기
+ .placeholder = 문서ì—ì„œ 찾기…
+pdfjs-find-previous-button =
+ .title = ì§€ì • 문ìžì—´ì— ì¼ì¹˜í•˜ëŠ” 1ê°œ ë¶€ë¶„ì„ ê²€ìƒ‰
+pdfjs-find-previous-button-label = ì´ì „
+pdfjs-find-next-button =
+ .title = ì§€ì • 문ìžì—´ì— ì¼ì¹˜í•˜ëŠ” ë‹¤ìŒ ë¶€ë¶„ì„ ê²€ìƒ‰
+pdfjs-find-next-button-label = 다ìŒ
+pdfjs-find-highlight-checkbox = ëª¨ë‘ ê°•ì¡° 표시
+pdfjs-find-match-case-checkbox-label = 대/ì†Œë¬¸ìž êµ¬ë¶„
+pdfjs-find-match-diacritics-checkbox-label = ë¶„ìŒ ë¶€í˜¸ ì¼ì¹˜
+pdfjs-find-entire-word-checkbox-label = 단어 단위로
+pdfjs-find-reached-top = 문서 처ìŒê¹Œì§€ ê²€ìƒ‰í•˜ê³ ë으로 ëŒì•„와 검색했습니다.
+pdfjs-find-reached-bottom = 문서 ë까지 ê²€ìƒ‰í•˜ê³ ì•žìœ¼ë¡œ ëŒì•„와 검색했습니다.
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = { $current } / { $total } ì¼ì¹˜
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit = { $limit }ê°œ ì´ìƒ ì¼ì¹˜
+pdfjs-find-not-found = 검색 ê²°ê³¼ ì—†ìŒ
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = 페ì´ì§€ ë„ˆë¹„ì— ë§žì¶”ê¸°
+pdfjs-page-scale-fit = 페ì´ì§€ì— 맞추기
+pdfjs-page-scale-auto = ìžë™
+pdfjs-page-scale-actual = ì‹¤ì œ í¬ê¸°
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page } 페ì´ì§€
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF를 로드하는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.
+pdfjs-invalid-file-error = 잘못ë˜ì—ˆê±°ë‚˜ ì†ìƒëœ PDF 파ì¼.
+pdfjs-missing-file-error = PDF íŒŒì¼ ì—†ìŒ.
+pdfjs-unexpected-response-error = 예기치 ì•Šì€ ì„œë²„ ì‘답입니다.
+pdfjs-rendering-error = 페ì´ì§€ë¥¼ ë Œë”ë§í•˜ëŠ” ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } 주ì„]
+
+## Password
+
+pdfjs-password-label = ì´ PDF 파ì¼ì„ ì—´ 수 있는 비밀번호를 ìž…ë ¥í•˜ì„¸ìš”.
+pdfjs-password-invalid = ìž˜ëª»ëœ ë¹„ë°€ë²ˆí˜¸ìž…ë‹ˆë‹¤. 다시 ì‹œë„하세요.
+pdfjs-password-ok-button = 확ì¸
+pdfjs-password-cancel-button = 취소
+pdfjs-web-fonts-disabled = 웹 í°íŠ¸ê°€ 비활성화ë¨: ë‚´ìž¥ëœ PDF ê¸€ê¼´ì„ ì‚¬ìš©í• ìˆ˜ 없습니다.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = í…스트
+pdfjs-editor-free-text-button-label = í…스트
+pdfjs-editor-ink-button =
+ .title = 그리기
+pdfjs-editor-ink-button-label = 그리기
+pdfjs-editor-stamp-button =
+ .title = ì´ë¯¸ì§€ 추가 ë˜ëŠ” 편집
+pdfjs-editor-stamp-button-label = ì´ë¯¸ì§€ 추가 ë˜ëŠ” 편집
+pdfjs-editor-remove-button =
+ .title = ì œê±°
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = 그리기 ì œê±°
+pdfjs-editor-remove-freetext-button =
+ .title = í…스트 ì œê±°
+pdfjs-editor-remove-stamp-button =
+ .title = ì´ë¯¸ì§€ ì œê±°
+pdfjs-editor-remove-highlight-button =
+ .title = ê°•ì¡° ì œê±°
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = 색ìƒ
+pdfjs-editor-free-text-size-input = í¬ê¸°
+pdfjs-editor-ink-color-input = 색ìƒ
+pdfjs-editor-ink-thickness-input = ë‘께
+pdfjs-editor-ink-opacity-input = 불투명ë„
+pdfjs-editor-stamp-add-image-button =
+ .title = ì´ë¯¸ì§€ 추가
+pdfjs-editor-stamp-add-image-button-label = ì´ë¯¸ì§€ 추가
+pdfjs-free-text =
+ .aria-label = í…스트 편집기
+pdfjs-free-text-default-content = ìž…ë ¥í•˜ì„¸ìš”â€¦
+pdfjs-ink =
+ .aria-label = 그리기 편집기
+pdfjs-ink-canvas =
+ .aria-label = ì‚¬ìš©ìž ìƒì„± ì´ë¯¸ì§€
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = 대체 í…스트
+pdfjs-editor-alt-text-edit-button-label = 대체 í…스트 편집
+pdfjs-editor-alt-text-dialog-label = ì˜µì…˜ì„ ì„ íƒí•˜ì„¸ìš”
+pdfjs-editor-alt-text-dialog-description = 대체 í…스트는 ì‚¬ëžŒë“¤ì´ ì´ë¯¸ì§€ë¥¼ ë³¼ 수 없거나 ì´ë¯¸ì§€ê°€ 로드ë˜ì§€ ì•Šì„ ë•Œ ë„ì›€ì´ ë©ë‹ˆë‹¤.
+pdfjs-editor-alt-text-add-description-label = 설명 추가
+pdfjs-editor-alt-text-add-description-description = ì£¼ì œ, ì„¤ì •, ë™ìž‘ì„ ì„¤ëª…í•˜ëŠ” 1~2ê°œì˜ ë¬¸ìž¥ì„ ëª©í‘œë¡œ 하세요.
+pdfjs-editor-alt-text-mark-decorative-label = 장ì‹ìš©ìœ¼ë¡œ 표시
+pdfjs-editor-alt-text-mark-decorative-description = í…Œë‘리나 워터마í¬ì™€ ê°™ì€ ìž¥ì‹ì ì¸ ì´ë¯¸ì§€ì— 사용ë©ë‹ˆë‹¤.
+pdfjs-editor-alt-text-cancel-button = 취소
+pdfjs-editor-alt-text-save-button = ì €ìž¥
+pdfjs-editor-alt-text-decorative-tooltip = 장ì‹ìš©ìœ¼ë¡œ 표시ë¨
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = 예를 들어, “한 ì²ë…„ì´ ì‹íƒì— 앉아 ì‹ì‚¬ë¥¼ í•˜ê³ ìžˆìŠµë‹ˆë‹¤.â€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = 왼쪽 위 — í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-top-middle = ê°€ìš´ë° ìœ„ - í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-top-right = 오른쪽 위 — í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-middle-right = 오른쪽 ê°€ìš´ë° â€” í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-bottom-right = 오른쪽 아래 - í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-bottom-middle = ê°€ìš´ë° ì•„ëž˜ — í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-bottom-left = 왼쪽 아래 - í¬ê¸° ì¡°ì •
+pdfjs-editor-resizer-label-middle-left = 왼쪽 ê°€ìš´ë° â€” í¬ê¸° ì¡°ì •
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = 강조 색
+pdfjs-editor-colorpicker-button =
+ .title = ìƒ‰ìƒ ë³€ê²½
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = ìƒ‰ìƒ ì„ íƒ
+pdfjs-editor-colorpicker-yellow =
+ .title = 노란색
+pdfjs-editor-colorpicker-green =
+ .title = 녹색
+pdfjs-editor-colorpicker-blue =
+ .title = 파란색
+pdfjs-editor-colorpicker-pink =
+ .title = 분í™ìƒ‰
+pdfjs-editor-colorpicker-red =
+ .title = 빨간색
diff --git a/www/lib/pdfjs/modern/web/locale/lij/viewer.ftl b/www/lib/pdfjs/modern/web/locale/lij/viewer.ftl
new file mode 100644
index 000000000..b2941f9f6
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/lij/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina primma
+pdfjs-previous-button-label = Precedente
+pdfjs-next-button =
+ .title = Pagina dòppo
+pdfjs-next-button-label = Pròscima
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Diminoisci zoom
+pdfjs-zoom-out-button-label = Diminoisci zoom
+pdfjs-zoom-in-button =
+ .title = Aomenta zoom
+pdfjs-zoom-in-button-label = Aomenta zoom
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Vanni into mòddo de prezentaçion
+pdfjs-presentation-mode-button-label = Mòddo de prezentaçion
+pdfjs-open-file-button =
+ .title = Arvi file
+pdfjs-open-file-button-label = Arvi
+pdfjs-print-button =
+ .title = Stanpa
+pdfjs-print-button-label = Stanpa
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Atressi
+pdfjs-tools-button-label = Atressi
+pdfjs-first-page-button =
+ .title = Vanni a-a primma pagina
+pdfjs-first-page-button-label = Vanni a-a primma pagina
+pdfjs-last-page-button =
+ .title = Vanni a l'urtima pagina
+pdfjs-last-page-button-label = Vanni a l'urtima pagina
+pdfjs-page-rotate-cw-button =
+ .title = Gia into verso oraio
+pdfjs-page-rotate-cw-button-label = Gia into verso oraio
+pdfjs-page-rotate-ccw-button =
+ .title = Gia into verso antioraio
+pdfjs-page-rotate-ccw-button-label = Gia into verso antioraio
+pdfjs-cursor-text-select-tool-button =
+ .title = Abilita strumento de seleçion do testo
+pdfjs-cursor-text-select-tool-button-label = Strumento de seleçion do testo
+pdfjs-cursor-hand-tool-button =
+ .title = Abilita strumento man
+pdfjs-cursor-hand-tool-button-label = Strumento man
+pdfjs-scroll-vertical-button =
+ .title = Deuvia rebelamento verticale
+pdfjs-scroll-vertical-button-label = Rebelamento verticale
+pdfjs-scroll-horizontal-button =
+ .title = Deuvia rebelamento orizontâ
+pdfjs-scroll-horizontal-button-label = Rebelamento orizontâ
+pdfjs-scroll-wrapped-button =
+ .title = Deuvia rebelamento incapsolou
+pdfjs-scroll-wrapped-button-label = Rebelamento incapsolou
+pdfjs-spread-none-button =
+ .title = No unite a-a difuxon de pagina
+pdfjs-spread-none-button-label = No difuxon
+pdfjs-spread-odd-button =
+ .title = Uniscite a-a difuxon de pagina co-o numero dèspa
+pdfjs-spread-odd-button-label = Difuxon dèspa
+pdfjs-spread-even-button =
+ .title = Uniscite a-a difuxon de pagina co-o numero pari
+pdfjs-spread-even-button-label = Difuxon pari
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propietæ do documento…
+pdfjs-document-properties-button-label = Propietæ do documento…
+pdfjs-document-properties-file-name = Nomme schedaio:
+pdfjs-document-properties-file-size = Dimenscion schedaio:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Titolo:
+pdfjs-document-properties-author = Aoto:
+pdfjs-document-properties-subject = Ogetto:
+pdfjs-document-properties-keywords = Paròlle ciave:
+pdfjs-document-properties-creation-date = Dæta creaçion:
+pdfjs-document-properties-modification-date = Dæta cangiamento:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Aotô originale:
+pdfjs-document-properties-producer = Produtô PDF:
+pdfjs-document-properties-version = Verscion PDF:
+pdfjs-document-properties-page-count = Contezzo pagine:
+pdfjs-document-properties-page-size = Dimenscion da pagina:
+pdfjs-document-properties-page-size-unit-inches = dii gròsci
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = drito
+pdfjs-document-properties-page-size-orientation-landscape = desteizo
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letia
+pdfjs-document-properties-page-size-name-legal = Lezze
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista veloce do Web:
+pdfjs-document-properties-linearized-yes = Sci
+pdfjs-document-properties-linearized-no = No
+pdfjs-document-properties-close-button = Særa
+
+## Print
+
+pdfjs-print-progress-message = Praparo o documento pe-a stanpa…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Anulla
+pdfjs-printing-not-supported = Atençion: a stanpa a no l'é conpletamente soportâ da sto navegatô.
+pdfjs-printing-not-ready = Atençion: o PDF o no l'é ancon caregou conpletamente pe-a stanpa.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Ativa/dizativa bara de scianco
+pdfjs-toggle-sidebar-button-label = Ativa/dizativa bara de scianco
+pdfjs-document-outline-button =
+ .title = Fanni vedde o contorno do documento (scicca doggio pe espande/ridue tutti i elementi)
+pdfjs-document-outline-button-label = Contorno do documento
+pdfjs-attachments-button =
+ .title = Fanni vedde alegæ
+pdfjs-attachments-button-label = Alegæ
+pdfjs-thumbs-button =
+ .title = Mostra miniatue
+pdfjs-thumbs-button-label = Miniatue
+pdfjs-findbar-button =
+ .title = Treuva into documento
+pdfjs-findbar-button-label = Treuva
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatua da pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Treuva
+ .placeholder = Treuva into documento…
+pdfjs-find-previous-button =
+ .title = Treuva a ripetiçion precedente do testo da çercâ
+pdfjs-find-previous-button-label = Precedente
+pdfjs-find-next-button =
+ .title = Treuva a ripetiçion dòppo do testo da çercâ
+pdfjs-find-next-button-label = Segoente
+pdfjs-find-highlight-checkbox = Evidençia
+pdfjs-find-match-case-checkbox-label = Maioscole/minoscole
+pdfjs-find-entire-word-checkbox-label = Poula intrega
+pdfjs-find-reached-top = Razonto a fin da pagina, continoa da l'iniçio
+pdfjs-find-reached-bottom = Razonto l'iniçio da pagina, continoa da-a fin
+pdfjs-find-not-found = Testo no trovou
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Larghessa pagina
+pdfjs-page-scale-fit = Adatta a una pagina
+pdfjs-page-scale-auto = Zoom aotomatico
+pdfjs-page-scale-actual = Dimenscioin efetive
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = S'é verificou 'n'erô itno caregamento do PDF.
+pdfjs-invalid-file-error = O schedaio PDF o l'é no valido ò aroinou.
+pdfjs-missing-file-error = O schedaio PDF o no gh'é.
+pdfjs-unexpected-response-error = Risposta inprevista do-u server
+pdfjs-rendering-error = Gh'é stæto 'n'erô itno rendering da pagina.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotaçion: { $type }]
+
+## Password
+
+pdfjs-password-label = Dimme a paròlla segreta pe arvî sto schedaio PDF.
+pdfjs-password-invalid = Paròlla segreta sbalia. Preuva torna.
+pdfjs-password-ok-button = Va ben
+pdfjs-password-cancel-button = Anulla
+pdfjs-web-fonts-disabled = I font do web en dizativæ: inposcibile adeuviâ i carateri do PDF.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/lo/viewer.ftl b/www/lib/pdfjs/modern/web/locale/lo/viewer.ftl
new file mode 100644
index 000000000..fdad16adf
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/lo/viewer.ftl
@@ -0,0 +1,299 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ຫນ້າàºà»ˆàºàº™àº«àº™à»‰àº²
+pdfjs-previous-button-label = àºà»ˆàºàº™àº«àº™à»‰àº²
+pdfjs-next-button =
+ .title = ຫນ້າຖັດໄປ
+pdfjs-next-button-label = ຖັດໄປ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ຫນ້າ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = ຈາຠ{ $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } ຈາຠ{ $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ຂະຫàºàº²àºàºàºàº
+pdfjs-zoom-out-button-label = ຂະຫàºàº²àºàºàºàº
+pdfjs-zoom-in-button =
+ .title = ຂະຫàºàº²àºà»€àº‚ົ້າ
+pdfjs-zoom-in-button-label = ຂະຫàºàº²àºà»€àº‚ົ້າ
+pdfjs-zoom-select =
+ .title = ຂະຫàºàº²àº
+pdfjs-presentation-mode-button =
+ .title = ສັບປ່ຽນເປັນໂຫມດàºàº²àº™àº™àº³àºªàº°à»€àº«àº™àºµ
+pdfjs-presentation-mode-button-label = ໂຫມດàºàº²àº™àº™àº³àºªàº°à»€àº«àº™àºµ
+pdfjs-open-file-button =
+ .title = ເປີດໄຟລ໌
+pdfjs-open-file-button-label = ເປີດ
+pdfjs-print-button =
+ .title = ພິມ
+pdfjs-print-button-label = ພິມ
+pdfjs-save-button =
+ .title = ບັນທຶàº
+pdfjs-save-button-label = ບັນທຶàº
+pdfjs-bookmark-button =
+ .title = ໜ້າປັດຈຸບັນ (ເບິ່ງ URL ຈາàºà»œà»‰àº²àº›àº±àº”ຈຸບັນ)
+pdfjs-bookmark-button-label = ຫນ້າ​ປັດ​ຈຸ​ບັນ
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = ເປີດໃນ App
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = ເປີດໃນ App
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ເຄື່àºàº‡àº¡àº·
+pdfjs-tools-button-label = ເຄື່àºàº‡àº¡àº·
+pdfjs-first-page-button =
+ .title = ໄປທີ່ຫນ້າທຳàºàº´àº”
+pdfjs-first-page-button-label = ໄປທີ່ຫນ້າທຳàºàº´àº”
+pdfjs-last-page-button =
+ .title = ໄປທີ່ຫນ້າສຸດທ້າàº
+pdfjs-last-page-button-label = ໄປທີ່ຫນ້າສຸດທ້າàº
+pdfjs-page-rotate-cw-button =
+ .title = ຫມູນຕາມເຂັມໂມງ
+pdfjs-page-rotate-cw-button-label = ຫມູນຕາມເຂັມໂມງ
+pdfjs-page-rotate-ccw-button =
+ .title = ຫມູນທວນເຂັມໂມງ
+pdfjs-page-rotate-ccw-button-label = ຫມູນທວນເຂັມໂມງ
+pdfjs-cursor-text-select-tool-button =
+ .title = ເປີດໃຊ້ເຄື່àºàº‡àº¡àº·àºàº²àº™à»€àº¥àº·àºàºàº‚à»à»‰àº„ວາມ
+pdfjs-cursor-text-select-tool-button-label = ເຄື່àºàº‡àº¡àº·à»€àº¥àº·àºàºàº‚à»à»‰àº„ວາມ
+pdfjs-cursor-hand-tool-button =
+ .title = ເປີດໃຊ້ເຄື່àºàº‡àº¡àº·àº¡àº·
+pdfjs-cursor-hand-tool-button-label = ເຄື່àºàº‡àº¡àº·àº¡àº·
+pdfjs-scroll-page-button =
+ .title = ໃຊ້àºàº²àº™à»€àº¥àº·à»ˆàºàº™à»œà»‰àº²
+pdfjs-scroll-page-button-label = ເລື່àºàº™à»œà»‰àº²
+pdfjs-scroll-vertical-button =
+ .title = ໃຊ້àºàº²àº™à»€àº¥àº·à»ˆàºàº™à»àº™àº§àº•àº±à»‰àº‡
+pdfjs-scroll-vertical-button-label = ເລື່àºàº™à»àº™àº§àº•àº±à»‰àº‡
+pdfjs-scroll-horizontal-button =
+ .title = ໃຊ້àºàº²àº™à»€àº¥àº·à»ˆàºàº™à»àº™àº§àº™àºàº™
+pdfjs-scroll-horizontal-button-label = ເລື່àºàº™à»àº™àº§àº™àºàº™
+pdfjs-scroll-wrapped-button =
+ .title = ໃຊ້ Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = ບà»à»ˆàº•à»‰àºàº‡àº®à»ˆàº§àº¡àºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àºàº«àº™à»‰àº²
+pdfjs-spread-none-button-label = ບà»à»ˆàº¡àºµàºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àº
+pdfjs-spread-odd-button =
+ .title = ເຂົ້າຮ່ວມàºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àºàº«àº™à»‰àº²à»€àº¥àºµà»ˆàº¡àº•àº»à»‰àº™àº”້ວàºàº«àº™à»‰àº²à»€àº¥àºàº„ີàº
+pdfjs-spread-odd-button-label = àºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àºàº„ີàº
+pdfjs-spread-even-button =
+ .title = ເຂົ້າຮ່ວມàºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àºàº‚àºàº‡àº«àº™à»‰àº²à»€àº¥àºµà»ˆàº¡àº•àº»à»‰àº™àº”້ວàºàº«àº™à»‰àº²à»€àº¥àºàº„ູ່
+pdfjs-spread-even-button-label = àºàº²àº™à»àºœà»ˆàºàº°àºˆàº²àºàº„ູ່
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ຄຸນສົມບັດເàºàºàº°àºªàº²àº™...
+pdfjs-document-properties-button-label = ຄຸນສົມບັດເàºàºàº°àºªàº²àº™...
+pdfjs-document-properties-file-name = ຊື່ໄຟລ໌:
+pdfjs-document-properties-file-size = ຂະຫນາດໄຟລ໌:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ໄບຕ໌)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ໄບຕ໌)
+pdfjs-document-properties-title = ຫົວຂà»à»‰:
+pdfjs-document-properties-author = ຜູ້ຂຽນ:
+pdfjs-document-properties-subject = ຫົວຂà»à»‰:
+pdfjs-document-properties-keywords = ຄà»àº²àº—ີ່ຕ້àºàº‡àºàº²àº™àº„ົ້ນຫາ:
+pdfjs-document-properties-creation-date = ວັນທີສ້າງ:
+pdfjs-document-properties-modification-date = ວັນທີà»àºà»‰à»„ຂ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ຜູ້ສ້າງ:
+pdfjs-document-properties-producer = ຜູ້ຜະລິດ PDF:
+pdfjs-document-properties-version = ເວີຊັ່ນ PDF:
+pdfjs-document-properties-page-count = ຈຳນວນໜ້າ:
+pdfjs-document-properties-page-size = ຂະໜາດໜ້າ:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = ລວງຕັ້ງ
+pdfjs-document-properties-page-size-orientation-landscape = ລວງນàºàº™
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ຈົດà»àº²àº
+pdfjs-document-properties-page-size-name-legal = ຂà»à»‰àºàº»àº”ຫມາàº
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ມຸມມàºàº‡à»€àº§àº±àºšàº—ີ່ໄວ:
+pdfjs-document-properties-linearized-yes = à»àº¡à»ˆàº™
+pdfjs-document-properties-linearized-no = ບà»à»ˆ
+pdfjs-document-properties-close-button = ປິດ
+
+## Print
+
+pdfjs-print-progress-message = àºàº³àº¥àº±àº‡àºàº°àºàº½àº¡à»€àºàºàº°àºªàº²àº™àºªàº³àº¥àº±àºšàºàº²àº™àºžàº´àº¡...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = àºàº»àºà»€àº¥àºµàº
+pdfjs-printing-not-supported = ຄຳເຕືàºàº™: ບຼາວເຊີນີ້ບà»à»ˆàº®àºàº‡àº®àº±àºšàºàº²àº™àºžàº´àº¡àº¢à»ˆàº²àº‡à»€àº•àº±àº¡àº—ີ່.
+pdfjs-printing-not-ready = ຄà»àº²â€‹à»€àº•àº·àºàº™â€‹: PDF ບà»à»ˆâ€‹à»„ດ້​ຖືàºâ€‹à»‚ຫຼດ​ຢ່າງ​ເຕັມ​ທີ່​ສà»àº²â€‹àº¥àº±àºšâ€‹àºàº²àº™â€‹àºžàº´àº¡â€‹.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ເປີດ/ປິດà»àº–ບຂ້າງ
+pdfjs-toggle-sidebar-notification-button =
+ .title = ສະຫຼັບà»àº–ບດ້ານຂ້າງ (ເàºàºàº°àºªàº²àº™àº›àº°àºàºàºšàº¡àºµà»‚ຄງຮ່າງ/ໄຟລ໌à»àº™àºš/ຊັ້ນຂà»à»‰àº¡àº¹àº™)
+pdfjs-toggle-sidebar-button-label = ເປີດ/ປິດà»àº–ບຂ້າງ
+pdfjs-document-outline-button =
+ .title = ສະ​à»àº”ງ​ໂຄງ​ຮ່າງ​ເàºâ€‹àºàº°â€‹àºªàº²àº™ (àºàº»àº”​ສàºàº‡â€‹àº„ັ້ງ​ເພື່àºâ€‹àº‚ະ​ຫàºàº²àº / ຫàºà»à»‰â€‹àº¥àº²àºâ€‹àºàº²àº™â€‹àº—ັງ​ຫມົດ​)
+pdfjs-document-outline-button-label = ເຄົ້າຮ່າງເàºàºàº°àºªàº²àº™
+pdfjs-attachments-button =
+ .title = ສະà»àº”ງໄຟລ໌à»àº™àºš
+pdfjs-attachments-button-label = ໄຟລ໌à»àº™àºš
+pdfjs-layers-button =
+ .title = ສະà»àº”ງຊັ້ນຂà»à»‰àº¡àº¹àº™ (ຄລິàºàºªàºàº‡à»€àº—ື່àºà»€àºžàº·à»ˆàºàº£àºµà»€àºŠàº±àº”ຊັ້ນຂà»à»‰àº¡àº¹àº™àº—ັງà»àº»àº”ໃຫ້ເປັນສະຖານະເລີ່ມຕົ້ນ)
+pdfjs-layers-button-label = ຊັ້ນ
+pdfjs-thumbs-button =
+ .title = ສະà»àº”ງຮູບຫàºà»à»‰
+pdfjs-thumbs-button-label = ຮູບຕົວຢ່າງ
+pdfjs-current-outline-item-button =
+ .title = ຊàºàºàº«àº²àº¥àº²àºàºàº²àº™à»‚ຄງຮ່າງປະຈຸບັນ
+pdfjs-current-outline-item-button-label = ລາàºàºàº²àº™à»‚ຄງຮ່າງປະຈຸບັນ
+pdfjs-findbar-button =
+ .title = ຊàºàºàº«àº²à»ƒàº™à»€àºàºàº°àºªàº²àº™
+pdfjs-findbar-button-label = ຄົ້ນຫາ
+pdfjs-additional-layers = ຊັ້ນຂà»à»‰àº¡àº¹àº™à»€àºžàºµà»ˆàº¡à»€àº•àºµàº¡
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = ໜ້າ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ຮູບຕົວຢ່າງຂàºàº‡à»œà»‰àº² { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ຄົ້ນຫາ
+ .placeholder = ຊàºàºàº«àº²à»ƒàº™à»€àºàºàº°àºªàº²àº™...
+pdfjs-find-previous-button =
+ .title = ຊàºàºàº«àº²àºàº²àº™àº›àº°àºàº»àº”ຕົວທີ່ຜ່ານມາຂàºàº‡àº›àº°à»‚ຫàºàº
+pdfjs-find-previous-button-label = àºà»ˆàºàº™àº«àº™à»‰àº²àº™àºµà»‰
+pdfjs-find-next-button =
+ .title = ຊàºàºàº«àº²àº•àº³à»àº«àº™à»ˆàº‡àº–ັດໄປຂàºàº‡àº§àº°àº¥àºµ
+pdfjs-find-next-button-label = ຕà»à»ˆà»„ປ
+pdfjs-find-highlight-checkbox = ໄຮໄລທ໌ທັງຫມົດ
+pdfjs-find-match-case-checkbox-label = àºà»àº¥àº°àº™àºµàº—ີ່àºàº»àº‡àºàº±àº™
+pdfjs-find-match-diacritics-checkbox-label = ເຄື່àºàº‡à»àº²àºàºàº³àºàº±àºšàºàº²àº™àºàºàºàºªàº½àº‡àºàº»àº‡àºàº±àº™
+pdfjs-find-entire-word-checkbox-label = àºàº»àº‡àºàº±àº™àº—ຸàºàº„ຳ
+pdfjs-find-reached-top = ມາຮàºàº”ເທິງຂàºàº‡à»€àºàºàº°àºªàº²àº™, ສືບຕà»à»ˆàºˆàº²àºàº¥àº¸à»ˆàº¡
+pdfjs-find-reached-bottom = ຮàºàº”ຕàºàº™àº—້າàºàº‚àºàº‡à»€àºàºàº°àºªàº²àº™, ສືບຕà»à»ˆàºˆàº²àºà»€àº—ິງ
+pdfjs-find-not-found = ບà»à»ˆàºžàº»àºšàº§àº°àº¥àºµàº—ີ່ຕ້àºàº‡àºàº²àº™
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ຄວາມàºàº§à»‰àº²àº‡à»œà»‰àº²
+pdfjs-page-scale-fit = ໜ້າພà»àº”ີ
+pdfjs-page-scale-auto = ຊູມàºàº±àº”ຕະໂນມັດ
+pdfjs-page-scale-actual = ຂະໜາດຕົວຈິງ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = ໜ້າ { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = ມີຂà»à»‰àºœàº´àº”ພາດເàºàºµàº”ຂື້ນຂະນະທີ່àºàº³àº¥àº±àº‡à»‚ຫລດ PDF.
+pdfjs-invalid-file-error = ໄຟລ໌ PDF ບà»à»ˆàº–ືàºàº•à»‰àºàº‡àº«àº¥àº·à»€àºªàºàº«àº²àº.
+pdfjs-missing-file-error = ບà»à»ˆàº¡àºµà»„ຟລ໌ PDF.
+pdfjs-unexpected-response-error = àºàº²àº™àº•àºàºšàºªàº°à»œàºàº‡àº‚àºàº‡à»€àºŠàºµàºšà»€àº§àºµàº—ີ່ບà»à»ˆàº„າດຄິດ.
+pdfjs-rendering-error = ມີຂà»à»‰àºœàº´àº”ພາດເàºàºµàº”ຂື້ນຂະນະທີ່àºàº³àº¥àº±àº‡à»€àº£àº±àº™à»€àº”ີຫນ້າ.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ຄຳບັນàºàº²àº]
+
+## Password
+
+pdfjs-password-label = ໃສ່ລະຫັດຜ່ານເພື່àºà»€àº›àºµàº”ໄຟລ໌ PDF ນີ້.
+pdfjs-password-invalid = ລະຫັດຜ່ານບà»à»ˆàº–ືàºàº•à»‰àºàº‡. àºàº°àº¥àº¸àº™àº²àº¥àºàº‡àºàºµàºàº„ັ້ງ.
+pdfjs-password-ok-button = ຕົàºàº¥àº»àº‡
+pdfjs-password-cancel-button = àºàº»àºà»€àº¥àºµàº
+pdfjs-web-fonts-disabled = ຟàºàº™à»€àº§àº±àºšàº–ືàºàº›àº´àº”ໃຊ້ງານ: ບà»à»ˆàºªàº²àº¡àº²àº”ໃຊ້ຟàºàº™ PDF ທີ່àºàº±àº‡à»„ວ້ໄດ້.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ຂà»à»‰àº„ວາມ
+pdfjs-editor-free-text-button-label = ຂà»à»‰àº„ວາມ
+pdfjs-editor-ink-button =
+ .title = à»àº•à»‰àº¡
+pdfjs-editor-ink-button-label = à»àº•à»‰àº¡
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ສີ
+pdfjs-editor-free-text-size-input = ຂະຫນາດ
+pdfjs-editor-ink-color-input = ສີ
+pdfjs-editor-ink-thickness-input = ຄວາມຫນາ
+pdfjs-editor-ink-opacity-input = ຄວາມໂປ່ງໃສ
+pdfjs-free-text =
+ .aria-label = ຕົວà»àºà»‰à»„ຂຂà»à»‰àº„ວາມ
+pdfjs-free-text-default-content = ເລີ່ມພິມ...
+pdfjs-ink =
+ .aria-label = ຕົວà»àºà»‰à»„ຂຮູບà»àº•à»‰àº¡
+pdfjs-ink-canvas =
+ .aria-label = ຮູບພາບທີ່ຜູ້ໃຊ້ສ້າງ
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/locale.json b/www/lib/pdfjs/modern/web/locale/locale.json
new file mode 100644
index 000000000..20122111f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/locale.json
@@ -0,0 +1 @@
+{"ach":"ach/viewer.ftl","af":"af/viewer.ftl","an":"an/viewer.ftl","ar":"ar/viewer.ftl","ast":"ast/viewer.ftl","az":"az/viewer.ftl","be":"be/viewer.ftl","bg":"bg/viewer.ftl","bn":"bn/viewer.ftl","bo":"bo/viewer.ftl","br":"br/viewer.ftl","brx":"brx/viewer.ftl","bs":"bs/viewer.ftl","ca":"ca/viewer.ftl","cak":"cak/viewer.ftl","ckb":"ckb/viewer.ftl","cs":"cs/viewer.ftl","cy":"cy/viewer.ftl","da":"da/viewer.ftl","de":"de/viewer.ftl","dsb":"dsb/viewer.ftl","el":"el/viewer.ftl","en-ca":"en-CA/viewer.ftl","en-gb":"en-GB/viewer.ftl","en-us":"en-US/viewer.ftl","eo":"eo/viewer.ftl","es-ar":"es-AR/viewer.ftl","es-cl":"es-CL/viewer.ftl","es-es":"es-ES/viewer.ftl","es-mx":"es-MX/viewer.ftl","et":"et/viewer.ftl","eu":"eu/viewer.ftl","fa":"fa/viewer.ftl","ff":"ff/viewer.ftl","fi":"fi/viewer.ftl","fr":"fr/viewer.ftl","fur":"fur/viewer.ftl","fy-nl":"fy-NL/viewer.ftl","ga-ie":"ga-IE/viewer.ftl","gd":"gd/viewer.ftl","gl":"gl/viewer.ftl","gn":"gn/viewer.ftl","gu-in":"gu-IN/viewer.ftl","he":"he/viewer.ftl","hi-in":"hi-IN/viewer.ftl","hr":"hr/viewer.ftl","hsb":"hsb/viewer.ftl","hu":"hu/viewer.ftl","hy-am":"hy-AM/viewer.ftl","hye":"hye/viewer.ftl","ia":"ia/viewer.ftl","id":"id/viewer.ftl","is":"is/viewer.ftl","it":"it/viewer.ftl","ja":"ja/viewer.ftl","ka":"ka/viewer.ftl","kab":"kab/viewer.ftl","kk":"kk/viewer.ftl","km":"km/viewer.ftl","kn":"kn/viewer.ftl","ko":"ko/viewer.ftl","lij":"lij/viewer.ftl","lo":"lo/viewer.ftl","lt":"lt/viewer.ftl","ltg":"ltg/viewer.ftl","lv":"lv/viewer.ftl","meh":"meh/viewer.ftl","mk":"mk/viewer.ftl","mr":"mr/viewer.ftl","ms":"ms/viewer.ftl","my":"my/viewer.ftl","nb-no":"nb-NO/viewer.ftl","ne-np":"ne-NP/viewer.ftl","nl":"nl/viewer.ftl","nn-no":"nn-NO/viewer.ftl","oc":"oc/viewer.ftl","pa-in":"pa-IN/viewer.ftl","pl":"pl/viewer.ftl","pt-br":"pt-BR/viewer.ftl","pt-pt":"pt-PT/viewer.ftl","rm":"rm/viewer.ftl","ro":"ro/viewer.ftl","ru":"ru/viewer.ftl","sat":"sat/viewer.ftl","sc":"sc/viewer.ftl","scn":"scn/viewer.ftl","sco":"sco/viewer.ftl","si":"si/viewer.ftl","sk":"sk/viewer.ftl","skr":"skr/viewer.ftl","sl":"sl/viewer.ftl","son":"son/viewer.ftl","sq":"sq/viewer.ftl","sr":"sr/viewer.ftl","sv-se":"sv-SE/viewer.ftl","szl":"szl/viewer.ftl","ta":"ta/viewer.ftl","te":"te/viewer.ftl","tg":"tg/viewer.ftl","th":"th/viewer.ftl","tl":"tl/viewer.ftl","tr":"tr/viewer.ftl","trs":"trs/viewer.ftl","uk":"uk/viewer.ftl","ur":"ur/viewer.ftl","uz":"uz/viewer.ftl","vi":"vi/viewer.ftl","wo":"wo/viewer.ftl","xh":"xh/viewer.ftl","zh-cn":"zh-CN/viewer.ftl","zh-tw":"zh-TW/viewer.ftl"}
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/locale/lt/viewer.ftl b/www/lib/pdfjs/modern/web/locale/lt/viewer.ftl
new file mode 100644
index 000000000..a8ee7a08f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/lt/viewer.ftl
@@ -0,0 +1,268 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Ankstesnis puslapis
+pdfjs-previous-button-label = Ankstesnis
+pdfjs-next-button =
+ .title = Kitas puslapis
+pdfjs-next-button-label = Kitas
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Puslapis
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = iš { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } iš { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Sumažinti
+pdfjs-zoom-out-button-label = Sumažinti
+pdfjs-zoom-in-button =
+ .title = Padidinti
+pdfjs-zoom-in-button-label = Padidinti
+pdfjs-zoom-select =
+ .title = Mastelis
+pdfjs-presentation-mode-button =
+ .title = Pereiti į pateikties veikseną
+pdfjs-presentation-mode-button-label = Pateikties veiksena
+pdfjs-open-file-button =
+ .title = Atverti failÄ…
+pdfjs-open-file-button-label = Atverti
+pdfjs-print-button =
+ .title = Spausdinti
+pdfjs-print-button-label = Spausdinti
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = PriemonÄ—s
+pdfjs-tools-button-label = PriemonÄ—s
+pdfjs-first-page-button =
+ .title = Eiti į pirmą puslapį
+pdfjs-first-page-button-label = Eiti į pirmą puslapį
+pdfjs-last-page-button =
+ .title = Eiti į paskutinį puslapį
+pdfjs-last-page-button-label = Eiti į paskutinį puslapį
+pdfjs-page-rotate-cw-button =
+ .title = Pasukti pagal laikrodžio rodyklę
+pdfjs-page-rotate-cw-button-label = Pasukti pagal laikrodžio rodyklę
+pdfjs-page-rotate-ccw-button =
+ .title = Pasukti prieš laikrodžio rodyklę
+pdfjs-page-rotate-ccw-button-label = Pasukti prieš laikrodžio rodyklę
+pdfjs-cursor-text-select-tool-button =
+ .title = Įjungti teksto žymėjimo įrankį
+pdfjs-cursor-text-select-tool-button-label = Teksto žymėjimo įrankis
+pdfjs-cursor-hand-tool-button =
+ .title = Įjungti vilkimo įrankį
+pdfjs-cursor-hand-tool-button-label = Vilkimo įrankis
+pdfjs-scroll-page-button =
+ .title = Naudoti puslapio slinkimÄ…
+pdfjs-scroll-page-button-label = Puslapio slinkimas
+pdfjs-scroll-vertical-button =
+ .title = Naudoti vertikalų slinkimą
+pdfjs-scroll-vertical-button-label = Vertikalus slinkimas
+pdfjs-scroll-horizontal-button =
+ .title = Naudoti horizontalų slinkimą
+pdfjs-scroll-horizontal-button-label = Horizontalus slinkimas
+pdfjs-scroll-wrapped-button =
+ .title = Naudoti išklotą slinkimą
+pdfjs-scroll-wrapped-button-label = IÅ¡klotas slinkimas
+pdfjs-spread-none-button =
+ .title = Nejungti puslapių į dvilapius
+pdfjs-spread-none-button-label = Be dvilapių
+pdfjs-spread-odd-button =
+ .title = Sujungti į dvilapius pradedant nelyginiais puslapiais
+pdfjs-spread-odd-button-label = Nelyginiai dvilapiai
+pdfjs-spread-even-button =
+ .title = Sujungti į dvilapius pradedant lyginiais puslapiais
+pdfjs-spread-even-button-label = Lyginiai dvilapiai
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumento savybės…
+pdfjs-document-properties-button-label = Dokumento savybės…
+pdfjs-document-properties-file-name = Failo vardas:
+pdfjs-document-properties-file-size = Failo dydis:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } B)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } B)
+pdfjs-document-properties-title = Antraštė:
+pdfjs-document-properties-author = Autorius:
+pdfjs-document-properties-subject = Tema:
+pdfjs-document-properties-keywords = Reikšminiai žodžiai:
+pdfjs-document-properties-creation-date = Sukūrimo data:
+pdfjs-document-properties-modification-date = Modifikavimo data:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = KÅ«rÄ—jas:
+pdfjs-document-properties-producer = PDF generatorius:
+pdfjs-document-properties-version = PDF versija:
+pdfjs-document-properties-page-count = Puslapių skaiÄius:
+pdfjs-document-properties-page-size = Puslapio dydis:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = staÄias
+pdfjs-document-properties-page-size-orientation-landscape = gulsÄias
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Laiškas
+pdfjs-document-properties-page-size-name-legal = Dokumentas
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Spartus žiniatinklio rodinys:
+pdfjs-document-properties-linearized-yes = Taip
+pdfjs-document-properties-linearized-no = Ne
+pdfjs-document-properties-close-button = Užverti
+
+## Print
+
+pdfjs-print-progress-message = Dokumentas ruošiamas spausdinimui…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Atsisakyti
+pdfjs-printing-not-supported = Dėmesio! Spausdinimas šioje naršyklėje nėra pilnai realizuotas.
+pdfjs-printing-not-ready = Dėmesio! PDF failas dar nėra pilnai įkeltas spausdinimui.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Rodyti / slėpti šoninį polangį
+pdfjs-toggle-sidebar-notification-button =
+ .title = Parankinė (dokumentas turi struktūrą / priedų / sluoksnių)
+pdfjs-toggle-sidebar-button-label = Å oninis polangis
+pdfjs-document-outline-button =
+ .title = Rodyti dokumento struktūrą (spustelėkite dukart norėdami išplėsti/suskleisti visus elementus)
+pdfjs-document-outline-button-label = Dokumento struktūra
+pdfjs-attachments-button =
+ .title = Rodyti priedus
+pdfjs-attachments-button-label = Priedai
+pdfjs-layers-button =
+ .title = Rodyti sluoksnius (spustelėkite dukart, norėdami atstatyti visus sluoksnius į numatytąją būseną)
+pdfjs-layers-button-label = Sluoksniai
+pdfjs-thumbs-button =
+ .title = Rodyti puslapių miniatiūras
+pdfjs-thumbs-button-label = Miniatiūros
+pdfjs-current-outline-item-button =
+ .title = Rasti dabartinį struktūros elementą
+pdfjs-current-outline-item-button-label = Dabartinis struktūros elementas
+pdfjs-findbar-button =
+ .title = Ieškoti dokumente
+pdfjs-findbar-button-label = Rasti
+pdfjs-additional-layers = Papildomi sluoksniai
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } puslapis
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } puslapio miniatiūra
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Rasti
+ .placeholder = Rasti dokumente…
+pdfjs-find-previous-button =
+ .title = Ieškoti ankstesnio frazės egzemplioriaus
+pdfjs-find-previous-button-label = Ankstesnis
+pdfjs-find-next-button =
+ .title = Ieškoti tolesnio frazės egzemplioriaus
+pdfjs-find-next-button-label = Tolesnis
+pdfjs-find-highlight-checkbox = Viską paryškinti
+pdfjs-find-match-case-checkbox-label = Skirti didžiąsias ir mažąsias raides
+pdfjs-find-match-diacritics-checkbox-label = Skirti diakritinius ženklus
+pdfjs-find-entire-word-checkbox-label = Ištisi žodžiai
+pdfjs-find-reached-top = Pasiekus dokumento pradžią, paieška pratęsta nuo pabaigos
+pdfjs-find-reached-bottom = Pasiekus dokumento pabaigą, paieška pratęsta nuo pradžios
+pdfjs-find-not-found = Ieškoma frazė nerasta
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Priderinti prie lapo ploÄio
+pdfjs-page-scale-fit = Pritaikyti prie lapo dydžio
+pdfjs-page-scale-auto = Automatinis mastelis
+pdfjs-page-scale-actual = Tikras dydis
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page } puslapis
+
+## Loading indicator messages
+
+pdfjs-loading-error = Įkeliant PDF failą įvyko klaida.
+pdfjs-invalid-file-error = Tai nÄ—ra PDF failas arba jis yra sugadintas.
+pdfjs-missing-file-error = PDF failas nerastas.
+pdfjs-unexpected-response-error = NetikÄ—tas serverio atsakas.
+pdfjs-rendering-error = Atvaizduojant puslapį įvyko klaida.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [„{ $type }“ tipo anotacija]
+
+## Password
+
+pdfjs-password-label = Įveskite slaptažodį šiam PDF failui atverti.
+pdfjs-password-invalid = Slaptažodis neteisingas. Bandykite dar kartą.
+pdfjs-password-ok-button = Gerai
+pdfjs-password-cancel-button = Atsisakyti
+pdfjs-web-fonts-disabled = Saityno Å¡riftai iÅ¡jungti – PDF faile esanÄių Å¡riftų naudoti negalima.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ltg/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ltg/viewer.ftl
new file mode 100644
index 000000000..d26216545
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ltg/viewer.ftl
@@ -0,0 +1,246 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ĪprÄ«kÅ¡ejÄ lopa
+pdfjs-previous-button-label = ĪprÄ«kÅ¡ejÄ
+pdfjs-next-button =
+ .title = Nuokomuo lopa
+pdfjs-next-button-label = Nuokomuo
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Lopa
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = nu { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } nu { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Attuolynuot
+pdfjs-zoom-out-button-label = Attuolynuot
+pdfjs-zoom-in-button =
+ .title = PÄ«tuvynuot
+pdfjs-zoom-in-button-label = PÄ«tuvynuot
+pdfjs-zoom-select =
+ .title = Palelynuojums
+pdfjs-presentation-mode-button =
+ .title = Puorslēgtīs iz Prezentacejis režymu
+pdfjs-presentation-mode-button-label = Prezentacejis režyms
+pdfjs-open-file-button =
+ .title = Attaiseit failu
+pdfjs-open-file-button-label = Attaiseit
+pdfjs-print-button =
+ .title = Drukuošona
+pdfjs-print-button-label = DrukÅt
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Reiki
+pdfjs-tools-button-label = Reiki
+pdfjs-first-page-button =
+ .title = Īt iz pyrmū lopu
+pdfjs-first-page-button-label = Īt iz pyrmū lopu
+pdfjs-last-page-button =
+ .title = Īt iz piedejū lopu
+pdfjs-last-page-button-label = Īt iz piedejū lopu
+pdfjs-page-rotate-cw-button =
+ .title = Pagrīzt pa pulksteni
+pdfjs-page-rotate-cw-button-label = Pagrīzt pa pulksteni
+pdfjs-page-rotate-ccw-button =
+ .title = Pagrīzt pret pulksteni
+pdfjs-page-rotate-ccw-button-label = Pagrīzt pret pulksteni
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktivizēt teksta izvieles reiku
+pdfjs-cursor-text-select-tool-button-label = Teksta izvieles reiks
+pdfjs-cursor-hand-tool-button =
+ .title = Aktivēt rūkys reiku
+pdfjs-cursor-hand-tool-button-label = RÅ«kys reiks
+pdfjs-scroll-vertical-button =
+ .title = IzmontÅt vertikalÅ« ritinÅÅ¡onu
+pdfjs-scroll-vertical-button-label = VertikalÅ ritinÅÅ¡ona
+pdfjs-scroll-horizontal-button =
+ .title = IzmontÅt horizontalÅ« ritinÅÅ¡onu
+pdfjs-scroll-horizontal-button-label = HorizontalÅ ritinÅÅ¡ona
+pdfjs-scroll-wrapped-button =
+ .title = IzmontÅt mÄrÅ«gojamÅ« ritinÅÅ¡onu
+pdfjs-scroll-wrapped-button-label = MÄrÅ«gojamÅ ritinÅÅ¡ona
+pdfjs-spread-none-button =
+ .title = NaizmontÅt lopu atvÄruma režimu
+pdfjs-spread-none-button-label = Bez atvÄrumim
+pdfjs-spread-odd-button =
+ .title = IzmontÅt lopu atvÄrumus sÅkut nu napÅra numeru lopom
+pdfjs-spread-odd-button-label = NapÅra lopys pa kreisi
+pdfjs-spread-even-button =
+ .title = IzmontÅt lopu atvÄrumus sÅkut nu pÅra numeru lopom
+pdfjs-spread-even-button-label = PÅra lopys pa kreisi
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumenta īstatiejumi…
+pdfjs-document-properties-button-label = Dokumenta īstatiejumi…
+pdfjs-document-properties-file-name = Faila nūsaukums:
+pdfjs-document-properties-file-size = Faila izmÄrs:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } biti)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } biti)
+pdfjs-document-properties-title = NÅ«saukums:
+pdfjs-document-properties-author = Autors:
+pdfjs-document-properties-subject = Tema:
+pdfjs-document-properties-keywords = AtslÄgi vuordi:
+pdfjs-document-properties-creation-date = Izveides datums:
+pdfjs-document-properties-modification-date = lobuošonys datums:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Radeituojs:
+pdfjs-document-properties-producer = PDF producents:
+pdfjs-document-properties-version = PDF verseja:
+pdfjs-document-properties-page-count = Lopu skaits:
+pdfjs-document-properties-page-size = Lopas izmÄrs:
+pdfjs-document-properties-page-size-unit-inches = collas
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portreta orientaceja
+pdfjs-document-properties-page-size-orientation-landscape = ainovys orientaceja
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = JÄ
+pdfjs-document-properties-linearized-no = NÄ
+pdfjs-document-properties-close-button = Aiztaiseit
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Atceļt
+pdfjs-printing-not-supported = Uzmaneibu: DrukuoÅ¡ona nu itei puorlÅ«ka dorbojÄs tikai daleji.
+pdfjs-printing-not-ready = Uzmaneibu: PDF nav pilneibÄ Ä«luodeits drukuoÅ¡onai.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Puorslēgt suonu jūslu
+pdfjs-toggle-sidebar-button-label = Puorslēgt suonu jūslu
+pdfjs-document-outline-button =
+ .title = Show Document Outline (double-click to expand/collapse all items)
+pdfjs-document-outline-button-label = Dokumenta saturs
+pdfjs-attachments-button =
+ .title = Show Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-thumbs-button =
+ .title = Paruodeit seiktÄlus
+pdfjs-thumbs-button-label = SeiktÄli
+pdfjs-findbar-button =
+ .title = Mekleit dokumentÄ
+pdfjs-findbar-button-label = Mekleit
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Lopa { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Lopys { $page } seiktÄls
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Mekleit
+ .placeholder = Mekleit dokumentÄ…
+pdfjs-find-previous-button =
+ .title = Atrast īprīkšejū
+pdfjs-find-previous-button-label = ĪprÄ«kÅ¡ejÄ
+pdfjs-find-next-button =
+ .title = Atrast nuokamū
+pdfjs-find-next-button-label = Nuokomuo
+pdfjs-find-highlight-checkbox = Īkruosuot vysys
+pdfjs-find-match-case-checkbox-label = Lelū, mozū burtu jiuteigs
+pdfjs-find-reached-top = Sasnīgts dokumenta suokums, turpynojom nu beigom
+pdfjs-find-reached-bottom = Sasnīgtys dokumenta beigys, turpynojom nu suokuma
+pdfjs-find-not-found = FrÄze nav atrosta
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lopys plotumÄ
+pdfjs-page-scale-fit = Ītylpynūt lopu
+pdfjs-page-scale-auto = Automatiskais izmÄrs
+pdfjs-page-scale-actual = PatÄ«sais izmÄrs
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Īluodejūt PDF nūtyka klaida.
+pdfjs-invalid-file-error = Nadereigs voi būjuots PDF fails.
+pdfjs-missing-file-error = PDF fails nav atrosts.
+pdfjs-unexpected-response-error = Unexpected server response.
+pdfjs-rendering-error = AttÄlojÅ«t lopu rodÄs klaida
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Īvodit paroli, kab attaiseitu PDF failu.
+pdfjs-password-invalid = Napareiza parole, raugit vēļreiz.
+pdfjs-password-ok-button = Labi
+pdfjs-password-cancel-button = Atceļt
+pdfjs-web-fonts-disabled = Å Ä·Ärsteikla fonti nav aktivizÄti: Navar Ä«gult PDF fontus.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/lv/viewer.ftl b/www/lib/pdfjs/modern/web/locale/lv/viewer.ftl
new file mode 100644
index 000000000..067dc105e
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/lv/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = IepriekÅ¡Ä“jÄ lapa
+pdfjs-previous-button-label = IepriekÅ¡Ä“jÄ
+pdfjs-next-button =
+ .title = NÄkamÄ lapa
+pdfjs-next-button-label = NÄkamÄ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Lapa
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = no { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } no { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = AttÄlinÄt
+pdfjs-zoom-out-button-label = AttÄlinÄt
+pdfjs-zoom-in-button =
+ .title = PietuvinÄt
+pdfjs-zoom-in-button-label = PietuvinÄt
+pdfjs-zoom-select =
+ .title = PalielinÄjums
+pdfjs-presentation-mode-button =
+ .title = PÄrslÄ“gties uz PrezentÄcijas režīmu
+pdfjs-presentation-mode-button-label = PrezentÄcijas režīms
+pdfjs-open-file-button =
+ .title = Atvērt failu
+pdfjs-open-file-button-label = Atvērt
+pdfjs-print-button =
+ .title = DrukÄÅ¡ana
+pdfjs-print-button-label = DrukÄt
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = RÄ«ki
+pdfjs-tools-button-label = RÄ«ki
+pdfjs-first-page-button =
+ .title = Iet uz pirmo lapu
+pdfjs-first-page-button-label = Iet uz pirmo lapu
+pdfjs-last-page-button =
+ .title = Iet uz pēdējo lapu
+pdfjs-last-page-button-label = Iet uz pēdējo lapu
+pdfjs-page-rotate-cw-button =
+ .title = Pagriezt pa pulksteni
+pdfjs-page-rotate-cw-button-label = Pagriezt pa pulksteni
+pdfjs-page-rotate-ccw-button =
+ .title = Pagriezt pret pulksteni
+pdfjs-page-rotate-ccw-button-label = Pagriezt pret pulksteni
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktivizēt teksta izvēles rīku
+pdfjs-cursor-text-select-tool-button-label = Teksta izvēles rīks
+pdfjs-cursor-hand-tool-button =
+ .title = Aktivēt rokas rīku
+pdfjs-cursor-hand-tool-button-label = Rokas rīks
+pdfjs-scroll-vertical-button =
+ .title = Izmantot vertikÄlo ritinÄÅ¡anu
+pdfjs-scroll-vertical-button-label = VertikÄlÄ ritinÄÅ¡ana
+pdfjs-scroll-horizontal-button =
+ .title = Izmantot horizontÄlo ritinÄÅ¡anu
+pdfjs-scroll-horizontal-button-label = HorizontÄlÄ ritinÄÅ¡ana
+pdfjs-scroll-wrapped-button =
+ .title = Izmantot apkļauto ritinÄÅ¡anu
+pdfjs-scroll-wrapped-button-label = ApkļautÄ ritinÄÅ¡ana
+pdfjs-spread-none-button =
+ .title = Nepievienoties lapu izpletumiem
+pdfjs-spread-none-button-label = Neizmantot izpletumus
+pdfjs-spread-odd-button =
+ .title = Izmantot lapu izpletumus sÄkot ar nepÄra numuru lapÄm
+pdfjs-spread-odd-button-label = NepÄra izpletumi
+pdfjs-spread-even-button =
+ .title = Izmantot lapu izpletumus sÄkot ar pÄra numuru lapÄm
+pdfjs-spread-even-button-label = PÄra izpletumi
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumenta iestatījumi…
+pdfjs-document-properties-button-label = Dokumenta iestatījumi…
+pdfjs-document-properties-file-name = Faila nosaukums:
+pdfjs-document-properties-file-size = Faila izmērs:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } biti)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } biti)
+pdfjs-document-properties-title = Nosaukums:
+pdfjs-document-properties-author = Autors:
+pdfjs-document-properties-subject = TÄ“ma:
+pdfjs-document-properties-keywords = AtslÄ“gas vÄrdi:
+pdfjs-document-properties-creation-date = Izveides datums:
+pdfjs-document-properties-modification-date = LAbošanas datums:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = RadÄ«tÄjs:
+pdfjs-document-properties-producer = PDF producents:
+pdfjs-document-properties-version = PDF versija:
+pdfjs-document-properties-page-count = Lapu skaits:
+pdfjs-document-properties-page-size = Papīra izmērs:
+pdfjs-document-properties-page-size-unit-inches = collas
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portretorientÄcija
+pdfjs-document-properties-page-size-orientation-landscape = ainavorientÄcija
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = VÄ“stule
+pdfjs-document-properties-page-size-name-legal = Juridiskie teksti
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Ä€trÄ tÄ«mekļa skats:
+pdfjs-document-properties-linearized-yes = JÄ
+pdfjs-document-properties-linearized-no = NÄ“
+pdfjs-document-properties-close-button = Aizvērt
+
+## Print
+
+pdfjs-print-progress-message = Gatavo dokumentu drukÄÅ¡anai...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Atcelt
+pdfjs-printing-not-supported = UzmanÄ«bu: DrukÄÅ¡ana no Å¡Ä« pÄrlÅ«ka darbojas tikai daļēji.
+pdfjs-printing-not-ready = UzmanÄ«bu: PDF nav pilnÄ«bÄ ielÄdÄ“ts drukÄÅ¡anai.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = PÄrslÄ“gt sÄnu joslu
+pdfjs-toggle-sidebar-button-label = PÄrslÄ“gt sÄnu joslu
+pdfjs-document-outline-button =
+ .title = RÄdÄ«t dokumenta struktÅ«ru (veiciet dubultklikÅ¡Ä·i lai izvÄ“rstu/sakļautu visus vienumus)
+pdfjs-document-outline-button-label = Dokumenta saturs
+pdfjs-attachments-button =
+ .title = RÄdÄ«t pielikumus
+pdfjs-attachments-button-label = Pielikumi
+pdfjs-thumbs-button =
+ .title = ParÄdÄ«t sÄ«ktÄ“lus
+pdfjs-thumbs-button-label = Sīktēli
+pdfjs-findbar-button =
+ .title = MeklÄ“t dokumentÄ
+pdfjs-findbar-button-label = Meklēt
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Lapa { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Lapas { $page } sīktēls
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Meklēt
+ .placeholder = Meklēt dokumentą
+pdfjs-find-previous-button =
+ .title = Atrast iepriekšējo
+pdfjs-find-previous-button-label = IepriekÅ¡Ä“jÄ
+pdfjs-find-next-button =
+ .title = Atrast nÄkamo
+pdfjs-find-next-button-label = NÄkamÄ
+pdfjs-find-highlight-checkbox = IekrÄsot visas
+pdfjs-find-match-case-checkbox-label = Lielo, mazo burtu jutīgs
+pdfjs-find-entire-word-checkbox-label = Veselus vÄrdus
+pdfjs-find-reached-top = Sasniegts dokumenta sÄkums, turpinÄm no beigÄm
+pdfjs-find-reached-bottom = Sasniegtas dokumenta beigas, turpinÄm no sÄkuma
+pdfjs-find-not-found = FrÄze nav atrasta
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lapas platumÄ
+pdfjs-page-scale-fit = Ietilpinot lapu
+pdfjs-page-scale-auto = AutomÄtiskais izmÄ“rs
+pdfjs-page-scale-actual = Patiesais izmērs
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = IelÄdÄ“jot PDF notika kļūda.
+pdfjs-invalid-file-error = NederÄ«gs vai bojÄts PDF fails.
+pdfjs-missing-file-error = PDF fails nav atrasts.
+pdfjs-unexpected-response-error = Negaidīa servera atbilde.
+pdfjs-rendering-error = AttÄ“lojot lapu radÄs kļūda
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } anotÄcija]
+
+## Password
+
+pdfjs-password-label = Ievadiet paroli, lai atvērtu PDF failu.
+pdfjs-password-invalid = Nepareiza parole, mēģiniet vēlreiz.
+pdfjs-password-ok-button = Labi
+pdfjs-password-cancel-button = Atcelt
+pdfjs-web-fonts-disabled = Tīmekļa fonti nav aktivizēti: Nevar iegult PDF fontus.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/meh/viewer.ftl b/www/lib/pdfjs/modern/web/locale/meh/viewer.ftl
new file mode 100644
index 000000000..d8bddc9d5
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/meh/viewer.ftl
@@ -0,0 +1,87 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página yata
+pdfjs-zoom-select =
+ .title = Nasa´a ka´nu/Nasa´a luli
+pdfjs-open-file-button-label = SÃne
+
+## Secondary toolbar and context menu
+
+
+## Document properties dialog
+
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = Kuvi
+pdfjs-document-properties-close-button = Nakasɨ
+
+## Print
+
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Nkuvi-ka
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-findbar-button-label = Nánuku
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+
+## Find panel button title and messages
+
+
+## Predefined zoom values
+
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+## Password
+
+pdfjs-password-cancel-button = Nkuvi-ka
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/mk/viewer.ftl b/www/lib/pdfjs/modern/web/locale/mk/viewer.ftl
new file mode 100644
index 000000000..47d24b240
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/mk/viewer.ftl
@@ -0,0 +1,215 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Претходна Ñтраница
+pdfjs-previous-button-label = Претходна
+pdfjs-next-button =
+ .title = Следна Ñтраница
+pdfjs-next-button-label = Следна
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Страница
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = од { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } од { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Ðамалување
+pdfjs-zoom-out-button-label = Ðамали
+pdfjs-zoom-in-button =
+ .title = Зголемување
+pdfjs-zoom-in-button-label = Зголеми
+pdfjs-zoom-select =
+ .title = Променување на големина
+pdfjs-presentation-mode-button =
+ .title = Премини во презентациÑки режим
+pdfjs-presentation-mode-button-label = ПрезентациÑки режим
+pdfjs-open-file-button =
+ .title = Отворање датотека
+pdfjs-open-file-button-label = Отвори
+pdfjs-print-button =
+ .title = Печатење
+pdfjs-print-button-label = Печати
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ðлатки
+pdfjs-tools-button-label = Ðлатки
+pdfjs-first-page-button =
+ .title = Оди до првата Ñтраница
+pdfjs-first-page-button-label = Оди до првата Ñтраница
+pdfjs-last-page-button =
+ .title = Оди до поÑледната Ñтраница
+pdfjs-last-page-button-label = Оди до поÑледната Ñтраница
+pdfjs-page-rotate-cw-button =
+ .title = Ротирај по Ñтрелките на чаÑовникот
+pdfjs-page-rotate-cw-button-label = Ротирај по Ñтрелките на чаÑовникот
+pdfjs-page-rotate-ccw-button =
+ .title = Ротирај Ñпротивно од Ñтрелките на чаÑовникот
+pdfjs-page-rotate-ccw-button-label = Ротирај Ñпротивно од Ñтрелките на чаÑовникот
+pdfjs-cursor-text-select-tool-button =
+ .title = Овозможи алатка за избор на текÑÑ‚
+pdfjs-cursor-text-select-tool-button-label = Ðлатка за избор на текÑÑ‚
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = СвојÑтва на документот…
+pdfjs-document-properties-button-label = СвојÑтва на документот…
+pdfjs-document-properties-file-name = Име на датотека:
+pdfjs-document-properties-file-size = Големина на датотеката:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } бајти)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } бајти)
+pdfjs-document-properties-title = ÐаÑлов:
+pdfjs-document-properties-author = Ðвтор:
+pdfjs-document-properties-subject = Тема:
+pdfjs-document-properties-keywords = Клучни зборови:
+pdfjs-document-properties-creation-date = Датум на Ñоздавање:
+pdfjs-document-properties-modification-date = Датум на промена:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Креатор:
+pdfjs-document-properties-version = Верзија на PDF:
+pdfjs-document-properties-page-count = Број на Ñтраници:
+pdfjs-document-properties-page-size = Големина на Ñтраница:
+pdfjs-document-properties-page-size-unit-inches = инч
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = портрет
+pdfjs-document-properties-page-size-orientation-landscape = пејзаж
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ПиÑмо
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = Да
+pdfjs-document-properties-linearized-no = Ðе
+pdfjs-document-properties-close-button = Затвори
+
+## Print
+
+pdfjs-print-progress-message = Документ Ñе подготвува за печатење…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Откажи
+pdfjs-printing-not-supported = Предупредување: Печатењето не е целоÑно поддржано во овој прелиÑтувач.
+pdfjs-printing-not-ready = Предупредување: PDF документот не е целоÑно вчитан за печатење.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Вклучи Ñтранична лента
+pdfjs-toggle-sidebar-button-label = Вклучи Ñтранична лента
+pdfjs-document-outline-button-label = Содржина на документот
+pdfjs-attachments-button =
+ .title = Прикажи додатоци
+pdfjs-thumbs-button =
+ .title = Прикажување на икони
+pdfjs-thumbs-button-label = Икони
+pdfjs-findbar-button =
+ .title = Ðајди во документот
+pdfjs-findbar-button-label = Ðајди
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Страница { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Икона од Ñтраница { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Пронајди
+ .placeholder = Пронајди во документот…
+pdfjs-find-previous-button =
+ .title = Ðајди ја предходната појава на фразата
+pdfjs-find-previous-button-label = Претходно
+pdfjs-find-next-button =
+ .title = Ðајди ја Ñледната појава на фразата
+pdfjs-find-next-button-label = Следно
+pdfjs-find-highlight-checkbox = Означи ÑÑ
+pdfjs-find-match-case-checkbox-label = Токму така
+pdfjs-find-entire-word-checkbox-label = Цели зборови
+pdfjs-find-reached-top = Барањето Ñтигна до почетокот на документот и почнува од крајот
+pdfjs-find-reached-bottom = Барањето Ñтигна до крајот на документот и почнува од почеток
+pdfjs-find-not-found = Фразата не е пронајдена
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ширина на Ñтраница
+pdfjs-page-scale-fit = Цела Ñтраница
+pdfjs-page-scale-auto = ÐвтоматÑка големина
+pdfjs-page-scale-actual = ВиÑтинÑка големина
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = ÐаÑтана грешка при вчитувањето на PDF-от.
+pdfjs-invalid-file-error = Ðевалидна или корумпирана PDF датотека.
+pdfjs-missing-file-error = ÐедоÑтаÑува PDF документ.
+pdfjs-unexpected-response-error = Ðеочекуван одговор од Ñерверот.
+pdfjs-rendering-error = ÐаÑтана грешка при прикажувањето на Ñтраницата.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+## Password
+
+pdfjs-password-label = ВнеÑете ја лозинката за да ја отворите оваа датотека.
+pdfjs-password-invalid = Ðевалидна лозинка. Обидете Ñе повторно.
+pdfjs-password-ok-button = Во ред
+pdfjs-password-cancel-button = Откажи
+pdfjs-web-fonts-disabled = Интернет фонтовите Ñе оневозможени: не може да Ñе кориÑтат вградените PDF фонтови.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/mr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/mr/viewer.ftl
new file mode 100644
index 000000000..49948b193
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/mr/viewer.ftl
@@ -0,0 +1,239 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = मागील पृषà¥à¤
+pdfjs-previous-button-label = मागील
+pdfjs-next-button =
+ .title = पà¥à¤¢à¥€à¤² पृषà¥à¤
+pdfjs-next-button-label = पà¥à¤¢à¥€à¤²
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = पृषà¥à¤
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount }पैकी
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } पैकी { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = छोटे करा
+pdfjs-zoom-out-button-label = छोटे करा
+pdfjs-zoom-in-button =
+ .title = मोठे करा
+pdfjs-zoom-in-button-label = मोठे करा
+pdfjs-zoom-select =
+ .title = लहान किंवा मोठे करा
+pdfjs-presentation-mode-button =
+ .title = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿à¤•à¤°à¤£ मोडचा वापर करा
+pdfjs-presentation-mode-button-label = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿à¤•à¤°à¤£ मोड
+pdfjs-open-file-button =
+ .title = फाइल उघडा
+pdfjs-open-file-button-label = उघडा
+pdfjs-print-button =
+ .title = छपाई करा
+pdfjs-print-button-label = छपाई करा
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = साधने
+pdfjs-tools-button-label = साधने
+pdfjs-first-page-button =
+ .title = पहिलà¥à¤¯à¤¾ पृषà¥à¤ ावर जा
+pdfjs-first-page-button-label = पहिलà¥à¤¯à¤¾ पृषà¥à¤ ावर जा
+pdfjs-last-page-button =
+ .title = शेवटचà¥à¤¯à¤¾ पृषà¥à¤ ावर जा
+pdfjs-last-page-button-label = शेवटचà¥à¤¯à¤¾ पृषà¥à¤ ावर जा
+pdfjs-page-rotate-cw-button =
+ .title = घडà¥à¤¯à¤¾à¤³à¤¾à¤šà¥à¤¯à¤¾ काटà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ दिशेने फिरवा
+pdfjs-page-rotate-cw-button-label = घडà¥à¤¯à¤¾à¤³à¤¾à¤šà¥à¤¯à¤¾ काटà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ दिशेने फिरवा
+pdfjs-page-rotate-ccw-button =
+ .title = घडà¥à¤¯à¤¾à¤³à¤¾à¤šà¥à¤¯à¤¾ काटà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ उलट दिशेने फिरवा
+pdfjs-page-rotate-ccw-button-label = घडà¥à¤¯à¤¾à¤³à¤¾à¤šà¥à¤¯à¤¾ काटà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ उलट दिशेने फिरवा
+pdfjs-cursor-text-select-tool-button =
+ .title = मजकूर निवड साधन कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¯à¥€à¤¤ करा
+pdfjs-cursor-text-select-tool-button-label = मजकूर निवड साधन
+pdfjs-cursor-hand-tool-button =
+ .title = हात साधन कारà¥à¤¯à¤¾à¤¨à¥à¤µà¤¿à¤¤ करा
+pdfjs-cursor-hand-tool-button-label = हसà¥à¤¤ साधन
+pdfjs-scroll-vertical-button =
+ .title = अनà¥à¤²à¤‚ब सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤‚ग वापरा
+pdfjs-scroll-vertical-button-label = अनà¥à¤²à¤‚ब सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤‚ग
+pdfjs-scroll-horizontal-button =
+ .title = कà¥à¤·à¥ˆà¤¤à¤¿à¤œ सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤‚ग वापरा
+pdfjs-scroll-horizontal-button-label = कà¥à¤·à¥ˆà¤¤à¤¿à¤œ सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤‚ग
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = दसà¥à¤¤à¤à¤µà¤œ गà¥à¤£à¤§à¤°à¥à¤®â€¦
+pdfjs-document-properties-button-label = दसà¥à¤¤à¤à¤µà¤œ गà¥à¤£à¤§à¤°à¥à¤®â€¦
+pdfjs-document-properties-file-name = फाइलचे नाव:
+pdfjs-document-properties-file-size = फाइल आकार:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } बाइटà¥à¤¸)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } बाइटà¥à¤¸)
+pdfjs-document-properties-title = शिरà¥à¤·à¤•:
+pdfjs-document-properties-author = लेखक:
+pdfjs-document-properties-subject = विषय:
+pdfjs-document-properties-keywords = मà¥à¤–à¥à¤¯à¤¶à¤¬à¥à¤¦:
+pdfjs-document-properties-creation-date = निरà¥à¤®à¤¾à¤£ दिनांक:
+pdfjs-document-properties-modification-date = दà¥à¤°à¥‚सà¥à¤¤à¥€ दिनांक:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = निरà¥à¤®à¤¾à¤¤à¤¾:
+pdfjs-document-properties-producer = PDF निरà¥à¤®à¤¾à¤¤à¤¾:
+pdfjs-document-properties-version = PDF आवृतà¥à¤¤à¥€:
+pdfjs-document-properties-page-count = पृषà¥à¤ संखà¥à¤¯à¤¾:
+pdfjs-document-properties-page-size = पृषà¥à¤ आकार:
+pdfjs-document-properties-page-size-unit-inches = इंच
+pdfjs-document-properties-page-size-unit-millimeters = मीमी
+pdfjs-document-properties-page-size-orientation-portrait = उà¤à¥€ मांडणी
+pdfjs-document-properties-page-size-orientation-landscape = आडवे
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = जलद वेब दृषà¥à¤¯:
+pdfjs-document-properties-linearized-yes = हो
+pdfjs-document-properties-linearized-no = नाही
+pdfjs-document-properties-close-button = बंद करा
+
+## Print
+
+pdfjs-print-progress-message = छपाई करीता पृषà¥à¤ तयार करीत आहे…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = रदà¥à¤¦ करा
+pdfjs-printing-not-supported = सावधानता: या बà¥à¤°à¤¾à¤‰à¤à¤°à¤¤à¤°à¥à¤«à¥‡ छपाइ पूरà¥à¤£à¤ªà¤£à¥‡ समरà¥à¤¥à¥€à¤¤ नाही.
+pdfjs-printing-not-ready = सावधानता: छपाईकरिता PDF पूरà¥à¤£à¤¤à¤¯à¤¾ लोड à¤à¤¾à¤²à¥‡ नाही.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = बाजूचीपटà¥à¤Ÿà¥€ टॉगल करा
+pdfjs-toggle-sidebar-button-label = बाजूचीपटà¥à¤Ÿà¥€ टॉगल करा
+pdfjs-document-outline-button =
+ .title = दसà¥à¤¤à¤à¤µà¤œ बाहà¥à¤¯à¤°à¥‡à¤–ा दरà¥à¤¶à¤µà¤¾ (विसà¥à¤¤à¥ƒà¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ ी दोनवेळा कà¥à¤²à¤¿à¤• करा /सरà¥à¤µ घटक दाखवा)
+pdfjs-document-outline-button-label = दसà¥à¤¤à¤à¤µà¤œ रूपरेषा
+pdfjs-attachments-button =
+ .title = जोडपतà¥à¤° दाखवा
+pdfjs-attachments-button-label = जोडपतà¥à¤°
+pdfjs-thumbs-button =
+ .title = थंबनेलà¥à¤¸à¥ दाखवा
+pdfjs-thumbs-button-label = थंबनेलà¥à¤¸à¥
+pdfjs-findbar-button =
+ .title = दसà¥à¤¤à¤à¤µà¤œà¤¾à¤¤ शोधा
+pdfjs-findbar-button-label = शोधा
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = पृषà¥à¤ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = पृषà¥à¤ ाचे थंबनेल { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = शोधा
+ .placeholder = दसà¥à¤¤à¤à¤µà¤œà¤¾à¤¤ शोधा…
+pdfjs-find-previous-button =
+ .title = वाकपà¥à¤°à¤¯à¥‹à¤—ची मागील घटना शोधा
+pdfjs-find-previous-button-label = मागील
+pdfjs-find-next-button =
+ .title = वाकपà¥à¤°à¤¯à¥‹à¤—ची पà¥à¤¢à¥€à¤² घटना शोधा
+pdfjs-find-next-button-label = पà¥à¤¢à¥€à¤²
+pdfjs-find-highlight-checkbox = सरà¥à¤µ ठळक करा
+pdfjs-find-match-case-checkbox-label = आकार जà¥à¤³à¤µà¤¾
+pdfjs-find-entire-word-checkbox-label = संपूरà¥à¤£ शबà¥à¤¦
+pdfjs-find-reached-top = दसà¥à¤¤à¤à¤µà¤œà¤¾à¤šà¥à¤¯à¤¾ शीरà¥à¤·à¤•à¤¾à¤¸ पोहचले, तळपासून पà¥à¤¢à¥‡
+pdfjs-find-reached-bottom = दसà¥à¤¤à¤à¤µà¤œà¤¾à¤šà¥à¤¯à¤¾ तळाला पोहचले, शीरà¥à¤·à¤•à¤¾à¤ªà¤¾à¤¸à¥‚न पà¥à¤¢à¥‡
+pdfjs-find-not-found = वाकपà¥à¤°à¤¯à¥‹à¤— आढळले नाही
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = पृषà¥à¤ ाची रूंदी
+pdfjs-page-scale-fit = पृषà¥à¤ बसवा
+pdfjs-page-scale-auto = सà¥à¤µà¤¯à¤‚ लाहन किंवा मोठे करणे
+pdfjs-page-scale-actual = पà¥à¤°à¤¤à¥à¤¯à¤•à¥à¤· आकार
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF लोड करतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली.
+pdfjs-invalid-file-error = अवैध किंवा दोषीत PDF फाइल.
+pdfjs-missing-file-error = न आढळणारी PDF फाइल.
+pdfjs-unexpected-response-error = अनपेकà¥à¤·à¤¿à¤¤ सरà¥à¤µà¥à¤¹à¤° पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦.
+pdfjs-rendering-error = पृषà¥à¤ दाखवतेवेळी तà¥à¤°à¥à¤Ÿà¥€ आढळली.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } टिपणà¥à¤£à¥€]
+
+## Password
+
+pdfjs-password-label = ही PDF फाइल उघडणà¥à¤¯à¤¾à¤•à¤°à¤¿à¤¤à¤¾ पासवरà¥à¤¡ दà¥à¤¯à¤¾.
+pdfjs-password-invalid = अवैध पासवरà¥à¤¡. कृपया पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.
+pdfjs-password-ok-button = ठीक आहे
+pdfjs-password-cancel-button = रदà¥à¤¦ करा
+pdfjs-web-fonts-disabled = वेब टंक असमरà¥à¤¥à¥€à¤¤ आहेत: à¤à¤®à¥à¤¬à¥‡à¤¡à¥‡à¤¡ PDF टंक वापर अशकà¥à¤¯.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ms/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ms/viewer.ftl
new file mode 100644
index 000000000..11b866514
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ms/viewer.ftl
@@ -0,0 +1,247 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Halaman Dahulu
+pdfjs-previous-button-label = Dahulu
+pdfjs-next-button =
+ .title = Halaman Berikut
+pdfjs-next-button-label = Berikut
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Halaman
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = daripada { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } daripada { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zum Keluar
+pdfjs-zoom-out-button-label = Zum Keluar
+pdfjs-zoom-in-button =
+ .title = Zum Masuk
+pdfjs-zoom-in-button-label = Zum Masuk
+pdfjs-zoom-select =
+ .title = Zum
+pdfjs-presentation-mode-button =
+ .title = Tukar ke Mod Persembahan
+pdfjs-presentation-mode-button-label = Mod Persembahan
+pdfjs-open-file-button =
+ .title = Buka Fail
+pdfjs-open-file-button-label = Buka
+pdfjs-print-button =
+ .title = Cetak
+pdfjs-print-button-label = Cetak
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Alatan
+pdfjs-tools-button-label = Alatan
+pdfjs-first-page-button =
+ .title = Pergi ke Halaman Pertama
+pdfjs-first-page-button-label = Pergi ke Halaman Pertama
+pdfjs-last-page-button =
+ .title = Pergi ke Halaman Terakhir
+pdfjs-last-page-button-label = Pergi ke Halaman Terakhir
+pdfjs-page-rotate-cw-button =
+ .title = Berputar ikut arah Jam
+pdfjs-page-rotate-cw-button-label = Berputar ikut arah Jam
+pdfjs-page-rotate-ccw-button =
+ .title = Pusing berlawan arah jam
+pdfjs-page-rotate-ccw-button-label = Pusing berlawan arah jam
+pdfjs-cursor-text-select-tool-button =
+ .title = Dayakan Alatan Pilihan Teks
+pdfjs-cursor-text-select-tool-button-label = Alatan Pilihan Teks
+pdfjs-cursor-hand-tool-button =
+ .title = Dayakan Alatan Tangan
+pdfjs-cursor-hand-tool-button-label = Alatan Tangan
+pdfjs-scroll-vertical-button =
+ .title = Guna Skrol Menegak
+pdfjs-scroll-vertical-button-label = Skrol Menegak
+pdfjs-scroll-horizontal-button =
+ .title = Guna Skrol Mengufuk
+pdfjs-scroll-horizontal-button-label = Skrol Mengufuk
+pdfjs-scroll-wrapped-button =
+ .title = Guna Skrol Berbalut
+pdfjs-scroll-wrapped-button-label = Skrol Berbalut
+pdfjs-spread-none-button =
+ .title = Jangan hubungkan hamparan halaman
+pdfjs-spread-none-button-label = Tanpa Hamparan
+pdfjs-spread-odd-button =
+ .title = Hubungkan hamparan halaman dengan halaman nombor ganjil
+pdfjs-spread-odd-button-label = Hamparan Ganjil
+pdfjs-spread-even-button =
+ .title = Hubungkan hamparan halaman dengan halaman nombor genap
+pdfjs-spread-even-button-label = Hamparan Seimbang
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Sifat Dokumen…
+pdfjs-document-properties-button-label = Sifat Dokumen…
+pdfjs-document-properties-file-name = Nama fail:
+pdfjs-document-properties-file-size = Saiz fail:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bait)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bait)
+pdfjs-document-properties-title = Tajuk:
+pdfjs-document-properties-author = Pengarang:
+pdfjs-document-properties-subject = Subjek:
+pdfjs-document-properties-keywords = Kata kunci:
+pdfjs-document-properties-creation-date = Masa Dicipta:
+pdfjs-document-properties-modification-date = Tarikh Ubahsuai:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Pencipta:
+pdfjs-document-properties-producer = Pengeluar PDF:
+pdfjs-document-properties-version = Versi PDF:
+pdfjs-document-properties-page-count = Kiraan Laman:
+pdfjs-document-properties-page-size = Saiz Halaman:
+pdfjs-document-properties-page-size-unit-inches = dalam
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = potret
+pdfjs-document-properties-page-size-orientation-landscape = landskap
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Paparan Web Pantas:
+pdfjs-document-properties-linearized-yes = Ya
+pdfjs-document-properties-linearized-no = Tidak
+pdfjs-document-properties-close-button = Tutup
+
+## Print
+
+pdfjs-print-progress-message = Menyediakan dokumen untuk dicetak…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Batal
+pdfjs-printing-not-supported = Amaran: Cetakan ini tidak sepenuhnya disokong oleh pelayar ini.
+pdfjs-printing-not-ready = Amaran: PDF tidak sepenuhnya dimuatkan untuk dicetak.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Togol Bar Sisi
+pdfjs-toggle-sidebar-button-label = Togol Bar Sisi
+pdfjs-document-outline-button =
+ .title = Papar Rangka Dokumen (klik-dua-kali untuk kembangkan/kolaps semua item)
+pdfjs-document-outline-button-label = Rangka Dokumen
+pdfjs-attachments-button =
+ .title = Papar Lampiran
+pdfjs-attachments-button-label = Lampiran
+pdfjs-thumbs-button =
+ .title = Papar Thumbnails
+pdfjs-thumbs-button-label = Imej kecil
+pdfjs-findbar-button =
+ .title = Cari didalam Dokumen
+pdfjs-findbar-button-label = Cari
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Halaman { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Halaman Imej kecil { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Cari
+ .placeholder = Cari dalam dokumen…
+pdfjs-find-previous-button =
+ .title = Cari teks frasa berkenaan yang terdahulu
+pdfjs-find-previous-button-label = Dahulu
+pdfjs-find-next-button =
+ .title = Cari teks frasa berkenaan yang berikut
+pdfjs-find-next-button-label = Berikut
+pdfjs-find-highlight-checkbox = Serlahkan semua
+pdfjs-find-match-case-checkbox-label = Huruf sepadan
+pdfjs-find-entire-word-checkbox-label = Seluruh perkataan
+pdfjs-find-reached-top = Mencapai teratas daripada dokumen, sambungan daripada bawah
+pdfjs-find-reached-bottom = Mencapai terakhir daripada dokumen, sambungan daripada atas
+pdfjs-find-not-found = Frasa tidak ditemui
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lebar Halaman
+pdfjs-page-scale-fit = Muat Halaman
+pdfjs-page-scale-auto = Zoom Automatik
+pdfjs-page-scale-actual = Saiz Sebenar
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Masalah berlaku semasa menuatkan sebuah PDF.
+pdfjs-invalid-file-error = Tidak sah atau fail PDF rosak.
+pdfjs-missing-file-error = Fail PDF Hilang.
+pdfjs-unexpected-response-error = Respon pelayan yang tidak dijangka.
+pdfjs-rendering-error = Ralat berlaku ketika memberikan halaman.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Anotasi]
+
+## Password
+
+pdfjs-password-label = Masukan kata kunci untuk membuka fail PDF ini.
+pdfjs-password-invalid = Kata laluan salah. Cuba lagi.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Batal
+pdfjs-web-fonts-disabled = Fon web dinyahdayakan: tidak dapat menggunakan fon terbenam PDF.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/my/viewer.ftl b/www/lib/pdfjs/modern/web/locale/my/viewer.ftl
new file mode 100644
index 000000000..d3b973d87
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/my/viewer.ftl
@@ -0,0 +1,206 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = အရင် စာမျက်နှာ
+pdfjs-previous-button-label = အရင်နေရာ
+pdfjs-next-button =
+ .title = ရှေ့ စာမျက်နှာ
+pdfjs-next-button-label = နောက်á€á€á€¯
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = စာမျက်နှာ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } á
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } á { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = á€á€»á€¯á€¶á€·á€•á€«
+pdfjs-zoom-out-button-label = á€á€»á€¯á€¶á€·á€•á€«
+pdfjs-zoom-in-button =
+ .title = á€á€»á€²á€·á€•á€«
+pdfjs-zoom-in-button-label = á€á€»á€²á€·á€•á€«
+pdfjs-zoom-select =
+ .title = á€á€»á€¯á€¶á€·/á€á€»á€²á€·á€•á€«
+pdfjs-presentation-mode-button =
+ .title = ဆွေးနွေးá€á€„်ပြစနစ်သá€á€¯á€· ကူးပြောင်းပါ
+pdfjs-presentation-mode-button-label = ဆွေးနွေးá€á€„်ပြစနစ်
+pdfjs-open-file-button =
+ .title = ဖá€á€¯á€„်အားဖွင့်ပါá‹
+pdfjs-open-file-button-label = ဖွင့်ပါ
+pdfjs-print-button =
+ .title = ပုံနှá€á€¯á€•á€ºá€•á€«
+pdfjs-print-button-label = ပုံနှá€á€¯á€•á€ºá€•á€«
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ကá€á€›á€á€šá€¬á€™á€»á€¬á€¸
+pdfjs-tools-button-label = ကá€á€›á€á€šá€¬á€™á€»á€¬á€¸
+pdfjs-first-page-button =
+ .title = ပထမ စာမျက်နှာသá€á€¯á€·
+pdfjs-first-page-button-label = ပထမ စာမျက်နှာသá€á€¯á€·
+pdfjs-last-page-button =
+ .title = နောက်ဆုံး စာမျက်နှာသá€á€¯á€·
+pdfjs-last-page-button-label = နောက်ဆုံး စာမျက်နှာသá€á€¯á€·
+pdfjs-page-rotate-cw-button =
+ .title = နာရီလက်á€á€¶ အá€á€á€¯á€„်း
+pdfjs-page-rotate-cw-button-label = နာရီလက်á€á€¶ အá€á€á€¯á€„်း
+pdfjs-page-rotate-ccw-button =
+ .title = နာရီလက်á€á€¶ ပြောင်းပြန်
+pdfjs-page-rotate-ccw-button-label = နာရီလက်á€á€¶ ပြောင်းပြန်
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = မှá€á€ºá€á€™á€ºá€¸á€™á€¾á€á€ºá€›á€¬ ဂုá€á€ºá€žá€á€¹á€á€á€™á€»á€¬á€¸
+pdfjs-document-properties-button-label = မှá€á€ºá€á€™á€ºá€¸á€™á€¾á€á€ºá€›á€¬ ဂုá€á€ºá€žá€á€¹á€á€á€™á€»á€¬á€¸
+pdfjs-document-properties-file-name = ဖá€á€¯á€„် :
+pdfjs-document-properties-file-size = ဖá€á€¯á€„်ဆá€á€¯á€’် :
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } ကီလá€á€¯á€˜á€á€¯á€á€º ({ $size_b }ဘá€á€¯á€á€º)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = á€á€±á€«á€„်းစဉ်‌ -
+pdfjs-document-properties-author = ရေးသားသူ:
+pdfjs-document-properties-subject = အကြောင်းအရာ:
+pdfjs-document-properties-keywords = သော့á€á€»á€€á€º စာလုံး:
+pdfjs-document-properties-creation-date = ထုá€á€ºá€œá€¯á€•á€ºá€›á€€á€ºá€…ွဲ:
+pdfjs-document-properties-modification-date = ပြင်ဆင်ရက်စွဲ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ဖန်á€á€®á€¸á€žá€°:
+pdfjs-document-properties-producer = PDF ထုá€á€ºá€œá€¯á€•á€ºá€žá€°:
+pdfjs-document-properties-version = PDF ဗားရှင်း:
+pdfjs-document-properties-page-count = စာမျက်နှာအရေအá€á€½á€€á€º:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = ပá€á€á€º
+
+## Print
+
+pdfjs-print-progress-message = Preparing document for printing…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ပယ်​ဖျက်ပါ
+pdfjs-printing-not-supported = သá€á€á€•á€±á€¸á€á€»á€€á€ºáŠá€•á€›á€„့်ထုá€á€ºá€á€¼á€„်းကá€á€¯á€¤á€˜á€šá€±á€¬á€€á€ºá€†á€¬á€žá€Šá€º ပြည့်á€á€…ွာထောက်ပံ့မထားပါ á‹
+pdfjs-printing-not-ready = သá€á€á€•á€±á€¸á€á€»á€€á€º: ယá€á€¯ PDF ဖá€á€¯á€„်သည် ပုံနှá€á€•á€ºá€›á€”် မပြည့်စုံပါ
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ဘေးá€á€”်းဖွင့်ပá€á€á€º
+pdfjs-toggle-sidebar-button-label = ဖွင့်ပá€á€á€º ဆလá€á€¯á€€á€ºá€’ါ
+pdfjs-document-outline-button =
+ .title = စာá€á€™á€ºá€¸á€¡á€€á€»á€‰á€ºá€¸á€á€»á€¯á€•á€ºá€€á€á€¯ ပြပါ (စာရင်းအားလုံးကá€á€¯ á€á€»á€¯á€¶á€·/á€á€»á€²á€·á€›á€”် ကလစ်နှစ်á€á€»á€€á€ºá€”ှá€á€•á€ºá€•á€«)
+pdfjs-document-outline-button-label = စာá€á€™á€ºá€¸á€¡á€€á€»á€‰á€ºá€¸á€á€»á€¯á€•á€º
+pdfjs-attachments-button =
+ .title = á€á€½á€²á€á€»á€€á€ºá€™á€»á€¬á€¸ ပြပါ
+pdfjs-attachments-button-label = á€á€½á€²á€‘ားá€á€»á€€á€ºá€™á€»á€¬á€¸
+pdfjs-thumbs-button =
+ .title = ပုံရá€á€•á€ºá€„ယ်များကá€á€¯ ပြပါ
+pdfjs-thumbs-button-label = ပုံရá€á€•á€ºá€„ယ်များ
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = ရှာဖွေပါ
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = စာမျက်နှာ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = စာမျက်နှာရဲ့ ပုံရá€á€•á€ºá€„ယ် { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ရှာဖွေပါ
+ .placeholder = စာá€á€™á€ºá€¸á€‘ဲá€á€½á€„် ရှာဖွေရန်…
+pdfjs-find-previous-button =
+ .title = စကားစုရဲ့ အရင် ​ဖြစ်ပွားမှုကá€á€¯ ရှာဖွေပါ
+pdfjs-find-previous-button-label = နောက်သá€á€¯á€·
+pdfjs-find-next-button =
+ .title = စကားစုရဲ့ နောက်ထပ် ​ဖြစ်ပွားမှုကá€á€¯ ရှာဖွေပါ
+pdfjs-find-next-button-label = ရှေ့သá€á€¯á€·
+pdfjs-find-highlight-checkbox = အားလုံးကá€á€¯ မျဉ်းသားပါ
+pdfjs-find-match-case-checkbox-label = စာလုံး á€á€á€¯á€€á€ºá€†á€á€¯á€„်ပါ
+pdfjs-find-reached-top = စာမျက်နှာထá€á€•á€º ရောက်နေပြီአအဆုံးကနေ ပြန်စပါ
+pdfjs-find-reached-bottom = စာမျက်နှာအဆုံး ရောက်နေပြီአထá€á€•á€ºá€€á€”ေ ပြန်စပါ
+pdfjs-find-not-found = စကားစု မá€á€½á€±á€·á€›á€˜á€°á€¸
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = စာမျက်နှာ အကျယ်
+pdfjs-page-scale-fit = စာမျက်နှာ ကွက်á€á€
+pdfjs-page-scale-auto = အလá€á€¯á€¡á€œá€»á€±á€¬á€€á€º á€á€»á€¯á€¶á€·á€á€»á€²á€·
+pdfjs-page-scale-actual = အမှန်á€á€€á€šá€ºá€›á€¾á€á€á€²á€· အရွယ်
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ဖá€á€¯á€„် ကá€á€¯á€†á€½á€²á€á€„်နေá€á€»á€á€”်မှာ အမှားá€á€…်á€á€¯á€á€½á€±á€·á€›á€•á€«á€á€šá€ºá‹
+pdfjs-invalid-file-error = မရသော သá€á€¯á€· ပျက်နေသော PDF ဖá€á€¯á€„်
+pdfjs-missing-file-error = PDF ပျောက်ဆုံး
+pdfjs-unexpected-response-error = မမျှော်လင့်ထားသော ဆာဗာမှ ပြန်ကြားá€á€»á€€á€º
+pdfjs-rendering-error = စာမျက်နှာကá€á€¯ ပုံဖော်နေá€á€»á€á€”်မှာ အမှားá€á€…်á€á€¯á€á€½á€±á€·á€›á€•á€«á€á€šá€ºá‹
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } အဓá€á€•á€¹á€•á€¬á€šá€ºá€–ွင့်ဆá€á€¯á€á€»á€€á€º]
+
+## Password
+
+pdfjs-password-label = ယá€á€¯ PDF ကá€á€¯ ဖွင့်ရန် စကားá€á€¾á€€á€ºá€€á€á€¯ ရá€á€¯á€€á€ºá€•á€«á‹
+pdfjs-password-invalid = စာá€á€¾á€€á€º မှားသည်ዠထပ်ကြá€á€¯á€¸á€…ားကြည့်ပါá‹
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = ပယ်​ဖျက်ပါ
+pdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/nb-NO/viewer.ftl b/www/lib/pdfjs/modern/web/locale/nb-NO/viewer.ftl
new file mode 100644
index 000000000..10e64da28
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/nb-NO/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Forrige side
+pdfjs-previous-button-label = Forrige
+pdfjs-next-button =
+ .title = Neste side
+pdfjs-next-button-label = Neste
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Side
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = av { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } av { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom ut
+pdfjs-zoom-out-button-label = Zoom ut
+pdfjs-zoom-in-button =
+ .title = Zoom inn
+pdfjs-zoom-in-button-label = Zoom inn
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Bytt til presentasjonsmodus
+pdfjs-presentation-mode-button-label = Presentasjonsmodus
+pdfjs-open-file-button =
+ .title = Ã…pne fil
+pdfjs-open-file-button-label = Ã…pne
+pdfjs-print-button =
+ .title = Skriv ut
+pdfjs-print-button-label = Skriv ut
+pdfjs-save-button =
+ .title = Lagre
+pdfjs-save-button-label = Lagre
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Last ned
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Last ned
+pdfjs-bookmark-button =
+ .title = Gjeldende side (se URL fra gjeldende side)
+pdfjs-bookmark-button-label = Gjeldende side
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Ã…pne i app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Ã…pne i app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Verktøy
+pdfjs-tools-button-label = Verktøy
+pdfjs-first-page-button =
+ .title = Gå til første side
+pdfjs-first-page-button-label = Gå til første side
+pdfjs-last-page-button =
+ .title = GÃ¥ til siste side
+pdfjs-last-page-button-label = GÃ¥ til siste side
+pdfjs-page-rotate-cw-button =
+ .title = Roter med klokken
+pdfjs-page-rotate-cw-button-label = Roter med klokken
+pdfjs-page-rotate-ccw-button =
+ .title = Roter mot klokken
+pdfjs-page-rotate-ccw-button-label = Roter mot klokken
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktiver tekstmarkeringsverktøy
+pdfjs-cursor-text-select-tool-button-label = Tekstmarkeringsverktøy
+pdfjs-cursor-hand-tool-button =
+ .title = Aktiver handverktøy
+pdfjs-cursor-hand-tool-button-label = Handverktøy
+pdfjs-scroll-page-button =
+ .title = Bruk siderulling
+pdfjs-scroll-page-button-label = Siderulling
+pdfjs-scroll-vertical-button =
+ .title = Bruk vertikal rulling
+pdfjs-scroll-vertical-button-label = Vertikal rulling
+pdfjs-scroll-horizontal-button =
+ .title = Bruk horisontal rulling
+pdfjs-scroll-horizontal-button-label = Horisontal rulling
+pdfjs-scroll-wrapped-button =
+ .title = Bruk flersiderulling
+pdfjs-scroll-wrapped-button-label = Flersiderulling
+pdfjs-spread-none-button =
+ .title = Vis enkeltsider
+pdfjs-spread-none-button-label = Enkeltsider
+pdfjs-spread-odd-button =
+ .title = Vis oppslag med ulike sidenumre til venstre
+pdfjs-spread-odd-button-label = Oppslag med forside
+pdfjs-spread-even-button =
+ .title = Vis oppslag med like sidenumre til venstre
+pdfjs-spread-even-button-label = Oppslag uten forside
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentegenskaper …
+pdfjs-document-properties-button-label = Dokumentegenskaper …
+pdfjs-document-properties-file-name = Filnavn:
+pdfjs-document-properties-file-size = Filstørrelse:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Dokumentegenskaper …
+pdfjs-document-properties-author = Forfatter:
+pdfjs-document-properties-subject = Emne:
+pdfjs-document-properties-keywords = Nøkkelord:
+pdfjs-document-properties-creation-date = Opprettet dato:
+pdfjs-document-properties-modification-date = Endret dato:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Opprettet av:
+pdfjs-document-properties-producer = PDF-verktøy:
+pdfjs-document-properties-version = PDF-versjon:
+pdfjs-document-properties-page-count = Sideantall:
+pdfjs-document-properties-page-size = Sidestørrelse:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = stående
+pdfjs-document-properties-page-size-orientation-landscape = liggende
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Hurtig nettvisning:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nei
+pdfjs-document-properties-close-button = Lukk
+
+## Print
+
+pdfjs-print-progress-message = Forbereder dokument for utskrift …
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Avbryt
+pdfjs-printing-not-supported = Advarsel: Utskrift er ikke fullstendig støttet av denne nettleseren.
+pdfjs-printing-not-ready = Advarsel: PDF er ikke fullstendig innlastet for utskrift.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Slå av/på sidestolpe
+pdfjs-toggle-sidebar-notification-button =
+ .title = Vis/gjem sidestolpe (dokumentet inneholder oversikt/vedlegg/lag)
+pdfjs-toggle-sidebar-button-label = Slå av/på sidestolpe
+pdfjs-document-outline-button =
+ .title = Vis dokumentdisposisjonen (dobbeltklikk for å utvide/skjule alle elementer)
+pdfjs-document-outline-button-label = Dokumentdisposisjon
+pdfjs-attachments-button =
+ .title = Vis vedlegg
+pdfjs-attachments-button-label = Vedlegg
+pdfjs-layers-button =
+ .title = Vis lag (dobbeltklikk for å tilbakestille alle lag til standardtilstand)
+pdfjs-layers-button-label = Lag
+pdfjs-thumbs-button =
+ .title = Vis miniatyrbilde
+pdfjs-thumbs-button-label = Miniatyrbilde
+pdfjs-current-outline-item-button =
+ .title = Finn gjeldende disposisjonselement
+pdfjs-current-outline-item-button-label = Gjeldende disposisjonselement
+pdfjs-findbar-button =
+ .title = Finn i dokumentet
+pdfjs-findbar-button-label = Finn
+pdfjs-additional-layers = Ytterligere lag
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Side { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatyrbilde av side { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Søk
+ .placeholder = Søk i dokument…
+pdfjs-find-previous-button =
+ .title = Finn forrige forekomst av frasen
+pdfjs-find-previous-button-label = Forrige
+pdfjs-find-next-button =
+ .title = Finn neste forekomst av frasen
+pdfjs-find-next-button-label = Neste
+pdfjs-find-highlight-checkbox = Uthev alle
+pdfjs-find-match-case-checkbox-label = Skill store/små bokstaver
+pdfjs-find-match-diacritics-checkbox-label = Samsvar diakritiske tegn
+pdfjs-find-entire-word-checkbox-label = Hele ord
+pdfjs-find-reached-top = NÃ¥dde toppen av dokumentet, fortsetter fra bunnen
+pdfjs-find-reached-bottom = NÃ¥dde bunnen av dokumentet, fortsetter fra toppen
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } av { $total } treff
+ *[other] { $current } av { $total } treff
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mer enn { $limit } treff
+ *[other] Mer enn { $limit } treff
+ }
+pdfjs-find-not-found = Fant ikke teksten
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sidebredde
+pdfjs-page-scale-fit = Tilpass til siden
+pdfjs-page-scale-auto = Automatisk zoom
+pdfjs-page-scale-actual = Virkelig størrelse
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Side { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = En feil oppstod ved lasting av PDF.
+pdfjs-invalid-file-error = Ugyldig eller skadet PDF-fil.
+pdfjs-missing-file-error = Manglende PDF-fil.
+pdfjs-unexpected-response-error = Uventet serverrespons.
+pdfjs-rendering-error = En feil oppstod ved opptegning av siden.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } annotasjon]
+
+## Password
+
+pdfjs-password-label = Skriv inn passordet for å åpne denne PDF-filen.
+pdfjs-password-invalid = Ugyldig passord. Prøv igjen.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Avbryt
+pdfjs-web-fonts-disabled = Web-fonter er avslått: Kan ikke bruke innbundne PDF-fonter.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Tegn
+pdfjs-editor-ink-button-label = Tegn
+pdfjs-editor-stamp-button =
+ .title = Legg til eller rediger bilder
+pdfjs-editor-stamp-button-label = Legg til eller rediger bilder
+pdfjs-editor-remove-button =
+ .title = Fjern
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Fjern tegningen
+pdfjs-editor-remove-freetext-button =
+ .title = Fjern tekst
+pdfjs-editor-remove-stamp-button =
+ .title = Fjern bildet
+pdfjs-editor-remove-highlight-button =
+ .title = Fjern utheving
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Farge
+pdfjs-editor-free-text-size-input = Størrelse
+pdfjs-editor-ink-color-input = Farge
+pdfjs-editor-ink-thickness-input = Tykkelse
+pdfjs-editor-ink-opacity-input = Ugjennomsiktighet
+pdfjs-editor-stamp-add-image-button =
+ .title = Legg til bilde
+pdfjs-editor-stamp-add-image-button-label = Legg til bilde
+pdfjs-free-text =
+ .aria-label = Tekstredigering
+pdfjs-free-text-default-content = Begynn å skrive…
+pdfjs-ink =
+ .aria-label = Tegneredigering
+pdfjs-ink-canvas =
+ .aria-label = Brukerskapt bilde
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alt-tekst
+pdfjs-editor-alt-text-edit-button-label = Rediger alt-tekst tekst
+pdfjs-editor-alt-text-dialog-label = Velg et alternativ
+pdfjs-editor-alt-text-dialog-description = Alt-tekst (alternativ tekst) hjelper når folk ikke kan se bildet eller når det ikke lastes inn.
+pdfjs-editor-alt-text-add-description-label = Legg til en beskrivelse
+pdfjs-editor-alt-text-add-description-description = GÃ¥ etter 1-2 setninger som beskriver emnet, settingen eller handlingene.
+pdfjs-editor-alt-text-mark-decorative-label = Merk som dekorativt
+pdfjs-editor-alt-text-mark-decorative-description = Dette brukes til dekorative bilder, som kantlinjer eller vannmerker.
+pdfjs-editor-alt-text-cancel-button = Avbryt
+pdfjs-editor-alt-text-save-button = Lagre
+pdfjs-editor-alt-text-decorative-tooltip = Merket som dekorativ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = For eksempel, «En ung mann setter seg ved et bord for å spise et måltid»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Øverste venstre hjørne – endre størrelse
+pdfjs-editor-resizer-label-top-middle = Øverst i midten — endre størrelse
+pdfjs-editor-resizer-label-top-right = Øverste høyre hjørne – endre størrelse
+pdfjs-editor-resizer-label-middle-right = Midt til høyre – endre størrelse
+pdfjs-editor-resizer-label-bottom-right = Nederste høyre hjørne – endre størrelse
+pdfjs-editor-resizer-label-bottom-middle = Nederst i midten — endre størrelse
+pdfjs-editor-resizer-label-bottom-left = Nederste venstre hjørne – endre størrelse
+pdfjs-editor-resizer-label-middle-left = Midt til venstre — endre størrelse
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Uthevingsfarge
+pdfjs-editor-colorpicker-button =
+ .title = Endre farge
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Fargevalg
+pdfjs-editor-colorpicker-yellow =
+ .title = Gul
+pdfjs-editor-colorpicker-green =
+ .title = Grønn
+pdfjs-editor-colorpicker-blue =
+ .title = Blå
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Rød
diff --git a/www/lib/pdfjs/modern/web/locale/ne-NP/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ne-NP/viewer.ftl
new file mode 100644
index 000000000..65193b6e8
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ne-NP/viewer.ftl
@@ -0,0 +1,234 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = अघिलà¥à¤²à¥‹ पृषà¥à¤
+pdfjs-previous-button-label = अघिलà¥à¤²à¥‹
+pdfjs-next-button =
+ .title = पछिलà¥à¤²à¥‹ पृषà¥à¤
+pdfjs-next-button-label = पछिलà¥à¤²à¥‹
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = पृषà¥à¤
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } मधà¥à¤¯à¥‡
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pagesCount } को { $pageNumber })
+pdfjs-zoom-out-button =
+ .title = जà¥à¤® घटाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-zoom-out-button-label = जà¥à¤® घटाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-zoom-in-button =
+ .title = जà¥à¤® बढाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-zoom-in-button-label = जà¥à¤® बढाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-zoom-select =
+ .title = जà¥à¤® गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-presentation-mode-button =
+ .title = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿ मोडमा जानà¥à¤¹à¥‹à¤¸à¥
+pdfjs-presentation-mode-button-label = पà¥à¤°à¤¸à¥à¤¤à¥à¤¤à¤¿ मोड
+pdfjs-open-file-button =
+ .title = फाइल खोलà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-open-file-button-label = खोलà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-print-button =
+ .title = मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-print-button-label = मà¥à¤¦à¥à¤°à¤£ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = औजारहरू
+pdfjs-tools-button-label = औजारहरू
+pdfjs-first-page-button =
+ .title = पहिलो पृषà¥à¤ मा जानà¥à¤¹à¥‹à¤¸à¥
+pdfjs-first-page-button-label = पहिलो पृषà¥à¤ मा जानà¥à¤¹à¥‹à¤¸à¥
+pdfjs-last-page-button =
+ .title = पछिलà¥à¤²à¥‹ पृषà¥à¤ मा जानà¥à¤¹à¥‹à¤¸à¥
+pdfjs-last-page-button-label = पछिलà¥à¤²à¥‹ पृषà¥à¤ मा जानà¥à¤¹à¥‹à¤¸à¥
+pdfjs-page-rotate-cw-button =
+ .title = घडीको दिशामा घà¥à¤®à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-page-rotate-cw-button-label = घडीको दिशामा घà¥à¤®à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-page-rotate-ccw-button =
+ .title = घडीको विपरित दिशामा घà¥à¤®à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-page-rotate-ccw-button-label = घडीको विपरित दिशामा घà¥à¤®à¤¾à¤‰à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-cursor-text-select-tool-button =
+ .title = पाठचयन उपकरण सकà¥à¤·à¤® गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-cursor-text-select-tool-button-label = पाठचयन उपकरण
+pdfjs-cursor-hand-tool-button =
+ .title = हाते उपकरण सकà¥à¤·à¤® गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-cursor-hand-tool-button-label = हाते उपकरण
+pdfjs-scroll-vertical-button =
+ .title = ठाडो सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤— पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-scroll-vertical-button-label = ठाडो सà¥à¤•à¥à¤°à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤—
+pdfjs-scroll-horizontal-button =
+ .title = तेरà¥à¤¸à¥‹ सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤— पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-scroll-horizontal-button-label = तेरà¥à¤¸à¥‹ सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤—
+pdfjs-scroll-wrapped-button =
+ .title = लिपि सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤— पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-scroll-wrapped-button-label = लिपि सà¥à¤•à¥à¤°à¥‹à¤²à¤¿à¤™à¥à¤—
+pdfjs-spread-none-button =
+ .title = पृषà¥à¤ सà¥à¤ªà¥à¤°à¥‡à¤¡à¤®à¤¾ सामेल हà¥à¤¨à¥à¤¹à¥à¤¨à¥à¤¨
+pdfjs-spread-none-button-label = सà¥à¤ªà¥à¤°à¥‡à¤¡ छैन
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = कागजात विशेषताहरू...
+pdfjs-document-properties-button-label = कागजात विशेषताहरू...
+pdfjs-document-properties-file-name = फाइल नाम:
+pdfjs-document-properties-file-size = फाइल आकार:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = शीरà¥à¤·à¤•:
+pdfjs-document-properties-author = लेखक:
+pdfjs-document-properties-subject = विषयः
+pdfjs-document-properties-keywords = शबà¥à¤¦à¤•à¥à¤žà¥à¤œà¥€à¤ƒ
+pdfjs-document-properties-creation-date = सिरà¥à¤œà¤¨à¤¾ गरिà¤à¤•à¥‹ मिति:
+pdfjs-document-properties-modification-date = परिमारà¥à¤œà¤¿à¤¤ मिति:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = सरà¥à¤œà¤•:
+pdfjs-document-properties-producer = PDF निरà¥à¤®à¤¾à¤¤à¤¾:
+pdfjs-document-properties-version = PDF संसà¥à¤•à¤°à¤£
+pdfjs-document-properties-page-count = पृषà¥à¤ गणना:
+pdfjs-document-properties-page-size = पृषà¥à¤ आकार:
+pdfjs-document-properties-page-size-unit-inches = इनà¥à¤š
+pdfjs-document-properties-page-size-unit-millimeters = मि.मि.
+pdfjs-document-properties-page-size-orientation-portrait = पोटà¥à¤°à¥‡à¤Ÿ
+pdfjs-document-properties-page-size-orientation-landscape = परिदृशà¥à¤¯
+pdfjs-document-properties-page-size-name-letter = अकà¥à¤·à¤°
+pdfjs-document-properties-page-size-name-legal = कानूनी
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-linearized-yes = हो
+pdfjs-document-properties-linearized-no = होइन
+pdfjs-document-properties-close-button = बनà¥à¤¦ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+
+## Print
+
+pdfjs-print-progress-message = मà¥à¤¦à¥à¤°à¤£à¤•à¤¾ लागि कागजात तयारी गरिदै…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = रदà¥à¤¦ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-printing-not-supported = चेतावनी: यो बà¥à¤°à¤¾à¤‰à¤œà¤°à¤®à¤¾ मà¥à¤¦à¥à¤°à¤£ पूरà¥à¤£à¤¤à¤¯à¤¾ समरà¥à¤¥à¤¿à¤¤ छैन।
+pdfjs-printing-not-ready = चेतावनी: PDF मà¥à¤¦à¥à¤°à¤£à¤•à¤¾ लागि पूरà¥à¤£à¤¤à¤¯à¤¾ लोड à¤à¤à¤•à¥‹ छैन।
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = टगल साइडबार
+pdfjs-toggle-sidebar-button-label = टगल साइडबार
+pdfjs-document-outline-button =
+ .title = कागजातको रूपरेखा देखाउनà¥à¤¹à¥‹à¤¸à¥ (सबै वसà¥à¤¤à¥à¤¹à¤°à¥‚ विसà¥à¤¤à¤¾à¤°/पतन गरà¥à¤¨ डबल-कà¥à¤²à¤¿à¤• गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥)
+pdfjs-document-outline-button-label = दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤•à¥‹ रूपरेखा
+pdfjs-attachments-button =
+ .title = संलगà¥à¤¨à¤¹à¤°à¥‚ देखाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-attachments-button-label = संलगà¥à¤¨à¤•à¤¹à¤°à¥‚
+pdfjs-thumbs-button =
+ .title = थमà¥à¤¬à¤¨à¥‡à¤²à¤¹à¤°à¥‚ देखाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-thumbs-button-label = थमà¥à¤¬à¤¨à¥‡à¤²à¤¹à¤°à¥‚
+pdfjs-findbar-button =
+ .title = कागजातमा फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-findbar-button-label = फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = पृषà¥à¤ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } पृषà¥à¤ को थमà¥à¤¬à¤¨à¥‡à¤²
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+ .placeholder = कागजातमा फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥â€¦
+pdfjs-find-previous-button =
+ .title = यस वाकà¥à¤¯à¤¾à¤‚शको अघिलà¥à¤²à¥‹ घटना फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-find-previous-button-label = अघिलà¥à¤²à¥‹
+pdfjs-find-next-button =
+ .title = यस वाकà¥à¤¯à¤¾à¤‚शको पछिलà¥à¤²à¥‹ घटना फेला पारà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-find-next-button-label = अरà¥à¤•à¥‹
+pdfjs-find-highlight-checkbox = सबै हाइलाइट गरà¥à¤¨à¥‡
+pdfjs-find-match-case-checkbox-label = केस जोडा मिलाउनà¥à¤¹à¥‹à¤¸à¥
+pdfjs-find-entire-word-checkbox-label = पà¥à¤°à¤¾ शबà¥à¤¦à¤¹à¤°à¥
+pdfjs-find-reached-top = पृषà¥à¤ को शिरà¥à¤·à¤®à¤¾ पà¥à¤—ीयो, तलबाट जारी गरिà¤à¤•à¥‹ थियो
+pdfjs-find-reached-bottom = पृषà¥à¤ को अनà¥à¤¤à¥à¤¯à¤®à¤¾ पà¥à¤—ीयो, शिरà¥à¤·à¤¬à¤¾à¤Ÿ जारी गरिà¤à¤•à¥‹ थियो
+pdfjs-find-not-found = वाकà¥à¤¯à¤¾à¤‚श फेला परेन
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = पृषà¥à¤ चौडाइ
+pdfjs-page-scale-fit = पृषà¥à¤ ठिकà¥à¤• मिलà¥à¤¨à¥‡
+pdfjs-page-scale-auto = सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ जà¥à¤®
+pdfjs-page-scale-actual = वासà¥à¤¤à¤µà¤¿à¤• आकार
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = यो PDF लोड गरà¥à¤¦à¤¾ à¤à¤‰à¤Ÿà¤¾ तà¥à¤°à¥à¤Ÿà¤¿ देखापरà¥â€à¤¯à¥‹à¥¤
+pdfjs-invalid-file-error = अवैध वा दà¥à¤·à¤¿à¤¤ PDF फाइल।
+pdfjs-missing-file-error = हराईरहेको PDF फाइल।
+pdfjs-unexpected-response-error = अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ सरà¥à¤à¤° पà¥à¤°à¤¤à¤¿à¤•à¥à¤°à¤¿à¤¯à¤¾à¥¤
+pdfjs-rendering-error = पृषà¥à¤ पà¥à¤°à¤¤à¤¿à¤ªà¤¾à¤¦à¤¨ गरà¥à¤¦à¤¾ à¤à¤‰à¤Ÿà¤¾ तà¥à¤°à¥à¤Ÿà¤¿ देखापरà¥â€à¤¯à¥‹à¥¤
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = यस PDF फाइललाई खोलà¥à¤¨ गोपà¥à¤¯à¤¶à¤¬à¥à¤¦ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤
+pdfjs-password-invalid = अवैध गोपà¥à¤¯à¤¶à¤¬à¥à¤¦à¥¤ पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥à¥¤
+pdfjs-password-ok-button = ठिक छ
+pdfjs-password-cancel-button = रदà¥à¤¦ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+pdfjs-web-fonts-disabled = वेब फनà¥à¤Ÿ असकà¥à¤·à¤® छनà¥: à¤à¤®à¥à¤¬à¥‡à¤¡à¥‡à¤¡ PDF फनà¥à¤Ÿ पà¥à¤°à¤¯à¥‹à¤— गरà¥à¤¨ असमरà¥à¤¥à¥¤
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/nl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/nl/viewer.ftl
new file mode 100644
index 000000000..e5535c0e1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/nl/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Vorige pagina
+pdfjs-previous-button-label = Vorige
+pdfjs-next-button =
+ .title = Volgende pagina
+pdfjs-next-button-label = Volgende
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = van { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } van { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Uitzoomen
+pdfjs-zoom-out-button-label = Uitzoomen
+pdfjs-zoom-in-button =
+ .title = Inzoomen
+pdfjs-zoom-in-button-label = Inzoomen
+pdfjs-zoom-select =
+ .title = Zoomen
+pdfjs-presentation-mode-button =
+ .title = Wisselen naar presentatiemodus
+pdfjs-presentation-mode-button-label = Presentatiemodus
+pdfjs-open-file-button =
+ .title = Bestand openen
+pdfjs-open-file-button-label = Openen
+pdfjs-print-button =
+ .title = Afdrukken
+pdfjs-print-button-label = Afdrukken
+pdfjs-save-button =
+ .title = Opslaan
+pdfjs-save-button-label = Opslaan
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Downloaden
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Downloaden
+pdfjs-bookmark-button =
+ .title = Huidige pagina (URL van huidige pagina bekijken)
+pdfjs-bookmark-button-label = Huidige pagina
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Openen in app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Openen in app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Hulpmiddelen
+pdfjs-tools-button-label = Hulpmiddelen
+pdfjs-first-page-button =
+ .title = Naar eerste pagina gaan
+pdfjs-first-page-button-label = Naar eerste pagina gaan
+pdfjs-last-page-button =
+ .title = Naar laatste pagina gaan
+pdfjs-last-page-button-label = Naar laatste pagina gaan
+pdfjs-page-rotate-cw-button =
+ .title = Rechtsom draaien
+pdfjs-page-rotate-cw-button-label = Rechtsom draaien
+pdfjs-page-rotate-ccw-button =
+ .title = Linksom draaien
+pdfjs-page-rotate-ccw-button-label = Linksom draaien
+pdfjs-cursor-text-select-tool-button =
+ .title = Tekstselectiehulpmiddel inschakelen
+pdfjs-cursor-text-select-tool-button-label = Tekstselectiehulpmiddel
+pdfjs-cursor-hand-tool-button =
+ .title = Handhulpmiddel inschakelen
+pdfjs-cursor-hand-tool-button-label = Handhulpmiddel
+pdfjs-scroll-page-button =
+ .title = Paginascrollen gebruiken
+pdfjs-scroll-page-button-label = Paginascrollen
+pdfjs-scroll-vertical-button =
+ .title = Verticaal scrollen gebruiken
+pdfjs-scroll-vertical-button-label = Verticaal scrollen
+pdfjs-scroll-horizontal-button =
+ .title = Horizontaal scrollen gebruiken
+pdfjs-scroll-horizontal-button-label = Horizontaal scrollen
+pdfjs-scroll-wrapped-button =
+ .title = Scrollen met terugloop gebruiken
+pdfjs-scroll-wrapped-button-label = Scrollen met terugloop
+pdfjs-spread-none-button =
+ .title = Dubbele pagina’s niet samenvoegen
+pdfjs-spread-none-button-label = Geen dubbele pagina’s
+pdfjs-spread-odd-button =
+ .title = Dubbele pagina’s samenvoegen vanaf oneven pagina’s
+pdfjs-spread-odd-button-label = Oneven dubbele pagina’s
+pdfjs-spread-even-button =
+ .title = Dubbele pagina’s samenvoegen vanaf even pagina’s
+pdfjs-spread-even-button-label = Even dubbele pagina’s
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Documenteigenschappen…
+pdfjs-document-properties-button-label = Documenteigenschappen…
+pdfjs-document-properties-file-name = Bestandsnaam:
+pdfjs-document-properties-file-size = Bestandsgrootte:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Auteur:
+pdfjs-document-properties-subject = Onderwerp:
+pdfjs-document-properties-keywords = Sleutelwoorden:
+pdfjs-document-properties-creation-date = Aanmaakdatum:
+pdfjs-document-properties-modification-date = Wijzigingsdatum:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Maker:
+pdfjs-document-properties-producer = PDF-producent:
+pdfjs-document-properties-version = PDF-versie:
+pdfjs-document-properties-page-count = Aantal pagina’s:
+pdfjs-document-properties-page-size = Paginagrootte:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = staand
+pdfjs-document-properties-page-size-orientation-landscape = liggend
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Snelle webweergave:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nee
+pdfjs-document-properties-close-button = Sluiten
+
+## Print
+
+pdfjs-print-progress-message = Document voorbereiden voor afdrukken…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Annuleren
+pdfjs-printing-not-supported = Waarschuwing: afdrukken wordt niet volledig ondersteund door deze browser.
+pdfjs-printing-not-ready = Waarschuwing: de PDF is niet volledig geladen voor afdrukken.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Zijbalk in-/uitschakelen
+pdfjs-toggle-sidebar-notification-button =
+ .title = Zijbalk in-/uitschakelen (document bevat overzicht/bijlagen/lagen)
+pdfjs-toggle-sidebar-button-label = Zijbalk in-/uitschakelen
+pdfjs-document-outline-button =
+ .title = Documentoverzicht tonen (dubbelklik om alle items uit/samen te vouwen)
+pdfjs-document-outline-button-label = Documentoverzicht
+pdfjs-attachments-button =
+ .title = Bijlagen tonen
+pdfjs-attachments-button-label = Bijlagen
+pdfjs-layers-button =
+ .title = Lagen tonen (dubbelklik om alle lagen naar de standaardstatus terug te zetten)
+pdfjs-layers-button-label = Lagen
+pdfjs-thumbs-button =
+ .title = Miniaturen tonen
+pdfjs-thumbs-button-label = Miniaturen
+pdfjs-current-outline-item-button =
+ .title = Huidig item in inhoudsopgave zoeken
+pdfjs-current-outline-item-button-label = Huidig item in inhoudsopgave
+pdfjs-findbar-button =
+ .title = Zoeken in document
+pdfjs-findbar-button-label = Zoeken
+pdfjs-additional-layers = Aanvullende lagen
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatuur van pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Zoeken
+ .placeholder = Zoeken in document…
+pdfjs-find-previous-button =
+ .title = De vorige overeenkomst van de tekst zoeken
+pdfjs-find-previous-button-label = Vorige
+pdfjs-find-next-button =
+ .title = De volgende overeenkomst van de tekst zoeken
+pdfjs-find-next-button-label = Volgende
+pdfjs-find-highlight-checkbox = Alles markeren
+pdfjs-find-match-case-checkbox-label = Hoofdlettergevoelig
+pdfjs-find-match-diacritics-checkbox-label = Diakritische tekens gebruiken
+pdfjs-find-entire-word-checkbox-label = Hele woorden
+pdfjs-find-reached-top = Bovenkant van document bereikt, doorgegaan vanaf onderkant
+pdfjs-find-reached-bottom = Onderkant van document bereikt, doorgegaan vanaf bovenkant
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } van { $total } overeenkomst
+ *[other] { $current } van { $total } overeenkomsten
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Meer dan { $limit } overeenkomst
+ *[other] Meer dan { $limit } overeenkomsten
+ }
+pdfjs-find-not-found = Tekst niet gevonden
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Paginabreedte
+pdfjs-page-scale-fit = Hele pagina
+pdfjs-page-scale-auto = Automatisch zoomen
+pdfjs-page-scale-actual = Werkelijke grootte
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Er is een fout opgetreden bij het laden van de PDF.
+pdfjs-invalid-file-error = Ongeldig of beschadigd PDF-bestand.
+pdfjs-missing-file-error = PDF-bestand ontbreekt.
+pdfjs-unexpected-response-error = Onverwacht serverantwoord.
+pdfjs-rendering-error = Er is een fout opgetreden bij het weergeven van de pagina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-aantekening]
+
+## Password
+
+pdfjs-password-label = Voer het wachtwoord in om dit PDF-bestand te openen.
+pdfjs-password-invalid = Ongeldig wachtwoord. Probeer het opnieuw.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Annuleren
+pdfjs-web-fonts-disabled = Weblettertypen zijn uitgeschakeld: gebruik van ingebedde PDF-lettertypen is niet mogelijk.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Tekenen
+pdfjs-editor-ink-button-label = Tekenen
+pdfjs-editor-stamp-button =
+ .title = Afbeeldingen toevoegen of bewerken
+pdfjs-editor-stamp-button-label = Afbeeldingen toevoegen of bewerken
+pdfjs-editor-remove-button =
+ .title = Verwijderen
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Tekening verwijderen
+pdfjs-editor-remove-freetext-button =
+ .title = Tekst verwijderen
+pdfjs-editor-remove-stamp-button =
+ .title = Afbeelding verwijderen
+pdfjs-editor-remove-highlight-button =
+ .title = Markering verwijderen
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Kleur
+pdfjs-editor-free-text-size-input = Grootte
+pdfjs-editor-ink-color-input = Kleur
+pdfjs-editor-ink-thickness-input = Dikte
+pdfjs-editor-ink-opacity-input = Opaciteit
+pdfjs-editor-stamp-add-image-button =
+ .title = Afbeelding toevoegen
+pdfjs-editor-stamp-add-image-button-label = Afbeelding toevoegen
+pdfjs-free-text =
+ .aria-label = Tekstbewerker
+pdfjs-free-text-default-content = Begin met typen…
+pdfjs-ink =
+ .aria-label = Tekeningbewerker
+pdfjs-ink-canvas =
+ .aria-label = Door gebruiker gemaakte afbeelding
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternatieve tekst
+pdfjs-editor-alt-text-edit-button-label = Alternatieve tekst bewerken
+pdfjs-editor-alt-text-dialog-label = Kies een optie
+pdfjs-editor-alt-text-dialog-description = Alternatieve tekst helpt wanneer mensen de afbeelding niet kunnen zien of wanneer deze niet wordt geladen.
+pdfjs-editor-alt-text-add-description-label = Voeg een beschrijving toe
+pdfjs-editor-alt-text-add-description-description = Streef naar 1-2 zinnen die het onderwerp, de omgeving of de acties beschrijven.
+pdfjs-editor-alt-text-mark-decorative-label = Als decoratief markeren
+pdfjs-editor-alt-text-mark-decorative-description = Dit wordt gebruikt voor sierafbeeldingen, zoals randen of watermerken.
+pdfjs-editor-alt-text-cancel-button = Annuleren
+pdfjs-editor-alt-text-save-button = Opslaan
+pdfjs-editor-alt-text-decorative-tooltip = Als decoratief gemarkeerd
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Bijvoorbeeld: ‘Een jonge man gaat aan een tafel zitten om te eten’
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Linkerbovenhoek – formaat wijzigen
+pdfjs-editor-resizer-label-top-middle = Midden boven – formaat wijzigen
+pdfjs-editor-resizer-label-top-right = Rechterbovenhoek – formaat wijzigen
+pdfjs-editor-resizer-label-middle-right = Midden rechts – formaat wijzigen
+pdfjs-editor-resizer-label-bottom-right = Rechterbenedenhoek – formaat wijzigen
+pdfjs-editor-resizer-label-bottom-middle = Midden onder – formaat wijzigen
+pdfjs-editor-resizer-label-bottom-left = Linkerbenedenhoek – formaat wijzigen
+pdfjs-editor-resizer-label-middle-left = Links midden – formaat wijzigen
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Markeringskleur
+pdfjs-editor-colorpicker-button =
+ .title = Kleur wijzigen
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Kleurkeuzes
+pdfjs-editor-colorpicker-yellow =
+ .title = Geel
+pdfjs-editor-colorpicker-green =
+ .title = Groen
+pdfjs-editor-colorpicker-blue =
+ .title = Blauw
+pdfjs-editor-colorpicker-pink =
+ .title = Roze
+pdfjs-editor-colorpicker-red =
+ .title = Rood
diff --git a/www/lib/pdfjs/modern/web/locale/nn-NO/viewer.ftl b/www/lib/pdfjs/modern/web/locale/nn-NO/viewer.ftl
new file mode 100644
index 000000000..166530dc3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/nn-NO/viewer.ftl
@@ -0,0 +1,343 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Føregåande side
+pdfjs-previous-button-label = Føregåande
+pdfjs-next-button =
+ .title = Neste side
+pdfjs-next-button-label = Neste
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Side
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = av { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } av { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom ut
+pdfjs-zoom-out-button-label = Zoom ut
+pdfjs-zoom-in-button =
+ .title = Zoom inn
+pdfjs-zoom-in-button-label = Zoom inn
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Byt til presentasjonsmodus
+pdfjs-presentation-mode-button-label = Presentasjonsmodus
+pdfjs-open-file-button =
+ .title = Opne fil
+pdfjs-open-file-button-label = Opne
+pdfjs-print-button =
+ .title = Skriv ut
+pdfjs-print-button-label = Skriv ut
+pdfjs-save-button =
+ .title = Lagre
+pdfjs-save-button-label = Lagre
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Last ned
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Last ned
+pdfjs-bookmark-button =
+ .title = Gjeldande side (sjå URL frå gjeldande side)
+pdfjs-bookmark-button-label = Gjeldande side
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Opne i app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Opne i app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Verktøy
+pdfjs-tools-button-label = Verktøy
+pdfjs-first-page-button =
+ .title = Gå til første side
+pdfjs-first-page-button-label = Gå til første side
+pdfjs-last-page-button =
+ .title = GÃ¥ til siste side
+pdfjs-last-page-button-label = GÃ¥ til siste side
+pdfjs-page-rotate-cw-button =
+ .title = Roter med klokka
+pdfjs-page-rotate-cw-button-label = Roter med klokka
+pdfjs-page-rotate-ccw-button =
+ .title = Roter mot klokka
+pdfjs-page-rotate-ccw-button-label = Roter mot klokka
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktiver tekstmarkeringsverktøy
+pdfjs-cursor-text-select-tool-button-label = Tekstmarkeringsverktøy
+pdfjs-cursor-hand-tool-button =
+ .title = Aktiver handverktøy
+pdfjs-cursor-hand-tool-button-label = Handverktøy
+pdfjs-scroll-page-button =
+ .title = Bruk siderulling
+pdfjs-scroll-page-button-label = Siderulling
+pdfjs-scroll-vertical-button =
+ .title = Bruk vertikal rulling
+pdfjs-scroll-vertical-button-label = Vertikal rulling
+pdfjs-scroll-horizontal-button =
+ .title = Bruk horisontal rulling
+pdfjs-scroll-horizontal-button-label = Horisontal rulling
+pdfjs-scroll-wrapped-button =
+ .title = Bruk fleirsiderulling
+pdfjs-scroll-wrapped-button-label = Fleirsiderulling
+pdfjs-spread-none-button =
+ .title = Vis enkeltsider
+pdfjs-spread-none-button-label = Enkeltside
+pdfjs-spread-odd-button =
+ .title = Vis oppslag med ulike sidenummer til venstre
+pdfjs-spread-odd-button-label = Oppslag med framside
+pdfjs-spread-even-button =
+ .title = Vis oppslag med like sidenummmer til venstre
+pdfjs-spread-even-button-label = Oppslag utan framside
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumenteigenskapar…
+pdfjs-document-properties-button-label = Dokumenteigenskapar…
+pdfjs-document-properties-file-name = Filnamn:
+pdfjs-document-properties-file-size = Filstorleik:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Tittel:
+pdfjs-document-properties-author = Forfattar:
+pdfjs-document-properties-subject = Emne:
+pdfjs-document-properties-keywords = Stikkord:
+pdfjs-document-properties-creation-date = Dato oppretta:
+pdfjs-document-properties-modification-date = Dato endra:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Oppretta av:
+pdfjs-document-properties-producer = PDF-verktøy:
+pdfjs-document-properties-version = PDF-versjon:
+pdfjs-document-properties-page-count = Sidetal:
+pdfjs-document-properties-page-size = Sidestørrelse:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = ståande
+pdfjs-document-properties-page-size-orientation-landscape = liggande
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Brev
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Rask nettvising:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nei
+pdfjs-document-properties-close-button = Lat att
+
+## Print
+
+pdfjs-print-progress-message = Førebur dokumentet for utskrift…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Avbryt
+pdfjs-printing-not-supported = Åtvaring: Utskrift er ikkje fullstendig støtta av denne nettlesaren.
+pdfjs-printing-not-ready = Ã…tvaring: PDF ikkje fullstendig innlasta for utskrift.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Slå av/på sidestolpe
+pdfjs-toggle-sidebar-notification-button =
+ .title = Vis/gøym sidestolpe (dokumentet inneheld oversikt/vedlegg/lag)
+pdfjs-toggle-sidebar-button-label = Slå av/på sidestolpe
+pdfjs-document-outline-button =
+ .title = Vis dokumentdisposisjonen (dobbelklikk for å utvide/gøyme alle elementa)
+pdfjs-document-outline-button-label = Dokumentdisposisjon
+pdfjs-attachments-button =
+ .title = Vis vedlegg
+pdfjs-attachments-button-label = Vedlegg
+pdfjs-layers-button =
+ .title = Vis lag (dobbeltklikk for å tilbakestille alle lag til standardtilstand)
+pdfjs-layers-button-label = Lag
+pdfjs-thumbs-button =
+ .title = Vis miniatyrbilde
+pdfjs-thumbs-button-label = Miniatyrbilde
+pdfjs-current-outline-item-button =
+ .title = Finn gjeldande disposisjonselement
+pdfjs-current-outline-item-button-label = Gjeldande disposisjonselement
+pdfjs-findbar-button =
+ .title = Finn i dokumentet
+pdfjs-findbar-button-label = Finn
+pdfjs-additional-layers = Ytterlegare lag
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Side { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatyrbilde av side { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Søk
+ .placeholder = Søk i dokument…
+pdfjs-find-previous-button =
+ .title = Finn førre førekomst av frasen
+pdfjs-find-previous-button-label = Førre
+pdfjs-find-next-button =
+ .title = Finn neste førekomst av frasen
+pdfjs-find-next-button-label = Neste
+pdfjs-find-highlight-checkbox = Uthev alle
+pdfjs-find-match-case-checkbox-label = Skil store/små bokstavar
+pdfjs-find-match-diacritics-checkbox-label = Samsvar diakritiske teikn
+pdfjs-find-entire-word-checkbox-label = Heile ord
+pdfjs-find-reached-top = Nådde toppen av dokumentet, fortset frå botnen
+pdfjs-find-reached-bottom = Nådde botnen av dokumentet, fortset frå toppen
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } av { $total } treff
+ *[other] { $current } av { $total } treff
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Meir enn { $limit } treff
+ *[other] Meir enn { $limit } treff
+ }
+pdfjs-find-not-found = Fann ikkje teksten
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sidebreidde
+pdfjs-page-scale-fit = Tilpass til sida
+pdfjs-page-scale-auto = Automatisk skalering
+pdfjs-page-scale-actual = Verkeleg storleik
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Side { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ein feil oppstod ved lasting av PDF.
+pdfjs-invalid-file-error = Ugyldig eller korrupt PDF-fil.
+pdfjs-missing-file-error = Manglande PDF-fil.
+pdfjs-unexpected-response-error = Uventa tenarrespons.
+pdfjs-rendering-error = Ein feil oppstod under vising av sida.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } annotasjon]
+
+## Password
+
+pdfjs-password-label = Skriv inn passordet for å opne denne PDF-fila.
+pdfjs-password-invalid = Ugyldig passord. Prøv på nytt.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Avbryt
+pdfjs-web-fonts-disabled = Web-skrifter er slått av: Kan ikkje bruke innbundne PDF-skrifter.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Teikne
+pdfjs-editor-ink-button-label = Teikne
+pdfjs-editor-stamp-button =
+ .title = Legg til eller rediger bilde
+pdfjs-editor-stamp-button-label = Legg til eller rediger bilde
+pdfjs-editor-remove-button =
+ .title = Fjern
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Farge
+pdfjs-editor-free-text-size-input = Storleik
+pdfjs-editor-ink-color-input = Farge
+pdfjs-editor-ink-thickness-input = Tjukkleik
+pdfjs-editor-ink-opacity-input = Ugjennomskinleg
+pdfjs-editor-stamp-add-image-button =
+ .title = Legg til bilde
+pdfjs-editor-stamp-add-image-button-label = Legg til bilde
+pdfjs-free-text =
+ .aria-label = Tekstredigering
+pdfjs-free-text-default-content = Byrje å skrive…
+pdfjs-ink =
+ .aria-label = Teikneredigering
+pdfjs-ink-canvas =
+ .aria-label = Brukarskapt bilde
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alt-tekst
+pdfjs-editor-alt-text-edit-button-label = Rediger alt-tekst tekst
+pdfjs-editor-alt-text-dialog-label = Vel eit alternativ
+pdfjs-editor-alt-text-dialog-description = Alt-tekst (alternativ tekst) hjelper når folk ikkje kan sjå bildet eller når det ikkje vert lasta inn.
+pdfjs-editor-alt-text-add-description-label = Legg til ei skildring
+pdfjs-editor-alt-text-add-description-description = GÃ¥ etter 1-2 setninger som skildrar emnet, settinga eller handlingane.
+pdfjs-editor-alt-text-mark-decorative-label = Merk som dekorativt
+pdfjs-editor-alt-text-mark-decorative-description = Dette vert brukt til dekorative bilde, som kantlinjer eller vassmerke.
+pdfjs-editor-alt-text-cancel-button = Avbryt
+pdfjs-editor-alt-text-save-button = Lagre
+pdfjs-editor-alt-text-decorative-tooltip = Merkt som dekorativ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Til dømes, «Ein ung mann set seg ved eit bord for å ete eit måltid»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/oc/viewer.ftl b/www/lib/pdfjs/modern/web/locale/oc/viewer.ftl
new file mode 100644
index 000000000..59500d97c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/oc/viewer.ftl
@@ -0,0 +1,318 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina precedenta
+pdfjs-previous-button-label = Precedent
+pdfjs-next-button =
+ .title = Pagina seguenta
+pdfjs-next-button-label = Seguent
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = sus { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom arrièr
+pdfjs-zoom-out-button-label = Zoom arrièr
+pdfjs-zoom-in-button =
+ .title = Zoom avant
+pdfjs-zoom-in-button-label = Zoom avant
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Bascular en mòde presentacion
+pdfjs-presentation-mode-button-label = Mòde Presentacion
+pdfjs-open-file-button =
+ .title = Dobrir lo fichièr
+pdfjs-open-file-button-label = Dobrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Enregistrar
+pdfjs-save-button-label = Enregistrar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Telecargar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Telecargar
+pdfjs-bookmark-button =
+ .title = Pagina actuala (mostrar l’adreça de la pagina actuala)
+pdfjs-bookmark-button-label = Pagina actuala
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Dobrir amb l’aplicacion
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Dobrir amb l’aplicacion
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Aisinas
+pdfjs-tools-button-label = Aisinas
+pdfjs-first-page-button =
+ .title = Anar a la primièra pagina
+pdfjs-first-page-button-label = Anar a la primièra pagina
+pdfjs-last-page-button =
+ .title = Anar a la darrièra pagina
+pdfjs-last-page-button-label = Anar a la darrièra pagina
+pdfjs-page-rotate-cw-button =
+ .title = Rotacion orà ria
+pdfjs-page-rotate-cw-button-label = Rotacion orà ria
+pdfjs-page-rotate-ccw-button =
+ .title = Rotacion antiorà ria
+pdfjs-page-rotate-ccw-button-label = Rotacion antiorà ria
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar l'aisina de seleccion de tèxte
+pdfjs-cursor-text-select-tool-button-label = Aisina de seleccion de tèxte
+pdfjs-cursor-hand-tool-button =
+ .title = Activar l’aisina man
+pdfjs-cursor-hand-tool-button-label = Aisina man
+pdfjs-scroll-page-button =
+ .title = Activar lo defilament per pagina
+pdfjs-scroll-page-button-label = Defilament per pagina
+pdfjs-scroll-vertical-button =
+ .title = Utilizar lo defilament vertical
+pdfjs-scroll-vertical-button-label = Defilament vertical
+pdfjs-scroll-horizontal-button =
+ .title = Utilizar lo defilament orizontal
+pdfjs-scroll-horizontal-button-label = Defilament orizontal
+pdfjs-scroll-wrapped-button =
+ .title = Activar lo defilament continú
+pdfjs-scroll-wrapped-button-label = Defilament continú
+pdfjs-spread-none-button =
+ .title = Agropar pas las paginas doas a doas
+pdfjs-spread-none-button-label = Una sola pagina
+pdfjs-spread-odd-button =
+ .title = Mostrar doas paginas en començant per las paginas imparas a esquèrra
+pdfjs-spread-odd-button-label = Dobla pagina, impara a drecha
+pdfjs-spread-even-button =
+ .title = Mostrar doas paginas en començant per las paginas paras a esquèrra
+pdfjs-spread-even-button-label = Dobla pagina, para a drecha
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Proprietats del document…
+pdfjs-document-properties-button-label = Proprietats del document…
+pdfjs-document-properties-file-name = Nom del fichièr :
+pdfjs-document-properties-file-size = Talha del fichièr :
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } Ko ({ $size_b } octets)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } Mo ({ $size_b } octets)
+pdfjs-document-properties-title = TÃtol :
+pdfjs-document-properties-author = Autor :
+pdfjs-document-properties-subject = Subjècte :
+pdfjs-document-properties-keywords = Mots claus :
+pdfjs-document-properties-creation-date = Data de creacion :
+pdfjs-document-properties-modification-date = Data de modificacion :
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, a { $time }
+pdfjs-document-properties-creator = Creator :
+pdfjs-document-properties-producer = Aisina de conversion PDFÂ :
+pdfjs-document-properties-version = Version PDFÂ :
+pdfjs-document-properties-page-count = Nombre de paginas :
+pdfjs-document-properties-page-size = Talha de la pagina :
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = retrach
+pdfjs-document-properties-page-size-orientation-landscape = païsatge
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letra
+pdfjs-document-properties-page-size-name-legal = Document juridic
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web rapida :
+pdfjs-document-properties-linearized-yes = Ã’c
+pdfjs-document-properties-linearized-no = Non
+pdfjs-document-properties-close-button = Tampar
+
+## Print
+
+pdfjs-print-progress-message = Preparacion del document per l’impression…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Anullar
+pdfjs-printing-not-supported = Atencion : l'impression es pas complètament gerida per aqueste navegador.
+pdfjs-printing-not-ready = Atencion : lo PDF es pas entièrament cargat per lo poder imprimir.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Afichar/amagar lo panèl lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Afichar/amagar lo panèl lateral (lo document conten esquèmas/pèças juntas/calques)
+pdfjs-toggle-sidebar-button-label = Afichar/amagar lo panèl lateral
+pdfjs-document-outline-button =
+ .title = Mostrar los esquèmas del document (dobleclicar per espandre/reduire totes los elements)
+pdfjs-document-outline-button-label = Marcapaginas del document
+pdfjs-attachments-button =
+ .title = Visualizar las pèças juntas
+pdfjs-attachments-button-label = Pèças juntas
+pdfjs-layers-button =
+ .title = Afichar los calques (doble-clicar per reïnicializar totes los calques a l’estat per defaut)
+pdfjs-layers-button-label = Calques
+pdfjs-thumbs-button =
+ .title = Afichar las vinhetas
+pdfjs-thumbs-button-label = Vinhetas
+pdfjs-current-outline-item-button =
+ .title = Trobar l’element de plan actual
+pdfjs-current-outline-item-button-label = Element de plan actual
+pdfjs-findbar-button =
+ .title = Cercar dins lo document
+pdfjs-findbar-button-label = Recercar
+pdfjs-additional-layers = Calques suplementaris
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Vinheta de la pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Recercar
+ .placeholder = Cercar dins lo document…
+pdfjs-find-previous-button =
+ .title = Tròba l'ocurréncia precedenta de la frasa
+pdfjs-find-previous-button-label = Precedent
+pdfjs-find-next-button =
+ .title = Tròba l'ocurréncia venenta de la frasa
+pdfjs-find-next-button-label = Seguent
+pdfjs-find-highlight-checkbox = Suslinhar tot
+pdfjs-find-match-case-checkbox-label = Respectar la cassa
+pdfjs-find-match-diacritics-checkbox-label = Respectar los diacritics
+pdfjs-find-entire-word-checkbox-label = Mots entièrs
+pdfjs-find-reached-top = Naut de la pagina atenh, perseguida del bas
+pdfjs-find-reached-bottom = Bas de la pagina atench, perseguida al començament
+pdfjs-find-not-found = Frasa pas trobada
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Largor plena
+pdfjs-page-scale-fit = Pagina entièra
+pdfjs-page-scale-auto = Zoom automatic
+pdfjs-page-scale-actual = Talha vertadièra
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Una error s'es producha pendent lo cargament del fichièr PDF.
+pdfjs-invalid-file-error = Fichièr PDF invalid o corromput.
+pdfjs-missing-file-error = Fichièr PDF mancant.
+pdfjs-unexpected-response-error = Responsa de servidor imprevista.
+pdfjs-rendering-error = Una error s'es producha pendent l'afichatge de la pagina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } a { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotacion { $type }]
+
+## Password
+
+pdfjs-password-label = Picatz lo senhal per dobrir aqueste fichièr PDF.
+pdfjs-password-invalid = Senhal incorrècte. Tornatz ensajar.
+pdfjs-password-ok-button = D'acòrdi
+pdfjs-password-cancel-button = Anullar
+pdfjs-web-fonts-disabled = Las polissas web son desactivadas : impossible d'utilizar las polissas integradas al PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tèxte
+pdfjs-editor-free-text-button-label = Tèxte
+pdfjs-editor-ink-button =
+ .title = Dessenhar
+pdfjs-editor-ink-button-label = Dessenhar
+pdfjs-editor-stamp-button =
+ .title = Apondre o modificar d’imatges
+pdfjs-editor-stamp-button-label = Apondre o modificar d’imatges
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Color
+pdfjs-editor-free-text-size-input = Talha
+pdfjs-editor-ink-color-input = Color
+pdfjs-editor-ink-thickness-input = Espessor
+pdfjs-editor-ink-opacity-input = Opacitat
+pdfjs-editor-stamp-add-image-button =
+ .title = Apondre imatge
+pdfjs-editor-stamp-add-image-button-label = Apondre imatge
+pdfjs-free-text =
+ .aria-label = Editor de tèxte
+pdfjs-free-text-default-content = Començatz d’escriure…
+pdfjs-ink =
+ .aria-label = Editor de dessenh
+pdfjs-ink-canvas =
+ .aria-label = Imatge creat per l’utilizaire
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Tèxt alternatiu
+pdfjs-editor-alt-text-edit-button-label = Modificar lo tèxt alternatiu
+pdfjs-editor-alt-text-dialog-label = Causir una opcion
+pdfjs-editor-alt-text-add-description-label = Apondre una descripcion
+pdfjs-editor-alt-text-cancel-button = Anullar
+pdfjs-editor-alt-text-save-button = Enregistrar
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/pa-IN/viewer.ftl b/www/lib/pdfjs/modern/web/locale/pa-IN/viewer.ftl
new file mode 100644
index 000000000..678c0f496
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/pa-IN/viewer.ftl
@@ -0,0 +1,363 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ਪਿਛਲਾ ਸਫ਼ਾ
+pdfjs-previous-button-label = ਪਿੱਛੇ
+pdfjs-next-button =
+ .title = ਅਗਲਾ ਸਫ਼ਾ
+pdfjs-next-button-label = ਅੱਗੇ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ਸਫ਼ਾ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } ਵਿੱਚੋਂ
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = { $pagesCount }) ਵਿੱਚੋਂ ({ $pageNumber }
+pdfjs-zoom-out-button =
+ .title = ਜ਼ੂਮ ਆਉਟ
+pdfjs-zoom-out-button-label = ਜ਼ੂਮ ਆਉਟ
+pdfjs-zoom-in-button =
+ .title = ਜ਼ੂਮ ਇਨ
+pdfjs-zoom-in-button-label = ਜ਼ੂਮ ਇਨ
+pdfjs-zoom-select =
+ .title = ਜ਼ੂਨ
+pdfjs-presentation-mode-button =
+ .title = ਪਰਿਜੈਂਟੇਸ਼ਨ ਮੋਡ ਵਿੱਚ ਜਾਓ
+pdfjs-presentation-mode-button-label = ਪਰਿਜੈਂਟੇਸ਼ਨ ਮੋਡ
+pdfjs-open-file-button =
+ .title = ਫਾਈਲ ਨੂੰ ਖੋਲà©à¨¹à©‹
+pdfjs-open-file-button-label = ਖੋਲà©à¨¹à©‹
+pdfjs-print-button =
+ .title = ਪਰਿੰਟ
+pdfjs-print-button-label = ਪਰਿੰਟ
+pdfjs-save-button =
+ .title = ਸੰà¨à¨¾à¨²à©‹
+pdfjs-save-button-label = ਸੰà¨à¨¾à¨²à©‹
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ਡਾਊਨਲੋਡ
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ਡਾਊਨਲੋਡ
+pdfjs-bookmark-button =
+ .title = ਮੌਜੂਦਾ ਸਫ਼਼ਾ (ਮੌਜੂਦਾ ਸਫ਼ੇ ਤੋਂ URL ਵੇਖੋ)
+pdfjs-bookmark-button-label = ਮੌਜੂਦਾ ਸਫ਼਼ਾ
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = à¨à¨ª ਵਿੱਚ ਖੋਲà©à¨¹à©‹
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = à¨à¨ª ਵਿੱਚ ਖੋਲà©à¨¹à©‹
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ਟੂਲ
+pdfjs-tools-button-label = ਟੂਲ
+pdfjs-first-page-button =
+ .title = ਪਹਿਲੇ ਸਫ਼ੇ ਉੱਤੇ ਜਾਓ
+pdfjs-first-page-button-label = ਪਹਿਲੇ ਸਫ਼ੇ ਉੱਤੇ ਜਾਓ
+pdfjs-last-page-button =
+ .title = ਆਖਰੀ ਸਫ਼ੇ ਉੱਤੇ ਜਾਓ
+pdfjs-last-page-button-label = ਆਖਰੀ ਸਫ਼ੇ ਉੱਤੇ ਜਾਓ
+pdfjs-page-rotate-cw-button =
+ .title = ਸੱਜੇ ਦਾਅ ਘà©à©°à¨®à¨¾à¨“
+pdfjs-page-rotate-cw-button-label = ਸੱਜੇ ਦਾਅ ਘà©à©°à¨®à¨¾à¨“
+pdfjs-page-rotate-ccw-button =
+ .title = ਖੱਬੇ ਦਾਅ ਘà©à©°à¨®à¨¾à¨“
+pdfjs-page-rotate-ccw-button-label = ਖੱਬੇ ਦਾਅ ਘà©à©°à¨®à¨¾à¨“
+pdfjs-cursor-text-select-tool-button =
+ .title = ਲਿਖਤ ਚੋਣ ਟੂਲ ਸਮਰੱਥ ਕਰੋ
+pdfjs-cursor-text-select-tool-button-label = ਲਿਖਤ ਚੋਣ ਟੂਲ
+pdfjs-cursor-hand-tool-button =
+ .title = ਹੱਥ ਟੂਲ ਸਮਰੱਥ ਕਰੋ
+pdfjs-cursor-hand-tool-button-label = ਹੱਥ ਟੂਲ
+pdfjs-scroll-page-button =
+ .title = ਸਫ਼ਾ ਖਿਸਕਾਉਣ ਨੂੰ ਵਰਤੋਂ
+pdfjs-scroll-page-button-label = ਸਫ਼ਾ ਖਿਸਕਾਉਣਾ
+pdfjs-scroll-vertical-button =
+ .title = ਖੜà©à¨¹à¨µà©‡à¨‚ ਸਕਰਾਉਣ ਨੂੰ ਵਰਤੋਂ
+pdfjs-scroll-vertical-button-label = ਖੜà©à¨¹à¨µà¨¾à¨‚ ਸਰਕਾਉਣਾ
+pdfjs-scroll-horizontal-button =
+ .title = ਲੇਟਵੇਂ ਸਰਕਾਉਣ ਨੂੰ ਵਰਤੋਂ
+pdfjs-scroll-horizontal-button-label = ਲੇਟਵਾਂ ਸਰਕਾਉਣਾ
+pdfjs-scroll-wrapped-button =
+ .title = ਸਮੇਟੇ ਸਰਕਾਉਣ ਨੂੰ ਵਰਤੋਂ
+pdfjs-scroll-wrapped-button-label = ਸਮੇਟਿਆ ਸਰਕਾਉਣਾ
+pdfjs-spread-none-button =
+ .title = ਸਫ਼ਾ ਫੈਲਾਅ ਵਿੱਚ ਸ਼ਾਮਲ ਨਾ ਹੋਵੋ
+pdfjs-spread-none-button-label = ਕੋਈ ਫੈਲਾਅ ਨਹੀਂ
+pdfjs-spread-odd-button =
+ .title = ਟਾਂਕ ਅੰਕ ਵਾਲੇ ਸਫ਼ਿਆਂ ਨਾਲ ਸ਼à©à¨°à©‚ ਹੋਣ ਵਾਲੇ ਸਫਿਆਂ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਵੋ
+pdfjs-spread-odd-button-label = ਟਾਂਕ ਫੈਲਾਅ
+pdfjs-spread-even-button =
+ .title = ਜਿਸਤ ਅੰਕ ਵਾਲੇ ਸਫ਼ਿਆਂ ਨਾਲ ਸ਼à©à¨°à©‚ ਹੋਣ ਵਾਲੇ ਸਫਿਆਂ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਵੋ
+pdfjs-spread-even-button-label = ਜਿਸਤ ਫੈਲਾਅ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = …ਦਸਤਾਵੇਜ਼ ਦੀ ਵਿਸ਼ੇਸ਼ਤਾ
+pdfjs-document-properties-button-label = …ਦਸਤਾਵੇਜ਼ ਦੀ ਵਿਸ਼ੇਸ਼ਤਾ
+pdfjs-document-properties-file-name = ਫਾਈਲ ਦਾ ਨਾਂ:
+pdfjs-document-properties-file-size = ਫਾਈਲ ਦਾ ਆਕਾਰ:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ਬਾਈਟ)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ਬਾਈਟ)
+pdfjs-document-properties-title = ਟਾਈਟਲ:
+pdfjs-document-properties-author = ਲੇਖਕ:
+pdfjs-document-properties-subject = ਵਿਸ਼ਾ:
+pdfjs-document-properties-keywords = ਸ਼ਬਦ:
+pdfjs-document-properties-creation-date = ਬਣਾਉਣ ਦੀ ਮਿਤੀ:
+pdfjs-document-properties-modification-date = ਸੋਧ ਦੀ ਮਿਤੀ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ਨਿਰਮਾਤਾ:
+pdfjs-document-properties-producer = PDF ਪà©à¨°à©‹à¨¡à¨¿à¨Šà¨¸à¨°:
+pdfjs-document-properties-version = PDF ਵਰਜਨ:
+pdfjs-document-properties-page-count = ਸਫ਼ੇ ਦੀ ਗਿਣਤੀ:
+pdfjs-document-properties-page-size = ਸਫ਼ਾ ਆਕਾਰ:
+pdfjs-document-properties-page-size-unit-inches = ਇੰਚ
+pdfjs-document-properties-page-size-unit-millimeters = ਮਿਮੀ
+pdfjs-document-properties-page-size-orientation-portrait = ਪੋਰਟਰੇਟ
+pdfjs-document-properties-page-size-orientation-landscape = ਲੈਂਡਸਕੇਪ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ਲੈਟਰ
+pdfjs-document-properties-page-size-name-legal = ਕਨੂੰਨੀ
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ਤੇਜ਼ ਵੈੱਬ à¨à¨²à¨•:
+pdfjs-document-properties-linearized-yes = ਹਾਂ
+pdfjs-document-properties-linearized-no = ਨਹੀਂ
+pdfjs-document-properties-close-button = ਬੰਦ ਕਰੋ
+
+## Print
+
+pdfjs-print-progress-message = …ਪਰਿੰਟ ਕਰਨ ਲਈ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਤਿਆਰ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ਰੱਦ ਕਰੋ
+pdfjs-printing-not-supported = ਸਾਵਧਾਨ: ਇਹ ਬਰਾਊਜ਼ਰ ਪਰਿੰਟ ਕਰਨ ਲਈ ਪੂਰੀ ਤਰà©à¨¹à¨¾à¨‚ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।
+pdfjs-printing-not-ready = ਸਾਵਧਾਨ: PDF ਨੂੰ ਪਰਿੰਟ ਕਰਨ ਲਈ ਪੂਰੀ ਤਰà©à¨¹à¨¾à¨‚ ਲੋਡ ਨਹੀਂ ਹੈ।
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ਬਾਹੀ ਬਦਲੋ
+pdfjs-toggle-sidebar-notification-button =
+ .title = ਬਾਹੀ ਨੂੰ ਬਦਲੋ (ਦਸਤਾਵੇਜ਼ ਖਾਕਾ/ਅਟੈਚਮੈਂਟ/ਪਰਤਾਂ ਰੱਖਦਾ ਹੈ)
+pdfjs-toggle-sidebar-button-label = ਬਾਹੀ ਬਦਲੋ
+pdfjs-document-outline-button =
+ .title = ਦਸਤਾਵੇਜ਼ ਖਾਕਾ ਦਿਖਾਓ (ਸਾਰੀਆਂ ਆਈਟਮਾਂ ਨੂੰ ਫੈਲਾਉਣ/ਸਮੇਟਣ ਲਈ ਦੋ ਵਾਰ ਕਲਿੱਕ ਕਰੋ)
+pdfjs-document-outline-button-label = ਦਸਤਾਵੇਜ਼ ਖਾਕਾ
+pdfjs-attachments-button =
+ .title = ਅਟੈਚਮੈਂਟ ਵੇਖਾਓ
+pdfjs-attachments-button-label = ਅਟੈਚਮੈਂਟਾਂ
+pdfjs-layers-button =
+ .title = ਪਰਤਾਂ ਵੇਖਾਓ (ਸਾਰੀਆਂ ਪਰਤਾਂ ਨੂੰ ਮੂਲ ਹਾਲਤ ਉੱਤੇ ਮà©à©œ-ਸੈੱਟ ਕਰਨ ਲਈ ਦੋ ਵਾਰ ਕਲਿੱਕ ਕਰੋ)
+pdfjs-layers-button-label = ਪਰਤਾਂ
+pdfjs-thumbs-button =
+ .title = ਥੰਮਨੇਲ ਨੂੰ ਵੇਖਾਓ
+pdfjs-thumbs-button-label = ਥੰਮਨੇਲ
+pdfjs-current-outline-item-button =
+ .title = ਮੌੌਜੂਦਾ ਖਾਕਾ ਚੀਜ਼ ਲੱà¨à©‹
+pdfjs-current-outline-item-button-label = ਮੌਜੂਦਾ ਖਾਕਾ ਚੀਜ਼
+pdfjs-findbar-button =
+ .title = ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਲੱà¨à©‹
+pdfjs-findbar-button-label = ਲੱà¨à©‹
+pdfjs-additional-layers = ਵਾਧੂ ਪਰਤਾਂ
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = ਸਫ਼ਾ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } ਸਫ਼ੇ ਦਾ ਥੰਮਨੇਲ
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ਲੱà¨à©‹
+ .placeholder = …ਦਸਤਾਵੇਜ਼ 'ਚ ਲੱà¨à©‹
+pdfjs-find-previous-button =
+ .title = ਵਾਕ ਦੀ ਪਿਛਲੀ ਮੌਜੂਦਗੀ ਲੱà¨à©‹
+pdfjs-find-previous-button-label = ਪਿੱਛੇ
+pdfjs-find-next-button =
+ .title = ਵਾਕ ਦੀ ਅਗਲੀ ਮੌਜੂਦਗੀ ਲੱà¨à©‹
+pdfjs-find-next-button-label = ਅੱਗੇ
+pdfjs-find-highlight-checkbox = ਸਠਉà¨à¨¾à¨°à©‹
+pdfjs-find-match-case-checkbox-label = ਅੱਖਰ ਆਕਾਰ ਨੂੰ ਮਿਲਾਉ
+pdfjs-find-match-diacritics-checkbox-label = à¨à©‡à¨¦à¨¸à©‚ਚਕ ਮੇਲ
+pdfjs-find-entire-word-checkbox-label = ਪੂਰੇ ਸ਼ਬਦ
+pdfjs-find-reached-top = ਦਸਤਾਵੇਜ਼ ਦੇ ਉੱਤੇ ਆ ਗਠਹਾਂ, ਥੱਲੇ ਤੋਂ ਜਾਰੀ ਰੱਖਿਆ ਹੈ
+pdfjs-find-reached-bottom = ਦਸਤਾਵੇਜ਼ ਦੇ ਅੰਤ ਉੱਤੇ ਆ ਗਠਹਾਂ, ਉੱਤੇ ਤੋਂ ਜਾਰੀ ਰੱਖਿਆ ਹੈ
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $total } ਵਿੱਚੋਂ { $current } ਮੇਲ
+ *[other] { $total } ਵਿੱਚੋਂ { $current } ਮੇਲ
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] { $limit } ਤੋਂ ਵੱਧ ਮੇਲ
+ *[other] { $limit } ਤੋਂ ਵੱਧ ਮੇਲ
+ }
+pdfjs-find-not-found = ਵਾਕ ਨਹੀਂ ਲੱà¨à¨¿à¨†
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ਸਫ਼ੇ ਦੀ ਚੌੜਾਈ
+pdfjs-page-scale-fit = ਸਫ਼ਾ ਫਿੱਟ
+pdfjs-page-scale-auto = ਆਟੋਮੈਟਿਕ ਜ਼ੂਮ ਕਰੋ
+pdfjs-page-scale-actual = ਆਟੋਮੈਟਿਕ ਆਕਾਰ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = ਸਫ਼ਾ { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ਲੋਡ ਕਰਨ ਦੇ ਦੌਰਾਨ ਗਲਤੀ ਆਈ ਹੈ।
+pdfjs-invalid-file-error = ਗਲਤ ਜਾਂ ਨਿਕਾਰਾ PDF ਫਾਈਲ ਹੈ।
+pdfjs-missing-file-error = ਨਾ-ਮੌਜੂਦ PDF ਫਾਈਲ।
+pdfjs-unexpected-response-error = ਅਣਜਾਣ ਸਰਵਰ ਜਵਾਬ।
+pdfjs-rendering-error = ਸਫ਼ਾ ਰੈਡਰ ਕਰਨ ਦੇ ਦੌਰਾਨ ਗਲਤੀ ਆਈ ਹੈ।
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ਵਿਆਖਿਆ]
+
+## Password
+
+pdfjs-password-label = ਇਹ PDF ਫਾਈਲ ਨੂੰ ਖੋਲà©à¨¹à¨£ ਲਈ ਪਾਸਵਰਡ ਦਿਉ।
+pdfjs-password-invalid = ਗਲਤ ਪਾਸਵਰਡ। ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।
+pdfjs-password-ok-button = ਠੀਕ ਹੈ
+pdfjs-password-cancel-button = ਰੱਦ ਕਰੋ
+pdfjs-web-fonts-disabled = ਵੈਬ ਫੋਂਟ ਬੰਦ ਹਨ: ਇੰਬੈਡ PDF ਫੋਂਟ ਨੂੰ ਵਰਤਣ ਲਈ ਅਸਮਰੱਥ ਹੈ।
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ਲਿਖਤ
+pdfjs-editor-free-text-button-label = ਲਿਖਤ
+pdfjs-editor-ink-button =
+ .title = ਵਾਹੋ
+pdfjs-editor-ink-button-label = ਵਾਹੋ
+pdfjs-editor-stamp-button =
+ .title = ਚਿੱਤਰ ਜੋੜੋ ਜਾਂ ਸੋਧੋ
+pdfjs-editor-stamp-button-label = ਚਿੱਤਰ ਜੋੜੋ ਜਾਂ ਸੋਧੋ
+pdfjs-editor-remove-button =
+ .title = ਹਟਾਓ
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = ਡਰਾਇੰਗ ਨੂੰ ਹਟਾਓ
+pdfjs-editor-remove-freetext-button =
+ .title = ਲਿਖਤ ਨੂੰ ਹਟਾਓ
+pdfjs-editor-remove-stamp-button =
+ .title = ਚਿੱਤਰ ਨੂੰ ਹਟਾਓ
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ਰੰਗ
+pdfjs-editor-free-text-size-input = ਆਕਾਰ
+pdfjs-editor-ink-color-input = ਰੰਗ
+pdfjs-editor-ink-thickness-input = ਮੋਟਾਈ
+pdfjs-editor-ink-opacity-input = ਧà©à©°à¨¦à¨²à¨¾à¨ªà¨¨
+pdfjs-editor-stamp-add-image-button =
+ .title = ਚਿੱਤਰ ਜੋੜੋ
+pdfjs-editor-stamp-add-image-button-label = ਚਿੱਤਰ ਜੋੜੋ
+pdfjs-free-text =
+ .aria-label = ਲਿਖਤ à¨à¨¡à©€à¨Ÿà¨°
+pdfjs-free-text-default-content = …ਲਿਖਣਾ ਸ਼à©à¨°à©‚ ਕਰੋ
+pdfjs-ink =
+ .aria-label = ਵਹਾਉਣ à¨à¨¡à©€à¨Ÿà¨°
+pdfjs-ink-canvas =
+ .aria-label = ਵਰਤੋਂਕਾਰ ਵਲੋਂ ਬਣਾਇਆ ਚਿੱਤਰ
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = ਬਦਲਵੀਂ ਲਿਖਤ
+pdfjs-editor-alt-text-edit-button-label = ਬਦਲਵੀ ਲਿਖਤ ਨੂੰ ਸੋਧੋ
+pdfjs-editor-alt-text-dialog-label = ਚੋਣ ਕਰੋ
+pdfjs-editor-alt-text-dialog-description = ਚਿੱਤਰ ਨਾ ਦਿੱਸਣ ਜਾਂ ਲੋਡ ਨਾ ਹੋਣ ਦੀ ਹਾਲਤ ਵਿੱਚ Alt ਲਿਖਤ (ਬਦਲਵੀਂ ਲਿਖਤ) ਲੋਕਾਂ ਲਈ ਮਦਦਗਾਰ ਹà©à©°à¨¦à©€ ਹੈ।
+pdfjs-editor-alt-text-add-description-label = ਵਰਣਨ ਜੋੜੋ
+pdfjs-editor-alt-text-add-description-description = 1-2 ਵਾਕ ਰੱਖੋ, ਜੋ ਕਿ ਵਿਸ਼ੇ, ਸੈਟਿੰਗ ਜਾਂ ਕਾਰਵਾਈਆਂ ਬਾਰੇ ਦਰਸਾਉਂਦੇ ਹੋਣ।
+pdfjs-editor-alt-text-mark-decorative-label = ਸਜਾਵਟ ਵਜੋਂ ਨਿਸ਼ਾਨ ਲਾਇਆ
+pdfjs-editor-alt-text-mark-decorative-description = ਇਸ ਨੂੰ ਸਜਾਵਟੀ ਚਿੱਤਰਾਂ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਹਾਸ਼ੀਆ ਜਾਂ ਵਾਟਰਮਾਰਕ ਆਦਿ।
+pdfjs-editor-alt-text-cancel-button = ਰੱਦ ਕਰੋ
+pdfjs-editor-alt-text-save-button = ਸੰà¨à¨¾à¨²à©‹
+pdfjs-editor-alt-text-decorative-tooltip = ਸਜਾਵਟ ਵਜੋਂ ਨਿਸ਼ਾਨ ਲਾਓ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = ਮਿਸਾਲ ਵਜੋਂ, “ਗੱà¨à¨°à©‚ à¨à©‹à¨œà¨¨ ਲੈ ਕੇ ਮੇਜ਼ ਉੱਤੇ ਬੈਠਾ ਹੈâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = ਉੱਤੇ ਖੱਬਾ ਕੋਨਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-top-middle = ਉੱਤੇ ਮੱਧ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-top-right = ਉੱਤੇ ਸੱਜਾ ਕੋਨਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-middle-right = ਮੱਧ ਸੱਜਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-bottom-right = ਹੇਠਾਂ ਸੱਜਾ ਕੋਨਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-bottom-middle = ਹੇਠਾਂ ਮੱਧ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-bottom-left = ਹੇਠਾਂ ਖੱਬਾ ਕੋਨਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
+pdfjs-editor-resizer-label-middle-left = ਮੱਧ ਖੱਬਾ — ਮà©à©œ-ਆਕਾਰ ਕਰੋ
diff --git a/www/lib/pdfjs/modern/web/locale/pl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/pl/viewer.ftl
new file mode 100644
index 000000000..500a2a32c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/pl/viewer.ftl
@@ -0,0 +1,386 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Poprzednia strona
+pdfjs-previous-button-label = Poprzednia
+pdfjs-next-button =
+ .title = Następna strona
+pdfjs-next-button-label = Następna
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Strona
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = z { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } z { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Pomniejsz
+pdfjs-zoom-out-button-label = Pomniejsz
+pdfjs-zoom-in-button =
+ .title = Powiększ
+pdfjs-zoom-in-button-label = Powiększ
+pdfjs-zoom-select =
+ .title = Skala
+pdfjs-presentation-mode-button =
+ .title = Przełącz na tryb prezentacji
+pdfjs-presentation-mode-button-label = Tryb prezentacji
+pdfjs-open-file-button =
+ .title = Otwórz plik
+pdfjs-open-file-button-label = Otwórz
+pdfjs-print-button =
+ .title = Drukuj
+pdfjs-print-button-label = Drukuj
+pdfjs-save-button =
+ .title = Zapisz
+pdfjs-save-button-label = Zapisz
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Pobierz
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Pobierz
+pdfjs-bookmark-button =
+ .title = Bieżąca strona (adres do otwarcia na bieżącej stronie)
+pdfjs-bookmark-button-label = Bieżąca strona
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Otwórz w aplikacji
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Otwórz w aplikacji
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Narzędzia
+pdfjs-tools-button-label = Narzędzia
+pdfjs-first-page-button =
+ .title = Przejdź do pierwszej strony
+pdfjs-first-page-button-label = Przejdź do pierwszej strony
+pdfjs-last-page-button =
+ .title = Przejdź do ostatniej strony
+pdfjs-last-page-button-label = Przejdź do ostatniej strony
+pdfjs-page-rotate-cw-button =
+ .title = Obróć zgodnie z ruchem wskazówek zegara
+pdfjs-page-rotate-cw-button-label = Obróć zgodnie z ruchem wskazówek zegara
+pdfjs-page-rotate-ccw-button =
+ .title = Obróć przeciwnie do ruchu wskazówek zegara
+pdfjs-page-rotate-ccw-button-label = Obróć przeciwnie do ruchu wskazówek zegara
+pdfjs-cursor-text-select-tool-button =
+ .title = Włącz narzędzie zaznaczania tekstu
+pdfjs-cursor-text-select-tool-button-label = Narzędzie zaznaczania tekstu
+pdfjs-cursor-hand-tool-button =
+ .title = Włącz narzędzie rączka
+pdfjs-cursor-hand-tool-button-label = Narzędzie rączka
+pdfjs-scroll-page-button =
+ .title = Przewijaj strony
+pdfjs-scroll-page-button-label = Przewijanie stron
+pdfjs-scroll-vertical-button =
+ .title = Przewijaj dokument w pionie
+pdfjs-scroll-vertical-button-label = Przewijanie pionowe
+pdfjs-scroll-horizontal-button =
+ .title = Przewijaj dokument w poziomie
+pdfjs-scroll-horizontal-button-label = Przewijanie poziome
+pdfjs-scroll-wrapped-button =
+ .title = Strony dokumentu wyświetlaj i przewijaj w kolumnach
+pdfjs-scroll-wrapped-button-label = Widok dwóch stron
+pdfjs-spread-none-button =
+ .title = Nie ustawiaj stron obok siebie
+pdfjs-spread-none-button-label = Brak kolumn
+pdfjs-spread-odd-button =
+ .title = Strony nieparzyste ustawiaj na lewo od parzystych
+pdfjs-spread-odd-button-label = Nieparzyste po lewej
+pdfjs-spread-even-button =
+ .title = Strony parzyste ustawiaj na lewo od nieparzystych
+pdfjs-spread-even-button-label = Parzyste po lewej
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Właściwości dokumentu…
+pdfjs-document-properties-button-label = Właściwości dokumentu…
+pdfjs-document-properties-file-name = Nazwa pliku:
+pdfjs-document-properties-file-size = Rozmiar pliku:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb }Â KB ({ $size_b }Â B)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb }Â MB ({ $size_b }Â B)
+pdfjs-document-properties-title = Tytuł:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Temat:
+pdfjs-document-properties-keywords = SÅ‚owa kluczowe:
+pdfjs-document-properties-creation-date = Data utworzenia:
+pdfjs-document-properties-modification-date = Data modyfikacji:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Utworzony przez:
+pdfjs-document-properties-producer = PDF wyprodukowany przez:
+pdfjs-document-properties-version = Wersja PDF:
+pdfjs-document-properties-page-count = Liczba stron:
+pdfjs-document-properties-page-size = Wymiary strony:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = pionowa
+pdfjs-document-properties-page-size-orientation-landscape = pozioma
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = US Letter
+pdfjs-document-properties-page-size-name-legal = US Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width }×{ $height } { $unit } (orientacja { $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width }×{ $height } { $unit } ({ $name }, orientacja { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Szybki podgląd w Internecie:
+pdfjs-document-properties-linearized-yes = tak
+pdfjs-document-properties-linearized-no = nie
+pdfjs-document-properties-close-button = Zamknij
+
+## Print
+
+pdfjs-print-progress-message = Przygotowywanie dokumentu do druku…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Anuluj
+pdfjs-printing-not-supported = Ostrzeżenie: drukowanie nie jest w pełni obsługiwane przez tę przeglądarkę.
+pdfjs-printing-not-ready = Ostrzeżenie: dokument PDF nie jest całkowicie wczytany, więc nie można go wydrukować.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Przełącz panel boczny
+pdfjs-toggle-sidebar-notification-button =
+ .title = Przełącz panel boczny (dokument zawiera konspekt/załączniki/warstwy)
+pdfjs-toggle-sidebar-button-label = Przełącz panel boczny
+pdfjs-document-outline-button =
+ .title = Konspekt dokumentu (podwójne kliknięcie rozwija lub zwija wszystkie pozycje)
+pdfjs-document-outline-button-label = Konspekt dokumentu
+pdfjs-attachments-button =
+ .title = Załączniki
+pdfjs-attachments-button-label = Załączniki
+pdfjs-layers-button =
+ .title = Warstwy (podwójne kliknięcie przywraca wszystkie warstwy do stanu domyślnego)
+pdfjs-layers-button-label = Warstwy
+pdfjs-thumbs-button =
+ .title = Miniatury
+pdfjs-thumbs-button-label = Miniatury
+pdfjs-current-outline-item-button =
+ .title = Znajdź bieżący element konspektu
+pdfjs-current-outline-item-button-label = Bieżący element konspektu
+pdfjs-findbar-button =
+ .title = Znajdź w dokumencie
+pdfjs-findbar-button-label = Znajdź
+pdfjs-additional-layers = Dodatkowe warstwy
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page }. strona
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura { $page }. strony
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Znajdź
+ .placeholder = Znajdź w dokumencie…
+pdfjs-find-previous-button =
+ .title = Znajdź poprzednie wystąpienie tekstu
+pdfjs-find-previous-button-label = Poprzednie
+pdfjs-find-next-button =
+ .title = Znajdź następne wystąpienie tekstu
+pdfjs-find-next-button-label = Następne
+pdfjs-find-highlight-checkbox = Wyróżnianie wszystkich
+pdfjs-find-match-case-checkbox-label = Rozróżnianie wielkości liter
+pdfjs-find-match-diacritics-checkbox-label = Rozróżnianie liter diakrytyzowanych
+pdfjs-find-entire-word-checkbox-label = Całe słowa
+pdfjs-find-reached-top = Początek dokumentu. Wyszukiwanie od końca.
+pdfjs-find-reached-bottom = Koniec dokumentu. Wyszukiwanie od poczÄ…tku.
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current }. z { $total } trafienia
+ [few] { $current }. z { $total } trafień
+ *[many] { $current }. z { $total } trafień
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Więcej niż { $limit } trafienie
+ [few] Więcej niż { $limit } trafienia
+ *[many] Więcej niż { $limit } trafień
+ }
+pdfjs-find-not-found = Nie znaleziono tekstu
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Szerokość strony
+pdfjs-page-scale-fit = Dopasowanie strony
+pdfjs-page-scale-auto = Skala automatyczna
+pdfjs-page-scale-actual = Rozmiar oryginalny
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page }. strona
+
+## Loading indicator messages
+
+pdfjs-loading-error = Podczas wczytywania dokumentu PDF wystąpił błąd.
+pdfjs-invalid-file-error = Nieprawidłowy lub uszkodzony plik PDF.
+pdfjs-missing-file-error = Brak pliku PDF.
+pdfjs-unexpected-response-error = Nieoczekiwana odpowiedź serwera.
+pdfjs-rendering-error = Podczas renderowania strony wystąpił błąd.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Przypis: { $type }]
+
+## Password
+
+pdfjs-password-label = Wprowadź hasło, aby otworzyć ten dokument PDF.
+pdfjs-password-invalid = Nieprawidłowe hasło. Proszę spróbować ponownie.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Anuluj
+pdfjs-web-fonts-disabled = Czcionki sieciowe są wyłączone: nie można użyć osadzonych czcionek PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Rysunek
+pdfjs-editor-ink-button-label = Rysunek
+pdfjs-editor-stamp-button =
+ .title = Dodaj lub edytuj obrazy
+pdfjs-editor-stamp-button-label = Dodaj lub edytuj obrazy
+pdfjs-editor-remove-button =
+ .title = Usuń
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Usuń rysunek
+pdfjs-editor-remove-freetext-button =
+ .title = Usuń tekst
+pdfjs-editor-remove-stamp-button =
+ .title = Usuń obraz
+pdfjs-editor-remove-highlight-button =
+ .title = Usuń wyróżnienie
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Kolor
+pdfjs-editor-free-text-size-input = Rozmiar
+pdfjs-editor-ink-color-input = Kolor
+pdfjs-editor-ink-thickness-input = Grubość
+pdfjs-editor-ink-opacity-input = Nieprzezroczystość
+pdfjs-editor-stamp-add-image-button =
+ .title = Dodaj obraz
+pdfjs-editor-stamp-add-image-button-label = Dodaj obraz
+pdfjs-free-text =
+ .aria-label = Edytor tekstu
+pdfjs-free-text-default-content = Zacznij pisać…
+pdfjs-ink =
+ .aria-label = Edytor rysunku
+pdfjs-ink-canvas =
+ .aria-label = Obraz utworzony przez użytkownika
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Tekst alternatywny
+pdfjs-editor-alt-text-edit-button-label = Edytuj tekst alternatywny
+pdfjs-editor-alt-text-dialog-label = Wybierz opcjÄ™
+pdfjs-editor-alt-text-dialog-description = Tekst alternatywny pomaga, kiedy ktoś nie może zobaczyć obrazu lub gdy się nie wczytuje.
+pdfjs-editor-alt-text-add-description-label = Dodaj opis
+pdfjs-editor-alt-text-add-description-description = Staraj się napisać 1-2 zdania opisujące temat, miejsce lub działania.
+pdfjs-editor-alt-text-mark-decorative-label = Oznacz jako dekoracyjne
+pdfjs-editor-alt-text-mark-decorative-description = Używane w przypadku obrazów ozdobnych, takich jak obramowania lub znaki wodne.
+pdfjs-editor-alt-text-cancel-button = Anuluj
+pdfjs-editor-alt-text-save-button = Zapisz
+pdfjs-editor-alt-text-decorative-tooltip = Oznaczone jako dekoracyjne
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Na przykÅ‚ad: „MÅ‚ody czÅ‚owiek siada przy stole, aby zjeść posiÅ‚ekâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Lewy górny róg — zmień rozmiar
+pdfjs-editor-resizer-label-top-middle = Górny środkowy — zmień rozmiar
+pdfjs-editor-resizer-label-top-right = Prawy górny róg — zmień rozmiar
+pdfjs-editor-resizer-label-middle-right = Prawy środkowy — zmień rozmiar
+pdfjs-editor-resizer-label-bottom-right = Prawy dolny róg — zmień rozmiar
+pdfjs-editor-resizer-label-bottom-middle = Dolny środkowy — zmień rozmiar
+pdfjs-editor-resizer-label-bottom-left = Lewy dolny róg — zmień rozmiar
+pdfjs-editor-resizer-label-middle-left = Lewy środkowy — zmień rozmiar
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Kolor wyróżnienia
+pdfjs-editor-colorpicker-button =
+ .title = Zmień kolor
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Wybór kolorów
+pdfjs-editor-colorpicker-yellow =
+ .title = Żółty
+pdfjs-editor-colorpicker-green =
+ .title = Zielony
+pdfjs-editor-colorpicker-blue =
+ .title = Niebieski
+pdfjs-editor-colorpicker-pink =
+ .title = Różowy
+pdfjs-editor-colorpicker-red =
+ .title = Czerwony
diff --git a/www/lib/pdfjs/modern/web/locale/pt-BR/viewer.ftl b/www/lib/pdfjs/modern/web/locale/pt-BR/viewer.ftl
new file mode 100644
index 000000000..ddde7804d
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/pt-BR/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Próxima página
+pdfjs-next-button-label = Próxima
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Reduzir
+pdfjs-zoom-out-button-label = Reduzir
+pdfjs-zoom-in-button =
+ .title = Ampliar
+pdfjs-zoom-in-button-label = Ampliar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Mudar para o modo de apresentação
+pdfjs-presentation-mode-button-label = Modo de apresentação
+pdfjs-open-file-button =
+ .title = Abrir arquivo
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Salvar
+pdfjs-save-button-label = Salvar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Baixar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Baixar
+pdfjs-bookmark-button =
+ .title = Página atual (ver URL da página atual)
+pdfjs-bookmark-button-label = Pagina atual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir em um aplicativo
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir em um aplicativo
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ferramentas
+pdfjs-tools-button-label = Ferramentas
+pdfjs-first-page-button =
+ .title = Ir para a primeira página
+pdfjs-first-page-button-label = Ir para a primeira página
+pdfjs-last-page-button =
+ .title = Ir para a última página
+pdfjs-last-page-button-label = Ir para a última página
+pdfjs-page-rotate-cw-button =
+ .title = Girar no sentido horário
+pdfjs-page-rotate-cw-button-label = Girar no sentido horário
+pdfjs-page-rotate-ccw-button =
+ .title = Girar no sentido anti-horário
+pdfjs-page-rotate-ccw-button-label = Girar no sentido anti-horário
+pdfjs-cursor-text-select-tool-button =
+ .title = Ativar a ferramenta de seleção de texto
+pdfjs-cursor-text-select-tool-button-label = Ferramenta de seleção de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Ativar ferramenta de deslocamento
+pdfjs-cursor-hand-tool-button-label = Ferramenta de deslocamento
+pdfjs-scroll-page-button =
+ .title = Usar rolagem de página
+pdfjs-scroll-page-button-label = Rolagem de página
+pdfjs-scroll-vertical-button =
+ .title = Usar deslocamento vertical
+pdfjs-scroll-vertical-button-label = Deslocamento vertical
+pdfjs-scroll-horizontal-button =
+ .title = Usar deslocamento horizontal
+pdfjs-scroll-horizontal-button-label = Deslocamento horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Usar deslocamento contido
+pdfjs-scroll-wrapped-button-label = Deslocamento contido
+pdfjs-spread-none-button =
+ .title = Não reagrupar páginas
+pdfjs-spread-none-button-label = Não estender
+pdfjs-spread-odd-button =
+ .title = Agrupar páginas começando em páginas com números Ãmpares
+pdfjs-spread-odd-button-label = Estender Ãmpares
+pdfjs-spread-even-button =
+ .title = Agrupar páginas começando em páginas com números pares
+pdfjs-spread-even-button-label = Estender pares
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propriedades do documento…
+pdfjs-document-properties-button-label = Propriedades do documento…
+pdfjs-document-properties-file-name = Nome do arquivo:
+pdfjs-document-properties-file-size = Tamanho do arquivo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Assunto:
+pdfjs-document-properties-keywords = Palavras-chave:
+pdfjs-document-properties-creation-date = Data da criação:
+pdfjs-document-properties-modification-date = Data da modificação:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Criação:
+pdfjs-document-properties-producer = Criador do PDF:
+pdfjs-document-properties-version = Versão do PDF:
+pdfjs-document-properties-page-count = Número de páginas:
+pdfjs-document-properties-page-size = Tamanho da página:
+pdfjs-document-properties-page-size-unit-inches = pol.
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = retrato
+pdfjs-document-properties-page-size-orientation-landscape = paisagem
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = JurÃdico
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Exibição web rápida:
+pdfjs-document-properties-linearized-yes = Sim
+pdfjs-document-properties-linearized-no = Não
+pdfjs-document-properties-close-button = Fechar
+
+## Print
+
+pdfjs-print-progress-message = Preparando documento para impressão…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress } %
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Aviso: a impressão não é totalmente suportada neste navegador.
+pdfjs-printing-not-ready = Aviso: o PDF não está totalmente carregado para impressão.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Exibir/ocultar painel lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Exibir/ocultar painel (documento contém estrutura/anexos/camadas)
+pdfjs-toggle-sidebar-button-label = Exibir/ocultar painel
+pdfjs-document-outline-button =
+ .title = Mostrar estrutura do documento (duplo-clique expande/recolhe todos os itens)
+pdfjs-document-outline-button-label = Estrutura do documento
+pdfjs-attachments-button =
+ .title = Mostrar anexos
+pdfjs-attachments-button-label = Anexos
+pdfjs-layers-button =
+ .title = Mostrar camadas (duplo-clique redefine todas as camadas ao estado predefinido)
+pdfjs-layers-button-label = Camadas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Encontrar item atual da estrutura
+pdfjs-current-outline-item-button-label = Item atual da estrutura
+pdfjs-findbar-button =
+ .title = Procurar no documento
+pdfjs-findbar-button-label = Procurar
+pdfjs-additional-layers = Camadas adicionais
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura da página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Procurar
+ .placeholder = Procurar no documento…
+pdfjs-find-previous-button =
+ .title = Procurar a ocorrência anterior da frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Procurar a próxima ocorrência da frase
+pdfjs-find-next-button-label = Próxima
+pdfjs-find-highlight-checkbox = Destacar tudo
+pdfjs-find-match-case-checkbox-label = Diferenciar maiúsculas/minúsculas
+pdfjs-find-match-diacritics-checkbox-label = Considerar acentuação
+pdfjs-find-entire-word-checkbox-label = Palavras completas
+pdfjs-find-reached-top = InÃcio do documento alcançado, continuando do fim
+pdfjs-find-reached-bottom = Fim do documento alcançado, continuando do inÃcio
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } de { $total } ocorrência
+ *[other] { $current } de { $total } ocorrências
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mais de { $limit } ocorrência
+ *[other] Mais de { $limit } ocorrências
+ }
+pdfjs-find-not-found = Não encontrado
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Largura da página
+pdfjs-page-scale-fit = Ajustar à janela
+pdfjs-page-scale-auto = Zoom automático
+pdfjs-page-scale-actual = Tamanho real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ocorreu um erro ao carregar o PDF.
+pdfjs-invalid-file-error = Arquivo PDF corrompido ou inválido.
+pdfjs-missing-file-error = Arquivo PDF ausente.
+pdfjs-unexpected-response-error = Resposta inesperada do servidor.
+pdfjs-rendering-error = Ocorreu um erro ao renderizar a página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotação { $type }]
+
+## Password
+
+pdfjs-password-label = Forneça a senha para abrir este arquivo PDF.
+pdfjs-password-invalid = Senha inválida. Tente novamente.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = As fontes web estão desativadas: não foi possÃvel usar fontes incorporadas do PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Desenho
+pdfjs-editor-ink-button-label = Desenho
+pdfjs-editor-stamp-button =
+ .title = Adicionar ou editar imagens
+pdfjs-editor-stamp-button-label = Adicionar ou editar imagens
+pdfjs-editor-remove-button =
+ .title = Remover
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Remover desenho
+pdfjs-editor-remove-freetext-button =
+ .title = Remover texto
+pdfjs-editor-remove-stamp-button =
+ .title = Remover imagem
+pdfjs-editor-remove-highlight-button =
+ .title = Remover destaque
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Cor
+pdfjs-editor-free-text-size-input = Tamanho
+pdfjs-editor-ink-color-input = Cor
+pdfjs-editor-ink-thickness-input = Espessura
+pdfjs-editor-ink-opacity-input = Opacidade
+pdfjs-editor-stamp-add-image-button =
+ .title = Adicionar imagem
+pdfjs-editor-stamp-add-image-button-label = Adicionar imagem
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Comece digitando…
+pdfjs-ink =
+ .aria-label = Editor de desenho
+pdfjs-ink-canvas =
+ .aria-label = Imagem criada pelo usuário
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar texto alternativo
+pdfjs-editor-alt-text-dialog-label = Escolha uma opção
+pdfjs-editor-alt-text-dialog-description = O texto alternativo ajuda quando uma imagem não aparece ou não for carregada.
+pdfjs-editor-alt-text-add-description-label = Adicione uma descrição
+pdfjs-editor-alt-text-add-description-description = Procure usar uma ou duas frases que descrevam o assunto, o cenário ou as ações.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativa
+pdfjs-editor-alt-text-mark-decorative-description = Isto é usado para imagens ornamentais, como bordas ou marcas d'água.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Salvar
+pdfjs-editor-alt-text-decorative-tooltip = Marcado como decorativa
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por exemplo, “Um jovem senta-se à mesa para comer uma refeiçãoâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Canto superior esquerdo — redimensionar
+pdfjs-editor-resizer-label-top-middle = No centro do topo — redimensionar
+pdfjs-editor-resizer-label-top-right = Canto superior direito — redimensionar
+pdfjs-editor-resizer-label-middle-right = No meio à direita — redimensionar
+pdfjs-editor-resizer-label-bottom-right = Canto inferior direito — redimensionar
+pdfjs-editor-resizer-label-bottom-middle = No centro da base — redimensionar
+pdfjs-editor-resizer-label-bottom-left = Canto inferior esquerdo — redimensionar
+pdfjs-editor-resizer-label-middle-left = No meio à esquerda — redimensionar
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Cor de destaque
+pdfjs-editor-colorpicker-button =
+ .title = Mudar cor
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Opções de cores
+pdfjs-editor-colorpicker-yellow =
+ .title = Amarelo
+pdfjs-editor-colorpicker-green =
+ .title = Verde
+pdfjs-editor-colorpicker-blue =
+ .title = Azul
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Vermelho
diff --git a/www/lib/pdfjs/modern/web/locale/pt-PT/viewer.ftl b/www/lib/pdfjs/modern/web/locale/pt-PT/viewer.ftl
new file mode 100644
index 000000000..fc4d31a51
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/pt-PT/viewer.ftl
@@ -0,0 +1,349 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Página anterior
+pdfjs-previous-button-label = Anterior
+pdfjs-next-button =
+ .title = Página seguinte
+pdfjs-next-button-label = Seguinte
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Página
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Reduzir
+pdfjs-zoom-out-button-label = Reduzir
+pdfjs-zoom-in-button =
+ .title = Ampliar
+pdfjs-zoom-in-button-label = Ampliar
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Trocar para o modo de apresentação
+pdfjs-presentation-mode-button-label = Modo de apresentação
+pdfjs-open-file-button =
+ .title = Abrir ficheiro
+pdfjs-open-file-button-label = Abrir
+pdfjs-print-button =
+ .title = Imprimir
+pdfjs-print-button-label = Imprimir
+pdfjs-save-button =
+ .title = Guardar
+pdfjs-save-button-label = Guardar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Transferir
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Transferir
+pdfjs-bookmark-button =
+ .title = Página atual (ver URL da página atual)
+pdfjs-bookmark-button-label = Pagina atual
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Abrir na aplicação
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Abrir na aplicação
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ferramentas
+pdfjs-tools-button-label = Ferramentas
+pdfjs-first-page-button =
+ .title = Ir para a primeira página
+pdfjs-first-page-button-label = Ir para a primeira página
+pdfjs-last-page-button =
+ .title = Ir para a última página
+pdfjs-last-page-button-label = Ir para a última página
+pdfjs-page-rotate-cw-button =
+ .title = Rodar à direita
+pdfjs-page-rotate-cw-button-label = Rodar à direita
+pdfjs-page-rotate-ccw-button =
+ .title = Rodar à esquerda
+pdfjs-page-rotate-ccw-button-label = Rodar à esquerda
+pdfjs-cursor-text-select-tool-button =
+ .title = Ativar ferramenta de seleção de texto
+pdfjs-cursor-text-select-tool-button-label = Ferramenta de seleção de texto
+pdfjs-cursor-hand-tool-button =
+ .title = Ativar ferramenta de mão
+pdfjs-cursor-hand-tool-button-label = Ferramenta de mão
+pdfjs-scroll-page-button =
+ .title = Utilizar deslocamento da página
+pdfjs-scroll-page-button-label = Deslocamento da página
+pdfjs-scroll-vertical-button =
+ .title = Utilizar deslocação vertical
+pdfjs-scroll-vertical-button-label = Deslocação vertical
+pdfjs-scroll-horizontal-button =
+ .title = Utilizar deslocação horizontal
+pdfjs-scroll-horizontal-button-label = Deslocação horizontal
+pdfjs-scroll-wrapped-button =
+ .title = Utilizar deslocação encapsulada
+pdfjs-scroll-wrapped-button-label = Deslocação encapsulada
+pdfjs-spread-none-button =
+ .title = Não juntar páginas dispersas
+pdfjs-spread-none-button-label = Sem spreads
+pdfjs-spread-odd-button =
+ .title = Juntar páginas dispersas a partir de páginas com números Ãmpares
+pdfjs-spread-odd-button-label = Spreads Ãmpares
+pdfjs-spread-even-button =
+ .title = Juntar páginas dispersas a partir de páginas com números pares
+pdfjs-spread-even-button-label = Spreads pares
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propriedades do documento…
+pdfjs-document-properties-button-label = Propriedades do documento…
+pdfjs-document-properties-file-name = Nome do ficheiro:
+pdfjs-document-properties-file-size = Tamanho do ficheiro:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = TÃtulo:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Assunto:
+pdfjs-document-properties-keywords = Palavras-chave:
+pdfjs-document-properties-creation-date = Data de criação:
+pdfjs-document-properties-modification-date = Data de modificação:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Criador:
+pdfjs-document-properties-producer = Produtor de PDF:
+pdfjs-document-properties-version = Versão do PDF:
+pdfjs-document-properties-page-count = N.º de páginas:
+pdfjs-document-properties-page-size = Tamanho da página:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = retrato
+pdfjs-document-properties-page-size-orientation-landscape = paisagem
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Carta
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista rápida web:
+pdfjs-document-properties-linearized-yes = Sim
+pdfjs-document-properties-linearized-no = Não
+pdfjs-document-properties-close-button = Fechar
+
+## Print
+
+pdfjs-print-progress-message = A preparar o documento para impressão…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cancelar
+pdfjs-printing-not-supported = Aviso: a impressão não é totalmente suportada por este navegador.
+pdfjs-printing-not-ready = Aviso: o PDF ainda não está totalmente carregado.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Alternar barra lateral
+pdfjs-toggle-sidebar-notification-button =
+ .title = Alternar barra lateral (o documento contém contornos/anexos/camadas)
+pdfjs-toggle-sidebar-button-label = Alternar barra lateral
+pdfjs-document-outline-button =
+ .title = Mostrar esquema do documento (duplo clique para expandir/colapsar todos os itens)
+pdfjs-document-outline-button-label = Esquema do documento
+pdfjs-attachments-button =
+ .title = Mostrar anexos
+pdfjs-attachments-button-label = Anexos
+pdfjs-layers-button =
+ .title = Mostrar camadas (clique duas vezes para repor todas as camadas para o estado predefinido)
+pdfjs-layers-button-label = Camadas
+pdfjs-thumbs-button =
+ .title = Mostrar miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Encontrar o item atualmente destacado
+pdfjs-current-outline-item-button-label = Item atualmente destacado
+pdfjs-findbar-button =
+ .title = Localizar em documento
+pdfjs-findbar-button-label = Localizar
+pdfjs-additional-layers = Camadas adicionais
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Página { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura da página { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Localizar
+ .placeholder = Localizar em documento…
+pdfjs-find-previous-button =
+ .title = Localizar ocorrência anterior da frase
+pdfjs-find-previous-button-label = Anterior
+pdfjs-find-next-button =
+ .title = Localizar ocorrência seguinte da frase
+pdfjs-find-next-button-label = Seguinte
+pdfjs-find-highlight-checkbox = Destacar tudo
+pdfjs-find-match-case-checkbox-label = Correspondência
+pdfjs-find-match-diacritics-checkbox-label = Corresponder diacrÃticos
+pdfjs-find-entire-word-checkbox-label = Palavras completas
+pdfjs-find-reached-top = Topo do documento atingido, a continuar a partir do fundo
+pdfjs-find-reached-bottom = Fim do documento atingido, a continuar a partir do topo
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } de { $total } correspondência
+ *[other] { $current } de { $total } correspondências
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mais de { $limit } correspondência
+ *[other] Mais de { $limit } correspondências
+ }
+pdfjs-find-not-found = Frase não encontrada
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ajustar à largura
+pdfjs-page-scale-fit = Ajustar à página
+pdfjs-page-scale-auto = Zoom automático
+pdfjs-page-scale-actual = Tamanho real
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Página { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ocorreu um erro ao carregar o PDF.
+pdfjs-invalid-file-error = Ficheiro PDF inválido ou danificado.
+pdfjs-missing-file-error = Ficheiro PDF inexistente.
+pdfjs-unexpected-response-error = Resposta inesperada do servidor.
+pdfjs-rendering-error = Ocorreu um erro ao processar a página.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotação { $type }]
+
+## Password
+
+pdfjs-password-label = Introduza a palavra-passe para abrir este ficheiro PDF.
+pdfjs-password-invalid = Palavra-passe inválida. Por favor, tente novamente.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Cancelar
+pdfjs-web-fonts-disabled = Os tipos de letra web estão desativados: não é possÃvel utilizar os tipos de letra PDF embutidos.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Texto
+pdfjs-editor-free-text-button-label = Texto
+pdfjs-editor-ink-button =
+ .title = Desenhar
+pdfjs-editor-ink-button-label = Desenhar
+pdfjs-editor-stamp-button =
+ .title = Adicionar ou editar imagens
+pdfjs-editor-stamp-button-label = Adicionar ou editar imagens
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Cor
+pdfjs-editor-free-text-size-input = Tamanho
+pdfjs-editor-ink-color-input = Cor
+pdfjs-editor-ink-thickness-input = Espessura
+pdfjs-editor-ink-opacity-input = Opacidade
+pdfjs-editor-stamp-add-image-button =
+ .title = Adicionar imagem
+pdfjs-editor-stamp-add-image-button-label = Adicionar imagem
+pdfjs-free-text =
+ .aria-label = Editor de texto
+pdfjs-free-text-default-content = Começar a digitar…
+pdfjs-ink =
+ .aria-label = Editor de desenho
+pdfjs-ink-canvas =
+ .aria-label = Imagem criada pelo utilizador
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Texto alternativo
+pdfjs-editor-alt-text-edit-button-label = Editar texto alternativo
+pdfjs-editor-alt-text-dialog-label = Escolher uma opção
+pdfjs-editor-alt-text-dialog-description = O texto alternativo (texto alternativo) ajuda quando as pessoas não conseguem ver a imagem ou quando a mesma não é carregada.
+pdfjs-editor-alt-text-add-description-label = Adicionar uma descrição
+pdfjs-editor-alt-text-add-description-description = Aponte para 1-2 frases que descrevam o assunto, definição ou ações.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar como decorativa
+pdfjs-editor-alt-text-mark-decorative-description = Isto é utilizado para imagens decorativas, tais como limites ou marcas d'água.
+pdfjs-editor-alt-text-cancel-button = Cancelar
+pdfjs-editor-alt-text-save-button = Guardar
+pdfjs-editor-alt-text-decorative-tooltip = Marcada como decorativa
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Por exemplo, “Um jovem senta-se à mesa para comer uma refeiçãoâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Canto superior esquerdo — redimensionar
+pdfjs-editor-resizer-label-top-middle = Superior ao centro — redimensionar
+pdfjs-editor-resizer-label-top-right = Canto superior direito — redimensionar
+pdfjs-editor-resizer-label-middle-right = Centro à direita — redimensionar
+pdfjs-editor-resizer-label-bottom-right = Canto inferior direito — redimensionar
+pdfjs-editor-resizer-label-bottom-middle = Inferior ao centro — redimensionar
+pdfjs-editor-resizer-label-bottom-left = Canto inferior esquerdo — redimensionar
+pdfjs-editor-resizer-label-middle-left = Centro à esquerda — redimensionar
diff --git a/www/lib/pdfjs/modern/web/locale/rm/viewer.ftl b/www/lib/pdfjs/modern/web/locale/rm/viewer.ftl
new file mode 100644
index 000000000..e1f2d20b5
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/rm/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina precedenta
+pdfjs-previous-button-label = Enavos
+pdfjs-next-button =
+ .title = Proxima pagina
+pdfjs-next-button-label = Enavant
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = da { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } da { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Empitschnir
+pdfjs-zoom-out-button-label = Empitschnir
+pdfjs-zoom-in-button =
+ .title = Engrondir
+pdfjs-zoom-in-button-label = Engrondir
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Midar en il modus da preschentaziun
+pdfjs-presentation-mode-button-label = Modus da preschentaziun
+pdfjs-open-file-button =
+ .title = Avrir datoteca
+pdfjs-open-file-button-label = Avrir
+pdfjs-print-button =
+ .title = Stampar
+pdfjs-print-button-label = Stampar
+pdfjs-save-button =
+ .title = Memorisar
+pdfjs-save-button-label = Memorisar
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Telechargiar
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Telechargiar
+pdfjs-bookmark-button =
+ .title = Pagina actuala (mussar l'URL da la pagina actuala)
+pdfjs-bookmark-button-label = Pagina actuala
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Avrir en ina app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Avrir en ina app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Utensils
+pdfjs-tools-button-label = Utensils
+pdfjs-first-page-button =
+ .title = Siglir a l'emprima pagina
+pdfjs-first-page-button-label = Siglir a l'emprima pagina
+pdfjs-last-page-button =
+ .title = Siglir a la davosa pagina
+pdfjs-last-page-button-label = Siglir a la davosa pagina
+pdfjs-page-rotate-cw-button =
+ .title = Rotar en direcziun da l'ura
+pdfjs-page-rotate-cw-button-label = Rotar en direcziun da l'ura
+pdfjs-page-rotate-ccw-button =
+ .title = Rotar en direcziun cuntraria a l'ura
+pdfjs-page-rotate-ccw-button-label = Rotar en direcziun cuntraria a l'ura
+pdfjs-cursor-text-select-tool-button =
+ .title = Activar l'utensil per selecziunar text
+pdfjs-cursor-text-select-tool-button-label = Utensil per selecziunar text
+pdfjs-cursor-hand-tool-button =
+ .title = Activar l'utensil da maun
+pdfjs-cursor-hand-tool-button-label = Utensil da maun
+pdfjs-scroll-page-button =
+ .title = Utilisar la defilada per pagina
+pdfjs-scroll-page-button-label = Defilada per pagina
+pdfjs-scroll-vertical-button =
+ .title = Utilisar il defilar vertical
+pdfjs-scroll-vertical-button-label = Defilar vertical
+pdfjs-scroll-horizontal-button =
+ .title = Utilisar il defilar orizontal
+pdfjs-scroll-horizontal-button-label = Defilar orizontal
+pdfjs-scroll-wrapped-button =
+ .title = Utilisar il defilar en colonnas
+pdfjs-scroll-wrapped-button-label = Defilar en colonnas
+pdfjs-spread-none-button =
+ .title = Betg parallelisar las paginas
+pdfjs-spread-none-button-label = Betg parallel
+pdfjs-spread-odd-button =
+ .title = Parallelisar las paginas cun cumenzar cun paginas spèras
+pdfjs-spread-odd-button-label = Parallel spèr
+pdfjs-spread-even-button =
+ .title = Parallelisar las paginas cun cumenzar cun paginas pèras
+pdfjs-spread-even-button-label = Parallel pèr
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Caracteristicas dal document…
+pdfjs-document-properties-button-label = Caracteristicas dal document…
+pdfjs-document-properties-file-name = Num da la datoteca:
+pdfjs-document-properties-file-size = Grondezza da la datoteca:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Autur:
+pdfjs-document-properties-subject = Tema:
+pdfjs-document-properties-keywords = Chavazzins:
+pdfjs-document-properties-creation-date = Data da creaziun:
+pdfjs-document-properties-modification-date = Data da modificaziun:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } { $time }
+pdfjs-document-properties-creator = Creà da:
+pdfjs-document-properties-producer = Creà il PDF cun:
+pdfjs-document-properties-version = Versiun da PDF:
+pdfjs-document-properties-page-count = Dumber da paginas:
+pdfjs-document-properties-page-size = Grondezza da la pagina:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = vertical
+pdfjs-document-properties-page-size-orientation-landscape = orizontal
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Gea
+pdfjs-document-properties-linearized-no = Na
+pdfjs-document-properties-close-button = Serrar
+
+## Print
+
+pdfjs-print-progress-message = Preparar il document per stampar…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Interrumper
+pdfjs-printing-not-supported = Attenziun: Il stampar na funcziunescha anc betg dal tut en quest navigatur.
+pdfjs-printing-not-ready = Attenziun: Il PDF n'è betg chargià cumplettamain per stampar.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Activar/deactivar la trav laterala
+pdfjs-toggle-sidebar-notification-button =
+ .title = Activar/deactivar la trav laterala (il document cuntegna structura dal document/agiuntas/nivels)
+pdfjs-toggle-sidebar-button-label = Activar/deactivar la trav laterala
+pdfjs-document-outline-button =
+ .title = Mussar la structura dal document (cliccar duas giadas per extender/cumprimer tut ils elements)
+pdfjs-document-outline-button-label = Structura dal document
+pdfjs-attachments-button =
+ .title = Mussar agiuntas
+pdfjs-attachments-button-label = Agiuntas
+pdfjs-layers-button =
+ .title = Mussar ils nivels (cliccar dubel per restaurar il stadi da standard da tut ils nivels)
+pdfjs-layers-button-label = Nivels
+pdfjs-thumbs-button =
+ .title = Mussar las miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Tschertgar l'element da structura actual
+pdfjs-current-outline-item-button-label = Element da structura actual
+pdfjs-findbar-button =
+ .title = Tschertgar en il document
+pdfjs-findbar-button-label = Tschertgar
+pdfjs-additional-layers = Nivels supplementars
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura da la pagina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Tschertgar
+ .placeholder = Tschertgar en il document…
+pdfjs-find-previous-button =
+ .title = Tschertgar la posiziun precedenta da l'expressiun
+pdfjs-find-previous-button-label = Enavos
+pdfjs-find-next-button =
+ .title = Tschertgar la proxima posiziun da l'expressiun
+pdfjs-find-next-button-label = Enavant
+pdfjs-find-highlight-checkbox = Relevar tuts
+pdfjs-find-match-case-checkbox-label = Resguardar maiusclas/minusclas
+pdfjs-find-match-diacritics-checkbox-label = Resguardar ils segns diacritics
+pdfjs-find-entire-word-checkbox-label = Pleds entirs
+pdfjs-find-reached-top = Il cumenzament dal document è cuntanschì, la tschertga cuntinuescha a la fin dal document
+pdfjs-find-reached-bottom = La fin dal document è cuntanschì, la tschertga cuntinuescha al cumenzament dal document
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } dad { $total } correspundenza
+ *[other] { $current } da { $total } correspundenzas
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Dapli che { $limit } correspundenza
+ *[other] Dapli che { $limit } correspundenzas
+ }
+pdfjs-find-not-found = Impussibel da chattar l'expressiun
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ladezza da la pagina
+pdfjs-page-scale-fit = Entira pagina
+pdfjs-page-scale-auto = Zoom automatic
+pdfjs-page-scale-actual = Grondezza actuala
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Pagina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ina errur è cumparida cun chargiar il PDF.
+pdfjs-invalid-file-error = Datoteca PDF nunvalida u donnegiada.
+pdfjs-missing-file-error = Datoteca PDF manconta.
+pdfjs-unexpected-response-error = Resposta nunspetgada dal server.
+pdfjs-rendering-error = Ina errur è cumparida cun visualisar questa pagina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Annotaziun da { $type }]
+
+## Password
+
+pdfjs-password-label = Endatescha il pled-clav per avrir questa datoteca da PDF.
+pdfjs-password-invalid = Pled-clav nunvalid. Emprova anc ina giada.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Interrumper
+pdfjs-web-fonts-disabled = Scrittiras dal web èn deactivadas: impussibel dad utilisar las scrittiras integradas en il PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Dissegnar
+pdfjs-editor-ink-button-label = Dissegnar
+pdfjs-editor-stamp-button =
+ .title = Agiuntar u modifitgar maletgs
+pdfjs-editor-stamp-button-label = Agiuntar u modifitgar maletgs
+pdfjs-editor-remove-button =
+ .title = Allontanar
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Allontanar il dissegn
+pdfjs-editor-remove-freetext-button =
+ .title = Allontanar il text
+pdfjs-editor-remove-stamp-button =
+ .title = Allontanar la grafica
+pdfjs-editor-remove-highlight-button =
+ .title = Allontanar l'emfasa
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colur
+pdfjs-editor-free-text-size-input = Grondezza
+pdfjs-editor-ink-color-input = Colur
+pdfjs-editor-ink-thickness-input = Grossezza
+pdfjs-editor-ink-opacity-input = Opacitad
+pdfjs-editor-stamp-add-image-button =
+ .title = Agiuntar in maletg
+pdfjs-editor-stamp-add-image-button-label = Agiuntar in maletg
+pdfjs-free-text =
+ .aria-label = Editur da text
+pdfjs-free-text-default-content = Cumenzar a tippar…
+pdfjs-ink =
+ .aria-label = Editur dissegn
+pdfjs-ink-canvas =
+ .aria-label = Maletg creà da l'utilisader
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Text alternativ
+pdfjs-editor-alt-text-edit-button-label = Modifitgar il text alternativ
+pdfjs-editor-alt-text-dialog-label = Tscherner ina opziun
+pdfjs-editor-alt-text-dialog-description = Il text alternativ (alt text) gida en cas che persunas na vesan betg il maletg u sch'i na reussescha betg d'al chargiar.
+pdfjs-editor-alt-text-add-description-label = Agiuntar ina descripziun
+pdfjs-editor-alt-text-add-description-description = Scriva idealmain 1-2 frasas che descrivan l'object, la situaziun u las acziuns.
+pdfjs-editor-alt-text-mark-decorative-label = Marcar sco decorativ
+pdfjs-editor-alt-text-mark-decorative-description = Quai vegn duvrà per maletgs ornamentals, sco urs u filigranas.
+pdfjs-editor-alt-text-cancel-button = Interrumper
+pdfjs-editor-alt-text-save-button = Memorisar
+pdfjs-editor-alt-text-decorative-tooltip = Marcà sco decorativ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Per exempel: «In um giuven sesa a maisa per mangiar in past»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Chantun sura a sanestra — redimensiunar
+pdfjs-editor-resizer-label-top-middle = Sura amez — redimensiunar
+pdfjs-editor-resizer-label-top-right = Chantun sura a dretga — redimensiunar
+pdfjs-editor-resizer-label-middle-right = Da vart dretga amez — redimensiunar
+pdfjs-editor-resizer-label-bottom-right = Chantun sut a dretga — redimensiunar
+pdfjs-editor-resizer-label-bottom-middle = Sutvart amez — redimensiunar
+pdfjs-editor-resizer-label-bottom-left = Chantun sut a sanestra — redimensiunar
+pdfjs-editor-resizer-label-middle-left = Vart sanestra amez — redimensiunar
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Colur per l'emfasa
+pdfjs-editor-colorpicker-button =
+ .title = Midar la colur
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Colurs disponiblas
+pdfjs-editor-colorpicker-yellow =
+ .title = Mellen
+pdfjs-editor-colorpicker-green =
+ .title = Verd
+pdfjs-editor-colorpicker-blue =
+ .title = Blau
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Cotschen
diff --git a/www/lib/pdfjs/modern/web/locale/ro/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ro/viewer.ftl
new file mode 100644
index 000000000..7c6f0b6a3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ro/viewer.ftl
@@ -0,0 +1,251 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pagina precedentă
+pdfjs-previous-button-label = ÃŽnapoi
+pdfjs-next-button =
+ .title = Pagina următoare
+pdfjs-next-button-label = ÃŽnainte
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pagina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = din { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } din { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Micșorează
+pdfjs-zoom-out-button-label = Micșorează
+pdfjs-zoom-in-button =
+ .title = Mărește
+pdfjs-zoom-in-button-label = Mărește
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Comută la modul de prezentare
+pdfjs-presentation-mode-button-label = Mod de prezentare
+pdfjs-open-file-button =
+ .title = Deschide un fișier
+pdfjs-open-file-button-label = Deschide
+pdfjs-print-button =
+ .title = Tipărește
+pdfjs-print-button-label = Tipărește
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Instrumente
+pdfjs-tools-button-label = Instrumente
+pdfjs-first-page-button =
+ .title = Mergi la prima pagină
+pdfjs-first-page-button-label = Mergi la prima pagină
+pdfjs-last-page-button =
+ .title = Mergi la ultima pagină
+pdfjs-last-page-button-label = Mergi la ultima pagină
+pdfjs-page-rotate-cw-button =
+ .title = Rotește în sensul acelor de ceas
+pdfjs-page-rotate-cw-button-label = Rotește în sensul acelor de ceas
+pdfjs-page-rotate-ccw-button =
+ .title = Rotește în sens invers al acelor de ceas
+pdfjs-page-rotate-ccw-button-label = Rotește în sens invers al acelor de ceas
+pdfjs-cursor-text-select-tool-button =
+ .title = Activează instrumentul de selecție a textului
+pdfjs-cursor-text-select-tool-button-label = Instrumentul de selecție a textului
+pdfjs-cursor-hand-tool-button =
+ .title = Activează instrumentul mână
+pdfjs-cursor-hand-tool-button-label = Unealta mână
+pdfjs-scroll-vertical-button =
+ .title = Folosește derularea verticală
+pdfjs-scroll-vertical-button-label = Derulare verticală
+pdfjs-scroll-horizontal-button =
+ .title = Folosește derularea orizontală
+pdfjs-scroll-horizontal-button-label = Derulare orizontală
+pdfjs-scroll-wrapped-button =
+ .title = Folosește derularea încadrată
+pdfjs-scroll-wrapped-button-label = Derulare încadrată
+pdfjs-spread-none-button =
+ .title = Nu uni paginile broșate
+pdfjs-spread-none-button-label = Fără pagini broșate
+pdfjs-spread-odd-button =
+ .title = Unește paginile broșate începând cu cele impare
+pdfjs-spread-odd-button-label = Broșare pagini impare
+pdfjs-spread-even-button =
+ .title = Unește paginile broșate începând cu cele pare
+pdfjs-spread-even-button-label = Broșare pagini pare
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Proprietățile documentului…
+pdfjs-document-properties-button-label = Proprietățile documentului…
+pdfjs-document-properties-file-name = Numele fișierului:
+pdfjs-document-properties-file-size = Mărimea fișierului:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } byți)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byți)
+pdfjs-document-properties-title = Titlu:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Subiect:
+pdfjs-document-properties-keywords = Cuvinte cheie:
+pdfjs-document-properties-creation-date = Data creării:
+pdfjs-document-properties-modification-date = Data modificării:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Autor:
+pdfjs-document-properties-producer = Producător PDF:
+pdfjs-document-properties-version = Versiune PDF:
+pdfjs-document-properties-page-count = Număr de pagini:
+pdfjs-document-properties-page-size = Mărimea paginii:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = verticală
+pdfjs-document-properties-page-size-orientation-landscape = orizontală
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Literă
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vizualizare web rapidă:
+pdfjs-document-properties-linearized-yes = Da
+pdfjs-document-properties-linearized-no = Nu
+pdfjs-document-properties-close-button = ÃŽnchide
+
+## Print
+
+pdfjs-print-progress-message = Se pregătește documentul pentru tipărire…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Renunță
+pdfjs-printing-not-supported = Avertisment: Tipărirea nu este suportată în totalitate de acest browser.
+pdfjs-printing-not-ready = Avertisment: PDF-ul nu este încărcat complet pentru tipărire.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Comută bara laterală
+pdfjs-toggle-sidebar-button-label = Comută bara laterală
+pdfjs-document-outline-button =
+ .title = Afișează schița documentului (dublu-clic pentru a extinde/restrânge toate elementele)
+pdfjs-document-outline-button-label = Schița documentului
+pdfjs-attachments-button =
+ .title = Afișează atașamentele
+pdfjs-attachments-button-label = Atașamente
+pdfjs-thumbs-button =
+ .title = Afișează miniaturi
+pdfjs-thumbs-button-label = Miniaturi
+pdfjs-findbar-button =
+ .title = Caută în document
+pdfjs-findbar-button-label = Caută
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pagina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura paginii { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Caută
+ .placeholder = Caută în document…
+pdfjs-find-previous-button =
+ .title = Mergi la apariția anterioară a textului
+pdfjs-find-previous-button-label = ÃŽnapoi
+pdfjs-find-next-button =
+ .title = Mergi la apariția următoare a textului
+pdfjs-find-next-button-label = ÃŽnainte
+pdfjs-find-highlight-checkbox = Evidențiază toate aparițiile
+pdfjs-find-match-case-checkbox-label = Ține cont de majuscule și minuscule
+pdfjs-find-entire-word-checkbox-label = Cuvinte întregi
+pdfjs-find-reached-top = Am ajuns la începutul documentului, continuă de la sfârșit
+pdfjs-find-reached-bottom = Am ajuns la sfârșitul documentului, continuă de la început
+pdfjs-find-not-found = Nu s-a găsit textul
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lățime pagină
+pdfjs-page-scale-fit = Potrivire la pagină
+pdfjs-page-scale-auto = Zoom automat
+pdfjs-page-scale-actual = Mărime reală
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = A intervenit o eroare la încărcarea PDF-ului.
+pdfjs-invalid-file-error = Fișier PDF nevalid sau corupt.
+pdfjs-missing-file-error = Fișier PDF lipsă.
+pdfjs-unexpected-response-error = Răspuns neașteptat de la server.
+pdfjs-rendering-error = A intervenit o eroare la randarea paginii.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Adnotare { $type }]
+
+## Password
+
+pdfjs-password-label = Introdu parola pentru a deschide acest fișier PDF.
+pdfjs-password-invalid = Parolă nevalidă. Te rugăm să încerci din nou.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Renunță
+pdfjs-web-fonts-disabled = Fonturile web sunt dezactivate: nu se pot folosi fonturile PDF încorporate.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ru/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ru/viewer.ftl
new file mode 100644
index 000000000..a2172138d
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ru/viewer.ftl
@@ -0,0 +1,386 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ñтраница
+pdfjs-previous-button-label = ПредыдущаÑ
+pdfjs-next-button =
+ .title = Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтраница
+pdfjs-next-button-label = СледующаÑ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Страница
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = из { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } из { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Уменьшить
+pdfjs-zoom-out-button-label = Уменьшить
+pdfjs-zoom-in-button =
+ .title = Увеличить
+pdfjs-zoom-in-button-label = Увеличить
+pdfjs-zoom-select =
+ .title = МаÑштаб
+pdfjs-presentation-mode-button =
+ .title = Перейти в режим презентации
+pdfjs-presentation-mode-button-label = Режим презентации
+pdfjs-open-file-button =
+ .title = Открыть файл
+pdfjs-open-file-button-label = Открыть
+pdfjs-print-button =
+ .title = Печать
+pdfjs-print-button-label = Печать
+pdfjs-save-button =
+ .title = Сохранить
+pdfjs-save-button-label = Сохранить
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Загрузить
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Загрузить
+pdfjs-bookmark-button =
+ .title = Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ñтраница (проÑмотр URL-адреÑа Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ Ñтраницы)
+pdfjs-bookmark-button-label = Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ñтраница
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Открыть в приложении
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Открыть в программе
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ИнÑтрументы
+pdfjs-tools-button-label = ИнÑтрументы
+pdfjs-first-page-button =
+ .title = Перейти на первую Ñтраницу
+pdfjs-first-page-button-label = Перейти на первую Ñтраницу
+pdfjs-last-page-button =
+ .title = Перейти на поÑледнюю Ñтраницу
+pdfjs-last-page-button-label = Перейти на поÑледнюю Ñтраницу
+pdfjs-page-rotate-cw-button =
+ .title = Повернуть по чаÑовой Ñтрелке
+pdfjs-page-rotate-cw-button-label = Повернуть по чаÑовой Ñтрелке
+pdfjs-page-rotate-ccw-button =
+ .title = Повернуть против чаÑовой Ñтрелки
+pdfjs-page-rotate-ccw-button-label = Повернуть против чаÑовой Ñтрелки
+pdfjs-cursor-text-select-tool-button =
+ .title = Включить ИнÑтрумент «Выделение текÑта»
+pdfjs-cursor-text-select-tool-button-label = ИнÑтрумент «Выделение текÑта»
+pdfjs-cursor-hand-tool-button =
+ .title = Включить ИнÑтрумент «Рука»
+pdfjs-cursor-hand-tool-button-label = ИнÑтрумент «Рука»
+pdfjs-scroll-page-button =
+ .title = ИÑпользовать прокрутку Ñтраниц
+pdfjs-scroll-page-button-label = Прокрутка Ñтраниц
+pdfjs-scroll-vertical-button =
+ .title = ИÑпользовать вертикальную прокрутку
+pdfjs-scroll-vertical-button-label = Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-scroll-horizontal-button =
+ .title = ИÑпользовать горизонтальную прокрутку
+pdfjs-scroll-horizontal-button-label = Ð“Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-scroll-wrapped-button =
+ .title = ИÑпользовать маÑштабируемую прокрутку
+pdfjs-scroll-wrapped-button-label = МаÑÑˆÑ‚Ð°Ð±Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ°
+pdfjs-spread-none-button =
+ .title = Ðе иÑпользовать режим разворотов Ñтраниц
+pdfjs-spread-none-button-label = Без разворотов Ñтраниц
+pdfjs-spread-odd-button =
+ .title = Развороты начинаютÑÑ Ñ Ð½ÐµÑ‡Ñ‘Ñ‚Ð½Ñ‹Ñ… номеров Ñтраниц
+pdfjs-spread-odd-button-label = Ðечётные Ñтраницы Ñлева
+pdfjs-spread-even-button =
+ .title = Развороты начинаютÑÑ Ñ Ñ‡Ñ‘Ñ‚Ð½Ñ‹Ñ… номеров Ñтраниц
+pdfjs-spread-even-button-label = Чётные Ñтраницы Ñлева
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = СвойÑтва документа…
+pdfjs-document-properties-button-label = СвойÑтва документа…
+pdfjs-document-properties-file-name = Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°:
+pdfjs-document-properties-file-size = Размер файла:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } байт)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } байт)
+pdfjs-document-properties-title = Заголовок:
+pdfjs-document-properties-author = Ðвтор:
+pdfjs-document-properties-subject = Тема:
+pdfjs-document-properties-keywords = Ключевые Ñлова:
+pdfjs-document-properties-creation-date = Дата ÑозданиÑ:
+pdfjs-document-properties-modification-date = Дата изменениÑ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Приложение:
+pdfjs-document-properties-producer = Производитель PDF:
+pdfjs-document-properties-version = ВерÑÐ¸Ñ PDF:
+pdfjs-document-properties-page-count = ЧиÑло Ñтраниц:
+pdfjs-document-properties-page-size = Размер Ñтраницы:
+pdfjs-document-properties-page-size-unit-inches = дюймов
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = книжнаÑ
+pdfjs-document-properties-page-size-orientation-landscape = альбомнаÑ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = БыÑтрый проÑмотр в Web:
+pdfjs-document-properties-linearized-yes = Да
+pdfjs-document-properties-linearized-no = Ðет
+pdfjs-document-properties-close-button = Закрыть
+
+## Print
+
+pdfjs-print-progress-message = Подготовка документа к печати…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Отмена
+pdfjs-printing-not-supported = Предупреждение: Ð’ Ñтом браузере не полноÑтью поддерживаетÑÑ Ð¿ÐµÑ‡Ð°Ñ‚ÑŒ.
+pdfjs-printing-not-ready = Предупреждение: PDF не полноÑтью загружен Ð´Ð»Ñ Ð¿ÐµÑ‡Ð°Ñ‚Ð¸.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Показать/Ñкрыть боковую панель
+pdfjs-toggle-sidebar-notification-button =
+ .title = Показать/Ñкрыть боковую панель (документ имеет Ñодержание/вложениÑ/Ñлои)
+pdfjs-toggle-sidebar-button-label = Показать/Ñкрыть боковую панель
+pdfjs-document-outline-button =
+ .title = Показать Ñодержание документа (двойной щелчок, чтобы развернуть/Ñвернуть вÑе Ñлементы)
+pdfjs-document-outline-button-label = Содержание документа
+pdfjs-attachments-button =
+ .title = Показать вложениÑ
+pdfjs-attachments-button-label = ВложениÑ
+pdfjs-layers-button =
+ .title = Показать Ñлои (дважды щёлкните, чтобы ÑброÑить вÑе Ñлои к ÑоÑтоÑнию по умолчанию)
+pdfjs-layers-button-label = Слои
+pdfjs-thumbs-button =
+ .title = Показать миниатюры
+pdfjs-thumbs-button-label = Миниатюры
+pdfjs-current-outline-item-button =
+ .title = Ðайти текущий Ñлемент Ñтруктуры
+pdfjs-current-outline-item-button-label = Текущий Ñлемент Ñтруктуры
+pdfjs-findbar-button =
+ .title = Ðайти в документе
+pdfjs-findbar-button-label = Ðайти
+pdfjs-additional-layers = Дополнительные Ñлои
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Страница { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Миниатюра Ñтраницы { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Ðайти
+ .placeholder = Ðайти в документе…
+pdfjs-find-previous-button =
+ .title = Ðайти предыдущее вхождение фразы в текÑÑ‚
+pdfjs-find-previous-button-label = Ðазад
+pdfjs-find-next-button =
+ .title = Ðайти Ñледующее вхождение фразы в текÑÑ‚
+pdfjs-find-next-button-label = Далее
+pdfjs-find-highlight-checkbox = ПодÑветить вÑе
+pdfjs-find-match-case-checkbox-label = С учётом региÑтра
+pdfjs-find-match-diacritics-checkbox-label = С учётом диакритичеÑких знаков
+pdfjs-find-entire-word-checkbox-label = Слова целиком
+pdfjs-find-reached-top = ДоÑтигнут верх документа, продолжено Ñнизу
+pdfjs-find-reached-bottom = ДоÑтигнут конец документа, продолжено Ñверху
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } из { $total } ÑовпадениÑ
+ [few] { $current } из { $total } Ñовпадений
+ *[many] { $current } из { $total } Ñовпадений
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Более { $limit } ÑовпадениÑ
+ [few] Более { $limit } Ñовпадений
+ *[many] Более { $limit } Ñовпадений
+ }
+pdfjs-find-not-found = Фраза не найдена
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = По ширине Ñтраницы
+pdfjs-page-scale-fit = По размеру Ñтраницы
+pdfjs-page-scale-auto = ÐвтоматичеÑки
+pdfjs-page-scale-actual = Реальный размер
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Страница { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = При загрузке PDF произошла ошибка.
+pdfjs-invalid-file-error = Ðекорректный или повреждённый PDF-файл.
+pdfjs-missing-file-error = PDF-файл отÑутÑтвует.
+pdfjs-unexpected-response-error = Ðеожиданный ответ Ñервера.
+pdfjs-rendering-error = При Ñоздании Ñтраницы произошла ошибка.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ { $type }]
+
+## Password
+
+pdfjs-password-label = Введите пароль, чтобы открыть Ñтот PDF-файл.
+pdfjs-password-invalid = Ðеверный пароль. ПожалуйÑта, попробуйте Ñнова.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Отмена
+pdfjs-web-fonts-disabled = Веб-шрифты отключены: не удалоÑÑŒ задейÑтвовать вÑтроенные PDF-шрифты.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ТекÑÑ‚
+pdfjs-editor-free-text-button-label = ТекÑÑ‚
+pdfjs-editor-ink-button =
+ .title = РиÑовать
+pdfjs-editor-ink-button-label = РиÑовать
+pdfjs-editor-stamp-button =
+ .title = Добавить или изменить изображениÑ
+pdfjs-editor-stamp-button-label = Добавить или изменить изображениÑ
+pdfjs-editor-remove-button =
+ .title = Удалить
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Удалить риÑунок
+pdfjs-editor-remove-freetext-button =
+ .title = Удалить текÑÑ‚
+pdfjs-editor-remove-stamp-button =
+ .title = Удалить изображение
+pdfjs-editor-remove-highlight-button =
+ .title = Удалить выделение
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Цвет
+pdfjs-editor-free-text-size-input = Размер
+pdfjs-editor-ink-color-input = Цвет
+pdfjs-editor-ink-thickness-input = Толщина
+pdfjs-editor-ink-opacity-input = ПрозрачноÑÑ‚ÑŒ
+pdfjs-editor-stamp-add-image-button =
+ .title = Добавить изображение
+pdfjs-editor-stamp-add-image-button-label = Добавить изображение
+pdfjs-free-text =
+ .aria-label = ТекÑтовый редактор
+pdfjs-free-text-default-content = Ðачните вводить…
+pdfjs-ink =
+ .aria-label = Редактор риÑованиÑ
+pdfjs-ink-canvas =
+ .aria-label = Созданное пользователем изображение
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Ðльтернативный текÑÑ‚
+pdfjs-editor-alt-text-edit-button-label = Изменить альтернативный текÑÑ‚
+pdfjs-editor-alt-text-dialog-label = Выберите вариант
+pdfjs-editor-alt-text-dialog-description = Ðльтернативный текÑÑ‚ помогает, когда люди не видÑÑ‚ изображение или оно не загружаетÑÑ.
+pdfjs-editor-alt-text-add-description-label = Добавить опиÑание
+pdfjs-editor-alt-text-add-description-description = СтарайтеÑÑŒ ÑоÑтавлÑÑ‚ÑŒ 1–2 предложениÑ, опиÑывающих предмет, обÑтановку или дейÑтвиÑ.
+pdfjs-editor-alt-text-mark-decorative-label = Отметить как декоративное
+pdfjs-editor-alt-text-mark-decorative-description = ИÑпользуетÑÑ Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ñ… изображений, таких как рамки или водÑные знаки.
+pdfjs-editor-alt-text-cancel-button = Отменить
+pdfjs-editor-alt-text-save-button = Сохранить
+pdfjs-editor-alt-text-decorative-tooltip = Помечен как декоративный
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Ðапример: «Молодой человек ÑадитÑÑ Ð·Ð° Ñтол, чтобы поеÑть»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Левый верхний угол — изменить размер
+pdfjs-editor-resizer-label-top-middle = Вверху поÑередине — изменить размер
+pdfjs-editor-resizer-label-top-right = Верхний правый угол — изменить размер
+pdfjs-editor-resizer-label-middle-right = Ð’ центре Ñправа — изменить размер
+pdfjs-editor-resizer-label-bottom-right = Ðижний правый угол — изменить размер
+pdfjs-editor-resizer-label-bottom-middle = Внизу поÑередине — изменить размер
+pdfjs-editor-resizer-label-bottom-left = Ðижний левый угол — изменить размер
+pdfjs-editor-resizer-label-middle-left = Ð’ центре Ñлева — изменить размер
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Цвет выделениÑ
+pdfjs-editor-colorpicker-button =
+ .title = Изменить цвет
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Выбор цвета
+pdfjs-editor-colorpicker-yellow =
+ .title = Жёлтый
+pdfjs-editor-colorpicker-green =
+ .title = Зелёный
+pdfjs-editor-colorpicker-blue =
+ .title = Синий
+pdfjs-editor-colorpicker-pink =
+ .title = Розовый
+pdfjs-editor-colorpicker-red =
+ .title = КраÑный
diff --git a/www/lib/pdfjs/modern/web/locale/sat/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sat/viewer.ftl
new file mode 100644
index 000000000..90f12a314
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sat/viewer.ftl
@@ -0,0 +1,311 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ᱢᱟᱲᱟᱠᱥᱟᱦᱴᱟ
+pdfjs-previous-button-label = ᱢᱟᱲᱟá±á±Ÿá±œ
+pdfjs-next-button =
+ .title = ᱤᱱᱟᱹ ᱛᱟá±á±šá±¢ ᱥᱟᱦᱴᱟ
+pdfjs-next-button-label = ᱤᱱᱟᱹ ᱛᱟá±á±šá±¢
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ᱥᱟᱦᱴᱟ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = ᱨᱮá±á±Ÿá±œ { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } ᱠᱷᱚᱱ { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ᱦᱤᱲᱤᱧ ᱛᱮá±á±Ÿá±¨
+pdfjs-zoom-out-button-label = ᱦᱤᱲᱤᱧ ᱛᱮá±á±Ÿá±¨
+pdfjs-zoom-in-button =
+ .title = ᱢᱟᱨᱟᱠᱛᱮá±á±Ÿá±¨
+pdfjs-zoom-in-button-label = ᱢᱟᱨᱟᱠᱛᱮá±á±Ÿá±¨
+pdfjs-zoom-select =
+ .title = ᱡᱩᱢ
+pdfjs-presentation-mode-button =
+ .title = ᱩᱫᱩᱜ ᱥᱚᱫᱚᱨ ᱚᱵᱚᱥᱛᱟ ᱨᱮ ᱚᱛᱟᱠᱢᱮ
+pdfjs-presentation-mode-button-label = ᱩᱫᱩᱜ ᱥᱚᱫᱚᱨ ᱚᱵᱚᱥᱛᱟ ᱨᱮ
+pdfjs-open-file-button =
+ .title = ᱨᱮᱫ ᱡᱷᱤᱡᱽ ᱢᱮ
+pdfjs-open-file-button-label = ᱡᱷᱤᱡᱽ ᱢᱮ
+pdfjs-print-button =
+ .title = ᱪᱷᱟᱯᱟ
+pdfjs-print-button-label = ᱪᱷᱟᱯᱟ
+pdfjs-save-button =
+ .title = ᱥᱟᱺᱪᱟᱣ ᱢᱮ
+pdfjs-save-button-label = ᱥᱟᱺᱪᱟᱣ ᱢᱮ
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ᱰᱟᱣᱩᱱᱞᱚᱰ
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ᱰᱟᱣᱩᱱᱞᱚᱰ
+pdfjs-bookmark-button =
+ .title = ᱱᱤᱛᱚᱜᱟᱜ ᱥᱟᱦᱴᱟ (ᱱᱤᱛᱚᱜᱟᱜ ᱥᱟᱦᱴᱟ ᱠᱷᱚᱱ URL ᱫᱮᱠᱷᱟᱣ ᱢᱮ)
+pdfjs-bookmark-button-label = ᱱᱤᱛᱚᱜᱟᱜ ᱥᱟᱦᱴᱟ
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = ᱮᱯ ᱨᱮ ᱡᱷᱤᱡᱽ ᱢᱮ
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = ᱮᱯ ᱨᱮ ᱡᱷᱤᱡᱽ ᱢᱮ
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ᱦᱟᱹᱛᱤá±á±Ÿá±¹á±¨ ᱠᱚ
+pdfjs-tools-button-label = ᱦᱟᱹᱛᱤá±á±Ÿá±¹á±¨ ᱠᱚ
+pdfjs-first-page-button =
+ .title = ᱯᱩá±á±žá±© ᱥᱟᱦᱴᱟ ᱥᱮᱫ ᱪᱟᱞᱟᱜ ᱢᱮ
+pdfjs-first-page-button-label = ᱯᱩá±á±žá±© ᱥᱟᱦᱴᱟ ᱥᱮᱫ ᱪᱟᱞᱟᱜ ᱢᱮ
+pdfjs-last-page-button =
+ .title = ᱢᱩᱪᱟᱹᱫ ᱥᱟᱦᱴᱟ ᱥᱮᱫ ᱪᱟᱞᱟᱜ ᱢᱮ
+pdfjs-last-page-button-label = ᱢᱩᱪᱟᱹᱫ ᱥᱟᱦᱴᱟ ᱥᱮᱫ ᱪᱟᱞᱟᱜ ᱢᱮ
+pdfjs-page-rotate-cw-button =
+ .title = ᱜᱷᱚᱰᱤ ᱦᱤᱥᱟᱹᱵ ᱛᱮ ᱟᱹᱪᱩᱨ
+pdfjs-page-rotate-cw-button-label = ᱜᱷᱚᱰᱤ ᱦᱤᱥᱟᱹᱵ ᱛᱮ ᱟᱹᱪᱩᱨ
+pdfjs-page-rotate-ccw-button =
+ .title = ᱜᱷᱚᱰᱤ ᱦᱤᱥᱟᱹᱵ ᱛᱮ ᱩᱞᱴᱟᱹ ᱟᱹᱪᱩᱨ
+pdfjs-page-rotate-ccw-button-label = ᱜᱷᱚᱰᱤ ᱦᱤᱥᱟᱹᱵ ᱛᱮ ᱩᱞᱴᱟᱹ ᱟᱹᱪᱩᱨ
+pdfjs-cursor-text-select-tool-button =
+ .title = ᱚᱞ ᱵᱟᱪᱷᱟᱣ ᱦᱟᱹᱛᱤá±á±Ÿá±¨ ᱮᱢ ᱪᱷᱚᱠᱢᱮ
+pdfjs-cursor-text-select-tool-button-label = ᱚᱞ ᱵᱟᱪᱷᱟᱣ ᱦᱟᱹᱛᱤá±á±Ÿá±¨
+pdfjs-cursor-hand-tool-button =
+ .title = ᱛᱤ ᱦᱟᱹᱛᱤá±á±Ÿá±¨ ᱮᱢ ᱪᱷᱚᱠᱢᱮ
+pdfjs-cursor-hand-tool-button-label = ᱛᱤ ᱦᱟᱹᱛᱤá±á±Ÿá±¨
+pdfjs-scroll-page-button =
+ .title = ᱥᱟᱦᱴᱟ ᱜᱩᱲᱟᱹᱣ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+pdfjs-scroll-page-button-label = ᱥᱟᱦᱴᱟ ᱜᱩᱲᱟᱹᱣ
+pdfjs-scroll-vertical-button =
+ .title = ᱥᱤᱫᱽ ᱜᱩᱲᱟᱹᱣ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+pdfjs-scroll-vertical-button-label = ᱥᱤᱫᱽ ᱜᱩᱲᱟᱹᱣ
+pdfjs-scroll-horizontal-button =
+ .title = ᱜᱤᱛᱤᱡ ᱛᱮ ᱜᱩᱲᱟᱹᱣ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+pdfjs-scroll-horizontal-button-label = ᱜᱤᱛᱤᱡ ᱛᱮ ᱜᱩᱲᱟᱹᱣ
+pdfjs-scroll-wrapped-button =
+ .title = ᱞᱤᱯᱴᱟᱹᱣ ᱜᱩᱰᱨᱟᱹᱣ ᱵᱮᱵᱷᱟᱨ ᱢᱮ
+pdfjs-scroll-wrapped-button-label = ᱞᱤᱯᱴᱟᱣ ᱜᱩᱰᱨᱟᱹᱣ
+pdfjs-spread-none-button =
+ .title = ᱟᱞᱚᱢ ᱡᱚᱲᱟᱣ ᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱯᱟᱥᱱᱟᱣᱜᱼᱟ
+pdfjs-spread-none-button-label = ᱯᱟᱥᱱᱟᱣ ᱵᱟᱹᱱᱩᱜᱼᱟ
+pdfjs-spread-odd-button =
+ .title = ᱥᱟᱦᱴᱟ ᱯᱟᱥᱱᱟᱣ ᱡᱚᱲᱟᱣ ᱢᱮ ᱡᱟᱦᱟᱸ ᱫᱚ ᱚᱰᱼᱮᱞ ᱥᱟᱦᱴᱟᱠᱚ ᱥᱟᱞᱟᱜ ᱮᱛᱦᱚᱵᱚᱜ ᱠᱟᱱᱟ
+pdfjs-spread-odd-button-label = ᱚᱰ ᱯᱟᱥᱱᱟᱣ
+pdfjs-spread-even-button =
+ .title = ᱥᱟᱦᱴᱟ ᱯᱟᱥᱱᱟᱣ ᱡᱚᱲᱟᱣ ᱢᱮ ᱡᱟᱦᱟᱸ ᱫᱚ ᱤᱣᱮᱱᱼᱮᱞ ᱥᱟᱦᱴᱟᱠᱚ ᱥᱟᱞᱟᱜ ᱮᱛᱦᱚᱵᱚᱜ ᱠᱟᱱᱟ
+pdfjs-spread-even-button-label = ᱯᱟᱥᱱᱟᱣ ᱤᱣᱮᱱ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ᱫᱚᱞᱤᱞ ᱜᱩᱱᱠᱚ …
+pdfjs-document-properties-button-label = ᱫᱚᱞᱤᱞ ᱜᱩᱱᱠᱚ …
+pdfjs-document-properties-file-name = ᱨᱮᱫᱽ ᱧᱩᱛᱩᱢ :
+pdfjs-document-properties-file-size = ᱨᱮᱫᱽ ᱢᱟᱯ :
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ᱵᱟá±á±¤á±´ ᱠᱚ)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ᱵᱟá±á±¤á±´ ᱠᱚ)
+pdfjs-document-properties-title = ᱧᱩᱛᱩᱢ :
+pdfjs-document-properties-author = ᱚᱱᱚᱞᱤá±á±Ÿá±¹ :
+pdfjs-document-properties-subject = ᱵᱤᱥᱚᱠ:
+pdfjs-document-properties-keywords = ᱠᱟᱹᱴᱷᱤ ᱥᱟᱵᱟᱫᱽ :
+pdfjs-document-properties-creation-date = ᱛᱮá±á±Ÿá±¨ ᱢᱟᱸᱦᱤᱛ :
+pdfjs-document-properties-modification-date = ᱵᱚᱫᱚᱞ ᱦᱚᱪᱚ ᱢᱟᱹᱦᱤᱛ :
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ᱵᱮᱱᱟᱣᱤᱡ :
+pdfjs-document-properties-producer = PDF ᱛᱮá±á±Ÿá±¨ ᱚᱰᱚᱠᱤᱡ :
+pdfjs-document-properties-version = PDF ᱵᱷᱟᱹᱨᱥᱚᱱ :
+pdfjs-document-properties-page-count = ᱥᱟᱦᱴᱟ ᱞᱮᱠᱷᱟ :
+pdfjs-document-properties-page-size = ᱥᱟᱦᱴᱟ ᱢᱟᱯ :
+pdfjs-document-properties-page-size-unit-inches = ᱤᱧᱪ
+pdfjs-document-properties-page-size-unit-millimeters = ᱢᱤᱢᱤ
+pdfjs-document-properties-page-size-orientation-portrait = ᱯᱚᱴᱨᱮᱴ
+pdfjs-document-properties-page-size-orientation-landscape = ᱞᱮᱱᱰᱥᱠᱮᱯ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ᱪᱤᱴᱷᱤ
+pdfjs-document-properties-page-size-name-legal = ᱠᱟᱹᱱᱩᱱᱤ
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = ᱞᱚᱜᱚᱱ ᱣᱮᱵᱽ ᱧᱮᱞ :
+pdfjs-document-properties-linearized-yes = ᱦᱚá±
+pdfjs-document-properties-linearized-no = ᱵᱟá±
+pdfjs-document-properties-close-button = ᱵᱚᱸᱫᱚᱠᱢᱮ
+
+## Print
+
+pdfjs-print-progress-message = ᱪᱷᱟᱯᱟ ᱞᱟᱹᱜᱤᱫ ᱫᱚᱞᱤᱞ ᱛᱮá±á±Ÿá±¨á±šá±œ ᱠᱟᱱᱟ …
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ᱵᱟᱹᱰᱨᱟᱹ
+pdfjs-printing-not-supported = ᱦᱚᱥᱤá±á±Ÿá±¨ : ᱪᱷᱟᱯᱟ ᱱᱚᱣᱟ ᱯᱟᱱᱛᱮá±á±Ÿá±œ ᱫᱟᱨᱟᱠᱛᱮ ᱯᱩᱨᱟᱹᱣ ᱵᱟᱠᱜᱚᱲᱚᱣᱟᱠᱟᱱᱟ á±¾
+pdfjs-printing-not-ready = ᱦᱩᱥᱤá±á±Ÿá±¹á±¨ : ᱪᱷᱟᱯᱟ ᱞᱟᱹᱜᱤᱫ PDF ᱯᱩᱨᱟᱹ ᱵᱟᱠᱞᱟᱫᱮ ᱟᱠᱟᱱᱟ á±¾
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = ᱫᱷᱟᱨᱮᱵᱟᱨ ᱥᱮᱫ ᱩᱪᱟᱹᱲᱚᱜ ᱢᱮ
+pdfjs-toggle-sidebar-notification-button =
+ .title = ᱫᱷᱟᱨᱮᱵᱟᱨ ᱥᱮᱫ ᱩᱪᱟᱹᱲᱚᱜ ᱢᱮ (ᱫᱚᱞᱤᱞ ᱨᱮ ᱟᱣᱴᱞᱟá±á±¤á±¢ ᱢᱮᱱᱟᱜᱼᱟ/ᱞᱟᱪᱷᱟᱠᱚ/ᱯᱚᱨᱚᱛᱠᱚ)
+pdfjs-toggle-sidebar-button-label = ᱫᱷᱟᱨᱮᱵᱟᱨ ᱥᱮᱫ ᱩᱪᱟᱹᱲᱚᱜ ᱢᱮ
+pdfjs-document-outline-button =
+ .title = ᱫᱚᱞᱚᱞ ᱟᱣᱴᱞᱟá±á±¤á±± ᱫᱮᱠᱷᱟᱣ ᱢᱮ (ᱡᱷᱚᱛᱚ ᱡᱤᱱᱤᱥᱠᱚ ᱵᱟᱨ ᱡᱮᱠᱷᱟ ᱚᱛᱟ ᱠᱮᱛᱮ ᱡᱷᱟᱹᱞ/ᱦᱩᱰᱤᱧ ᱪᱷᱚᱠᱢᱮ)
+pdfjs-document-outline-button-label = ᱫᱚᱞᱤᱞ ᱛᱮá±á±Ÿá±¨ ᱛᱮᱫ
+pdfjs-attachments-button =
+ .title = ᱞᱟᱴᱷᱟ ᱥᱮᱞᱮᱫ ᱠᱚ ᱩᱫᱩᱜᱽ ᱢᱮ
+pdfjs-attachments-button-label = ᱞᱟᱴᱷᱟ ᱥᱮᱞᱮᱫ ᱠᱚ
+pdfjs-layers-button =
+ .title = ᱯᱚᱨᱚᱛ ᱫᱮᱠᱷᱟᱣ ᱢᱮ (ᱢᱩᱞ ᱡᱟá±á±œá±Ÿ ᱛᱮ ᱡᱷᱚᱛᱚ ᱯᱚᱨᱚᱛᱠᱚ ᱨᱤᱥᱮᱴ ᱞᱟᱹᱜᱤᱫ ᱵᱟᱨ ᱡᱮᱠᱷᱟ ᱚᱛᱚᱠᱢᱮ)
+pdfjs-layers-button-label = ᱯᱚᱨᱚᱛᱠᱚ
+pdfjs-thumbs-button =
+ .title = ᱪᱤᱛᱟᱹᱨ ᱟᱦᱞᱟ ᱠᱚ ᱩᱫᱩᱜᱽ ᱢᱮ
+pdfjs-thumbs-button-label = ᱪᱤᱛᱟᱹᱨ ᱟᱦᱞᱟ ᱠᱚ
+pdfjs-current-outline-item-button =
+ .title = ᱱᱤᱛᱚᱜᱟᱜ ᱟᱣᱴᱞᱟá±á±¤á±± ᱡᱟᱱᱤᱥ ᱯᱟᱱᱛᱮ ᱢᱮ
+pdfjs-current-outline-item-button-label = ᱱᱤᱛᱚᱜᱟᱜ ᱟᱣᱴᱞᱟá±á±¤á±± ᱡᱟᱱᱤᱥ
+pdfjs-findbar-button =
+ .title = ᱫᱚᱞᱤᱞ ᱨᱮ ᱯᱟᱱᱛᱮ
+pdfjs-findbar-button-label = ᱥᱮᱸᱫᱽᱨᱟᱠᱢᱮ
+pdfjs-additional-layers = ᱵᱟᱹᱲᱛᱤ ᱯᱚᱨᱚᱛᱠᱚ
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } ᱥᱟᱦᱴᱟ
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } ᱥᱟᱦᱴᱟ ᱨᱮá±á±Ÿá±œ ᱪᱤᱛᱟᱹᱨ ᱟᱦᱞᱟ
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ᱥᱮᱸᱫᱽᱨᱟᱠᱢᱮ
+ .placeholder = ᱫᱚᱞᱤᱞ ᱨᱮ ᱯᱟᱱᱛᱮ ᱢᱮ …
+pdfjs-find-previous-button =
+ .title = ᱟá±á±Ÿá±› ᱦᱤᱸᱥ ᱨᱮá±á±Ÿá±œ ᱯᱟᱹᱦᱤᱞ ᱥᱮᱫᱟᱜ ᱚᱰᱚᱠᱧᱟᱢ ᱢᱮ
+pdfjs-find-previous-button-label = ᱢᱟᱲᱟá±á±Ÿá±œ
+pdfjs-find-next-button =
+ .title = ᱟá±á±Ÿá±› ᱦᱤᱸᱥ ᱨᱮá±á±Ÿá±œ ᱤᱱᱟᱹ ᱛᱟá±á±šá±¢ ᱚᱰᱚᱠᱧᱟᱢ ᱢᱮ
+pdfjs-find-next-button-label = ᱤᱱᱟᱹ ᱛᱟá±á±šá±¢
+pdfjs-find-highlight-checkbox = ᱡᱷᱚᱛᱚ ᱩᱫᱩᱜ ᱨᱟᱠᱟᱵ
+pdfjs-find-match-case-checkbox-label = ᱡᱚᱲ ᱠᱟᱛᱷᱟ
+pdfjs-find-match-diacritics-checkbox-label = ᱵᱤᱥᱮᱥᱚᱠᱠᱚ ᱢᱮᱲᱟᱣ ᱢᱮ
+pdfjs-find-entire-word-checkbox-label = ᱡᱷᱚᱛᱚ ᱟᱹᱲᱟᱹᱠᱚ
+pdfjs-find-reached-top = ᱫᱚᱞᱤᱞ ᱨᱮá±á±Ÿá±œ ᱪᱤᱴ ᱨᱮ ᱥᱮᱴᱮᱨ, ᱞᱟᱛᱟᱨ ᱠᱷᱚᱱ ᱞᱮᱛᱟᱲ
+pdfjs-find-reached-bottom = ᱫᱚᱞᱤᱞ ᱨᱮá±á±Ÿá±œ ᱢᱩᱪᱟᱹᱫ ᱨᱮ ᱥᱮᱴᱮᱨ, ᱪᱚᱴ ᱠᱷᱚᱱ ᱞᱮᱛᱟᱲ
+pdfjs-find-not-found = ᱛᱚᱯᱚᱞ ᱫᱚᱱᱚᱲ ᱵᱟᱠᱧᱟᱢ ᱞᱮᱱᱟ
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ᱥᱟᱦᱴᱟ ᱚᱥᱟᱨ
+pdfjs-page-scale-fit = ᱥᱟᱦᱴᱟ ᱠᱷᱟᱯ
+pdfjs-page-scale-auto = ᱟᱡᱼᱟᱡ ᱛᱮ ᱦᱩᱰᱤᱧ ᱞᱟᱹᱴᱩ ᱛᱮá±á±Ÿá±¨
+pdfjs-page-scale-actual = ᱴᱷᱤᱠᱢᱟᱨᱟᱠᱛᱮᱫ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = { $page } ᱥᱟᱦᱴᱟ
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF ᱞᱟᱫᱮ ᱡᱚᱦᱚᱜ ᱢᱤᱫ ᱵᱷᱩᱞ ᱦᱩᱠᱮᱱᱟ ᱾
+pdfjs-invalid-file-error = ᱵᱟᱠᱵᱟᱛᱟᱣ ᱟᱨᱵᱟá±á± ᱷᱟᱱ ᱰᱤᱜᱟᱹᱣ PDF ᱨᱮᱫᱽ á±¾
+pdfjs-missing-file-error = ᱟᱫᱟᱜ PDF ᱨᱮᱫᱽ ᱾
+pdfjs-unexpected-response-error = ᱵᱟá±á±µá±©á±¡á±· ᱥᱚᱨᱵᱷᱚᱨ ᱛᱮᱞᱟ á±¾
+pdfjs-rendering-error = ᱥᱟᱦᱴᱟ ᱮᱢ ᱡᱚᱦᱚᱠᱢᱤᱫ ᱵᱷᱩᱞ ᱦᱩᱠᱮᱱᱟ ᱾
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } ᱢᱚᱱᱛᱚ ᱮᱢ]
+
+## Password
+
+pdfjs-password-label = ᱱᱚᱶᱟ PDF ᱨᱮᱫᱽ ᱡᱷᱤᱡᱽ ᱞᱟᱹᱜᱤᱫ ᱫᱟᱱᱟᱠᱥᱟᱵᱟᱫᱽ ᱟᱫᱮᱨ ᱢᱮ ᱾
+pdfjs-password-invalid = ᱵᱷᱩᱞ ᱫᱟᱱᱟᱠᱥᱟᱵᱟᱫᱽ á±¾ ᱫᱟá±á±Ÿá± ᱟᱛᱮ ᱫᱩᱦᱲᱟᱹ ᱪᱮᱥᱴᱟᱠᱢᱮ á±¾
+pdfjs-password-ok-button = ᱴᱷᱤá±
+pdfjs-password-cancel-button = ᱵᱟᱹᱰᱨᱟᱹ
+pdfjs-web-fonts-disabled = ᱣᱮᱵᱽ ᱪᱤᱠᱤ ᱵᱟᱠᱦᱩᱠᱦᱚᱪᱚ ᱠᱟᱱᱟ : ᱵᱷᱤᱛᱤᱨ ᱛᱷᱟᱯᱚᱱ PDF ᱪᱤᱠᱤ ᱵᱮᱵᱷᱟᱨ ᱵᱟᱠᱦᱩᱠᱠᱮá±á±Ÿ á±¾
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ᱚᱞ
+pdfjs-editor-free-text-button-label = ᱚᱞ
+pdfjs-editor-ink-button =
+ .title = ᱛᱮá±á±Ÿá±¨
+pdfjs-editor-ink-button-label = ᱛᱮá±á±Ÿá±¨
+pdfjs-editor-stamp-button =
+ .title = ᱪᱤᱛᱟᱹᱨᱠᱚ ᱥᱮᱞᱮᱫ ᱥᱮ ᱥᱟᱯᱲᱟᱣ ᱢᱮ
+pdfjs-editor-stamp-button-label = ᱪᱤᱛᱟᱹᱨᱠᱚ ᱥᱮᱞᱮᱫ ᱥᱮ ᱥᱟᱯᱲᱟᱣ ᱢᱮ
+# Editor Parameters
+pdfjs-editor-free-text-color-input = ᱨᱚá±
+pdfjs-editor-free-text-size-input = ᱢᱟᱯ
+pdfjs-editor-ink-color-input = ᱨᱚá±
+pdfjs-editor-ink-thickness-input = ᱢᱚᱴᱟ
+pdfjs-editor-ink-opacity-input = ᱟᱨᱯᱟᱨ
+pdfjs-editor-stamp-add-image-button =
+ .title = ᱪᱤᱛᱟᱹᱨ ᱥᱮᱞᱮᱫ ᱢᱮ
+pdfjs-editor-stamp-add-image-button-label = ᱪᱤᱛᱟᱹᱨ ᱥᱮᱞᱮᱫ ᱢᱮ
+pdfjs-free-text =
+ .aria-label = ᱚᱞ ᱥᱟᱯᱲᱟᱣᱤá±á±Ÿá±¹
+pdfjs-free-text-default-content = ᱚᱞ ᱮᱛᱦᱚᱵ ᱢᱮ …
+pdfjs-ink =
+ .aria-label = ᱛᱮá±á±Ÿá±¨ ᱥᱟᱯᱲᱟᱣᱤá±á±Ÿá±¹
+pdfjs-ink-canvas =
+ .aria-label = ᱵᱮᱵᱷᱟᱨᱤá±á±Ÿá±¹ ᱛᱮá±á±Ÿá±¨ ᱠᱟᱫ ᱪᱤᱛᱟᱹᱨ
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sc/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sc/viewer.ftl
new file mode 100644
index 000000000..a51943c90
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sc/viewer.ftl
@@ -0,0 +1,290 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = PÃ gina anteriore
+pdfjs-previous-button-label = S'ischeda chi b'est primu
+pdfjs-next-button =
+ .title = PÃ gina imbeniente
+pdfjs-next-button-label = Imbeniente
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = PÃ gina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = de { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } de { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Impitica
+pdfjs-zoom-out-button-label = Impitica
+pdfjs-zoom-in-button =
+ .title = Ismà nnia
+pdfjs-zoom-in-button-label = Ismà nnia
+pdfjs-zoom-select =
+ .title = Ismà nnia
+pdfjs-presentation-mode-button =
+ .title = Cola a sa modalidade de presentatzione
+pdfjs-presentation-mode-button-label = Modalidade de presentatzione
+pdfjs-open-file-button =
+ .title = Aberi s'archìviu
+pdfjs-open-file-button-label = Abertu
+pdfjs-print-button =
+ .title = Imprenta
+pdfjs-print-button-label = Imprenta
+pdfjs-save-button =
+ .title = Sarva
+pdfjs-save-button-label = Sarva
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Iscà rriga
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Iscà rriga
+pdfjs-bookmark-button =
+ .title = Pà gina atuale (ammustra s’URL de sa pà gina atuale)
+pdfjs-bookmark-button-label = PÃ gina atuale
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Aberi in un’aplicatzione
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Aberi in un’aplicatzione
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Istrumentos
+pdfjs-tools-button-label = Istrumentos
+pdfjs-first-page-button =
+ .title = Bae a sa prima pà gina
+pdfjs-first-page-button-label = Bae a sa prima pà gina
+pdfjs-last-page-button =
+ .title = Bae a s'ùrtima pà gina
+pdfjs-last-page-button-label = Bae a s'ùrtima pà gina
+pdfjs-page-rotate-cw-button =
+ .title = Gira in sensu orà riu
+pdfjs-page-rotate-cw-button-label = Gira in sensu orà riu
+pdfjs-page-rotate-ccw-button =
+ .title = Gira in sensu anti-orà riu
+pdfjs-page-rotate-ccw-button-label = Gira in sensu anti-orà riu
+pdfjs-cursor-text-select-tool-button =
+ .title = Ativa s'aina de seletzione de testu
+pdfjs-cursor-text-select-tool-button-label = Aina de seletzione de testu
+pdfjs-cursor-hand-tool-button =
+ .title = Ativa s'aina de manu
+pdfjs-cursor-hand-tool-button-label = Aina de manu
+pdfjs-scroll-page-button =
+ .title = Imprea s'iscurrimentu de pà gina
+pdfjs-scroll-page-button-label = Iscurrimentu de pà gina
+pdfjs-scroll-vertical-button =
+ .title = Imprea s'iscurrimentu verticale
+pdfjs-scroll-vertical-button-label = Iscurrimentu verticale
+pdfjs-scroll-horizontal-button =
+ .title = Imprea s'iscurrimentu orizontale
+pdfjs-scroll-horizontal-button-label = Iscurrimentu orizontale
+pdfjs-scroll-wrapped-button =
+ .title = Imprea s'iscurrimentu continu
+pdfjs-scroll-wrapped-button-label = Iscurrimentu continu
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Propiedades de su documentu…
+pdfjs-document-properties-button-label = Propiedades de su documentu…
+pdfjs-document-properties-file-name = Nòmine de s'archìviu:
+pdfjs-document-properties-file-size = Mannà ria de s'archìviu:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Tìtulu:
+pdfjs-document-properties-author = Autoria:
+pdfjs-document-properties-subject = Ogetu:
+pdfjs-document-properties-keywords = Faeddos crae:
+pdfjs-document-properties-creation-date = Data de creatzione:
+pdfjs-document-properties-modification-date = Data de modìfica:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Creatzione:
+pdfjs-document-properties-producer = Produtore de PDF:
+pdfjs-document-properties-version = Versione de PDF:
+pdfjs-document-properties-page-count = Contu de pà ginas:
+pdfjs-document-properties-page-size = Mannà ria de sa pà gina:
+pdfjs-document-properties-page-size-unit-inches = pòddighes
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = verticale
+pdfjs-document-properties-page-size-orientation-landscape = orizontale
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Lìtera
+pdfjs-document-properties-page-size-name-legal = Legale
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Visualizatzione web lestra:
+pdfjs-document-properties-linearized-yes = Eja
+pdfjs-document-properties-linearized-no = Nono
+pdfjs-document-properties-close-button = Serra
+
+## Print
+
+pdfjs-print-progress-message = Aparitzende s'imprenta de su documentu…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Cantzella
+pdfjs-printing-not-supported = Atentzione: s'imprenta no est funtzionende de su totu in custu navigadore.
+pdfjs-printing-not-ready = Atentzione: su PDF no est istadu carrigadu de su totu pro s'imprenta.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Ativa/disativa sa barra laterale
+pdfjs-toggle-sidebar-notification-button =
+ .title = Ativa/disativa sa barra laterale (su documentu cuntenet un'ischema, alligongiados o livellos)
+pdfjs-toggle-sidebar-button-label = Ativa/disativa sa barra laterale
+pdfjs-document-outline-button-label = Ischema de su documentu
+pdfjs-attachments-button =
+ .title = Ammustra alligongiados
+pdfjs-attachments-button-label = Alliongiados
+pdfjs-layers-button =
+ .title = Ammustra livellos (clic dòpiu pro ripristinare totu is livellos a s'istadu predefinidu)
+pdfjs-layers-button-label = Livellos
+pdfjs-thumbs-button =
+ .title = Ammustra miniaturas
+pdfjs-thumbs-button-label = Miniaturas
+pdfjs-current-outline-item-button =
+ .title = Agata s'elementu atuale de s'ischema
+pdfjs-current-outline-item-button-label = Elementu atuale de s'ischema
+pdfjs-findbar-button =
+ .title = Agata in su documentu
+pdfjs-findbar-button-label = Agata
+pdfjs-additional-layers = Livellos additzionales
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = PÃ gina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura de sa pà gina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Agata
+ .placeholder = Agata in su documentu…
+pdfjs-find-previous-button =
+ .title = Agata s'ocurrèntzia pretzedente de sa frà sia
+pdfjs-find-previous-button-label = S'ischeda chi b'est primu
+pdfjs-find-next-button =
+ .title = Agata s'ocurrèntzia imbeniente de sa frà sia
+pdfjs-find-next-button-label = Imbeniente
+pdfjs-find-highlight-checkbox = Evidèntzia totu
+pdfjs-find-match-case-checkbox-label = Distinghe intre majùsculas e minùsculas
+pdfjs-find-match-diacritics-checkbox-label = Respeta is diacrìticos
+pdfjs-find-entire-word-checkbox-label = Faeddos intreos
+pdfjs-find-reached-top = S'est lòmpidu a su cumintzu de su documentu, si sighit dae su bà sciu
+pdfjs-find-reached-bottom = Acabbu de su documentu, si sighit dae s'artu
+pdfjs-find-not-found = Testu no agatadu
+
+## Predefined zoom values
+
+pdfjs-page-scale-auto = Ingrandimentu automà ticu
+pdfjs-page-scale-actual = Mannà ria reale
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = PÃ gina { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Faddina in sa cà rriga de su PDF.
+pdfjs-invalid-file-error = Archìviu PDF non và lidu o corrùmpidu.
+pdfjs-missing-file-error = Ammancat s'archìviu PDF.
+pdfjs-unexpected-response-error = Risposta imprevista de su serbidore.
+pdfjs-rendering-error = Faddina in sa visualizatzione de sa pà gina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+## Password
+
+pdfjs-password-label = Inserta sa crae pro abèrrere custu archìviu PDF.
+pdfjs-password-invalid = Sa crae no est curreta. Torra a nche proare.
+pdfjs-password-ok-button = Andat bene
+pdfjs-password-cancel-button = Cantzella
+pdfjs-web-fonts-disabled = Is tipografias web sunt disativadas: is tipografias incrustadas a su PDF non podent èssere impreadas.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Testu
+pdfjs-editor-free-text-button-label = Testu
+pdfjs-editor-ink-button =
+ .title = Disinnu
+pdfjs-editor-ink-button-label = Disinnu
+pdfjs-editor-stamp-button =
+ .title = Agiunghe o modìfica immà gines
+pdfjs-editor-stamp-button-label = Agiunghe o modìfica immà gines
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Colore
+pdfjs-editor-free-text-size-input = Mannà ria
+pdfjs-editor-ink-color-input = Colore
+pdfjs-editor-ink-thickness-input = Grussà ria
+pdfjs-editor-stamp-add-image-button =
+ .title = Agiunghe un’immà gine
+pdfjs-editor-stamp-add-image-button-label = Agiunghe un’immà gine
+pdfjs-free-text =
+ .aria-label = Editore de testu
+pdfjs-free-text-default-content = Cumintza a iscrìere…
+pdfjs-ink =
+ .aria-label = Editore de disinnos
+pdfjs-ink-canvas =
+ .aria-label = Immà gine creada dae s’utente
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/scn/viewer.ftl b/www/lib/pdfjs/modern/web/locale/scn/viewer.ftl
new file mode 100644
index 000000000..a3c7c038c
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/scn/viewer.ftl
@@ -0,0 +1,74 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-zoom-out-button =
+ .title = Cchiù nicu
+pdfjs-zoom-out-button-label = Cchiù nicu
+pdfjs-zoom-in-button =
+ .title = Cchiù granni
+pdfjs-zoom-in-button-label = Cchiù granni
+
+## Secondary toolbar and context menu
+
+
+## Document properties dialog
+
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Vista web lesta:
+pdfjs-document-properties-linearized-yes = Se
+
+## Print
+
+pdfjs-print-progress-close-button = Sfai
+
+## Tooltips and alt text for side panel toolbar buttons
+
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+
+## Find panel button title and messages
+
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Larghizza dâ pà ggina
+
+## PDF page
+
+
+## Loading indicator messages
+
+
+## Annotations
+
+
+## Password
+
+pdfjs-password-cancel-button = Sfai
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sco/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sco/viewer.ftl
new file mode 100644
index 000000000..6f71c47a3
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sco/viewer.ftl
@@ -0,0 +1,264 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Page Afore
+pdfjs-previous-button-label = Previous
+pdfjs-next-button =
+ .title = Page Efter
+pdfjs-next-button-label = Neist
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Page
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = o { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } o { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zoom Oot
+pdfjs-zoom-out-button-label = Zoom Oot
+pdfjs-zoom-in-button =
+ .title = Zoom In
+pdfjs-zoom-in-button-label = Zoom In
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Flit tae Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Open File
+pdfjs-open-file-button-label = Open
+pdfjs-print-button =
+ .title = Prent
+pdfjs-print-button-label = Prent
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Tools
+pdfjs-tools-button-label = Tools
+pdfjs-first-page-button =
+ .title = Gang tae First Page
+pdfjs-first-page-button-label = Gang tae First Page
+pdfjs-last-page-button =
+ .title = Gang tae Lest Page
+pdfjs-last-page-button-label = Gang tae Lest Page
+pdfjs-page-rotate-cw-button =
+ .title = Rotate Clockwise
+pdfjs-page-rotate-cw-button-label = Rotate Clockwise
+pdfjs-page-rotate-ccw-button =
+ .title = Rotate Coonterclockwise
+pdfjs-page-rotate-ccw-button-label = Rotate Coonterclockwise
+pdfjs-cursor-text-select-tool-button =
+ .title = Enable Text Walin Tool
+pdfjs-cursor-text-select-tool-button-label = Text Walin Tool
+pdfjs-cursor-hand-tool-button =
+ .title = Enable Haun Tool
+pdfjs-cursor-hand-tool-button-label = Haun Tool
+pdfjs-scroll-vertical-button =
+ .title = Yaise Vertical Scrollin
+pdfjs-scroll-vertical-button-label = Vertical Scrollin
+pdfjs-scroll-horizontal-button =
+ .title = Yaise Horizontal Scrollin
+pdfjs-scroll-horizontal-button-label = Horizontal Scrollin
+pdfjs-scroll-wrapped-button =
+ .title = Yaise Wrapped Scrollin
+pdfjs-scroll-wrapped-button-label = Wrapped Scrollin
+pdfjs-spread-none-button =
+ .title = Dinnae jyn page spreids
+pdfjs-spread-none-button-label = Nae Spreids
+pdfjs-spread-odd-button =
+ .title = Jyn page spreids stertin wi odd-numbered pages
+pdfjs-spread-odd-button-label = Odd Spreids
+pdfjs-spread-even-button =
+ .title = Jyn page spreids stertin wi even-numbered pages
+pdfjs-spread-even-button-label = Even Spreids
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Document Properties…
+pdfjs-document-properties-button-label = Document Properties…
+pdfjs-document-properties-file-name = File nemme:
+pdfjs-document-properties-file-size = File size:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Title:
+pdfjs-document-properties-author = Author:
+pdfjs-document-properties-subject = Subjeck:
+pdfjs-document-properties-keywords = Keywirds:
+pdfjs-document-properties-creation-date = Date o Makkin:
+pdfjs-document-properties-modification-date = Date o Chynges:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Makker:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Page Coont:
+pdfjs-document-properties-page-size = Page Size:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portrait
+pdfjs-document-properties-page-size-orientation-landscape = landscape
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Wab View:
+pdfjs-document-properties-linearized-yes = Aye
+pdfjs-document-properties-linearized-no = Naw
+pdfjs-document-properties-close-button = Sneck
+
+## Print
+
+pdfjs-print-progress-message = Reddin document fur prentin…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Stap
+pdfjs-printing-not-supported = Tak tent: Prentin isnae richt supportit by this stravaiger.
+pdfjs-printing-not-ready = Tak tent: The PDF isnae richt loadit fur prentin.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Toggle Sidebaur
+pdfjs-toggle-sidebar-notification-button =
+ .title = Toggle Sidebaur (document conteens ootline/attachments/layers)
+pdfjs-toggle-sidebar-button-label = Toggle Sidebaur
+pdfjs-document-outline-button =
+ .title = Kythe Document Ootline (double-click fur tae oot-fauld/in-fauld aw items)
+pdfjs-document-outline-button-label = Document Ootline
+pdfjs-attachments-button =
+ .title = Kythe Attachments
+pdfjs-attachments-button-label = Attachments
+pdfjs-layers-button =
+ .title = Kythe Layers (double-click fur tae reset aw layers tae the staunart state)
+pdfjs-layers-button-label = Layers
+pdfjs-thumbs-button =
+ .title = Kythe Thumbnails
+pdfjs-thumbs-button-label = Thumbnails
+pdfjs-current-outline-item-button =
+ .title = Find Current Ootline Item
+pdfjs-current-outline-item-button-label = Current Ootline Item
+pdfjs-findbar-button =
+ .title = Find in Document
+pdfjs-findbar-button-label = Find
+pdfjs-additional-layers = Mair Layers
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Page { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail o Page { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Find
+ .placeholder = Find in document…
+pdfjs-find-previous-button =
+ .title = Airt oot the last time this phrase occurred
+pdfjs-find-previous-button-label = Previous
+pdfjs-find-next-button =
+ .title = Airt oot the neist time this phrase occurs
+pdfjs-find-next-button-label = Neist
+pdfjs-find-highlight-checkbox = Highlicht aw
+pdfjs-find-match-case-checkbox-label = Match case
+pdfjs-find-entire-word-checkbox-label = Hale Wirds
+pdfjs-find-reached-top = Raxed tap o document, went on fae the dowp end
+pdfjs-find-reached-bottom = Raxed end o document, went on fae the tap
+pdfjs-find-not-found = Phrase no fund
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Page Width
+pdfjs-page-scale-fit = Page Fit
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Actual Size
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Page { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = An mishanter tuik place while loadin the PDF.
+pdfjs-invalid-file-error = No suithfest or camshauchlet PDF file.
+pdfjs-missing-file-error = PDF file tint.
+pdfjs-unexpected-response-error = Unexpectit server repone.
+pdfjs-rendering-error = A mishanter tuik place while renderin the page.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Inpit the passwird fur tae open this PDF file.
+pdfjs-password-invalid = Passwird no suithfest. Gonnae gie it anither shot.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Stap
+pdfjs-web-fonts-disabled = Wab fonts are disabled: cannae yaise embeddit PDF fonts.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/si/viewer.ftl b/www/lib/pdfjs/modern/web/locale/si/viewer.ftl
new file mode 100644
index 000000000..283872989
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/si/viewer.ftl
@@ -0,0 +1,253 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = කලින් පිටුව
+pdfjs-previous-button-label = කලින්
+pdfjs-next-button =
+ .title = ඊළඟ පිටුව
+pdfjs-next-button-label = ඊළඟ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = පිටුව
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = කුඩà·à¶½à¶±à¶º
+pdfjs-zoom-out-button-label = කුඩà·à¶½à¶±à¶º
+pdfjs-zoom-in-button =
+ .title = විà·à·à¶½à¶±à¶º
+pdfjs-zoom-in-button-label = විà·à·à¶½à¶±à¶º
+pdfjs-zoom-select =
+ .title = විà·à·à¶½ කරන්න
+pdfjs-presentation-mode-button =
+ .title = සමර්පණ ප්â€à¶»à¶šà·à¶»à¶º වෙචමà·à¶»à·”වන්න
+pdfjs-presentation-mode-button-label = සමර්පණ ප්â€à¶»à¶šà·à¶»à¶º
+pdfjs-open-file-button =
+ .title = ගොනුව අරින්න
+pdfjs-open-file-button-label = අරින්න
+pdfjs-print-button =
+ .title = මුද්â€à¶»à¶«à¶º
+pdfjs-print-button-label = මුද්â€à¶»à¶«à¶º
+pdfjs-save-button =
+ .title = සුරකින්න
+pdfjs-save-button-label = සුරකින්න
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = බà·à¶œà¶±à·Šà¶±
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = බà·à¶œà¶±à·Šà¶±
+pdfjs-bookmark-button-label = පවà¶à·’න පිටුව
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = යෙදුමෙහි අරින්න
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = යෙදුමෙහි අරින්න
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = මෙවලම්
+pdfjs-tools-button-label = මෙවලම්
+pdfjs-first-page-button =
+ .title = මුල් පිටුවට යන්න
+pdfjs-first-page-button-label = මුල් පිටුවට යන්න
+pdfjs-last-page-button =
+ .title = අවසන් පිටුවට යන්න
+pdfjs-last-page-button-label = අවසන් පිටුවට යන්න
+pdfjs-cursor-text-select-tool-button =
+ .title = පෙළ à¶à·šà¶»à·“මේ මෙවලම සබල කරන්න
+pdfjs-cursor-text-select-tool-button-label = පෙළ à¶à·šà¶»à·“මේ මෙවලම
+pdfjs-cursor-hand-tool-button =
+ .title = අà¶à·Š මෙවලම සබල කරන්න
+pdfjs-cursor-hand-tool-button-label = අà¶à·Š මෙවලම
+pdfjs-scroll-page-button =
+ .title = පිටුව අනුචලනය භà·à·€à·’à¶à¶º
+pdfjs-scroll-page-button-label = පිටුව අනුචලනය
+pdfjs-scroll-vertical-button =
+ .title = සිරස් අනුචලනය භà·à·€à·’à¶à¶º
+pdfjs-scroll-vertical-button-label = සිරස් අනුචලනය
+pdfjs-scroll-horizontal-button =
+ .title = à¶à·’රස් අනුචලනය භà·à·€à·’à¶à¶º
+pdfjs-scroll-horizontal-button-label = à¶à·’රස් අනුචලනය
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ලේඛනයේ ගුණà·à¶‚ග…
+pdfjs-document-properties-button-label = ලේඛනයේ ගුණà·à¶‚ග…
+pdfjs-document-properties-file-name = ගොනුවේ නම:
+pdfjs-document-properties-file-size = ගොනුවේ ප්â€à¶»à¶¸à·à¶«à¶º:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = කි.බ. { $size_kb } (බයිට { $size_b })
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = මෙ.බ. { $size_mb } (බයිට { $size_b })
+pdfjs-document-properties-title = සිරà·à·ƒà·’ය:
+pdfjs-document-properties-author = කà¶à·˜:
+pdfjs-document-properties-subject = මà·à¶à·˜à¶šà·à·€:
+pdfjs-document-properties-keywords = මූල පද:
+pdfjs-document-properties-creation-date = සෑදූ දිනය:
+pdfjs-document-properties-modification-date = සංà·à·à¶°à·’චදිනය:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = නිර්මà·à¶à·˜:
+pdfjs-document-properties-producer = පීඩීඑෆ් සම්පà·à¶¯à¶š:
+pdfjs-document-properties-version = පීඩීඑෆ් අනුවà·à¶¯à¶º:
+pdfjs-document-properties-page-count = පිටු ගණන:
+pdfjs-document-properties-page-size = පිටුවේ à¶à¶»à¶¸:
+pdfjs-document-properties-page-size-unit-inches = අඟල්
+pdfjs-document-properties-page-size-unit-millimeters = මි.මී.
+pdfjs-document-properties-page-size-orientation-portrait = සිරස්
+pdfjs-document-properties-page-size-orientation-landscape = à¶à·’රස්
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width }×{ $height }{ $unit }{ $name }{ $orientation }
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = වේගවà¶à·Š වියමන දà·à¶šà·Šà¶¸:
+pdfjs-document-properties-linearized-yes = ඔව්
+pdfjs-document-properties-linearized-no = නà·à·„à·
+pdfjs-document-properties-close-button = වසන්න
+
+## Print
+
+pdfjs-print-progress-message = මුද්â€à¶»à¶«à¶º සඳහ෠ලේඛනය සූදà·à¶±à¶¸à·Š වෙමින්…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = අවලංගු කරන්න
+pdfjs-printing-not-supported = අවවà·à¶¯à¶ºà¶ºà·’: මෙම අà¶à·’රික්සුව මුද්â€à¶»à¶«à¶º සඳහ෠හොඳින් සහà·à¶º නොදක්වයි.
+pdfjs-printing-not-ready = අවවà·à¶¯à¶ºà¶ºà·’: මුද්â€à¶»à¶«à¶ºà¶§ පීඩීඑෆ් ගොනුව සම්පූර්ණයෙන් පූරණය වී නà·à¶.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-document-outline-button-label = ලේඛනයේ වටසන
+pdfjs-attachments-button =
+ .title = ඇමුණුම් පෙන්වන්න
+pdfjs-attachments-button-label = ඇමුණුම්
+pdfjs-layers-button =
+ .title = ස්à¶à¶» පෙන්වන්න (සියළු ස්à¶à¶» පෙරනිමි à¶à¶à·Šâ€à·€à¶ºà¶§ යළි à·ƒà·à¶šà·ƒà·“මට දෙවරක් ඔබන්න)
+pdfjs-layers-button-label = ස්à¶à¶»
+pdfjs-thumbs-button =
+ .title = සිඟිà¶à·’ රූ පෙන්වන්න
+pdfjs-thumbs-button-label = සිඟිà¶à·’ රූ
+pdfjs-findbar-button =
+ .title = ලේඛනයෙහි සොයන්න
+pdfjs-findbar-button-label = සොයන්න
+pdfjs-additional-layers = අà¶à·’රේක ස්à¶à¶»
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = පිටුව { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = පිටුවේ සිඟිචරූව { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = සොයන්න
+ .placeholder = ලේඛනයේ සොයන්න…
+pdfjs-find-previous-button =
+ .title = මෙම à·€à·à¶šà·’කඩ කලින් යෙදුණු ස්ථà·à¶±à¶º සොයන්න
+pdfjs-find-previous-button-label = කලින්
+pdfjs-find-next-button =
+ .title = මෙම à·€à·à¶šà·’කඩ ඊළඟට යෙදෙන ස්ථà·à¶±à¶º සොයන්න
+pdfjs-find-next-button-label = ඊළඟ
+pdfjs-find-highlight-checkbox = සියල්ල උද්දීපනය
+pdfjs-find-entire-word-checkbox-label = සමස්චවචන
+pdfjs-find-reached-top = ලේඛනයේ මුදුනට ළඟ෠විය, පහළ සිට ඉහළට
+pdfjs-find-reached-bottom = ලේඛනයේ අවසà·à¶±à¶ºà¶§ ළඟ෠විය, ඉහළ සිට පහළට
+pdfjs-find-not-found = à·€à·à¶šà·’කඩ හමු නොවිණි
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = පිටුවේ පළල
+pdfjs-page-scale-auto = ස්වයංක්â€à¶»à·“ය විà·à·à¶½à¶±à¶º
+pdfjs-page-scale-actual = à·ƒà·à¶¶à·‘ ප්â€à¶»à¶¸à·à¶«à¶º
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = පිටුව { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = පීඩීඑෆ් පූරණය කිරීමේදී දà·à·‚යක් සිදු විය.
+pdfjs-invalid-file-error = වලංගු නොවන à·„à· à·„à·à¶±à·’වූ පීඩීඑෆ් ගොනුවකි.
+pdfjs-missing-file-error = මඟහà·à¶»à·”ණු පීඩීඑෆ් ගොනුවකි.
+pdfjs-unexpected-response-error = අනපේක්â€à·‚ිචසේවà·à¶¯à·à¶ºà¶š ප්â€à¶»à¶à·’චà·à¶»à¶ºà¶šà·’.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+
+## Password
+
+pdfjs-password-label = මෙම පීඩීඑෆ් ගොනුව විවෘචකිරීමට මුරපදය යොදන්න.
+pdfjs-password-invalid = à·€à·à¶»à¶¯à·’ මුරපදයකි. නà·à·€à¶ උà¶à·Šà·ƒà·à·„ කරන්න.
+pdfjs-password-ok-button = හරි
+pdfjs-password-cancel-button = අවලංගු
+pdfjs-web-fonts-disabled = වියමන අකුරු අබලයි: පීඩීඑෆ් වෙචකà·à·€à·à¶¯à·Šà¶¯à·– රුවකුරු භà·à·€à·’à¶à· කළ නොහà·à¶šà·’ය.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = පෙළ
+pdfjs-editor-free-text-button-label = පෙළ
+pdfjs-editor-ink-button =
+ .title = අඳින්න
+pdfjs-editor-ink-button-label = අඳින්න
+# Editor Parameters
+pdfjs-editor-free-text-color-input = වර්ණය
+pdfjs-editor-free-text-size-input = à¶à¶»à¶¸
+pdfjs-editor-ink-color-input = වර්ණය
+pdfjs-editor-ink-thickness-input = à¶à¶«à¶šà¶¸
+pdfjs-free-text =
+ .aria-label = වදන් සකසනය
+pdfjs-free-text-default-content = ලිවීීම අරඹන්න…
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sk/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sk/viewer.ftl
new file mode 100644
index 000000000..5858ffec0
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sk/viewer.ftl
@@ -0,0 +1,388 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Predchádzajúca strana
+pdfjs-previous-button-label = Predchádzajúca
+pdfjs-next-button =
+ .title = Nasledujúca strana
+pdfjs-next-button-label = Nasledujúca
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Strana
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = z { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } z { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zmenšiť veľkosť
+pdfjs-zoom-out-button-label = Zmenšiť veľkosť
+pdfjs-zoom-in-button =
+ .title = ZväÄÅ¡iÅ¥ veľkosÅ¥
+pdfjs-zoom-in-button-label = ZväÄÅ¡iÅ¥ veľkosÅ¥
+pdfjs-zoom-select =
+ .title = Nastavenie veľkosti
+pdfjs-presentation-mode-button =
+ .title = Prepnúť na režim prezentácie
+pdfjs-presentation-mode-button-label = Režim prezentácie
+pdfjs-open-file-button =
+ .title = Otvoriť súbor
+pdfjs-open-file-button-label = Otvoriť
+pdfjs-print-button =
+ .title = TlaÄiÅ¥
+pdfjs-print-button-label = TlaÄiÅ¥
+pdfjs-save-button =
+ .title = Uložiť
+pdfjs-save-button-label = Uložiť
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Stiahnuť
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Stiahnuť
+pdfjs-bookmark-button =
+ .title = Aktuálna stránka (zobraziť adresu URL z aktuálnej stránky)
+pdfjs-bookmark-button-label = Aktuálna stránka
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Otvoriť v aplikácii
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Otvoriť v aplikácii
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Nástroje
+pdfjs-tools-button-label = Nástroje
+pdfjs-first-page-button =
+ .title = Prejsť na prvú stranu
+pdfjs-first-page-button-label = Prejsť na prvú stranu
+pdfjs-last-page-button =
+ .title = Prejsť na poslednú stranu
+pdfjs-last-page-button-label = Prejsť na poslednú stranu
+pdfjs-page-rotate-cw-button =
+ .title = OtoÄiÅ¥ v smere hodinových ruÄiÄiek
+pdfjs-page-rotate-cw-button-label = OtoÄiÅ¥ v smere hodinových ruÄiÄiek
+pdfjs-page-rotate-ccw-button =
+ .title = OtoÄiÅ¥ proti smeru hodinových ruÄiÄiek
+pdfjs-page-rotate-ccw-button-label = OtoÄiÅ¥ proti smeru hodinových ruÄiÄiek
+pdfjs-cursor-text-select-tool-button =
+ .title = Povoliť výber textu
+pdfjs-cursor-text-select-tool-button-label = Výber textu
+pdfjs-cursor-hand-tool-button =
+ .title = Povoliť nástroj ruka
+pdfjs-cursor-hand-tool-button-label = Nástroj ruka
+pdfjs-scroll-page-button =
+ .title = Použiť rolovanie po stránkach
+pdfjs-scroll-page-button-label = Rolovanie po stránkach
+pdfjs-scroll-vertical-button =
+ .title = PoužÃvaÅ¥ zvislé posúvanie
+pdfjs-scroll-vertical-button-label = Zvislé posúvanie
+pdfjs-scroll-horizontal-button =
+ .title = PoužÃvaÅ¥ vodorovné posúvanie
+pdfjs-scroll-horizontal-button-label = Vodorovné posúvanie
+pdfjs-scroll-wrapped-button =
+ .title = Použiť postupné posúvanie
+pdfjs-scroll-wrapped-button-label = Postupné posúvanie
+pdfjs-spread-none-button =
+ .title = Nezdružovať stránky
+pdfjs-spread-none-button-label = Žiadne združovanie
+pdfjs-spread-odd-button =
+ .title = Združà stránky a umiestni nepárne stránky vľavo
+pdfjs-spread-odd-button-label = Združiť stránky (nepárne vľavo)
+pdfjs-spread-even-button =
+ .title = Združà stránky a umiestni párne stránky vľavo
+pdfjs-spread-even-button-label = Združiť stránky (párne vľavo)
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Vlastnosti dokumentu…
+pdfjs-document-properties-button-label = Vlastnosti dokumentu…
+pdfjs-document-properties-file-name = Názov súboru:
+pdfjs-document-properties-file-size = Veľkosť súboru:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } bajtov)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtov)
+pdfjs-document-properties-title = Názov:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Predmet:
+pdfjs-document-properties-keywords = KľúÄové slová:
+pdfjs-document-properties-creation-date = Dátum vytvorenia:
+pdfjs-document-properties-modification-date = Dátum úpravy:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Vytvoril:
+pdfjs-document-properties-producer = Tvorca PDF:
+pdfjs-document-properties-version = Verzia PDF:
+pdfjs-document-properties-page-count = PoÄet strán:
+pdfjs-document-properties-page-size = Veľkosť stránky:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = na výšku
+pdfjs-document-properties-page-size-orientation-landscape = na Å¡Ãrku
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = List
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Rýchle Web View:
+pdfjs-document-properties-linearized-yes = Ãno
+pdfjs-document-properties-linearized-no = Nie
+pdfjs-document-properties-close-button = Zavrieť
+
+## Print
+
+pdfjs-print-progress-message = PrÃprava dokumentu na tlaÄ…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress } %
+pdfjs-print-progress-close-button = Zrušiť
+pdfjs-printing-not-supported = Upozornenie: tlaÄ nie je v tomto prehliadaÄi plne podporovaná.
+pdfjs-printing-not-ready = Upozornenie: súbor PDF nie je plne naÄÃtaný pre tlaÄ.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Prepnúť boÄný panel
+pdfjs-toggle-sidebar-notification-button =
+ .title = Prepnúť boÄný panel (dokument obsahuje osnovu/prÃlohy/vrstvy)
+pdfjs-toggle-sidebar-button-label = Prepnúť boÄný panel
+pdfjs-document-outline-button =
+ .title = ZobraziÅ¥ osnovu dokumentu (dvojitým kliknutÃm rozbalÃte/zbalÃte vÅ¡etky položky)
+pdfjs-document-outline-button-label = Osnova dokumentu
+pdfjs-attachments-button =
+ .title = ZobraziÅ¥ prÃlohy
+pdfjs-attachments-button-label = PrÃlohy
+pdfjs-layers-button =
+ .title = ZobraziÅ¥ vrstvy (dvojitým kliknutÃm uvediete vÅ¡etky vrstvy do pôvodného stavu)
+pdfjs-layers-button-label = Vrstvy
+pdfjs-thumbs-button =
+ .title = Zobraziť miniatúry
+pdfjs-thumbs-button-label = Miniatúry
+pdfjs-current-outline-item-button =
+ .title = Nájsť aktuálnu položku v osnove
+pdfjs-current-outline-item-button-label = Aktuálna položka v osnove
+pdfjs-findbar-button =
+ .title = Hľadať v dokumente
+pdfjs-findbar-button-label = Hľadať
+pdfjs-additional-layers = Ďalšie vrstvy
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Strana { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatúra strany { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Hľadať
+ .placeholder = Hľadať v dokumente…
+pdfjs-find-previous-button =
+ .title = Vyhľadať predchádzajúci výskyt reťazca
+pdfjs-find-previous-button-label = Predchádzajúce
+pdfjs-find-next-button =
+ .title = VyhľadaÅ¥ ÄalÅ¡Ã výskyt reÅ¥azca
+pdfjs-find-next-button-label = Ďalšie
+pdfjs-find-highlight-checkbox = Zvýrazniť všetky
+pdfjs-find-match-case-checkbox-label = RozliÅ¡ovaÅ¥ veľkosÅ¥ pÃsmen
+pdfjs-find-match-diacritics-checkbox-label = Rozlišovať diakritiku
+pdfjs-find-entire-word-checkbox-label = Celé slová
+pdfjs-find-reached-top = Bol dosiahnutý zaÄiatok stránky, pokraÄuje sa od konca
+pdfjs-find-reached-bottom = Bol dosiahnutý koniec stránky, pokraÄuje sa od zaÄiatku
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] Výskyt { $current } z { $total }
+ [few] Výskyt { $current } z { $total }
+ [many] Výskyt { $current } z { $total }
+ *[other] Výskyt { $current } z { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Viac ako { $limit } výskyt
+ [few] Viac ako { $limit } výskyty
+ [many] Viac ako { $limit } výskytov
+ *[other] Viac ako { $limit } výskytov
+ }
+pdfjs-find-not-found = Výraz nebol nájdený
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Na Å¡Ãrku strany
+pdfjs-page-scale-fit = Na veľkosť strany
+pdfjs-page-scale-auto = Automatická veľkosť
+pdfjs-page-scale-actual = SkutoÄná veľkosÅ¥
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Strana { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PoÄas naÄÃtavania dokumentu PDF sa vyskytla chyba.
+pdfjs-invalid-file-error = Neplatný alebo poškodený súbor PDF.
+pdfjs-missing-file-error = Chýbajúci súbor PDF.
+pdfjs-unexpected-response-error = NeoÄakávaná odpoveÄ zo servera.
+pdfjs-rendering-error = Pri vykresľovanà stránky sa vyskytla chyba.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotácia typu { $type }]
+
+## Password
+
+pdfjs-password-label = Ak chcete otvoriť tento súbor PDF, zadajte jeho heslo.
+pdfjs-password-invalid = Heslo nie je platné. Skúste to znova.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Zrušiť
+pdfjs-web-fonts-disabled = Webové pÃsma sú vypnuté: nie je možné použiÅ¥ pÃsma vložené do súboru PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Kreslenie
+pdfjs-editor-ink-button-label = Kresliť
+pdfjs-editor-stamp-button =
+ .title = Pridať alebo upraviť obrázky
+pdfjs-editor-stamp-button-label = Pridať alebo upraviť obrázky
+pdfjs-editor-remove-button =
+ .title = Odstrániť
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Odstrániť kresbu
+pdfjs-editor-remove-freetext-button =
+ .title = Odstrániť text
+pdfjs-editor-remove-stamp-button =
+ .title = Odstrániť obrázok
+pdfjs-editor-remove-highlight-button =
+ .title = Odstrániť zvýraznenie
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Farba
+pdfjs-editor-free-text-size-input = Veľkosť
+pdfjs-editor-ink-color-input = Farba
+pdfjs-editor-ink-thickness-input = Hrúbka
+pdfjs-editor-ink-opacity-input = Priehľadnosť
+pdfjs-editor-stamp-add-image-button =
+ .title = Pridať obrázok
+pdfjs-editor-stamp-add-image-button-label = Pridať obrázok
+pdfjs-free-text =
+ .aria-label = Textový editor
+pdfjs-free-text-default-content = ZaÄnite pÃsať…
+pdfjs-ink =
+ .aria-label = Editor kreslenia
+pdfjs-ink-canvas =
+ .aria-label = Obrázok vytvorený použÃvateľom
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = AlternatÃvny text
+pdfjs-editor-alt-text-edit-button-label = UpraviÅ¥ alternatÃvny text
+pdfjs-editor-alt-text-dialog-label = Vyberte možnosť
+pdfjs-editor-alt-text-dialog-description = AlternatÃvny text (alt text) pomáha, keÄ Ä¾udia obrázok nevidia alebo sa nenaÄÃtava.
+pdfjs-editor-alt-text-add-description-label = Pridať popis
+pdfjs-editor-alt-text-add-description-description = Zamerajte sa na 1-2 vety, ktoré popisujú predmet, prostredie alebo akcie.
+pdfjs-editor-alt-text-mark-decorative-label = OznaÄiÅ¥ ako dekoratÃvny
+pdfjs-editor-alt-text-mark-decorative-description = PoužÃva sa na ozdobné obrázky, ako sú okraje alebo vodoznaky.
+pdfjs-editor-alt-text-cancel-button = Zrušiť
+pdfjs-editor-alt-text-save-button = Uložiť
+pdfjs-editor-alt-text-decorative-tooltip = OznaÄený ako dekoratÃvny
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = NaprÃklad: „Mladý muž si sadá za stôl, aby sa najedol“
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Ľavý horný roh – zmena veľkosti
+pdfjs-editor-resizer-label-top-middle = Horný stred – zmena veľkosti
+pdfjs-editor-resizer-label-top-right = Pravý horný roh – zmena veľkosti
+pdfjs-editor-resizer-label-middle-right = Vpravo uprostred – zmena veľkosti
+pdfjs-editor-resizer-label-bottom-right = Pravý dolný roh – zmena veľkosti
+pdfjs-editor-resizer-label-bottom-middle = Stred dole – zmena veľkosti
+pdfjs-editor-resizer-label-bottom-left = Ľavý dolný roh – zmena veľkosti
+pdfjs-editor-resizer-label-middle-left = Vľavo uprostred – zmena veľkosti
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Farba zvýraznenia
+pdfjs-editor-colorpicker-button =
+ .title = Zmeniť farbu
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Výber farieb
+pdfjs-editor-colorpicker-yellow =
+ .title = Žltá
+pdfjs-editor-colorpicker-green =
+ .title = Zelená
+pdfjs-editor-colorpicker-blue =
+ .title = Modrá
+pdfjs-editor-colorpicker-pink =
+ .title = Ružová
+pdfjs-editor-colorpicker-red =
+ .title = Červená
diff --git a/www/lib/pdfjs/modern/web/locale/skr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/skr/viewer.ftl
new file mode 100644
index 000000000..9bb20d680
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/skr/viewer.ftl
@@ -0,0 +1,305 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = پچھلا ورقÛ
+pdfjs-previous-button-label = پچھلا
+pdfjs-next-button =
+ .title = اڳلا ورقÛ
+pdfjs-next-button-label = اڳلا
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = ورقÛ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } دا
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } دا { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = زوم آؤٹ
+pdfjs-zoom-out-button-label = زوم آؤٹ
+pdfjs-zoom-in-button =
+ .title = زوم اÙÙ†
+pdfjs-zoom-in-button-label = زوم اÙÙ†
+pdfjs-zoom-select =
+ .title = زوم
+pdfjs-presentation-mode-button =
+ .title = پریزنٹیشن موڈ تے سوئچ کرو
+pdfjs-presentation-mode-button-label = پریزنٹیشن موڈ
+pdfjs-open-file-button =
+ .title = Ùائل کھولو
+pdfjs-open-file-button-label = کھولو
+pdfjs-print-button =
+ .title = چھاپو
+pdfjs-print-button-label = چھاپو
+pdfjs-save-button =
+ .title = Ûتھیکڑا کرو
+pdfjs-save-button-label = Ûتھیکڑا کرو
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ڈاؤن لوڈ
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ڈاؤن لوڈ
+pdfjs-bookmark-button =
+ .title = Ù…ÙˆØ¬ÙˆØ¯Û ÙˆØ±Ù‚Û (Ù…ÙˆØ¬ÙˆØ¯Û ÙˆØ±Ù‚Û’ کنوں یوآرایل ݙیکھو)
+pdfjs-bookmark-button-label = Ù…ÙˆØ¬ÙˆØ¯Û ÙˆØ±Ù‚Û
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = ایپ وچ کھولو
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = ایپ وچ کھولو
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = اوزار
+pdfjs-tools-button-label = اوزار
+pdfjs-first-page-button =
+ .title = Ù¾ÛÙ„Û’ ورقے تے ونڄو
+pdfjs-first-page-button-label = Ù¾ÛÙ„Û’ ورقے تے ونڄو
+pdfjs-last-page-button =
+ .title = چھیکڑی ورقے تے ونڄو
+pdfjs-last-page-button-label = چھیکڑی ورقے تے ونڄو
+pdfjs-page-rotate-cw-button =
+ .title = گھڑی وانگوں گھماؤ
+pdfjs-page-rotate-cw-button-label = گھڑی وانگوں گھماؤ
+pdfjs-page-rotate-ccw-button =
+ .title = Ú¯Ú¾Ú‘ÛŒ تے اÙپٹھ گھماؤ
+pdfjs-page-rotate-ccw-button-label = Ú¯Ú¾Ú‘ÛŒ تے اÙپٹھ گھماؤ
+pdfjs-cursor-text-select-tool-button =
+ .title = متن منتخب کݨ والا Ø¢Ù„Û Ùعال بݨاؤ
+pdfjs-cursor-text-select-tool-button-label = متن منتخب کرݨ والا آلÛ
+pdfjs-cursor-hand-tool-button =
+ .title = Ûینڈ ٹول Ùعال بݨاؤ
+pdfjs-cursor-hand-tool-button-label = Ûینڈ ٹول
+pdfjs-scroll-page-button =
+ .title = پیج سکرولنگ استعمال کرو
+pdfjs-scroll-page-button-label = پیج سکرولنگ
+pdfjs-scroll-vertical-button =
+ .title = عمودی سکرولنگ استعمال کرو
+pdfjs-scroll-vertical-button-label = عمودی سکرولنگ
+pdfjs-scroll-horizontal-button =
+ .title = اÙÙ‚ÛŒ سکرولنگ استعمال کرو
+pdfjs-scroll-horizontal-button-label = اÙÙ‚ÛŒ سکرولنگ
+pdfjs-scroll-wrapped-button =
+ .title = ویڑھی Ûوئی سکرولنگ استعمال کرو
+pdfjs-scroll-wrapped-button-label = ÙˆÛÚ‘Ú¾ÛŒ Ûوئی سکرولنگ
+pdfjs-spread-none-button =
+ .title = پیج سپریڈز ÙˆÙÚ† شامل Ù†Û ØªÚ¾ÛŒÙˆÙˆÛ”
+pdfjs-spread-none-button-label = کوئی پولھ کائنی
+pdfjs-spread-odd-button =
+ .title = طاق نمبر والے ورقیاں دے نال شروع تھیوݨ والے پیج سپریڈز ÙˆÙÚ† شامل تھیوو۔
+pdfjs-spread-odd-button-label = تاک پھیلاؤ
+pdfjs-spread-even-button =
+ .title = جÙت نمر والے ورقیاں نال شروع تھیوݨ والے پیج سپریڈز و٠شامل تھیوو۔
+pdfjs-spread-even-button-label = جÙت پھیلاؤ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = دستاویز خواص…
+pdfjs-document-properties-button-label = دستاویز خواص …
+pdfjs-document-properties-file-name = Ùائل دا ناں:
+pdfjs-document-properties-file-size = Ùائل دا سائز:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } کے بی ({ $size_b } بائٹس)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } ایم بی ({ $size_b } بائٹس)
+pdfjs-document-properties-title = عنوان:
+pdfjs-document-properties-author = تخلیق کار:
+pdfjs-document-properties-subject = موضوع:
+pdfjs-document-properties-keywords = کلیدی الÙاظ:
+pdfjs-document-properties-creation-date = تخلیق دی تاریخ:
+pdfjs-document-properties-modification-date = ترمیم دی تاریخ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = تخلیق کار:
+pdfjs-document-properties-producer = PDF پیدا کار:
+pdfjs-document-properties-version = PDF ورژن:
+pdfjs-document-properties-page-count = ÙˆØ±Ù‚Û Ø´Ù…Ø§Ø±ÛŒ:
+pdfjs-document-properties-page-size = ÙˆØ±Ù‚Û Ø¯ÛŒ سائز:
+pdfjs-document-properties-page-size-unit-inches = ÙˆÙÚ†
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = عمودی انداز
+pdfjs-document-properties-page-size-orientation-landscape = اÙقى انداز
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = لیٹر
+pdfjs-document-properties-page-size-name-legal = قنونی
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = تکھا ویب نظارÛ:
+pdfjs-document-properties-linearized-yes = جیا
+pdfjs-document-properties-linearized-no = Ú©Ùˆ
+pdfjs-document-properties-close-button = بند کرو
+
+## Print
+
+pdfjs-print-progress-message = چھاپݨ کیتے دستاویز تیار تھیندے پئے ÛÙ† …
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = منسوخ کرو
+pdfjs-printing-not-supported = چتاوݨی: چھپائی ایں براؤزر تے پوری طراں معاونت Ø´Ø¯Û Ú©Ø§Ø¦Ù†ÛŒÛ”
+pdfjs-printing-not-ready = چتاوݨی: PDF چھپائی کیتے پوری طراں لوڈ نئیں تھئی۔
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = سائیڈ بار ٹوگل کرو
+pdfjs-toggle-sidebar-notification-button =
+ .title = سائیڈ بار ٹوگل کرو (دستاویز ÙˆÙÚ† آؤٹ لائن/ منسلکات/ پرتاں شامل ÛÙ†)
+pdfjs-toggle-sidebar-button-label = سائیڈ بار ٹوگل کرو
+pdfjs-document-outline-button =
+ .title = دستاویز دا Ø®Ø§Ú©Û Ý™Ú©Ú¾Ø§Ø¤ (تمام آئٹمز Ú©ÙˆÚº پھیلاوݨ/سنگوڑݨ کیتے ڈبل Ú©Ù„Ú© کرو)
+pdfjs-document-outline-button-label = دستاویز آؤٹ لائن
+pdfjs-attachments-button =
+ .title = نتھیاں ݙکھاؤ
+pdfjs-attachments-button-label = منسلکات
+pdfjs-layers-button =
+ .title = پرتاں ݙکھاؤ (تمام پرتاں Ú©ÙˆÚº ÚˆÛŒÙالٹ Øالت ÙˆÙÚ† Ø¯ÙˆØ¨Ø§Ø±Û ØªØ±ØªÛŒØ¨ ݙیوݨ کیتے ڈبل Ú©Ù„Ú© کرو)
+pdfjs-layers-button-label = پرتاں
+pdfjs-thumbs-button =
+ .title = تھمبنیل ݙکھاؤ
+pdfjs-thumbs-button-label = تھمبنیلز
+pdfjs-current-outline-item-button =
+ .title = Ù…ÙˆØ¬ÙˆØ¯Û Ø¢Ø¤Ù¹ لائن آئٹم لبھو
+pdfjs-current-outline-item-button-label = Ù…ÙˆØ¬ÙˆØ¯Û Ø¢Ø¤Ù¹ لائن آئٹم
+pdfjs-findbar-button =
+ .title = دستاویز ÙˆÙÚ† لبھو
+pdfjs-findbar-button-label = لبھو
+pdfjs-additional-layers = اضاÙÛŒ پرتاں
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = ÙˆØ±Ù‚Û { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ورقے دا تھمبنیل { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = لبھو
+ .placeholder = دستاویز ÙˆÙÚ† لبھو …
+pdfjs-find-previous-button =
+ .title = Ùقرے دا پچھلا ÙˆØ§Ù‚Ø¹Û Ù„Ø¨Ú¾Ùˆ
+pdfjs-find-previous-button-label = پچھلا
+pdfjs-find-next-button =
+ .title = Ùقرے دا اڳلا ÙˆØ§Ù‚Ø¹Û Ù„Ø¨Ú¾Ùˆ
+pdfjs-find-next-button-label = اڳلا
+pdfjs-find-highlight-checkbox = تمام نشابر کرو
+pdfjs-find-match-case-checkbox-label = ØØ±ÙˆÙ Ù…Ø´Ø§Ø¨Û Ú©Ø±Ùˆ
+pdfjs-find-match-diacritics-checkbox-label = ڈائیکرٹکس Ù…Ø´Ø§Ø¨Û Ú©Ø±Ùˆ
+pdfjs-find-entire-word-checkbox-label = تمام الÙاظ
+pdfjs-find-reached-top = ورقے دے شروع تے Ù¾Ùج ڳیا، تلوں جاری کیتا ڳیا
+pdfjs-find-reached-bottom = ورقے دے پاند تے Ù¾ÙÚ„ ڳیا، اÙتوں شروع کیتا ڳیا
+pdfjs-find-not-found = ÙÙ‚Ø±Û Ù†Ø¦ÛŒÚº ملیا
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ورقے دی چوڑائی
+pdfjs-page-scale-fit = ÙˆØ±Ù‚Û Ùٹنگ
+pdfjs-page-scale-auto = آپوں آپ زوم
+pdfjs-page-scale-actual = اصل میچا
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = ÙˆØ±Ù‚Û { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF لوڈ کریندے ویلھے نقص آ ڳیا۔
+pdfjs-invalid-file-error = غلط یا خراب Ø´Ø¯Û PDF Ùائل۔
+pdfjs-missing-file-error = PDF Ùائل غائب ÛÛ’Û”
+pdfjs-unexpected-response-error = سرور دا غیر متوقع جواب۔
+pdfjs-rendering-error = ÙˆØ±Ù‚Û Ø±ÛŒÙ†ÚˆØ± کریندے ویلھے ÛÚ© خرابی پیش آڳئی۔
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } تشریØ]
+
+## Password
+
+pdfjs-password-label = Ø§ÛŒÛ PDF Ùائل کھولݨ کیتے پاس ورڈ درج کرو۔
+pdfjs-password-invalid = غلط پاس ورڈ: Ø¨Ø±Ø§Û Ù…Ûربانی ولدا کوشش کرو۔
+pdfjs-password-ok-button = ٹھیک ÛÛ’
+pdfjs-password-cancel-button = منسوخ کرو
+pdfjs-web-fonts-disabled = ویب Ùونٹس غیر Ùعال ÛÙ†: ایمبیڈڈ PDF Ùونٹس استعمال کرݨ کنوں قاصر ÛÙ†
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = متن
+pdfjs-editor-free-text-button-label = متن
+pdfjs-editor-ink-button =
+ .title = Ú†Ú¾Ú©Ùˆ
+pdfjs-editor-ink-button-label = Ú†Ú¾Ú©Ùˆ
+# Editor Parameters
+pdfjs-editor-free-text-color-input = رنگ
+pdfjs-editor-free-text-size-input = سائز
+pdfjs-editor-ink-color-input = رنگ
+pdfjs-editor-ink-thickness-input = ٹھولھ
+pdfjs-editor-ink-opacity-input = دھندلاپن
+pdfjs-free-text =
+ .aria-label = ٹیکسٹ ایڈیٹر
+pdfjs-free-text-default-content = ٹائپنگ شروع کرو …
+pdfjs-ink =
+ .aria-label = ڈرا ایڈیٹر
+pdfjs-ink-canvas =
+ .aria-label = صار٠دی بݨائی Ûوئی تصویر
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sl/viewer.ftl
new file mode 100644
index 000000000..e75eeb3b1
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sl/viewer.ftl
@@ -0,0 +1,388 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Prejšnja stran
+pdfjs-previous-button-label = Nazaj
+pdfjs-next-button =
+ .title = Naslednja stran
+pdfjs-next-button-label = Naprej
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Stran
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = od { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } od { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Pomanjšaj
+pdfjs-zoom-out-button-label = Pomanjšaj
+pdfjs-zoom-in-button =
+ .title = PoveÄaj
+pdfjs-zoom-in-button-label = PoveÄaj
+pdfjs-zoom-select =
+ .title = PoveÄava
+pdfjs-presentation-mode-button =
+ .title = Preklopi v naÄin predstavitve
+pdfjs-presentation-mode-button-label = NaÄin predstavitve
+pdfjs-open-file-button =
+ .title = Odpri datoteko
+pdfjs-open-file-button-label = Odpri
+pdfjs-print-button =
+ .title = Natisni
+pdfjs-print-button-label = Natisni
+pdfjs-save-button =
+ .title = Shrani
+pdfjs-save-button-label = Shrani
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Prenesi
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Prenesi
+pdfjs-bookmark-button =
+ .title = Trenutna stran (prikaži URL, ki vodi do trenutne strani)
+pdfjs-bookmark-button-label = Na trenutno stran
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Odpri v programu
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Odpri v programu
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Orodja
+pdfjs-tools-button-label = Orodja
+pdfjs-first-page-button =
+ .title = Pojdi na prvo stran
+pdfjs-first-page-button-label = Pojdi na prvo stran
+pdfjs-last-page-button =
+ .title = Pojdi na zadnjo stran
+pdfjs-last-page-button-label = Pojdi na zadnjo stran
+pdfjs-page-rotate-cw-button =
+ .title = Zavrti v smeri urnega kazalca
+pdfjs-page-rotate-cw-button-label = Zavrti v smeri urnega kazalca
+pdfjs-page-rotate-ccw-button =
+ .title = Zavrti v nasprotni smeri urnega kazalca
+pdfjs-page-rotate-ccw-button-label = Zavrti v nasprotni smeri urnega kazalca
+pdfjs-cursor-text-select-tool-button =
+ .title = OmogoÄi orodje za izbor besedila
+pdfjs-cursor-text-select-tool-button-label = Orodje za izbor besedila
+pdfjs-cursor-hand-tool-button =
+ .title = OmogoÄi roko
+pdfjs-cursor-hand-tool-button-label = Roka
+pdfjs-scroll-page-button =
+ .title = Uporabi drsenje po strani
+pdfjs-scroll-page-button-label = Drsenje po strani
+pdfjs-scroll-vertical-button =
+ .title = Uporabi navpiÄno drsenje
+pdfjs-scroll-vertical-button-label = NavpiÄno drsenje
+pdfjs-scroll-horizontal-button =
+ .title = Uporabi vodoravno drsenje
+pdfjs-scroll-horizontal-button-label = Vodoravno drsenje
+pdfjs-scroll-wrapped-button =
+ .title = Uporabi ovito drsenje
+pdfjs-scroll-wrapped-button-label = Ovito drsenje
+pdfjs-spread-none-button =
+ .title = Ne združuj razponov strani
+pdfjs-spread-none-button-label = Brez razponov
+pdfjs-spread-odd-button =
+ .title = Združuj razpone strani z zaÄetkom pri lihih straneh
+pdfjs-spread-odd-button-label = Lihi razponi
+pdfjs-spread-even-button =
+ .title = Združuj razpone strani z zaÄetkom pri sodih straneh
+pdfjs-spread-even-button-label = Sodi razponi
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Lastnosti dokumenta …
+pdfjs-document-properties-button-label = Lastnosti dokumenta …
+pdfjs-document-properties-file-name = Ime datoteke:
+pdfjs-document-properties-file-size = Velikost datoteke:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajtov)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajtov)
+pdfjs-document-properties-title = Ime:
+pdfjs-document-properties-author = Avtor:
+pdfjs-document-properties-subject = Tema:
+pdfjs-document-properties-keywords = KljuÄne besede:
+pdfjs-document-properties-creation-date = Datum nastanka:
+pdfjs-document-properties-modification-date = Datum spremembe:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Ustvaril:
+pdfjs-document-properties-producer = Izdelovalec PDF:
+pdfjs-document-properties-version = RazliÄica PDF:
+pdfjs-document-properties-page-count = Å tevilo strani:
+pdfjs-document-properties-page-size = Velikost strani:
+pdfjs-document-properties-page-size-unit-inches = palcev
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = pokonÄno
+pdfjs-document-properties-page-size-orientation-landscape = ležeÄe
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Pismo
+pdfjs-document-properties-page-size-name-legal = Pravno
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Hitri spletni ogled:
+pdfjs-document-properties-linearized-yes = Da
+pdfjs-document-properties-linearized-no = Ne
+pdfjs-document-properties-close-button = Zapri
+
+## Print
+
+pdfjs-print-progress-message = Priprava dokumenta na tiskanje …
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress } %
+pdfjs-print-progress-close-button = PrekliÄi
+pdfjs-printing-not-supported = Opozorilo: ta brskalnik ne podpira vseh možnosti tiskanja.
+pdfjs-printing-not-ready = Opozorilo: PDF ni v celoti naložen za tiskanje.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Preklopi stransko vrstico
+pdfjs-toggle-sidebar-notification-button =
+ .title = Preklopi stransko vrstico (dokument vsebuje oris/priponke/plasti)
+pdfjs-toggle-sidebar-button-label = Preklopi stransko vrstico
+pdfjs-document-outline-button =
+ .title = Prikaži oris dokumenta (dvokliknite za razširitev/strnitev vseh predmetov)
+pdfjs-document-outline-button-label = Oris dokumenta
+pdfjs-attachments-button =
+ .title = Prikaži priponke
+pdfjs-attachments-button-label = Priponke
+pdfjs-layers-button =
+ .title = Prikaži plasti (dvokliknite za ponastavitev vseh plasti na privzeto stanje)
+pdfjs-layers-button-label = Plasti
+pdfjs-thumbs-button =
+ .title = Prikaži sliÄice
+pdfjs-thumbs-button-label = SliÄice
+pdfjs-current-outline-item-button =
+ .title = Najdi trenutni predmet orisa
+pdfjs-current-outline-item-button-label = Trenutni predmet orisa
+pdfjs-findbar-button =
+ .title = Iskanje po dokumentu
+pdfjs-findbar-button-label = Najdi
+pdfjs-additional-layers = Dodatne plasti
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Stran { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = SliÄica strani { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Najdi
+ .placeholder = Najdi v dokumentu …
+pdfjs-find-previous-button =
+ .title = Najdi prejšnjo ponovitev iskanega
+pdfjs-find-previous-button-label = Najdi nazaj
+pdfjs-find-next-button =
+ .title = Najdi naslednjo ponovitev iskanega
+pdfjs-find-next-button-label = Najdi naprej
+pdfjs-find-highlight-checkbox = OznaÄi vse
+pdfjs-find-match-case-checkbox-label = Razlikuj velike/male Ärke
+pdfjs-find-match-diacritics-checkbox-label = Razlikuj diakritiÄne znake
+pdfjs-find-entire-word-checkbox-label = Cele besede
+pdfjs-find-reached-top = Dosežen zaÄetek dokumenta iz smeri konca
+pdfjs-find-reached-bottom = Doseženo konec dokumenta iz smeri zaÄetka
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] Zadetek { $current } od { $total }
+ [two] Zadetek { $current } od { $total }
+ [few] Zadetek { $current } od { $total }
+ *[other] Zadetek { $current } od { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] VeÄ kot { $limit } zadetek
+ [two] VeÄ kot { $limit } zadetka
+ [few] VeÄ kot { $limit } zadetki
+ *[other] VeÄ kot { $limit } zadetkov
+ }
+pdfjs-find-not-found = Iskanega ni mogoÄe najti
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Å irina strani
+pdfjs-page-scale-fit = Prilagodi stran
+pdfjs-page-scale-auto = Samodejno
+pdfjs-page-scale-actual = Dejanska velikost
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale } %
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Stran { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Med nalaganjem datoteke PDF je prišlo do napake.
+pdfjs-invalid-file-error = Neveljavna ali pokvarjena datoteka PDF.
+pdfjs-missing-file-error = Ni datoteke PDF.
+pdfjs-unexpected-response-error = NepriÄakovan odgovor strežnika.
+pdfjs-rendering-error = Med pripravljanjem strani je prišlo do napake!
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Opomba vrste { $type }]
+
+## Password
+
+pdfjs-password-label = Vnesite geslo za odpiranje te datoteke PDF.
+pdfjs-password-invalid = Neveljavno geslo. Poskusite znova.
+pdfjs-password-ok-button = V redu
+pdfjs-password-cancel-button = PrekliÄi
+pdfjs-web-fonts-disabled = Spletne pisave so onemogoÄene: vgradnih pisav za PDF ni mogoÄe uporabiti.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Besedilo
+pdfjs-editor-free-text-button-label = Besedilo
+pdfjs-editor-ink-button =
+ .title = Riši
+pdfjs-editor-ink-button-label = Riši
+pdfjs-editor-stamp-button =
+ .title = Dodajanje ali urejanje slik
+pdfjs-editor-stamp-button-label = Dodajanje ali urejanje slik
+pdfjs-editor-remove-button =
+ .title = Odstrani
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Odstrani risbo
+pdfjs-editor-remove-freetext-button =
+ .title = Odstrani besedilo
+pdfjs-editor-remove-stamp-button =
+ .title = Odstrani sliko
+pdfjs-editor-remove-highlight-button =
+ .title = Odstrani oznaÄbo
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Barva
+pdfjs-editor-free-text-size-input = Velikost
+pdfjs-editor-ink-color-input = Barva
+pdfjs-editor-ink-thickness-input = Debelina
+pdfjs-editor-ink-opacity-input = Neprosojnost
+pdfjs-editor-stamp-add-image-button =
+ .title = Dodaj sliko
+pdfjs-editor-stamp-add-image-button-label = Dodaj sliko
+pdfjs-free-text =
+ .aria-label = Urejevalnik besedila
+pdfjs-free-text-default-content = ZaÄnite tipkati …
+pdfjs-ink =
+ .aria-label = Urejevalnik risanja
+pdfjs-ink-canvas =
+ .aria-label = Uporabnikova slika
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Nadomestno besedilo
+pdfjs-editor-alt-text-edit-button-label = Uredi nadomestno besedilo
+pdfjs-editor-alt-text-dialog-label = Izberite možnost
+pdfjs-editor-alt-text-dialog-description = Nadomestno besedilo se prikaže tistim, ki ne vidijo slike, ali Äe se ta ne naloži.
+pdfjs-editor-alt-text-add-description-label = Dodaj opis
+pdfjs-editor-alt-text-add-description-description = Poskušajte v enem ali dveh stavkih opisati motiv, okolje ali dejanja.
+pdfjs-editor-alt-text-mark-decorative-label = OznaÄi kot okrasno
+pdfjs-editor-alt-text-mark-decorative-description = Uporablja se za slike, ki služijo samo okrasu, na primer obrobe ali vodne žige.
+pdfjs-editor-alt-text-cancel-button = PrekliÄi
+pdfjs-editor-alt-text-save-button = Shrani
+pdfjs-editor-alt-text-decorative-tooltip = OznaÄeno kot okrasno
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Na primer: "MladeniÄ sedi za mizo pri jedi"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Zgornji levi kot – spremeni velikost
+pdfjs-editor-resizer-label-top-middle = Zgoraj na sredini – spremeni velikost
+pdfjs-editor-resizer-label-top-right = Zgornji desni kot – spremeni velikost
+pdfjs-editor-resizer-label-middle-right = Desno na sredini – spremeni velikost
+pdfjs-editor-resizer-label-bottom-right = Spodnji desni kot – spremeni velikost
+pdfjs-editor-resizer-label-bottom-middle = Spodaj na sredini – spremeni velikost
+pdfjs-editor-resizer-label-bottom-left = Spodnji levi kot – spremeni velikost
+pdfjs-editor-resizer-label-middle-left = Levo na sredini – spremeni velikost
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Barva oznaÄbe
+pdfjs-editor-colorpicker-button =
+ .title = Spremeni barvo
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Izbira barve
+pdfjs-editor-colorpicker-yellow =
+ .title = Rumena
+pdfjs-editor-colorpicker-green =
+ .title = Zelena
+pdfjs-editor-colorpicker-blue =
+ .title = Modra
+pdfjs-editor-colorpicker-pink =
+ .title = Roza
+pdfjs-editor-colorpicker-red =
+ .title = RdeÄa
diff --git a/www/lib/pdfjs/modern/web/locale/son/viewer.ftl b/www/lib/pdfjs/modern/web/locale/son/viewer.ftl
new file mode 100644
index 000000000..fa4f6b1fc
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/son/viewer.ftl
@@ -0,0 +1,206 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Moo bisante
+pdfjs-previous-button-label = Bisante
+pdfjs-next-button =
+ .title = Jinehere moo
+pdfjs-next-button-label = Jine
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Moo
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } ra
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } ka hun { $pagesCount }) ra
+pdfjs-zoom-out-button =
+ .title = Nakasandi
+pdfjs-zoom-out-button-label = Nakasandi
+pdfjs-zoom-in-button =
+ .title = Bebbeerandi
+pdfjs-zoom-in-button-label = Bebbeerandi
+pdfjs-zoom-select =
+ .title = Bebbeerandi
+pdfjs-presentation-mode-button =
+ .title = Bere cebeyan alhaali
+pdfjs-presentation-mode-button-label = Cebeyan alhaali
+pdfjs-open-file-button =
+ .title = Tuku feeri
+pdfjs-open-file-button-label = Feeri
+pdfjs-print-button =
+ .title = Kar
+pdfjs-print-button-label = Kar
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Goyjinawey
+pdfjs-tools-button-label = Goyjinawey
+pdfjs-first-page-button =
+ .title = Koy moo jinaa ga
+pdfjs-first-page-button-label = Koy moo jinaa ga
+pdfjs-last-page-button =
+ .title = Koy moo koraa ga
+pdfjs-last-page-button-label = Koy moo koraa ga
+pdfjs-page-rotate-cw-button =
+ .title = Kuubi kanbe guma here
+pdfjs-page-rotate-cw-button-label = Kuubi kanbe guma here
+pdfjs-page-rotate-ccw-button =
+ .title = Kuubi kanbe wowa here
+pdfjs-page-rotate-ccw-button-label = Kuubi kanbe wowa here
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Takadda mayrawey…
+pdfjs-document-properties-button-label = Takadda mayrawey…
+pdfjs-document-properties-file-name = Tuku maa:
+pdfjs-document-properties-file-size = Tuku adadu:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = KB { $size_kb } (cebsu-ize { $size_b })
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = MB { $size_mb } (cebsu-ize { $size_b })
+pdfjs-document-properties-title = Tiiramaa:
+pdfjs-document-properties-author = Hantumkaw:
+pdfjs-document-properties-subject = Dalil:
+pdfjs-document-properties-keywords = Kufalkalimawey:
+pdfjs-document-properties-creation-date = Teeyan han:
+pdfjs-document-properties-modification-date = Barmayan han:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Teekaw:
+pdfjs-document-properties-producer = PDF berandikaw:
+pdfjs-document-properties-version = PDF dumi:
+pdfjs-document-properties-page-count = Moo hinna:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = Daabu
+
+## Print
+
+pdfjs-print-progress-message = Goo ma takaddaa soolu k'a kar se…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Naŋ
+pdfjs-printing-not-supported = Yaamar: Karyan Å¡i tee ka timme nda ceecikaa woo.
+pdfjs-printing-not-ready = Yaamar: PDF Å¡i zunbu ka timme karyan Å¡e.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Kanjari ceraw zuu
+pdfjs-toggle-sidebar-button-label = Kanjari ceraw zuu
+pdfjs-document-outline-button =
+ .title = Takaddaa korfur alhaaloo cebe (naagu cee hinka ka haya-izey kul hayandi/kankamandi)
+pdfjs-document-outline-button-label = Takadda filla-boŋ
+pdfjs-attachments-button =
+ .title = Hangarey cebe
+pdfjs-attachments-button-label = Hangarey
+pdfjs-thumbs-button =
+ .title = Kabeboy biyey cebe
+pdfjs-thumbs-button-label = Kabeboy biyey
+pdfjs-findbar-button =
+ .title = Ceeci takaddaa ra
+pdfjs-findbar-button-label = Ceeci
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } moo
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Kabeboy bii { $page } moo Å¡e
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Ceeci
+ .placeholder = Ceeci takaddaa ra…
+pdfjs-find-previous-button =
+ .title = Kalimaɲaŋoo bangayri bisantaa ceeci
+pdfjs-find-previous-button-label = Bisante
+pdfjs-find-next-button =
+ .title = Kalimaɲaŋoo hiino bangayroo ceeci
+pdfjs-find-next-button-label = Jine
+pdfjs-find-highlight-checkbox = Ikul Å¡ilbay
+pdfjs-find-match-case-checkbox-label = Harfu-beeriyan hawgay
+pdfjs-find-reached-top = A too moŋoo boŋoo, koy jine ka šinitin nda cewoo
+pdfjs-find-reached-bottom = A too moɲoo cewoo, koy jine šintioo ga
+pdfjs-find-not-found = Kalimaɲaa mana duwandi
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Mooo hayyan
+pdfjs-page-scale-fit = Moo sawayan
+pdfjs-page-scale-auto = Boŋše azzaati barmayyan
+pdfjs-page-scale-actual = Adadu cimi
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Firka bangay kaŋ PDF goo ma zumandi.
+pdfjs-invalid-file-error = PDF tuku laala wala laybante.
+pdfjs-missing-file-error = PDF tuku kumante.
+pdfjs-unexpected-response-error = Manti feršikaw tuuruyan maatante.
+pdfjs-rendering-error = Firka bangay kaŋ moɲoo goo ma willandi.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = { $type } maasa-caw]
+
+## Password
+
+pdfjs-password-label = Å ennikufal dam ka PDF tukoo woo feeri.
+pdfjs-password-invalid = Å ennikufal laalo. Ceeci koyne taare.
+pdfjs-password-ok-button = Ayyo
+pdfjs-password-cancel-button = Naŋ
+pdfjs-web-fonts-disabled = Interneti Å¡igirawey kay: Å¡i hin ka goy nda PDF Å¡igira hurantey.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sq/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sq/viewer.ftl
new file mode 100644
index 000000000..e46f5e4b8
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sq/viewer.ftl
@@ -0,0 +1,375 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Faqja e Mëparshme
+pdfjs-previous-button-label = E mëparshmja
+pdfjs-next-button =
+ .title = Faqja Pasuese
+pdfjs-next-button-label = Pasuesja
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Faqe
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = nga { $pagesCount } gjithsej
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } nga { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zvogëlojeni
+pdfjs-zoom-out-button-label = Zvogëlojeni
+pdfjs-zoom-in-button =
+ .title = Zmadhojeni
+pdfjs-zoom-in-button-label = Zmadhojini
+pdfjs-zoom-select =
+ .title = Zmadhim/Zvogëlim
+pdfjs-presentation-mode-button =
+ .title = Kalo te Mënyra Paraqitje
+pdfjs-presentation-mode-button-label = Mënyra Paraqitje
+pdfjs-open-file-button =
+ .title = Hapni Kartelë
+pdfjs-open-file-button-label = Hape
+pdfjs-print-button =
+ .title = Shtypje
+pdfjs-print-button-label = Shtype
+pdfjs-save-button =
+ .title = Ruaje
+pdfjs-save-button-label = Ruaje
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Shkarkojeni
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Shkarkoje
+pdfjs-bookmark-button =
+ .title = Faqja e Tanishme (Shihni URL nga Faqja e Tanishme)
+pdfjs-bookmark-button-label = Faqja e Tanishme
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Hape në aplikacion
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Hape në aplikacion
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Mjete
+pdfjs-tools-button-label = Mjete
+pdfjs-first-page-button =
+ .title = Kaloni te Faqja e Parë
+pdfjs-first-page-button-label = Kaloni te Faqja e Parë
+pdfjs-last-page-button =
+ .title = Kaloni te Faqja e Fundit
+pdfjs-last-page-button-label = Kaloni te Faqja e Fundit
+pdfjs-page-rotate-cw-button =
+ .title = Rrotullojeni Në Kahun Orar
+pdfjs-page-rotate-cw-button-label = Rrotulloje Në Kahun Orar
+pdfjs-page-rotate-ccw-button =
+ .title = Rrotullojeni Në Kahun Kundërorar
+pdfjs-page-rotate-ccw-button-label = Rrotulloje Në Kahun Kundërorar
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktivizo Mjet Përzgjedhjeje Teksti
+pdfjs-cursor-text-select-tool-button-label = Mjet Përzgjedhjeje Teksti
+pdfjs-cursor-hand-tool-button =
+ .title = Aktivizo Mjetin Dorë
+pdfjs-cursor-hand-tool-button-label = Mjeti Dorë
+pdfjs-scroll-page-button =
+ .title = Përdor Rrëshqitje Në Faqe
+pdfjs-scroll-page-button-label = Rrëshqitje Në Faqe
+pdfjs-scroll-vertical-button =
+ .title = Përdor Rrëshqitje Vertikale
+pdfjs-scroll-vertical-button-label = Rrëshqitje Vertikale
+pdfjs-scroll-horizontal-button =
+ .title = Përdor Rrëshqitje Horizontale
+pdfjs-scroll-horizontal-button-label = Rrëshqitje Horizontale
+pdfjs-scroll-wrapped-button =
+ .title = Përdor Rrëshqitje Me Mbështjellje
+pdfjs-scroll-wrapped-button-label = Rrëshqitje Me Mbështjellje
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Veti Dokumenti…
+pdfjs-document-properties-button-label = Veti Dokumenti…
+pdfjs-document-properties-file-name = Emër kartele:
+pdfjs-document-properties-file-size = Madhësi kartele:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bajte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bajte)
+pdfjs-document-properties-title = Titull:
+pdfjs-document-properties-author = Autor:
+pdfjs-document-properties-subject = Subjekt:
+pdfjs-document-properties-keywords = Fjalëkyçe:
+pdfjs-document-properties-creation-date = Datë Krijimi:
+pdfjs-document-properties-modification-date = Datë Ndryshimi:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Krijues:
+pdfjs-document-properties-producer = Prodhues PDF-je:
+pdfjs-document-properties-version = Version PDF-je:
+pdfjs-document-properties-page-count = Numër Faqesh:
+pdfjs-document-properties-page-size = Madhësi Faqeje:
+pdfjs-document-properties-page-size-unit-inches = inç
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = portret
+pdfjs-document-properties-page-size-orientation-landscape = së gjeri
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Parje e Shpjetë në Web:
+pdfjs-document-properties-linearized-yes = Po
+pdfjs-document-properties-linearized-no = Jo
+pdfjs-document-properties-close-button = Mbylleni
+
+## Print
+
+pdfjs-print-progress-message = Po përgatitet dokumenti për shtypje…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Anuloje
+pdfjs-printing-not-supported = Kujdes: Shtypja s’mbulohet plotësisht nga ky shfletues.
+pdfjs-printing-not-ready = Kujdes: PDF-ja s’është ngarkuar plotësisht që ta shtypni.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Shfaqni/Fshihni Anështyllën
+pdfjs-toggle-sidebar-notification-button =
+ .title = Hap/Mbyll Anështylë (dokumenti përmban përvijim/nashkëngjitje/shtresa)
+pdfjs-toggle-sidebar-button-label = Shfaq/Fshih Anështyllën
+pdfjs-document-outline-button =
+ .title = Shfaqni Përvijim Dokumenti (dyklikoni që të shfaqen/fshihen krejt elementët)
+pdfjs-document-outline-button-label = Përvijim Dokumenti
+pdfjs-attachments-button =
+ .title = Shfaqni Bashkëngjitje
+pdfjs-attachments-button-label = Bashkëngjitje
+pdfjs-layers-button =
+ .title = Shfaq Shtresa (dyklikoni që të rikthehen krejt shtresat në gjendjen e tyre parazgjedhje)
+pdfjs-layers-button-label = Shtresa
+pdfjs-thumbs-button =
+ .title = Shfaqni Miniatura
+pdfjs-thumbs-button-label = Miniatura
+pdfjs-current-outline-item-button =
+ .title = Gjej Objektin e Tanishëm të Përvijuar
+pdfjs-current-outline-item-button-label = Objekt i Tanishëm i Përvijuar
+pdfjs-findbar-button =
+ .title = Gjeni në Dokument
+pdfjs-findbar-button-label = Gjej
+pdfjs-additional-layers = Shtresa Shtesë
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Faqja { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniaturë e Faqes { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Gjej
+ .placeholder = Gjeni në dokument…
+pdfjs-find-previous-button =
+ .title = Gjeni hasjen e mëparshme të togfjalëshit
+pdfjs-find-previous-button-label = E mëparshmja
+pdfjs-find-next-button =
+ .title = Gjeni hasjen pasuese të togfjalëshit
+pdfjs-find-next-button-label = Pasuesja
+pdfjs-find-highlight-checkbox = Theksoji të tëra
+pdfjs-find-match-case-checkbox-label = Siç Është Shkruar
+pdfjs-find-match-diacritics-checkbox-label = Me Përputhje Me Shenjat Diakritike
+pdfjs-find-entire-word-checkbox-label = Fjalë të Plota
+pdfjs-find-reached-top = U mbërrit në krye të dokumentit, vazhduar prej fundit
+pdfjs-find-reached-bottom = U mbërrit në fund të dokumentit, vazhduar prej kreut
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } nga { $total } përputhje
+ *[other] { $current } nga { $total } përputhje
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Më tepër se { $limit } përputhje
+ *[other] Më tepër se { $limit } përputhje
+ }
+pdfjs-find-not-found = Togfjalësh që s’gjendet
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Gjerësi Faqeje
+pdfjs-page-scale-fit = Sa Nxë Faqja
+pdfjs-page-scale-auto = Zoom i Vetvetishëm
+pdfjs-page-scale-actual = Madhësia Faktike
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Faqja { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ndodhi një gabim gjatë ngarkimit të PDF-së.
+pdfjs-invalid-file-error = Kartelë PDF e pavlefshme ose e dëmtuar.
+pdfjs-missing-file-error = Kartelë PDF që mungon.
+pdfjs-unexpected-response-error = Përgjigje shërbyesi e papritur.
+pdfjs-rendering-error = Ndodhi një gabim gjatë riprodhimit të faqes.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Nënvizim { $type }]
+
+## Password
+
+pdfjs-password-label = Jepni fjalëkalimin që të hapet kjo kartelë PDF.
+pdfjs-password-invalid = Fjalëkalim i pavlefshëm. Ju lutemi, riprovoni.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Anuloje
+pdfjs-web-fonts-disabled = Shkronjat Web janë të çaktivizuara: s’arrihet të përdoren shkronja të trupëzuara në PDF.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Tekst
+pdfjs-editor-free-text-button-label = Tekst
+pdfjs-editor-ink-button =
+ .title = Vizatoni
+pdfjs-editor-ink-button-label = Vizatoni
+pdfjs-editor-stamp-button =
+ .title = Shtoni ose përpunoni figura
+pdfjs-editor-stamp-button-label = Shtoni ose përpunoni figura
+pdfjs-editor-remove-button =
+ .title = Hiqe
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Hiq vizatim
+pdfjs-editor-remove-freetext-button =
+ .title = Hiq tekst
+pdfjs-editor-remove-stamp-button =
+ .title = Hiq figurë
+pdfjs-editor-remove-highlight-button =
+ .title = Hiqe theksimin
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Ngjyrë
+pdfjs-editor-free-text-size-input = Madhësi
+pdfjs-editor-ink-color-input = Ngjyrë
+pdfjs-editor-ink-thickness-input = Trashësi
+pdfjs-editor-ink-opacity-input = Patejdukshmëri
+pdfjs-editor-stamp-add-image-button =
+ .title = Shtoni figurë
+pdfjs-editor-stamp-add-image-button-label = Shtoni figurë
+pdfjs-free-text =
+ .aria-label = Përpunues Tekstesh
+pdfjs-free-text-default-content = Filloni të shtypni…
+pdfjs-ink =
+ .aria-label = Përpunues Vizatimesh
+pdfjs-ink-canvas =
+ .aria-label = Figurë e krijuar nga përdoruesi
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Tekst alternativ
+pdfjs-editor-alt-text-edit-button-label = Përpunoni tekst alternativ
+pdfjs-editor-alt-text-dialog-label = Zgjidhni një mundësi
+pdfjs-editor-alt-text-dialog-description = Teksti alt (tekst alternativ) vjen në ndihmë kur njerëzit s’mund të shohin figurën, ose kur ajo nuk ngarkohet.
+pdfjs-editor-alt-text-add-description-label = Shtoni një përshkrim
+pdfjs-editor-alt-text-add-description-description = Synoni për 1-2 togfjalësha që përshkruajnë subjektin, rrethanat apo veprimet.
+pdfjs-editor-alt-text-mark-decorative-label = Vëri shenjë si dekorative
+pdfjs-editor-alt-text-mark-decorative-description = Kjo përdoret për figura zbukuruese, fjala vjen, anë, ose watermark-e.
+pdfjs-editor-alt-text-cancel-button = Anuloje
+pdfjs-editor-alt-text-save-button = Ruaje
+pdfjs-editor-alt-text-decorative-tooltip = Iu vu shenjë si dekorative
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Për shembull, “Një djalosh ulet në një tryezë të hajëâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Cepi i sipërm majtas — ripërmasojeni
+pdfjs-editor-resizer-label-top-middle = Mesi i pjesës sipër — ripërmasojeni
+pdfjs-editor-resizer-label-top-right = Cepi i sipërm djathtas — ripërmasojeni
+pdfjs-editor-resizer-label-middle-right = Djathtas në mes — ripërmasojeni
+pdfjs-editor-resizer-label-bottom-right = Cepi i poshtëm djathtas — ripërmasojeni
+pdfjs-editor-resizer-label-bottom-middle = Mesi i pjesës poshtë — ripërmasojeni
+pdfjs-editor-resizer-label-bottom-left = Cepi i poshtëm — ripërmasojeni
+pdfjs-editor-resizer-label-middle-left = Majtas në mes — ripërmasojeni
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Ngjyrë theksimi
+pdfjs-editor-colorpicker-button =
+ .title = Ndryshoni ngjyrë
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Zgjedhje ngjyre
+pdfjs-editor-colorpicker-yellow =
+ .title = E verdhë
+pdfjs-editor-colorpicker-green =
+ .title = E gjelbër
+pdfjs-editor-colorpicker-blue =
+ .title = Blu
+pdfjs-editor-colorpicker-pink =
+ .title = Rozë
+pdfjs-editor-colorpicker-red =
+ .title = E kuqe
diff --git a/www/lib/pdfjs/modern/web/locale/sr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sr/viewer.ftl
new file mode 100644
index 000000000..c678d4917
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sr/viewer.ftl
@@ -0,0 +1,299 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Претходна Ñтраница
+pdfjs-previous-button-label = Претходна
+pdfjs-next-button =
+ .title = Следећа Ñтраница
+pdfjs-next-button-label = Следећа
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Страница
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = од { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } од { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Умањи
+pdfjs-zoom-out-button-label = Умањи
+pdfjs-zoom-in-button =
+ .title = Увеличај
+pdfjs-zoom-in-button-label = Увеличај
+pdfjs-zoom-select =
+ .title = Увеличавање
+pdfjs-presentation-mode-button =
+ .title = Промени на приказ у режиму презентације
+pdfjs-presentation-mode-button-label = Режим презентације
+pdfjs-open-file-button =
+ .title = Отвори датотеку
+pdfjs-open-file-button-label = Отвори
+pdfjs-print-button =
+ .title = Штампај
+pdfjs-print-button-label = Штампај
+pdfjs-save-button =
+ .title = Сачувај
+pdfjs-save-button-label = Сачувај
+pdfjs-bookmark-button =
+ .title = Тренутна Ñтраница (погледајте URL Ñа тренутне Ñтранице)
+pdfjs-bookmark-button-label = Тренутна Ñтраница
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Отвори у апликацији
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Отвори у апликацији
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ðлатке
+pdfjs-tools-button-label = Ðлатке
+pdfjs-first-page-button =
+ .title = Иди на прву Ñтраницу
+pdfjs-first-page-button-label = Иди на прву Ñтраницу
+pdfjs-last-page-button =
+ .title = Иди на поÑледњу Ñтраницу
+pdfjs-last-page-button-label = Иди на поÑледњу Ñтраницу
+pdfjs-page-rotate-cw-button =
+ .title = Ротирај у Ñмеру казаљке на Ñату
+pdfjs-page-rotate-cw-button-label = Ротирај у Ñмеру казаљке на Ñату
+pdfjs-page-rotate-ccw-button =
+ .title = Ротирај у Ñмеру Ñупротном од казаљке на Ñату
+pdfjs-page-rotate-ccw-button-label = Ротирај у Ñмеру Ñупротном од казаљке на Ñату
+pdfjs-cursor-text-select-tool-button =
+ .title = Омогући алат за Ñелектовање текÑта
+pdfjs-cursor-text-select-tool-button-label = Ðлат за Ñелектовање текÑта
+pdfjs-cursor-hand-tool-button =
+ .title = Омогући алат за померање
+pdfjs-cursor-hand-tool-button-label = Ðлат за померање
+pdfjs-scroll-page-button =
+ .title = КориÑти Ñкроловање по омоту
+pdfjs-scroll-page-button-label = Скроловање Ñтранице
+pdfjs-scroll-vertical-button =
+ .title = КориÑти вертикално Ñкроловање
+pdfjs-scroll-vertical-button-label = Вертикално Ñкроловање
+pdfjs-scroll-horizontal-button =
+ .title = КориÑти хоризонтално Ñкроловање
+pdfjs-scroll-horizontal-button-label = Хоризонтално Ñкроловање
+pdfjs-scroll-wrapped-button =
+ .title = КориÑти Ñкроловање по омоту
+pdfjs-scroll-wrapped-button-label = Скроловање по омоту
+pdfjs-spread-none-button =
+ .title = Ðемој Ñпајати ширења Ñтраница
+pdfjs-spread-none-button-label = Без раÑпроÑтирања
+pdfjs-spread-odd-button =
+ .title = Споји ширења Ñтраница које почињу непарним бројем
+pdfjs-spread-odd-button-label = Ðепарна раÑпроÑтирања
+pdfjs-spread-even-button =
+ .title = Споји ширења Ñтраница које почињу парним бројем
+pdfjs-spread-even-button-label = Парна раÑпроÑтирања
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Параметри документа…
+pdfjs-document-properties-button-label = Параметри документа…
+pdfjs-document-properties-file-name = Име датотеке:
+pdfjs-document-properties-file-size = Величина датотеке:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } B)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } B)
+pdfjs-document-properties-title = ÐаÑлов:
+pdfjs-document-properties-author = Ðутор:
+pdfjs-document-properties-subject = Тема:
+pdfjs-document-properties-keywords = Кључне речи:
+pdfjs-document-properties-creation-date = Датум креирања:
+pdfjs-document-properties-modification-date = Датум модификације:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Стваралац:
+pdfjs-document-properties-producer = PDF произвођач:
+pdfjs-document-properties-version = PDF верзија:
+pdfjs-document-properties-page-count = Број Ñтраница:
+pdfjs-document-properties-page-size = Величина Ñтранице:
+pdfjs-document-properties-page-size-unit-inches = ин
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = уÑправно
+pdfjs-document-properties-page-size-orientation-landscape = водоравно
+pdfjs-document-properties-page-size-name-a-three = Ð3
+pdfjs-document-properties-page-size-name-a-four = Ð4
+pdfjs-document-properties-page-size-name-letter = Слово
+pdfjs-document-properties-page-size-name-legal = Права
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Брз веб приказ:
+pdfjs-document-properties-linearized-yes = Да
+pdfjs-document-properties-linearized-no = Ðе
+pdfjs-document-properties-close-button = Затвори
+
+## Print
+
+pdfjs-print-progress-message = Припремам документ за штампање…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Откажи
+pdfjs-printing-not-supported = Упозорење: Штампање није у потпуноÑти подржано у овом прегледачу.
+pdfjs-printing-not-ready = Упозорење: PDF није у потпуноÑти учитан за штампу.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Прикажи додатну палету
+pdfjs-toggle-sidebar-notification-button =
+ .title = Прикажи/Ñакриј бочну траку (документ Ñадржи контуру/прилоге/Ñлојеве)
+pdfjs-toggle-sidebar-button-label = Прикажи додатну палету
+pdfjs-document-outline-button =
+ .title = Прикажи Ñтруктуру документа (двоÑтруким кликом проширујете/Ñкупљате Ñве Ñтавке)
+pdfjs-document-outline-button-label = Контура документа
+pdfjs-attachments-button =
+ .title = Прикажи прилоге
+pdfjs-attachments-button-label = Прилози
+pdfjs-layers-button =
+ .title = Прикажи Ñлојеве (дупли клик за враћање Ñвих Ñлојева у подразумевано Ñтање)
+pdfjs-layers-button-label = Слојеви
+pdfjs-thumbs-button =
+ .title = Прикажи Ñличице
+pdfjs-thumbs-button-label = Сличице
+pdfjs-current-outline-item-button =
+ .title = Пронађите тренутни елемент Ñтруктуре
+pdfjs-current-outline-item-button-label = Тренутна контура
+pdfjs-findbar-button =
+ .title = Пронађи у документу
+pdfjs-findbar-button-label = Пронађи
+pdfjs-additional-layers = Додатни Ñлојеви
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Страница { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Сличица од Ñтранице { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Пронађи
+ .placeholder = Пронађи у документу…
+pdfjs-find-previous-button =
+ .title = Пронађи претходно појављивање фразе
+pdfjs-find-previous-button-label = Претходна
+pdfjs-find-next-button =
+ .title = Пронађи Ñледеће појављивање фразе
+pdfjs-find-next-button-label = Следећа
+pdfjs-find-highlight-checkbox = ИÑтакнути Ñве
+pdfjs-find-match-case-checkbox-label = Подударања
+pdfjs-find-match-diacritics-checkbox-label = Дијакритика
+pdfjs-find-entire-word-checkbox-label = Целе речи
+pdfjs-find-reached-top = ДоÑтигнут врх документа, наÑтавио Ñа дна
+pdfjs-find-reached-bottom = ДоÑтигнуто дно документа, наÑтавио Ñа врха
+pdfjs-find-not-found = Фраза није пронађена
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ширина Ñтранице
+pdfjs-page-scale-fit = Прилагоди Ñтраницу
+pdfjs-page-scale-auto = ÐутоматÑко увеличавање
+pdfjs-page-scale-actual = Стварна величина
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Страница { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Дошло је до грешке приликом учитавања PDF-а.
+pdfjs-invalid-file-error = PDF датотека је неважећа или је оштећена.
+pdfjs-missing-file-error = ÐедоÑтаје PDF датотека.
+pdfjs-unexpected-response-error = Ðеочекиван одговор од Ñервера.
+pdfjs-rendering-error = Дошло је до грешке приликом рендеровања ове Ñтранице.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } коментар]
+
+## Password
+
+pdfjs-password-label = УнеÑите лозинку да биÑте отворили овај PDF докуменат.
+pdfjs-password-invalid = ÐеиÑправна лозинка. Покушајте поново.
+pdfjs-password-ok-button = У реду
+pdfjs-password-cancel-button = Откажи
+pdfjs-web-fonts-disabled = Веб фонтови Ñу онемогућени: не могу кориÑтити уграђене PDF фонтове.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ТекÑÑ‚
+pdfjs-editor-free-text-button-label = ТекÑÑ‚
+pdfjs-editor-ink-button =
+ .title = Цртај
+pdfjs-editor-ink-button-label = Цртај
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Боја
+pdfjs-editor-free-text-size-input = Величина
+pdfjs-editor-ink-color-input = Боја
+pdfjs-editor-ink-thickness-input = Дебљина
+pdfjs-editor-ink-opacity-input = Опацитет
+pdfjs-free-text =
+ .aria-label = Уређивач текÑта
+pdfjs-free-text-default-content = Почни куцање…
+pdfjs-ink =
+ .aria-label = Уређивач цртежа
+pdfjs-ink-canvas =
+ .aria-label = КориÑнички направљена Ñлика
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/sv-SE/viewer.ftl b/www/lib/pdfjs/modern/web/locale/sv-SE/viewer.ftl
new file mode 100644
index 000000000..bb840aabb
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/sv-SE/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Föregående sida
+pdfjs-previous-button-label = Föregående
+pdfjs-next-button =
+ .title = Nästa sida
+pdfjs-next-button-label = Nästa
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Sida
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = av { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } av { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zooma ut
+pdfjs-zoom-out-button-label = Zooma ut
+pdfjs-zoom-in-button =
+ .title = Zooma in
+pdfjs-zoom-in-button-label = Zooma in
+pdfjs-zoom-select =
+ .title = Zoom
+pdfjs-presentation-mode-button =
+ .title = Byt till presentationsläge
+pdfjs-presentation-mode-button-label = Presentationsläge
+pdfjs-open-file-button =
+ .title = Öppna fil
+pdfjs-open-file-button-label = Öppna
+pdfjs-print-button =
+ .title = Skriv ut
+pdfjs-print-button-label = Skriv ut
+pdfjs-save-button =
+ .title = Spara
+pdfjs-save-button-label = Spara
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Hämta
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Hämta
+pdfjs-bookmark-button =
+ .title = Aktuell sida (Visa URL från aktuell sida)
+pdfjs-bookmark-button-label = Aktuell sida
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Öppna i app
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Öppna i app
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Verktyg
+pdfjs-tools-button-label = Verktyg
+pdfjs-first-page-button =
+ .title = Gå till första sidan
+pdfjs-first-page-button-label = Gå till första sidan
+pdfjs-last-page-button =
+ .title = GÃ¥ till sista sidan
+pdfjs-last-page-button-label = GÃ¥ till sista sidan
+pdfjs-page-rotate-cw-button =
+ .title = Rotera medurs
+pdfjs-page-rotate-cw-button-label = Rotera medurs
+pdfjs-page-rotate-ccw-button =
+ .title = Rotera moturs
+pdfjs-page-rotate-ccw-button-label = Rotera moturs
+pdfjs-cursor-text-select-tool-button =
+ .title = Aktivera textmarkeringsverktyg
+pdfjs-cursor-text-select-tool-button-label = Textmarkeringsverktyg
+pdfjs-cursor-hand-tool-button =
+ .title = Aktivera handverktyg
+pdfjs-cursor-hand-tool-button-label = Handverktyg
+pdfjs-scroll-page-button =
+ .title = Använd sidrullning
+pdfjs-scroll-page-button-label = Sidrullning
+pdfjs-scroll-vertical-button =
+ .title = Använd vertikal rullning
+pdfjs-scroll-vertical-button-label = Vertikal rullning
+pdfjs-scroll-horizontal-button =
+ .title = Använd horisontell rullning
+pdfjs-scroll-horizontal-button-label = Horisontell rullning
+pdfjs-scroll-wrapped-button =
+ .title = Använd överlappande rullning
+pdfjs-scroll-wrapped-button-label = Överlappande rullning
+pdfjs-spread-none-button =
+ .title = Visa enkelsidor
+pdfjs-spread-none-button-label = Enkelsidor
+pdfjs-spread-odd-button =
+ .title = Visa uppslag med olika sidnummer till vänster
+pdfjs-spread-odd-button-label = Uppslag med framsida
+pdfjs-spread-even-button =
+ .title = Visa uppslag med lika sidnummer till vänster
+pdfjs-spread-even-button-label = Uppslag utan framsida
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Dokumentegenskaper…
+pdfjs-document-properties-button-label = Dokumentegenskaper…
+pdfjs-document-properties-file-name = Filnamn:
+pdfjs-document-properties-file-size = Filstorlek:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } kB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Titel:
+pdfjs-document-properties-author = Författare:
+pdfjs-document-properties-subject = Ämne:
+pdfjs-document-properties-keywords = Nyckelord:
+pdfjs-document-properties-creation-date = Skapades:
+pdfjs-document-properties-modification-date = Ändrades:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Skapare:
+pdfjs-document-properties-producer = PDF-producent:
+pdfjs-document-properties-version = PDF-version:
+pdfjs-document-properties-page-count = Sidantal:
+pdfjs-document-properties-page-size = Pappersstorlek:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = porträtt
+pdfjs-document-properties-page-size-orientation-landscape = landskap
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Snabb webbvisning:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Nej
+pdfjs-document-properties-close-button = Stäng
+
+## Print
+
+pdfjs-print-progress-message = Förbereder sidor för utskrift…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Avbryt
+pdfjs-printing-not-supported = Varning: Utskrifter stöds inte helt av den här webbläsaren.
+pdfjs-printing-not-ready = Varning: PDF:en är inte klar för utskrift.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Visa/dölj sidofält
+pdfjs-toggle-sidebar-notification-button =
+ .title = Växla sidofält (dokumentet innehåller dokumentstruktur/bilagor/lager)
+pdfjs-toggle-sidebar-button-label = Visa/dölj sidofält
+pdfjs-document-outline-button =
+ .title = Visa dokumentdisposition (dubbelklicka för att expandera/komprimera alla objekt)
+pdfjs-document-outline-button-label = Dokumentöversikt
+pdfjs-attachments-button =
+ .title = Visa Bilagor
+pdfjs-attachments-button-label = Bilagor
+pdfjs-layers-button =
+ .title = Visa lager (dubbelklicka för att återställa alla lager till standardläge)
+pdfjs-layers-button-label = Lager
+pdfjs-thumbs-button =
+ .title = Visa miniatyrer
+pdfjs-thumbs-button-label = Miniatyrer
+pdfjs-current-outline-item-button =
+ .title = Hitta aktuellt dispositionsobjekt
+pdfjs-current-outline-item-button-label = Aktuellt dispositionsobjekt
+pdfjs-findbar-button =
+ .title = Sök i dokument
+pdfjs-findbar-button-label = Sök
+pdfjs-additional-layers = Ytterligare lager
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Sida { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatyr av sida { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Sök
+ .placeholder = Sök i dokument…
+pdfjs-find-previous-button =
+ .title = Hitta föregående förekomst av frasen
+pdfjs-find-previous-button-label = Föregående
+pdfjs-find-next-button =
+ .title = Hitta nästa förekomst av frasen
+pdfjs-find-next-button-label = Nästa
+pdfjs-find-highlight-checkbox = Markera alla
+pdfjs-find-match-case-checkbox-label = Matcha versal/gemen
+pdfjs-find-match-diacritics-checkbox-label = Matcha diakritiska tecken
+pdfjs-find-entire-word-checkbox-label = Hela ord
+pdfjs-find-reached-top = Nådde början av dokumentet, började från slutet
+pdfjs-find-reached-bottom = Nådde slutet på dokumentet, började från början
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } av { $total } match
+ *[other] { $current } av { $total } matchningar
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Mer än { $limit } matchning
+ *[other] Fler än { $limit } matchningar
+ }
+pdfjs-find-not-found = Frasen hittades inte
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sidbredd
+pdfjs-page-scale-fit = Anpassa sida
+pdfjs-page-scale-auto = Automatisk zoom
+pdfjs-page-scale-actual = Verklig storlek
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Sida { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ett fel uppstod vid laddning av PDF-filen.
+pdfjs-invalid-file-error = Ogiltig eller korrupt PDF-fil.
+pdfjs-missing-file-error = Saknad PDF-fil.
+pdfjs-unexpected-response-error = Oväntat svar från servern.
+pdfjs-rendering-error = Ett fel uppstod vid visning av sidan.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-annotering]
+
+## Password
+
+pdfjs-password-label = Skriv in lösenordet för att öppna PDF-filen.
+pdfjs-password-invalid = Ogiltigt lösenord. Försök igen.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Avbryt
+pdfjs-web-fonts-disabled = Webbtypsnitt är inaktiverade: kan inte använda inbäddade PDF-typsnitt.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Text
+pdfjs-editor-free-text-button-label = Text
+pdfjs-editor-ink-button =
+ .title = Rita
+pdfjs-editor-ink-button-label = Rita
+pdfjs-editor-stamp-button =
+ .title = Lägg till eller redigera bilder
+pdfjs-editor-stamp-button-label = Lägg till eller redigera bilder
+pdfjs-editor-remove-button =
+ .title = Ta bort
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Ta bort ritning
+pdfjs-editor-remove-freetext-button =
+ .title = Ta bort text
+pdfjs-editor-remove-stamp-button =
+ .title = Ta bort bild
+pdfjs-editor-remove-highlight-button =
+ .title = Ta bort markering
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Färg
+pdfjs-editor-free-text-size-input = Storlek
+pdfjs-editor-ink-color-input = Färg
+pdfjs-editor-ink-thickness-input = Tjocklek
+pdfjs-editor-ink-opacity-input = Opacitet
+pdfjs-editor-stamp-add-image-button =
+ .title = Lägg till bild
+pdfjs-editor-stamp-add-image-button-label = Lägg till bild
+pdfjs-free-text =
+ .aria-label = Textredigerare
+pdfjs-free-text-default-content = Börja skriva…
+pdfjs-ink =
+ .aria-label = Ritredigerare
+pdfjs-ink-canvas =
+ .aria-label = Användarskapad bild
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternativ text
+pdfjs-editor-alt-text-edit-button-label = Redigera alternativ text
+pdfjs-editor-alt-text-dialog-label = Välj ett alternativ
+pdfjs-editor-alt-text-dialog-description = Alt text (alternativ text) hjälper till när människor inte kan se bilden eller när den inte laddas.
+pdfjs-editor-alt-text-add-description-label = Lägg till en beskrivning
+pdfjs-editor-alt-text-add-description-description = Sikta på 1-2 meningar som beskriver ämnet, miljön eller handlingen.
+pdfjs-editor-alt-text-mark-decorative-label = Markera som dekorativ
+pdfjs-editor-alt-text-mark-decorative-description = Detta används för dekorativa bilder, som kanter eller vattenstämplar.
+pdfjs-editor-alt-text-cancel-button = Avbryt
+pdfjs-editor-alt-text-save-button = Spara
+pdfjs-editor-alt-text-decorative-tooltip = Märkt som dekorativ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Till exempel, "En ung man sätter sig vid ett bord för att äta en måltid"
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Det övre vänstra hörnet — ändra storlek
+pdfjs-editor-resizer-label-top-middle = Överst i mitten — ändra storlek
+pdfjs-editor-resizer-label-top-right = Det övre högra hörnet — ändra storlek
+pdfjs-editor-resizer-label-middle-right = Mitten höger — ändra storlek
+pdfjs-editor-resizer-label-bottom-right = Nedre högra hörnet — ändra storlek
+pdfjs-editor-resizer-label-bottom-middle = Nedre mitten — ändra storlek
+pdfjs-editor-resizer-label-bottom-left = Nedre vänstra hörnet — ändra storlek
+pdfjs-editor-resizer-label-middle-left = Mitten till vänster — ändra storlek
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Markeringsfärg
+pdfjs-editor-colorpicker-button =
+ .title = Ändra färg
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Färgval
+pdfjs-editor-colorpicker-yellow =
+ .title = Gul
+pdfjs-editor-colorpicker-green =
+ .title = Grön
+pdfjs-editor-colorpicker-blue =
+ .title = Blå
+pdfjs-editor-colorpicker-pink =
+ .title = Rosa
+pdfjs-editor-colorpicker-red =
+ .title = Röd
diff --git a/www/lib/pdfjs/modern/web/locale/szl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/szl/viewer.ftl
new file mode 100644
index 000000000..cbf166e45
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/szl/viewer.ftl
@@ -0,0 +1,257 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Piyrwyjszo strÅna
+pdfjs-previous-button-label = Piyrwyjszo
+pdfjs-next-button =
+ .title = Nastympno strÅna
+pdfjs-next-button-label = Dalij
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = StrÅna
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = ze { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } ze { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Zmyńsz
+pdfjs-zoom-out-button-label = Zmyńsz
+pdfjs-zoom-in-button =
+ .title = Zwiynksz
+pdfjs-zoom-in-button-label = Zwiynksz
+pdfjs-zoom-select =
+ .title = Srogość
+pdfjs-presentation-mode-button =
+ .title = PrzeÅ‚Åncz na tryb prezyntacyje
+pdfjs-presentation-mode-button-label = Tryb prezyntacyje
+pdfjs-open-file-button =
+ .title = Ôdewrzij zbiÅr
+pdfjs-open-file-button-label = Ôdewrzij
+pdfjs-print-button =
+ .title = Durkuj
+pdfjs-print-button-label = Durkuj
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Noczynia
+pdfjs-tools-button-label = Noczynia
+pdfjs-first-page-button =
+ .title = Idź ku piyrszyj strÅnie
+pdfjs-first-page-button-label = Idź ku piyrszyj strÅnie
+pdfjs-last-page-button =
+ .title = Idź ku ôstatnij strÅnie
+pdfjs-last-page-button-label = Idź ku ôstatnij strÅnie
+pdfjs-page-rotate-cw-button =
+ .title = Zwyrtnij w prawo
+pdfjs-page-rotate-cw-button-label = Zwyrtnij w prawo
+pdfjs-page-rotate-ccw-button =
+ .title = Zwyrtnij w lewo
+pdfjs-page-rotate-ccw-button-label = Zwyrtnij w lewo
+pdfjs-cursor-text-select-tool-button =
+ .title = ZaÅ‚Åncz noczynie ôbiyranio tekstu
+pdfjs-cursor-text-select-tool-button-label = Noczynie ôbiyranio tekstu
+pdfjs-cursor-hand-tool-button =
+ .title = ZaÅ‚Åncz noczynie rÅnczka
+pdfjs-cursor-hand-tool-button-label = Noczynie rÅnczka
+pdfjs-scroll-vertical-button =
+ .title = Używej piÅnowego przewijanio
+pdfjs-scroll-vertical-button-label = PiÅnowe przewijanie
+pdfjs-scroll-horizontal-button =
+ .title = Używej poziÅmego przewijanio
+pdfjs-scroll-horizontal-button-label = PoziÅme przewijanie
+pdfjs-scroll-wrapped-button =
+ .title = Używej szichtowego przewijanio
+pdfjs-scroll-wrapped-button-label = Szichtowe przewijanie
+pdfjs-spread-none-button =
+ .title = Niy dowej strÅn w widoku po dwie
+pdfjs-spread-none-button-label = Po jednyj strÅnie
+pdfjs-spread-odd-button =
+ .title = Pokoż strÅny po dwie; niyporziste po lewyj
+pdfjs-spread-odd-button-label = Niyporziste po lewyj
+pdfjs-spread-even-button =
+ .title = Pokoż strÅny po dwie; porziste po lewyj
+pdfjs-spread-even-button-label = Porziste po lewyj
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Włosności dokumyntu…
+pdfjs-document-properties-button-label = Włosności dokumyntu…
+pdfjs-document-properties-file-name = Miano zbioru:
+pdfjs-document-properties-file-size = Srogość zbioru:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb }Â KB ({ $size_b }Â B)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb }Â MB ({ $size_b }Â B)
+pdfjs-document-properties-title = Tytuł:
+pdfjs-document-properties-author = AutÅr:
+pdfjs-document-properties-subject = Tymat:
+pdfjs-document-properties-keywords = Kluczowe słowa:
+pdfjs-document-properties-creation-date = Data zrychtowanio:
+pdfjs-document-properties-modification-date = Data zmiany:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Zrychtowane ôd:
+pdfjs-document-properties-producer = PDF ôd:
+pdfjs-document-properties-version = Wersyjo PDF:
+pdfjs-document-properties-page-count = Wielość strÅn:
+pdfjs-document-properties-page-size = Srogość strÅny:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = piÅnowo
+pdfjs-document-properties-page-size-orientation-landscape = poziÅmo
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Gibki necowy podglÅnd:
+pdfjs-document-properties-linearized-yes = Ja
+pdfjs-document-properties-linearized-no = Niy
+pdfjs-document-properties-close-button = Zawrzij
+
+## Print
+
+pdfjs-print-progress-message = Rychtowanie dokumyntu do durku…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Pociep
+pdfjs-printing-not-supported = PozÅr: Ta przeglÅndarka niy coÅ‚kiym ôbsuguje durk.
+pdfjs-printing-not-ready = PozÅr: Tyn PDF niy ma za tela zaladowany do durku.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = PrzeÅ‚Åncz posek na rancie
+pdfjs-toggle-sidebar-notification-button =
+ .title = PrzeÅ‚Åncz posek na rancie (dokumynt mo struktura/przidowki/warstwy)
+pdfjs-toggle-sidebar-button-label = PrzeÅ‚Åncz posek na rancie
+pdfjs-document-outline-button =
+ .title = Pokoż struktura dokumyntu (tuplowane klikniyncie rozszyrzo/swijo wszyskie elymynta)
+pdfjs-document-outline-button-label = Struktura dokumyntu
+pdfjs-attachments-button =
+ .title = Pokoż przidowki
+pdfjs-attachments-button-label = Przidowki
+pdfjs-layers-button =
+ .title = Pokoż warstwy (tuplowane klikniyncie resetuje wszyskie warstwy do bazowego stanu)
+pdfjs-layers-button-label = Warstwy
+pdfjs-thumbs-button =
+ .title = Pokoż miniatury
+pdfjs-thumbs-button-label = Miniatury
+pdfjs-findbar-button =
+ .title = Znojdź w dokumyncie
+pdfjs-findbar-button-label = Znojdź
+pdfjs-additional-layers = Nadbytnie warstwy
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = StrÅna { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Miniatura strÅny { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Znojdź
+ .placeholder = Znojdź w dokumyncie…
+pdfjs-find-previous-button =
+ .title = Znojdź piyrwyjsze pokozanie sie tyj frazy
+pdfjs-find-previous-button-label = Piyrwyjszo
+pdfjs-find-next-button =
+ .title = Znojdź nastympne pokozanie sie tyj frazy
+pdfjs-find-next-button-label = Dalij
+pdfjs-find-highlight-checkbox = Zaznacz wszysko
+pdfjs-find-match-case-checkbox-label = Poznowej srogość liter
+pdfjs-find-entire-word-checkbox-label = Cołke słowa
+pdfjs-find-reached-top = DoszÅ‚o do samego wiyrchu strÅny, dalij ôd spodku
+pdfjs-find-reached-bottom = DoszÅ‚o do samego spodku strÅny, dalij ôd wiyrchu
+pdfjs-find-not-found = Fraza niy znaleziÅno
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Szyrzka strÅny
+pdfjs-page-scale-fit = Napasowanie strÅny
+pdfjs-page-scale-auto = AutÅmatyczno srogość
+pdfjs-page-scale-actual = Aktualno srogość
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Przi ladowaniu PDFa pokozoł sie feler.
+pdfjs-invalid-file-error = ZÅ‚y abo felerny zbiÅr PDF.
+pdfjs-missing-file-error = Chybio zbioru PDF.
+pdfjs-unexpected-response-error = Niyôczekowano ôdpowiydź serwera.
+pdfjs-rendering-error = Przi renderowaniu strÅny pokozoÅ‚ sie feler.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Anotacyjo typu { $type }]
+
+## Password
+
+pdfjs-password-label = Wkludź hasÅ‚o, coby ôdewrzić tyn zbiÅr PDF.
+pdfjs-password-invalid = HasÅ‚o je zÅ‚e. SprÅbuj jeszcze roz.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Pociep
+pdfjs-web-fonts-disabled = Necowe fÅnty sÅm zastawiÅne: niy idzie użyć wkludzÅnych fÅntÅw PDF.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/ta/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ta/viewer.ftl
new file mode 100644
index 000000000..82cf19703
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ta/viewer.ftl
@@ -0,0 +1,223 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = à®®à¯à®¨à¯à®¤à¯ˆà®¯ பகà¯à®•à®®à¯
+pdfjs-previous-button-label = à®®à¯à®¨à¯à®¤à¯ˆà®¯à®¤à¯
+pdfjs-next-button =
+ .title = அடà¯à®¤à¯à®¤ பகà¯à®•à®®à¯
+pdfjs-next-button-label = அடà¯à®¤à¯à®¤à¯
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = பகà¯à®•à®®à¯
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } இலà¯
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = { $pagesCount }) இல௠({ $pageNumber }
+pdfjs-zoom-out-button =
+ .title = சிறிதாகà¯à®•à¯
+pdfjs-zoom-out-button-label = சிறிதாகà¯à®•à¯
+pdfjs-zoom-in-button =
+ .title = பெரிதாகà¯à®•à¯
+pdfjs-zoom-in-button-label = பெரிதாகà¯à®•à¯
+pdfjs-zoom-select =
+ .title = பெரிதாகà¯à®•à¯
+pdfjs-presentation-mode-button =
+ .title = விளகà¯à®•à®•à®¾à®Ÿà¯à®šà®¿ பயனà¯à®®à¯à®±à¯ˆà®•à¯à®•à¯ மாறà¯
+pdfjs-presentation-mode-button-label = விளகà¯à®•à®•à®¾à®Ÿà¯à®šà®¿ பயனà¯à®®à¯à®±à¯ˆ
+pdfjs-open-file-button =
+ .title = கோபà¯à®ªà®¿à®©à¯ˆ திற
+pdfjs-open-file-button-label = திற
+pdfjs-print-button =
+ .title = அசà¯à®šà®¿à®Ÿà¯
+pdfjs-print-button-label = அசà¯à®šà®¿à®Ÿà¯
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = கரà¯à®µà®¿à®•à®³à¯
+pdfjs-tools-button-label = கரà¯à®µà®¿à®•à®³à¯
+pdfjs-first-page-button =
+ .title = à®®à¯à®¤à®²à¯ பகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ செலà¯à®²à®µà¯à®®à¯
+pdfjs-first-page-button-label = à®®à¯à®¤à®²à¯ பகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ செலà¯à®²à®µà¯à®®à¯
+pdfjs-last-page-button =
+ .title = கடைசி பகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ செலà¯à®²à®µà¯à®®à¯
+pdfjs-last-page-button-label = கடைசி பகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ செலà¯à®²à®µà¯à®®à¯
+pdfjs-page-rotate-cw-button =
+ .title = வலஞà¯à®šà¯à®´à®¿à®¯à®¾à®• சà¯à®´à®±à¯à®±à¯
+pdfjs-page-rotate-cw-button-label = வலஞà¯à®šà¯à®´à®¿à®¯à®¾à®• சà¯à®´à®±à¯à®±à¯
+pdfjs-page-rotate-ccw-button =
+ .title = இடஞà¯à®šà¯à®´à®¿à®¯à®¾à®• சà¯à®´à®±à¯à®±à¯
+pdfjs-page-rotate-ccw-button-label = இடஞà¯à®šà¯à®´à®¿à®¯à®¾à®• சà¯à®´à®±à¯à®±à¯
+pdfjs-cursor-text-select-tool-button =
+ .title = உரைத௠தெரிவ௠கரà¯à®µà®¿à®¯à¯ˆà®šà¯ செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯
+pdfjs-cursor-text-select-tool-button-label = உரைத௠தெரிவ௠கரà¯à®µà®¿
+pdfjs-cursor-hand-tool-button =
+ .title = கைக௠கரà¯à®µà®¿à®•à¯à®šà¯ செயறà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯
+pdfjs-cursor-hand-tool-button-label = கைகà¯à®•à¯à®°à¯à®µà®¿
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ஆவண பணà¯à®ªà¯à®•à®³à¯...
+pdfjs-document-properties-button-label = ஆவண பணà¯à®ªà¯à®•à®³à¯...
+pdfjs-document-properties-file-name = கோபà¯à®ªà¯ பெயரà¯:
+pdfjs-document-properties-file-size = கோபà¯à®ªà®¿à®©à¯ அளவà¯:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } கிபை ({ $size_b } பைடà¯à®Ÿà¯à®•à®³à¯)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } மெபை ({ $size_b } பைடà¯à®Ÿà¯à®•à®³à¯)
+pdfjs-document-properties-title = தலைபà¯à®ªà¯:
+pdfjs-document-properties-author = எழà¯à®¤à®¿à®¯à®µà®°à¯
+pdfjs-document-properties-subject = பொரà¯à®³à¯:
+pdfjs-document-properties-keywords = à®®à¯à®•à¯à®•à®¿à®¯ வாரà¯à®¤à¯à®¤à¯ˆà®•à®³à¯:
+pdfjs-document-properties-creation-date = படைதà¯à®¤ தேதி :
+pdfjs-document-properties-modification-date = திரà¯à®¤à¯à®¤à®¿à®¯ தேதி:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = உரà¯à®µà®¾à®•à¯à®•à¯à®ªà®µà®°à¯:
+pdfjs-document-properties-producer = பிடிஎஃப௠தயாரிபà¯à®ªà®¾à®³à®°à¯:
+pdfjs-document-properties-version = PDF பதிபà¯à®ªà¯:
+pdfjs-document-properties-page-count = பகà¯à®• எணà¯à®£à®¿à®•à¯à®•à¯ˆ:
+pdfjs-document-properties-page-size = பகà¯à®• அளவà¯:
+pdfjs-document-properties-page-size-unit-inches = இதிலà¯
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = நிலைபதிபà¯à®ªà¯
+pdfjs-document-properties-page-size-orientation-landscape = நிலைபரபà¯à®ªà¯
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = கடிதமà¯
+pdfjs-document-properties-page-size-name-legal = சடà¯à®Ÿà®ªà¯‚à®°à¯à®µ
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-close-button = மூடà¯à®•
+
+## Print
+
+pdfjs-print-progress-message = அசà¯à®šà®¿à®Ÿà¯à®µà®¤à®±à¯à®•à®¾à®© ஆவணம௠தயாராகிறதà¯...
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ரதà¯à®¤à¯
+pdfjs-printing-not-supported = எசà¯à®šà®°à®¿à®•à¯à®•à¯ˆ: இநà¯à®¤ உலாவி அசà¯à®šà®¿à®Ÿà¯à®¤à®²à¯ˆ à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®• ஆதரிகà¯à®•à®µà®¿à®²à¯à®²à¯ˆ.
+pdfjs-printing-not-ready = எசà¯à®šà®°à®¿à®•à¯à®•à¯ˆ: PDF அசà¯à®šà®¿à®Ÿ à®®à¯à®´à¯à®µà®¤à¯à®®à®¾à®• à®à®±à¯à®±à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = பகà¯à®•à®ªà¯ படà¯à®Ÿà®¿à®¯à¯ˆ நிலைமாறà¯à®±à¯
+pdfjs-toggle-sidebar-button-label = பகà¯à®•à®ªà¯ படà¯à®Ÿà®¿à®¯à¯ˆ நிலைமாறà¯à®±à¯
+pdfjs-document-outline-button =
+ .title = ஆவண அடகà¯à®•à®¤à¯à®¤à¯ˆà®•à¯ காடà¯à®Ÿà¯ (இரà¯à®®à¯à®±à¯ˆà®šà¯ சொடà¯à®•à¯à®•à®¿ அனைதà¯à®¤à¯ உறà¯à®ªà¯à®ªà®¿à®Ÿà®¿à®•à®³à¯ˆà®¯à¯à®®à¯ விரி/சேரà¯)
+pdfjs-document-outline-button-label = ஆவண வெளிவரை
+pdfjs-attachments-button =
+ .title = இணைபà¯à®ªà¯à®•à®³à¯ˆ காணà¯à®ªà®¿
+pdfjs-attachments-button-label = இணைபà¯à®ªà¯à®•à®³à¯
+pdfjs-thumbs-button =
+ .title = சிறà¯à®ªà®Ÿà®™à¯à®•à®³à¯ˆà®•à¯ காணà¯à®ªà®¿
+pdfjs-thumbs-button-label = சிறà¯à®ªà®Ÿà®™à¯à®•à®³à¯
+pdfjs-findbar-button =
+ .title = ஆவணதà¯à®¤à®¿à®²à¯ கணà¯à®Ÿà®±à®¿
+pdfjs-findbar-button-label = தேடà¯
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = பகà¯à®•à®®à¯ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = பகà¯à®•à®¤à¯à®¤à®¿à®©à¯ சிறà¯à®ªà®Ÿà®®à¯ { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿
+ .placeholder = ஆவணதà¯à®¤à®¿à®²à¯ கணà¯à®Ÿà®±à®¿â€¦
+pdfjs-find-previous-button =
+ .title = இநà¯à®¤ சொறà¯à®±à¯Šà®Ÿà®°à®¿à®©à¯ à®®à¯à®¨à¯à®¤à¯ˆà®¯ நிகழà¯à®µà¯ˆ தேடà¯
+pdfjs-find-previous-button-label = à®®à¯à®¨à¯à®¤à¯ˆà®¯à®¤à¯
+pdfjs-find-next-button =
+ .title = இநà¯à®¤ சொறà¯à®±à¯Šà®Ÿà®°à®¿à®©à¯ அடà¯à®¤à¯à®¤ நிகழà¯à®µà¯ˆ தேடà¯
+pdfjs-find-next-button-label = அடà¯à®¤à¯à®¤à¯
+pdfjs-find-highlight-checkbox = அனைதà¯à®¤à¯ˆà®¯à¯à®®à¯ தனிபà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯
+pdfjs-find-match-case-checkbox-label = பேரெழà¯à®¤à¯à®¤à®¾à®•à¯à®•à®¤à¯à®¤à¯ˆ உணரà¯
+pdfjs-find-reached-top = ஆவணதà¯à®¤à®¿à®©à¯ மேல௠பகà¯à®¤à®¿à®¯à¯ˆ அடைநà¯à®¤à®¤à¯, அடிபà¯à®ªà®•à¯à®•à®¤à¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ தொடரà¯à®¨à¯à®¤à®¤à¯
+pdfjs-find-reached-bottom = ஆவணதà¯à®¤à®¿à®©à¯ à®®à¯à®Ÿà®¿à®µà¯ˆ அடைநà¯à®¤à®¤à¯, மேலிரà¯à®¨à¯à®¤à¯ தொடரà¯à®¨à¯à®¤à®¤à¯
+pdfjs-find-not-found = சொறà¯à®±à¯Šà®Ÿà®°à¯ காணவிலà¯à®²à¯ˆ
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = பகà¯à®• அகலமà¯
+pdfjs-page-scale-fit = பகà¯à®•à®ªà¯ பொரà¯à®¤à¯à®¤à®®à¯
+pdfjs-page-scale-auto = தானியகà¯à®• பெரிதாகà¯à®•à®²à¯
+pdfjs-page-scale-actual = உணà¯à®®à¯ˆà®¯à®¾à®© அளவà¯
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF à® à®à®±à¯à®±à¯à®®à¯ போத௠ஒர௠பிழை à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¤à¯.
+pdfjs-invalid-file-error = செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à®¾à®¤ அலà¯à®²à®¤à¯ சிதைநà¯à®¤ PDF கோபà¯à®ªà¯.
+pdfjs-missing-file-error = PDF கோபà¯à®ªà¯ காணவிலà¯à®²à¯ˆ.
+pdfjs-unexpected-response-error = சேவகன௠பதில௠எதிரà¯à®ªà®¾à®°à®¤à®¤à¯.
+pdfjs-rendering-error = இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆ காடà¯à®šà®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯ போத௠ஒர௠பிழை à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¤à¯.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } விளகà¯à®•à®®à¯]
+
+## Password
+
+pdfjs-password-label = இநà¯à®¤ PDF கோபà¯à®ªà¯ˆ திறகà¯à®• கடவà¯à®šà¯à®šà¯†à®¾à®²à¯à®²à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯.
+pdfjs-password-invalid = செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à®¾à®¤ கடவà¯à®šà¯à®šà¯Šà®²à¯, தயை செயà¯à®¤à¯ மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿ செயà¯à®•.
+pdfjs-password-ok-button = சரி
+pdfjs-password-cancel-button = ரதà¯à®¤à¯
+pdfjs-web-fonts-disabled = வலை எழà¯à®¤à¯à®¤à¯à®°à¯à®•à¯à®•à®³à¯ à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®©: உடà¯à®ªà¯Šà®¤à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ PDF எழà¯à®¤à¯à®¤à¯à®°à¯à®•à¯à®•à®³à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/te/viewer.ftl b/www/lib/pdfjs/modern/web/locale/te/viewer.ftl
new file mode 100644
index 000000000..94dc2b8ee
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/te/viewer.ftl
@@ -0,0 +1,239 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = à°®à±à°¨à±à°ªà°Ÿà°¿ పేజీ
+pdfjs-previous-button-label = à°•à±à°°à°¿à°¤à°‚
+pdfjs-next-button =
+ .title = తరà±à°µà°¾à°¤ పేజీ
+pdfjs-next-button-label = తరà±à°µà°¾à°¤
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = పేజీ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = మొతà±à°¤à°‚ { $pagesCount } లో
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = (మొతà±à°¤à°‚ { $pagesCount } లో { $pageNumber }వది)
+pdfjs-zoom-out-button =
+ .title = జూమౠతగà±à°—à°¿à°‚à°šà±
+pdfjs-zoom-out-button-label = జూమౠతగà±à°—à°¿à°‚à°šà±
+pdfjs-zoom-in-button =
+ .title = జూమౠచేయి
+pdfjs-zoom-in-button-label = జూమౠచేయి
+pdfjs-zoom-select =
+ .title = జూమà±
+pdfjs-presentation-mode-button =
+ .title = à°ªà±à°°à°¦à°°à±à°¶à°¨à°¾ రీతికి మారà±
+pdfjs-presentation-mode-button-label = à°ªà±à°°à°¦à°°à±à°¶à°¨à°¾ రీతి
+pdfjs-open-file-button =
+ .title = ఫైలౠతెరà±à°µà±
+pdfjs-open-file-button-label = తెరà±à°µà±
+pdfjs-print-button =
+ .title = à°®à±à°¦à±à°°à°¿à°‚à°šà±
+pdfjs-print-button-label = à°®à±à°¦à±à°°à°¿à°‚à°šà±
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = పనిమà±à°Ÿà±à°²à±
+pdfjs-tools-button-label = పనిమà±à°Ÿà±à°²à±
+pdfjs-first-page-button =
+ .title = మొదటి పేజీకి వెళà±à°³à±
+pdfjs-first-page-button-label = మొదటి పేజీకి వెళà±à°³à±
+pdfjs-last-page-button =
+ .title = చివరి పేజీకి వెళà±à°³à±
+pdfjs-last-page-button-label = చివరి పేజీకి వెళà±à°³à±
+pdfjs-page-rotate-cw-button =
+ .title = సవà±à°¯à°¦à°¿à°¶à°²à±‹ తిపà±à°ªà±
+pdfjs-page-rotate-cw-button-label = సవà±à°¯à°¦à°¿à°¶à°²à±‹ తిపà±à°ªà±
+pdfjs-page-rotate-ccw-button =
+ .title = అపసవà±à°¯à°¦à°¿à°¶à°²à±‹ తిపà±à°ªà±
+pdfjs-page-rotate-ccw-button-label = అపసవà±à°¯à°¦à°¿à°¶à°²à±‹ తిపà±à°ªà±
+pdfjs-cursor-text-select-tool-button =
+ .title = టెకà±à°¸à±à°Ÿà± ఎంపిక సాధనానà±à°¨à°¿ à°ªà±à°°à°¾à°°à°‚à°à°¿à°‚à°šà°‚à°¡à°¿
+pdfjs-cursor-text-select-tool-button-label = టెకà±à°¸à±à°Ÿà± ఎంపిక సాధనం
+pdfjs-cursor-hand-tool-button =
+ .title = చేతి సాధనం చేతనించà±
+pdfjs-cursor-hand-tool-button-label = చేతి సాధనం
+pdfjs-scroll-vertical-button-label = నిలà±à°µà± à°¸à±à°•à±à°°à±‹à°²à°¿à°‚à°—à±
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = పతà±à°°à°®à± లకà±à°·à°£à°¾à°²à±...
+pdfjs-document-properties-button-label = పతà±à°°à°®à± లకà±à°·à°£à°¾à°²à±...
+pdfjs-document-properties-file-name = దసà±à°¤à±à°°à°‚ పేరà±:
+pdfjs-document-properties-file-size = దసà±à°¤à±à°°à°‚ పరిమాణం:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = శీరà±à°·à°¿à°•:
+pdfjs-document-properties-author = మూలకరà±à°¤:
+pdfjs-document-properties-subject = విషయం:
+pdfjs-document-properties-keywords = à°•à±€ పదాలà±:
+pdfjs-document-properties-creation-date = సృషà±à°Ÿà°¿à°‚à°šà°¿à°¨ తేదీ:
+pdfjs-document-properties-modification-date = సవరించిన తేదీ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = సృషà±à°Ÿà°¿à°•à°°à±à°¤:
+pdfjs-document-properties-producer = PDF ఉతà±à°ªà°¾à°¦à°•à°¿:
+pdfjs-document-properties-version = PDF వరà±à°·à°¨à±:
+pdfjs-document-properties-page-count = పేజీల సంఖà±à°¯:
+pdfjs-document-properties-page-size = కాగితం పరిమాణం:
+pdfjs-document-properties-page-size-unit-inches = లో
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = నిలà±à°µà±à°šà°¿à°¤à±à°°à°‚
+pdfjs-document-properties-page-size-orientation-landscape = à°…à°¡à±à°¡à°šà°¿à°¤à±à°°à°‚
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = లేఖ
+pdfjs-document-properties-page-size-name-legal = à°šà°Ÿà±à°Ÿà°ªà°°à°®à±†à±–à°¨
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+pdfjs-document-properties-linearized-yes = à°…à°µà±à°¨à±
+pdfjs-document-properties-linearized-no = కాదà±
+pdfjs-document-properties-close-button = మూసివేయి
+
+## Print
+
+pdfjs-print-progress-message = à°®à±à°¦à±à°°à°¿à°‚చడానికి పతà±à°°à°®à± సిదà±à°§à°®à°µà±à°¤à±à°¨à±à°¨à°¦à°¿â€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = à°°à°¦à±à°¦à±à°šà±‡à°¯à°¿
+pdfjs-printing-not-supported = హెచà±à°šà°°à°¿à°•: à°ˆ విహారిణి చేత à°®à±à°¦à±à°°à°£ పూరà±à°¤à°¿à°—à°¾ తోడà±à°ªà°¾à°Ÿà± లేదà±.
+pdfjs-printing-not-ready = హెచà±à°šà°°à°¿à°•: à°®à±à°¦à±à°°à°£ కొరకౠఈ PDF పూరà±à°¤à°¿à°—à°¾ లోడవలేదà±.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = పకà±à°•à°ªà°Ÿà±à°Ÿà±€ మారà±à°šà±
+pdfjs-toggle-sidebar-button-label = పకà±à°•à°ªà°Ÿà±à°Ÿà±€ మారà±à°šà±
+pdfjs-document-outline-button =
+ .title = పతà±à°°à°®à± రూపమౠచూపించౠ(à°¡à°¬à±à°²à± à°•à±à°²à°¿à°•à± చేసి à°…à°¨à±à°¨à°¿ అంశాలనౠవిసà±à°¤à°°à°¿à°‚à°šà±/కూలà±à°šà±)
+pdfjs-document-outline-button-label = పతà±à°°à°®à± à°…à°µà±à°Ÿà±â€Œà°²à±ˆà°¨à±
+pdfjs-attachments-button =
+ .title = à°…à°¨à±à°¬à°‚ధాలౠచూపà±
+pdfjs-attachments-button-label = à°…à°¨à±à°¬à°‚ధాలà±
+pdfjs-layers-button-label = పొరలà±
+pdfjs-thumbs-button =
+ .title = థంబà±â€Œà°¨à±ˆà°²à±à°¸à± చూపà±
+pdfjs-thumbs-button-label = థంబà±â€Œà°¨à±ˆà°²à±à°¸à±
+pdfjs-findbar-button =
+ .title = పతà±à°°à°®à±à°²à±‹ à°•à°¨à±à°—ొనà±à°®à±
+pdfjs-findbar-button-label = à°•à°¨à±à°—ొనà±
+pdfjs-additional-layers = అదనపౠపొరలà±
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = పేజీ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } పేజీ నఖచితà±à°°à°‚
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = à°•à°¨à±à°—ొనà±
+ .placeholder = పతà±à°°à°®à±à°²à±‹ à°•à°¨à±à°—ొనà±â€¦
+pdfjs-find-previous-button =
+ .title = పదం యొకà±à°• à°®à±à°‚దౠసంà°à°µà°¾à°¨à±à°¨à°¿ à°•à°¨à±à°—ొనà±
+pdfjs-find-previous-button-label = à°®à±à°¨à±à°ªà°Ÿà°¿
+pdfjs-find-next-button =
+ .title = పదం యొకà±à°• తరà±à°µà°¾à°¤à°¿ సంà°à°µà°¾à°¨à±à°¨à°¿ à°•à°¨à±à°—ొనà±
+pdfjs-find-next-button-label = తరà±à°µà°¾à°¤
+pdfjs-find-highlight-checkbox = à°…à°¨à±à°¨à°¿à°Ÿà°¿à°¨à°¿ ఉదà±à°¦à±€à°ªà°¨à°‚ చేయà±à°®à±
+pdfjs-find-match-case-checkbox-label = à°…à°•à±à°·à°°à°®à±à°² తేడాతో పోలà±à°šà±
+pdfjs-find-entire-word-checkbox-label = పూరà±à°¤à°¿ పదాలà±
+pdfjs-find-reached-top = పేజీ పైకి చేరà±à°•à±à°¨à±à°¨à°¦à°¿, à°•à±à°°à°¿à°‚ది à°¨à±à°‚à°¡à°¿ కొనసాగించండి
+pdfjs-find-reached-bottom = పేజీ చివరకౠచేరà±à°•à±à°¨à±à°¨à°¦à°¿, పైనà±à°‚à°¡à°¿ కొనసాగించండి
+pdfjs-find-not-found = పదబంధం కనబడలేదà±
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = పేజీ వెడలà±à°ªà±
+pdfjs-page-scale-fit = పేజీ అమరà±à°ªà±
+pdfjs-page-scale-auto = à°¸à±à°µà°¯à°‚చాలక జూమà±
+pdfjs-page-scale-actual = యథారà±à°§ పరిమాణం
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF లోడవà±à°šà±à°¨à±à°¨à°ªà±à°ªà±à°¡à± à°’à°• దోషం à°Žà°¦à±à°°à±ˆà°‚ది.
+pdfjs-invalid-file-error = చెలà±à°²à°¨à°¿ లేదా పాడైన PDF ఫైలà±.
+pdfjs-missing-file-error = దొరకని PDF ఫైలà±.
+pdfjs-unexpected-response-error = à°…à°¨à±à°•à±‹à°¨à°¿ సరà±à°µà°°à± à°¸à±à°ªà°‚దన.
+pdfjs-rendering-error = పేజీనౠరెండరౠచేయà±à°Ÿà°²à±‹ à°’à°• దోషం à°Žà°¦à±à°°à±ˆà°‚ది.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } టీకా]
+
+## Password
+
+pdfjs-password-label = à°ˆ PDF ఫైలౠతెరà±à°šà±à°Ÿà°•à± సంకేతపదం à°ªà±à°°à°µà±‡à°¶à°ªà±†à°Ÿà±à°Ÿà±à°®à±.
+pdfjs-password-invalid = సంకేతపదం చెలà±à°²à°¦à±. దయచేసి మళà±à°³à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.
+pdfjs-password-ok-button = సరే
+pdfjs-password-cancel-button = à°°à°¦à±à°¦à±à°šà±‡à°¯à°¿
+pdfjs-web-fonts-disabled = వెబౠఫాంటà±à°²à± అచేతనించబడెనà±: ఎంబెడెడౠPDF ఫాంటà±à°²à± ఉపయోగించలేక పోయింది.
+
+## Editing
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = à°°à°‚à°—à±
+pdfjs-editor-free-text-size-input = పరిమాణం
+pdfjs-editor-ink-color-input = à°°à°‚à°—à±
+pdfjs-editor-ink-thickness-input = మందం
+pdfjs-editor-ink-opacity-input = à°…à°•à°¿à°°à°£à±à°¯à°¤
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/tg/viewer.ftl b/www/lib/pdfjs/modern/web/locale/tg/viewer.ftl
new file mode 100644
index 000000000..ea03d393a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/tg/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Саҳифаи қаблӣ
+pdfjs-previous-button-label = Қаблӣ
+pdfjs-next-button =
+ .title = Саҳифаи навбатӣ
+pdfjs-next-button-label = Ðавбатӣ
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Саҳифа
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = аз { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } аз { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Хурд кардан
+pdfjs-zoom-out-button-label = Хурд кардан
+pdfjs-zoom-in-button =
+ .title = Калон кардан
+pdfjs-zoom-in-button-label = Калон кардан
+pdfjs-zoom-select =
+ .title = Танзими андоза
+pdfjs-presentation-mode-button =
+ .title = Гузариш ба реҷаи тақдим
+pdfjs-presentation-mode-button-label = Реҷаи тақдим
+pdfjs-open-file-button =
+ .title = Кушодани файл
+pdfjs-open-file-button-label = Кушодан
+pdfjs-print-button =
+ .title = Чоп кардан
+pdfjs-print-button-label = Чоп кардан
+pdfjs-save-button =
+ .title = Ðигоҳ доштан
+pdfjs-save-button-label = Ðигоҳ доштан
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Боргирӣ кардан
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Боргирӣ кардан
+pdfjs-bookmark-button =
+ .title = Саҳифаи ҷорӣ (Дидани нишонии URL аз Ñаҳифаи ҷорӣ)
+pdfjs-bookmark-button-label = Саҳифаи ҷорӣ
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Кушодан дар барнома
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Кушодан дар барнома
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Ðбзорҳо
+pdfjs-tools-button-label = Ðбзорҳо
+pdfjs-first-page-button =
+ .title = Ба Ñаҳифаи аввал гузаред
+pdfjs-first-page-button-label = Ба Ñаҳифаи аввал гузаред
+pdfjs-last-page-button =
+ .title = Ба Ñаҳифаи охирин гузаред
+pdfjs-last-page-button-label = Ба Ñаҳифаи охирин гузаред
+pdfjs-page-rotate-cw-button =
+ .title = Ба Ñамти ҳаракати ақрабаки Ñоат давр задан
+pdfjs-page-rotate-cw-button-label = Ба Ñамти ҳаракати ақрабаки Ñоат давр задан
+pdfjs-page-rotate-ccw-button =
+ .title = Ба муқобили Ñамти ҳаракати ақрабаки Ñоат давр задан
+pdfjs-page-rotate-ccw-button-label = Ба муқобили Ñамти ҳаракати ақрабаки Ñоат давр задан
+pdfjs-cursor-text-select-tool-button =
+ .title = Фаъол кардани «Ðбзори интихоби матн»
+pdfjs-cursor-text-select-tool-button-label = Ðбзори интихоби матн
+pdfjs-cursor-hand-tool-button =
+ .title = Фаъол кардани «Ðбзори даÑт»
+pdfjs-cursor-hand-tool-button-label = Ðбзори даÑÑ‚
+pdfjs-scroll-page-button =
+ .title = ИÑтифодаи варақзанӣ
+pdfjs-scroll-page-button-label = Варақзанӣ
+pdfjs-scroll-vertical-button =
+ .title = ИÑтифодаи варақзании амудӣ
+pdfjs-scroll-vertical-button-label = Варақзании амудӣ
+pdfjs-scroll-horizontal-button =
+ .title = ИÑтифодаи варақзании уфуқӣ
+pdfjs-scroll-horizontal-button-label = Варақзании уфуқӣ
+pdfjs-scroll-wrapped-button =
+ .title = ИÑтифодаи варақзании миқёÑбандӣ
+pdfjs-scroll-wrapped-button-label = Варақзании миқёÑбандӣ
+pdfjs-spread-none-button =
+ .title = ГуÑтариши Ñаҳифаҳо иÑтифода бурда нашавад
+pdfjs-spread-none-button-label = Бе гуÑтурдани Ñаҳифаҳо
+pdfjs-spread-odd-button =
+ .title = ГуÑтариши Ñаҳифаҳо аз Ñаҳифаҳо бо рақамҳои тоқ оғоз карда мешавад
+pdfjs-spread-odd-button-label = Саҳифаҳои тоқ аз тарафи чап
+pdfjs-spread-even-button =
+ .title = ГуÑтариши Ñаҳифаҳо аз Ñаҳифаҳо бо рақамҳои ҷуфт оғоз карда мешавад
+pdfjs-spread-even-button-label = Саҳифаҳои ҷуфт аз тарафи чап
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ХуÑуÑиÑтҳои ҳуҷҷат…
+pdfjs-document-properties-button-label = ХуÑуÑиÑтҳои ҳуҷҷат…
+pdfjs-document-properties-file-name = Ðоми файл:
+pdfjs-document-properties-file-size = Ðндозаи файл:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } байт)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } байт)
+pdfjs-document-properties-title = Сарлавҳа:
+pdfjs-document-properties-author = Муаллиф:
+pdfjs-document-properties-subject = Мавзуъ:
+pdfjs-document-properties-keywords = Калимаҳои калидӣ:
+pdfjs-document-properties-creation-date = Санаи Ñҷод:
+pdfjs-document-properties-modification-date = Санаи тағйирот:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Ðҷодкунанда:
+pdfjs-document-properties-producer = ТаҳиÑкунандаи «PDF»:
+pdfjs-document-properties-version = ВерÑиÑи «PDF»:
+pdfjs-document-properties-page-count = Шумораи Ñаҳифаҳо:
+pdfjs-document-properties-page-size = Ðндозаи Ñаҳифа:
+pdfjs-document-properties-page-size-unit-inches = дюйм
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = амудӣ
+pdfjs-document-properties-page-size-orientation-landscape = уфуқӣ
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Мактуб
+pdfjs-document-properties-page-size-name-legal = Ҳуқуқӣ
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Ðамоиши тез дар Интернет:
+pdfjs-document-properties-linearized-yes = Ҳа
+pdfjs-document-properties-linearized-no = Ðе
+pdfjs-document-properties-close-button = Пӯшидан
+
+## Print
+
+pdfjs-print-progress-message = ОмодаÑозии ҳуҷҷат барои чоп…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Бекор кардан
+pdfjs-printing-not-supported = Диққат: Чопкунӣ аз тарафи ин браузер ба таври пурра даÑтгирӣ намешавад.
+pdfjs-printing-not-ready = Диққат: Файли «PDF» барои чопкунӣ пурра бор карда нашуд.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Фаъол кардани навори ҷонибӣ
+pdfjs-toggle-sidebar-notification-button =
+ .title = Фаъол кардани навори ҷонибӣ (ҳуҷҷат дорои Ñохтор/замимаҳо/қабатҳо мебошад)
+pdfjs-toggle-sidebar-button-label = Фаъол кардани навори ҷонибӣ
+pdfjs-document-outline-button =
+ .title = Ðамоиш додани Ñохтори ҳуҷҷат (барои баркушодан/пеҷондани ҳамаи унÑурҳо дубора зер кунед)
+pdfjs-document-outline-button-label = Сохтори ҳуҷҷат
+pdfjs-attachments-button =
+ .title = Ðамоиш додани замимаҳо
+pdfjs-attachments-button-label = Замимаҳо
+pdfjs-layers-button =
+ .title = Ðамоиш додани қабатҳо (барои барқарор кардани ҳамаи қабатҳо ба вазъиÑти пешфарз дубора зер кунед)
+pdfjs-layers-button-label = Қабатҳо
+pdfjs-thumbs-button =
+ .title = Ðамоиш додани таÑвирчаҳо
+pdfjs-thumbs-button-label = ТаÑвирчаҳо
+pdfjs-current-outline-item-button =
+ .title = Ðфтани унÑури Ñохтори ҷорӣ
+pdfjs-current-outline-item-button-label = УнÑури Ñохтори ҷорӣ
+pdfjs-findbar-button =
+ .title = Ðфтан дар ҳуҷҷат
+pdfjs-findbar-button-label = Ðфтан
+pdfjs-additional-layers = Қабатҳои иловагӣ
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Саҳифаи { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ТаÑвирчаи Ñаҳифаи { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Ðфтан
+ .placeholder = Ðфтан дар ҳуҷҷат…
+pdfjs-find-previous-button =
+ .title = ҶуÑтуҷӯи мавриди қаблии ибораи пешниҳодшуда
+pdfjs-find-previous-button-label = Қаблӣ
+pdfjs-find-next-button =
+ .title = ҶуÑтуҷӯи мавриди навбатии ибораи пешниҳодшуда
+pdfjs-find-next-button-label = Ðавбатӣ
+pdfjs-find-highlight-checkbox = Ҳамаашро бо ранг ҷудо кардан
+pdfjs-find-match-case-checkbox-label = Бо дарназардошти ҳарфҳои хурду калон
+pdfjs-find-match-diacritics-checkbox-label = Бо дарназардошти аломатҳои диакритикӣ
+pdfjs-find-entire-word-checkbox-label = Калимаҳои пурра
+pdfjs-find-reached-top = Ба болои ҳуҷҷат раÑид, аз поён идома Ñ‘Ñ„Ñ‚
+pdfjs-find-reached-bottom = Ба поёни ҳуҷҷат раÑид, аз боло идома Ñ‘Ñ„Ñ‚
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } аз { $total } мувофиқат
+ *[other] { $current } аз { $total } мувофиқат
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Зиёда аз { $limit } мувофиқат
+ *[other] Зиёда аз { $limit } мувофиқат
+ }
+pdfjs-find-not-found = Ибора ёфт нашуд
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ðз рӯи паҳнои Ñаҳифа
+pdfjs-page-scale-fit = Ðз рӯи андозаи Ñаҳифа
+pdfjs-page-scale-auto = Ðндозаи худкор
+pdfjs-page-scale-actual = Ðндозаи воқеӣ
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Саҳифаи { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Ҳангоми боркунии «PDF» хато ба миён омад.
+pdfjs-invalid-file-error = Файли «PDF» нодуруÑÑ‚ Ñ‘ вайроншуда мебошад.
+pdfjs-missing-file-error = Файли «PDF» ғоиб аÑÑ‚.
+pdfjs-unexpected-response-error = Ҷавоби ногаҳон аз Ñервер.
+pdfjs-rendering-error = Ҳангоми шаклÑозии Ñаҳифа хато ба миён омад.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [ҲошиÑнавиÑÓ£ - { $type }]
+
+## Password
+
+pdfjs-password-label = Барои кушодани ин файли «PDF» ниҳонвожаро ворид кунед.
+pdfjs-password-invalid = Ðиҳонвожаи нодуруÑÑ‚. Лутфан, аз нав кӯшиш кунед.
+pdfjs-password-ok-button = ХУБ
+pdfjs-password-cancel-button = Бекор кардан
+pdfjs-web-fonts-disabled = Шрифтҳои интернетӣ ғайрифаъоланд: иÑтифодаи шрифтҳои дарунÑохти «PDF» ғайриимкон аÑÑ‚.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Матн
+pdfjs-editor-free-text-button-label = Матн
+pdfjs-editor-ink-button =
+ .title = РаÑмкашӣ
+pdfjs-editor-ink-button-label = РаÑмкашӣ
+pdfjs-editor-stamp-button =
+ .title = Илова Ñ‘ таҳрир кардани таÑвирҳо
+pdfjs-editor-stamp-button-label = Илова Ñ‘ таҳрир кардани таÑвирҳо
+pdfjs-editor-remove-button =
+ .title = Тоза кардан
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Тоза кардани нақша
+pdfjs-editor-remove-freetext-button =
+ .title = Тоза кардани матн
+pdfjs-editor-remove-stamp-button =
+ .title = Тоза кардани таÑвир
+pdfjs-editor-remove-highlight-button =
+ .title = Тоза кардани ҷудокунӣ
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Ранг
+pdfjs-editor-free-text-size-input = Ðндоза
+pdfjs-editor-ink-color-input = Ранг
+pdfjs-editor-ink-thickness-input = ҒафÑÓ£
+pdfjs-editor-ink-opacity-input = Шаффофӣ
+pdfjs-editor-stamp-add-image-button =
+ .title = Илова кардани таÑвир
+pdfjs-editor-stamp-add-image-button-label = Илова кардани таÑвир
+pdfjs-free-text =
+ .aria-label = Муҳаррири матн
+pdfjs-free-text-default-content = ÐавиÑед…
+pdfjs-ink =
+ .aria-label = Муҳаррири раÑмкашӣ
+pdfjs-ink-canvas =
+ .aria-label = ТаÑвири Ñҷодкардаи корбар
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Матни ивазкунанда
+pdfjs-editor-alt-text-edit-button-label = Таҳрир кардани матни ивазкунанда
+pdfjs-editor-alt-text-dialog-label = Имконеро интихоб намоед
+pdfjs-editor-alt-text-dialog-description = Вақте ки одамон таÑвирро дида наметавонанд Ñ‘ вақте ки таÑвир бор карда намешавад, матни иловагӣ (Alt text) кумак мераÑонад.
+pdfjs-editor-alt-text-add-description-label = Илова кардани тавÑиф
+pdfjs-editor-alt-text-add-description-description = Кӯшиш кунед, ки 1-2 ҷумлаеро навиÑед, ки ба мавзӯъ, танзим Ñ‘ амалҳо тавзеҳ медиҳад.
+pdfjs-editor-alt-text-mark-decorative-label = Гузоштан ҳамчун матни ороишӣ
+pdfjs-editor-alt-text-mark-decorative-description = Ин барои таÑвирҳои ороишӣ, ба монанди марзҳо Ñ‘ аломатҳои обӣ, иÑтифода мешавад.
+pdfjs-editor-alt-text-cancel-button = Бекор кардан
+pdfjs-editor-alt-text-save-button = Ðигоҳ доштан
+pdfjs-editor-alt-text-decorative-tooltip = Ҳамчун матни ороишӣ гузошта шуд
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Барои миÑол, «Ман забони тоҷикиро дӯÑÑ‚ медорам»
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Кунҷи чапи боло — тағйир додани андоза
+pdfjs-editor-resizer-label-top-middle = Канори миёнаи боло — тағйир додани андоза
+pdfjs-editor-resizer-label-top-right = Кунҷи роÑти боло — тағйир додани андоза
+pdfjs-editor-resizer-label-middle-right = Канори миёнаи роÑÑ‚ — тағйир додани андоза
+pdfjs-editor-resizer-label-bottom-right = Кунҷи роÑти поён — тағйир додани андоза
+pdfjs-editor-resizer-label-bottom-middle = Канори миёнаи поён — тағйир додани андоза
+pdfjs-editor-resizer-label-bottom-left = Кунҷи чапи поён — тағйир додани андоза
+pdfjs-editor-resizer-label-middle-left = Канори миёнаи чап — тағйир додани андоза
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Ранги ҷудокунӣ
+pdfjs-editor-colorpicker-button =
+ .title = Иваз кардани ранг
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Интихоби ранг
+pdfjs-editor-colorpicker-yellow =
+ .title = Зард
+pdfjs-editor-colorpicker-green =
+ .title = Сабз
+pdfjs-editor-colorpicker-blue =
+ .title = Кабуд
+pdfjs-editor-colorpicker-pink =
+ .title = Гулобӣ
+pdfjs-editor-colorpicker-red =
+ .title = Сурх
diff --git a/www/lib/pdfjs/modern/web/locale/th/viewer.ftl b/www/lib/pdfjs/modern/web/locale/th/viewer.ftl
new file mode 100644
index 000000000..f6fbadb87
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/th/viewer.ftl
@@ -0,0 +1,341 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = หน้าà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²
+pdfjs-previous-button-label = à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²
+pdfjs-next-button =
+ .title = หน้าถัดไป
+pdfjs-next-button-label = ถัดไป
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = หน้า
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = จาภ{ $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } จาภ{ $pagesCount })
+pdfjs-zoom-out-button =
+ .title = ซูมà¸à¸à¸
+pdfjs-zoom-out-button-label = ซูมà¸à¸à¸
+pdfjs-zoom-in-button =
+ .title = ซูมเข้า
+pdfjs-zoom-in-button-label = ซูมเข้า
+pdfjs-zoom-select =
+ .title = ซูม
+pdfjs-presentation-mode-button =
+ .title = สลับเป็นโหมดà¸à¸²à¸£à¸™à¸³à¹€à¸ªà¸™à¸
+pdfjs-presentation-mode-button-label = โหมดà¸à¸²à¸£à¸™à¸³à¹€à¸ªà¸™à¸
+pdfjs-open-file-button =
+ .title = เปิดไฟล์
+pdfjs-open-file-button-label = เปิด
+pdfjs-print-button =
+ .title = พิมพ์
+pdfjs-print-button-label = พิมพ์
+pdfjs-save-button =
+ .title = บันทึà¸
+pdfjs-save-button-label = บันทึà¸
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = ดาวน์โหลด
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = ดาวน์โหลด
+pdfjs-bookmark-button =
+ .title = หน้าปัจจุบัน (ดู URL จาà¸à¸«à¸™à¹‰à¸²à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™)
+pdfjs-bookmark-button-label = หน้าปัจจุบัน
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = เปิดในà¹à¸à¸›
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = เปิดในà¹à¸à¸›
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = เครื่à¸à¸‡à¸¡à¸·à¸
+pdfjs-tools-button-label = เครื่à¸à¸‡à¸¡à¸·à¸
+pdfjs-first-page-button =
+ .title = ไปยังหน้าà¹à¸£à¸
+pdfjs-first-page-button-label = ไปยังหน้าà¹à¸£à¸
+pdfjs-last-page-button =
+ .title = ไปยังหน้าสุดท้าย
+pdfjs-last-page-button-label = ไปยังหน้าสุดท้าย
+pdfjs-page-rotate-cw-button =
+ .title = หมุนตามเข็มนาฬิà¸à¸²
+pdfjs-page-rotate-cw-button-label = หมุนตามเข็มนาฬิà¸à¸²
+pdfjs-page-rotate-ccw-button =
+ .title = หมุนทวนเข็มนาฬิà¸à¸²
+pdfjs-page-rotate-ccw-button-label = หมุนทวนเข็มนาฬิà¸à¸²
+pdfjs-cursor-text-select-tool-button =
+ .title = เปิดใช้งานเครื่à¸à¸‡à¸¡à¸·à¸à¸à¸²à¸£à¹€à¸¥à¸·à¸à¸à¸‚้à¸à¸„วาม
+pdfjs-cursor-text-select-tool-button-label = เครื่à¸à¸‡à¸¡à¸·à¸à¸à¸²à¸£à¹€à¸¥à¸·à¸à¸à¸‚้à¸à¸„วาม
+pdfjs-cursor-hand-tool-button =
+ .title = เปิดใช้งานเครื่à¸à¸‡à¸¡à¸·à¸à¸¡à¸·à¸
+pdfjs-cursor-hand-tool-button-label = เครื่à¸à¸‡à¸¡à¸·à¸à¸¡à¸·à¸
+pdfjs-scroll-page-button =
+ .title = ใช้à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²
+pdfjs-scroll-page-button-label = à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²
+pdfjs-scroll-vertical-button =
+ .title = ใช้à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¹à¸™à¸§à¸•à¸±à¹‰à¸‡
+pdfjs-scroll-vertical-button-label = à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¹à¸™à¸§à¸•à¸±à¹‰à¸‡
+pdfjs-scroll-horizontal-button =
+ .title = ใช้à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¹à¸™à¸§à¸™à¸à¸™
+pdfjs-scroll-horizontal-button-label = à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¹à¸™à¸§à¸™à¸à¸™
+pdfjs-scroll-wrapped-button =
+ .title = ใช้à¸à¸²à¸£à¹€à¸¥à¸·à¹ˆà¸à¸™à¹à¸šà¸šà¸„ลุม
+pdfjs-scroll-wrapped-button-label = เลื่à¸à¸™à¹à¸šà¸šà¸„ลุม
+pdfjs-spread-none-button =
+ .title = ไม่ต้à¸à¸‡à¸£à¸§à¸¡à¸à¸²à¸£à¸à¸£à¸°à¸ˆà¸²à¸¢à¸«à¸™à¹‰à¸²
+pdfjs-spread-none-button-label = ไม่à¸à¸£à¸°à¸ˆà¸²à¸¢
+pdfjs-spread-odd-button =
+ .title = รวมà¸à¸²à¸£à¸à¸£à¸°à¸ˆà¸²à¸¢à¸«à¸™à¹‰à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¸„ี่
+pdfjs-spread-odd-button-label = à¸à¸£à¸°à¸ˆà¸²à¸¢à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸«à¸¥à¸·à¸à¹€à¸¨à¸©
+pdfjs-spread-even-button =
+ .title = รวมà¸à¸²à¸£à¸à¸£à¸°à¸ˆà¸²à¸¢à¸«à¸™à¹‰à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¸„ู่
+pdfjs-spread-even-button-label = à¸à¸£à¸°à¸ˆà¸²à¸¢à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸—่าเทียม
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = คุณสมบัติเà¸à¸à¸ªà¸²à¸£â€¦
+pdfjs-document-properties-button-label = คุณสมบัติเà¸à¸à¸ªà¸²à¸£â€¦
+pdfjs-document-properties-file-name = ชื่à¸à¹„ฟล์:
+pdfjs-document-properties-file-size = ขนาดไฟล์:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } ไบต์)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } ไบต์)
+pdfjs-document-properties-title = ชื่à¸à¹€à¸£à¸·à¹ˆà¸à¸‡:
+pdfjs-document-properties-author = ผู้สร้าง:
+pdfjs-document-properties-subject = ชื่à¸à¹€à¸£à¸·à¹ˆà¸à¸‡:
+pdfjs-document-properties-keywords = คำสำคัà¸:
+pdfjs-document-properties-creation-date = วันที่สร้าง:
+pdfjs-document-properties-modification-date = วันที่à¹à¸à¹‰à¹„ข:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = ผู้สร้าง:
+pdfjs-document-properties-producer = ผู้ผลิต PDF:
+pdfjs-document-properties-version = รุ่น PDF:
+pdfjs-document-properties-page-count = จำนวนหน้า:
+pdfjs-document-properties-page-size = ขนาดหน้า:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = à¹à¸™à¸§à¸•à¸±à¹‰à¸‡
+pdfjs-document-properties-page-size-orientation-landscape = à¹à¸™à¸§à¸™à¸à¸™
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = จดหมาย
+pdfjs-document-properties-page-size-name-legal = ข้à¸à¸à¸Žà¸«à¸¡à¸²à¸¢
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = มุมมà¸à¸‡à¹€à¸§à¹‡à¸šà¹à¸šà¸šà¸£à¸§à¸”เร็ว:
+pdfjs-document-properties-linearized-yes = ใช่
+pdfjs-document-properties-linearized-no = ไม่
+pdfjs-document-properties-close-button = ปิด
+
+## Print
+
+pdfjs-print-progress-message = à¸à¸³à¸¥à¸±à¸‡à¹€à¸•à¸£à¸µà¸¢à¸¡à¹€à¸à¸à¸ªà¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸žà¸´à¸¡à¸žà¹Œâ€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = ยà¸à¹€à¸¥à¸´à¸
+pdfjs-printing-not-supported = คำเตืà¸à¸™: เบราว์เซà¸à¸£à¹Œà¸™à¸µà¹‰à¹„ม่ได้สนับสนุนà¸à¸²à¸£à¸žà¸´à¸¡à¸žà¹Œà¸à¸¢à¹ˆà¸²à¸‡à¹€à¸•à¹‡à¸¡à¸—ี่
+pdfjs-printing-not-ready = คำเตืà¸à¸™: PDF ไม่ได้รับà¸à¸²à¸£à¹‚หลดà¸à¸¢à¹ˆà¸²à¸‡à¹€à¸•à¹‡à¸¡à¸—ี่สำหรับà¸à¸²à¸£à¸žà¸´à¸¡à¸žà¹Œ
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = เปิด/ปิดà¹à¸–บข้าง
+pdfjs-toggle-sidebar-notification-button =
+ .title = เปิด/ปิดà¹à¸–บข้าง (เà¸à¸à¸ªà¸²à¸£à¸¡à¸µà¹€à¸„้าร่าง/ไฟล์à¹à¸™à¸š/เลเยà¸à¸£à¹Œ)
+pdfjs-toggle-sidebar-button-label = เปิด/ปิดà¹à¸–บข้าง
+pdfjs-document-outline-button =
+ .title = à¹à¸ªà¸”งเค้าร่างเà¸à¸à¸ªà¸²à¸£ (คลิà¸à¸ªà¸à¸‡à¸„รั้งเพื่à¸à¸‚ยาย/ยุบรายà¸à¸²à¸£à¸—ั้งหมด)
+pdfjs-document-outline-button-label = เค้าร่างเà¸à¸à¸ªà¸²à¸£
+pdfjs-attachments-button =
+ .title = à¹à¸ªà¸”งไฟล์à¹à¸™à¸š
+pdfjs-attachments-button-label = ไฟล์à¹à¸™à¸š
+pdfjs-layers-button =
+ .title = à¹à¸ªà¸”งเลเยà¸à¸£à¹Œ (คลิà¸à¸ªà¸à¸‡à¸„รั้งเพื่à¸à¸£à¸µà¹€à¸‹à¹‡à¸•à¹€à¸¥à¹€à¸¢à¸à¸£à¹Œà¸—ั้งหมดเป็นสถานะเริ่มต้น)
+pdfjs-layers-button-label = เลเยà¸à¸£à¹Œ
+pdfjs-thumbs-button =
+ .title = à¹à¸ªà¸”งภาพขนาดย่à¸
+pdfjs-thumbs-button-label = ภาพขนาดย่à¸
+pdfjs-current-outline-item-button =
+ .title = ค้นหารายà¸à¸²à¸£à¹€à¸„้าร่างปัจจุบัน
+pdfjs-current-outline-item-button-label = รายà¸à¸²à¸£à¹€à¸„้าร่างปัจจุบัน
+pdfjs-findbar-button =
+ .title = ค้นหาในเà¸à¸à¸ªà¸²à¸£
+pdfjs-findbar-button-label = ค้นหา
+pdfjs-additional-layers = เลเยà¸à¸£à¹Œà¹€à¸žà¸´à¹ˆà¸¡à¹€à¸•à¸´à¸¡
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = หน้า { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ภาพขนาดย่à¸à¸‚à¸à¸‡à¸«à¸™à¹‰à¸² { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ค้นหา
+ .placeholder = ค้นหาในเà¸à¸à¸ªà¸²à¸£â€¦
+pdfjs-find-previous-button =
+ .title = หาตำà¹à¸«à¸™à¹ˆà¸‡à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²à¸‚à¸à¸‡à¸§à¸¥à¸µ
+pdfjs-find-previous-button-label = à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²
+pdfjs-find-next-button =
+ .title = หาตำà¹à¸«à¸™à¹ˆà¸‡à¸–ัดไปขà¸à¸‡à¸§à¸¥à¸µ
+pdfjs-find-next-button-label = ถัดไป
+pdfjs-find-highlight-checkbox = เน้นสีทั้งหมด
+pdfjs-find-match-case-checkbox-label = ตัวพิมพ์ใหà¸à¹ˆà¹€à¸¥à¹‡à¸à¸•à¸£à¸‡à¸à¸±à¸™
+pdfjs-find-match-diacritics-checkbox-label = เครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸à¸³à¸à¸±à¸šà¸à¸²à¸£à¸à¸à¸à¹€à¸ªà¸µà¸¢à¸‡à¸•à¸£à¸‡à¸à¸±à¸™
+pdfjs-find-entire-word-checkbox-label = ทั้งคำ
+pdfjs-find-reached-top = ค้นหาถึงจุดเริ่มต้นขà¸à¸‡à¸«à¸™à¹‰à¸² เริ่มค้นต่à¸à¸ˆà¸²à¸à¸”้านล่าง
+pdfjs-find-reached-bottom = ค้นหาถึงจุดสิ้นสุดหน้า เริ่มค้นต่à¸à¸ˆà¸²à¸à¸”้านบน
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = { $current } จาภ{ $total } รายà¸à¸²à¸£à¸—ี่ตรงà¸à¸±à¸™
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit = มาà¸à¸à¸§à¹ˆà¸² { $limit } รายà¸à¸²à¸£à¸—ี่ตรงà¸à¸±à¸™
+pdfjs-find-not-found = ไม่พบวลี
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = ความà¸à¸§à¹‰à¸²à¸‡à¸«à¸™à¹‰à¸²
+pdfjs-page-scale-fit = พà¸à¸”ีหน้า
+pdfjs-page-scale-auto = ซูมà¸à¸±à¸•à¹‚นมัติ
+pdfjs-page-scale-actual = ขนาดจริง
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = หน้า { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = เà¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขณะโหลด PDF
+pdfjs-invalid-file-error = ไฟล์ PDF ไม่ถูà¸à¸•à¹‰à¸à¸‡à¸«à¸£à¸·à¸à¹€à¸ªà¸µà¸¢à¸«à¸²à¸¢
+pdfjs-missing-file-error = ไฟล์ PDF หายไป
+pdfjs-unexpected-response-error = à¸à¸²à¸£à¸•à¸à¸šà¸ªà¸™à¸à¸‡à¸‚à¸à¸‡à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸à¸£à¹Œà¸—ี่ไม่คาดคิด
+pdfjs-rendering-error = เà¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขณะเรนเดà¸à¸£à¹Œà¸«à¸™à¹‰à¸²
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [คำà¸à¸˜à¸´à¸šà¸²à¸¢à¸›à¸£à¸°à¸à¸à¸š { $type }]
+
+## Password
+
+pdfjs-password-label = ป้à¸à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹€à¸žà¸·à¹ˆà¸à¹€à¸›à¸´à¸”ไฟล์ PDF นี้
+pdfjs-password-invalid = รหัสผ่านไม่ถูà¸à¸•à¹‰à¸à¸‡ โปรดลà¸à¸‡à¸à¸µà¸à¸„รั้ง
+pdfjs-password-ok-button = ตà¸à¸¥à¸‡
+pdfjs-password-cancel-button = ยà¸à¹€à¸¥à¸´à¸
+pdfjs-web-fonts-disabled = à¹à¸šà¸šà¸à¸±à¸à¸©à¸£à¹€à¸§à¹‡à¸šà¸–ูà¸à¸›à¸´à¸”ใช้งาน: ไม่สามารถใช้à¹à¸šà¸šà¸à¸±à¸à¸©à¸£ PDF à¸à¸±à¸‡à¸•à¸±à¸§
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ข้à¸à¸„วาม
+pdfjs-editor-free-text-button-label = ข้à¸à¸„วาม
+pdfjs-editor-ink-button =
+ .title = รูปวาด
+pdfjs-editor-ink-button-label = รูปวาด
+pdfjs-editor-stamp-button =
+ .title = เพิ่มหรืà¸à¹à¸à¹‰à¹„ขภาพ
+pdfjs-editor-stamp-button-label = เพิ่มหรืà¸à¹à¸à¹‰à¹„ขภาพ
+# Editor Parameters
+pdfjs-editor-free-text-color-input = สี
+pdfjs-editor-free-text-size-input = ขนาด
+pdfjs-editor-ink-color-input = สี
+pdfjs-editor-ink-thickness-input = ความหนา
+pdfjs-editor-ink-opacity-input = ความทึบ
+pdfjs-editor-stamp-add-image-button =
+ .title = เพิ่มภาพ
+pdfjs-editor-stamp-add-image-button-label = เพิ่มภาพ
+pdfjs-free-text =
+ .aria-label = ตัวà¹à¸à¹‰à¹„ขข้à¸à¸„วาม
+pdfjs-free-text-default-content = เริ่มพิมพ์…
+pdfjs-ink =
+ .aria-label = ตัวà¹à¸à¹‰à¹„ขรูปวาด
+pdfjs-ink-canvas =
+ .aria-label = ภาพที่ผู้ใช้สร้างขึ้น
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = ข้à¸à¸„วามทดà¹à¸—น
+pdfjs-editor-alt-text-edit-button-label = à¹à¸à¹‰à¹„ขข้à¸à¸„วามทดà¹à¸—น
+pdfjs-editor-alt-text-dialog-label = เลืà¸à¸à¸•à¸±à¸§à¹€à¸¥à¸·à¸à¸
+pdfjs-editor-alt-text-dialog-description = ข้à¸à¸„วามทดà¹à¸—นสามารถช่วยเหลืà¸à¹„ด้เมื่à¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸¡à¸à¸‡à¹„ม่เห็นภาพ หรืà¸à¸ าพไม่โหลด
+pdfjs-editor-alt-text-add-description-label = เพิ่มคำà¸à¸˜à¸´à¸šà¸²à¸¢
+pdfjs-editor-alt-text-add-description-description = à¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰ 1-2 ประโยคซึ่งà¸à¸˜à¸´à¸šà¸²à¸¢à¸«à¸±à¸§à¹€à¸£à¸·à¹ˆà¸à¸‡ ฉาภหรืà¸à¸à¸²à¸£à¸à¸£à¸°à¸—ำ
+pdfjs-editor-alt-text-mark-decorative-label = ทำเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¹€à¸›à¹‡à¸™à¸ªà¸´à¹ˆà¸‡à¸•à¸à¹à¸•à¹ˆà¸‡
+pdfjs-editor-alt-text-mark-decorative-description = สิ่งนี้ใช้สำหรับภาพที่เป็นสิ่งประดับ เช่น ขà¸à¸š หรืà¸à¸¥à¸²à¸¢à¸™à¹‰à¸³
+pdfjs-editor-alt-text-cancel-button = ยà¸à¹€à¸¥à¸´à¸
+pdfjs-editor-alt-text-save-button = บันทึà¸
+pdfjs-editor-alt-text-decorative-tooltip = ทำเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¹€à¸›à¹‡à¸™à¸ªà¸´à¹ˆà¸‡à¸•à¸à¹à¸•à¹ˆà¸‡à¹à¸¥à¹‰à¸§
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = ตัวà¸à¸¢à¹ˆà¸²à¸‡à¹€à¸Šà¹ˆà¸™ “ชายหนุ่มคนหนึ่งนั่งลงที่โต๊ะเพื่à¸à¸£à¸±à¸šà¸›à¸£à¸°à¸—านà¸à¸²à¸«à¸²à¸£à¸¡à¸·à¹‰à¸à¸«à¸™à¸¶à¹ˆà¸‡â€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = มุมซ้ายบน — ปรับขนาด
+pdfjs-editor-resizer-label-top-middle = ตรงà¸à¸¥à¸²à¸‡à¸”้านบน — ปรับขนาด
+pdfjs-editor-resizer-label-top-right = มุมขวาบน — ปรับขนาด
+pdfjs-editor-resizer-label-middle-right = ตรงà¸à¸¥à¸²à¸‡à¸”้านขวา — ปรับขนาด
+pdfjs-editor-resizer-label-bottom-right = มุมขวาล่าง — ปรับขนาด
+pdfjs-editor-resizer-label-bottom-middle = ตรงà¸à¸¥à¸²à¸‡à¸”้านล่าง — ปรับขนาด
+pdfjs-editor-resizer-label-bottom-left = มุมซ้ายล่าง — ปรับขนาด
+pdfjs-editor-resizer-label-middle-left = ตรงà¸à¸¥à¸²à¸‡à¸”้านซ้าย — ปรับขนาด
diff --git a/www/lib/pdfjs/modern/web/locale/tl/viewer.ftl b/www/lib/pdfjs/modern/web/locale/tl/viewer.ftl
new file mode 100644
index 000000000..faa0009bd
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/tl/viewer.ftl
@@ -0,0 +1,257 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Naunang Pahina
+pdfjs-previous-button-label = Nakaraan
+pdfjs-next-button =
+ .title = Sunod na Pahina
+pdfjs-next-button-label = Sunod
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Pahina
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = ng { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } ng { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Paliitin
+pdfjs-zoom-out-button-label = Paliitin
+pdfjs-zoom-in-button =
+ .title = Palakihin
+pdfjs-zoom-in-button-label = Palakihin
+pdfjs-zoom-select =
+ .title = Mag-zoom
+pdfjs-presentation-mode-button =
+ .title = Lumipat sa Presentation Mode
+pdfjs-presentation-mode-button-label = Presentation Mode
+pdfjs-open-file-button =
+ .title = Magbukas ng file
+pdfjs-open-file-button-label = Buksan
+pdfjs-print-button =
+ .title = i-Print
+pdfjs-print-button-label = i-Print
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Mga Kagamitan
+pdfjs-tools-button-label = Mga Kagamitan
+pdfjs-first-page-button =
+ .title = Pumunta sa Unang Pahina
+pdfjs-first-page-button-label = Pumunta sa Unang Pahina
+pdfjs-last-page-button =
+ .title = Pumunta sa Huling Pahina
+pdfjs-last-page-button-label = Pumunta sa Huling Pahina
+pdfjs-page-rotate-cw-button =
+ .title = Paikutin Pakanan
+pdfjs-page-rotate-cw-button-label = Paikutin Pakanan
+pdfjs-page-rotate-ccw-button =
+ .title = Paikutin Pakaliwa
+pdfjs-page-rotate-ccw-button-label = Paikutin Pakaliwa
+pdfjs-cursor-text-select-tool-button =
+ .title = I-enable ang Text Selection Tool
+pdfjs-cursor-text-select-tool-button-label = Text Selection Tool
+pdfjs-cursor-hand-tool-button =
+ .title = I-enable ang Hand Tool
+pdfjs-cursor-hand-tool-button-label = Hand Tool
+pdfjs-scroll-vertical-button =
+ .title = Gumamit ng Vertical Scrolling
+pdfjs-scroll-vertical-button-label = Vertical Scrolling
+pdfjs-scroll-horizontal-button =
+ .title = Gumamit ng Horizontal Scrolling
+pdfjs-scroll-horizontal-button-label = Horizontal Scrolling
+pdfjs-scroll-wrapped-button =
+ .title = Gumamit ng Wrapped Scrolling
+pdfjs-scroll-wrapped-button-label = Wrapped Scrolling
+pdfjs-spread-none-button =
+ .title = Huwag pagsamahin ang mga page spread
+pdfjs-spread-none-button-label = No Spreads
+pdfjs-spread-odd-button =
+ .title = Join page spreads starting with odd-numbered pages
+pdfjs-spread-odd-button-label = Mga Odd Spread
+pdfjs-spread-even-button =
+ .title = Pagsamahin ang mga page spread na nagsisimula sa mga even-numbered na pahina
+pdfjs-spread-even-button-label = Mga Even Spread
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Mga Katangian ng Dokumento…
+pdfjs-document-properties-button-label = Mga Katangian ng Dokumento…
+pdfjs-document-properties-file-name = File name:
+pdfjs-document-properties-file-size = File size:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Pamagat:
+pdfjs-document-properties-author = May-akda:
+pdfjs-document-properties-subject = Paksa:
+pdfjs-document-properties-keywords = Mga keyword:
+pdfjs-document-properties-creation-date = Petsa ng Pagkakagawa:
+pdfjs-document-properties-modification-date = Petsa ng Pagkakabago:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Tagalikha:
+pdfjs-document-properties-producer = PDF Producer:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Bilang ng Pahina:
+pdfjs-document-properties-page-size = Laki ng Pahina:
+pdfjs-document-properties-page-size-unit-inches = pulgada
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = patayo
+pdfjs-document-properties-page-size-orientation-landscape = pahiga
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Fast Web View:
+pdfjs-document-properties-linearized-yes = Oo
+pdfjs-document-properties-linearized-no = Hindi
+pdfjs-document-properties-close-button = Isara
+
+## Print
+
+pdfjs-print-progress-message = Inihahanda ang dokumento para sa pag-print…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Kanselahin
+pdfjs-printing-not-supported = Babala: Hindi pa ganap na suportado ang pag-print sa browser na ito.
+pdfjs-printing-not-ready = Babala: Hindi ganap na nabuksan ang PDF para sa pag-print.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Ipakita/Itago ang Sidebar
+pdfjs-toggle-sidebar-notification-button =
+ .title = Ipakita/Itago ang Sidebar (nagtataglay ang dokumento ng balangkas/mga attachment/mga layer)
+pdfjs-toggle-sidebar-button-label = Ipakita/Itago ang Sidebar
+pdfjs-document-outline-button =
+ .title = Ipakita ang Document Outline (mag-double-click para i-expand/collapse ang laman)
+pdfjs-document-outline-button-label = Balangkas ng Dokumento
+pdfjs-attachments-button =
+ .title = Ipakita ang mga Attachment
+pdfjs-attachments-button-label = Mga attachment
+pdfjs-layers-button =
+ .title = Ipakita ang mga Layer (mag-double click para mareset ang lahat ng layer sa orihinal na estado)
+pdfjs-layers-button-label = Mga layer
+pdfjs-thumbs-button =
+ .title = Ipakita ang mga Thumbnail
+pdfjs-thumbs-button-label = Mga thumbnail
+pdfjs-findbar-button =
+ .title = Hanapin sa Dokumento
+pdfjs-findbar-button-label = Hanapin
+pdfjs-additional-layers = Mga Karagdagang Layer
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Pahina { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Thumbnail ng Pahina { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Hanapin
+ .placeholder = Hanapin sa dokumento…
+pdfjs-find-previous-button =
+ .title = Hanapin ang nakaraang pangyayari ng parirala
+pdfjs-find-previous-button-label = Nakaraan
+pdfjs-find-next-button =
+ .title = Hanapin ang susunod na pangyayari ng parirala
+pdfjs-find-next-button-label = Susunod
+pdfjs-find-highlight-checkbox = I-highlight lahat
+pdfjs-find-match-case-checkbox-label = Itugma ang case
+pdfjs-find-entire-word-checkbox-label = Buong salita
+pdfjs-find-reached-top = Naabot na ang tuktok ng dokumento, ipinagpatuloy mula sa ilalim
+pdfjs-find-reached-bottom = Naabot na ang dulo ng dokumento, ipinagpatuloy mula sa tuktok
+pdfjs-find-not-found = Hindi natagpuan ang parirala
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Lapad ng Pahina
+pdfjs-page-scale-fit = Pagkasyahin ang Pahina
+pdfjs-page-scale-auto = Automatic Zoom
+pdfjs-page-scale-actual = Totoong sukat
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Nagkaproblema habang niloload ang PDF.
+pdfjs-invalid-file-error = Di-wasto o sira ang PDF file.
+pdfjs-missing-file-error = Nawawalang PDF file.
+pdfjs-unexpected-response-error = Hindi inaasahang tugon ng server.
+pdfjs-rendering-error = Nagkaproblema habang nirerender ang pahina.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = Ipasok ang password upang buksan ang PDF file na ito.
+pdfjs-password-invalid = Maling password. Subukan uli.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Kanselahin
+pdfjs-web-fonts-disabled = Naka-disable ang mga Web font: hindi kayang gamitin ang mga naka-embed na PDF font.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/tr/viewer.ftl b/www/lib/pdfjs/modern/web/locale/tr/viewer.ftl
new file mode 100644
index 000000000..bd30d09a0
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/tr/viewer.ftl
@@ -0,0 +1,384 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Önceki sayfa
+pdfjs-previous-button-label = Önceki
+pdfjs-next-button =
+ .title = Sonraki sayfa
+pdfjs-next-button-label = Sonraki
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Sayfa
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Uzaklaştır
+pdfjs-zoom-out-button-label = Uzaklaştır
+pdfjs-zoom-in-button =
+ .title = Yaklaştır
+pdfjs-zoom-in-button-label = Yaklaştır
+pdfjs-zoom-select =
+ .title = Yakınlaştırma
+pdfjs-presentation-mode-button =
+ .title = Sunum moduna geç
+pdfjs-presentation-mode-button-label = Sunum modu
+pdfjs-open-file-button =
+ .title = Dosya aç
+pdfjs-open-file-button-label = Aç
+pdfjs-print-button =
+ .title = Yazdır
+pdfjs-print-button-label = Yazdır
+pdfjs-save-button =
+ .title = Kaydet
+pdfjs-save-button-label = Kaydet
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Ä°ndir
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Ä°ndir
+pdfjs-bookmark-button =
+ .title = Geçerli sayfa (geçerli sayfanın adresini görüntüle)
+pdfjs-bookmark-button-label = Geçerli sayfa
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Uygulamada aç
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Uygulamada aç
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Araçlar
+pdfjs-tools-button-label = Araçlar
+pdfjs-first-page-button =
+ .title = Ä°lk sayfaya git
+pdfjs-first-page-button-label = Ä°lk sayfaya git
+pdfjs-last-page-button =
+ .title = Son sayfaya git
+pdfjs-last-page-button-label = Son sayfaya git
+pdfjs-page-rotate-cw-button =
+ .title = Saat yönünde döndür
+pdfjs-page-rotate-cw-button-label = Saat yönünde döndür
+pdfjs-page-rotate-ccw-button =
+ .title = Saat yönünün tersine döndür
+pdfjs-page-rotate-ccw-button-label = Saat yönünün tersine döndür
+pdfjs-cursor-text-select-tool-button =
+ .title = Metin seçme aracını etkinleştir
+pdfjs-cursor-text-select-tool-button-label = Metin seçme aracı
+pdfjs-cursor-hand-tool-button =
+ .title = El aracını etkinleştir
+pdfjs-cursor-hand-tool-button-label = El aracı
+pdfjs-scroll-page-button =
+ .title = Sayfa kaydırmayı kullan
+pdfjs-scroll-page-button-label = Sayfa kaydırma
+pdfjs-scroll-vertical-button =
+ .title = Dikey kaydırma kullan
+pdfjs-scroll-vertical-button-label = Dikey kaydırma
+pdfjs-scroll-horizontal-button =
+ .title = Yatay kaydırma kullan
+pdfjs-scroll-horizontal-button-label = Yatay kaydırma
+pdfjs-scroll-wrapped-button =
+ .title = Yan yana kaydırmayı kullan
+pdfjs-scroll-wrapped-button-label = Yan yana kaydırma
+pdfjs-spread-none-button =
+ .title = Yan yana sayfaları birleştirme
+pdfjs-spread-none-button-label = BirleÅŸtirme
+pdfjs-spread-odd-button =
+ .title = Yan yana sayfaları tek numaralı sayfalardan başlayarak birleştir
+pdfjs-spread-odd-button-label = Tek numaralı
+pdfjs-spread-even-button =
+ .title = Yan yana sayfaları çift numaralı sayfalardan başlayarak birleştir
+pdfjs-spread-even-button-label = Çift numaralı
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Belge özellikleri…
+pdfjs-document-properties-button-label = Belge özellikleri…
+pdfjs-document-properties-file-name = Dosya adı:
+pdfjs-document-properties-file-size = Dosya boyutu:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bayt)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bayt)
+pdfjs-document-properties-title = Başlık:
+pdfjs-document-properties-author = Yazar:
+pdfjs-document-properties-subject = Konu:
+pdfjs-document-properties-keywords = Anahtar kelimeler:
+pdfjs-document-properties-creation-date = Oluturma tarihi:
+pdfjs-document-properties-modification-date = DeÄŸiÅŸtirme tarihi:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } { $time }
+pdfjs-document-properties-creator = OluÅŸturan:
+pdfjs-document-properties-producer = PDF üreticisi:
+pdfjs-document-properties-version = PDF sürümü:
+pdfjs-document-properties-page-count = Sayfa sayısı:
+pdfjs-document-properties-page-size = Sayfa boyutu:
+pdfjs-document-properties-page-size-unit-inches = inç
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = dikey
+pdfjs-document-properties-page-size-orientation-landscape = yatay
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Hızlı web görünümü:
+pdfjs-document-properties-linearized-yes = Evet
+pdfjs-document-properties-linearized-no = Hayır
+pdfjs-document-properties-close-button = Kapat
+
+## Print
+
+pdfjs-print-progress-message = Belge yazdırılmaya hazırlanıyor…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = %{ $progress }
+pdfjs-print-progress-close-button = Ä°ptal
+pdfjs-printing-not-supported = Uyarı: Yazdırma bu tarayıcı tarafından tam olarak desteklenmemektedir.
+pdfjs-printing-not-ready = Uyarı: PDF tamamen yüklenmedi ve yazdırmaya hazır değil.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Kenar çubuğunu aç/kapat
+pdfjs-toggle-sidebar-notification-button =
+ .title = Kenar çubuğunu aç/kapat (Belge ana hat/ekler/katmanlar içeriyor)
+pdfjs-toggle-sidebar-button-label = Kenar çubuğunu aç/kapat
+pdfjs-document-outline-button =
+ .title = Belge ana hatlarını göster (Tüm öğeleri genişletmek/daraltmak için çift tıklayın)
+pdfjs-document-outline-button-label = Belge ana hatları
+pdfjs-attachments-button =
+ .title = Ekleri göster
+pdfjs-attachments-button-label = Ekler
+pdfjs-layers-button =
+ .title = Katmanları göster (tüm katmanları varsayılan duruma sıfırlamak için çift tıklayın)
+pdfjs-layers-button-label = Katmanlar
+pdfjs-thumbs-button =
+ .title = Küçük resimleri göster
+pdfjs-thumbs-button-label = Küçük resimler
+pdfjs-current-outline-item-button =
+ .title = Mevcut ana hat öğesini bul
+pdfjs-current-outline-item-button-label = Mevcut ana hat öğesi
+pdfjs-findbar-button =
+ .title = Belgede bul
+pdfjs-findbar-button-label = Bul
+pdfjs-additional-layers = Ek katmanlar
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Sayfa { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page }. sayfanın küçük hâli
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Bul
+ .placeholder = Belgede bul…
+pdfjs-find-previous-button =
+ .title = Önceki eşleşmeyi bul
+pdfjs-find-previous-button-label = Önceki
+pdfjs-find-next-button =
+ .title = Sonraki eÅŸleÅŸmeyi bul
+pdfjs-find-next-button-label = Sonraki
+pdfjs-find-highlight-checkbox = Tümünü vurgula
+pdfjs-find-match-case-checkbox-label = Büyük-küçük harfe duyarlı
+pdfjs-find-match-diacritics-checkbox-label = Fonetik iÅŸaretleri bul
+pdfjs-find-entire-word-checkbox-label = Tam sözcükler
+pdfjs-find-reached-top = Belgenin başına ulaşıldı, sonundan devam edildi
+pdfjs-find-reached-bottom = Belgenin sonuna ulaşıldı, başından devam edildi
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $total } eÅŸleÅŸmeden { $current }. eÅŸleÅŸme
+ *[other] { $total } eÅŸleÅŸmeden { $current }. eÅŸleÅŸme
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] { $limit } eÅŸleÅŸmeden fazla
+ *[other] { $limit } eÅŸleÅŸmeden fazla
+ }
+pdfjs-find-not-found = Eşleşme bulunamadı
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sayfa geniÅŸliÄŸi
+pdfjs-page-scale-fit = Sayfayı sığdır
+pdfjs-page-scale-auto = Otomatik yakınlaştır
+pdfjs-page-scale-actual = Gerçek boyut
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = %{ $scale }
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Sayfa { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF yüklenirken bir hata oluştu.
+pdfjs-invalid-file-error = Geçersiz veya bozulmuş PDF dosyası.
+pdfjs-missing-file-error = PDF dosyası eksik.
+pdfjs-unexpected-response-error = Beklenmeyen sunucu yanıtı.
+pdfjs-rendering-error = Sayfa yorumlanırken bir hata oluştu.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } iÅŸareti]
+
+## Password
+
+pdfjs-password-label = Bu PDF dosyasını açmak için parolasını yazın.
+pdfjs-password-invalid = Geçersiz parola. Lütfen yeniden deneyin.
+pdfjs-password-ok-button = Tamam
+pdfjs-password-cancel-button = Ä°ptal
+pdfjs-web-fonts-disabled = Web fontları devre dışı: Gömülü PDF fontları kullanılamıyor.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Metin
+pdfjs-editor-free-text-button-label = Metin
+pdfjs-editor-ink-button =
+ .title = Çiz
+pdfjs-editor-ink-button-label = Çiz
+pdfjs-editor-stamp-button =
+ .title = Resim ekle veya düzenle
+pdfjs-editor-stamp-button-label = Resim ekle veya düzenle
+pdfjs-editor-remove-button =
+ .title = Kaldır
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Çizimi kaldır
+pdfjs-editor-remove-freetext-button =
+ .title = Metni kaldır
+pdfjs-editor-remove-stamp-button =
+ .title = Resmi kaldır
+pdfjs-editor-remove-highlight-button =
+ .title = Vurgulamayı kaldır
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Renk
+pdfjs-editor-free-text-size-input = Boyut
+pdfjs-editor-ink-color-input = Renk
+pdfjs-editor-ink-thickness-input = Kalınlık
+pdfjs-editor-ink-opacity-input = Saydamlık
+pdfjs-editor-stamp-add-image-button =
+ .title = Resim ekle
+pdfjs-editor-stamp-add-image-button-label = Resim ekle
+pdfjs-free-text =
+ .aria-label = Metin düzenleyicisi
+pdfjs-free-text-default-content = Yazmaya başlayın…
+pdfjs-ink =
+ .aria-label = Çizim düzenleyicisi
+pdfjs-ink-canvas =
+ .aria-label = Kullanıcı tarafından oluşturulan resim
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Alternatif metin
+pdfjs-editor-alt-text-edit-button-label = Alternatif metni düzenle
+pdfjs-editor-alt-text-dialog-label = Bir seçenek seçin
+pdfjs-editor-alt-text-dialog-description = Alternatif metin, insanlar görseli göremediğinde veya görsel yüklenmediğinde işe yarar.
+pdfjs-editor-alt-text-add-description-label = Açıklama ekle
+pdfjs-editor-alt-text-add-description-description = Konuyu, ortamı veya eylemleri tanımlayan bir iki cümle yazmaya çalışın.
+pdfjs-editor-alt-text-mark-decorative-label = Dekoratif olarak iÅŸaretle
+pdfjs-editor-alt-text-mark-decorative-description = Kenarlıklar veya filigranlar gibi dekoratif görüntüler için kullanılır.
+pdfjs-editor-alt-text-cancel-button = Vazgeç
+pdfjs-editor-alt-text-save-button = Kaydet
+pdfjs-editor-alt-text-decorative-tooltip = Dekoratif olarak iÅŸaretlendi
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = ÖrneÄŸin, “Genç bir adam yemek yemek için masaya oturuyorâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Sol üst köşe — yeniden boyutlandır
+pdfjs-editor-resizer-label-top-middle = Üst orta — yeniden boyutlandır
+pdfjs-editor-resizer-label-top-right = Sağ üst köşe — yeniden boyutlandır
+pdfjs-editor-resizer-label-middle-right = Orta sağ — yeniden boyutlandır
+pdfjs-editor-resizer-label-bottom-right = Sağ alt köşe — yeniden boyutlandır
+pdfjs-editor-resizer-label-bottom-middle = Alt orta — yeniden boyutlandır
+pdfjs-editor-resizer-label-bottom-left = Sol alt köşe — yeniden boyutlandır
+pdfjs-editor-resizer-label-middle-left = Orta sol — yeniden boyutlandır
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Vurgu rengi
+pdfjs-editor-colorpicker-button =
+ .title = Rengi deÄŸiÅŸtir
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Renk seçenekleri
+pdfjs-editor-colorpicker-yellow =
+ .title = Sarı
+pdfjs-editor-colorpicker-green =
+ .title = YeÅŸil
+pdfjs-editor-colorpicker-blue =
+ .title = Mavi
+pdfjs-editor-colorpicker-pink =
+ .title = Pembe
+pdfjs-editor-colorpicker-red =
+ .title = Kırmızı
diff --git a/www/lib/pdfjs/modern/web/locale/trs/viewer.ftl b/www/lib/pdfjs/modern/web/locale/trs/viewer.ftl
new file mode 100644
index 000000000..aba3c72a9
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/trs/viewer.ftl
@@ -0,0 +1,197 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Pajinâ gunâj rukùu
+pdfjs-previous-button-label = Sa gachin
+pdfjs-next-button =
+ .title = Pajinâ 'na' ñaan
+pdfjs-next-button-label = Ne' ñaan
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Ñanj
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = si'iaj { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Nagi'iaj li'
+pdfjs-zoom-out-button-label = Nagi'iaj li'
+pdfjs-zoom-in-button =
+ .title = Nagi'iaj niko'
+pdfjs-zoom-in-button-label = Nagi'iaj niko'
+pdfjs-zoom-select =
+ .title = dà j nìko ma'an
+pdfjs-presentation-mode-button =
+ .title = Naduno' daj ga ma
+pdfjs-presentation-mode-button-label = Daj gà ma
+pdfjs-open-file-button =
+ .title = Na'nïn' chrû ñanj
+pdfjs-open-file-button-label = Na'nïn
+pdfjs-print-button =
+ .title = Nari' ña du'ua
+pdfjs-print-button-label = Nari' ñadu'ua
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Rasun
+pdfjs-tools-button-label = Nej rasùun
+pdfjs-first-page-button =
+ .title = gun' riña pajina asiniin
+pdfjs-first-page-button-label = Gun' riña pajina asiniin
+pdfjs-last-page-button =
+ .title = Gun' riña pajina rukù ni'in
+pdfjs-last-page-button-label = Gun' riña pajina rukù ni'inj
+pdfjs-page-rotate-cw-button =
+ .title = Tanikaj ne' huat
+pdfjs-page-rotate-cw-button-label = Tanikaj ne' huat
+pdfjs-page-rotate-ccw-button =
+ .title = Tanikaj ne' chînt'
+pdfjs-page-rotate-ccw-button-label = Tanikaj ne' chint
+pdfjs-cursor-text-select-tool-button =
+ .title = Dugi'iaj sun' sa ganahui texto
+pdfjs-cursor-text-select-tool-button-label = Nej rasun arajsun' da' nahui' texto
+pdfjs-cursor-hand-tool-button =
+ .title = Nachrun' nej rasun
+pdfjs-cursor-hand-tool-button-label = Sa rajsun ro'o'
+pdfjs-scroll-vertical-button =
+ .title = Garasun' dukuán runūu
+pdfjs-scroll-vertical-button-label = Dukuán runūu
+pdfjs-scroll-horizontal-button =
+ .title = Garasun' dukuán nikin' nahui
+pdfjs-scroll-horizontal-button-label = Dukuán nikin' nahui
+pdfjs-scroll-wrapped-button =
+ .title = Garasun' sa nachree
+pdfjs-scroll-wrapped-button-label = Sa nachree
+pdfjs-spread-none-button =
+ .title = Si nagi'iaj nugun'un' nej pagina hua ninin
+pdfjs-spread-none-button-label = Ni'io daj hua pagina
+pdfjs-spread-odd-button =
+ .title = Nagi'iaj nugua'ant nej pajina
+pdfjs-spread-odd-button-label = Ni'io' daj hua libro gurin
+pdfjs-spread-even-button =
+ .title = NakÄj dugui' ngà nej pajinâ ayi'ì ngà da' hùi hùi
+pdfjs-spread-even-button-label = Nahuin nìko nej
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Nej sa nikÄj ñanj…
+pdfjs-document-properties-button-label = Nej sa nikÄj ñanj…
+pdfjs-document-properties-file-name = Si yugui archîbo:
+pdfjs-document-properties-file-size = Dà j yachìj archîbo:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Si yugui:
+pdfjs-document-properties-author = Sà girirà :
+pdfjs-document-properties-subject = Dugui':
+pdfjs-document-properties-keywords = Nej nuguan' huìi:
+pdfjs-document-properties-creation-date = Gui gurugui' man:
+pdfjs-document-properties-modification-date = Nuguan' nahuin nakà :
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Guiri ro'
+pdfjs-document-properties-producer = Sa ri PDF:
+pdfjs-document-properties-version = PDF Version:
+pdfjs-document-properties-page-count = Si Guendâ Pâjina:
+pdfjs-document-properties-page-size = Dà j yachìj pâjina:
+pdfjs-document-properties-page-size-unit-inches = riña
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = nadu'ua
+pdfjs-document-properties-page-size-orientation-landscape = dà j huaj
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Da'ngà 'a
+pdfjs-document-properties-page-size-name-legal = Nuguan' a'nï'ïn
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Nanèt chre ni'iajt riña Web:
+pdfjs-document-properties-linearized-yes = Ga'ue
+pdfjs-document-properties-linearized-no = Si ga'ue
+pdfjs-document-properties-close-button = Narán
+
+## Print
+
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Duyichin'
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = NadunÄ barrâ nù yi'nïn
+pdfjs-toggle-sidebar-button-label = NadunÄ barrâ nù yi'nïn
+pdfjs-findbar-button-label = Narì'
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+
+## Find panel button title and messages
+
+pdfjs-find-previous-button-label = Sa gachîn
+pdfjs-find-next-button-label = Ne' ñaan
+pdfjs-find-highlight-checkbox = Daran' sa ña'an
+pdfjs-find-match-case-checkbox-label = Match case
+pdfjs-find-not-found = Nu narì'ij nugua'anj
+
+## Predefined zoom values
+
+pdfjs-page-scale-actual = Dà j yà chi akuan' nÃn
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+
+## Annotations
+
+
+## Password
+
+pdfjs-password-ok-button = Ga'ue
+pdfjs-password-cancel-button = Duyichin'
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/uk/viewer.ftl b/www/lib/pdfjs/modern/web/locale/uk/viewer.ftl
new file mode 100644
index 000000000..7855d427a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/uk/viewer.ftl
@@ -0,0 +1,386 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñторінка
+pdfjs-previous-button-label = ПопереднÑ
+pdfjs-next-button =
+ .title = ÐаÑтупна Ñторінка
+pdfjs-next-button-label = ÐаÑтупна
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Сторінка
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = із { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } із { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Зменшити
+pdfjs-zoom-out-button-label = Зменшити
+pdfjs-zoom-in-button =
+ .title = Збільшити
+pdfjs-zoom-in-button-label = Збільшити
+pdfjs-zoom-select =
+ .title = МаÑштаб
+pdfjs-presentation-mode-button =
+ .title = Перейти в режим презентації
+pdfjs-presentation-mode-button-label = Режим презентації
+pdfjs-open-file-button =
+ .title = Відкрити файл
+pdfjs-open-file-button-label = Відкрити
+pdfjs-print-button =
+ .title = Друк
+pdfjs-print-button-label = Друк
+pdfjs-save-button =
+ .title = Зберегти
+pdfjs-save-button-label = Зберегти
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Завантажити
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Завантажити
+pdfjs-bookmark-button =
+ .title = Поточна Ñторінка (переглÑд URL-адреÑи з поточної Ñторінки)
+pdfjs-bookmark-button-label = Поточна Ñторінка
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Відкрити у програмі
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Відкрити у програмі
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = ІнÑтрументи
+pdfjs-tools-button-label = ІнÑтрументи
+pdfjs-first-page-button =
+ .title = Ðа першу Ñторінку
+pdfjs-first-page-button-label = Ðа першу Ñторінку
+pdfjs-last-page-button =
+ .title = Ðа оÑтанню Ñторінку
+pdfjs-last-page-button-label = Ðа оÑтанню Ñторінку
+pdfjs-page-rotate-cw-button =
+ .title = Повернути за годинниковою Ñтрілкою
+pdfjs-page-rotate-cw-button-label = Повернути за годинниковою Ñтрілкою
+pdfjs-page-rotate-ccw-button =
+ .title = Повернути проти годинникової Ñтрілки
+pdfjs-page-rotate-ccw-button-label = Повернути проти годинникової Ñтрілки
+pdfjs-cursor-text-select-tool-button =
+ .title = Увімкнути інÑтрумент вибору текÑту
+pdfjs-cursor-text-select-tool-button-label = ІнÑтрумент вибору текÑту
+pdfjs-cursor-hand-tool-button =
+ .title = Увімкнути інÑтрумент "Рука"
+pdfjs-cursor-hand-tool-button-label = ІнÑтрумент "Рука"
+pdfjs-scroll-page-button =
+ .title = ВикориÑтовувати Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ñторінки
+pdfjs-scroll-page-button-label = ÐŸÑ€Ð¾ÐºÑ€ÑƒÑ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ñторінки
+pdfjs-scroll-vertical-button =
+ .title = ВикориÑтовувати вертикальне прокручуваннÑ
+pdfjs-scroll-vertical-button-label = Вертикальне прокручуваннÑ
+pdfjs-scroll-horizontal-button =
+ .title = ВикориÑтовувати горизонтальне прокручуваннÑ
+pdfjs-scroll-horizontal-button-label = Горизонтальне прокручуваннÑ
+pdfjs-scroll-wrapped-button =
+ .title = ВикориÑтовувати маÑштабоване прокручуваннÑ
+pdfjs-scroll-wrapped-button-label = МаÑштабоване прокручуваннÑ
+pdfjs-spread-none-button =
+ .title = Ðе викориÑтовувати розгорнуті Ñторінки
+pdfjs-spread-none-button-label = Без розгорнутих Ñторінок
+pdfjs-spread-odd-button =
+ .title = Розгорнуті Ñторінки починаютьÑÑ Ð· непарних номерів
+pdfjs-spread-odd-button-label = Ðепарні Ñторінки зліва
+pdfjs-spread-even-button =
+ .title = Розгорнуті Ñторінки починаютьÑÑ Ð· парних номерів
+pdfjs-spread-even-button-label = Парні Ñторінки зліва
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = ВлаÑтивоÑÑ‚Ñ– документа…
+pdfjs-document-properties-button-label = ВлаÑтивоÑÑ‚Ñ– документа…
+pdfjs-document-properties-file-name = Ðазва файла:
+pdfjs-document-properties-file-size = Розмір файла:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } КБ ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } МБ ({ $size_b } bytes)
+pdfjs-document-properties-title = Заголовок:
+pdfjs-document-properties-author = Ðвтор:
+pdfjs-document-properties-subject = Тема:
+pdfjs-document-properties-keywords = Ключові Ñлова:
+pdfjs-document-properties-creation-date = Дата ÑтвореннÑ:
+pdfjs-document-properties-modification-date = Дата зміни:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Створено:
+pdfjs-document-properties-producer = Виробник PDF:
+pdfjs-document-properties-version = ВерÑÑ–Ñ PDF:
+pdfjs-document-properties-page-count = КількіÑÑ‚ÑŒ Ñторінок:
+pdfjs-document-properties-page-size = Розмір Ñторінки:
+pdfjs-document-properties-page-size-unit-inches = дюймів
+pdfjs-document-properties-page-size-unit-millimeters = мм
+pdfjs-document-properties-page-size-orientation-portrait = книжкова
+pdfjs-document-properties-page-size-orientation-landscape = альбомна
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Швидкий переглÑд в Інтернеті:
+pdfjs-document-properties-linearized-yes = Так
+pdfjs-document-properties-linearized-no = ÐÑ–
+pdfjs-document-properties-close-button = Закрити
+
+## Print
+
+pdfjs-print-progress-message = Підготовка документу до друку…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = СкаÑувати
+pdfjs-printing-not-supported = ПопередженнÑ: Цей браузер не повніÑÑ‚ÑŽ підтримує друк.
+pdfjs-printing-not-ready = ПопередженнÑ: PDF не повніÑÑ‚ÑŽ завантажений Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÑƒ.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Бічна панель
+pdfjs-toggle-sidebar-notification-button =
+ .title = Перемкнути бічну панель (документ міÑтить еÑкіз/вкладеннÑ/шари)
+pdfjs-toggle-sidebar-button-label = Перемкнути бічну панель
+pdfjs-document-outline-button =
+ .title = Показати Ñхему документу (подвійний клік Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ/Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ñ–Ð²)
+pdfjs-document-outline-button-label = Схема документа
+pdfjs-attachments-button =
+ .title = Показати прикріпленнÑ
+pdfjs-attachments-button-label = ПрикріпленнÑ
+pdfjs-layers-button =
+ .title = Показати шари (двічі клацніть, щоб Ñкинути вÑÑ– шари до типового Ñтану)
+pdfjs-layers-button-label = Шари
+pdfjs-thumbs-button =
+ .title = Показувати еÑкізи
+pdfjs-thumbs-button-label = ЕÑкізи
+pdfjs-current-outline-item-button =
+ .title = Знайти поточний елемент зміÑту
+pdfjs-current-outline-item-button-label = Поточний елемент зміÑту
+pdfjs-findbar-button =
+ .title = Знайти в документі
+pdfjs-findbar-button-label = Знайти
+pdfjs-additional-layers = Додаткові шари
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Сторінка { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = ЕÑкіз Ñторінки { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Знайти
+ .placeholder = Знайти в документі…
+pdfjs-find-previous-button =
+ .title = Знайти попереднє Ð²Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ñ„Ñ€Ð°Ð·Ð¸
+pdfjs-find-previous-button-label = Попереднє
+pdfjs-find-next-button =
+ .title = Знайти наÑтупне Ð²Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ñ„Ñ€Ð°Ð·Ð¸
+pdfjs-find-next-button-label = ÐаÑтупне
+pdfjs-find-highlight-checkbox = ПідÑвітити вÑе
+pdfjs-find-match-case-checkbox-label = З урахуваннÑм регіÑтру
+pdfjs-find-match-diacritics-checkbox-label = ВідповідніÑÑ‚ÑŒ діакритичних знаків
+pdfjs-find-entire-word-checkbox-label = Цілі Ñлова
+pdfjs-find-reached-top = ДоÑÑгнуто початку документу, продовжено з кінцÑ
+pdfjs-find-reached-bottom = ДоÑÑгнуто ÐºÑ–Ð½Ñ†Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñƒ, продовжено з початку
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count =
+ { $total ->
+ [one] { $current } збіг з { $total }
+ [few] { $current } збіги з { $total }
+ *[many] { $current } збігів з { $total }
+ }
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit =
+ { $limit ->
+ [one] Понад { $limit } збіг
+ [few] Понад { $limit } збіги
+ *[many] Понад { $limit } збігів
+ }
+pdfjs-find-not-found = Фразу не знайдено
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = За шириною
+pdfjs-page-scale-fit = ВміÑтити
+pdfjs-page-scale-auto = ÐвтомаÑштаб
+pdfjs-page-scale-actual = ДійÑний розмір
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Сторінка { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ PDF ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°.
+pdfjs-invalid-file-error = ÐедійÑний або пошкоджений PDF-файл.
+pdfjs-missing-file-error = ВідÑутній PDF-файл.
+pdfjs-unexpected-response-error = Ðеочікувана відповідь Ñервера.
+pdfjs-rendering-error = Під Ñ‡Ð°Ñ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñторінки ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type }-анотаціÑ]
+
+## Password
+
+pdfjs-password-label = Введіть пароль Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ†ÑŒÐ¾Ð³Ð¾ PDF-файла.
+pdfjs-password-invalid = Ðевірний пароль. Спробуйте ще.
+pdfjs-password-ok-button = Гаразд
+pdfjs-password-cancel-button = СкаÑувати
+pdfjs-web-fonts-disabled = Веб-шрифти вимкнено: неможливо викориÑтати вбудовані у PDF шрифти.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = ТекÑÑ‚
+pdfjs-editor-free-text-button-label = ТекÑÑ‚
+pdfjs-editor-ink-button =
+ .title = Малювати
+pdfjs-editor-ink-button-label = Малювати
+pdfjs-editor-stamp-button =
+ .title = Додати чи редагувати зображеннÑ
+pdfjs-editor-stamp-button-label = Додати чи редагувати зображеннÑ
+pdfjs-editor-remove-button =
+ .title = Вилучити
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Вилучити малюнок
+pdfjs-editor-remove-freetext-button =
+ .title = Вилучити текÑÑ‚
+pdfjs-editor-remove-stamp-button =
+ .title = Вилучити зображеннÑ
+pdfjs-editor-remove-highlight-button =
+ .title = Вилучити підÑвічуваннÑ
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = Колір
+pdfjs-editor-free-text-size-input = Розмір
+pdfjs-editor-ink-color-input = Колір
+pdfjs-editor-ink-thickness-input = Товщина
+pdfjs-editor-ink-opacity-input = ПрозоріÑÑ‚ÑŒ
+pdfjs-editor-stamp-add-image-button =
+ .title = Додати зображеннÑ
+pdfjs-editor-stamp-add-image-button-label = Додати зображеннÑ
+pdfjs-free-text =
+ .aria-label = ТекÑтовий редактор
+pdfjs-free-text-default-content = Почніть вводити…
+pdfjs-ink =
+ .aria-label = Графічний редактор
+pdfjs-ink-canvas =
+ .aria-label = ЗображеннÑ, Ñтворене кориÑтувачем
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Ðльтернативний текÑÑ‚
+pdfjs-editor-alt-text-edit-button-label = Змінити альтернативний текÑÑ‚
+pdfjs-editor-alt-text-dialog-label = Вибрати варіант
+pdfjs-editor-alt-text-dialog-description = Ðльтернативний текÑÑ‚ допомагає, коли Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ видно або коли воно не завантажуєтьÑÑ.
+pdfjs-editor-alt-text-add-description-label = Додати опиÑ
+pdfjs-editor-alt-text-add-description-description = ÐамагайтеÑÑ Ñтворити 1-2 реченнÑ, Ñкі опиÑують тему, обÑтавини або дії.
+pdfjs-editor-alt-text-mark-decorative-label = Позначити декоративним
+pdfjs-editor-alt-text-mark-decorative-description = ВикориÑтовуєтьÑÑ Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð¸Ñ… зображень, наприклад рамок або водÑних знаків.
+pdfjs-editor-alt-text-cancel-button = СкаÑувати
+pdfjs-editor-alt-text-save-button = Зберегти
+pdfjs-editor-alt-text-decorative-tooltip = Позначено декоративним
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Ðаприклад, “Молодий чоловік Ñідає за Ñтіл Ñ—Ñтиâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Верхній лівий кут — зміна розміру
+pdfjs-editor-resizer-label-top-middle = Вгорі поÑередині — зміна розміру
+pdfjs-editor-resizer-label-top-right = Верхній правий кут — зміна розміру
+pdfjs-editor-resizer-label-middle-right = Праворуч поÑередині — зміна розміру
+pdfjs-editor-resizer-label-bottom-right = Ðижній правий кут — зміна розміру
+pdfjs-editor-resizer-label-bottom-middle = Внизу поÑередині — зміна розміру
+pdfjs-editor-resizer-label-bottom-left = Ðижній лівий кут — зміна розміру
+pdfjs-editor-resizer-label-middle-left = Ліворуч поÑередині — зміна розміру
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Колір підÑвічуваннÑ
+pdfjs-editor-colorpicker-button =
+ .title = Змінити колір
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Вибір кольору
+pdfjs-editor-colorpicker-yellow =
+ .title = Жовтий
+pdfjs-editor-colorpicker-green =
+ .title = Зелений
+pdfjs-editor-colorpicker-blue =
+ .title = Блакитний
+pdfjs-editor-colorpicker-pink =
+ .title = Рожевий
+pdfjs-editor-colorpicker-red =
+ .title = Червоний
diff --git a/www/lib/pdfjs/modern/web/locale/ur/viewer.ftl b/www/lib/pdfjs/modern/web/locale/ur/viewer.ftl
new file mode 100644
index 000000000..c15f157e7
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/ur/viewer.ftl
@@ -0,0 +1,248 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = پچھلا صÙØÛ
+pdfjs-previous-button-label = پچھلا
+pdfjs-next-button =
+ .title = اگلا صÙØÛ
+pdfjs-next-button-label = آگے
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = صÙØÛ
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = { $pagesCount } کا
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } کا { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = باÛر زوم کریں
+pdfjs-zoom-out-button-label = باÛر زوم کریں
+pdfjs-zoom-in-button =
+ .title = اندر زوم کریں
+pdfjs-zoom-in-button-label = اندر زوم کریں
+pdfjs-zoom-select =
+ .title = زوم
+pdfjs-presentation-mode-button =
+ .title = پیشکش موڈ میں چلے جائیں
+pdfjs-presentation-mode-button-label = پیشکش موڈ
+pdfjs-open-file-button =
+ .title = مسل کھولیں
+pdfjs-open-file-button-label = کھولیں
+pdfjs-print-button =
+ .title = چھاپیں
+pdfjs-print-button-label = چھاپیں
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = آلات
+pdfjs-tools-button-label = آلات
+pdfjs-first-page-button =
+ .title = Ù¾ÛÙ„Û’ صÙØÛ Ù¾Ø± جائیں
+pdfjs-first-page-button-label = Ù¾ÛÙ„Û’ صÙØÛ Ù¾Ø± جائیں
+pdfjs-last-page-button =
+ .title = آخری صÙØÛ Ù¾Ø± جائیں
+pdfjs-last-page-button-label = آخری صÙØÛ Ù¾Ø± جائیں
+pdfjs-page-rotate-cw-button =
+ .title = گھڑی وار گھمائیں
+pdfjs-page-rotate-cw-button-label = گھڑی وار گھمائیں
+pdfjs-page-rotate-ccw-button =
+ .title = ضد گھڑی وار گھمائیں
+pdfjs-page-rotate-ccw-button-label = ضد گھڑی وار گھمائیں
+pdfjs-cursor-text-select-tool-button =
+ .title = متن Ú©Û’ انتخاب Ú©Û’ ٹول Ú©Ùˆ Ùعال بناے
+pdfjs-cursor-text-select-tool-button-label = متن Ú©Û’ انتخاب کا آلÛ
+pdfjs-cursor-hand-tool-button =
+ .title = Ûینڈ ٹول Ú©Ùˆ Ùعال بناییں
+pdfjs-cursor-hand-tool-button-label = Ûاتھ کا آلÛ
+pdfjs-scroll-vertical-button =
+ .title = عمودی اسکرولنگ کا استعمال کریں
+pdfjs-scroll-vertical-button-label = عمودی اسکرولنگ
+pdfjs-scroll-horizontal-button =
+ .title = اÙÙ‚ÛŒ سکرولنگ کا استعمال کریں
+pdfjs-scroll-horizontal-button-label = اÙÙ‚ÛŒ سکرولنگ
+pdfjs-spread-none-button =
+ .title = صÙØÛ Ù¾Ú¾ÛŒÙ„Ø§Ù†Û’ میں شامل Ù†Û ÛÙˆÚº
+pdfjs-spread-none-button-label = کوئی پھیلاؤ Ù†Ûیں
+pdfjs-spread-odd-button-label = تاک پھیلاؤ
+pdfjs-spread-even-button-label = جÙت پھیلاؤ
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = دستاویز خواص…
+pdfjs-document-properties-button-label = دستاویز خواص…
+pdfjs-document-properties-file-name = نام مسل:
+pdfjs-document-properties-file-size = مسل سائز:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = عنوان:
+pdfjs-document-properties-author = تخلیق کار:
+pdfjs-document-properties-subject = موضوع:
+pdfjs-document-properties-keywords = کلیدی الÙاظ:
+pdfjs-document-properties-creation-date = تخلیق کی تاریخ:
+pdfjs-document-properties-modification-date = ترمیم کی تاریخ:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }، { $time }
+pdfjs-document-properties-creator = تخلیق کار:
+pdfjs-document-properties-producer = PDF پیدا کار:
+pdfjs-document-properties-version = PDF ورژن:
+pdfjs-document-properties-page-count = صÙØÛ Ø´Ù…Ø§Ø±:
+pdfjs-document-properties-page-size = صÙÛ Ú©ÛŒ لمبائ:
+pdfjs-document-properties-page-size-unit-inches = میں
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = عمودی انداز
+pdfjs-document-properties-page-size-orientation-landscape = اÙقى انداز
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = خط
+pdfjs-document-properties-page-size-name-legal = قانونی
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } { $name } { $orientation }
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = تیز ویب دیکھیں:
+pdfjs-document-properties-linearized-yes = Ûاں
+pdfjs-document-properties-linearized-no = Ù†Ûیں
+pdfjs-document-properties-close-button = بند کریں
+
+## Print
+
+pdfjs-print-progress-message = چھاپنے کرنے کے لیے دستاویز تیار کیے جا رھے ھیں
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = *{ $progress }%*
+pdfjs-print-progress-close-button = منسوخ کریں
+pdfjs-printing-not-supported = تنبیÛ:چھاپنا اس براؤزر پر پوری Ø·Ø±Ø Ù…Ø¹Ø§ÙˆÙ†Øª Ø´Ø¯Û Ù†Ûیں ÛÛ’Û”
+pdfjs-printing-not-ready = تنبیÛ: PDF چھپائی Ú©Û’ لیے پوری Ø·Ø±Ø Ù„ÙˆÚˆ Ù†Ûیں Ûوئی۔
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = سلائیڈ ٹوگل کریں
+pdfjs-toggle-sidebar-button-label = سلائیڈ ٹوگل کریں
+pdfjs-document-outline-button =
+ .title = دستاویز کی سرخیاں دکھایں (تمام اشیاء وسیع / غائب کرنے کے لیے ڈبل کلک کریں)
+pdfjs-document-outline-button-label = دستاویز آؤٹ لائن
+pdfjs-attachments-button =
+ .title = منسلکات دکھائیں
+pdfjs-attachments-button-label = منسلکات
+pdfjs-thumbs-button =
+ .title = تھمبنیل دکھائیں
+pdfjs-thumbs-button-label = مجمل
+pdfjs-findbar-button =
+ .title = دستاویز میں ڈھونڈیں
+pdfjs-findbar-button-label = ڈھونڈیں
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = صÙØÛ { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = صÙØÛ’ کا مجمل { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = ڈھونڈیں
+ .placeholder = دستاویز… میں ڈھونڈیں
+pdfjs-find-previous-button =
+ .title = Ùقرے کا پچھلا وقوع ڈھونڈیں
+pdfjs-find-previous-button-label = پچھلا
+pdfjs-find-next-button =
+ .title = Ùقرے کا Ø§Ú¯Ù„Û ÙˆÙ‚ÙˆØ¹ ڈھونڈیں
+pdfjs-find-next-button-label = آگے
+pdfjs-find-highlight-checkbox = تمام نمایاں کریں
+pdfjs-find-match-case-checkbox-label = ØØ±ÙˆÙ Ù…Ø´Ø§Ø¨Û Ú©Ø±ÛŒÚº
+pdfjs-find-entire-word-checkbox-label = تمام الÙاظ
+pdfjs-find-reached-top = صÙØÛ Ú©Û’ شروع پر Ù¾ÛÙ†Ú† گیا، نیچے سے جاری کیا
+pdfjs-find-reached-bottom = صÙØÛ Ú©Û’ اختتام پر Ù¾ÛÙ†Ú† گیا، اوپر سے جاری کیا
+pdfjs-find-not-found = Ùقرا Ù†Ûیں ملا
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = صÙØÛ Ú†ÙˆÚ‘Ø§Ø¦ÛŒ
+pdfjs-page-scale-fit = صÙØÛ Ùٹنگ
+pdfjs-page-scale-auto = خودکار زوم
+pdfjs-page-scale-actual = اصل سائز
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = صÙØÛ { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF لوڈ کرتے وقت نقص آ گیا۔
+pdfjs-invalid-file-error = ناجائز یا خراب PDF مسل
+pdfjs-missing-file-error = PDF مسل غائب ÛÛ’Û”
+pdfjs-unexpected-response-error = غیرمتوقع پیش کار جواب
+pdfjs-rendering-error = صÙØÛ Ø¨Ù†Ø§ØªÛ’ Ûوئے نقص Ø¢ گیا۔
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }.{ $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } نوٹ]
+
+## Password
+
+pdfjs-password-label = PDF مسل کھولنے کے لیے پاس ورڈ داخل کریں.
+pdfjs-password-invalid = ناجائز پاس ورڈ. براےؑ کرم Ø¯ÙˆØ¨Ø§Ø±Û Ú©ÙˆØ´Ø´ کریں.
+pdfjs-password-ok-button = ٹھیک ÛÛ’
+pdfjs-password-cancel-button = منسوخ کریں
+pdfjs-web-fonts-disabled = ویب Ùانٹ نا اÛÙ„ Ûیں: شامل PDF Ùانٹ استعمال کرنے میں ناکام۔
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/uz/viewer.ftl b/www/lib/pdfjs/modern/web/locale/uz/viewer.ftl
new file mode 100644
index 000000000..fb82f22d4
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/uz/viewer.ftl
@@ -0,0 +1,187 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Oldingi sahifa
+pdfjs-previous-button-label = Oldingi
+pdfjs-next-button =
+ .title = Keyingi sahifa
+pdfjs-next-button-label = Keyingi
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = /{ $pagesCount }
+pdfjs-zoom-out-button =
+ .title = Kichiklashtirish
+pdfjs-zoom-out-button-label = Kichiklashtirish
+pdfjs-zoom-in-button =
+ .title = Kattalashtirish
+pdfjs-zoom-in-button-label = Kattalashtirish
+pdfjs-zoom-select =
+ .title = Masshtab
+pdfjs-presentation-mode-button =
+ .title = Namoyish usuliga oʻtish
+pdfjs-presentation-mode-button-label = Namoyish usuli
+pdfjs-open-file-button =
+ .title = Faylni ochish
+pdfjs-open-file-button-label = Ochish
+pdfjs-print-button =
+ .title = Chop qilish
+pdfjs-print-button-label = Chop qilish
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Vositalar
+pdfjs-tools-button-label = Vositalar
+pdfjs-first-page-button =
+ .title = Birinchi sahifaga oʻtish
+pdfjs-first-page-button-label = Birinchi sahifaga oʻtish
+pdfjs-last-page-button =
+ .title = Soʻnggi sahifaga oʻtish
+pdfjs-last-page-button-label = Soʻnggi sahifaga oʻtish
+pdfjs-page-rotate-cw-button =
+ .title = Soat yoʻnalishi boʻyicha burish
+pdfjs-page-rotate-cw-button-label = Soat yoʻnalishi boʻyicha burish
+pdfjs-page-rotate-ccw-button =
+ .title = Soat yoʻnalishiga qarshi burish
+pdfjs-page-rotate-ccw-button-label = Soat yoʻnalishiga qarshi burish
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Hujjat xossalari
+pdfjs-document-properties-button-label = Hujjat xossalari
+pdfjs-document-properties-file-name = Fayl nomi:
+pdfjs-document-properties-file-size = Fayl hajmi:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)
+pdfjs-document-properties-title = Nomi:
+pdfjs-document-properties-author = Muallifi:
+pdfjs-document-properties-subject = Mavzusi:
+pdfjs-document-properties-keywords = Kalit so‘zlar
+pdfjs-document-properties-creation-date = Yaratilgan sanasi:
+pdfjs-document-properties-modification-date = O‘zgartirilgan sanasi
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Yaratuvchi:
+pdfjs-document-properties-producer = PDF ishlab chiqaruvchi:
+pdfjs-document-properties-version = PDF versiyasi:
+pdfjs-document-properties-page-count = Sahifa soni:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = Yopish
+
+## Print
+
+pdfjs-printing-not-supported = Diqqat: chop qilish bruzer tomonidan toʻliq qoʻllab-quvvatlanmaydi.
+pdfjs-printing-not-ready = Diqqat: PDF fayl chop qilish uchun toʻliq yuklanmadi.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Yon panelni yoqib/oʻchirib qoʻyish
+pdfjs-toggle-sidebar-button-label = Yon panelni yoqib/oʻchirib qoʻyish
+pdfjs-document-outline-button-label = Hujjat tuzilishi
+pdfjs-attachments-button =
+ .title = Ilovalarni ko‘rsatish
+pdfjs-attachments-button-label = Ilovalar
+pdfjs-thumbs-button =
+ .title = Nishonchalarni koʻrsatish
+pdfjs-thumbs-button-label = Nishoncha
+pdfjs-findbar-button =
+ .title = Hujjat ichidan topish
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = { $page } sahifa
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = { $page } sahifa nishonchasi
+
+## Find panel button title and messages
+
+pdfjs-find-previous-button =
+ .title = Soʻzlardagi oldingi hodisani topish
+pdfjs-find-previous-button-label = Oldingi
+pdfjs-find-next-button =
+ .title = Iboradagi keyingi hodisani topish
+pdfjs-find-next-button-label = Keyingi
+pdfjs-find-highlight-checkbox = Barchasini ajratib koʻrsatish
+pdfjs-find-match-case-checkbox-label = Katta-kichik harflarni farqlash
+pdfjs-find-reached-top = Hujjatning boshigacha yetib keldik, pastdan davom ettiriladi
+pdfjs-find-reached-bottom = Hujjatning oxiriga yetib kelindi, yuqoridan davom ettirladi
+pdfjs-find-not-found = Soʻzlar topilmadi
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Sahifa eni
+pdfjs-page-scale-fit = Sahifani moslashtirish
+pdfjs-page-scale-auto = Avtomatik masshtab
+pdfjs-page-scale-actual = Haqiqiy hajmi
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = PDF yuklanayotganda xato yuz berdi.
+pdfjs-invalid-file-error = Xato yoki buzuq PDF fayli.
+pdfjs-missing-file-error = PDF fayl kerak.
+pdfjs-unexpected-response-error = Kutilmagan server javobi.
+pdfjs-rendering-error = Sahifa renderlanayotganda xato yuz berdi.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Annotation]
+
+## Password
+
+pdfjs-password-label = PDF faylni ochish uchun parolni kiriting.
+pdfjs-password-invalid = Parol - notoʻgʻri. Qaytadan urinib koʻring.
+pdfjs-password-ok-button = OK
+pdfjs-web-fonts-disabled = Veb shriftlar oʻchirilgan: ichki PDF shriftlardan foydalanib boʻlmmaydi.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/vi/viewer.ftl b/www/lib/pdfjs/modern/web/locale/vi/viewer.ftl
new file mode 100644
index 000000000..9f66aad34
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/vi/viewer.ftl
@@ -0,0 +1,376 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Trang trÆ°á»›c
+pdfjs-previous-button-label = TrÆ°á»›c
+pdfjs-next-button =
+ .title = Trang Sau
+pdfjs-next-button-label = Tiếp
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Trang
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = trên { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } trên { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Thu nhá»
+pdfjs-zoom-out-button-label = Thu nhá»
+pdfjs-zoom-in-button =
+ .title = Phóng to
+pdfjs-zoom-in-button-label = Phóng to
+pdfjs-zoom-select =
+ .title = Thu phóng
+pdfjs-presentation-mode-button =
+ .title = Chuyển sang chế độ trình chiếu
+pdfjs-presentation-mode-button-label = Chế độ trình chiếu
+pdfjs-open-file-button =
+ .title = Mở táºp tin
+pdfjs-open-file-button-label = Mở táºp tin
+pdfjs-print-button =
+ .title = In
+pdfjs-print-button-label = In
+pdfjs-save-button =
+ .title = LÆ°u
+pdfjs-save-button-label = LÆ°u
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = Tải xuống
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = Tải xuống
+pdfjs-bookmark-button =
+ .title = Trang hiện tại (xem URL từ trang hiện tại)
+pdfjs-bookmark-button-label = Trang hiện tại
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = Mở trong ứng dụng
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = Mở trong ứng dụng
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Công cụ
+pdfjs-tools-button-label = Công cụ
+pdfjs-first-page-button =
+ .title = VỠtrang đầu
+pdfjs-first-page-button-label = VỠtrang đầu
+pdfjs-last-page-button =
+ .title = Äến trang cuối
+pdfjs-last-page-button-label = Äến trang cuối
+pdfjs-page-rotate-cw-button =
+ .title = Xoay theo chiá»u kim đồng hồ
+pdfjs-page-rotate-cw-button-label = Xoay theo chiá»u kim đồng hồ
+pdfjs-page-rotate-ccw-button =
+ .title = Xoay ngược chiá»u kim đồng hồ
+pdfjs-page-rotate-ccw-button-label = Xoay ngược chiá»u kim đồng hồ
+pdfjs-cursor-text-select-tool-button =
+ .title = KÃch hoạt công cụ chá»n vùng văn bản
+pdfjs-cursor-text-select-tool-button-label = Công cụ chá»n vùng văn bản
+pdfjs-cursor-hand-tool-button =
+ .title = KÃch hoạt công cụ con trá»
+pdfjs-cursor-hand-tool-button-label = Công cụ con trá»
+pdfjs-scroll-page-button =
+ .title = SỠdụng cuộn trang hiện tại
+pdfjs-scroll-page-button-label = Cuộn trang hiện tại
+pdfjs-scroll-vertical-button =
+ .title = Sá» dụng cuá»™n dá»c
+pdfjs-scroll-vertical-button-label = Cuá»™n dá»c
+pdfjs-scroll-horizontal-button =
+ .title = SỠdụng cuộn ngang
+pdfjs-scroll-horizontal-button-label = Cuá»™n ngang
+pdfjs-scroll-wrapped-button =
+ .title = SỠdụng cuộn ngắt dòng
+pdfjs-scroll-wrapped-button-label = Cuộn ngắt dòng
+pdfjs-spread-none-button =
+ .title = Không nối rộng trang
+pdfjs-spread-none-button-label = Không có phân cách
+pdfjs-spread-odd-button =
+ .title = Nối trang bà i bắt đầu với các trang được đánh số lẻ
+pdfjs-spread-odd-button-label = Phân cách theo số lẻ
+pdfjs-spread-even-button =
+ .title = Nối trang bà i bắt đầu với các trang được đánh số chẵn
+pdfjs-spread-even-button-label = Phân cách theo số chẵn
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Thuá»™c tÃnh của tà i liệu…
+pdfjs-document-properties-button-label = Thuá»™c tÃnh của tà i liệu…
+pdfjs-document-properties-file-name = Tên táºp tin:
+pdfjs-document-properties-file-size = KÃch thÆ°á»›c:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } byte)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } byte)
+pdfjs-document-properties-title = Tiêu Ä‘á»:
+pdfjs-document-properties-author = Tác giả:
+pdfjs-document-properties-subject = Chủ Ä‘á»:
+pdfjs-document-properties-keywords = Từ khóa:
+pdfjs-document-properties-creation-date = Ngà y tạo:
+pdfjs-document-properties-modification-date = Ngà y sá»a đổi:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = NgÆ°á»i tạo:
+pdfjs-document-properties-producer = Phần má»m tạo PDF:
+pdfjs-document-properties-version = Phiên bản PDF:
+pdfjs-document-properties-page-count = Tổng số trang:
+pdfjs-document-properties-page-size = KÃch thÆ°á»›c trang:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = khổ dá»c
+pdfjs-document-properties-page-size-orientation-landscape = khổ ngang
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = ThÆ°
+pdfjs-document-properties-page-size-name-legal = Pháp lý
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit } ({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit } ({ $name }, { $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = Xem nhanh trên web:
+pdfjs-document-properties-linearized-yes = Có
+pdfjs-document-properties-linearized-no = Không
+pdfjs-document-properties-close-button = Ãóng
+
+## Print
+
+pdfjs-print-progress-message = Chuẩn bị trang để in…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Hủy bá»
+pdfjs-printing-not-supported = Cảnh báo: In ấn không được hỗ trợ đầy đủ ở trình duyệt nà y.
+pdfjs-printing-not-ready = Cảnh báo: PDF chưa được tải hết để in.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Báºt/Tắt thanh lá»
+pdfjs-toggle-sidebar-notification-button =
+ .title = Báºt tắt thanh lá» (tà i liệu bao gồm bản phác thảo/táºp tin Ä‘Ãnh kèm/lá»›p)
+pdfjs-toggle-sidebar-button-label = Báºt/Tắt thanh lá»
+pdfjs-document-outline-button =
+ .title = Hiển thị tà i liệu phác thảo (nhấp đúp và o để mở rá»™ng/thu gá»n tất cả các mục)
+pdfjs-document-outline-button-label = Bản phác tà i liệu
+pdfjs-attachments-button =
+ .title = Hiện ná»™i dung Ä‘Ãnh kèm
+pdfjs-attachments-button-label = Ná»™i dung Ä‘Ãnh kèm
+pdfjs-layers-button =
+ .title = Hiển thị các lớp (nhấp đúp để đặt lại tất cả các lớp vỠtrạng thái mặc định)
+pdfjs-layers-button-label = Lá»›p
+pdfjs-thumbs-button =
+ .title = Hiển thị ảnh thu nhá»
+pdfjs-thumbs-button-label = Ảnh thu nhá»
+pdfjs-current-outline-item-button =
+ .title = Tìm mục phác thảo hiện tại
+pdfjs-current-outline-item-button-label = Mục phác thảo hiện tại
+pdfjs-findbar-button =
+ .title = Tìm trong tà i liệu
+pdfjs-findbar-button-label = Tìm
+pdfjs-additional-layers = Các lớp bổ sung
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Trang { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Ảnh thu nhỠcủa trang { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Tìm
+ .placeholder = Tìm trong tà i liệu…
+pdfjs-find-previous-button =
+ .title = Tìm cụm từ ở phần trước
+pdfjs-find-previous-button-label = TrÆ°á»›c
+pdfjs-find-next-button =
+ .title = Tìm cụm từ ở phần sau
+pdfjs-find-next-button-label = Tiếp
+pdfjs-find-highlight-checkbox = Tô sáng tất cả
+pdfjs-find-match-case-checkbox-label = Phân biệt hoa, thÆ°á»ng
+pdfjs-find-match-diacritics-checkbox-label = Khớp dấu phụ
+pdfjs-find-entire-word-checkbox-label = Toà n bộ từ
+pdfjs-find-reached-top = Äã đến phần đầu tà i liệu, quay trở lại từ cuối
+pdfjs-find-reached-bottom = Äã đến phần cuối của tà i liệu, quay trở lại từ đầu
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = { $current } trên { $total } kết quả
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit = Tìm thấy hơn { $limit } kết quả
+pdfjs-find-not-found = Không tìm thấy cụm từ nà y
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Vừa chiá»u rá»™ng
+pdfjs-page-scale-fit = Vừa chiá»u cao
+pdfjs-page-scale-auto = Tá»± Ä‘á»™ng chá»n kÃch thÆ°á»›c
+pdfjs-page-scale-actual = KÃch thÆ°á»›c thá»±c
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = Trang { $page }
+
+## Loading indicator messages
+
+pdfjs-loading-error = Lỗi khi tải tà i liệu PDF.
+pdfjs-invalid-file-error = Táºp tin PDF há»ng hoặc không hợp lệ.
+pdfjs-missing-file-error = Thiếu táºp tin PDF.
+pdfjs-unexpected-response-error = Máy chủ có phản hồi lạ.
+pdfjs-rendering-error = Lỗi khi hiển thị trang.
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date }, { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Chú thÃch]
+
+## Password
+
+pdfjs-password-label = Nháºp máºt khẩu để mở táºp tin PDF nà y.
+pdfjs-password-invalid = Máºt khẩu không đúng. Vui lòng thá» lại.
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Hủy bá»
+pdfjs-web-fonts-disabled = Phông chữ Web bị vô hiệu hóa: không thể sỠdụng các phông chữ PDF được nhúng.
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = Văn bản
+pdfjs-editor-free-text-button-label = Văn bản
+pdfjs-editor-ink-button =
+ .title = Vẽ
+pdfjs-editor-ink-button-label = Vẽ
+pdfjs-editor-stamp-button =
+ .title = Thêm hoặc chỉnh sá»a hình ảnh
+pdfjs-editor-stamp-button-label = Thêm hoặc chỉnh sá»a hình ảnh
+pdfjs-editor-remove-button =
+ .title = Xóa
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = Xóa bản vẽ
+pdfjs-editor-remove-freetext-button =
+ .title = Xóa văn bản
+pdfjs-editor-remove-stamp-button =
+ .title = Xóa ảnh
+pdfjs-editor-remove-highlight-button =
+ .title = Xóa phần đánh dấu
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = MÃ u
+pdfjs-editor-free-text-size-input = KÃch cỡ
+pdfjs-editor-ink-color-input = MÃ u
+pdfjs-editor-ink-thickness-input = Äá»™ dà y
+pdfjs-editor-ink-opacity-input = Äộ mÆ¡Ì€
+pdfjs-editor-stamp-add-image-button =
+ .title = Thêm hình ảnh
+pdfjs-editor-stamp-add-image-button-label = Thêm hình ảnh
+pdfjs-free-text =
+ .aria-label = Trình sá»a văn bản
+pdfjs-free-text-default-content = Bắt đầu nháºp…
+pdfjs-ink =
+ .aria-label = Trình sá»a nét vẽ
+pdfjs-ink-canvas =
+ .aria-label = Hình ảnh do ngÆ°á»i dùng tạo
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = Văn bản thay thế
+pdfjs-editor-alt-text-edit-button-label = Chỉnh sá»a văn bản thay thế
+pdfjs-editor-alt-text-dialog-label = Chá»n má»™t lá»±a chá»n
+pdfjs-editor-alt-text-dialog-description = Văn bản thay thế sẽ hữu Ãch khi má»i ngÆ°á»i không thể thấy hình ảnh hoặc khi hình ảnh không tải.
+pdfjs-editor-alt-text-add-description-label = Thêm một mô tả
+pdfjs-editor-alt-text-add-description-description = Hãy nhắm tá»›i 1-2 câu mô tả chủ Ä‘á», bối cảnh hoặc hà nh Ä‘á»™ng.
+pdfjs-editor-alt-text-mark-decorative-label = Äánh dấu là trang trÃ
+pdfjs-editor-alt-text-mark-decorative-description = Äiá»u nà y được sá» dụng cho các hình ảnh trang trÃ, nhÆ° Ä‘Æ°á»ng viá»n hoặc watermark.
+pdfjs-editor-alt-text-cancel-button = Hủy bá»
+pdfjs-editor-alt-text-save-button = LÆ°u
+pdfjs-editor-alt-text-decorative-tooltip = Äã đánh dấu là trang trÃ
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = Và dụ: “Má»™t thanh niên ngồi xuống bà n để thưởng thức má»™t bữa ănâ€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = Trên cùng bên trái — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-top-middle = Trên cùng ở giữa — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-top-right = Trên cùng bên phải — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-middle-right = Ở giữa bên phải — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-bottom-right = DÆ°á»›i cùng bên phải — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-bottom-middle = Ở giữa dÆ°á»›i cùng — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-bottom-left = Góc dÆ°á»›i bên trái — thay đổi kÃch thÆ°á»›c
+pdfjs-editor-resizer-label-middle-left = Ở giữa bên trái — thay đổi kÃch thÆ°á»›c
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = Mà u đánh dấu
+pdfjs-editor-colorpicker-button =
+ .title = Thay đổi mà u
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = Lá»±a chá»n mà u sắc
+pdfjs-editor-colorpicker-yellow =
+ .title = VÃ ng
+pdfjs-editor-colorpicker-green =
+ .title = Xanh lục
+pdfjs-editor-colorpicker-blue =
+ .title = Xanh dÆ°Æ¡ng
+pdfjs-editor-colorpicker-pink =
+ .title = Hồng
+pdfjs-editor-colorpicker-red =
+ .title = Äá»
diff --git a/www/lib/pdfjs/modern/web/locale/wo/viewer.ftl b/www/lib/pdfjs/modern/web/locale/wo/viewer.ftl
new file mode 100644
index 000000000..d66c4591f
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/wo/viewer.ftl
@@ -0,0 +1,127 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Xët wi jiitu
+pdfjs-previous-button-label = Bi jiitu
+pdfjs-next-button =
+ .title = Xët wi ci topp
+pdfjs-next-button-label = Bi ci topp
+pdfjs-zoom-out-button =
+ .title = Wà ññi
+pdfjs-zoom-out-button-label = Wà ññi
+pdfjs-zoom-in-button =
+ .title = Yaatal
+pdfjs-zoom-in-button-label = Yaatal
+pdfjs-zoom-select =
+ .title = Yambalaŋ
+pdfjs-presentation-mode-button =
+ .title = Wañarñil ci anamu wone
+pdfjs-presentation-mode-button-label = Anamu Wone
+pdfjs-open-file-button =
+ .title = Ubbi benn dencukaay
+pdfjs-open-file-button-label = Ubbi
+pdfjs-print-button =
+ .title = Móol
+pdfjs-print-button-label = Móol
+
+## Secondary toolbar and context menu
+
+
+## Document properties dialog
+
+pdfjs-document-properties-title = Bopp:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+
+## Print
+
+pdfjs-printing-not-supported = Artu: Joowkat bii nanguwul lool mool.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-thumbs-button =
+ .title = Wone nataal yu ndaw yi
+pdfjs-thumbs-button-label = Nataal yu ndaw yi
+pdfjs-findbar-button =
+ .title = Gis ci biir jukki bi
+pdfjs-findbar-button-label = Wut
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Xët { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Wiñet bu xët { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-previous-button =
+ .title = Seet beneen kaddu bu ni mel te jiitu
+pdfjs-find-previous-button-label = Bi jiitu
+pdfjs-find-next-button =
+ .title = Seet beneen kaddu bu ni mel
+pdfjs-find-next-button-label = Bi ci topp
+pdfjs-find-highlight-checkbox = Melaxal lépp
+pdfjs-find-match-case-checkbox-label = Sà mm jëmmalin wi
+pdfjs-find-reached-top = Jot nañu ndorteel xët wi, kontine dale ko ci suuf
+pdfjs-find-reached-bottom = Jot nañu jeexitalu xët wi, kontine ci ndorte
+pdfjs-find-not-found = Gisiñu kaddu gi
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Yaatuwaay bu mët
+pdfjs-page-scale-fit = Xët lëmm
+pdfjs-page-scale-auto = Yambalaŋ ci saa si
+pdfjs-page-scale-actual = Dayo bi am
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Am na njumte ci yebum dencukaay PDF bi.
+pdfjs-invalid-file-error = Dencukaay PDF bi baaxul walla mu sankar.
+pdfjs-rendering-error = Am njumte bu am bi xët bi di wonewu.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [Karmat { $type }]
+
+## Password
+
+pdfjs-password-ok-button = OK
+pdfjs-password-cancel-button = Neenal
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/xh/viewer.ftl b/www/lib/pdfjs/modern/web/locale/xh/viewer.ftl
new file mode 100644
index 000000000..079888733
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/xh/viewer.ftl
@@ -0,0 +1,212 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = Iphepha langaphambili
+pdfjs-previous-button-label = Okwangaphambili
+pdfjs-next-button =
+ .title = Iphepha elilandelayo
+pdfjs-next-button-label = Okulandelayo
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = Iphepha
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = kwali- { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } kwali { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = Bhekelisela Kudana
+pdfjs-zoom-out-button-label = Bhekelisela Kudana
+pdfjs-zoom-in-button =
+ .title = Sondeza Kufuphi
+pdfjs-zoom-in-button-label = Sondeza Kufuphi
+pdfjs-zoom-select =
+ .title = Yandisa / Nciphisa
+pdfjs-presentation-mode-button =
+ .title = Tshintshela kwimo yonikezelo
+pdfjs-presentation-mode-button-label = Imo yonikezelo
+pdfjs-open-file-button =
+ .title = Vula Ifayile
+pdfjs-open-file-button-label = Vula
+pdfjs-print-button =
+ .title = Printa
+pdfjs-print-button-label = Printa
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = Izixhobo zemiyalelo
+pdfjs-tools-button-label = Izixhobo zemiyalelo
+pdfjs-first-page-button =
+ .title = Yiya kwiphepha lokuqala
+pdfjs-first-page-button-label = Yiya kwiphepha lokuqala
+pdfjs-last-page-button =
+ .title = Yiya kwiphepha lokugqibela
+pdfjs-last-page-button-label = Yiya kwiphepha lokugqibela
+pdfjs-page-rotate-cw-button =
+ .title = Jikelisa ngasekunene
+pdfjs-page-rotate-cw-button-label = Jikelisa ngasekunene
+pdfjs-page-rotate-ccw-button =
+ .title = Jikelisa ngasekhohlo
+pdfjs-page-rotate-ccw-button-label = Jikelisa ngasekhohlo
+pdfjs-cursor-text-select-tool-button =
+ .title = Vumela iSixhobo sokuKhetha iTeksti
+pdfjs-cursor-text-select-tool-button-label = ISixhobo sokuKhetha iTeksti
+pdfjs-cursor-hand-tool-button =
+ .title = Yenza iSixhobo seSandla siSebenze
+pdfjs-cursor-hand-tool-button-label = ISixhobo seSandla
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = Iipropati zoxwebhu…
+pdfjs-document-properties-button-label = Iipropati zoxwebhu…
+pdfjs-document-properties-file-name = Igama lefayile:
+pdfjs-document-properties-file-size = Isayizi yefayile:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB (iibhayiti{ $size_b })
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB (iibhayithi{ $size_b })
+pdfjs-document-properties-title = Umxholo:
+pdfjs-document-properties-author = Umbhali:
+pdfjs-document-properties-subject = Umbandela:
+pdfjs-document-properties-keywords = Amagama aphambili:
+pdfjs-document-properties-creation-date = Umhla wokwenziwa kwayo:
+pdfjs-document-properties-modification-date = Umhla wokulungiswa kwayo:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = Umntu oyenzileyo:
+pdfjs-document-properties-producer = Umvelisi we-PDF:
+pdfjs-document-properties-version = Uhlelo lwe-PDF:
+pdfjs-document-properties-page-count = Inani lamaphepha:
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+
+##
+
+pdfjs-document-properties-close-button = Vala
+
+## Print
+
+pdfjs-print-progress-message = Ilungisa uxwebhu ukuze iprinte…
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = Rhoxisa
+pdfjs-printing-not-supported = Isilumkiso: Ukuprinta akuxhaswa ngokupheleleyo yile bhrawuza.
+pdfjs-printing-not-ready = Isilumkiso: IPDF ayihlohlwanga ngokupheleleyo ukwenzela ukuprinta.
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = Togola ngebha eseCaleni
+pdfjs-toggle-sidebar-button-label = Togola ngebha eseCaleni
+pdfjs-document-outline-button =
+ .title = Bonisa uLwandlalo loXwebhu (cofa kabini ukuze wandise/diliza zonke izinto)
+pdfjs-document-outline-button-label = Isishwankathelo soxwebhu
+pdfjs-attachments-button =
+ .title = Bonisa iziqhotyoshelwa
+pdfjs-attachments-button-label = Iziqhoboshelo
+pdfjs-thumbs-button =
+ .title = Bonisa ukrobiso kumfanekiso
+pdfjs-thumbs-button-label = Ukrobiso kumfanekiso
+pdfjs-findbar-button =
+ .title = Fumana kuXwebhu
+pdfjs-findbar-button-label = Fumana
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = Iphepha { $page }
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = Ukrobiso kumfanekiso wephepha { $page }
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = Fumana
+ .placeholder = Fumana kuXwebhu…
+pdfjs-find-previous-button =
+ .title = Fumanisa isenzeko sangaphambili sebinzana lamagama
+pdfjs-find-previous-button-label = Okwangaphambili
+pdfjs-find-next-button =
+ .title = Fumanisa isenzeko esilandelayo sebinzana lamagama
+pdfjs-find-next-button-label = Okulandelayo
+pdfjs-find-highlight-checkbox = Qaqambisa konke
+pdfjs-find-match-case-checkbox-label = Tshatisa ngobukhulu bukanobumba
+pdfjs-find-reached-top = Ufike ngaphezulu ephepheni, kusukwa ngezantsi
+pdfjs-find-reached-bottom = Ufike ekupheleni kwephepha, kusukwa ngaphezulu
+pdfjs-find-not-found = Ibinzana alifunyenwanga
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = Ububanzi bephepha
+pdfjs-page-scale-fit = Ukulinganiswa kwephepha
+pdfjs-page-scale-auto = Ukwandisa/Ukunciphisa Ngokwayo
+pdfjs-page-scale-actual = Ubungakanani bokwenene
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+
+## Loading indicator messages
+
+pdfjs-loading-error = Imposiso yenzekile xa kulayishwa i-PDF.
+pdfjs-invalid-file-error = Ifayile ye-PDF engeyiyo okanye eyonakalisiweyo.
+pdfjs-missing-file-error = Ifayile ye-PDF edukileyo.
+pdfjs-unexpected-response-error = Impendulo yeseva engalindelekanga.
+pdfjs-rendering-error = Imposiso yenzekile xa bekunikezelwa iphepha.
+
+## Annotations
+
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } Ubhalo-nqaku]
+
+## Password
+
+pdfjs-password-label = Faka ipasiwedi ukuze uvule le fayile yePDF.
+pdfjs-password-invalid = Ipasiwedi ayisebenzi. Nceda uzame kwakhona.
+pdfjs-password-ok-button = KULUNGILE
+pdfjs-password-cancel-button = Rhoxisa
+pdfjs-web-fonts-disabled = Iifonti zewebhu ziqhwalelisiwe: ayikwazi ukusebenzisa iifonti ze-PDF ezincanyathelisiweyo.
+
+## Editing
+
+
+## Alt-text dialog
+
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
diff --git a/www/lib/pdfjs/modern/web/locale/zh-CN/viewer.ftl b/www/lib/pdfjs/modern/web/locale/zh-CN/viewer.ftl
new file mode 100644
index 000000000..b204a83ee
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/zh-CN/viewer.ftl
@@ -0,0 +1,376 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = 上一页
+pdfjs-previous-button-label = 上一页
+pdfjs-next-button =
+ .title = 下一页
+pdfjs-next-button-label = 下一页
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = 页é¢
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = / { $pagesCount }
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = ({ $pageNumber } / { $pagesCount })
+pdfjs-zoom-out-button =
+ .title = 缩å°
+pdfjs-zoom-out-button-label = 缩å°
+pdfjs-zoom-in-button =
+ .title = 放大
+pdfjs-zoom-in-button-label = 放大
+pdfjs-zoom-select =
+ .title = 缩放
+pdfjs-presentation-mode-button =
+ .title = 切æ¢åˆ°æ¼”示模å¼
+pdfjs-presentation-mode-button-label = 演示模å¼
+pdfjs-open-file-button =
+ .title = 打开文件
+pdfjs-open-file-button-label = 打开
+pdfjs-print-button =
+ .title = 打å°
+pdfjs-print-button-label = 打å°
+pdfjs-save-button =
+ .title = ä¿å˜
+pdfjs-save-button-label = ä¿å˜
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = 下载
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = 下载
+pdfjs-bookmark-button =
+ .title = 当å‰é¡µé¢ï¼ˆåœ¨å½“å‰é¡µé¢æŸ¥çœ‹ URL)
+pdfjs-bookmark-button-label = 当å‰é¡µé¢
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = 在应用ä¸æ‰“å¼€
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = 在应用ä¸æ‰“å¼€
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = 工具
+pdfjs-tools-button-label = 工具
+pdfjs-first-page-button =
+ .title = 转到第一页
+pdfjs-first-page-button-label = 转到第一页
+pdfjs-last-page-button =
+ .title = 转到最åŽä¸€é¡µ
+pdfjs-last-page-button-label = 转到最åŽä¸€é¡µ
+pdfjs-page-rotate-cw-button =
+ .title = 顺时针旋转
+pdfjs-page-rotate-cw-button-label = 顺时针旋转
+pdfjs-page-rotate-ccw-button =
+ .title = 逆时针旋转
+pdfjs-page-rotate-ccw-button-label = 逆时针旋转
+pdfjs-cursor-text-select-tool-button =
+ .title = å¯ç”¨æ–‡æœ¬é€‰æ‹©å·¥å…·
+pdfjs-cursor-text-select-tool-button-label = 文本选择工具
+pdfjs-cursor-hand-tool-button =
+ .title = å¯ç”¨æ‰‹å½¢å·¥å…·
+pdfjs-cursor-hand-tool-button-label = 手形工具
+pdfjs-scroll-page-button =
+ .title = 使用页é¢æ»šåŠ¨
+pdfjs-scroll-page-button-label = 页é¢æ»šåŠ¨
+pdfjs-scroll-vertical-button =
+ .title = 使用垂直滚动
+pdfjs-scroll-vertical-button-label = 垂直滚动
+pdfjs-scroll-horizontal-button =
+ .title = 使用水平滚动
+pdfjs-scroll-horizontal-button-label = 水平滚动
+pdfjs-scroll-wrapped-button =
+ .title = 使用平铺滚动
+pdfjs-scroll-wrapped-button-label = 平铺滚动
+pdfjs-spread-none-button =
+ .title = ä¸åŠ 入衔接页
+pdfjs-spread-none-button-label = å•é¡µè§†å›¾
+pdfjs-spread-odd-button =
+ .title = åŠ å…¥è¡”æŽ¥é¡µä½¿å¥‡æ•°é¡µä½œä¸ºèµ·å§‹é¡µ
+pdfjs-spread-odd-button-label = åŒé¡µè§†å›¾
+pdfjs-spread-even-button =
+ .title = åŠ å…¥è¡”æŽ¥é¡µä½¿å¶æ•°é¡µä½œä¸ºèµ·å§‹é¡µ
+pdfjs-spread-even-button-label = 书ç±è§†å›¾
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = 文档属性…
+pdfjs-document-properties-button-label = 文档属性…
+pdfjs-document-properties-file-name = 文件å:
+pdfjs-document-properties-file-size = 文件大å°:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } å—节)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } å—节)
+pdfjs-document-properties-title = æ ‡é¢˜:
+pdfjs-document-properties-author = 作者:
+pdfjs-document-properties-subject = 主题:
+pdfjs-document-properties-keywords = 关键è¯:
+pdfjs-document-properties-creation-date = 创建日期:
+pdfjs-document-properties-modification-date = 修改日期:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date }, { $time }
+pdfjs-document-properties-creator = 创建者:
+pdfjs-document-properties-producer = PDF 生æˆå™¨ï¼š
+pdfjs-document-properties-version = PDF 版本:
+pdfjs-document-properties-page-count = 页数:
+pdfjs-document-properties-page-size = 页é¢å¤§å°ï¼š
+pdfjs-document-properties-page-size-unit-inches = 英寸
+pdfjs-document-properties-page-size-unit-millimeters = 毫米
+pdfjs-document-properties-page-size-orientation-portrait = 纵å‘
+pdfjs-document-properties-page-size-orientation-landscape = 横å‘
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit }({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit }({ $name },{ $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = 快速 Web 视图:
+pdfjs-document-properties-linearized-yes = 是
+pdfjs-document-properties-linearized-no = å¦
+pdfjs-document-properties-close-button = å…³é—
+
+## Print
+
+pdfjs-print-progress-message = æ£åœ¨å‡†å¤‡æ‰“å°æ–‡æ¡£â€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = å–消
+pdfjs-printing-not-supported = è¦å‘Šï¼šæ¤æµè§ˆå™¨å°šæœªå®Œæ•´æ”¯æŒæ‰“å°åŠŸèƒ½ã€‚
+pdfjs-printing-not-ready = è¦å‘Šï¼šæ¤ PDF 未完æˆåŠ è½½ï¼Œæ— æ³•æ‰“å°ã€‚
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = 切æ¢ä¾§æ
+pdfjs-toggle-sidebar-notification-button =
+ .title = 切æ¢ä¾§æ (文档所å«çš„大纲/附件/图层)
+pdfjs-toggle-sidebar-button-label = 切æ¢ä¾§æ
+pdfjs-document-outline-button =
+ .title = 显示文档大纲(åŒå‡»å±•å¼€/折å 所有项)
+pdfjs-document-outline-button-label = 文档大纲
+pdfjs-attachments-button =
+ .title = 显示附件
+pdfjs-attachments-button-label = 附件
+pdfjs-layers-button =
+ .title = 显示图层(åŒå‡»å³å¯å°†æ‰€æœ‰å›¾å±‚é‡ç½®ä¸ºé»˜è®¤çŠ¶æ€ï¼‰
+pdfjs-layers-button-label = 图层
+pdfjs-thumbs-button =
+ .title = 显示缩略图
+pdfjs-thumbs-button-label = 缩略图
+pdfjs-current-outline-item-button =
+ .title = 查找当å‰å¤§çº²é¡¹ç›®
+pdfjs-current-outline-item-button-label = 当å‰å¤§çº²é¡¹ç›®
+pdfjs-findbar-button =
+ .title = 在文档ä¸æŸ¥æ‰¾
+pdfjs-findbar-button-label = 查找
+pdfjs-additional-layers = 其他图层
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = 第 { $page } 页
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = é¡µé¢ { $page } 的缩略图
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = 查找
+ .placeholder = 在文档ä¸æŸ¥æ‰¾â€¦
+pdfjs-find-previous-button =
+ .title = 查找è¯è¯ä¸Šä¸€æ¬¡å‡ºçŽ°çš„ä½ç½®
+pdfjs-find-previous-button-label = 上一页
+pdfjs-find-next-button =
+ .title = 查找è¯è¯åŽä¸€æ¬¡å‡ºçŽ°çš„ä½ç½®
+pdfjs-find-next-button-label = 下一页
+pdfjs-find-highlight-checkbox = 全部高亮显示
+pdfjs-find-match-case-checkbox-label = 区分大å°å†™
+pdfjs-find-match-diacritics-checkbox-label = 匹é…å˜éŸ³ç¬¦å·
+pdfjs-find-entire-word-checkbox-label = å…¨è¯åŒ¹é…
+pdfjs-find-reached-top = 到达文档开头,从末尾继ç»
+pdfjs-find-reached-bottom = 到达文档末尾,从开头继ç»
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = 第 { $current } 项,共找到 { $total } 个匹é…项
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit = 匹é…超过 { $limit } 项
+pdfjs-find-not-found = 找ä¸åˆ°æŒ‡å®šè¯è¯
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = 适åˆé¡µå®½
+pdfjs-page-scale-fit = 适åˆé¡µé¢
+pdfjs-page-scale-auto = 自动缩放
+pdfjs-page-scale-actual = 实际大å°
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = 第 { $page } 页
+
+## Loading indicator messages
+
+pdfjs-loading-error = åŠ è½½ PDF æ—¶å‘生错误。
+pdfjs-invalid-file-error = æ— æ•ˆæˆ–æŸåçš„ PDF 文件。
+pdfjs-missing-file-error = 缺少 PDF 文件。
+pdfjs-unexpected-response-error = æ„外的æœåŠ¡å™¨å“应。
+pdfjs-rendering-error = 渲染页é¢æ—¶å‘生错误。
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date },{ $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } 注释]
+
+## Password
+
+pdfjs-password-label = 输入密ç ä»¥æ‰“å¼€æ¤ PDF 文件。
+pdfjs-password-invalid = 密ç æ— æ•ˆã€‚è¯·é‡è¯•ã€‚
+pdfjs-password-ok-button = 确定
+pdfjs-password-cancel-button = å–消
+pdfjs-web-fonts-disabled = Web å—体已被ç¦ç”¨ï¼šæ— 法使用嵌入的 PDF å—体。
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = 文本
+pdfjs-editor-free-text-button-label = 文本
+pdfjs-editor-ink-button =
+ .title = 绘图
+pdfjs-editor-ink-button-label = 绘图
+pdfjs-editor-stamp-button =
+ .title = æ·»åŠ æˆ–ç¼–è¾‘å›¾åƒ
+pdfjs-editor-stamp-button-label = æ·»åŠ æˆ–ç¼–è¾‘å›¾åƒ
+pdfjs-editor-remove-button =
+ .title = 移除
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = 移除绘图
+pdfjs-editor-remove-freetext-button =
+ .title = 移除文本
+pdfjs-editor-remove-stamp-button =
+ .title = 移除图åƒ
+pdfjs-editor-remove-highlight-button =
+ .title = 移除高亮
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = 颜色
+pdfjs-editor-free-text-size-input = å—å·
+pdfjs-editor-ink-color-input = 颜色
+pdfjs-editor-ink-thickness-input = 粗细
+pdfjs-editor-ink-opacity-input = ä¸é€æ˜Žåº¦
+pdfjs-editor-stamp-add-image-button =
+ .title = æ·»åŠ å›¾åƒ
+pdfjs-editor-stamp-add-image-button-label = æ·»åŠ å›¾åƒ
+pdfjs-free-text =
+ .aria-label = 文本编辑器
+pdfjs-free-text-default-content = 开始输入…
+pdfjs-ink =
+ .aria-label = 绘图编辑器
+pdfjs-ink-canvas =
+ .aria-label = 用户创建图åƒ
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = 替æ¢æ–‡å—
+pdfjs-editor-alt-text-edit-button-label = 编辑替æ¢æ–‡å—
+pdfjs-editor-alt-text-dialog-label = 选择一项
+pdfjs-editor-alt-text-dialog-description = 替æ¢æ–‡å—å¯åœ¨ç”¨æˆ·æ— æ³•çœ‹åˆ°æˆ–åŠ è½½å›¾åƒæ—¶ï¼Œæ述其内容。
+pdfjs-editor-alt-text-add-description-label = æ·»åŠ æè¿°
+pdfjs-editor-alt-text-add-description-description = æ述主题ã€èƒŒæ™¯æˆ–动作,长度尽é‡æŽ§åˆ¶åœ¨ä¸¤å¥è¯å†…。
+pdfjs-editor-alt-text-mark-decorative-label = æ ‡è®°ä¸ºè£…é¥°
+pdfjs-editor-alt-text-mark-decorative-description = 用于装饰的图åƒï¼Œä¾‹å¦‚边框和水å°ã€‚
+pdfjs-editor-alt-text-cancel-button = å–消
+pdfjs-editor-alt-text-save-button = ä¿å˜
+pdfjs-editor-alt-text-decorative-tooltip = å·²æ ‡è®°ä¸ºè£…é¥°
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = 例如:一个少年å到桌å‰ï¼Œå‡†å¤‡åƒé¥
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = 调整尺寸 - 左上角
+pdfjs-editor-resizer-label-top-middle = 调整尺寸 - 顶部ä¸é—´
+pdfjs-editor-resizer-label-top-right = 调整尺寸 - å³ä¸Šè§’
+pdfjs-editor-resizer-label-middle-right = 调整尺寸 - å³ä¾§ä¸é—´
+pdfjs-editor-resizer-label-bottom-right = 调整尺寸 - å³ä¸‹è§’
+pdfjs-editor-resizer-label-bottom-middle = è°ƒæ•´å¤§å° - 底部ä¸é—´
+pdfjs-editor-resizer-label-bottom-left = 调整尺寸 - 左下角
+pdfjs-editor-resizer-label-middle-left = 调整尺寸 - 左侧ä¸é—´
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = 高亮色
+pdfjs-editor-colorpicker-button =
+ .title = 更改颜色
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = 颜色选择
+pdfjs-editor-colorpicker-yellow =
+ .title = 黄色
+pdfjs-editor-colorpicker-green =
+ .title = 绿色
+pdfjs-editor-colorpicker-blue =
+ .title = è“色
+pdfjs-editor-colorpicker-pink =
+ .title = 粉色
+pdfjs-editor-colorpicker-red =
+ .title = 红色
diff --git a/www/lib/pdfjs/modern/web/locale/zh-TW/viewer.ftl b/www/lib/pdfjs/modern/web/locale/zh-TW/viewer.ftl
new file mode 100644
index 000000000..944e0fc7b
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/locale/zh-TW/viewer.ftl
@@ -0,0 +1,376 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+## Main toolbar buttons (tooltips and alt text for images)
+
+pdfjs-previous-button =
+ .title = 上一é
+pdfjs-previous-button-label = 上一é
+pdfjs-next-button =
+ .title = 下一é
+pdfjs-next-button-label = 下一é
+# .title: Tooltip for the pageNumber input.
+pdfjs-page-input =
+ .title = 第
+# Variables:
+# $pagesCount (Number) - the total number of pages in the document
+# This string follows an input field with the number of the page currently displayed.
+pdfjs-of-pages = é ,共 { $pagesCount } é
+# Variables:
+# $pageNumber (Number) - the currently visible page
+# $pagesCount (Number) - the total number of pages in the document
+pdfjs-page-of-pages = (第 { $pageNumber } é ,共 { $pagesCount } é )
+pdfjs-zoom-out-button =
+ .title = 縮å°
+pdfjs-zoom-out-button-label = 縮å°
+pdfjs-zoom-in-button =
+ .title = 放大
+pdfjs-zoom-in-button-label = 放大
+pdfjs-zoom-select =
+ .title = 縮放
+pdfjs-presentation-mode-button =
+ .title = 切æ›è‡³ç°¡å ±æ¨¡å¼
+pdfjs-presentation-mode-button-label = ç°¡å ±æ¨¡å¼
+pdfjs-open-file-button =
+ .title = 開啟檔案
+pdfjs-open-file-button-label = é–‹å•Ÿ
+pdfjs-print-button =
+ .title = 列å°
+pdfjs-print-button-label = 列å°
+pdfjs-save-button =
+ .title = 儲å˜
+pdfjs-save-button-label = 儲å˜
+# Used in Firefox for Android as a tooltip for the download button (“download†is a verb).
+pdfjs-download-button =
+ .title = 下載
+# Used in Firefox for Android as a label for the download button (“download†is a verb).
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-download-button-label = 下載
+pdfjs-bookmark-button =
+ .title = ç›®å‰é é¢ï¼ˆå«ç›®å‰æª¢è¦–é é¢çš„網å€ï¼‰
+pdfjs-bookmark-button-label = ç›®å‰é é¢
+# Used in Firefox for Android.
+pdfjs-open-in-app-button =
+ .title = 在應用程å¼ä¸é–‹å•Ÿ
+# Used in Firefox for Android.
+# Length of the translation matters since we are in a mobile context, with limited screen estate.
+pdfjs-open-in-app-button-label = 用程å¼é–‹å•Ÿ
+
+## Secondary toolbar and context menu
+
+pdfjs-tools-button =
+ .title = 工具
+pdfjs-tools-button-label = 工具
+pdfjs-first-page-button =
+ .title = 跳到第一é
+pdfjs-first-page-button-label = 跳到第一é
+pdfjs-last-page-button =
+ .title = 跳到最後一é
+pdfjs-last-page-button-label = 跳到最後一é
+pdfjs-page-rotate-cw-button =
+ .title = é †æ™‚é‡æ—‹è½‰
+pdfjs-page-rotate-cw-button-label = é †æ™‚é‡æ—‹è½‰
+pdfjs-page-rotate-ccw-button =
+ .title = 逆時é‡æ—‹è½‰
+pdfjs-page-rotate-ccw-button-label = 逆時é‡æ—‹è½‰
+pdfjs-cursor-text-select-tool-button =
+ .title = é–‹å•Ÿæ–‡å—é¸æ“‡å·¥å…·
+pdfjs-cursor-text-select-tool-button-label = æ–‡å—é¸æ“‡å·¥å…·
+pdfjs-cursor-hand-tool-button =
+ .title = é–‹å•Ÿé é¢ç§»å‹•å·¥å…·
+pdfjs-cursor-hand-tool-button-label = é é¢ç§»å‹•å·¥å…·
+pdfjs-scroll-page-button =
+ .title = 使用é é¢æ²å‹•åŠŸèƒ½
+pdfjs-scroll-page-button-label = é é¢æ²å‹•åŠŸèƒ½
+pdfjs-scroll-vertical-button =
+ .title = 使用垂直æ²å‹•ç‰ˆé¢
+pdfjs-scroll-vertical-button-label = åž‚ç›´æ²å‹•
+pdfjs-scroll-horizontal-button =
+ .title = 使用水平æ²å‹•ç‰ˆé¢
+pdfjs-scroll-horizontal-button-label = æ°´å¹³æ²å‹•
+pdfjs-scroll-wrapped-button =
+ .title = 使用多é æ²å‹•ç‰ˆé¢
+pdfjs-scroll-wrapped-button-label = 多é æ²å‹•
+pdfjs-spread-none-button =
+ .title = ä¸è¦é€²è¡Œè·¨é 顯示
+pdfjs-spread-none-button-label = ä¸è·¨é
+pdfjs-spread-odd-button =
+ .title = 從奇數é 開始跨é
+pdfjs-spread-odd-button-label = 奇數跨é
+pdfjs-spread-even-button =
+ .title = 從å¶æ•¸é 開始跨é
+pdfjs-spread-even-button-label = å¶æ•¸è·¨é
+
+## Document properties dialog
+
+pdfjs-document-properties-button =
+ .title = 文件內容…
+pdfjs-document-properties-button-label = 文件內容…
+pdfjs-document-properties-file-name = 檔案å稱:
+pdfjs-document-properties-file-size = 檔案大å°:
+# Variables:
+# $size_kb (Number) - the PDF file size in kilobytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-kb = { $size_kb } KB({ $size_b } ä½å…ƒçµ„)
+# Variables:
+# $size_mb (Number) - the PDF file size in megabytes
+# $size_b (Number) - the PDF file size in bytes
+pdfjs-document-properties-mb = { $size_mb } MB({ $size_b } ä½å…ƒçµ„)
+pdfjs-document-properties-title = 標題:
+pdfjs-document-properties-author = 作者:
+pdfjs-document-properties-subject = 主旨:
+pdfjs-document-properties-keywords = é—œéµå—:
+pdfjs-document-properties-creation-date = 建立日期:
+pdfjs-document-properties-modification-date = 修改日期:
+# Variables:
+# $date (Date) - the creation/modification date of the PDF file
+# $time (Time) - the creation/modification time of the PDF file
+pdfjs-document-properties-date-string = { $date } { $time }
+pdfjs-document-properties-creator = 建立者:
+pdfjs-document-properties-producer = PDF 產生器:
+pdfjs-document-properties-version = PDF 版本:
+pdfjs-document-properties-page-count = é 數:
+pdfjs-document-properties-page-size = é é¢å¤§å°:
+pdfjs-document-properties-page-size-unit-inches = in
+pdfjs-document-properties-page-size-unit-millimeters = mm
+pdfjs-document-properties-page-size-orientation-portrait = åž‚ç›´
+pdfjs-document-properties-page-size-orientation-landscape = æ°´å¹³
+pdfjs-document-properties-page-size-name-a-three = A3
+pdfjs-document-properties-page-size-name-a-four = A4
+pdfjs-document-properties-page-size-name-letter = Letter
+pdfjs-document-properties-page-size-name-legal = Legal
+
+## Variables:
+## $width (Number) - the width of the (current) page
+## $height (Number) - the height of the (current) page
+## $unit (String) - the unit of measurement of the (current) page
+## $name (String) - the name of the (current) page
+## $orientation (String) - the orientation of the (current) page
+
+pdfjs-document-properties-page-size-dimension-string = { $width } × { $height } { $unit }({ $orientation })
+pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $height } { $unit }({ $name },{ $orientation })
+
+##
+
+# The linearization status of the document; usually called "Fast Web View" in
+# English locales of Adobe software.
+pdfjs-document-properties-linearized = 快速 Web 檢視:
+pdfjs-document-properties-linearized-yes = 是
+pdfjs-document-properties-linearized-no = å¦
+pdfjs-document-properties-close-button = 關閉
+
+## Print
+
+pdfjs-print-progress-message = æ£åœ¨æº–備列å°æ–‡ä»¶â€¦
+# Variables:
+# $progress (Number) - percent value
+pdfjs-print-progress-percent = { $progress }%
+pdfjs-print-progress-close-button = å–消
+pdfjs-printing-not-supported = è¦å‘Š: æ¤ç€è¦½å™¨æœªå®Œæ•´æ”¯æ´åˆ—å°åŠŸèƒ½ã€‚
+pdfjs-printing-not-ready = è¦å‘Š: æ¤ PDF 未完æˆä¸‹è¼‰ä»¥ä¾›åˆ—å°ã€‚
+
+## Tooltips and alt text for side panel toolbar buttons
+
+pdfjs-toggle-sidebar-button =
+ .title = 切æ›å´é‚Šæ¬„
+pdfjs-toggle-sidebar-notification-button =
+ .title = 切æ›å´é‚Šæ¬„(包å«å¤§ç¶±ã€é™„件ã€åœ–層的文件)
+pdfjs-toggle-sidebar-button-label = 切æ›å´é‚Šæ¬„
+pdfjs-document-outline-button =
+ .title = 顯示文件大綱(雙擊展開/æ‘ºç–Šæ‰€æœ‰é …ç›®ï¼‰
+pdfjs-document-outline-button-label = 文件大綱
+pdfjs-attachments-button =
+ .title = 顯示附件
+pdfjs-attachments-button-label = 附件
+pdfjs-layers-button =
+ .title = é¡¯ç¤ºåœ–å±¤ï¼ˆæ»‘é¼ é›™æ“Šå³å¯å°‡æ‰€æœ‰åœ–層é‡è¨ç‚ºé è¨ç‹€æ…‹ï¼‰
+pdfjs-layers-button-label = 圖層
+pdfjs-thumbs-button =
+ .title = 顯示縮圖
+pdfjs-thumbs-button-label = 縮圖
+pdfjs-current-outline-item-button =
+ .title = 尋找目å‰çš„å¤§ç¶±é …ç›®
+pdfjs-current-outline-item-button-label = ç›®å‰çš„å¤§ç¶±é …ç›®
+pdfjs-findbar-button =
+ .title = 在文件ä¸å°‹æ‰¾
+pdfjs-findbar-button-label = 尋找
+pdfjs-additional-layers = 其他圖層
+
+## Thumbnails panel item (tooltip and alt text for images)
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-title =
+ .title = 第 { $page } é
+# Variables:
+# $page (Number) - the page number
+pdfjs-thumb-page-canvas =
+ .aria-label = 第 { $page } é 的縮圖
+
+## Find panel button title and messages
+
+pdfjs-find-input =
+ .title = 尋找
+ .placeholder = 在文件ä¸æœå°‹â€¦
+pdfjs-find-previous-button =
+ .title = 尋找文å—å‰æ¬¡å‡ºç¾çš„ä½ç½®
+pdfjs-find-previous-button-label = 上一個
+pdfjs-find-next-button =
+ .title = 尋找文å—下次出ç¾çš„ä½ç½®
+pdfjs-find-next-button-label = 下一個
+pdfjs-find-highlight-checkbox = 強調全部
+pdfjs-find-match-case-checkbox-label = å€åˆ†å¤§å°å¯«
+pdfjs-find-match-diacritics-checkbox-label = 符åˆè®ŠéŸ³ç¬¦è™Ÿ
+pdfjs-find-entire-word-checkbox-label = 符åˆæ•´å€‹å—
+pdfjs-find-reached-top = å·²æœå°‹è‡³æ–‡ä»¶é ‚端,自底端繼續æœå°‹
+pdfjs-find-reached-bottom = å·²æœå°‹è‡³æ–‡ä»¶åº•ç«¯ï¼Œè‡ªé ‚端繼續æœå°‹
+# Variables:
+# $current (Number) - the index of the currently active find result
+# $total (Number) - the total number of matches in the document
+pdfjs-find-match-count = 第 { $current } ç†ç¬¦åˆï¼Œå…±ç¬¦åˆ { $total } ç†
+# Variables:
+# $limit (Number) - the maximum number of matches
+pdfjs-find-match-count-limit = 符åˆè¶…éŽ { $limit } é …
+pdfjs-find-not-found = 找ä¸åˆ°æŒ‡å®šæ–‡å—
+
+## Predefined zoom values
+
+pdfjs-page-scale-width = é é¢å¯¬åº¦
+pdfjs-page-scale-fit = 縮放至é é¢å¤§å°
+pdfjs-page-scale-auto = 自動縮放
+pdfjs-page-scale-actual = 實際大å°
+# Variables:
+# $scale (Number) - percent value for page scale
+pdfjs-page-scale-percent = { $scale }%
+
+## PDF page
+
+# Variables:
+# $page (Number) - the page number
+pdfjs-page-landmark =
+ .aria-label = 第 { $page } é
+
+## Loading indicator messages
+
+pdfjs-loading-error = 載入 PDF 時發生錯誤。
+pdfjs-invalid-file-error = 無效或毀æçš„ PDF 檔案。
+pdfjs-missing-file-error = 找ä¸åˆ° PDF 檔案。
+pdfjs-unexpected-response-error = 伺æœå™¨å›žæ‡‰æœªé 期的內容。
+pdfjs-rendering-error = æ繪é é¢æ™‚發生錯誤。
+
+## Annotations
+
+# Variables:
+# $date (Date) - the modification date of the annotation
+# $time (Time) - the modification time of the annotation
+pdfjs-annotation-date-string = { $date } { $time }
+# .alt: This is used as a tooltip.
+# Variables:
+# $type (String) - an annotation type from a list defined in the PDF spec
+# (32000-1:2008 Table 169 – Annotation types).
+# Some common types are e.g.: "Check", "Text", "Comment", "Note"
+pdfjs-text-annotation-type =
+ .alt = [{ $type } 註解]
+
+## Password
+
+pdfjs-password-label = è«‹è¼¸å…¥ç”¨ä¾†é–‹å•Ÿæ¤ PDF 檔案的密碼。
+pdfjs-password-invalid = 密碼ä¸æ£ç¢ºï¼Œè«‹å†è©¦ä¸€æ¬¡ã€‚
+pdfjs-password-ok-button = 確定
+pdfjs-password-cancel-button = å–消
+pdfjs-web-fonts-disabled = å·²åœç”¨ç¶²è·¯å—åž‹ (Web fonts): 無法使用 PDF 內嵌å—型。
+
+## Editing
+
+pdfjs-editor-free-text-button =
+ .title = æ–‡å—
+pdfjs-editor-free-text-button-label = æ–‡å—
+pdfjs-editor-ink-button =
+ .title = 繪圖
+pdfjs-editor-ink-button-label = 繪圖
+pdfjs-editor-stamp-button =
+ .title = 新增或編輯圖片
+pdfjs-editor-stamp-button-label = 新增或編輯圖片
+pdfjs-editor-remove-button =
+ .title = 移除
+
+## Remove button for the various kind of editor.
+
+pdfjs-editor-remove-ink-button =
+ .title = 移除繪圖
+pdfjs-editor-remove-freetext-button =
+ .title = 移除文å—
+pdfjs-editor-remove-stamp-button =
+ .title = 移除圖片
+pdfjs-editor-remove-highlight-button =
+ .title = 移除強調範åœ
+
+##
+
+# Editor Parameters
+pdfjs-editor-free-text-color-input = 色彩
+pdfjs-editor-free-text-size-input = 大å°
+pdfjs-editor-ink-color-input = 色彩
+pdfjs-editor-ink-thickness-input = ç·šæ¢ç²—ç´°
+pdfjs-editor-ink-opacity-input = é€â€‹æ˜Žåº¦
+pdfjs-editor-stamp-add-image-button =
+ .title = 新增圖片
+pdfjs-editor-stamp-add-image-button-label = 新增圖片
+pdfjs-free-text =
+ .aria-label = 文本編輯器
+pdfjs-free-text-default-content = 開始打å—…
+pdfjs-ink =
+ .aria-label = 圖形編輯器
+pdfjs-ink-canvas =
+ .aria-label = 使用者建立的圖片
+
+## Alt-text dialog
+
+# Alternative text (alt text) helps when people can't see the image.
+pdfjs-editor-alt-text-button-label = 替代文å—
+pdfjs-editor-alt-text-edit-button-label = 編輯替代文å—
+pdfjs-editor-alt-text-dialog-label = 挑é¸ä¸€ç¨®
+pdfjs-editor-alt-text-dialog-description = 替代文å—å¯å”助盲人,或於圖片無法載入時æ供說明。
+pdfjs-editor-alt-text-add-description-label = 新增æè¿°
+pdfjs-editor-alt-text-add-description-description = 用 1-2 å¥æ–‡å—æ述主題ã€èƒŒæ™¯æˆ–動作。
+pdfjs-editor-alt-text-mark-decorative-label = 標示為è£é£¾æ€§å…§å®¹
+pdfjs-editor-alt-text-mark-decorative-description = 這是è£é£¾æ€§åœ–片,例如邊框或浮水å°ã€‚
+pdfjs-editor-alt-text-cancel-button = å–消
+pdfjs-editor-alt-text-save-button = 儲å˜
+pdfjs-editor-alt-text-decorative-tooltip = 已標示為è£é£¾æ€§å…§å®¹
+# .placeholder: This is a placeholder for the alt text input area
+pdfjs-editor-alt-text-textarea =
+ .placeholder = 例如:「有一ä½å¹´è¼•ç”·äººå在桌åå‰é¢åƒé£¯ã€
+
+## Editor resizers
+## This is used in an aria label to help to understand the role of the resizer.
+
+pdfjs-editor-resizer-label-top-left = 左上角 — 調整大å°
+pdfjs-editor-resizer-label-top-middle = é ‚éƒ¨ä¸é–“ — 調整大å°
+pdfjs-editor-resizer-label-top-right = å³ä¸Šè§’ — 調整大å°
+pdfjs-editor-resizer-label-middle-right = ä¸é–“å³æ–¹ — 調整大å°
+pdfjs-editor-resizer-label-bottom-right = å³ä¸‹è§’ — 調整大å°
+pdfjs-editor-resizer-label-bottom-middle = 底部ä¸é–“ — 調整大å°
+pdfjs-editor-resizer-label-bottom-left = 左下角 — 調整大å°
+pdfjs-editor-resizer-label-middle-left = ä¸é–“左方 — 調整大å°
+
+## Color picker
+
+# This means "Color used to highlight text"
+pdfjs-editor-highlight-colorpicker-label = 強調色彩
+pdfjs-editor-colorpicker-button =
+ .title = 更改色彩
+pdfjs-editor-colorpicker-dropdown =
+ .aria-label = 色彩é¸é …
+pdfjs-editor-colorpicker-yellow =
+ .title = 黃色
+pdfjs-editor-colorpicker-green =
+ .title = ç¶ è‰²
+pdfjs-editor-colorpicker-blue =
+ .title = è—色
+pdfjs-editor-colorpicker-pink =
+ .title = 粉紅色
+pdfjs-editor-colorpicker-red =
+ .title = 紅色
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitDingbats.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitDingbats.pfb
new file mode 100644
index 000000000..30d52963e
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitDingbats.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixed.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixed.pfb
new file mode 100644
index 000000000..f12dcbce5
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixed.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBold.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBold.pfb
new file mode 100644
index 000000000..cf8e24aee
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBold.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBoldItalic.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBoldItalic.pfb
new file mode 100644
index 000000000..d2880017c
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedBoldItalic.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedItalic.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedItalic.pfb
new file mode 100644
index 000000000..d71697d4b
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitFixedItalic.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerif.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerif.pfb
new file mode 100644
index 000000000..3fa682efb
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerif.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBold.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBold.pfb
new file mode 100644
index 000000000..ff7c6ddec
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBold.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBoldItalic.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBoldItalic.pfb
new file mode 100644
index 000000000..460231fb8
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifBoldItalic.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifItalic.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifItalic.pfb
new file mode 100644
index 000000000..d03a7c781
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSerifItalic.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/FoxitSymbol.pfb b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSymbol.pfb
new file mode 100644
index 000000000..c8f9bca78
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/FoxitSymbol.pfb differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_FOXIT b/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_FOXIT
new file mode 100644
index 000000000..8b4ed6ddd
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_FOXIT
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. 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 Google Inc. 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.
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_LIBERATION b/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_LIBERATION
new file mode 100644
index 000000000..aba73e8a4
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/standard_fonts/LICENSE_LIBERATION
@@ -0,0 +1,102 @@
+Digitized data copyright (c) 2010 Google Corporation
+ with Reserved Font Arimo, Tinos and Cousine.
+Copyright (c) 2012 Red Hat, Inc.
+ with Reserved Font Name Liberation.
+
+This Font Software is licensed under the SIL Open Font License,
+Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+
+PREAMBLE The goals of the Open Font License (OFL) are to stimulate
+worldwide development of collaborative font projects, to support the font
+creation efforts of academic and linguistic communities, and to provide
+a free and open framework in which fonts may be shared and improved in
+partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves.
+The fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such.
+This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components
+as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting ? in part or in whole ?
+any of the components of the Original Version, by changing formats or
+by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer
+or other person who contributed to the Font Software.
+
+
+PERMISSION & CONDITIONS
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,in
+ Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+ redistributed and/or sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or
+ in the appropriate machine-readable metadata fields within text or
+ binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s) unless explicit written permission is granted by the
+ corresponding Copyright Holder. This restriction only applies to the
+ primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+ Software shall not be used to promote, endorse or advertise any
+ Modified Version, except to acknowledge the contribution(s) of the
+ Copyright Holder(s) and the Author(s) or with their explicit written
+ permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must
+ be distributed entirely under this license, and must not be distributed
+ under any other license. The requirement for fonts to remain under
+ this license does not apply to any document created using the Font
+ Software.
+
+
+
+TERMINATION
+This license becomes null and void if any of the above conditions are not met.
+
+
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
+DEALINGS IN THE FONT SOFTWARE.
+
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Bold.ttf b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Bold.ttf
new file mode 100644
index 000000000..ee2371540
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Bold.ttf differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-BoldItalic.ttf b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-BoldItalic.ttf
new file mode 100644
index 000000000..42b5717dd
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-BoldItalic.ttf differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Italic.ttf b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Italic.ttf
new file mode 100644
index 000000000..0cf612634
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Italic.ttf differ
diff --git a/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Regular.ttf b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Regular.ttf
new file mode 100644
index 000000000..366d1489c
Binary files /dev/null and b/www/lib/pdfjs/modern/web/standard_fonts/LiberationSans-Regular.ttf differ
diff --git a/www/lib/pdfjs/modern/web/viewer.css b/www/lib/pdfjs/modern/web/viewer.css
new file mode 100644
index 000000000..0c6f1e272
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/viewer.css
@@ -0,0 +1,3882 @@
+/* Copyright 2014 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.textLayer{
+ position:absolute;
+ text-align:initial;
+ inset:0;
+ overflow:hidden;
+ opacity:0.25;
+ line-height:1;
+ -webkit-text-size-adjust:none;
+ -moz-text-size-adjust:none;
+ text-size-adjust:none;
+ forced-color-adjust:none;
+ transform-origin:0 0;
+ z-index:2;
+}
+
+.textLayer :is(span, br){
+ color:transparent;
+ position:absolute;
+ white-space:pre;
+ cursor:text;
+ transform-origin:0% 0%;
+ }
+
+.textLayer span.markedContent{
+ top:0;
+ height:0;
+ }
+
+.textLayer .highlight{
+ --highlight-bg-color:rgb(180 0 170);
+ --highlight-selected-bg-color:rgb(0 100 0);
+
+ margin:-1px;
+ padding:1px;
+ background-color:var(--highlight-bg-color);
+ border-radius:4px;
+ }
+
+@media screen and (forced-colors: active){
+
+.textLayer .highlight{
+ --highlight-bg-color:Highlight;
+ --highlight-selected-bg-color:ButtonText;
+ }
+ }
+
+.textLayer .highlight.appended{
+ position:initial;
+ }
+
+.textLayer .highlight.begin{
+ border-radius:4px 0 0 4px;
+ }
+
+.textLayer .highlight.end{
+ border-radius:0 4px 4px 0;
+ }
+
+.textLayer .highlight.middle{
+ border-radius:0;
+ }
+
+.textLayer .highlight.selected{
+ background-color:var(--highlight-selected-bg-color);
+ }
+
+.textLayer ::-moz-selection{
+ background:blue;
+ background:AccentColor;
+ }
+
+.textLayer ::selection{
+ background:blue;
+ background:AccentColor;
+ }
+
+.textLayer br::-moz-selection{
+ background:transparent;
+ }
+
+.textLayer br::selection{
+ background:transparent;
+ }
+
+.textLayer .endOfContent{
+ display:block;
+ position:absolute;
+ inset:100% 0 0;
+ z-index:-1;
+ cursor:default;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ }
+
+.textLayer .endOfContent.active{
+ top:0;
+ }
+
+.annotationLayer{
+ --annotation-unfocused-field-background:url("data:image/svg+xml;charset=UTF-8,");
+ --input-focus-border-color:Highlight;
+ --input-focus-outline:1px solid Canvas;
+ --input-unfocused-border-color:transparent;
+ --input-disabled-border-color:transparent;
+ --input-hover-border-color:black;
+ --link-outline:none;
+
+ position:absolute;
+ top:0;
+ left:0;
+ pointer-events:none;
+ transform-origin:0 0;
+ z-index:3;
+}
+
+@media screen and (forced-colors: active){
+
+.annotationLayer{
+ --input-focus-border-color:CanvasText;
+ --input-unfocused-border-color:ActiveText;
+ --input-disabled-border-color:GrayText;
+ --input-hover-border-color:Highlight;
+ --link-outline:1.5px solid LinkText;
+ --hcm-highlight-filter:invert(100%);
+}
+
+ .annotationLayer .textWidgetAnnotation :is(input, textarea):required, .annotationLayer .choiceWidgetAnnotation select:required, .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required{
+ outline:1.5px solid selectedItem;
+ }
+
+ .annotationLayer .linkAnnotation{
+ outline:var(--link-outline);
+ }
+
+ .annotationLayer .linkAnnotation:hover{
+ -webkit-backdrop-filter:var(--hcm-highlight-filter);
+ backdrop-filter:var(--hcm-highlight-filter);
+ }
+
+ .annotationLayer .linkAnnotation > a:hover{
+ opacity:0 !important;
+ background:none !important;
+ box-shadow:none;
+ }
+
+ .annotationLayer .popupAnnotation .popup{
+ outline:calc(1.5px * var(--scale-factor)) solid CanvasText !important;
+ background-color:ButtonFace !important;
+ color:ButtonText !important;
+ }
+
+ .annotationLayer .highlightArea:hover::after{
+ position:absolute;
+ top:0;
+ left:0;
+ width:100%;
+ height:100%;
+ -webkit-backdrop-filter:var(--hcm-highlight-filter);
+ backdrop-filter:var(--hcm-highlight-filter);
+ content:"";
+ pointer-events:none;
+ }
+
+ .annotationLayer .popupAnnotation.focused .popup{
+ outline:calc(3px * var(--scale-factor)) solid Highlight !important;
+ }
+ }
+
+.annotationLayer[data-main-rotation="90"] .norotate{
+ transform:rotate(270deg) translateX(-100%);
+ }
+
+.annotationLayer[data-main-rotation="180"] .norotate{
+ transform:rotate(180deg) translate(-100%, -100%);
+ }
+
+.annotationLayer[data-main-rotation="270"] .norotate{
+ transform:rotate(90deg) translateY(-100%);
+ }
+
+.annotationLayer canvas{
+ position:absolute;
+ width:100%;
+ height:100%;
+ pointer-events:none;
+ }
+
+.annotationLayer section{
+ position:absolute;
+ text-align:initial;
+ pointer-events:auto;
+ box-sizing:border-box;
+ transform-origin:0 0;
+ }
+
+.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a{
+ position:absolute;
+ font-size:1em;
+ top:0;
+ left:0;
+ width:100%;
+ height:100%;
+ }
+
+.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder)
+ > a:hover{
+ opacity:0.2;
+ background-color:rgb(255 255 0);
+ box-shadow:0 2px 10px rgb(255 255 0);
+ }
+
+.annotationLayer .linkAnnotation.hasBorder:hover{
+ background-color:rgb(255 255 0 / 0.2);
+ }
+
+.annotationLayer .hasBorder{
+ background-size:100% 100%;
+ }
+
+.annotationLayer .textAnnotation img{
+ position:absolute;
+ cursor:pointer;
+ width:100%;
+ height:100%;
+ top:0;
+ left:0;
+ }
+
+.annotationLayer .textWidgetAnnotation :is(input, textarea), .annotationLayer .choiceWidgetAnnotation select, .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input{
+ background-image:var(--annotation-unfocused-field-background);
+ border:2px solid var(--input-unfocused-border-color);
+ box-sizing:border-box;
+ font:calc(9px * var(--scale-factor)) sans-serif;
+ height:100%;
+ margin:0;
+ vertical-align:top;
+ width:100%;
+ }
+
+.annotationLayer .textWidgetAnnotation :is(input, textarea):required, .annotationLayer .choiceWidgetAnnotation select:required, .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required{
+ outline:1.5px solid red;
+ }
+
+.annotationLayer .choiceWidgetAnnotation select option{
+ padding:0;
+ }
+
+.annotationLayer .buttonWidgetAnnotation.radioButton input{
+ border-radius:50%;
+ }
+
+.annotationLayer .textWidgetAnnotation textarea{
+ resize:none;
+ }
+
+.annotationLayer .textWidgetAnnotation [disabled]:is(input, textarea), .annotationLayer .choiceWidgetAnnotation select[disabled], .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input[disabled]{
+ background:none;
+ border:2px solid var(--input-disabled-border-color);
+ cursor:not-allowed;
+ }
+
+.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, .annotationLayer .choiceWidgetAnnotation select:hover, .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:hover{
+ border:2px solid var(--input-hover-border-color);
+ }
+
+.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, .annotationLayer .choiceWidgetAnnotation select:hover, .annotationLayer .buttonWidgetAnnotation.checkBox input:hover{
+ border-radius:2px;
+ }
+
+.annotationLayer .textWidgetAnnotation :is(input, textarea):focus, .annotationLayer .choiceWidgetAnnotation select:focus{
+ background:none;
+ border:2px solid var(--input-focus-border-color);
+ border-radius:2px;
+ outline:var(--input-focus-outline);
+ }
+
+.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) :focus{
+ background-image:none;
+ background-color:transparent;
+ }
+
+.annotationLayer .buttonWidgetAnnotation.checkBox :focus{
+ border:2px solid var(--input-focus-border-color);
+ border-radius:2px;
+ outline:var(--input-focus-outline);
+ }
+
+.annotationLayer .buttonWidgetAnnotation.radioButton :focus{
+ border:2px solid var(--input-focus-border-color);
+ outline:var(--input-focus-outline);
+ }
+
+.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,
+ .annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after,
+ .annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before{
+ background-color:CanvasText;
+ content:"";
+ display:block;
+ position:absolute;
+ }
+
+.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before,
+ .annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after{
+ height:80%;
+ left:45%;
+ width:1px;
+ }
+
+.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before{
+ transform:rotate(45deg);
+ }
+
+.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after{
+ transform:rotate(-45deg);
+ }
+
+.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before{
+ border-radius:50%;
+ height:50%;
+ left:25%;
+ top:25%;
+ width:50%;
+ }
+
+.annotationLayer .textWidgetAnnotation input.comb{
+ font-family:monospace;
+ padding-left:2px;
+ padding-right:0;
+ }
+
+.annotationLayer .textWidgetAnnotation input.comb:focus{
+ width:103%;
+ }
+
+.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input{
+ -webkit-appearance:none;
+ -moz-appearance:none;
+ appearance:none;
+ }
+
+.annotationLayer .fileAttachmentAnnotation .popupTriggerArea{
+ height:100%;
+ width:100%;
+ }
+
+.annotationLayer .popupAnnotation{
+ position:absolute;
+ font-size:calc(9px * var(--scale-factor));
+ pointer-events:none;
+ width:-moz-max-content;
+ width:max-content;
+ max-width:45%;
+ height:auto;
+ }
+
+.annotationLayer .popup{
+ background-color:rgb(255 255 153);
+ box-shadow:0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor)) rgb(136 136 136);
+ border-radius:calc(2px * var(--scale-factor));
+ outline:1.5px solid rgb(255 255 74);
+ padding:calc(6px * var(--scale-factor));
+ cursor:pointer;
+ font:message-box;
+ white-space:normal;
+ word-wrap:break-word;
+ pointer-events:auto;
+ }
+
+.annotationLayer .popupAnnotation.focused .popup{
+ outline-width:3px;
+ }
+
+.annotationLayer .popup *{
+ font-size:calc(9px * var(--scale-factor));
+ }
+
+.annotationLayer .popup > .header{
+ display:inline-block;
+ }
+
+.annotationLayer .popup > .header h1{
+ display:inline;
+ }
+
+.annotationLayer .popup > .header .popupDate{
+ display:inline-block;
+ margin-left:calc(5px * var(--scale-factor));
+ width:-moz-fit-content;
+ width:fit-content;
+ }
+
+.annotationLayer .popupContent{
+ border-top:1px solid rgb(51 51 51);
+ margin-top:calc(2px * var(--scale-factor));
+ padding-top:calc(2px * var(--scale-factor));
+ }
+
+.annotationLayer .richText > *{
+ white-space:pre-wrap;
+ font-size:calc(9px * var(--scale-factor));
+ }
+
+.annotationLayer .popupTriggerArea{
+ cursor:pointer;
+ }
+
+.annotationLayer section svg{
+ position:absolute;
+ width:100%;
+ height:100%;
+ top:0;
+ left:0;
+ }
+
+.annotationLayer .annotationTextContent{
+ position:absolute;
+ width:100%;
+ height:100%;
+ opacity:0;
+ color:transparent;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ pointer-events:none;
+ }
+
+.annotationLayer .annotationTextContent span{
+ width:100%;
+ display:inline-block;
+ }
+
+.annotationLayer svg.quadrilateralsContainer{
+ contain:strict;
+ width:0;
+ height:0;
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:-1;
+ }
+
+:root{
+ --xfa-unfocused-field-background:url("data:image/svg+xml;charset=UTF-8,");
+ --xfa-focus-outline:auto;
+}
+
+@media screen and (forced-colors: active){
+ :root{
+ --xfa-focus-outline:2px solid CanvasText;
+ }
+ .xfaLayer *:required{
+ outline:1.5px solid selectedItem;
+ }
+}
+
+.xfaLayer{
+ background-color:transparent;
+}
+
+.xfaLayer .highlight{
+ margin:-1px;
+ padding:1px;
+ background-color:rgb(239 203 237);
+ border-radius:4px;
+}
+
+.xfaLayer .highlight.appended{
+ position:initial;
+}
+
+.xfaLayer .highlight.begin{
+ border-radius:4px 0 0 4px;
+}
+
+.xfaLayer .highlight.end{
+ border-radius:0 4px 4px 0;
+}
+
+.xfaLayer .highlight.middle{
+ border-radius:0;
+}
+
+.xfaLayer .highlight.selected{
+ background-color:rgb(203 223 203);
+}
+
+.xfaPage{
+ overflow:hidden;
+ position:relative;
+}
+
+.xfaContentarea{
+ position:absolute;
+}
+
+.xfaPrintOnly{
+ display:none;
+}
+
+.xfaLayer{
+ position:absolute;
+ text-align:initial;
+ top:0;
+ left:0;
+ transform-origin:0 0;
+ line-height:1.2;
+}
+
+.xfaLayer *{
+ color:inherit;
+ font:inherit;
+ font-style:inherit;
+ font-weight:inherit;
+ font-kerning:inherit;
+ letter-spacing:-0.01px;
+ text-align:inherit;
+ text-decoration:inherit;
+ box-sizing:border-box;
+ background-color:transparent;
+ padding:0;
+ margin:0;
+ pointer-events:auto;
+ line-height:inherit;
+}
+
+.xfaLayer *:required{
+ outline:1.5px solid red;
+}
+
+.xfaLayer div,
+.xfaLayer svg,
+.xfaLayer svg *{
+ pointer-events:none;
+}
+
+.xfaLayer a{
+ color:blue;
+}
+
+.xfaRich li{
+ margin-left:3em;
+}
+
+.xfaFont{
+ color:black;
+ font-weight:normal;
+ font-kerning:none;
+ font-size:10px;
+ font-style:normal;
+ letter-spacing:0;
+ text-decoration:none;
+ vertical-align:0;
+}
+
+.xfaCaption{
+ overflow:hidden;
+ flex:0 0 auto;
+}
+
+.xfaCaptionForCheckButton{
+ overflow:hidden;
+ flex:1 1 auto;
+}
+
+.xfaLabel{
+ height:100%;
+ width:100%;
+}
+
+.xfaLeft{
+ display:flex;
+ flex-direction:row;
+ align-items:center;
+}
+
+.xfaRight{
+ display:flex;
+ flex-direction:row-reverse;
+ align-items:center;
+}
+
+:is(.xfaLeft, .xfaRight) > :is(.xfaCaption, .xfaCaptionForCheckButton){
+ max-height:100%;
+}
+
+.xfaTop{
+ display:flex;
+ flex-direction:column;
+ align-items:flex-start;
+}
+
+.xfaBottom{
+ display:flex;
+ flex-direction:column-reverse;
+ align-items:flex-start;
+}
+
+:is(.xfaTop, .xfaBottom) > :is(.xfaCaption, .xfaCaptionForCheckButton){
+ width:100%;
+}
+
+.xfaBorder{
+ background-color:transparent;
+ position:absolute;
+ pointer-events:none;
+}
+
+.xfaWrapped{
+ width:100%;
+ height:100%;
+}
+
+:is(.xfaTextfield, .xfaSelect):focus{
+ background-image:none;
+ background-color:transparent;
+ outline:var(--xfa-focus-outline);
+ outline-offset:-1px;
+}
+
+:is(.xfaCheckbox, .xfaRadio):focus{
+ outline:var(--xfa-focus-outline);
+}
+
+.xfaTextfield,
+.xfaSelect{
+ height:100%;
+ width:100%;
+ flex:1 1 auto;
+ border:none;
+ resize:none;
+ background-image:var(--xfa-unfocused-field-background);
+}
+
+.xfaSelect{
+ padding-inline:2px;
+}
+
+:is(.xfaTop, .xfaBottom) > :is(.xfaTextfield, .xfaSelect){
+ flex:0 1 auto;
+}
+
+.xfaButton{
+ cursor:pointer;
+ width:100%;
+ height:100%;
+ border:none;
+ text-align:center;
+}
+
+.xfaLink{
+ width:100%;
+ height:100%;
+ position:absolute;
+ top:0;
+ left:0;
+}
+
+.xfaCheckbox,
+.xfaRadio{
+ width:100%;
+ height:100%;
+ flex:0 0 auto;
+ border:none;
+}
+
+.xfaRich{
+ white-space:pre-wrap;
+ width:100%;
+ height:100%;
+}
+
+.xfaImage{
+ -o-object-position:left top;
+ object-position:left top;
+ -o-object-fit:contain;
+ object-fit:contain;
+ width:100%;
+ height:100%;
+}
+
+.xfaLrTb,
+.xfaRlTb,
+.xfaTb{
+ display:flex;
+ flex-direction:column;
+ align-items:stretch;
+}
+
+.xfaLr{
+ display:flex;
+ flex-direction:row;
+ align-items:stretch;
+}
+
+.xfaRl{
+ display:flex;
+ flex-direction:row-reverse;
+ align-items:stretch;
+}
+
+.xfaTb > div{
+ justify-content:left;
+}
+
+.xfaPosition{
+ position:relative;
+}
+
+.xfaArea{
+ position:relative;
+}
+
+.xfaValignMiddle{
+ display:flex;
+ align-items:center;
+}
+
+.xfaTable{
+ display:flex;
+ flex-direction:column;
+ align-items:stretch;
+}
+
+.xfaTable .xfaRow{
+ display:flex;
+ flex-direction:row;
+ align-items:stretch;
+}
+
+.xfaTable .xfaRlRow{
+ display:flex;
+ flex-direction:row-reverse;
+ align-items:stretch;
+ flex:1;
+}
+
+.xfaTable .xfaRlRow > div{
+ flex:1;
+}
+
+:is(.xfaNonInteractive, .xfaDisabled, .xfaReadOnly) :is(input, textarea){
+ background:initial;
+}
+
+@media print{
+ .xfaTextfield,
+ .xfaSelect{
+ background:transparent;
+ }
+
+ .xfaSelect{
+ -webkit-appearance:none;
+ -moz-appearance:none;
+ appearance:none;
+ text-indent:1px;
+ text-overflow:"";
+ }
+}
+
+.canvasWrapper svg{
+ transform:none;
+ }
+
+.canvasWrapper svg[data-main-rotation="90"] use:not(.clip){
+ transform:matrix(0, 1, -1, 0, 1, 0);
+ }
+
+.canvasWrapper svg[data-main-rotation="180"] use:not(.clip){
+ transform:matrix(-1, 0, 0, -1, 1, 1);
+ }
+
+.canvasWrapper svg[data-main-rotation="270"] use:not(.clip){
+ transform:matrix(0, -1, 1, 0, 0, 1);
+ }
+
+.canvasWrapper svg.highlight{
+ --blend-mode:multiply;
+
+ position:absolute;
+ mix-blend-mode:var(--blend-mode);
+ fill-rule:evenodd;
+ }
+
+@media screen and (forced-colors: active){
+
+.canvasWrapper svg.highlight{
+ --blend-mode:difference;
+ }
+ }
+
+.canvasWrapper svg.highlightOutline{
+ position:absolute;
+ mix-blend-mode:normal;
+ fill-rule:evenodd;
+ fill:none;
+ }
+
+.canvasWrapper svg.highlightOutline.hovered{
+ stroke:var(--hover-outline-color);
+ stroke-width:var(--outline-width);
+ }
+
+.canvasWrapper svg.highlightOutline.selected .mainOutline{
+ stroke:var(--outline-around-color);
+ stroke-width:calc(
+ var(--outline-width) + 2 * var(--outline-around-width)
+ );
+ }
+
+.canvasWrapper svg.highlightOutline.selected .secondaryOutline{
+ stroke:var(--outline-color);
+ stroke-width:var(--outline-width);
+ }
+
+:root{
+ --outline-width:2px;
+ --outline-color:#0060df;
+ --outline-around-width:1px;
+ --outline-around-color:#f0f0f4;
+ --hover-outline-around-color:var(--outline-around-color);
+ --focus-outline:solid var(--outline-width) var(--outline-color);
+ --unfocus-outline:solid var(--outline-width) transparent;
+ --focus-outline-around:solid var(--outline-around-width) var(--outline-around-color);
+ --hover-outline-color:#8f8f9d;
+ --hover-outline:solid var(--outline-width) var(--hover-outline-color);
+ --hover-outline-around:solid var(--outline-around-width) var(--hover-outline-around-color);
+ --freetext-line-height:1.35;
+ --freetext-padding:2px;
+ --resizer-bg-color:var(--outline-color);
+ --resizer-size:6px;
+ --resizer-shift:calc(
+ 0px - (var(--outline-width) + var(--resizer-size)) / 2 -
+ var(--outline-around-width)
+ );
+ --editorFreeText-editing-cursor:text;
+ --editorInk-editing-cursor:url(images/cursor-editorInk.svg) 0 16, pointer;
+}
+
+@media (-webkit-min-device-pixel-ratio: 1.1), (min-resolution: 1.1dppx){
+ :root{
+ --editorFreeText-editing-cursor:url(images/cursor-editorFreeText.svg) 0 16, text;
+ }
+}
+
+@media screen and (forced-colors: active){
+ :root{
+ --outline-color:CanvasText;
+ --outline-around-color:ButtonFace;
+ --resizer-bg-color:ButtonText;
+ --hover-outline-color:Highlight;
+ --hover-outline-around-color:SelectedItemText;
+ }
+}
+
+[data-editor-rotation="90"]{
+ transform:rotate(90deg);
+}
+
+[data-editor-rotation="180"]{
+ transform:rotate(180deg);
+}
+
+[data-editor-rotation="270"]{
+ transform:rotate(270deg);
+}
+
+.annotationEditorLayer{
+ background:transparent;
+ position:absolute;
+ inset:0;
+ font-size:calc(100px * var(--scale-factor));
+ transform-origin:0 0;
+ cursor:auto;
+ z-index:4;
+}
+
+.annotationEditorLayer.waiting{
+ content:"";
+ cursor:wait;
+ position:absolute;
+ inset:0;
+ width:100%;
+ height:100%;
+}
+
+.annotationEditorLayer.disabled{
+ pointer-events:none;
+}
+
+.annotationEditorLayer.freetextEditing{
+ cursor:var(--editorFreeText-editing-cursor);
+}
+
+.annotationEditorLayer.inkEditing{
+ cursor:var(--editorInk-editing-cursor);
+}
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor){
+ position:absolute;
+ background:transparent;
+ z-index:1;
+ transform-origin:0 0;
+ cursor:auto;
+ max-width:100%;
+ max-height:100%;
+ border:var(--unfocus-outline);
+}
+
+.annotationEditorLayer .draggable.selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor){
+ cursor:move;
+ }
+
+.annotationEditorLayer .selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor){
+ border:var(--focus-outline);
+ outline:var(--focus-outline-around);
+ }
+
+.annotationEditorLayer .selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor)::before{
+ content:"";
+ position:absolute;
+ inset:0;
+ border:var(--focus-outline-around);
+ pointer-events:none;
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor):hover:not(.selectedEditor){
+ border:var(--hover-outline);
+ outline:var(--hover-outline-around);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor):hover:not(.selectedEditor)::before{
+ content:"";
+ position:absolute;
+ inset:0;
+ border:var(--focus-outline-around);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ --editor-toolbar-delete-image:url(images/editor-toolbar-delete.svg);
+ --editor-toolbar-bg-color:#f0f0f4;
+ --editor-toolbar-fg-color:#2e2e56;
+ --editor-toolbar-border-color:#8f8f9d;
+ --editor-toolbar-hover-border-color:var(--editor-toolbar-border-color);
+ --editor-toolbar-hover-bg-color:#e0e0e6;
+ --editor-toolbar-hover-fg-color:var(--editor-toolbar-fg-color);
+ --editor-toolbar-hover-outline:none;
+ --editor-toolbar-focus-outline-color:#0060df;
+ --editor-toolbar-shadow:0 2px 6px 0 rgb(58 57 68 / 0.2);
+ --editor-toolbar-vert-offset:6px;
+ --editor-toolbar-height:28px;
+ --editor-toolbar-padding:2px;
+
+ display:flex;
+ width:-moz-fit-content;
+ width:fit-content;
+ height:var(--editor-toolbar-height);
+ flex-direction:column;
+ justify-content:center;
+ align-items:center;
+ cursor:default;
+ pointer-events:auto;
+ box-sizing:content-box;
+ padding:var(--editor-toolbar-padding);
+
+ position:absolute;
+ inset-inline-end:0;
+ inset-block-start:calc(100% + var(--editor-toolbar-vert-offset));
+
+ border-radius:6px;
+ background-color:var(--editor-toolbar-bg-color);
+ border:1px solid var(--editor-toolbar-border-color);
+ box-shadow:var(--editor-toolbar-shadow);
+ }
+
+@media (prefers-color-scheme: dark){
+
+:where(html:not(.is-light)) .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ --editor-toolbar-bg-color:#2b2a33;
+ --editor-toolbar-fg-color:#fbfbfe;
+ --editor-toolbar-hover-bg-color:#52525e;
+ --editor-toolbar-focus-outline-color:#0df;
+ }
+ }
+
+:where(html.is-dark) .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ --editor-toolbar-bg-color:#2b2a33;
+ --editor-toolbar-fg-color:#fbfbfe;
+ --editor-toolbar-hover-bg-color:#52525e;
+ --editor-toolbar-focus-outline-color:#0df;
+ }
+
+@media screen and (forced-colors: active){
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ --editor-toolbar-bg-color:ButtonFace;
+ --editor-toolbar-fg-color:ButtonText;
+ --editor-toolbar-border-color:ButtonText;
+ --editor-toolbar-hover-border-color:AccentColor;
+ --editor-toolbar-hover-bg-color:ButtonFace;
+ --editor-toolbar-hover-fg-color:AccentColor;
+ --editor-toolbar-hover-outline:2px solid var(--editor-toolbar-hover-border-color);
+ --editor-toolbar-focus-outline-color:ButtonBorder;
+ --editor-toolbar-shadow:none;
+ }
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar.hidden{
+ display:none;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar:has(:focus-visible){
+ border-color:transparent;
+ }
+
+[dir="ltr"] .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ transform-origin:100% 0;
+ }
+
+[dir="rtl"] .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar{
+ transform-origin:0 0;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons{
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ gap:0;
+ height:100%;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .divider{
+ width:1px;
+ height:calc(
+ 2 * var(--editor-toolbar-padding) + var(--editor-toolbar-height)
+ );
+ background-color:var(--editor-toolbar-border-color);
+ display:inline-block;
+ margin-inline:2px;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .delete{
+ width:var(--editor-toolbar-height);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .delete::before{
+ content:"";
+ -webkit-mask-image:var(--editor-toolbar-delete-image);
+ mask-image:var(--editor-toolbar-delete-image);
+ -webkit-mask-repeat:no-repeat;
+ mask-repeat:no-repeat;
+ -webkit-mask-position:center;
+ mask-position:center;
+ display:inline-block;
+ background-color:var(--editor-toolbar-fg-color);
+ width:100%;
+ height:100%;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .delete:hover::before{
+ background-color:var(--editor-toolbar-hover-fg-color);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons > *{
+ height:var(--editor-toolbar-height);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons > :not(.divider){
+ border:none;
+ background-color:transparent;
+ cursor:pointer;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons > :not(.divider):hover{
+ border-radius:2px;
+ background-color:var(--editor-toolbar-hover-bg-color);
+ color:var(--editor-toolbar-hover-fg-color);
+ outline:var(--editor-toolbar-hover-outline);
+ outline-offset:1px;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons > :not(.divider):hover:active{
+ outline:none;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons > :not(.divider):focus-visible{
+ border-radius:2px;
+ outline:2px solid var(--editor-toolbar-focus-outline-color);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText{
+ --alt-text-add-image:url(images/altText_add.svg);
+ --alt-text-done-image:url(images/altText_done.svg);
+
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ width:-moz-max-content;
+ width:max-content;
+ padding-inline:8px;
+ pointer-events:all;
+ font:menu;
+ font-weight:590;
+ font-size:12px;
+ color:var(--editor-toolbar-fg-color);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText:disabled{
+ pointer-events:none;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText::before{
+ content:"";
+ -webkit-mask-image:var(--alt-text-add-image);
+ mask-image:var(--alt-text-add-image);
+ -webkit-mask-repeat:no-repeat;
+ mask-repeat:no-repeat;
+ -webkit-mask-position:center;
+ mask-position:center;
+ display:inline-block;
+ width:12px;
+ height:13px;
+ background-color:var(--editor-toolbar-fg-color);
+ margin-inline-end:4px;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText:hover::before{
+ background-color:var(--editor-toolbar-hover-fg-color);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText.done::before{
+ -webkit-mask-image:var(--alt-text-done-image);
+ mask-image:var(--alt-text-done-image);
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText .tooltip{
+ display:none;
+ }
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText .tooltip.show{
+ --alt-text-tooltip-bg:#f0f0f4;
+ --alt-text-tooltip-fg:#15141a;
+ --alt-text-tooltip-border:#8f8f9d;
+ --alt-text-tooltip-shadow:0px 2px 6px 0px rgb(58 57 68 / 0.2);
+
+ display:inline-flex;
+ flex-direction:column;
+ align-items:center;
+ justify-content:center;
+ position:absolute;
+ top:calc(100% + 2px);
+ inset-inline-start:0;
+ padding-block:2px 3px;
+ padding-inline:3px;
+ max-width:300px;
+ width:-moz-max-content;
+ width:max-content;
+ height:auto;
+ font-size:12px;
+
+ border:0.5px solid var(--alt-text-tooltip-border);
+ background:var(--alt-text-tooltip-bg);
+ box-shadow:var(--alt-text-tooltip-shadow);
+ color:var(--alt-text-tooltip-fg);
+
+ pointer-events:none;
+ }
+
+@media (prefers-color-scheme: dark){
+
+:where(html:not(.is-light)) .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText .tooltip.show{
+ --alt-text-tooltip-bg:#1c1b22;
+ --alt-text-tooltip-fg:#fbfbfe;
+ --alt-text-tooltip-shadow:0px 2px 6px 0px #15141a;
+ }
+ }
+
+:where(html.is-dark) .annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText .tooltip.show{
+ --alt-text-tooltip-bg:#1c1b22;
+ --alt-text-tooltip-fg:#fbfbfe;
+ --alt-text-tooltip-shadow:0px 2px 6px 0px #15141a;
+ }
+
+@media screen and (forced-colors: active){
+
+.annotationEditorLayer
+ :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor) .editToolbar .buttons .altText .tooltip.show{
+ --alt-text-tooltip-bg:Canvas;
+ --alt-text-tooltip-fg:CanvasText;
+ --alt-text-tooltip-border:CanvasText;
+ --alt-text-tooltip-shadow:none;
+ }
+ }
+
+.annotationEditorLayer .freeTextEditor{
+ padding:calc(var(--freetext-padding) * var(--scale-factor));
+ width:auto;
+ height:auto;
+ touch-action:none;
+}
+
+.annotationEditorLayer .freeTextEditor .internal{
+ background:transparent;
+ border:none;
+ inset:0;
+ overflow:visible;
+ white-space:nowrap;
+ font:10px sans-serif;
+ line-height:var(--freetext-line-height);
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+}
+
+.annotationEditorLayer .freeTextEditor .overlay{
+ position:absolute;
+ display:none;
+ background:transparent;
+ inset:0;
+ width:100%;
+ height:100%;
+}
+
+.annotationEditorLayer freeTextEditor .overlay.enabled{
+ display:block;
+}
+
+.annotationEditorLayer .freeTextEditor .internal:empty::before{
+ content:attr(default-content);
+ color:gray;
+}
+
+.annotationEditorLayer .freeTextEditor .internal:focus{
+ outline:none;
+ -webkit-user-select:auto;
+ -moz-user-select:auto;
+ user-select:auto;
+}
+
+.annotationEditorLayer .inkEditor{
+ width:100%;
+ height:100%;
+}
+
+.annotationEditorLayer .inkEditor.editing{
+ cursor:inherit;
+}
+
+.annotationEditorLayer .inkEditor .inkEditorCanvas{
+ position:absolute;
+ inset:0;
+ width:100%;
+ height:100%;
+ touch-action:none;
+}
+
+.annotationEditorLayer .stampEditor{
+ width:auto;
+ height:auto;
+}
+
+.annotationEditorLayer .stampEditor canvas{
+ width:100%;
+ height:100%;
+}
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers{
+ position:absolute;
+ inset:0;
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers.hidden{
+ display:none;
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer{
+ width:var(--resizer-size);
+ height:var(--resizer-size);
+ background:content-box var(--resizer-bg-color);
+ border:var(--focus-outline-around);
+ border-radius:2px;
+ position:absolute;
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.topLeft{
+ top:var(--resizer-shift);
+ left:var(--resizer-shift);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.topMiddle{
+ top:var(--resizer-shift);
+ left:calc(50% + var(--resizer-shift));
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.topRight{
+ top:var(--resizer-shift);
+ right:var(--resizer-shift);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.middleRight{
+ top:calc(50% + var(--resizer-shift));
+ right:var(--resizer-shift);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.bottomRight{
+ bottom:var(--resizer-shift);
+ right:var(--resizer-shift);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.bottomMiddle{
+ bottom:var(--resizer-shift);
+ left:calc(50% + var(--resizer-shift));
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.bottomLeft{
+ bottom:var(--resizer-shift);
+ left:var(--resizer-shift);
+ }
+
+.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) > .resizers > .resizer.middleLeft{
+ top:calc(50% + var(--resizer-shift));
+ left:var(--resizer-shift);
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight{
+ cursor:nwse-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle{
+ cursor:ns-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft{
+ cursor:nesw-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft{
+ cursor:ew-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight{
+ cursor:nesw-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle{
+ cursor:ew-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft{
+ cursor:nwse-resize;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
+ .annotationEditorLayer[data-main-rotation="0"]
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="90"]
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="180"]
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
+ .annotationEditorLayer[data-main-rotation="270"]
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft{
+ cursor:ns-resize;
+ }
+
+.annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ ) .editToolbar{
+ rotate:270deg;
+ }
+
+[dir="ltr"] .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ ) .editToolbar{
+ inset-inline-end:calc(0px - var(--editor-toolbar-vert-offset));
+ inset-block-start:0;
+ }
+
+[dir="rtl"] .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ ) .editToolbar{
+ inset-inline-end:calc(100% + var(--editor-toolbar-vert-offset));
+ inset-block-start:0;
+ }
+
+.annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="180"],
+ [data-main-rotation="90"] [data-editor-rotation="90"],
+ [data-main-rotation="180"] [data-editor-rotation="0"],
+ [data-main-rotation="270"] [data-editor-rotation="270"]
+ ) .editToolbar{
+ rotate:180deg;
+ inset-inline-end:100%;
+ inset-block-start:calc(0pc - var(--editor-toolbar-vert-offset));
+ }
+
+.annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ ) .editToolbar{
+ rotate:90deg;
+ }
+
+[dir="ltr"] .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ ) .editToolbar{
+ inset-inline-end:calc(100% + var(--editor-toolbar-vert-offset));
+ inset-block-start:100%;
+ }
+
+[dir="rtl"] .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ ) .editToolbar{
+ inset-inline-start:calc(0px - var(--editor-toolbar-vert-offset));
+ inset-block-start:0;
+ }
+
+#altTextDialog{
+ --dialog-bg-color:white;
+ --dialog-border-color:white;
+ --dialog-shadow:0 2px 14px 0 rgb(58 57 68 / 0.2);
+ --text-primary-color:#15141a;
+ --text-secondary-color:#5b5b66;
+ --hover-filter:brightness(0.9);
+ --focus-ring-color:#0060df;
+ --focus-ring-outline:2px solid var(--focus-ring-color);
+
+ --textarea-border-color:#8f8f9d;
+ --textarea-bg-color:white;
+ --textarea-fg-color:var(--text-secondary-color);
+
+ --radio-bg-color:#f0f0f4;
+ --radio-checked-bg-color:#fbfbfe;
+ --radio-border-color:#8f8f9d;
+ --radio-checked-border-color:#0060df;
+
+ --button-cancel-bg-color:#f0f0f4;
+ --button-cancel-fg-color:var(--text-primary-color);
+ --button-cancel-border-color:var(--button-cancel-bg-color);
+ --button-cancel-hover-bg-color:var(--button-cancel-bg-color);
+ --button-cancel-hover-fg-color:var(--button-cancel-fg-color);
+ --button-cancel-hover-border-color:var(--button-cancel-hover-bg-color);
+
+ --button-save-bg-color:#0060df;
+ --button-save-fg-color:#fbfbfe;
+ --button-save-hover-bg-color:var(--button-save-bg-color);
+ --button-save-hover-fg-color:var(--button-save-fg-color);
+ --button-save-hover-border-color:var(--button-save-hover-bg-color);
+
+ font:message-box;
+ font-size:13px;
+ font-weight:400;
+ line-height:150%;
+ border-radius:4px;
+ padding:12px 16px;
+ border:1px solid var(--dialog-border-color);
+ background:var(--dialog-bg-color);
+ color:var(--text-primary-color);
+ box-shadow:var(--dialog-shadow);
+}
+
+@media (prefers-color-scheme: dark){
+
+:where(html:not(.is-light)) #altTextDialog{
+ --dialog-bg-color:#1c1b22;
+ --dialog-border-color:#1c1b22;
+ --dialog-shadow:0 2px 14px 0 #15141a;
+ --text-primary-color:#fbfbfe;
+ --text-secondary-color:#cfcfd8;
+ --focus-ring-color:#0df;
+ --hover-filter:brightness(1.4);
+
+ --textarea-bg-color:#42414d;
+
+ --radio-bg-color:#2b2a33;
+ --radio-checked-bg-color:#15141a;
+ --radio-checked-border-color:#0df;
+
+ --button-cancel-bg-color:#2b2a33;
+ --button-save-bg-color:#0df;
+ --button-save-fg-color:#15141a;
+}
+ }
+
+:where(html.is-dark) #altTextDialog{
+ --dialog-bg-color:#1c1b22;
+ --dialog-border-color:#1c1b22;
+ --dialog-shadow:0 2px 14px 0 #15141a;
+ --text-primary-color:#fbfbfe;
+ --text-secondary-color:#cfcfd8;
+ --focus-ring-color:#0df;
+ --hover-filter:brightness(1.4);
+
+ --textarea-bg-color:#42414d;
+
+ --radio-bg-color:#2b2a33;
+ --radio-checked-bg-color:#15141a;
+ --radio-checked-border-color:#0df;
+
+ --button-cancel-bg-color:#2b2a33;
+ --button-save-bg-color:#0df;
+ --button-save-fg-color:#15141a;
+}
+
+@media screen and (forced-colors: active){
+
+#altTextDialog{
+ --dialog-bg-color:Canvas;
+ --dialog-border-color:CanvasText;
+ --dialog-shadow:none;
+ --text-primary-color:CanvasText;
+ --text-secondary-color:CanvasText;
+ --hover-filter:none;
+ --focus-ring-color:ButtonBorder;
+
+ --textarea-border-color:ButtonBorder;
+ --textarea-bg-color:Field;
+ --textarea-fg-color:ButtonText;
+
+ --radio-bg-color:ButtonFace;
+ --radio-checked-bg-color:ButtonFace;
+ --radio-border-color:ButtonText;
+ --radio-checked-border-color:ButtonText;
+
+ --button-cancel-bg-color:ButtonFace;
+ --button-cancel-fg-color:ButtonText;
+ --button-cancel-border-color:ButtonText;
+ --button-cancel-hover-bg-color:AccentColor;
+ --button-cancel-hover-fg-color:AccentColorText;
+
+ --button-save-bg-color:ButtonText;
+ --button-save-fg-color:ButtonFace;
+ --button-save-hover-bg-color:AccentColor;
+ --button-save-hover-fg-color:AccentColorText;
+}
+ }
+
+#altTextDialog::backdrop{
+ -webkit-mask:url(#alttext-manager-mask);
+ mask:url(#alttext-manager-mask);
+ }
+
+#altTextDialog.positioned{
+ margin:0;
+ }
+
+#altTextDialog #altTextContainer{
+ width:300px;
+ height:-moz-fit-content;
+ height:fit-content;
+ display:inline-flex;
+ flex-direction:column;
+ align-items:flex-start;
+ gap:16px;
+ }
+
+#altTextDialog #altTextContainer *:focus-visible{
+ outline:var(--focus-ring-outline);
+ outline-offset:2px;
+ }
+
+#altTextDialog #altTextContainer .radio{
+ display:flex;
+ flex-direction:column;
+ align-items:flex-start;
+ gap:4px;
+ }
+
+#altTextDialog #altTextContainer .radio .radioButton{
+ display:flex;
+ gap:8px;
+ align-self:stretch;
+ align-items:center;
+ }
+
+#altTextDialog #altTextContainer .radio .radioButton input{
+ -webkit-appearance:none;
+ -moz-appearance:none;
+ appearance:none;
+ box-sizing:border-box;
+ width:16px;
+ height:16px;
+ border-radius:50%;
+ background-color:var(--radio-bg-color);
+ border:1px solid var(--radio-border-color);
+ }
+
+#altTextDialog #altTextContainer .radio .radioButton input:hover{
+ filter:var(--hover-filter);
+ }
+
+#altTextDialog #altTextContainer .radio .radioButton input:checked{
+ background-color:var(--radio-checked-bg-color);
+ border:4px solid var(--radio-checked-border-color);
+ }
+
+#altTextDialog #altTextContainer .radio .radioLabel{
+ display:flex;
+ padding-inline-start:24px;
+ align-items:flex-start;
+ gap:10px;
+ align-self:stretch;
+ }
+
+#altTextDialog #altTextContainer .radio .radioLabel span{
+ flex:1 0 0;
+ font-size:11px;
+ color:var(--text-secondary-color);
+ }
+
+#altTextDialog #altTextContainer #overallDescription{
+ display:flex;
+ flex-direction:column;
+ align-items:flex-start;
+ gap:4px;
+ align-self:stretch;
+ }
+
+#altTextDialog #altTextContainer #overallDescription span{
+ align-self:stretch;
+ }
+
+#altTextDialog #altTextContainer #overallDescription .title{
+ font-size:13px;
+ font-style:normal;
+ font-weight:590;
+ }
+
+#altTextDialog #altTextContainer #addDescription{
+ display:flex;
+ flex-direction:column;
+ align-items:stretch;
+ gap:8px;
+ }
+
+#altTextDialog #altTextContainer #addDescription .descriptionArea{
+ flex:1;
+ padding-inline:24px 10px;
+ }
+
+#altTextDialog #altTextContainer #addDescription .descriptionArea textarea{
+ font:inherit;
+ width:100%;
+ min-height:75px;
+ padding:8px;
+ resize:none;
+ margin:0;
+ box-sizing:border-box;
+ border-radius:4px;
+ border:1px solid var(--textarea-border-color);
+ background:var(--textarea-bg-color);
+ color:var(--textarea-fg-color);
+ }
+
+#altTextDialog #altTextContainer #addDescription .descriptionArea textarea:focus{
+ outline-offset:0;
+ border-color:transparent;
+ }
+
+#altTextDialog #altTextContainer #addDescription .descriptionArea textarea:disabled{
+ pointer-events:none;
+ opacity:0.4;
+ }
+
+#altTextDialog #altTextContainer #buttons{
+ display:flex;
+ justify-content:flex-end;
+ align-items:flex-start;
+ gap:8px;
+ align-self:stretch;
+ }
+
+#altTextDialog #altTextContainer #buttons button{
+ border-radius:4px;
+ border:1px solid;
+ font:menu;
+ font-weight:600;
+ padding:4px 16px;
+ width:auto;
+ height:32px;
+ }
+
+#altTextDialog #altTextContainer #buttons button:hover{
+ cursor:pointer;
+ filter:var(--hover-filter);
+ }
+
+#altTextDialog #altTextContainer #buttons button#altTextCancel{
+ color:var(--button-cancel-fg-color);
+ background-color:var(--button-cancel-bg-color);
+ border-color:var(--button-cancel-border-color);
+ }
+
+#altTextDialog #altTextContainer #buttons button#altTextCancel:hover{
+ color:var(--button-cancel-hover-fg-color);
+ background-color:var(--button-cancel-hover-bg-color);
+ border-color:var(--button-cancel-hover-border-color);
+ }
+
+#altTextDialog #altTextContainer #buttons button#altTextSave{
+ color:var(--button-save-hover-fg-color);
+ background-color:var(--button-save-hover-bg-color);
+ border-color:var(--button-save-hover-border-color);
+ opacity:1;
+ }
+
+#altTextDialog #altTextContainer #buttons button#altTextSave:hover{
+ color:var(--button-save-hover-fg-color);
+ background-color:var(--button-save-hover-bg-color);
+ border-color:var(--button-save-hover-border-color);
+ }
+
+.colorPicker{
+ --hover-outline-color:#0250bb;
+ --selected-outline-color:#0060df;
+ --swatch-border-color:#cfcfd8;
+}
+
+@media (prefers-color-scheme: dark){
+
+:where(html:not(.is-light)) .colorPicker{
+ --hover-outline-color:#80ebff;
+ --selected-outline-color:#aaf2ff;
+ --swatch-border-color:#52525e;
+}
+ }
+
+:where(html.is-dark) .colorPicker{
+ --hover-outline-color:#80ebff;
+ --selected-outline-color:#aaf2ff;
+ --swatch-border-color:#52525e;
+}
+
+@media screen and (forced-colors: active){
+
+.colorPicker{
+ --hover-outline-color:Highlight;
+ --selected-outline-color:var(--hover-outline-color);
+ --swatch-border-color:ButtonText;
+}
+ }
+
+.colorPicker .swatch{
+ width:16px;
+ height:16px;
+ border:1px solid var(--swatch-border-color);
+ border-radius:100%;
+ outline-offset:2px;
+ box-sizing:border-box;
+ forced-color-adjust:none;
+ }
+
+.colorPicker button:is(:hover, .selected) > .swatch{
+ border:none;
+ }
+
+.annotationEditorLayer[data-main-rotation="0"] .highlightEditor > .editToolbar{
+ rotate:0deg;
+ }
+
+.annotationEditorLayer[data-main-rotation="90"] .highlightEditor > .editToolbar{
+ rotate:270deg;
+ }
+
+.annotationEditorLayer[data-main-rotation="180"] .highlightEditor > .editToolbar{
+ rotate:180deg;
+ }
+
+.annotationEditorLayer[data-main-rotation="270"] .highlightEditor > .editToolbar{
+ rotate:90deg;
+ }
+
+.annotationEditorLayer .highlightEditor{
+ position:absolute;
+ background:transparent;
+ z-index:1;
+ transform-origin:0 0;
+ cursor:auto;
+ max-width:100%;
+ max-height:100%;
+ border:none;
+ outline:none;
+ pointer-events:none;
+ transform:none;
+ }
+
+.annotationEditorLayer .highlightEditor .internal{
+ position:absolute;
+ top:0;
+ left:0;
+ width:100%;
+ height:100%;
+ pointer-events:auto;
+ }
+
+.annotationEditorLayer .highlightEditor.disabled .internal{
+ pointer-events:none;
+ }
+
+.annotationEditorLayer .highlightEditor.selectedEditor .internal{
+ cursor:pointer;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar{
+ --editor-toolbar-colorpicker-arrow-image:url(images/toolbarButton-menuArrow.svg);
+
+ transform-origin:center !important;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker{
+ position:relative;
+ width:auto;
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ gap:4px;
+ padding:4px;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker::after{
+ content:"";
+ -webkit-mask-image:var(--editor-toolbar-colorpicker-arrow-image);
+ mask-image:var(--editor-toolbar-colorpicker-arrow-image);
+ -webkit-mask-repeat:no-repeat;
+ mask-repeat:no-repeat;
+ -webkit-mask-position:center;
+ mask-position:center;
+ display:inline-block;
+ background-color:var(--editor-toolbar-fg-color);
+ width:12px;
+ height:12px;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker:hover::after{
+ background-color:var(--editor-toolbar-hover-fg-color);
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker:has(.dropdown:not(.hidden)){
+ background-color:var(--editor-toolbar-hover-bg-color);
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown{
+ position:absolute;
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ flex-direction:column;
+ gap:11px;
+ padding-block:8px;
+ border-radius:6px;
+ background-color:var(--editor-toolbar-bg-color);
+ border:1px solid var(--editor-toolbar-border-color);
+ box-shadow:var(--editor-toolbar-shadow);
+ inset-block-start:calc(100% + 4px);
+ width:calc(100% + 2 * var(--editor-toolbar-padding));
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown button{
+ width:100%;
+ height:auto;
+ border:none;
+ cursor:pointer;
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ background:none;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown button:is(:active, :focus-visible){
+ outline:none;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown button > .swatch{
+ outline-offset:2px;
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown button[aria-selected="true"] > .swatch{
+ outline:2px solid var(--selected-outline-color);
+ }
+
+.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker .dropdown button:is(:hover, :active, :focus-visible) > .swatch{
+ outline:2px solid var(--hover-outline-color);
+ }
+
+.editorParamsToolbar:has(#highlightParamsToolbarContainer){
+ padding:unset;
+}
+
+#highlightParamsToolbarContainer{
+ height:auto;
+ padding-inline:10px;
+ padding-block:10px 16px;
+ display:flex;
+ flex-direction:column;
+ box-sizing:border-box;
+}
+
+#highlightParamsToolbarContainer .colorPicker{
+ display:flex;
+ flex-direction:column;
+ gap:8px;
+ }
+
+#highlightParamsToolbarContainer .colorPicker #highlightColorPickerLabel{
+ width:-moz-fit-content;
+ width:fit-content;
+ inset-inline-start:0;
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown{
+ display:flex;
+ justify-content:space-between;
+ align-items:center;
+ flex-direction:row;
+ height:auto;
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown button{
+ width:auto;
+ height:auto;
+ border:none;
+ cursor:pointer;
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ background:none;
+ flex:0 0 auto;
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown button .swatch{
+ width:24px;
+ height:24px;
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown button:is(:active, :focus-visible){
+ outline:none;
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown button[aria-selected="true"] > .swatch{
+ outline:2px solid var(--selected-outline-color);
+ }
+
+#highlightParamsToolbarContainer .colorPicker .dropdown button:is(:hover, :active, :focus-visible) > .swatch{
+ outline:2px solid var(--hover-outline-color);
+ }
+
+:root{
+ --viewer-container-height:0;
+ --pdfViewer-padding-bottom:0;
+ --page-margin:1px auto -8px;
+ --page-border:9px solid transparent;
+ --spreadHorizontalWrapped-margin-LR:-3.5px;
+ --loading-icon-delay:400ms;
+}
+
+@media screen and (forced-colors: active){
+ :root{
+ --pdfViewer-padding-bottom:9px;
+ --page-margin:8px auto -1px;
+ --page-border:1px solid CanvasText;
+ --spreadHorizontalWrapped-margin-LR:3.5px;
+ }
+}
+
+[data-main-rotation="90"]{
+ transform:rotate(90deg) translateY(-100%);
+}
+[data-main-rotation="180"]{
+ transform:rotate(180deg) translate(-100%, -100%);
+}
+[data-main-rotation="270"]{
+ transform:rotate(270deg) translateX(-100%);
+}
+
+#hiddenCopyElement{
+ position:absolute;
+ top:0;
+ left:0;
+ width:0;
+ height:0;
+ display:none;
+}
+
+.pdfViewer{
+ --scale-factor:1;
+
+ padding-bottom:var(--pdfViewer-padding-bottom);
+}
+
+.pdfViewer .canvasWrapper{
+ overflow:hidden;
+ width:100%;
+ height:100%;
+ z-index:1;
+}
+
+.pdfViewer .page{
+ direction:ltr;
+ width:816px;
+ height:1056px;
+ margin:var(--page-margin);
+ position:relative;
+ overflow:visible;
+ border:var(--page-border);
+ background-clip:content-box;
+ background-color:rgb(255 255 255);
+}
+
+.pdfViewer .dummyPage{
+ position:relative;
+ width:0;
+ height:var(--viewer-container-height);
+}
+
+.pdfViewer.noUserSelect{
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+}
+
+.pdfViewer.removePageBorders .page{
+ margin:0 auto 10px;
+ border:none;
+}
+
+.pdfViewer:is(.scrollHorizontal, .scrollWrapped),
+.spread{
+ margin-inline:3.5px;
+ text-align:center;
+}
+
+.pdfViewer.scrollHorizontal,
+.spread{
+ white-space:nowrap;
+}
+
+.pdfViewer.removePageBorders,
+.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .spread{
+ margin-inline:0;
+}
+
+.spread :is(.page, .dummyPage),
+.pdfViewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread){
+ display:inline-block;
+ vertical-align:middle;
+}
+
+.spread .page,
+.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .page{
+ margin-inline:var(--spreadHorizontalWrapped-margin-LR);
+}
+
+.pdfViewer.removePageBorders .spread .page,
+.pdfViewer.removePageBorders:is(.scrollHorizontal, .scrollWrapped) .page{
+ margin-inline:5px;
+}
+
+.pdfViewer .page canvas{
+ margin:0;
+ display:block;
+}
+
+.pdfViewer .page canvas .structTree{
+ contain:strict;
+}
+
+.pdfViewer .page canvas[hidden]{
+ display:none;
+}
+
+.pdfViewer .page canvas[zooming]{
+ width:100%;
+ height:100%;
+}
+
+.pdfViewer .page.loadingIcon::after{
+ position:absolute;
+ top:0;
+ left:0;
+ content:"";
+ width:100%;
+ height:100%;
+ background:url("images/loading-icon.gif") center no-repeat;
+ display:none;
+ transition-property:display;
+ transition-delay:var(--loading-icon-delay);
+ z-index:5;
+ contain:strict;
+}
+
+.pdfViewer .page.loading::after{
+ display:block;
+}
+
+.pdfViewer .page:not(.loading)::after{
+ transition-property:none;
+ display:none;
+}
+
+.pdfPresentationMode .pdfViewer{
+ padding-bottom:0;
+}
+
+.pdfPresentationMode .spread{
+ margin:0;
+}
+
+.pdfPresentationMode .pdfViewer .page{
+ margin:0 auto;
+ border:2px solid transparent;
+}
+
+:root{
+ --dir-factor:1;
+ --inline-start:left;
+ --inline-end:right;
+
+ --sidebar-width:200px;
+ --sidebar-transition-duration:200ms;
+ --sidebar-transition-timing-function:ease;
+
+ --toolbar-icon-opacity:0.7;
+ --doorhanger-icon-opacity:0.9;
+ --editor-toolbar-base-offset:105px;
+
+ --main-color:rgb(12 12 13);
+ --body-bg-color:rgb(212 212 215);
+ --progressBar-color:rgb(10 132 255);
+ --progressBar-bg-color:rgb(221 221 222);
+ --progressBar-blend-color:rgb(116 177 239);
+ --scrollbar-color:auto;
+ --scrollbar-bg-color:auto;
+ --toolbar-icon-bg-color:rgb(0 0 0);
+ --toolbar-icon-hover-bg-color:rgb(0 0 0);
+
+ --sidebar-narrow-bg-color:rgb(212 212 215 / 0.9);
+ --sidebar-toolbar-bg-color:rgb(245 246 247);
+ --toolbar-bg-color:rgb(249 249 250);
+ --toolbar-border-color:rgb(184 184 184);
+ --toolbar-box-shadow:0 1px 0 var(--toolbar-border-color);
+ --toolbar-border-bottom:none;
+ --toolbarSidebar-box-shadow:inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25), 0 1px 0 rgb(0 0 0 / 0.15), 0 0 1px rgb(0 0 0 / 0.1);
+ --toolbarSidebar-border-bottom:none;
+ --button-hover-color:rgb(221 222 223);
+ --toggled-btn-color:rgb(0 0 0);
+ --toggled-btn-bg-color:rgb(0 0 0 / 0.3);
+ --toggled-hover-active-btn-color:rgb(0 0 0 / 0.4);
+ --toggled-hover-btn-outline:none;
+ --dropdown-btn-bg-color:rgb(215 215 219);
+ --dropdown-btn-border:none;
+ --separator-color:rgb(0 0 0 / 0.3);
+ --field-color:rgb(6 6 6);
+ --field-bg-color:rgb(255 255 255);
+ --field-border-color:rgb(187 187 188);
+ --treeitem-color:rgb(0 0 0 / 0.8);
+ --treeitem-bg-color:rgb(0 0 0 / 0.15);
+ --treeitem-hover-color:rgb(0 0 0 / 0.9);
+ --treeitem-selected-color:rgb(0 0 0 / 0.9);
+ --treeitem-selected-bg-color:rgb(0 0 0 / 0.25);
+ --thumbnail-hover-color:rgb(0 0 0 / 0.1);
+ --thumbnail-selected-color:rgb(0 0 0 / 0.2);
+ --doorhanger-bg-color:rgb(255 255 255);
+ --doorhanger-border-color:rgb(12 12 13 / 0.2);
+ --doorhanger-hover-color:rgb(12 12 13);
+ --doorhanger-hover-bg-color:rgb(237 237 237);
+ --doorhanger-separator-color:rgb(222 222 222);
+ --dialog-button-border:none;
+ --dialog-button-bg-color:rgb(12 12 13 / 0.1);
+ --dialog-button-hover-bg-color:rgb(12 12 13 / 0.3);
+
+ --loading-icon:url(images/loading.svg);
+ --treeitem-expanded-icon:url(images/treeitem-expanded.svg);
+ --treeitem-collapsed-icon:url(images/treeitem-collapsed.svg);
+ --toolbarButton-editorFreeText-icon:url(images/toolbarButton-editorFreeText.svg);
+ --toolbarButton-editorHighlight-icon:url(images/toolbarButton-editorHighlight.svg);
+ --toolbarButton-editorInk-icon:url(images/toolbarButton-editorInk.svg);
+ --toolbarButton-editorStamp-icon:url(images/toolbarButton-editorStamp.svg);
+ --toolbarButton-menuArrow-icon:url(images/toolbarButton-menuArrow.svg);
+ --toolbarButton-sidebarToggle-icon:url(images/toolbarButton-sidebarToggle.svg);
+ --toolbarButton-secondaryToolbarToggle-icon:url(images/toolbarButton-secondaryToolbarToggle.svg);
+ --toolbarButton-pageUp-icon:url(images/toolbarButton-pageUp.svg);
+ --toolbarButton-pageDown-icon:url(images/toolbarButton-pageDown.svg);
+ --toolbarButton-zoomOut-icon:url(images/toolbarButton-zoomOut.svg);
+ --toolbarButton-zoomIn-icon:url(images/toolbarButton-zoomIn.svg);
+ --toolbarButton-presentationMode-icon:url(images/toolbarButton-presentationMode.svg);
+ --toolbarButton-print-icon:url(images/toolbarButton-print.svg);
+ --toolbarButton-openFile-icon:url(images/toolbarButton-openFile.svg);
+ --toolbarButton-download-icon:url(images/toolbarButton-download.svg);
+ --toolbarButton-bookmark-icon:url(images/toolbarButton-bookmark.svg);
+ --toolbarButton-viewThumbnail-icon:url(images/toolbarButton-viewThumbnail.svg);
+ --toolbarButton-viewOutline-icon:url(images/toolbarButton-viewOutline.svg);
+ --toolbarButton-viewAttachments-icon:url(images/toolbarButton-viewAttachments.svg);
+ --toolbarButton-viewLayers-icon:url(images/toolbarButton-viewLayers.svg);
+ --toolbarButton-currentOutlineItem-icon:url(images/toolbarButton-currentOutlineItem.svg);
+ --toolbarButton-search-icon:url(images/toolbarButton-search.svg);
+ --findbarButton-previous-icon:url(images/findbarButton-previous.svg);
+ --findbarButton-next-icon:url(images/findbarButton-next.svg);
+ --secondaryToolbarButton-firstPage-icon:url(images/secondaryToolbarButton-firstPage.svg);
+ --secondaryToolbarButton-lastPage-icon:url(images/secondaryToolbarButton-lastPage.svg);
+ --secondaryToolbarButton-rotateCcw-icon:url(images/secondaryToolbarButton-rotateCcw.svg);
+ --secondaryToolbarButton-rotateCw-icon:url(images/secondaryToolbarButton-rotateCw.svg);
+ --secondaryToolbarButton-selectTool-icon:url(images/secondaryToolbarButton-selectTool.svg);
+ --secondaryToolbarButton-handTool-icon:url(images/secondaryToolbarButton-handTool.svg);
+ --secondaryToolbarButton-scrollPage-icon:url(images/secondaryToolbarButton-scrollPage.svg);
+ --secondaryToolbarButton-scrollVertical-icon:url(images/secondaryToolbarButton-scrollVertical.svg);
+ --secondaryToolbarButton-scrollHorizontal-icon:url(images/secondaryToolbarButton-scrollHorizontal.svg);
+ --secondaryToolbarButton-scrollWrapped-icon:url(images/secondaryToolbarButton-scrollWrapped.svg);
+ --secondaryToolbarButton-spreadNone-icon:url(images/secondaryToolbarButton-spreadNone.svg);
+ --secondaryToolbarButton-spreadOdd-icon:url(images/secondaryToolbarButton-spreadOdd.svg);
+ --secondaryToolbarButton-spreadEven-icon:url(images/secondaryToolbarButton-spreadEven.svg);
+ --secondaryToolbarButton-documentProperties-icon:url(images/secondaryToolbarButton-documentProperties.svg);
+ --editorParams-stampAddImage-icon:url(images/toolbarButton-zoomIn.svg);
+}
+
+[dir="rtl"]:root{
+ --dir-factor:-1;
+ --inline-start:right;
+ --inline-end:left;
+}
+
+@media (prefers-color-scheme: dark){
+ :root:where(:not(.is-light)){
+ --main-color:rgb(249 249 250);
+ --body-bg-color:rgb(42 42 46);
+ --progressBar-color:rgb(0 96 223);
+ --progressBar-bg-color:rgb(40 40 43);
+ --progressBar-blend-color:rgb(20 68 133);
+ --scrollbar-color:rgb(121 121 123);
+ --scrollbar-bg-color:rgb(35 35 39);
+ --toolbar-icon-bg-color:rgb(255 255 255);
+ --toolbar-icon-hover-bg-color:rgb(255 255 255);
+
+ --sidebar-narrow-bg-color:rgb(42 42 46 / 0.9);
+ --sidebar-toolbar-bg-color:rgb(50 50 52);
+ --toolbar-bg-color:rgb(56 56 61);
+ --toolbar-border-color:rgb(12 12 13);
+ --button-hover-color:rgb(102 102 103);
+ --toggled-btn-color:rgb(255 255 255);
+ --toggled-btn-bg-color:rgb(0 0 0 / 0.3);
+ --toggled-hover-active-btn-color:rgb(0 0 0 / 0.4);
+ --dropdown-btn-bg-color:rgb(74 74 79);
+ --separator-color:rgb(0 0 0 / 0.3);
+ --field-color:rgb(250 250 250);
+ --field-bg-color:rgb(64 64 68);
+ --field-border-color:rgb(115 115 115);
+ --treeitem-color:rgb(255 255 255 / 0.8);
+ --treeitem-bg-color:rgb(255 255 255 / 0.15);
+ --treeitem-hover-color:rgb(255 255 255 / 0.9);
+ --treeitem-selected-color:rgb(255 255 255 / 0.9);
+ --treeitem-selected-bg-color:rgb(255 255 255 / 0.25);
+ --thumbnail-hover-color:rgb(255 255 255 / 0.1);
+ --thumbnail-selected-color:rgb(255 255 255 / 0.2);
+ --doorhanger-bg-color:rgb(74 74 79);
+ --doorhanger-border-color:rgb(39 39 43);
+ --doorhanger-hover-color:rgb(249 249 250);
+ --doorhanger-hover-bg-color:rgb(93 94 98);
+ --doorhanger-separator-color:rgb(92 92 97);
+ --dialog-button-bg-color:rgb(92 92 97);
+ --dialog-button-hover-bg-color:rgb(115 115 115);
+ }
+}
+
+:root:where(.is-dark){
+ --main-color:rgb(249 249 250);
+ --body-bg-color:rgb(42 42 46);
+ --progressBar-color:rgb(0 96 223);
+ --progressBar-bg-color:rgb(40 40 43);
+ --progressBar-blend-color:rgb(20 68 133);
+ --scrollbar-color:rgb(121 121 123);
+ --scrollbar-bg-color:rgb(35 35 39);
+ --toolbar-icon-bg-color:rgb(255 255 255);
+ --toolbar-icon-hover-bg-color:rgb(255 255 255);
+
+ --sidebar-narrow-bg-color:rgb(42 42 46 / 0.9);
+ --sidebar-toolbar-bg-color:rgb(50 50 52);
+ --toolbar-bg-color:rgb(56 56 61);
+ --toolbar-border-color:rgb(12 12 13);
+ --button-hover-color:rgb(102 102 103);
+ --toggled-btn-color:rgb(255 255 255);
+ --toggled-btn-bg-color:rgb(0 0 0 / 0.3);
+ --toggled-hover-active-btn-color:rgb(0 0 0 / 0.4);
+ --dropdown-btn-bg-color:rgb(74 74 79);
+ --separator-color:rgb(0 0 0 / 0.3);
+ --field-color:rgb(250 250 250);
+ --field-bg-color:rgb(64 64 68);
+ --field-border-color:rgb(115 115 115);
+ --treeitem-color:rgb(255 255 255 / 0.8);
+ --treeitem-bg-color:rgb(255 255 255 / 0.15);
+ --treeitem-hover-color:rgb(255 255 255 / 0.9);
+ --treeitem-selected-color:rgb(255 255 255 / 0.9);
+ --treeitem-selected-bg-color:rgb(255 255 255 / 0.25);
+ --thumbnail-hover-color:rgb(255 255 255 / 0.1);
+ --thumbnail-selected-color:rgb(255 255 255 / 0.2);
+ --doorhanger-bg-color:rgb(74 74 79);
+ --doorhanger-border-color:rgb(39 39 43);
+ --doorhanger-hover-color:rgb(249 249 250);
+ --doorhanger-hover-bg-color:rgb(93 94 98);
+ --doorhanger-separator-color:rgb(92 92 97);
+ --dialog-button-bg-color:rgb(92 92 97);
+ --dialog-button-hover-bg-color:rgb(115 115 115);
+ }
+
+@media screen and (forced-colors: active){
+ :root{
+ --button-hover-color:Highlight;
+ --doorhanger-hover-bg-color:Highlight;
+ --toolbar-icon-opacity:1;
+ --toolbar-icon-bg-color:ButtonText;
+ --toolbar-icon-hover-bg-color:ButtonFace;
+ --toggled-hover-active-btn-color:ButtonText;
+ --toggled-hover-btn-outline:2px solid ButtonBorder;
+ --toolbar-border-color:CanvasText;
+ --toolbar-border-bottom:1px solid var(--toolbar-border-color);
+ --toolbar-box-shadow:none;
+ --toggled-btn-color:HighlightText;
+ --toggled-btn-bg-color:LinkText;
+ --doorhanger-hover-color:ButtonFace;
+ --doorhanger-border-color-whcm:1px solid ButtonText;
+ --doorhanger-triangle-opacity-whcm:0;
+ --dialog-button-border:1px solid Highlight;
+ --dialog-button-hover-bg-color:Highlight;
+ --dialog-button-hover-color:ButtonFace;
+ --dropdown-btn-border:1px solid ButtonText;
+ --field-border-color:ButtonText;
+ --main-color:CanvasText;
+ --separator-color:GrayText;
+ --doorhanger-separator-color:GrayText;
+ --toolbarSidebar-box-shadow:none;
+ --toolbarSidebar-border-bottom:1px solid var(--toolbar-border-color);
+ }
+}
+
+@media screen and (prefers-reduced-motion: reduce){
+ :root{
+ --sidebar-transition-duration:0;
+ }
+}
+
+*{
+ padding:0;
+ margin:0;
+}
+
+html,
+body{
+ height:100%;
+ width:100%;
+}
+
+body{
+ background-color:var(--body-bg-color);
+ scrollbar-color:var(--scrollbar-color) var(--scrollbar-bg-color);
+}
+
+.hidden,
+[hidden]{
+ display:none !important;
+}
+
+#viewerContainer.pdfPresentationMode:-webkit-full-screen{
+ top:0;
+ background-color:rgb(0 0 0);
+ width:100%;
+ height:100%;
+ overflow:hidden;
+ cursor:none;
+ -webkit-user-select:none;
+ user-select:none;
+}
+
+#viewerContainer.pdfPresentationMode:fullscreen{
+ top:0;
+ background-color:rgb(0 0 0);
+ width:100%;
+ height:100%;
+ overflow:hidden;
+ cursor:none;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+}
+
+.pdfPresentationMode:-webkit-full-screen section:not([data-internal-link]){
+ pointer-events:none;
+}
+
+.pdfPresentationMode:fullscreen section:not([data-internal-link]){
+ pointer-events:none;
+}
+
+.pdfPresentationMode:-webkit-full-screen .textLayer span{
+ cursor:none;
+}
+
+.pdfPresentationMode:fullscreen .textLayer span{
+ cursor:none;
+}
+
+.pdfPresentationMode.pdfPresentationModeControls > *,
+.pdfPresentationMode.pdfPresentationModeControls .textLayer span{
+ cursor:default;
+}
+
+#outerContainer{
+ width:100%;
+ height:100%;
+ position:relative;
+}
+
+#sidebarContainer{
+ position:absolute;
+ inset-block:32px 0;
+ inset-inline-start:calc(-1 * var(--sidebar-width));
+ width:var(--sidebar-width);
+ visibility:hidden;
+ z-index:100;
+ font:message-box;
+ border-top:1px solid rgb(51 51 51);
+ border-inline-end:var(--doorhanger-border-color-whcm);
+ transition-property:inset-inline-start;
+ transition-duration:var(--sidebar-transition-duration);
+ transition-timing-function:var(--sidebar-transition-timing-function);
+}
+
+#outerContainer:is(.sidebarMoving, .sidebarOpen) #sidebarContainer{
+ visibility:visible;
+}
+#outerContainer.sidebarOpen #sidebarContainer{
+ inset-inline-start:0;
+}
+
+#mainContainer{
+ position:absolute;
+ inset:0;
+ min-width:350px;
+}
+
+#sidebarContent{
+ inset-block:32px 0;
+ inset-inline-start:0;
+ overflow:auto;
+ position:absolute;
+ width:100%;
+ box-shadow:inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25);
+}
+
+#viewerContainer{
+ overflow:auto;
+ position:absolute;
+ inset:32px 0 0;
+ outline:none;
+}
+#viewerContainer:not(.pdfPresentationMode){
+ transition-duration:var(--sidebar-transition-duration);
+ transition-timing-function:var(--sidebar-transition-timing-function);
+}
+
+#outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode){
+ inset-inline-start:var(--sidebar-width);
+ transition-property:inset-inline-start;
+}
+
+.toolbar{
+ position:relative;
+ inset-inline:0;
+ z-index:9999;
+ cursor:default;
+ font:message-box;
+}
+
+:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer)
+ :is(input, button, select),
+.secondaryToolbar :is(input, button, a, select){
+ outline:none;
+ font:message-box;
+}
+
+#toolbarContainer{
+ width:100%;
+}
+
+#toolbarSidebar{
+ width:100%;
+ height:32px;
+ background-color:var(--sidebar-toolbar-bg-color);
+ box-shadow:var(--toolbarSidebar-box-shadow);
+ border-bottom:var(--toolbarSidebar-border-bottom);
+}
+
+#sidebarResizer{
+ position:absolute;
+ inset-block:0;
+ inset-inline-end:-6px;
+ width:6px;
+ z-index:200;
+ cursor:ew-resize;
+}
+
+#toolbarContainer,
+.findbar,
+.secondaryToolbar,
+.editorParamsToolbar{
+ position:relative;
+ height:32px;
+ background-color:var(--toolbar-bg-color);
+ box-shadow:var(--toolbar-box-shadow);
+ border-bottom:var(--toolbar-border-bottom);
+}
+
+#toolbarViewer{
+ height:32px;
+}
+
+#loadingBar{
+ --progressBar-percent:0%;
+ --progressBar-end-offset:0;
+
+ position:absolute;
+ inset-inline:0 var(--progressBar-end-offset);
+ height:4px;
+ background-color:var(--progressBar-bg-color);
+ border-bottom:1px solid var(--toolbar-border-color);
+ transition-property:inset-inline-start;
+ transition-duration:var(--sidebar-transition-duration);
+ transition-timing-function:var(--sidebar-transition-timing-function);
+}
+
+#outerContainer.sidebarOpen #loadingBar{
+ inset-inline-start:var(--sidebar-width);
+}
+
+#loadingBar .progress{
+ position:absolute;
+ top:0;
+ inset-inline-start:0;
+ width:100%;
+ transform:scaleX(var(--progressBar-percent));
+ transform-origin:calc(50% - 50% * var(--dir-factor)) 0;
+ height:100%;
+ background-color:var(--progressBar-color);
+ overflow:hidden;
+ transition:transform 200ms;
+}
+
+@keyframes progressIndeterminate{
+ 0%{
+ transform:translateX(calc(-142px * var(--dir-factor)));
+ }
+ 100%{
+ transform:translateX(0);
+ }
+}
+
+#loadingBar.indeterminate .progress{
+ transform:none;
+ background-color:var(--progressBar-bg-color);
+ transition:none;
+}
+
+#loadingBar.indeterminate .progress .glimmer{
+ position:absolute;
+ top:0;
+ inset-inline-start:0;
+ height:100%;
+ width:calc(100% + 150px);
+ background:repeating-linear-gradient(
+ 135deg,
+ var(--progressBar-blend-color) 0,
+ var(--progressBar-bg-color) 5px,
+ var(--progressBar-bg-color) 45px,
+ var(--progressBar-color) 55px,
+ var(--progressBar-color) 95px,
+ var(--progressBar-blend-color) 100px
+ );
+ animation:progressIndeterminate 1s linear infinite;
+}
+
+#outerContainer.sidebarResizing
+ :is(#sidebarContainer, #viewerContainer, #loadingBar){
+ transition-duration:0s;
+}
+
+.findbar,
+.secondaryToolbar,
+.editorParamsToolbar{
+ top:32px;
+ position:absolute;
+ z-index:30000;
+ height:auto;
+ padding:0 4px;
+ margin:4px 2px;
+ font:message-box;
+ font-size:12px;
+ line-height:14px;
+ text-align:left;
+ cursor:default;
+}
+
+.findbar{
+ inset-inline-start:64px;
+ min-width:300px;
+ background-color:var(--toolbar-bg-color);
+}
+.findbar > div{
+ height:32px;
+}
+.findbar > div#findbarInputContainer{
+ margin-inline-end:4px;
+}
+.findbar.wrapContainers > div,
+.findbar.wrapContainers > div#findbarMessageContainer > *{
+ clear:both;
+}
+.findbar.wrapContainers > div#findbarMessageContainer{
+ height:auto;
+}
+
+.findbar input[type="checkbox"]{
+ pointer-events:none;
+}
+
+.findbar label{
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+}
+
+.findbar label:hover,
+.findbar input:focus-visible + label{
+ color:var(--toggled-btn-color);
+ background-color:var(--button-hover-color);
+}
+
+.findbar .toolbarField[type="checkbox"]:checked + .toolbarLabel{
+ background-color:var(--toggled-btn-bg-color) !important;
+ color:var(--toggled-btn-color);
+}
+
+#findInput{
+ width:200px;
+}
+
+#findInput::-moz-placeholder{
+ font-style:normal;
+ }
+
+#findInput::placeholder{
+ font-style:normal;
+ }
+
+.loadingInput:has(> #findInput[data-status="pending"])::after{
+ visibility:visible;
+ }
+
+#findInput[data-status="notFound"]{
+ background-color:rgb(255 102 102);
+ }
+
+.secondaryToolbar,
+.editorParamsToolbar{
+ padding:6px 0 10px;
+ inset-inline-end:4px;
+ height:auto;
+ background-color:var(--doorhanger-bg-color);
+}
+
+.editorParamsToolbarContainer{
+ width:220px;
+ margin-bottom:-4px;
+}
+
+.editorParamsToolbarContainer > .editorParamsSetter{
+ min-height:26px;
+ display:flex;
+ align-items:center;
+ justify-content:space-between;
+ padding-inline:10px;
+}
+
+.editorParamsToolbarContainer .editorParamsLabel{
+ padding-inline-end:10px;
+ flex:none;
+ font:menu;
+ font-size:13px;
+ font-style:normal;
+ font-weight:400;
+ line-height:150%;
+ color:var(--main-color);
+}
+
+.editorParamsToolbarContainer .editorParamsColor{
+ width:32px;
+ height:32px;
+ flex:none;
+}
+
+.editorParamsToolbarContainer .editorParamsSlider{
+ background-color:transparent;
+ width:90px;
+ flex:0 1 0;
+}
+
+.editorParamsToolbarContainer .editorParamsSlider::-moz-range-progress{
+ background-color:black;
+}
+
+.editorParamsToolbarContainer .editorParamsSlider::-webkit-slider-runnable-track,
+.editorParamsToolbarContainer .editorParamsSlider::-moz-range-track{
+ background-color:black;
+}
+
+.editorParamsToolbarContainer .editorParamsSlider::-webkit-slider-thumb,
+.editorParamsToolbarContainer .editorParamsSlider::-moz-range-thumb{
+ background-color:white;
+}
+
+#secondaryToolbarButtonContainer{
+ max-width:220px;
+ min-height:26px;
+ max-height:calc(var(--viewer-container-height) - 40px);
+ overflow-y:auto;
+ margin-bottom:-4px;
+}
+
+#editorStampParamsToolbar{
+ inset-inline-end:calc(var(--editor-toolbar-base-offset) + 0px);
+}
+
+#editorInkParamsToolbar{
+ inset-inline-end:calc(var(--editor-toolbar-base-offset) + 28px);
+}
+
+#editorFreeTextParamsToolbar{
+ inset-inline-end:calc(var(--editor-toolbar-base-offset) + 56px);
+}
+
+#editorHighlightParamsToolbar{
+ inset-inline-end:calc(var(--editor-toolbar-base-offset) + 84px);
+}
+
+#editorStampAddImage::before{
+ -webkit-mask-image:var(--editorParams-stampAddImage-icon);
+ mask-image:var(--editorParams-stampAddImage-icon);
+}
+
+.doorHanger,
+.doorHangerRight{
+ border-radius:2px;
+ box-shadow:0 1px 5px var(--doorhanger-border-color), 0 0 0 1px var(--doorhanger-border-color);
+ border:var(--doorhanger-border-color-whcm);
+}
+:is(.doorHanger, .doorHangerRight)::after,
+:is(.doorHanger, .doorHangerRight)::before{
+ bottom:100%;
+ border:8px solid rgb(0 0 0 / 0);
+ content:" ";
+ height:0;
+ width:0;
+ position:absolute;
+ pointer-events:none;
+ opacity:var(--doorhanger-triangle-opacity-whcm);
+}
+.doorHanger::after{
+ inset-inline-start:10px;
+ margin-inline-start:-8px;
+ border-bottom-color:var(--toolbar-bg-color);
+}
+.doorHangerRight::after{
+ inset-inline-end:10px;
+ margin-inline-end:-8px;
+ border-bottom-color:var(--doorhanger-bg-color);
+}
+:is(.doorHanger, .doorHangerRight)::before{
+ border-bottom-color:var(--doorhanger-border-color);
+ border-width:9px;
+}
+.doorHanger::before{
+ inset-inline-start:10px;
+ margin-inline-start:-9px;
+}
+.doorHangerRight::before{
+ inset-inline-end:10px;
+ margin-inline-end:-9px;
+}
+
+#findResultsCount{
+ background-color:rgb(217 217 217);
+ color:rgb(82 82 82);
+ text-align:center;
+ padding:4px 5px;
+ margin:5px;
+}
+
+#findMsg[data-status="notFound"]{
+ font-weight:bold;
+}
+
+:is(#findResultsCount, #findMsg):empty{
+ display:none;
+}
+
+#toolbarViewerMiddle{
+ position:absolute;
+ left:50%;
+ transform:translateX(-50%);
+}
+
+#toolbarViewerLeft,
+#toolbarSidebarLeft{
+ float:var(--inline-start);
+}
+#toolbarViewerRight,
+#toolbarSidebarRight{
+ float:var(--inline-end);
+}
+
+#toolbarViewerLeft > *,
+#toolbarViewerMiddle > *,
+#toolbarViewerRight > *,
+#toolbarSidebarLeft *,
+#toolbarSidebarRight *,
+.findbar *{
+ position:relative;
+ float:var(--inline-start);
+}
+
+#toolbarViewerLeft{
+ padding-inline-start:1px;
+}
+#toolbarViewerRight{
+ padding-inline-end:1px;
+}
+#toolbarSidebarRight{
+ padding-inline-end:2px;
+}
+
+.splitToolbarButton{
+ margin:2px;
+ display:inline-block;
+}
+.splitToolbarButton > .toolbarButton{
+ float:var(--inline-start);
+}
+
+.toolbarButton,
+.secondaryToolbarButton,
+.dialogButton{
+ border:none;
+ background:none;
+ width:28px;
+ height:28px;
+ outline:none;
+}
+
+.dialogButton:is(:hover, :focus-visible){
+ background-color:var(--dialog-button-hover-bg-color);
+}
+
+.dialogButton:is(:hover, :focus-visible) > span{
+ color:var(--dialog-button-hover-color);
+}
+
+.toolbarButton > span{
+ display:inline-block;
+ width:0;
+ height:0;
+ overflow:hidden;
+}
+
+:is(.toolbarButton, .secondaryToolbarButton, .dialogButton)[disabled]{
+ opacity:0.5;
+}
+
+.splitToolbarButton > .toolbarButton:is(:hover, :focus-visible),
+.dropdownToolbarButton:hover{
+ background-color:var(--button-hover-color);
+}
+.splitToolbarButton > .toolbarButton{
+ position:relative;
+ margin:0;
+}
+#toolbarSidebar .splitToolbarButton > .toolbarButton{
+ margin-inline-end:2px;
+}
+
+.splitToolbarButtonSeparator{
+ float:var(--inline-start);
+ margin:4px 0;
+ width:1px;
+ height:20px;
+ background-color:var(--separator-color);
+}
+
+.toolbarButton,
+.dropdownToolbarButton,
+.secondaryToolbarButton,
+.dialogButton{
+ min-width:16px;
+ margin:2px 1px;
+ padding:2px 6px 0;
+ border:none;
+ border-radius:2px;
+ color:var(--main-color);
+ font-size:12px;
+ line-height:14px;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ cursor:default;
+ box-sizing:border-box;
+}
+
+.toolbarButton:is(:hover, :focus-visible){
+ background-color:var(--button-hover-color);
+}
+.secondaryToolbarButton:is(:hover, :focus-visible){
+ background-color:var(--doorhanger-hover-bg-color);
+ color:var(--doorhanger-hover-color);
+}
+
+:is(.toolbarButton, .secondaryToolbarButton).toggled,
+.splitToolbarButton.toggled > .toolbarButton.toggled{
+ background-color:var(--toggled-btn-bg-color);
+ color:var(--toggled-btn-color);
+}
+
+:is(.toolbarButton, .secondaryToolbarButton).toggled:hover,
+.splitToolbarButton.toggled > .toolbarButton.toggled:hover{
+ outline:var(--toggled-hover-btn-outline) !important;
+}
+
+:is(.toolbarButton, .secondaryToolbarButton).toggled::before{
+ background-color:var(--toggled-btn-color);
+}
+
+:is(.toolbarButton, .secondaryToolbarButton).toggled:hover:active,
+.splitToolbarButton.toggled > .toolbarButton.toggled:hover:active{
+ background-color:var(--toggled-hover-active-btn-color);
+}
+
+.dropdownToolbarButton{
+ display:flex;
+ width:-moz-fit-content;
+ width:fit-content;
+ min-width:140px;
+ padding:0;
+ background-color:var(--dropdown-btn-bg-color);
+ border:var(--dropdown-btn-border);
+}
+.dropdownToolbarButton::after{
+ top:6px;
+ inset-inline-end:6px;
+ pointer-events:none;
+ -webkit-mask-image:var(--toolbarButton-menuArrow-icon);
+ mask-image:var(--toolbarButton-menuArrow-icon);
+}
+
+.dropdownToolbarButton > select{
+ -webkit-appearance:none;
+ -moz-appearance:none;
+ appearance:none;
+ width:inherit;
+ min-width:inherit;
+ height:28px;
+ font-size:12px;
+ color:var(--main-color);
+ margin:0;
+ padding-block:1px 2px;
+ padding-inline:6px 38px;
+ border:none;
+ background-color:var(--dropdown-btn-bg-color);
+}
+.dropdownToolbarButton > select:is(:hover, :focus-visible){
+ background-color:var(--button-hover-color);
+ color:var(--toggled-btn-color);
+}
+.dropdownToolbarButton > select > option{
+ background:var(--doorhanger-bg-color);
+ color:var(--main-color);
+}
+
+.toolbarButtonSpacer{
+ width:30px;
+ display:inline-block;
+ height:1px;
+}
+
+:is(.toolbarButton, .secondaryToolbarButton, .treeItemToggler)::before,
+.dropdownToolbarButton::after{
+ position:absolute;
+ display:inline-block;
+ width:16px;
+ height:16px;
+
+ content:"";
+ background-color:var(--toolbar-icon-bg-color);
+ -webkit-mask-size:cover;
+ mask-size:cover;
+}
+
+.dropdownToolbarButton:is(:hover, :focus-visible, :active)::after{
+ background-color:var(--toolbar-icon-hover-bg-color);
+}
+
+.toolbarButton::before{
+ opacity:var(--toolbar-icon-opacity);
+ top:6px;
+ left:6px;
+}
+
+.toolbarButton:is(:hover, :focus-visible)::before,
+.secondaryToolbarButton:is(:hover, :focus-visible)::before{
+ background-color:var(--toolbar-icon-hover-bg-color);
+}
+
+.secondaryToolbarButton::before{
+ opacity:var(--doorhanger-icon-opacity);
+ top:5px;
+ inset-inline-start:12px;
+}
+
+#sidebarToggle::before{
+ -webkit-mask-image:var(--toolbarButton-sidebarToggle-icon);
+ mask-image:var(--toolbarButton-sidebarToggle-icon);
+ transform:scaleX(var(--dir-factor));
+}
+
+#secondaryToolbarToggle::before{
+ -webkit-mask-image:var(--toolbarButton-secondaryToolbarToggle-icon);
+ mask-image:var(--toolbarButton-secondaryToolbarToggle-icon);
+ transform:scaleX(var(--dir-factor));
+}
+
+#findPrevious::before{
+ -webkit-mask-image:var(--findbarButton-previous-icon);
+ mask-image:var(--findbarButton-previous-icon);
+}
+
+#findNext::before{
+ -webkit-mask-image:var(--findbarButton-next-icon);
+ mask-image:var(--findbarButton-next-icon);
+}
+
+#previous::before{
+ -webkit-mask-image:var(--toolbarButton-pageUp-icon);
+ mask-image:var(--toolbarButton-pageUp-icon);
+}
+
+#next::before{
+ -webkit-mask-image:var(--toolbarButton-pageDown-icon);
+ mask-image:var(--toolbarButton-pageDown-icon);
+}
+
+#zoomOut::before{
+ -webkit-mask-image:var(--toolbarButton-zoomOut-icon);
+ mask-image:var(--toolbarButton-zoomOut-icon);
+}
+
+#zoomIn::before{
+ -webkit-mask-image:var(--toolbarButton-zoomIn-icon);
+ mask-image:var(--toolbarButton-zoomIn-icon);
+}
+
+#presentationMode::before{
+ -webkit-mask-image:var(--toolbarButton-presentationMode-icon);
+ mask-image:var(--toolbarButton-presentationMode-icon);
+}
+
+#editorFreeText::before{
+ -webkit-mask-image:var(--toolbarButton-editorFreeText-icon);
+ mask-image:var(--toolbarButton-editorFreeText-icon);
+}
+
+#editorHighlight::before{
+ -webkit-mask-image:var(--toolbarButton-editorHighlight-icon);
+ mask-image:var(--toolbarButton-editorHighlight-icon);
+}
+
+#editorInk::before{
+ -webkit-mask-image:var(--toolbarButton-editorInk-icon);
+ mask-image:var(--toolbarButton-editorInk-icon);
+}
+
+#editorStamp::before{
+ -webkit-mask-image:var(--toolbarButton-editorStamp-icon);
+ mask-image:var(--toolbarButton-editorStamp-icon);
+}
+
+:is(#print, #secondaryPrint)::before{
+ -webkit-mask-image:var(--toolbarButton-print-icon);
+ mask-image:var(--toolbarButton-print-icon);
+}
+
+#secondaryOpenFile::before{
+ -webkit-mask-image:var(--toolbarButton-openFile-icon);
+ mask-image:var(--toolbarButton-openFile-icon);
+}
+
+:is(#download, #secondaryDownload)::before{
+ -webkit-mask-image:var(--toolbarButton-download-icon);
+ mask-image:var(--toolbarButton-download-icon);
+}
+
+a.secondaryToolbarButton{
+ padding-top:5px;
+ text-decoration:none;
+}
+a:is(.toolbarButton, .secondaryToolbarButton)[href="#"]{
+ opacity:0.5;
+ pointer-events:none;
+}
+
+#viewBookmark::before{
+ -webkit-mask-image:var(--toolbarButton-bookmark-icon);
+ mask-image:var(--toolbarButton-bookmark-icon);
+}
+
+#viewThumbnail::before{
+ -webkit-mask-image:var(--toolbarButton-viewThumbnail-icon);
+ mask-image:var(--toolbarButton-viewThumbnail-icon);
+}
+
+#viewOutline::before{
+ -webkit-mask-image:var(--toolbarButton-viewOutline-icon);
+ mask-image:var(--toolbarButton-viewOutline-icon);
+ transform:scaleX(var(--dir-factor));
+}
+
+#viewAttachments::before{
+ -webkit-mask-image:var(--toolbarButton-viewAttachments-icon);
+ mask-image:var(--toolbarButton-viewAttachments-icon);
+}
+
+#viewLayers::before{
+ -webkit-mask-image:var(--toolbarButton-viewLayers-icon);
+ mask-image:var(--toolbarButton-viewLayers-icon);
+}
+
+#currentOutlineItem::before{
+ -webkit-mask-image:var(--toolbarButton-currentOutlineItem-icon);
+ mask-image:var(--toolbarButton-currentOutlineItem-icon);
+ transform:scaleX(var(--dir-factor));
+}
+
+#viewFind::before{
+ -webkit-mask-image:var(--toolbarButton-search-icon);
+ mask-image:var(--toolbarButton-search-icon);
+}
+
+.pdfSidebarNotification::after{
+ position:absolute;
+ display:inline-block;
+ top:2px;
+ inset-inline-end:2px;
+ content:"";
+ background-color:rgb(112 219 85);
+ height:9px;
+ width:9px;
+ border-radius:50%;
+}
+
+.secondaryToolbarButton{
+ position:relative;
+ margin:0;
+ padding:0 0 1px;
+ padding-inline-start:36px;
+ height:auto;
+ min-height:26px;
+ width:auto;
+ min-width:100%;
+ text-align:start;
+ white-space:normal;
+ border-radius:0;
+ box-sizing:border-box;
+ display:inline-block;
+}
+.secondaryToolbarButton > span{
+ padding-inline-end:4px;
+}
+
+#firstPage::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-firstPage-icon);
+ mask-image:var(--secondaryToolbarButton-firstPage-icon);
+}
+
+#lastPage::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-lastPage-icon);
+ mask-image:var(--secondaryToolbarButton-lastPage-icon);
+}
+
+#pageRotateCcw::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-rotateCcw-icon);
+ mask-image:var(--secondaryToolbarButton-rotateCcw-icon);
+}
+
+#pageRotateCw::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-rotateCw-icon);
+ mask-image:var(--secondaryToolbarButton-rotateCw-icon);
+}
+
+#cursorSelectTool::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-selectTool-icon);
+ mask-image:var(--secondaryToolbarButton-selectTool-icon);
+}
+
+#cursorHandTool::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-handTool-icon);
+ mask-image:var(--secondaryToolbarButton-handTool-icon);
+}
+
+#scrollPage::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-scrollPage-icon);
+ mask-image:var(--secondaryToolbarButton-scrollPage-icon);
+}
+
+#scrollVertical::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-scrollVertical-icon);
+ mask-image:var(--secondaryToolbarButton-scrollVertical-icon);
+}
+
+#scrollHorizontal::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-scrollHorizontal-icon);
+ mask-image:var(--secondaryToolbarButton-scrollHorizontal-icon);
+}
+
+#scrollWrapped::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-scrollWrapped-icon);
+ mask-image:var(--secondaryToolbarButton-scrollWrapped-icon);
+}
+
+#spreadNone::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-spreadNone-icon);
+ mask-image:var(--secondaryToolbarButton-spreadNone-icon);
+}
+
+#spreadOdd::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-spreadOdd-icon);
+ mask-image:var(--secondaryToolbarButton-spreadOdd-icon);
+}
+
+#spreadEven::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-spreadEven-icon);
+ mask-image:var(--secondaryToolbarButton-spreadEven-icon);
+}
+
+#documentProperties::before{
+ -webkit-mask-image:var(--secondaryToolbarButton-documentProperties-icon);
+ mask-image:var(--secondaryToolbarButton-documentProperties-icon);
+}
+
+.verticalToolbarSeparator{
+ display:block;
+ margin:5px 2px;
+ width:1px;
+ height:22px;
+ background-color:var(--separator-color);
+}
+.horizontalToolbarSeparator{
+ display:block;
+ margin:6px 0;
+ height:1px;
+ width:100%;
+ background-color:var(--doorhanger-separator-color);
+}
+
+.toolbarField{
+ padding:4px 7px;
+ margin:3px 0;
+ border-radius:2px;
+ background-color:var(--field-bg-color);
+ background-clip:padding-box;
+ border:1px solid var(--field-border-color);
+ box-shadow:none;
+ color:var(--field-color);
+ font-size:12px;
+ line-height:16px;
+ outline:none;
+}
+
+.toolbarField[type="checkbox"]{
+ opacity:0;
+ position:absolute !important;
+ left:0;
+ margin:10px 0 3px;
+ margin-inline-start:7px;
+}
+
+#pageNumber{
+ -moz-appearance:textfield;
+ text-align:end;
+ width:40px;
+ background-size:0 0;
+ transition-property:none;
+}
+
+#pageNumber::-webkit-inner-spin-button{
+ -webkit-appearance:none;
+ }
+
+.loadingInput:has(> #pageNumber.loading)::after{
+ visibility:visible;
+
+ transition-property:visibility;
+ transition-delay:var(--loading-icon-delay);
+ }
+
+.loadingInput::after{
+ position:absolute;
+ visibility:hidden;
+ top:calc(50% - 8px);
+ width:16px;
+ height:16px;
+
+ content:"";
+ background-color:var(--toolbar-icon-bg-color);
+ -webkit-mask-size:cover;
+ mask-size:cover;
+ -webkit-mask-image:var(--loading-icon);
+ mask-image:var(--loading-icon);
+ }
+
+.loadingInput.start::after{
+ inset-inline-start:4px;
+ }
+
+.loadingInput.end::after{
+ inset-inline-end:4px;
+ }
+
+.toolbarField:focus{
+ border-color:#0a84ff;
+}
+
+.toolbarLabel{
+ min-width:16px;
+ padding:7px;
+ margin:2px;
+ border-radius:2px;
+ color:var(--main-color);
+ font-size:12px;
+ line-height:14px;
+ text-align:left;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ cursor:default;
+}
+
+#numPages.toolbarLabel{
+ padding-inline-start:3px;
+}
+
+#thumbnailView,
+#outlineView,
+#attachmentsView,
+#layersView{
+ position:absolute;
+ width:calc(100% - 8px);
+ inset-block:0;
+ padding:4px 4px 0;
+ overflow:auto;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+}
+#thumbnailView{
+ width:calc(100% - 60px);
+ padding:10px 30px 0;
+}
+
+#thumbnailView > a:is(:active, :focus){
+ outline:0;
+}
+
+.thumbnail{
+ --thumbnail-width:0;
+ --thumbnail-height:0;
+
+ float:var(--inline-start);
+ width:var(--thumbnail-width);
+ height:var(--thumbnail-height);
+ margin:0 10px 5px;
+ padding:1px;
+ border:7px solid transparent;
+ border-radius:2px;
+}
+
+#thumbnailView > a:last-of-type > .thumbnail{
+ margin-bottom:10px;
+}
+
+a:focus > .thumbnail,
+.thumbnail:hover{
+ border-color:var(--thumbnail-hover-color);
+}
+.thumbnail.selected{
+ border-color:var(--thumbnail-selected-color) !important;
+}
+
+.thumbnailImage{
+ width:var(--thumbnail-width);
+ height:var(--thumbnail-height);
+ opacity:0.9;
+}
+a:focus > .thumbnail > .thumbnailImage,
+.thumbnail:hover > .thumbnailImage{
+ opacity:0.95;
+}
+.thumbnail.selected > .thumbnailImage{
+ opacity:1 !important;
+}
+
+.thumbnail:not([data-loaded]) > .thumbnailImage{
+ width:calc(var(--thumbnail-width) - 2px);
+ height:calc(var(--thumbnail-height) - 2px);
+ border:1px dashed rgb(132 132 132);
+}
+
+.treeWithDeepNesting > .treeItem,
+.treeItem > .treeItems{
+ margin-inline-start:20px;
+}
+
+.treeItem > a{
+ text-decoration:none;
+ display:inline-block;
+ min-width:calc(100% - 4px);
+ height:auto;
+ margin-bottom:1px;
+ padding:2px 0 5px;
+ padding-inline-start:4px;
+ border-radius:2px;
+ color:var(--treeitem-color);
+ font-size:13px;
+ line-height:15px;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ white-space:normal;
+ cursor:pointer;
+}
+
+#layersView .treeItem > a *{
+ cursor:pointer;
+}
+#layersView .treeItem > a > label{
+ padding-inline-start:4px;
+}
+#layersView .treeItem > a > label > input{
+ float:var(--inline-start);
+ margin-top:1px;
+}
+
+.treeItemToggler{
+ position:relative;
+ float:var(--inline-start);
+ height:0;
+ width:0;
+ color:rgb(255 255 255 / 0.5);
+}
+.treeItemToggler::before{
+ inset-inline-end:4px;
+ -webkit-mask-image:var(--treeitem-expanded-icon);
+ mask-image:var(--treeitem-expanded-icon);
+}
+.treeItemToggler.treeItemsHidden::before{
+ -webkit-mask-image:var(--treeitem-collapsed-icon);
+ mask-image:var(--treeitem-collapsed-icon);
+ transform:scaleX(var(--dir-factor));
+}
+.treeItemToggler.treeItemsHidden ~ .treeItems{
+ display:none;
+}
+
+.treeItem.selected > a{
+ background-color:var(--treeitem-selected-bg-color);
+ color:var(--treeitem-selected-color);
+}
+
+.treeItemToggler:hover,
+.treeItemToggler:hover + a,
+.treeItemToggler:hover ~ .treeItems,
+.treeItem > a:hover{
+ background-color:var(--treeitem-bg-color);
+ background-clip:padding-box;
+ border-radius:2px;
+ color:var(--treeitem-hover-color);
+}
+
+#outlineOptionsContainer{
+ display:none;
+}
+
+#sidebarContainer:has(#outlineView:not(.hidden)) #outlineOptionsContainer{
+ display:inherit;
+ }
+
+.dialogButton{
+ width:auto;
+ margin:3px 4px 2px !important;
+ padding:2px 11px;
+ color:var(--main-color);
+ background-color:var(--dialog-button-bg-color);
+ border:var(--dialog-button-border) !important;
+}
+
+dialog{
+ margin:auto;
+ padding:15px;
+ border-spacing:4px;
+ color:var(--main-color);
+ font:message-box;
+ font-size:12px;
+ line-height:14px;
+ background-color:var(--doorhanger-bg-color);
+ border:1px solid rgb(0 0 0 / 0.5);
+ border-radius:4px;
+ box-shadow:0 1px 4px rgb(0 0 0 / 0.3);
+}
+dialog::backdrop{
+ background-color:rgb(0 0 0 / 0.2);
+}
+
+dialog > .row{
+ display:table-row;
+}
+
+dialog > .row > *{
+ display:table-cell;
+}
+
+dialog .toolbarField{
+ margin:5px 0;
+}
+
+dialog .separator{
+ display:block;
+ margin:4px 0;
+ height:1px;
+ width:100%;
+ background-color:var(--separator-color);
+}
+
+dialog .buttonRow{
+ text-align:center;
+ vertical-align:middle;
+}
+
+dialog :link{
+ color:rgb(255 255 255);
+}
+
+#passwordDialog{
+ text-align:center;
+}
+#passwordDialog .toolbarField{
+ width:200px;
+}
+
+#documentPropertiesDialog{
+ text-align:left;
+}
+#documentPropertiesDialog .row > *{
+ min-width:100px;
+ text-align:start;
+}
+#documentPropertiesDialog .row > span{
+ width:125px;
+ word-wrap:break-word;
+}
+#documentPropertiesDialog .row > p{
+ max-width:225px;
+ word-wrap:break-word;
+}
+#documentPropertiesDialog .buttonRow{
+ margin-top:10px;
+}
+
+.grab-to-pan-grab{
+ cursor:grab !important;
+}
+.grab-to-pan-grab
+ *:not(input):not(textarea):not(button):not(select):not(:link){
+ cursor:inherit !important;
+}
+.grab-to-pan-grab:active,
+.grab-to-pan-grabbing{
+ cursor:grabbing !important;
+}
+.grab-to-pan-grabbing{
+ position:fixed;
+ background:rgb(0 0 0 / 0);
+ display:block;
+ inset:0;
+ overflow:hidden;
+ z-index:50000;
+}
+
+@page{
+ margin:0;
+}
+
+#printContainer{
+ display:none;
+}
+
+@media print{
+ body{
+ background:rgb(0 0 0 / 0) none;
+ }
+ body[data-pdfjsprinting] #outerContainer{
+ display:none;
+ }
+ body[data-pdfjsprinting] #printContainer{
+ display:block;
+ }
+ #printContainer{
+ height:100%;
+ }
+ #printContainer > .printedPage{
+ page-break-after:always;
+ page-break-inside:avoid;
+ height:100%;
+ width:100%;
+
+ display:flex;
+ flex-direction:column;
+ justify-content:center;
+ align-items:center;
+ }
+
+ #printContainer > .xfaPrintedPage .xfaPage{
+ position:absolute;
+ }
+
+ #printContainer > .xfaPrintedPage{
+ page-break-after:always;
+ page-break-inside:avoid;
+ width:100%;
+ height:100%;
+ position:relative;
+ }
+
+ #printContainer > .printedPage :is(canvas, img){
+ max-width:100%;
+ max-height:100%;
+
+ direction:ltr;
+ display:block;
+ }
+}
+
+.visibleMediumView{
+ display:none;
+}
+
+@media all and (max-width: 900px){
+ #toolbarViewerMiddle{
+ display:table;
+ margin:auto;
+ left:auto;
+ position:inherit;
+ transform:none;
+ }
+}
+
+@media all and (max-width: 840px){
+ #sidebarContainer{
+ background-color:var(--sidebar-narrow-bg-color);
+ }
+ #outerContainer.sidebarOpen #viewerContainer{
+ inset-inline-start:0 !important;
+ }
+}
+
+@media all and (max-width: 750px){
+ :root{
+ --editor-toolbar-base-offset:40px;
+ }
+ #outerContainer .hiddenMediumView{
+ display:none;
+ }
+ #outerContainer .visibleMediumView{
+ display:inherit;
+ }
+}
+
+@media all and (max-width: 690px){
+ .hiddenSmallView,
+ .hiddenSmallView *{
+ display:none;
+ }
+ .toolbarButtonSpacer{
+ width:0;
+ }
+ .findbar{
+ inset-inline-start:34px;
+ }
+}
+
+@media all and (max-width: 560px){
+ #scaleSelectContainer{
+ display:none;
+ }
+}
diff --git a/www/lib/pdfjs/modern/web/viewer.html b/www/lib/pdfjs/modern/web/viewer.html
new file mode 100644
index 000000000..8de85e286
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/viewer.html
@@ -0,0 +1,497 @@
+
+
+
+
+
+
+
+ PDF.js viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/www/lib/pdfjs/modern/web/viewer.mjs b/www/lib/pdfjs/modern/web/viewer.mjs
new file mode 100644
index 000000000..e9041cadd
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/viewer.mjs
@@ -0,0 +1,15114 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * JavaScript code in this page
+ *
+ * Copyright 2023 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * JavaScript code in this page
+ */
+
+/******/ var __webpack_modules__ = ({
+
+/***/ 8759:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ FluentBundle: () => (/* reexport */ FluentBundle),
+ FluentResource: () => (/* reexport */ FluentResource)
+});
+
+// UNUSED EXPORTS: FluentDateTime, FluentNone, FluentNumber, FluentType
+
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/types.js
+class FluentType {
+ constructor(value) {
+ this.value = value;
+ }
+ valueOf() {
+ return this.value;
+ }
+}
+class FluentNone extends FluentType {
+ constructor(value = "???") {
+ super(value);
+ }
+ toString(scope) {
+ return `{${this.value}}`;
+ }
+}
+class FluentNumber extends FluentType {
+ constructor(value, opts = {}) {
+ super(value);
+ this.opts = opts;
+ }
+ toString(scope) {
+ try {
+ const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);
+ return nf.format(this.value);
+ } catch (err) {
+ scope.reportError(err);
+ return this.value.toString(10);
+ }
+ }
+}
+class FluentDateTime extends FluentType {
+ constructor(value, opts = {}) {
+ super(value);
+ this.opts = opts;
+ }
+ toString(scope) {
+ try {
+ const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);
+ return dtf.format(this.value);
+ } catch (err) {
+ scope.reportError(err);
+ return new Date(this.value).toISOString();
+ }
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/resolver.js
+
+const MAX_PLACEABLES = 100;
+const FSI = "\u2068";
+const PDI = "\u2069";
+function match(scope, selector, key) {
+ if (key === selector) {
+ return true;
+ }
+ if (key instanceof FluentNumber && selector instanceof FluentNumber && key.value === selector.value) {
+ return true;
+ }
+ if (selector instanceof FluentNumber && typeof key === "string") {
+ let category = scope.memoizeIntlObject(Intl.PluralRules, selector.opts).select(selector.value);
+ if (key === category) {
+ return true;
+ }
+ }
+ return false;
+}
+function getDefault(scope, variants, star) {
+ if (variants[star]) {
+ return resolvePattern(scope, variants[star].value);
+ }
+ scope.reportError(new RangeError("No default"));
+ return new FluentNone();
+}
+function getArguments(scope, args) {
+ const positional = [];
+ const named = Object.create(null);
+ for (const arg of args) {
+ if (arg.type === "narg") {
+ named[arg.name] = resolveExpression(scope, arg.value);
+ } else {
+ positional.push(resolveExpression(scope, arg));
+ }
+ }
+ return {
+ positional,
+ named
+ };
+}
+function resolveExpression(scope, expr) {
+ switch (expr.type) {
+ case "str":
+ return expr.value;
+ case "num":
+ return new FluentNumber(expr.value, {
+ minimumFractionDigits: expr.precision
+ });
+ case "var":
+ return resolveVariableReference(scope, expr);
+ case "mesg":
+ return resolveMessageReference(scope, expr);
+ case "term":
+ return resolveTermReference(scope, expr);
+ case "func":
+ return resolveFunctionReference(scope, expr);
+ case "select":
+ return resolveSelectExpression(scope, expr);
+ default:
+ return new FluentNone();
+ }
+}
+function resolveVariableReference(scope, {
+ name
+}) {
+ let arg;
+ if (scope.params) {
+ if (Object.prototype.hasOwnProperty.call(scope.params, name)) {
+ arg = scope.params[name];
+ } else {
+ return new FluentNone(`$${name}`);
+ }
+ } else if (scope.args && Object.prototype.hasOwnProperty.call(scope.args, name)) {
+ arg = scope.args[name];
+ } else {
+ scope.reportError(new ReferenceError(`Unknown variable: $${name}`));
+ return new FluentNone(`$${name}`);
+ }
+ if (arg instanceof FluentType) {
+ return arg;
+ }
+ switch (typeof arg) {
+ case "string":
+ return arg;
+ case "number":
+ return new FluentNumber(arg);
+ case "object":
+ if (arg instanceof Date) {
+ return new FluentDateTime(arg.getTime());
+ }
+ default:
+ scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`));
+ return new FluentNone(`$${name}`);
+ }
+}
+function resolveMessageReference(scope, {
+ name,
+ attr
+}) {
+ const message = scope.bundle._messages.get(name);
+ if (!message) {
+ scope.reportError(new ReferenceError(`Unknown message: ${name}`));
+ return new FluentNone(name);
+ }
+ if (attr) {
+ const attribute = message.attributes[attr];
+ if (attribute) {
+ return resolvePattern(scope, attribute);
+ }
+ scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));
+ return new FluentNone(`${name}.${attr}`);
+ }
+ if (message.value) {
+ return resolvePattern(scope, message.value);
+ }
+ scope.reportError(new ReferenceError(`No value: ${name}`));
+ return new FluentNone(name);
+}
+function resolveTermReference(scope, {
+ name,
+ attr,
+ args
+}) {
+ const id = `-${name}`;
+ const term = scope.bundle._terms.get(id);
+ if (!term) {
+ scope.reportError(new ReferenceError(`Unknown term: ${id}`));
+ return new FluentNone(id);
+ }
+ if (attr) {
+ const attribute = term.attributes[attr];
+ if (attribute) {
+ scope.params = getArguments(scope, args).named;
+ const resolved = resolvePattern(scope, attribute);
+ scope.params = null;
+ return resolved;
+ }
+ scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));
+ return new FluentNone(`${id}.${attr}`);
+ }
+ scope.params = getArguments(scope, args).named;
+ const resolved = resolvePattern(scope, term.value);
+ scope.params = null;
+ return resolved;
+}
+function resolveFunctionReference(scope, {
+ name,
+ args
+}) {
+ let func = scope.bundle._functions[name];
+ if (!func) {
+ scope.reportError(new ReferenceError(`Unknown function: ${name}()`));
+ return new FluentNone(`${name}()`);
+ }
+ if (typeof func !== "function") {
+ scope.reportError(new TypeError(`Function ${name}() is not callable`));
+ return new FluentNone(`${name}()`);
+ }
+ try {
+ let resolved = getArguments(scope, args);
+ return func(resolved.positional, resolved.named);
+ } catch (err) {
+ scope.reportError(err);
+ return new FluentNone(`${name}()`);
+ }
+}
+function resolveSelectExpression(scope, {
+ selector,
+ variants,
+ star
+}) {
+ let sel = resolveExpression(scope, selector);
+ if (sel instanceof FluentNone) {
+ return getDefault(scope, variants, star);
+ }
+ for (const variant of variants) {
+ const key = resolveExpression(scope, variant.key);
+ if (match(scope, sel, key)) {
+ return resolvePattern(scope, variant.value);
+ }
+ }
+ return getDefault(scope, variants, star);
+}
+function resolveComplexPattern(scope, ptn) {
+ if (scope.dirty.has(ptn)) {
+ scope.reportError(new RangeError("Cyclic reference"));
+ return new FluentNone();
+ }
+ scope.dirty.add(ptn);
+ const result = [];
+ const useIsolating = scope.bundle._useIsolating && ptn.length > 1;
+ for (const elem of ptn) {
+ if (typeof elem === "string") {
+ result.push(scope.bundle._transform(elem));
+ continue;
+ }
+ scope.placeables++;
+ if (scope.placeables > MAX_PLACEABLES) {
+ scope.dirty.delete(ptn);
+ throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` + `max allowed is ${MAX_PLACEABLES}`);
+ }
+ if (useIsolating) {
+ result.push(FSI);
+ }
+ result.push(resolveExpression(scope, elem).toString(scope));
+ if (useIsolating) {
+ result.push(PDI);
+ }
+ }
+ scope.dirty.delete(ptn);
+ return result.join("");
+}
+function resolvePattern(scope, value) {
+ if (typeof value === "string") {
+ return scope.bundle._transform(value);
+ }
+ return resolveComplexPattern(scope, value);
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/scope.js
+class Scope {
+ constructor(bundle, errors, args) {
+ this.dirty = new WeakSet();
+ this.params = null;
+ this.placeables = 0;
+ this.bundle = bundle;
+ this.errors = errors;
+ this.args = args;
+ }
+ reportError(error) {
+ if (!this.errors || !(error instanceof Error)) {
+ throw error;
+ }
+ this.errors.push(error);
+ }
+ memoizeIntlObject(ctor, opts) {
+ let cache = this.bundle._intls.get(ctor);
+ if (!cache) {
+ cache = {};
+ this.bundle._intls.set(ctor, cache);
+ }
+ let id = JSON.stringify(opts);
+ if (!cache[id]) {
+ cache[id] = new ctor(this.bundle.locales, opts);
+ }
+ return cache[id];
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/builtins.js
+
+function values(opts, allowed) {
+ const unwrapped = Object.create(null);
+ for (const [name, opt] of Object.entries(opts)) {
+ if (allowed.includes(name)) {
+ unwrapped[name] = opt.valueOf();
+ }
+ }
+ return unwrapped;
+}
+const NUMBER_ALLOWED = ["unitDisplay", "currencyDisplay", "useGrouping", "minimumIntegerDigits", "minimumFractionDigits", "maximumFractionDigits", "minimumSignificantDigits", "maximumSignificantDigits"];
+function NUMBER(args, opts) {
+ let arg = args[0];
+ if (arg instanceof FluentNone) {
+ return new FluentNone(`NUMBER(${arg.valueOf()})`);
+ }
+ if (arg instanceof FluentNumber) {
+ return new FluentNumber(arg.valueOf(), {
+ ...arg.opts,
+ ...values(opts, NUMBER_ALLOWED)
+ });
+ }
+ if (arg instanceof FluentDateTime) {
+ return new FluentNumber(arg.valueOf(), {
+ ...values(opts, NUMBER_ALLOWED)
+ });
+ }
+ throw new TypeError("Invalid argument to NUMBER");
+}
+const DATETIME_ALLOWED = ["dateStyle", "timeStyle", "fractionalSecondDigits", "dayPeriod", "hour12", "weekday", "era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"];
+function DATETIME(args, opts) {
+ let arg = args[0];
+ if (arg instanceof FluentNone) {
+ return new FluentNone(`DATETIME(${arg.valueOf()})`);
+ }
+ if (arg instanceof FluentDateTime) {
+ return new FluentDateTime(arg.valueOf(), {
+ ...arg.opts,
+ ...values(opts, DATETIME_ALLOWED)
+ });
+ }
+ if (arg instanceof FluentNumber) {
+ return new FluentDateTime(arg.valueOf(), {
+ ...values(opts, DATETIME_ALLOWED)
+ });
+ }
+ throw new TypeError("Invalid argument to DATETIME");
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/memoizer.js
+const cache = new Map();
+function getMemoizerForLocale(locales) {
+ const stringLocale = Array.isArray(locales) ? locales.join(" ") : locales;
+ let memoizer = cache.get(stringLocale);
+ if (memoizer === undefined) {
+ memoizer = new Map();
+ cache.set(stringLocale, memoizer);
+ }
+ return memoizer;
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/bundle.js
+
+
+
+
+
+class FluentBundle {
+ constructor(locales, {
+ functions,
+ useIsolating = true,
+ transform = v => v
+ } = {}) {
+ this._terms = new Map();
+ this._messages = new Map();
+ this.locales = Array.isArray(locales) ? locales : [locales];
+ this._functions = {
+ NUMBER: NUMBER,
+ DATETIME: DATETIME,
+ ...functions
+ };
+ this._useIsolating = useIsolating;
+ this._transform = transform;
+ this._intls = getMemoizerForLocale(locales);
+ }
+ hasMessage(id) {
+ return this._messages.has(id);
+ }
+ getMessage(id) {
+ return this._messages.get(id);
+ }
+ addResource(res, {
+ allowOverrides = false
+ } = {}) {
+ const errors = [];
+ for (let i = 0; i < res.body.length; i++) {
+ let entry = res.body[i];
+ if (entry.id.startsWith("-")) {
+ if (allowOverrides === false && this._terms.has(entry.id)) {
+ errors.push(new Error(`Attempt to override an existing term: "${entry.id}"`));
+ continue;
+ }
+ this._terms.set(entry.id, entry);
+ } else {
+ if (allowOverrides === false && this._messages.has(entry.id)) {
+ errors.push(new Error(`Attempt to override an existing message: "${entry.id}"`));
+ continue;
+ }
+ this._messages.set(entry.id, entry);
+ }
+ }
+ return errors;
+ }
+ formatPattern(pattern, args = null, errors = null) {
+ if (typeof pattern === "string") {
+ return this._transform(pattern);
+ }
+ let scope = new Scope(this, errors, args);
+ try {
+ let value = resolveComplexPattern(scope, pattern);
+ return value.toString(scope);
+ } catch (err) {
+ if (scope.errors && err instanceof Error) {
+ scope.errors.push(err);
+ return new FluentNone().toString(scope);
+ }
+ throw err;
+ }
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/resource.js
+const RE_MESSAGE_START = /^(-?[a-zA-Z][\w-]*) *= */gm;
+const RE_ATTRIBUTE_START = /\.([a-zA-Z][\w-]*) *= */y;
+const RE_VARIANT_START = /\*?\[/y;
+const RE_NUMBER_LITERAL = /(-?[0-9]+(?:\.([0-9]+))?)/y;
+const RE_IDENTIFIER = /([a-zA-Z][\w-]*)/y;
+const RE_REFERENCE = /([$-])?([a-zA-Z][\w-]*)(?:\.([a-zA-Z][\w-]*))?/y;
+const RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/;
+const RE_TEXT_RUN = /([^{}\n\r]+)/y;
+const RE_STRING_RUN = /([^\\"\n\r]*)/y;
+const RE_STRING_ESCAPE = /\\([\\"])/y;
+const RE_UNICODE_ESCAPE = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{6})/y;
+const RE_LEADING_NEWLINES = /^\n+/;
+const RE_TRAILING_SPACES = / +$/;
+const RE_BLANK_LINES = / *\r?\n/g;
+const RE_INDENT = /( *)$/;
+const TOKEN_BRACE_OPEN = /{\s*/y;
+const TOKEN_BRACE_CLOSE = /\s*}/y;
+const TOKEN_BRACKET_OPEN = /\[\s*/y;
+const TOKEN_BRACKET_CLOSE = /\s*] */y;
+const TOKEN_PAREN_OPEN = /\s*\(\s*/y;
+const TOKEN_ARROW = /\s*->\s*/y;
+const TOKEN_COLON = /\s*:\s*/y;
+const TOKEN_COMMA = /\s*,?\s*/y;
+const TOKEN_BLANK = /\s+/y;
+class FluentResource {
+ constructor(source) {
+ this.body = [];
+ RE_MESSAGE_START.lastIndex = 0;
+ let cursor = 0;
+ while (true) {
+ let next = RE_MESSAGE_START.exec(source);
+ if (next === null) {
+ break;
+ }
+ cursor = RE_MESSAGE_START.lastIndex;
+ try {
+ this.body.push(parseMessage(next[1]));
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ continue;
+ }
+ throw err;
+ }
+ }
+ function test(re) {
+ re.lastIndex = cursor;
+ return re.test(source);
+ }
+ function consumeChar(char, errorClass) {
+ if (source[cursor] === char) {
+ cursor++;
+ return true;
+ }
+ if (errorClass) {
+ throw new errorClass(`Expected ${char}`);
+ }
+ return false;
+ }
+ function consumeToken(re, errorClass) {
+ if (test(re)) {
+ cursor = re.lastIndex;
+ return true;
+ }
+ if (errorClass) {
+ throw new errorClass(`Expected ${re.toString()}`);
+ }
+ return false;
+ }
+ function match(re) {
+ re.lastIndex = cursor;
+ let result = re.exec(source);
+ if (result === null) {
+ throw new SyntaxError(`Expected ${re.toString()}`);
+ }
+ cursor = re.lastIndex;
+ return result;
+ }
+ function match1(re) {
+ return match(re)[1];
+ }
+ function parseMessage(id) {
+ let value = parsePattern();
+ let attributes = parseAttributes();
+ if (value === null && Object.keys(attributes).length === 0) {
+ throw new SyntaxError("Expected message value or attributes");
+ }
+ return {
+ id,
+ value,
+ attributes
+ };
+ }
+ function parseAttributes() {
+ let attrs = Object.create(null);
+ while (test(RE_ATTRIBUTE_START)) {
+ let name = match1(RE_ATTRIBUTE_START);
+ let value = parsePattern();
+ if (value === null) {
+ throw new SyntaxError("Expected attribute value");
+ }
+ attrs[name] = value;
+ }
+ return attrs;
+ }
+ function parsePattern() {
+ let first;
+ if (test(RE_TEXT_RUN)) {
+ first = match1(RE_TEXT_RUN);
+ }
+ if (source[cursor] === "{" || source[cursor] === "}") {
+ return parsePatternElements(first ? [first] : [], Infinity);
+ }
+ let indent = parseIndent();
+ if (indent) {
+ if (first) {
+ return parsePatternElements([first, indent], indent.length);
+ }
+ indent.value = trim(indent.value, RE_LEADING_NEWLINES);
+ return parsePatternElements([indent], indent.length);
+ }
+ if (first) {
+ return trim(first, RE_TRAILING_SPACES);
+ }
+ return null;
+ }
+ function parsePatternElements(elements = [], commonIndent) {
+ while (true) {
+ if (test(RE_TEXT_RUN)) {
+ elements.push(match1(RE_TEXT_RUN));
+ continue;
+ }
+ if (source[cursor] === "{") {
+ elements.push(parsePlaceable());
+ continue;
+ }
+ if (source[cursor] === "}") {
+ throw new SyntaxError("Unbalanced closing brace");
+ }
+ let indent = parseIndent();
+ if (indent) {
+ elements.push(indent);
+ commonIndent = Math.min(commonIndent, indent.length);
+ continue;
+ }
+ break;
+ }
+ let lastIndex = elements.length - 1;
+ let lastElement = elements[lastIndex];
+ if (typeof lastElement === "string") {
+ elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES);
+ }
+ let baked = [];
+ for (let element of elements) {
+ if (element instanceof Indent) {
+ element = element.value.slice(0, element.value.length - commonIndent);
+ }
+ if (element) {
+ baked.push(element);
+ }
+ }
+ return baked;
+ }
+ function parsePlaceable() {
+ consumeToken(TOKEN_BRACE_OPEN, SyntaxError);
+ let selector = parseInlineExpression();
+ if (consumeToken(TOKEN_BRACE_CLOSE)) {
+ return selector;
+ }
+ if (consumeToken(TOKEN_ARROW)) {
+ let variants = parseVariants();
+ consumeToken(TOKEN_BRACE_CLOSE, SyntaxError);
+ return {
+ type: "select",
+ selector,
+ ...variants
+ };
+ }
+ throw new SyntaxError("Unclosed placeable");
+ }
+ function parseInlineExpression() {
+ if (source[cursor] === "{") {
+ return parsePlaceable();
+ }
+ if (test(RE_REFERENCE)) {
+ let [, sigil, name, attr = null] = match(RE_REFERENCE);
+ if (sigil === "$") {
+ return {
+ type: "var",
+ name
+ };
+ }
+ if (consumeToken(TOKEN_PAREN_OPEN)) {
+ let args = parseArguments();
+ if (sigil === "-") {
+ return {
+ type: "term",
+ name,
+ attr,
+ args
+ };
+ }
+ if (RE_FUNCTION_NAME.test(name)) {
+ return {
+ type: "func",
+ name,
+ args
+ };
+ }
+ throw new SyntaxError("Function names must be all upper-case");
+ }
+ if (sigil === "-") {
+ return {
+ type: "term",
+ name,
+ attr,
+ args: []
+ };
+ }
+ return {
+ type: "mesg",
+ name,
+ attr
+ };
+ }
+ return parseLiteral();
+ }
+ function parseArguments() {
+ let args = [];
+ while (true) {
+ switch (source[cursor]) {
+ case ")":
+ cursor++;
+ return args;
+ case undefined:
+ throw new SyntaxError("Unclosed argument list");
+ }
+ args.push(parseArgument());
+ consumeToken(TOKEN_COMMA);
+ }
+ }
+ function parseArgument() {
+ let expr = parseInlineExpression();
+ if (expr.type !== "mesg") {
+ return expr;
+ }
+ if (consumeToken(TOKEN_COLON)) {
+ return {
+ type: "narg",
+ name: expr.name,
+ value: parseLiteral()
+ };
+ }
+ return expr;
+ }
+ function parseVariants() {
+ let variants = [];
+ let count = 0;
+ let star;
+ while (test(RE_VARIANT_START)) {
+ if (consumeChar("*")) {
+ star = count;
+ }
+ let key = parseVariantKey();
+ let value = parsePattern();
+ if (value === null) {
+ throw new SyntaxError("Expected variant value");
+ }
+ variants[count++] = {
+ key,
+ value
+ };
+ }
+ if (count === 0) {
+ return null;
+ }
+ if (star === undefined) {
+ throw new SyntaxError("Expected default variant");
+ }
+ return {
+ variants,
+ star
+ };
+ }
+ function parseVariantKey() {
+ consumeToken(TOKEN_BRACKET_OPEN, SyntaxError);
+ let key;
+ if (test(RE_NUMBER_LITERAL)) {
+ key = parseNumberLiteral();
+ } else {
+ key = {
+ type: "str",
+ value: match1(RE_IDENTIFIER)
+ };
+ }
+ consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError);
+ return key;
+ }
+ function parseLiteral() {
+ if (test(RE_NUMBER_LITERAL)) {
+ return parseNumberLiteral();
+ }
+ if (source[cursor] === '"') {
+ return parseStringLiteral();
+ }
+ throw new SyntaxError("Invalid expression");
+ }
+ function parseNumberLiteral() {
+ let [, value, fraction = ""] = match(RE_NUMBER_LITERAL);
+ let precision = fraction.length;
+ return {
+ type: "num",
+ value: parseFloat(value),
+ precision
+ };
+ }
+ function parseStringLiteral() {
+ consumeChar('"', SyntaxError);
+ let value = "";
+ while (true) {
+ value += match1(RE_STRING_RUN);
+ if (source[cursor] === "\\") {
+ value += parseEscapeSequence();
+ continue;
+ }
+ if (consumeChar('"')) {
+ return {
+ type: "str",
+ value
+ };
+ }
+ throw new SyntaxError("Unclosed string literal");
+ }
+ }
+ function parseEscapeSequence() {
+ if (test(RE_STRING_ESCAPE)) {
+ return match1(RE_STRING_ESCAPE);
+ }
+ if (test(RE_UNICODE_ESCAPE)) {
+ let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE);
+ let codepoint = parseInt(codepoint4 || codepoint6, 16);
+ return codepoint <= 0xd7ff || 0xe000 <= codepoint ? String.fromCodePoint(codepoint) : "�";
+ }
+ throw new SyntaxError("Unknown escape sequence");
+ }
+ function parseIndent() {
+ let start = cursor;
+ consumeToken(TOKEN_BLANK);
+ switch (source[cursor]) {
+ case ".":
+ case "[":
+ case "*":
+ case "}":
+ case undefined:
+ return false;
+ case "{":
+ return makeIndent(source.slice(start, cursor));
+ }
+ if (source[cursor - 1] === " ") {
+ return makeIndent(source.slice(start, cursor));
+ }
+ return false;
+ }
+ function trim(text, re) {
+ return text.replace(re, "");
+ }
+ function makeIndent(blank) {
+ let value = blank.replace(RE_BLANK_LINES, "\n");
+ let length = RE_INDENT.exec(blank)[1].length;
+ return new Indent(value, length);
+ }
+ }
+}
+class Indent {
+ constructor(value, length) {
+ this.value = value;
+ this.length = length;
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/index.js
+
+
+
+
+/***/ }),
+
+/***/ 8275:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ DOMLocalization: () => (/* reexport */ DOMLocalization)
+});
+
+// UNUSED EXPORTS: Localization
+
+;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/overlay.js
+const reOverlay = /<|?\w+;/;
+const TEXT_LEVEL_ELEMENTS = {
+ "http://www.w3.org/1999/xhtml": ["em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data", "time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u", "mark", "bdi", "bdo", "span", "br", "wbr"]
+};
+const LOCALIZABLE_ATTRIBUTES = {
+ "http://www.w3.org/1999/xhtml": {
+ global: ["title", "aria-label", "aria-valuetext"],
+ a: ["download"],
+ area: ["download", "alt"],
+ input: ["alt", "placeholder"],
+ menuitem: ["label"],
+ menu: ["label"],
+ optgroup: ["label"],
+ option: ["label"],
+ track: ["label"],
+ img: ["alt"],
+ textarea: ["placeholder"],
+ th: ["abbr"]
+ },
+ "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": {
+ global: ["accesskey", "aria-label", "aria-valuetext", "label", "title", "tooltiptext"],
+ description: ["value"],
+ key: ["key", "keycode"],
+ label: ["value"],
+ textbox: ["placeholder", "value"]
+ }
+};
+function translateElement(element, translation) {
+ const {
+ value
+ } = translation;
+ if (typeof value === "string") {
+ if (element.localName === "title" && element.namespaceURI === "http://www.w3.org/1999/xhtml") {
+ element.textContent = value;
+ } else if (!reOverlay.test(value)) {
+ element.textContent = value;
+ } else {
+ const templateElement = element.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "template");
+ templateElement.innerHTML = value;
+ overlayChildNodes(templateElement.content, element);
+ }
+ }
+ overlayAttributes(translation, element);
+}
+function overlayChildNodes(fromFragment, toElement) {
+ for (const childNode of fromFragment.childNodes) {
+ if (childNode.nodeType === childNode.TEXT_NODE) {
+ continue;
+ }
+ if (childNode.hasAttribute("data-l10n-name")) {
+ const sanitized = getNodeForNamedElement(toElement, childNode);
+ fromFragment.replaceChild(sanitized, childNode);
+ continue;
+ }
+ if (isElementAllowed(childNode)) {
+ const sanitized = createSanitizedElement(childNode);
+ fromFragment.replaceChild(sanitized, childNode);
+ continue;
+ }
+ console.warn(`An element of forbidden type "${childNode.localName}" was found in ` + "the translation. Only safe text-level elements and elements with " + "data-l10n-name are allowed.");
+ fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode);
+ }
+ toElement.textContent = "";
+ toElement.appendChild(fromFragment);
+}
+function hasAttribute(attributes, name) {
+ if (!attributes) {
+ return false;
+ }
+ for (let attr of attributes) {
+ if (attr.name === name) {
+ return true;
+ }
+ }
+ return false;
+}
+function overlayAttributes(fromElement, toElement) {
+ const explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") ? toElement.getAttribute("data-l10n-attrs").split(",").map(i => i.trim()) : null;
+ for (const attr of Array.from(toElement.attributes)) {
+ if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && !hasAttribute(fromElement.attributes, attr.name)) {
+ toElement.removeAttribute(attr.name);
+ }
+ }
+ if (!fromElement.attributes) {
+ return;
+ }
+ for (const attr of Array.from(fromElement.attributes)) {
+ if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && toElement.getAttribute(attr.name) !== attr.value) {
+ toElement.setAttribute(attr.name, attr.value);
+ }
+ }
+}
+function getNodeForNamedElement(sourceElement, translatedChild) {
+ const childName = translatedChild.getAttribute("data-l10n-name");
+ const sourceChild = sourceElement.querySelector(`[data-l10n-name="${childName}"]`);
+ if (!sourceChild) {
+ console.warn(`An element named "${childName}" wasn't found in the source.`);
+ return createTextNodeFromTextContent(translatedChild);
+ }
+ if (sourceChild.localName !== translatedChild.localName) {
+ console.warn(`An element named "${childName}" was found in the translation ` + `but its type ${translatedChild.localName} didn't match the ` + `element found in the source (${sourceChild.localName}).`);
+ return createTextNodeFromTextContent(translatedChild);
+ }
+ sourceElement.removeChild(sourceChild);
+ const clone = sourceChild.cloneNode(false);
+ return shallowPopulateUsing(translatedChild, clone);
+}
+function createSanitizedElement(element) {
+ const clone = element.ownerDocument.createElement(element.localName);
+ return shallowPopulateUsing(element, clone);
+}
+function createTextNodeFromTextContent(element) {
+ return element.ownerDocument.createTextNode(element.textContent);
+}
+function isElementAllowed(element) {
+ const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];
+ return allowed && allowed.includes(element.localName);
+}
+function isAttrNameLocalizable(name, element, explicitlyAllowed = null) {
+ if (explicitlyAllowed && explicitlyAllowed.includes(name)) {
+ return true;
+ }
+ const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];
+ if (!allowed) {
+ return false;
+ }
+ const attrName = name.toLowerCase();
+ const elemName = element.localName;
+ if (allowed.global.includes(attrName)) {
+ return true;
+ }
+ if (!allowed[elemName]) {
+ return false;
+ }
+ if (allowed[elemName].includes(attrName)) {
+ return true;
+ }
+ if (element.namespaceURI === "http://www.w3.org/1999/xhtml" && elemName === "input" && attrName === "value") {
+ const type = element.type.toLowerCase();
+ if (type === "submit" || type === "button" || type === "reset") {
+ return true;
+ }
+ }
+ return false;
+}
+function shallowPopulateUsing(fromElement, toElement) {
+ toElement.textContent = fromElement.textContent;
+ overlayAttributes(fromElement, toElement);
+ return toElement;
+}
+;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_iterable.mjs
+class CachedIterable extends Array {
+ static from(iterable) {
+ if (iterable instanceof this) {
+ return iterable;
+ }
+ return new this(iterable);
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_sync_iterable.mjs
+
+class CachedSyncIterable extends CachedIterable {
+ constructor(iterable) {
+ super();
+ if (Symbol.iterator in Object(iterable)) {
+ this.iterator = iterable[Symbol.iterator]();
+ } else {
+ throw new TypeError("Argument must implement the iteration protocol.");
+ }
+ }
+ [Symbol.iterator]() {
+ const cached = this;
+ let cur = 0;
+ return {
+ next() {
+ if (cached.length <= cur) {
+ cached.push(cached.iterator.next());
+ }
+ return cached[cur++];
+ }
+ };
+ }
+ touchNext(count = 1) {
+ let idx = 0;
+ while (idx++ < count) {
+ const last = this[this.length - 1];
+ if (last && last.done) {
+ break;
+ }
+ this.push(this.iterator.next());
+ }
+ return this[this.length - 1];
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_async_iterable.mjs
+
+class CachedAsyncIterable extends CachedIterable {
+ constructor(iterable) {
+ super();
+ if (Symbol.asyncIterator in Object(iterable)) {
+ this.iterator = iterable[Symbol.asyncIterator]();
+ } else if (Symbol.iterator in Object(iterable)) {
+ this.iterator = iterable[Symbol.iterator]();
+ } else {
+ throw new TypeError("Argument must implement the iteration protocol.");
+ }
+ }
+ [Symbol.asyncIterator]() {
+ const cached = this;
+ let cur = 0;
+ return {
+ async next() {
+ if (cached.length <= cur) {
+ cached.push(cached.iterator.next());
+ }
+ return cached[cur++];
+ }
+ };
+ }
+ async touchNext(count = 1) {
+ let idx = 0;
+ while (idx++ < count) {
+ const last = this[this.length - 1];
+ if (last && (await last).done) {
+ break;
+ }
+ this.push(this.iterator.next());
+ }
+ return this[this.length - 1];
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/index.mjs
+
+
+;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/localization.js
+
+class Localization {
+ constructor(resourceIds = [], generateBundles) {
+ this.resourceIds = resourceIds;
+ this.generateBundles = generateBundles;
+ this.onChange(true);
+ }
+ addResourceIds(resourceIds, eager = false) {
+ this.resourceIds.push(...resourceIds);
+ this.onChange(eager);
+ return this.resourceIds.length;
+ }
+ removeResourceIds(resourceIds) {
+ this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));
+ this.onChange();
+ return this.resourceIds.length;
+ }
+ async formatWithFallback(keys, method) {
+ const translations = [];
+ let hasAtLeastOneBundle = false;
+ for await (const bundle of this.bundles) {
+ hasAtLeastOneBundle = true;
+ const missingIds = keysFromBundle(method, bundle, keys, translations);
+ if (missingIds.size === 0) {
+ break;
+ }
+ if (typeof console !== "undefined") {
+ const locale = bundle.locales[0];
+ const ids = Array.from(missingIds).join(", ");
+ console.warn(`[fluent] Missing translations in ${locale}: ${ids}`);
+ }
+ }
+ if (!hasAtLeastOneBundle && typeof console !== "undefined") {
+ console.warn(`[fluent] Request for keys failed because no resource bundles got generated.
+ keys: ${JSON.stringify(keys)}.
+ resourceIds: ${JSON.stringify(this.resourceIds)}.`);
+ }
+ return translations;
+ }
+ formatMessages(keys) {
+ return this.formatWithFallback(keys, messageFromBundle);
+ }
+ formatValues(keys) {
+ return this.formatWithFallback(keys, valueFromBundle);
+ }
+ async formatValue(id, args) {
+ const [val] = await this.formatValues([{
+ id,
+ args
+ }]);
+ return val;
+ }
+ handleEvent() {
+ this.onChange();
+ }
+ onChange(eager = false) {
+ this.bundles = CachedAsyncIterable.from(this.generateBundles(this.resourceIds));
+ if (eager) {
+ this.bundles.touchNext(2);
+ }
+ }
+}
+function valueFromBundle(bundle, errors, message, args) {
+ if (message.value) {
+ return bundle.formatPattern(message.value, args, errors);
+ }
+ return null;
+}
+function messageFromBundle(bundle, errors, message, args) {
+ const formatted = {
+ value: null,
+ attributes: null
+ };
+ if (message.value) {
+ formatted.value = bundle.formatPattern(message.value, args, errors);
+ }
+ let attrNames = Object.keys(message.attributes);
+ if (attrNames.length > 0) {
+ formatted.attributes = new Array(attrNames.length);
+ for (let [i, name] of attrNames.entries()) {
+ let value = bundle.formatPattern(message.attributes[name], args, errors);
+ formatted.attributes[i] = {
+ name,
+ value
+ };
+ }
+ }
+ return formatted;
+}
+function keysFromBundle(method, bundle, keys, translations) {
+ const messageErrors = [];
+ const missingIds = new Set();
+ keys.forEach(({
+ id,
+ args
+ }, i) => {
+ if (translations[i] !== undefined) {
+ return;
+ }
+ let message = bundle.getMessage(id);
+ if (message) {
+ messageErrors.length = 0;
+ translations[i] = method(bundle, messageErrors, message, args);
+ if (messageErrors.length > 0 && typeof console !== "undefined") {
+ const locale = bundle.locales[0];
+ const errors = messageErrors.join(", ");
+ console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`);
+ }
+ } else {
+ missingIds.add(id);
+ }
+ });
+ return missingIds;
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/dom_localization.js
+
+
+const L10NID_ATTR_NAME = "data-l10n-id";
+const L10NARGS_ATTR_NAME = "data-l10n-args";
+const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`;
+class DOMLocalization extends Localization {
+ constructor(resourceIds, generateBundles) {
+ super(resourceIds, generateBundles);
+ this.roots = new Set();
+ this.pendingrAF = null;
+ this.pendingElements = new Set();
+ this.windowElement = null;
+ this.mutationObserver = null;
+ this.observerConfig = {
+ attributes: true,
+ characterData: false,
+ childList: true,
+ subtree: true,
+ attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME]
+ };
+ }
+ onChange(eager = false) {
+ super.onChange(eager);
+ if (this.roots) {
+ this.translateRoots();
+ }
+ }
+ setAttributes(element, id, args) {
+ element.setAttribute(L10NID_ATTR_NAME, id);
+ if (args) {
+ element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args));
+ } else {
+ element.removeAttribute(L10NARGS_ATTR_NAME);
+ }
+ return element;
+ }
+ getAttributes(element) {
+ return {
+ id: element.getAttribute(L10NID_ATTR_NAME),
+ args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null)
+ };
+ }
+ connectRoot(newRoot) {
+ for (const root of this.roots) {
+ if (root === newRoot || root.contains(newRoot) || newRoot.contains(root)) {
+ throw new Error("Cannot add a root that overlaps with existing root.");
+ }
+ }
+ if (this.windowElement) {
+ if (this.windowElement !== newRoot.ownerDocument.defaultView) {
+ throw new Error(`Cannot connect a root:
+ DOMLocalization already has a root from a different window.`);
+ }
+ } else {
+ this.windowElement = newRoot.ownerDocument.defaultView;
+ this.mutationObserver = new this.windowElement.MutationObserver(mutations => this.translateMutations(mutations));
+ }
+ this.roots.add(newRoot);
+ this.mutationObserver.observe(newRoot, this.observerConfig);
+ }
+ disconnectRoot(root) {
+ this.roots.delete(root);
+ this.pauseObserving();
+ if (this.roots.size === 0) {
+ this.mutationObserver = null;
+ this.windowElement = null;
+ this.pendingrAF = null;
+ this.pendingElements.clear();
+ return true;
+ }
+ this.resumeObserving();
+ return false;
+ }
+ translateRoots() {
+ const roots = Array.from(this.roots);
+ return Promise.all(roots.map(root => this.translateFragment(root)));
+ }
+ pauseObserving() {
+ if (!this.mutationObserver) {
+ return;
+ }
+ this.translateMutations(this.mutationObserver.takeRecords());
+ this.mutationObserver.disconnect();
+ }
+ resumeObserving() {
+ if (!this.mutationObserver) {
+ return;
+ }
+ for (const root of this.roots) {
+ this.mutationObserver.observe(root, this.observerConfig);
+ }
+ }
+ translateMutations(mutations) {
+ for (const mutation of mutations) {
+ switch (mutation.type) {
+ case "attributes":
+ if (mutation.target.hasAttribute("data-l10n-id")) {
+ this.pendingElements.add(mutation.target);
+ }
+ break;
+ case "childList":
+ for (const addedNode of mutation.addedNodes) {
+ if (addedNode.nodeType === addedNode.ELEMENT_NODE) {
+ if (addedNode.childElementCount) {
+ for (const element of this.getTranslatables(addedNode)) {
+ this.pendingElements.add(element);
+ }
+ } else if (addedNode.hasAttribute(L10NID_ATTR_NAME)) {
+ this.pendingElements.add(addedNode);
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (this.pendingElements.size > 0) {
+ if (this.pendingrAF === null) {
+ this.pendingrAF = this.windowElement.requestAnimationFrame(() => {
+ this.translateElements(Array.from(this.pendingElements));
+ this.pendingElements.clear();
+ this.pendingrAF = null;
+ });
+ }
+ }
+ }
+ translateFragment(frag) {
+ return this.translateElements(this.getTranslatables(frag));
+ }
+ async translateElements(elements) {
+ if (!elements.length) {
+ return undefined;
+ }
+ const keys = elements.map(this.getKeysForElement);
+ const translations = await this.formatMessages(keys);
+ return this.applyTranslations(elements, translations);
+ }
+ applyTranslations(elements, translations) {
+ this.pauseObserving();
+ for (let i = 0; i < elements.length; i++) {
+ if (translations[i] !== undefined) {
+ translateElement(elements[i], translations[i]);
+ }
+ }
+ this.resumeObserving();
+ }
+ getTranslatables(element) {
+ const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));
+ if (typeof element.hasAttribute === "function" && element.hasAttribute(L10NID_ATTR_NAME)) {
+ nodes.push(element);
+ }
+ return nodes;
+ }
+ getKeysForElement(element) {
+ return {
+ id: element.getAttribute(L10NID_ATTR_NAME),
+ args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null)
+ };
+ }
+}
+;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/index.js
+
+
+
+/***/ }),
+
+/***/ 631:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AltTextManager: () => (/* binding */ AltTextManager)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+class AltTextManager {
+ #boundUpdateUIState = this.#updateUIState.bind(this);
+ #boundSetPosition = this.#setPosition.bind(this);
+ #boundOnClick = this.#onClick.bind(this);
+ #currentEditor = null;
+ #cancelButton;
+ #dialog;
+ #eventBus;
+ #hasUsedPointer = false;
+ #optionDescription;
+ #optionDecorative;
+ #overlayManager;
+ #saveButton;
+ #textarea;
+ #uiManager;
+ #previousAltText = null;
+ #svgElement = null;
+ #rectElement = null;
+ #container;
+ #telemetryData = null;
+ constructor({
+ dialog,
+ optionDescription,
+ optionDecorative,
+ textarea,
+ cancelButton,
+ saveButton
+ }, container, overlayManager, eventBus) {
+ this.#dialog = dialog;
+ this.#optionDescription = optionDescription;
+ this.#optionDecorative = optionDecorative;
+ this.#textarea = textarea;
+ this.#cancelButton = cancelButton;
+ this.#saveButton = saveButton;
+ this.#overlayManager = overlayManager;
+ this.#eventBus = eventBus;
+ this.#container = container;
+ dialog.addEventListener("close", this.#close.bind(this));
+ dialog.addEventListener("contextmenu", event => {
+ if (event.target !== this.#textarea) {
+ event.preventDefault();
+ }
+ });
+ cancelButton.addEventListener("click", this.#finish.bind(this));
+ saveButton.addEventListener("click", this.#save.bind(this));
+ optionDescription.addEventListener("change", this.#boundUpdateUIState);
+ optionDecorative.addEventListener("change", this.#boundUpdateUIState);
+ this.#overlayManager.register(dialog);
+ }
+ get _elements() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_elements", [this.#optionDescription, this.#optionDecorative, this.#textarea, this.#saveButton, this.#cancelButton]);
+ }
+ #createSVGElement() {
+ if (this.#svgElement) {
+ return;
+ }
+ const svgFactory = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.DOMSVGFactory();
+ const svg = this.#svgElement = svgFactory.createElement("svg");
+ svg.setAttribute("width", "0");
+ svg.setAttribute("height", "0");
+ const defs = svgFactory.createElement("defs");
+ svg.append(defs);
+ const mask = svgFactory.createElement("mask");
+ defs.append(mask);
+ mask.setAttribute("id", "alttext-manager-mask");
+ mask.setAttribute("maskContentUnits", "objectBoundingBox");
+ let rect = svgFactory.createElement("rect");
+ mask.append(rect);
+ rect.setAttribute("fill", "white");
+ rect.setAttribute("width", "1");
+ rect.setAttribute("height", "1");
+ rect.setAttribute("x", "0");
+ rect.setAttribute("y", "0");
+ rect = this.#rectElement = svgFactory.createElement("rect");
+ mask.append(rect);
+ rect.setAttribute("fill", "black");
+ this.#dialog.append(svg);
+ }
+ async editAltText(uiManager, editor) {
+ if (this.#currentEditor || !editor) {
+ return;
+ }
+ this.#createSVGElement();
+ this.#hasUsedPointer = false;
+ for (const element of this._elements) {
+ element.addEventListener("click", this.#boundOnClick);
+ }
+ const {
+ altText,
+ decorative
+ } = editor.altTextData;
+ if (decorative === true) {
+ this.#optionDecorative.checked = true;
+ this.#optionDescription.checked = false;
+ } else {
+ this.#optionDecorative.checked = false;
+ this.#optionDescription.checked = true;
+ }
+ this.#previousAltText = this.#textarea.value = altText?.trim() || "";
+ this.#updateUIState();
+ this.#currentEditor = editor;
+ this.#uiManager = uiManager;
+ this.#uiManager.removeEditListeners();
+ this.#eventBus._on("resize", this.#boundSetPosition);
+ try {
+ await this.#overlayManager.open(this.#dialog);
+ this.#setPosition();
+ } catch (ex) {
+ this.#close();
+ throw ex;
+ }
+ }
+ #setPosition() {
+ if (!this.#currentEditor) {
+ return;
+ }
+ const dialog = this.#dialog;
+ const {
+ style
+ } = dialog;
+ const {
+ x: containerX,
+ y: containerY,
+ width: containerW,
+ height: containerH
+ } = this.#container.getBoundingClientRect();
+ const {
+ innerWidth: windowW,
+ innerHeight: windowH
+ } = window;
+ const {
+ width: dialogW,
+ height: dialogH
+ } = dialog.getBoundingClientRect();
+ const {
+ x,
+ y,
+ width,
+ height
+ } = this.#currentEditor.getClientDimensions();
+ const MARGIN = 10;
+ const isLTR = this.#uiManager.direction === "ltr";
+ const xs = Math.max(x, containerX);
+ const xe = Math.min(x + width, containerX + containerW);
+ const ys = Math.max(y, containerY);
+ const ye = Math.min(y + height, containerY + containerH);
+ this.#rectElement.setAttribute("width", `${(xe - xs) / windowW}`);
+ this.#rectElement.setAttribute("height", `${(ye - ys) / windowH}`);
+ this.#rectElement.setAttribute("x", `${xs / windowW}`);
+ this.#rectElement.setAttribute("y", `${ys / windowH}`);
+ let left = null;
+ let top = Math.max(y, 0);
+ top += Math.min(windowH - (top + dialogH), 0);
+ if (isLTR) {
+ if (x + width + MARGIN + dialogW < windowW) {
+ left = x + width + MARGIN;
+ } else if (x > dialogW + MARGIN) {
+ left = x - dialogW - MARGIN;
+ }
+ } else if (x > dialogW + MARGIN) {
+ left = x - dialogW - MARGIN;
+ } else if (x + width + MARGIN + dialogW < windowW) {
+ left = x + width + MARGIN;
+ }
+ if (left === null) {
+ top = null;
+ left = Math.max(x, 0);
+ left += Math.min(windowW - (left + dialogW), 0);
+ if (y > dialogH + MARGIN) {
+ top = y - dialogH - MARGIN;
+ } else if (y + height + MARGIN + dialogH < windowH) {
+ top = y + height + MARGIN;
+ }
+ }
+ if (top !== null) {
+ dialog.classList.add("positioned");
+ if (isLTR) {
+ style.left = `${left}px`;
+ } else {
+ style.right = `${windowW - left - dialogW}px`;
+ }
+ style.top = `${top}px`;
+ } else {
+ dialog.classList.remove("positioned");
+ style.left = "";
+ style.top = "";
+ }
+ }
+ #finish() {
+ if (this.#overlayManager.active === this.#dialog) {
+ this.#overlayManager.close(this.#dialog);
+ }
+ }
+ #close() {
+ this.#eventBus.dispatch("reporttelemetry", {
+ source: this,
+ details: {
+ type: "editing",
+ subtype: this.#currentEditor.editorType,
+ data: this.#telemetryData || {
+ action: "alt_text_cancel",
+ alt_text_keyboard: !this.#hasUsedPointer
+ }
+ }
+ });
+ this.#telemetryData = null;
+ this.#removeOnClickListeners();
+ this.#uiManager?.addEditListeners();
+ this.#eventBus._off("resize", this.#boundSetPosition);
+ this.#currentEditor.altTextFinish();
+ this.#currentEditor = null;
+ this.#uiManager = null;
+ }
+ #updateUIState() {
+ this.#textarea.disabled = this.#optionDecorative.checked;
+ }
+ #save() {
+ const altText = this.#textarea.value.trim();
+ const decorative = this.#optionDecorative.checked;
+ this.#currentEditor.altTextData = {
+ altText,
+ decorative
+ };
+ this.#telemetryData = {
+ action: "alt_text_save",
+ alt_text_description: !!altText,
+ alt_text_edit: !!this.#previousAltText && this.#previousAltText !== altText,
+ alt_text_decorative: decorative,
+ alt_text_keyboard: !this.#hasUsedPointer
+ };
+ this.#finish();
+ }
+ #onClick(evt) {
+ if (evt.detail === 0) {
+ return;
+ }
+ this.#hasUsedPointer = true;
+ this.#removeOnClickListeners();
+ }
+ #removeOnClickListeners() {
+ for (const element of this._elements) {
+ element.removeEventListener("click", this.#boundOnClick);
+ }
+ }
+ destroy() {
+ this.#uiManager = null;
+ this.#finish();
+ this.#svgElement?.remove();
+ this.#svgElement = this.#rectElement = null;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 2640:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AnnotationEditorLayerBuilder: () => (/* binding */ AnnotationEditorLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7910);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+class AnnotationEditorLayerBuilder {
+ #annotationLayer = null;
+ #drawLayer = null;
+ #textLayer = null;
+ #uiManager;
+ constructor(options) {
+ this.pageDiv = options.pageDiv;
+ this.pdfPage = options.pdfPage;
+ this.accessibilityManager = options.accessibilityManager;
+ this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__.NullL10n;
+ this.annotationEditorLayer = null;
+ this.div = null;
+ this._cancelled = false;
+ this.#uiManager = options.uiManager;
+ this.#annotationLayer = options.annotationLayer || null;
+ this.#textLayer = options.textLayer || null;
+ this.#drawLayer = options.drawLayer || null;
+ }
+ async render(viewport, intent = "display") {
+ if (intent !== "display") {
+ return;
+ }
+ if (this._cancelled) {
+ return;
+ }
+ const clonedViewport = viewport.clone({
+ dontFlip: true
+ });
+ if (this.div) {
+ this.annotationEditorLayer.update({
+ viewport: clonedViewport
+ });
+ this.show();
+ return;
+ }
+ const div = this.div = document.createElement("div");
+ div.className = "annotationEditorLayer";
+ div.tabIndex = 0;
+ div.hidden = true;
+ div.dir = this.#uiManager.direction;
+ this.pageDiv.append(div);
+ this.annotationEditorLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorLayer({
+ uiManager: this.#uiManager,
+ div,
+ accessibilityManager: this.accessibilityManager,
+ pageIndex: this.pdfPage.pageNumber - 1,
+ l10n: this.l10n,
+ viewport: clonedViewport,
+ annotationLayer: this.#annotationLayer,
+ textLayer: this.#textLayer,
+ drawLayer: this.#drawLayer
+ });
+ const parameters = {
+ viewport: clonedViewport,
+ div,
+ annotations: null,
+ intent
+ };
+ this.annotationEditorLayer.render(parameters);
+ this.show();
+ }
+ cancel() {
+ this._cancelled = true;
+ if (!this.div) {
+ return;
+ }
+ this.pageDiv = null;
+ this.annotationEditorLayer.destroy();
+ this.div.remove();
+ }
+ hide() {
+ if (!this.div) {
+ return;
+ }
+ this.div.hidden = true;
+ }
+ show() {
+ if (!this.div || this.annotationEditorLayer.isEmpty) {
+ return;
+ }
+ this.div.hidden = false;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1296:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AnnotationEditorParams: () => (/* binding */ AnnotationEditorParams)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+class AnnotationEditorParams {
+ constructor(options, eventBus) {
+ this.eventBus = eventBus;
+ this.#bindListeners(options);
+ }
+ #bindListeners({
+ editorFreeTextFontSize,
+ editorFreeTextColor,
+ editorInkColor,
+ editorInkThickness,
+ editorInkOpacity,
+ editorStampAddImage
+ }) {
+ const dispatchEvent = (typeStr, value) => {
+ this.eventBus.dispatch("switchannotationeditorparams", {
+ source: this,
+ type: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType[typeStr],
+ value
+ });
+ };
+ editorFreeTextFontSize.addEventListener("input", function () {
+ dispatchEvent("FREETEXT_SIZE", this.valueAsNumber);
+ });
+ editorFreeTextColor.addEventListener("input", function () {
+ dispatchEvent("FREETEXT_COLOR", this.value);
+ });
+ editorInkColor.addEventListener("input", function () {
+ dispatchEvent("INK_COLOR", this.value);
+ });
+ editorInkThickness.addEventListener("input", function () {
+ dispatchEvent("INK_THICKNESS", this.valueAsNumber);
+ });
+ editorInkOpacity.addEventListener("input", function () {
+ dispatchEvent("INK_OPACITY", this.valueAsNumber);
+ });
+ editorStampAddImage.addEventListener("click", () => {
+ dispatchEvent("CREATE");
+ });
+ this.eventBus._on("annotationeditorparamschanged", evt => {
+ for (const [type, value] of evt.details) {
+ switch (type) {
+ case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.FREETEXT_SIZE:
+ editorFreeTextFontSize.value = value;
+ break;
+ case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.FREETEXT_COLOR:
+ editorFreeTextColor.value = value;
+ break;
+ case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_COLOR:
+ editorInkColor.value = value;
+ break;
+ case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_THICKNESS:
+ editorInkThickness.value = value;
+ break;
+ case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_OPACITY:
+ editorInkOpacity.value = value;
+ break;
+ }
+ }
+ });
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6735:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AnnotationLayerBuilder: () => (/* binding */ AnnotationLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+class AnnotationLayerBuilder {
+ #onPresentationModeChanged = null;
+ constructor({
+ pageDiv,
+ pdfPage,
+ linkService,
+ downloadManager,
+ annotationStorage = null,
+ imageResourcesPath = "",
+ renderForms = true,
+ enableScripting = false,
+ hasJSActionsPromise = null,
+ fieldObjectsPromise = null,
+ annotationCanvasMap = null,
+ accessibilityManager = null
+ }) {
+ this.pageDiv = pageDiv;
+ this.pdfPage = pdfPage;
+ this.linkService = linkService;
+ this.downloadManager = downloadManager;
+ this.imageResourcesPath = imageResourcesPath;
+ this.renderForms = renderForms;
+ this.annotationStorage = annotationStorage;
+ this.enableScripting = enableScripting;
+ this._hasJSActionsPromise = hasJSActionsPromise || Promise.resolve(false);
+ this._fieldObjectsPromise = fieldObjectsPromise || Promise.resolve(null);
+ this._annotationCanvasMap = annotationCanvasMap;
+ this._accessibilityManager = accessibilityManager;
+ this.annotationLayer = null;
+ this.div = null;
+ this._cancelled = false;
+ this._eventBus = linkService.eventBus;
+ }
+ async render(viewport, intent = "display") {
+ if (this.div) {
+ if (this._cancelled || !this.annotationLayer) {
+ return;
+ }
+ this.annotationLayer.update({
+ viewport: viewport.clone({
+ dontFlip: true
+ })
+ });
+ return;
+ }
+ const [annotations, hasJSActions, fieldObjects] = await Promise.all([this.pdfPage.getAnnotations({
+ intent
+ }), this._hasJSActionsPromise, this._fieldObjectsPromise]);
+ if (this._cancelled) {
+ return;
+ }
+ const div = this.div = document.createElement("div");
+ div.className = "annotationLayer";
+ this.pageDiv.append(div);
+ if (annotations.length === 0) {
+ this.hide();
+ return;
+ }
+ this.annotationLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationLayer({
+ div,
+ accessibilityManager: this._accessibilityManager,
+ annotationCanvasMap: this._annotationCanvasMap,
+ page: this.pdfPage,
+ viewport: viewport.clone({
+ dontFlip: true
+ })
+ });
+ await this.annotationLayer.render({
+ annotations,
+ imageResourcesPath: this.imageResourcesPath,
+ renderForms: this.renderForms,
+ linkService: this.linkService,
+ downloadManager: this.downloadManager,
+ annotationStorage: this.annotationStorage,
+ enableScripting: this.enableScripting,
+ hasJSActions,
+ fieldObjects
+ });
+ if (this.linkService.isInPresentationMode) {
+ this.#updatePresentationModeState(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN);
+ }
+ if (!this.#onPresentationModeChanged) {
+ this.#onPresentationModeChanged = evt => {
+ this.#updatePresentationModeState(evt.state);
+ };
+ this._eventBus?._on("presentationmodechanged", this.#onPresentationModeChanged);
+ }
+ }
+ cancel() {
+ this._cancelled = true;
+ if (this.#onPresentationModeChanged) {
+ this._eventBus?._off("presentationmodechanged", this.#onPresentationModeChanged);
+ this.#onPresentationModeChanged = null;
+ }
+ }
+ hide() {
+ if (!this.div) {
+ return;
+ }
+ this.div.hidden = true;
+ }
+ #updatePresentationModeState(state) {
+ if (!this.div) {
+ return;
+ }
+ let disableFormElements = false;
+ switch (state) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN:
+ disableFormElements = true;
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL:
+ break;
+ default:
+ return;
+ }
+ for (const section of this.div.childNodes) {
+ if (section.hasAttribute("data-internal-link")) {
+ continue;
+ }
+ section.inert = disableFormElements;
+ }
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 39:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ DefaultExternalServices: () => (/* binding */ DefaultExternalServices),
+/* harmony export */ PDFPrintServiceFactory: () => (/* binding */ PDFPrintServiceFactory),
+/* harmony export */ PDFViewerApplication: () => (/* binding */ PDFViewerApplication)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8961);
+/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6554);
+/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3234);
+/* harmony import */ var web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(631);
+/* harmony import */ var web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1296);
+/* harmony import */ var _overlay_manager_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(1996);
+/* harmony import */ var _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6329);
+/* harmony import */ var web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(716);
+/* harmony import */ var web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(3611);
+/* harmony import */ var web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(6312);
+/* harmony import */ var web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(1795);
+/* harmony import */ var _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3557);
+/* harmony import */ var _pdf_history_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6418);
+/* harmony import */ var web_pdf_layer_viewer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(3706);
+/* harmony import */ var web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(1141);
+/* harmony import */ var web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(323);
+/* harmony import */ var _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(5119);
+/* harmony import */ var _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2599);
+/* harmony import */ var web_pdf_sidebar__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(4487);
+/* harmony import */ var web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(3510);
+/* harmony import */ var _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(9290);
+/* harmony import */ var web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(1544);
+/* harmony import */ var web_toolbar__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(276);
+/* harmony import */ var _view_history_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(1096);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__, web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__, web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__, _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__, web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__, web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__, web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__, web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__, _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__, web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__, web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__, _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__, web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__, _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__, web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__, web_toolbar__WEBPACK_IMPORTED_MODULE_23__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__, web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__, web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__, _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__, web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__, web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__, web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__, web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__, _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__, web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__, web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__, _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__, web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__, _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__, web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__, web_toolbar__WEBPACK_IMPORTED_MODULE_23__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const FORCE_PAGES_LOADED_TIMEOUT = 10000;
+const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000;
+const ViewOnLoad = {
+ UNKNOWN: -1,
+ PREVIOUS: 0,
+ INITIAL: 1
+};
+class DefaultExternalServices {
+ constructor() {
+ throw new Error("Cannot initialize DefaultExternalServices.");
+ }
+ static updateFindControlState(data) {}
+ static updateFindMatchesCount(data) {}
+ static initPassiveLoading(callbacks) {}
+ static reportTelemetry(data) {}
+ static createDownloadManager() {
+ throw new Error("Not implemented: createDownloadManager");
+ }
+ static createPreferences() {
+ throw new Error("Not implemented: createPreferences");
+ }
+ static async createL10n() {
+ throw new Error("Not implemented: createL10n");
+ }
+ static createScripting() {
+ throw new Error("Not implemented: createScripting");
+ }
+ static updateEditorStates(data) {
+ throw new Error("Not implemented: updateEditorStates");
+ }
+ static getNimbusExperimentData() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "getNimbusExperimentData", Promise.resolve(null));
+ }
+}
+const PDFViewerApplication = {
+ initialBookmark: document.location.hash.substring(1),
+ _initializedCapability: new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(),
+ appConfig: null,
+ pdfDocument: null,
+ pdfLoadingTask: null,
+ printService: null,
+ pdfViewer: null,
+ pdfThumbnailViewer: null,
+ pdfRenderingQueue: null,
+ pdfPresentationMode: null,
+ pdfDocumentProperties: null,
+ pdfLinkService: null,
+ pdfHistory: null,
+ pdfSidebar: null,
+ pdfOutlineViewer: null,
+ pdfAttachmentViewer: null,
+ pdfLayerViewer: null,
+ pdfCursorTools: null,
+ pdfScriptingManager: null,
+ store: null,
+ downloadManager: null,
+ overlayManager: null,
+ preferences: null,
+ toolbar: null,
+ secondaryToolbar: null,
+ eventBus: null,
+ l10n: null,
+ annotationEditorParams: null,
+ isInitialViewSet: false,
+ downloadComplete: false,
+ isViewerEmbedded: window.parent !== window,
+ url: "",
+ baseUrl: "",
+ _downloadUrl: "",
+ externalServices: DefaultExternalServices,
+ _boundEvents: Object.create(null),
+ documentInfo: null,
+ metadata: null,
+ _contentDispositionFilename: null,
+ _contentLength: null,
+ _saveInProgress: false,
+ _wheelUnusedTicks: 0,
+ _wheelUnusedFactor: 1,
+ _touchUnusedTicks: 0,
+ _touchUnusedFactor: 1,
+ _PDFBug: null,
+ _hasAnnotationEditors: false,
+ _title: document.title,
+ _printAnnotationStoragePromise: null,
+ _touchInfo: null,
+ _isCtrlKeyDown: false,
+ _nimbusDataPromise: null,
+ async initialize(appConfig) {
+ let l10nPromise;
+ this.appConfig = appConfig;
+ try {
+ await this.preferences.initializedPromise;
+ } catch (ex) {
+ console.error(`initialize: "${ex.message}".`);
+ }
+ if (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pdfBugEnabled")) {
+ await this._parseHashParams();
+ }
+ let mode;
+ switch (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("viewerCssTheme")) {
+ case 1:
+ mode = "is-light";
+ break;
+ case 2:
+ mode = "is-dark";
+ break;
+ }
+ if (mode) {
+ document.documentElement.classList.add(mode);
+ }
+ l10nPromise = this.externalServices.createL10n();
+ this.l10n = await l10nPromise;
+ document.getElementsByTagName("html")[0].dir = this.l10n.getDirection();
+ this.l10n.translate(appConfig.appContainer || document.documentElement);
+ if (this.isViewerEmbedded && _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkTarget") === _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget.NONE) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("externalLinkTarget", _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget.TOP);
+ }
+ await this._initializeViewerComponents();
+ this.bindEvents();
+ this.bindWindowEvents();
+ this._initializedCapability.resolve();
+ },
+ async _parseHashParams() {
+ const hash = document.location.hash.substring(1);
+ if (!hash) {
+ return;
+ }
+ const {
+ mainContainer,
+ viewerContainer
+ } = this.appConfig,
+ params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash);
+ if (params.get("disableworker") === "true") {
+ try {
+ await loadFakeWorker();
+ } catch (ex) {
+ console.error(`_parseHashParams: "${ex.message}".`);
+ }
+ }
+ if (params.has("disablerange")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableRange", params.get("disablerange") === "true");
+ }
+ if (params.has("disablestream")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableStream", params.get("disablestream") === "true");
+ }
+ if (params.has("disableautofetch")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableAutoFetch", params.get("disableautofetch") === "true");
+ }
+ if (params.has("disablefontface")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableFontFace", params.get("disablefontface") === "true");
+ }
+ if (params.has("disablehistory")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableHistory", params.get("disablehistory") === "true");
+ }
+ if (params.has("verbosity")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("verbosity", params.get("verbosity") | 0);
+ }
+ if (params.has("textlayer")) {
+ switch (params.get("textlayer")) {
+ case "off":
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("textLayerMode", _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.TextLayerMode.DISABLE);
+ break;
+ case "visible":
+ case "shadow":
+ case "hover":
+ viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`);
+ try {
+ await loadPDFBug(this);
+ this._PDFBug.loadCSS();
+ } catch (ex) {
+ console.error(`_parseHashParams: "${ex.message}".`);
+ }
+ break;
+ }
+ }
+ if (params.has("pdfbug")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("pdfBug", true);
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("fontExtraProperties", true);
+ const enabled = params.get("pdfbug").split(",");
+ try {
+ await loadPDFBug(this);
+ this._PDFBug.init(mainContainer, enabled);
+ } catch (ex) {
+ console.error(`_parseHashParams: "${ex.message}".`);
+ }
+ }
+ if (params.has("locale")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("locale", params.get("locale"));
+ }
+ },
+ async _initializeViewerComponents() {
+ const {
+ appConfig,
+ externalServices,
+ l10n
+ } = this;
+ const eventBus = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("isInAutomation") ? new _event_utils_js__WEBPACK_IMPORTED_MODULE_3__.AutomationEventBus() : new _event_utils_js__WEBPACK_IMPORTED_MODULE_3__.EventBus();
+ this.eventBus = eventBus;
+ this.overlayManager = new _overlay_manager_js__WEBPACK_IMPORTED_MODULE_24__.OverlayManager();
+ const pdfRenderingQueue = new _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__.PDFRenderingQueue();
+ pdfRenderingQueue.onIdle = this._cleanup.bind(this);
+ this.pdfRenderingQueue = pdfRenderingQueue;
+ const pdfLinkService = new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.PDFLinkService({
+ eventBus,
+ externalLinkTarget: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkTarget"),
+ externalLinkRel: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkRel"),
+ ignoreDestinationZoom: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("ignoreDestinationZoom")
+ });
+ this.pdfLinkService = pdfLinkService;
+ const downloadManager = externalServices.createDownloadManager();
+ this.downloadManager = downloadManager;
+ const findController = new _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__.PDFFindController({
+ linkService: pdfLinkService,
+ eventBus,
+ updateMatchesCountOnProgress: true
+ });
+ this.findController = findController;
+ const pdfScriptingManager = new _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__.PDFScriptingManager({
+ eventBus,
+ externalServices,
+ docProperties: this._scriptingDocProperties.bind(this)
+ });
+ this.pdfScriptingManager = pdfScriptingManager;
+ const container = appConfig.mainContainer,
+ viewer = appConfig.viewerContainer;
+ const annotationEditorMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("annotationEditorMode");
+ const isOffscreenCanvasSupported = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("isOffscreenCanvasSupported") && pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.FeatureTest.isOffscreenCanvasSupported;
+ const pageColors = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("forcePageColors") || window.matchMedia("(forced-colors: active)").matches ? {
+ background: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pageColorsBackground"),
+ foreground: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pageColorsForeground")
+ } : null;
+ const altTextManager = appConfig.altTextDialog ? new web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__.AltTextManager(appConfig.altTextDialog, container, this.overlayManager, eventBus) : null;
+ const pdfViewer = new _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__.PDFViewer({
+ container,
+ viewer,
+ eventBus,
+ renderingQueue: pdfRenderingQueue,
+ linkService: pdfLinkService,
+ downloadManager,
+ altTextManager,
+ findController,
+ scriptingManager: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enableScripting") && pdfScriptingManager,
+ l10n,
+ textLayerMode: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("textLayerMode"),
+ annotationMode: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("annotationMode"),
+ annotationEditorMode,
+ annotationEditorHighlightColors: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("highlightEditorColors"),
+ imageResourcesPath: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("imageResourcesPath"),
+ enablePrintAutoRotate: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enablePrintAutoRotate"),
+ isOffscreenCanvasSupported,
+ maxCanvasPixels: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("maxCanvasPixels"),
+ enablePermissions: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enablePermissions"),
+ pageColors
+ });
+ this.pdfViewer = pdfViewer;
+ pdfRenderingQueue.setViewer(pdfViewer);
+ pdfLinkService.setViewer(pdfViewer);
+ pdfScriptingManager.setViewer(pdfViewer);
+ if (appConfig.sidebar?.thumbnailView) {
+ this.pdfThumbnailViewer = new web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__.PDFThumbnailViewer({
+ container: appConfig.sidebar.thumbnailView,
+ eventBus,
+ renderingQueue: pdfRenderingQueue,
+ linkService: pdfLinkService,
+ pageColors
+ });
+ pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
+ }
+ if (!this.isViewerEmbedded && !_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disableHistory")) {
+ this.pdfHistory = new _pdf_history_js__WEBPACK_IMPORTED_MODULE_13__.PDFHistory({
+ linkService: pdfLinkService,
+ eventBus
+ });
+ pdfLinkService.setHistory(this.pdfHistory);
+ }
+ if (!this.supportsIntegratedFind && appConfig.findBar) {
+ this.findBar = new web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__.PDFFindBar(appConfig.findBar, eventBus);
+ }
+ if (appConfig.annotationEditorParams) {
+ if (annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.DISABLE) {
+ if (!isOffscreenCanvasSupported) {
+ appConfig.toolbar?.editorStampButton?.classList.add("hidden");
+ }
+ const editorHighlightButton = appConfig.toolbar?.editorHighlightButton;
+ if (editorHighlightButton && _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enableHighlightEditor")) {
+ editorHighlightButton.hidden = false;
+ }
+ this.annotationEditorParams = new web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__.AnnotationEditorParams(appConfig.annotationEditorParams, eventBus);
+ } else {
+ for (const id of ["editorModeButtons", "editorModeSeparator"]) {
+ document.getElementById(id)?.classList.add("hidden");
+ }
+ }
+ }
+ if (appConfig.documentProperties) {
+ this.pdfDocumentProperties = new web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, l10n, () => this._docFilename);
+ }
+ if (appConfig.secondaryToolbar?.cursorHandToolButton) {
+ this.pdfCursorTools = new web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__.PDFCursorTools({
+ container,
+ eventBus,
+ cursorToolOnLoad: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("cursorToolOnLoad")
+ });
+ }
+ if (appConfig.toolbar) {
+ this.toolbar = new web_toolbar__WEBPACK_IMPORTED_MODULE_23__.Toolbar(appConfig.toolbar, eventBus);
+ }
+ if (appConfig.secondaryToolbar) {
+ this.secondaryToolbar = new web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__.SecondaryToolbar(appConfig.secondaryToolbar, eventBus);
+ }
+ if (this.supportsFullscreen && appConfig.secondaryToolbar?.presentationModeButton) {
+ this.pdfPresentationMode = new web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__.PDFPresentationMode({
+ container,
+ pdfViewer,
+ eventBus
+ });
+ }
+ if (appConfig.passwordOverlay) {
+ this.passwordPrompt = new _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__.PasswordPrompt(appConfig.passwordOverlay, this.overlayManager, this.isViewerEmbedded);
+ }
+ if (appConfig.sidebar?.outlineView) {
+ this.pdfOutlineViewer = new web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__.PDFOutlineViewer({
+ container: appConfig.sidebar.outlineView,
+ eventBus,
+ l10n,
+ linkService: pdfLinkService,
+ downloadManager
+ });
+ }
+ if (appConfig.sidebar?.attachmentsView) {
+ this.pdfAttachmentViewer = new web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__.PDFAttachmentViewer({
+ container: appConfig.sidebar.attachmentsView,
+ eventBus,
+ l10n,
+ downloadManager
+ });
+ }
+ if (appConfig.sidebar?.layersView) {
+ this.pdfLayerViewer = new web_pdf_layer_viewer__WEBPACK_IMPORTED_MODULE_14__.PDFLayerViewer({
+ container: appConfig.sidebar.layersView,
+ eventBus,
+ l10n
+ });
+ }
+ if (appConfig.sidebar) {
+ this.pdfSidebar = new web_pdf_sidebar__WEBPACK_IMPORTED_MODULE_19__.PDFSidebar({
+ elements: appConfig.sidebar,
+ eventBus,
+ l10n
+ });
+ this.pdfSidebar.onToggled = this.forceRendering.bind(this);
+ this.pdfSidebar.onUpdateThumbnails = () => {
+ for (const pageView of pdfViewer.getCachedPageViews()) {
+ if (pageView.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) {
+ this.pdfThumbnailViewer.getThumbnail(pageView.id - 1)?.setImage(pageView);
+ }
+ }
+ this.pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber);
+ };
+ }
+ },
+ async run(config) {
+ this.preferences = this.externalServices.createPreferences();
+ await this.initialize(config);
+ const {
+ appConfig,
+ eventBus
+ } = this;
+ let file;
+ const queryString = document.location.search.substring(1);
+ const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(queryString);
+ file = params.get("file") ?? _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultUrl");
+ validateFileURL(file);
+ const fileInput = appConfig.openFileInput;
+ fileInput.value = null;
+ fileInput.addEventListener("change", function (evt) {
+ const {
+ files
+ } = evt.target;
+ if (!files || files.length === 0) {
+ return;
+ }
+ eventBus.dispatch("fileinputchange", {
+ source: this,
+ fileInput: evt.target
+ });
+ });
+ appConfig.mainContainer.addEventListener("dragover", function (evt) {
+ evt.preventDefault();
+ evt.dataTransfer.dropEffect = evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move";
+ });
+ appConfig.mainContainer.addEventListener("drop", function (evt) {
+ evt.preventDefault();
+ const {
+ files
+ } = evt.dataTransfer;
+ if (!files || files.length === 0) {
+ return;
+ }
+ eventBus.dispatch("fileinputchange", {
+ source: this,
+ fileInput: evt.dataTransfer
+ });
+ });
+ if (!_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsDocumentFonts")) {
+ _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableFontFace", true);
+ this.l10n.get("pdfjs-web-fonts-disabled").then(msg => {
+ console.warn(msg);
+ });
+ }
+ if (!this.supportsPrinting) {
+ appConfig.toolbar?.print?.classList.add("hidden");
+ appConfig.secondaryToolbar?.printButton.classList.add("hidden");
+ }
+ if (!this.supportsFullscreen) {
+ appConfig.secondaryToolbar?.presentationModeButton.classList.add("hidden");
+ }
+ if (this.supportsIntegratedFind) {
+ appConfig.toolbar?.viewFind?.classList.add("hidden");
+ }
+ if (file) {
+ this.open({
+ url: file
+ });
+ } else {
+ this._hideViewBookmark();
+ }
+ },
+ get initialized() {
+ return this._initializedCapability.settled;
+ },
+ get initializedPromise() {
+ return this._initializedCapability.promise;
+ },
+ zoomIn(steps, scaleFactor) {
+ if (this.pdfViewer.isInPresentationMode) {
+ return;
+ }
+ this.pdfViewer.increaseScale({
+ drawingDelay: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomDelay"),
+ steps,
+ scaleFactor
+ });
+ },
+ zoomOut(steps, scaleFactor) {
+ if (this.pdfViewer.isInPresentationMode) {
+ return;
+ }
+ this.pdfViewer.decreaseScale({
+ drawingDelay: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomDelay"),
+ steps,
+ scaleFactor
+ });
+ },
+ zoomReset() {
+ if (this.pdfViewer.isInPresentationMode) {
+ return;
+ }
+ this.pdfViewer.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE;
+ },
+ get pagesCount() {
+ return this.pdfDocument ? this.pdfDocument.numPages : 0;
+ },
+ get page() {
+ return this.pdfViewer.currentPageNumber;
+ },
+ set page(val) {
+ this.pdfViewer.currentPageNumber = val;
+ },
+ get supportsPrinting() {
+ return PDFPrintServiceFactory.instance.supportsPrinting;
+ },
+ get supportsFullscreen() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsFullscreen", document.fullscreenEnabled);
+ },
+ get supportsPinchToZoom() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsPinchToZoom", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsPinchToZoom"));
+ },
+ get supportsIntegratedFind() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsIntegratedFind", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsIntegratedFind"));
+ },
+ get loadingBar() {
+ const barElement = document.getElementById("loadingBar");
+ const bar = barElement ? new _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ProgressBar(barElement) : null;
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "loadingBar", bar);
+ },
+ get supportsMouseWheelZoomCtrlKey() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsMouseWheelZoomCtrlKey", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsMouseWheelZoomCtrlKey"));
+ },
+ get supportsMouseWheelZoomMetaKey() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsMouseWheelZoomMetaKey", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsMouseWheelZoomMetaKey"));
+ },
+ initPassiveLoading(file) {
+ throw new Error("Not implemented: initPassiveLoading");
+ },
+ setTitleUsingUrl(url = "", downloadUrl = null) {
+ this.url = url;
+ this.baseUrl = url.split("#", 1)[0];
+ if (downloadUrl) {
+ this._downloadUrl = downloadUrl === url ? this.baseUrl : downloadUrl.split("#", 1)[0];
+ }
+ if ((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.isDataScheme)(url)) {
+ this._hideViewBookmark();
+ }
+ let title = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getPdfFilenameFromUrl)(url, "");
+ if (!title) {
+ try {
+ title = decodeURIComponent((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getFilenameFromUrl)(url)) || url;
+ } catch {
+ title = url;
+ }
+ }
+ this.setTitle(title);
+ },
+ setTitle(title = this._title) {
+ this._title = title;
+ if (this.isViewerEmbedded) {
+ return;
+ }
+ const editorIndicator = this._hasAnnotationEditors && !this.pdfRenderingQueue.printing;
+ document.title = `${editorIndicator ? "* " : ""}${title}`;
+ },
+ get _docFilename() {
+ return this._contentDispositionFilename || (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getPdfFilenameFromUrl)(this.url);
+ },
+ _hideViewBookmark() {
+ const {
+ secondaryToolbar
+ } = this.appConfig;
+ secondaryToolbar?.viewBookmarkButton.classList.add("hidden");
+ if (secondaryToolbar?.presentationModeButton.classList.contains("hidden")) {
+ document.getElementById("viewBookmarkSeparator")?.classList.add("hidden");
+ }
+ },
+ async close() {
+ this._unblockDocumentLoadEvent();
+ this._hideViewBookmark();
+ if (!this.pdfLoadingTask) {
+ return;
+ }
+ if (this.pdfDocument?.annotationStorage.size > 0 && this._annotationStorageModified) {
+ try {
+ await this.save();
+ } catch {}
+ }
+ const promises = [];
+ promises.push(this.pdfLoadingTask.destroy());
+ this.pdfLoadingTask = null;
+ if (this.pdfDocument) {
+ this.pdfDocument = null;
+ this.pdfThumbnailViewer?.setDocument(null);
+ this.pdfViewer.setDocument(null);
+ this.pdfLinkService.setDocument(null);
+ this.pdfDocumentProperties?.setDocument(null);
+ }
+ this.pdfLinkService.externalLinkEnabled = true;
+ this.store = null;
+ this.isInitialViewSet = false;
+ this.downloadComplete = false;
+ this.url = "";
+ this.baseUrl = "";
+ this._downloadUrl = "";
+ this.documentInfo = null;
+ this.metadata = null;
+ this._contentDispositionFilename = null;
+ this._contentLength = null;
+ this._saveInProgress = false;
+ this._hasAnnotationEditors = false;
+ promises.push(this.pdfScriptingManager.destroyPromise, this.passwordPrompt.close());
+ this.setTitle();
+ this.pdfSidebar?.reset();
+ this.pdfOutlineViewer?.reset();
+ this.pdfAttachmentViewer?.reset();
+ this.pdfLayerViewer?.reset();
+ this.pdfHistory?.reset();
+ this.findBar?.reset();
+ this.toolbar?.reset();
+ this.secondaryToolbar?.reset();
+ this._PDFBug?.cleanup();
+ await Promise.all(promises);
+ },
+ async open(args) {
+ if (this.pdfLoadingTask) {
+ await this.close();
+ }
+ const workerParams = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.getAll(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.OptionKind.WORKER);
+ Object.assign(pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.GlobalWorkerOptions, workerParams);
+ if (args.url) {
+ this.setTitleUsingUrl(args.originalUrl || args.url, args.url);
+ }
+ const apiParams = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.getAll(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.OptionKind.API);
+ const loadingTask = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getDocument)({
+ ...apiParams,
+ ...args
+ });
+ this.pdfLoadingTask = loadingTask;
+ loadingTask.onPassword = (updateCallback, reason) => {
+ if (this.isViewerEmbedded) {
+ this._unblockDocumentLoadEvent();
+ }
+ this.pdfLinkService.externalLinkEnabled = false;
+ this.passwordPrompt.setUpdateCallback(updateCallback, reason);
+ this.passwordPrompt.open();
+ };
+ loadingTask.onProgress = ({
+ loaded,
+ total
+ }) => {
+ this.progress(loaded / total);
+ };
+ return loadingTask.promise.then(pdfDocument => {
+ this.load(pdfDocument);
+ }, reason => {
+ if (loadingTask !== this.pdfLoadingTask) {
+ return undefined;
+ }
+ let key = "pdfjs-loading-error";
+ if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.InvalidPDFException) {
+ key = "pdfjs-invalid-file-error";
+ } else if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.MissingPDFException) {
+ key = "pdfjs-missing-file-error";
+ } else if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.UnexpectedResponseException) {
+ key = "pdfjs-unexpected-response-error";
+ }
+ return this.l10n.get(key).then(msg => {
+ this._documentError(msg, {
+ message: reason?.message
+ });
+ throw reason;
+ });
+ });
+ },
+ _ensureDownloadComplete() {
+ if (this.pdfDocument && this.downloadComplete) {
+ return;
+ }
+ throw new Error("PDF document not downloaded.");
+ },
+ async download(options = {}) {
+ const url = this._downloadUrl,
+ filename = this._docFilename;
+ try {
+ this._ensureDownloadComplete();
+ const data = await this.pdfDocument.getData();
+ const blob = new Blob([data], {
+ type: "application/pdf"
+ });
+ await this.downloadManager.download(blob, url, filename, options);
+ } catch {
+ await this.downloadManager.downloadUrl(url, filename, options);
+ }
+ },
+ async save(options = {}) {
+ if (this._saveInProgress) {
+ return;
+ }
+ this._saveInProgress = true;
+ await this.pdfScriptingManager.dispatchWillSave();
+ const url = this._downloadUrl,
+ filename = this._docFilename;
+ try {
+ this._ensureDownloadComplete();
+ const data = await this.pdfDocument.saveDocument();
+ const blob = new Blob([data], {
+ type: "application/pdf"
+ });
+ await this.downloadManager.download(blob, url, filename, options);
+ } catch (reason) {
+ console.error(`Error when saving the document: ${reason.message}`);
+ await this.download(options);
+ } finally {
+ await this.pdfScriptingManager.dispatchDidSave();
+ this._saveInProgress = false;
+ }
+ if (this._hasAnnotationEditors) {
+ this.externalServices.reportTelemetry({
+ type: "editing",
+ data: {
+ type: "save"
+ }
+ });
+ }
+ },
+ downloadOrSave(options = {}) {
+ if (this.pdfDocument?.annotationStorage.size > 0) {
+ this.save(options);
+ } else {
+ this.download(options);
+ }
+ },
+ openInExternalApp() {
+ this.downloadOrSave({
+ openInExternalApp: true
+ });
+ },
+ _documentError(message, moreInfo = null) {
+ this._unblockDocumentLoadEvent();
+ this._otherError(message, moreInfo);
+ this.eventBus.dispatch("documenterror", {
+ source: this,
+ message,
+ reason: moreInfo?.message ?? null
+ });
+ },
+ _otherError(message, moreInfo = null) {
+ const moreInfoText = [`PDF.js v${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.version || "?"} (build: ${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.build || "?"})`];
+ if (moreInfo) {
+ moreInfoText.push(`Message: ${moreInfo.message}`);
+ if (moreInfo.stack) {
+ moreInfoText.push(`Stack: ${moreInfo.stack}`);
+ } else {
+ if (moreInfo.filename) {
+ moreInfoText.push(`File: ${moreInfo.filename}`);
+ }
+ if (moreInfo.lineNumber) {
+ moreInfoText.push(`Line: ${moreInfo.lineNumber}`);
+ }
+ }
+ }
+ console.error(`${message}\n\n${moreInfoText.join("\n")}`);
+ },
+ progress(level) {
+ if (!this.loadingBar || this.downloadComplete) {
+ return;
+ }
+ const percent = Math.round(level * 100);
+ if (percent <= this.loadingBar.percent) {
+ return;
+ }
+ this.loadingBar.percent = percent;
+ if (this.pdfDocument?.loadingParams.disableAutoFetch ?? _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disableAutoFetch")) {
+ this.loadingBar.setDisableAutoFetch();
+ }
+ },
+ load(pdfDocument) {
+ this.pdfDocument = pdfDocument;
+ pdfDocument.getDownloadInfo().then(({
+ length
+ }) => {
+ this._contentLength = length;
+ this.downloadComplete = true;
+ this.loadingBar?.hide();
+ firstPagePromise.then(() => {
+ this.eventBus.dispatch("documentloaded", {
+ source: this
+ });
+ });
+ });
+ const pageLayoutPromise = pdfDocument.getPageLayout().catch(() => {});
+ const pageModePromise = pdfDocument.getPageMode().catch(() => {});
+ const openActionPromise = pdfDocument.getOpenAction().catch(() => {});
+ this.toolbar?.setPagesCount(pdfDocument.numPages, false);
+ this.secondaryToolbar?.setPagesCount(pdfDocument.numPages);
+ this.pdfLinkService.setDocument(pdfDocument);
+ this.pdfDocumentProperties?.setDocument(pdfDocument);
+ const pdfViewer = this.pdfViewer;
+ pdfViewer.setDocument(pdfDocument);
+ const {
+ firstPagePromise,
+ onePageRendered,
+ pagesPromise
+ } = pdfViewer;
+ this.pdfThumbnailViewer?.setDocument(pdfDocument);
+ const storedPromise = (this.store = new _view_history_js__WEBPACK_IMPORTED_MODULE_25__.ViewHistory(pdfDocument.fingerprints[0])).getMultiple({
+ page: null,
+ zoom: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE,
+ scrollLeft: "0",
+ scrollTop: "0",
+ rotation: null,
+ sidebarView: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN,
+ scrollMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN,
+ spreadMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN
+ }).catch(() => {});
+ firstPagePromise.then(pdfPage => {
+ this.loadingBar?.setWidth(this.appConfig.viewerContainer);
+ this._initializeAnnotationStorageCallbacks(pdfDocument);
+ Promise.all([_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.animationStarted, storedPromise, pageLayoutPromise, pageModePromise, openActionPromise]).then(async ([timeStamp, stored, pageLayout, pageMode, openAction]) => {
+ const viewOnLoad = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("viewOnLoad");
+ this._initializePdfHistory({
+ fingerprint: pdfDocument.fingerprints[0],
+ viewOnLoad,
+ initialDest: openAction?.dest
+ });
+ const initialBookmark = this.initialBookmark;
+ const zoom = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomValue");
+ let hash = zoom ? `zoom=${zoom}` : null;
+ let rotation = null;
+ let sidebarView = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("sidebarViewOnLoad");
+ let scrollMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("scrollModeOnLoad");
+ let spreadMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("spreadModeOnLoad");
+ if (stored?.page && viewOnLoad !== ViewOnLoad.INITIAL) {
+ hash = `page=${stored.page}&zoom=${zoom || stored.zoom},` + `${stored.scrollLeft},${stored.scrollTop}`;
+ rotation = parseInt(stored.rotation, 10);
+ if (sidebarView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) {
+ sidebarView = stored.sidebarView | 0;
+ }
+ if (scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN) {
+ scrollMode = stored.scrollMode | 0;
+ }
+ if (spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN) {
+ spreadMode = stored.spreadMode | 0;
+ }
+ }
+ if (pageMode && sidebarView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) {
+ sidebarView = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageModeToSidebarView)(pageMode);
+ }
+ if (pageLayout && scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN && spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN) {
+ const modes = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageLayoutToViewerModes)(pageLayout);
+ spreadMode = modes.spreadMode;
+ }
+ this.setInitialView(hash, {
+ rotation,
+ sidebarView,
+ scrollMode,
+ spreadMode
+ });
+ this.eventBus.dispatch("documentinit", {
+ source: this
+ });
+ if (!this.isViewerEmbedded) {
+ pdfViewer.focus();
+ }
+ await Promise.race([pagesPromise, new Promise(resolve => {
+ setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
+ })]);
+ if (!initialBookmark && !hash) {
+ return;
+ }
+ if (pdfViewer.hasEqualPageSizes) {
+ return;
+ }
+ this.initialBookmark = initialBookmark;
+ pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
+ this.setInitialView(hash);
+ }).catch(() => {
+ this.setInitialView();
+ }).then(function () {
+ pdfViewer.update();
+ });
+ });
+ pagesPromise.then(() => {
+ this._unblockDocumentLoadEvent();
+ this._initializeAutoPrint(pdfDocument, openActionPromise);
+ }, reason => {
+ this.l10n.get("pdfjs-loading-error").then(msg => {
+ this._documentError(msg, {
+ message: reason?.message
+ });
+ });
+ });
+ onePageRendered.then(data => {
+ this.externalServices.reportTelemetry({
+ type: "pageInfo",
+ timestamp: data.timestamp
+ });
+ if (this.pdfOutlineViewer) {
+ pdfDocument.getOutline().then(outline => {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ this.pdfOutlineViewer.render({
+ outline,
+ pdfDocument
+ });
+ });
+ }
+ if (this.pdfAttachmentViewer) {
+ pdfDocument.getAttachments().then(attachments => {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ this.pdfAttachmentViewer.render({
+ attachments
+ });
+ });
+ }
+ if (this.pdfLayerViewer) {
+ pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ this.pdfLayerViewer.render({
+ optionalContentConfig,
+ pdfDocument
+ });
+ });
+ }
+ });
+ this._initializePageLabels(pdfDocument);
+ this._initializeMetadata(pdfDocument);
+ },
+ async _scriptingDocProperties(pdfDocument) {
+ if (!this.documentInfo) {
+ await new Promise(resolve => {
+ this.eventBus._on("metadataloaded", resolve, {
+ once: true
+ });
+ });
+ if (pdfDocument !== this.pdfDocument) {
+ return null;
+ }
+ }
+ if (!this._contentLength) {
+ await new Promise(resolve => {
+ this.eventBus._on("documentloaded", resolve, {
+ once: true
+ });
+ });
+ if (pdfDocument !== this.pdfDocument) {
+ return null;
+ }
+ }
+ return {
+ ...this.documentInfo,
+ baseURL: this.baseUrl,
+ filesize: this._contentLength,
+ filename: this._docFilename,
+ metadata: this.metadata?.getRaw(),
+ authors: this.metadata?.get("dc:creator"),
+ numPages: this.pagesCount,
+ URL: this.url
+ };
+ },
+ async _initializeAutoPrint(pdfDocument, openActionPromise) {
+ const [openAction, jsActions] = await Promise.all([openActionPromise, this.pdfViewer.enableScripting ? null : pdfDocument.getJSActions()]);
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ let triggerAutoPrint = openAction?.action === "Print";
+ if (jsActions) {
+ console.warn("Warning: JavaScript support is not enabled");
+ for (const name in jsActions) {
+ if (triggerAutoPrint) {
+ break;
+ }
+ switch (name) {
+ case "WillClose":
+ case "WillSave":
+ case "DidSave":
+ case "WillPrint":
+ case "DidPrint":
+ continue;
+ }
+ triggerAutoPrint = jsActions[name].some(js => _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.AutoPrintRegExp.test(js));
+ }
+ }
+ if (triggerAutoPrint) {
+ this.triggerPrinting();
+ }
+ },
+ async _initializeMetadata(pdfDocument) {
+ const {
+ info,
+ metadata,
+ contentDispositionFilename,
+ contentLength
+ } = await pdfDocument.getMetadata();
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ this.documentInfo = info;
+ this.metadata = metadata;
+ this._contentDispositionFilename ??= contentDispositionFilename;
+ this._contentLength ??= contentLength;
+ console.log(`PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` + `${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` + `(PDF.js: ${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.version || "?"} [${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.build || "?"}])`);
+ let pdfTitle = info.Title;
+ const metadataTitle = metadata?.get("dc:title");
+ if (metadataTitle) {
+ if (metadataTitle !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(metadataTitle)) {
+ pdfTitle = metadataTitle;
+ }
+ }
+ if (pdfTitle) {
+ this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || this._title}`);
+ } else if (this._contentDispositionFilename) {
+ this.setTitle(this._contentDispositionFilename);
+ }
+ if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) {
+ if (pdfDocument.loadingParams.enableXfa) {
+ console.warn("Warning: XFA Foreground documents are not supported");
+ } else {
+ console.warn("Warning: XFA support is not enabled");
+ }
+ } else if ((info.IsAcroFormPresent || info.IsXFAPresent) && !this.pdfViewer.renderForms) {
+ console.warn("Warning: Interactive form support is not enabled");
+ }
+ if (info.IsSignaturesPresent) {
+ console.warn("Warning: Digital signatures validation is not supported");
+ }
+ this.eventBus.dispatch("metadataloaded", {
+ source: this
+ });
+ },
+ async _initializePageLabels(pdfDocument) {
+ const labels = await pdfDocument.getPageLabels();
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ if (!labels || _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disablePageLabels")) {
+ return;
+ }
+ const numLabels = labels.length;
+ let standardLabels = 0,
+ emptyLabels = 0;
+ for (let i = 0; i < numLabels; i++) {
+ const label = labels[i];
+ if (label === (i + 1).toString()) {
+ standardLabels++;
+ } else if (label === "") {
+ emptyLabels++;
+ } else {
+ break;
+ }
+ }
+ if (standardLabels >= numLabels || emptyLabels >= numLabels) {
+ return;
+ }
+ const {
+ pdfViewer,
+ pdfThumbnailViewer,
+ toolbar
+ } = this;
+ pdfViewer.setPageLabels(labels);
+ pdfThumbnailViewer?.setPageLabels(labels);
+ toolbar?.setPagesCount(numLabels, true);
+ toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
+ },
+ _initializePdfHistory({
+ fingerprint,
+ viewOnLoad,
+ initialDest = null
+ }) {
+ if (!this.pdfHistory) {
+ return;
+ }
+ this.pdfHistory.initialize({
+ fingerprint,
+ resetHistory: viewOnLoad === ViewOnLoad.INITIAL,
+ updateUrl: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("historyUpdateUrl")
+ });
+ if (this.pdfHistory.initialBookmark) {
+ this.initialBookmark = this.pdfHistory.initialBookmark;
+ this.initialRotation = this.pdfHistory.initialRotation;
+ }
+ if (initialDest && !this.initialBookmark && viewOnLoad === ViewOnLoad.UNKNOWN) {
+ this.initialBookmark = JSON.stringify(initialDest);
+ this.pdfHistory.push({
+ explicitDest: initialDest,
+ pageNumber: null
+ });
+ }
+ },
+ _initializeAnnotationStorageCallbacks(pdfDocument) {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ const {
+ annotationStorage
+ } = pdfDocument;
+ annotationStorage.onSetModified = () => {
+ window.addEventListener("beforeunload", beforeUnload);
+ this._annotationStorageModified = true;
+ };
+ annotationStorage.onResetModified = () => {
+ window.removeEventListener("beforeunload", beforeUnload);
+ delete this._annotationStorageModified;
+ };
+ annotationStorage.onAnnotationEditor = typeStr => {
+ this._hasAnnotationEditors = !!typeStr;
+ this.setTitle();
+ if (typeStr) {
+ this.externalServices.reportTelemetry({
+ type: "editing",
+ data: {
+ type: typeStr
+ }
+ });
+ }
+ };
+ },
+ setInitialView(storedHash, {
+ rotation,
+ sidebarView,
+ scrollMode,
+ spreadMode
+ } = {}) {
+ const setRotation = angle => {
+ if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(angle)) {
+ this.pdfViewer.pagesRotation = angle;
+ }
+ };
+ const setViewerModes = (scroll, spread) => {
+ if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidScrollMode)(scroll)) {
+ this.pdfViewer.scrollMode = scroll;
+ }
+ if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidSpreadMode)(spread)) {
+ this.pdfViewer.spreadMode = spread;
+ }
+ };
+ this.isInitialViewSet = true;
+ this.pdfSidebar?.setInitialView(sidebarView);
+ setViewerModes(scrollMode, spreadMode);
+ if (this.initialBookmark) {
+ setRotation(this.initialRotation);
+ delete this.initialRotation;
+ this.pdfLinkService.setHash(this.initialBookmark);
+ this.initialBookmark = null;
+ } else if (storedHash) {
+ setRotation(rotation);
+ this.pdfLinkService.setHash(storedHash);
+ }
+ this.toolbar?.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel);
+ this.secondaryToolbar?.setPageNumber(this.pdfViewer.currentPageNumber);
+ if (!this.pdfViewer.currentScaleValue) {
+ this.pdfViewer.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE;
+ }
+ },
+ _cleanup() {
+ if (!this.pdfDocument) {
+ return;
+ }
+ this.pdfViewer.cleanup();
+ this.pdfThumbnailViewer?.cleanup();
+ this.pdfDocument.cleanup(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("fontExtraProperties"));
+ },
+ forceRendering() {
+ this.pdfRenderingQueue.printing = !!this.printService;
+ this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS;
+ this.pdfRenderingQueue.renderHighestPriority();
+ },
+ beforePrint() {
+ this._printAnnotationStoragePromise = this.pdfScriptingManager.dispatchWillPrint().catch(() => {}).then(() => {
+ return this.pdfDocument?.annotationStorage.print;
+ });
+ if (this.printService) {
+ return;
+ }
+ if (!this.supportsPrinting) {
+ this.l10n.get("pdfjs-printing-not-supported").then(msg => {
+ this._otherError(msg);
+ });
+ return;
+ }
+ if (!this.pdfViewer.pageViewsReady) {
+ this.l10n.get("pdfjs-printing-not-ready").then(msg => {
+ window.alert(msg);
+ });
+ return;
+ }
+ const pagesOverview = this.pdfViewer.getPagesOverview();
+ const printContainer = this.appConfig.printContainer;
+ const printResolution = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("printResolution");
+ const optionalContentConfigPromise = this.pdfViewer.optionalContentConfigPromise;
+ const printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, this._printAnnotationStoragePromise);
+ this.printService = printService;
+ this.forceRendering();
+ this.setTitle();
+ printService.layout();
+ if (this._hasAnnotationEditors) {
+ this.externalServices.reportTelemetry({
+ type: "editing",
+ data: {
+ type: "print"
+ }
+ });
+ }
+ },
+ afterPrint() {
+ if (this._printAnnotationStoragePromise) {
+ this._printAnnotationStoragePromise.then(() => {
+ this.pdfScriptingManager.dispatchDidPrint();
+ });
+ this._printAnnotationStoragePromise = null;
+ }
+ if (this.printService) {
+ this.printService.destroy();
+ this.printService = null;
+ this.pdfDocument?.annotationStorage.resetModified();
+ }
+ this.forceRendering();
+ this.setTitle();
+ },
+ rotatePages(delta) {
+ this.pdfViewer.pagesRotation += delta;
+ },
+ requestPresentationMode() {
+ this.pdfPresentationMode?.request();
+ },
+ triggerPrinting() {
+ if (!this.supportsPrinting) {
+ return;
+ }
+ window.print();
+ },
+ bindEvents() {
+ const {
+ eventBus,
+ _boundEvents
+ } = this;
+ _boundEvents.beforePrint = this.beforePrint.bind(this);
+ _boundEvents.afterPrint = this.afterPrint.bind(this);
+ eventBus._on("resize", webViewerResize);
+ eventBus._on("hashchange", webViewerHashchange);
+ eventBus._on("beforeprint", _boundEvents.beforePrint);
+ eventBus._on("afterprint", _boundEvents.afterPrint);
+ eventBus._on("pagerender", webViewerPageRender);
+ eventBus._on("pagerendered", webViewerPageRendered);
+ eventBus._on("updateviewarea", webViewerUpdateViewarea);
+ eventBus._on("pagechanging", webViewerPageChanging);
+ eventBus._on("scalechanging", webViewerScaleChanging);
+ eventBus._on("rotationchanging", webViewerRotationChanging);
+ eventBus._on("sidebarviewchanged", webViewerSidebarViewChanged);
+ eventBus._on("pagemode", webViewerPageMode);
+ eventBus._on("namedaction", webViewerNamedAction);
+ eventBus._on("presentationmodechanged", webViewerPresentationModeChanged);
+ eventBus._on("presentationmode", webViewerPresentationMode);
+ eventBus._on("switchannotationeditormode", webViewerSwitchAnnotationEditorMode);
+ eventBus._on("switchannotationeditorparams", webViewerSwitchAnnotationEditorParams);
+ eventBus._on("print", webViewerPrint);
+ eventBus._on("download", webViewerDownload);
+ eventBus._on("openinexternalapp", webViewerOpenInExternalApp);
+ eventBus._on("firstpage", webViewerFirstPage);
+ eventBus._on("lastpage", webViewerLastPage);
+ eventBus._on("nextpage", webViewerNextPage);
+ eventBus._on("previouspage", webViewerPreviousPage);
+ eventBus._on("zoomin", webViewerZoomIn);
+ eventBus._on("zoomout", webViewerZoomOut);
+ eventBus._on("zoomreset", webViewerZoomReset);
+ eventBus._on("pagenumberchanged", webViewerPageNumberChanged);
+ eventBus._on("scalechanged", webViewerScaleChanged);
+ eventBus._on("rotatecw", webViewerRotateCw);
+ eventBus._on("rotateccw", webViewerRotateCcw);
+ eventBus._on("optionalcontentconfig", webViewerOptionalContentConfig);
+ eventBus._on("switchscrollmode", webViewerSwitchScrollMode);
+ eventBus._on("scrollmodechanged", webViewerScrollModeChanged);
+ eventBus._on("switchspreadmode", webViewerSwitchSpreadMode);
+ eventBus._on("spreadmodechanged", webViewerSpreadModeChanged);
+ eventBus._on("documentproperties", webViewerDocumentProperties);
+ eventBus._on("findfromurlhash", webViewerFindFromUrlHash);
+ eventBus._on("updatefindmatchescount", webViewerUpdateFindMatchesCount);
+ eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState);
+ if (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pdfBug")) {
+ _boundEvents.reportPageStatsPDFBug = reportPageStatsPDFBug;
+ eventBus._on("pagerendered", _boundEvents.reportPageStatsPDFBug);
+ eventBus._on("pagechanging", _boundEvents.reportPageStatsPDFBug);
+ }
+ eventBus._on("fileinputchange", webViewerFileInputChange);
+ eventBus._on("openfile", webViewerOpenFile);
+ },
+ bindWindowEvents() {
+ const {
+ eventBus,
+ _boundEvents
+ } = this;
+ function addWindowResolutionChange(evt = null) {
+ if (evt) {
+ webViewerResolutionChange(evt);
+ }
+ const mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`);
+ mediaQueryList.addEventListener("change", addWindowResolutionChange, {
+ once: true
+ });
+ _boundEvents.removeWindowResolutionChange ||= function () {
+ mediaQueryList.removeEventListener("change", addWindowResolutionChange);
+ _boundEvents.removeWindowResolutionChange = null;
+ };
+ }
+ addWindowResolutionChange();
+ _boundEvents.windowResize = () => {
+ eventBus.dispatch("resize", {
+ source: window
+ });
+ };
+ _boundEvents.windowHashChange = () => {
+ eventBus.dispatch("hashchange", {
+ source: window,
+ hash: document.location.hash.substring(1)
+ });
+ };
+ _boundEvents.windowBeforePrint = () => {
+ eventBus.dispatch("beforeprint", {
+ source: window
+ });
+ };
+ _boundEvents.windowAfterPrint = () => {
+ eventBus.dispatch("afterprint", {
+ source: window
+ });
+ };
+ _boundEvents.windowUpdateFromSandbox = event => {
+ eventBus.dispatch("updatefromsandbox", {
+ source: window,
+ detail: event.detail
+ });
+ };
+ window.addEventListener("visibilitychange", webViewerVisibilityChange);
+ window.addEventListener("wheel", webViewerWheel, {
+ passive: false
+ });
+ window.addEventListener("touchstart", webViewerTouchStart, {
+ passive: false
+ });
+ window.addEventListener("touchmove", webViewerTouchMove, {
+ passive: false
+ });
+ window.addEventListener("touchend", webViewerTouchEnd, {
+ passive: false
+ });
+ window.addEventListener("click", webViewerClick);
+ window.addEventListener("keydown", webViewerKeyDown);
+ window.addEventListener("keyup", webViewerKeyUp);
+ window.addEventListener("resize", _boundEvents.windowResize);
+ window.addEventListener("hashchange", _boundEvents.windowHashChange);
+ window.addEventListener("beforeprint", _boundEvents.windowBeforePrint);
+ window.addEventListener("afterprint", _boundEvents.windowAfterPrint);
+ window.addEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox);
+ },
+ unbindEvents() {
+ const {
+ eventBus,
+ _boundEvents
+ } = this;
+ eventBus._off("resize", webViewerResize);
+ eventBus._off("hashchange", webViewerHashchange);
+ eventBus._off("beforeprint", _boundEvents.beforePrint);
+ eventBus._off("afterprint", _boundEvents.afterPrint);
+ eventBus._off("pagerender", webViewerPageRender);
+ eventBus._off("pagerendered", webViewerPageRendered);
+ eventBus._off("updateviewarea", webViewerUpdateViewarea);
+ eventBus._off("pagechanging", webViewerPageChanging);
+ eventBus._off("scalechanging", webViewerScaleChanging);
+ eventBus._off("rotationchanging", webViewerRotationChanging);
+ eventBus._off("sidebarviewchanged", webViewerSidebarViewChanged);
+ eventBus._off("pagemode", webViewerPageMode);
+ eventBus._off("namedaction", webViewerNamedAction);
+ eventBus._off("presentationmodechanged", webViewerPresentationModeChanged);
+ eventBus._off("presentationmode", webViewerPresentationMode);
+ eventBus._off("print", webViewerPrint);
+ eventBus._off("download", webViewerDownload);
+ eventBus._off("openinexternalapp", webViewerOpenInExternalApp);
+ eventBus._off("firstpage", webViewerFirstPage);
+ eventBus._off("lastpage", webViewerLastPage);
+ eventBus._off("nextpage", webViewerNextPage);
+ eventBus._off("previouspage", webViewerPreviousPage);
+ eventBus._off("zoomin", webViewerZoomIn);
+ eventBus._off("zoomout", webViewerZoomOut);
+ eventBus._off("zoomreset", webViewerZoomReset);
+ eventBus._off("pagenumberchanged", webViewerPageNumberChanged);
+ eventBus._off("scalechanged", webViewerScaleChanged);
+ eventBus._off("rotatecw", webViewerRotateCw);
+ eventBus._off("rotateccw", webViewerRotateCcw);
+ eventBus._off("optionalcontentconfig", webViewerOptionalContentConfig);
+ eventBus._off("switchscrollmode", webViewerSwitchScrollMode);
+ eventBus._off("scrollmodechanged", webViewerScrollModeChanged);
+ eventBus._off("switchspreadmode", webViewerSwitchSpreadMode);
+ eventBus._off("spreadmodechanged", webViewerSpreadModeChanged);
+ eventBus._off("documentproperties", webViewerDocumentProperties);
+ eventBus._off("findfromurlhash", webViewerFindFromUrlHash);
+ eventBus._off("updatefindmatchescount", webViewerUpdateFindMatchesCount);
+ eventBus._off("updatefindcontrolstate", webViewerUpdateFindControlState);
+ if (_boundEvents.reportPageStatsPDFBug) {
+ eventBus._off("pagerendered", _boundEvents.reportPageStatsPDFBug);
+ eventBus._off("pagechanging", _boundEvents.reportPageStatsPDFBug);
+ _boundEvents.reportPageStatsPDFBug = null;
+ }
+ eventBus._off("fileinputchange", webViewerFileInputChange);
+ eventBus._off("openfile", webViewerOpenFile);
+ _boundEvents.beforePrint = null;
+ _boundEvents.afterPrint = null;
+ },
+ unbindWindowEvents() {
+ const {
+ _boundEvents
+ } = this;
+ window.removeEventListener("visibilitychange", webViewerVisibilityChange);
+ window.removeEventListener("wheel", webViewerWheel, {
+ passive: false
+ });
+ window.removeEventListener("touchstart", webViewerTouchStart, {
+ passive: false
+ });
+ window.removeEventListener("touchmove", webViewerTouchMove, {
+ passive: false
+ });
+ window.removeEventListener("touchend", webViewerTouchEnd, {
+ passive: false
+ });
+ window.removeEventListener("click", webViewerClick);
+ window.removeEventListener("keydown", webViewerKeyDown);
+ window.removeEventListener("keyup", webViewerKeyUp);
+ window.removeEventListener("resize", _boundEvents.windowResize);
+ window.removeEventListener("hashchange", _boundEvents.windowHashChange);
+ window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint);
+ window.removeEventListener("afterprint", _boundEvents.windowAfterPrint);
+ window.removeEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox);
+ _boundEvents.removeWindowResolutionChange?.();
+ _boundEvents.windowResize = null;
+ _boundEvents.windowHashChange = null;
+ _boundEvents.windowBeforePrint = null;
+ _boundEvents.windowAfterPrint = null;
+ _boundEvents.windowUpdateFromSandbox = null;
+ },
+ _accumulateTicks(ticks, prop) {
+ if (this[prop] > 0 && ticks < 0 || this[prop] < 0 && ticks > 0) {
+ this[prop] = 0;
+ }
+ this[prop] += ticks;
+ const wholeTicks = Math.trunc(this[prop]);
+ this[prop] -= wholeTicks;
+ return wholeTicks;
+ },
+ _accumulateFactor(previousScale, factor, prop) {
+ if (factor === 1) {
+ return 1;
+ }
+ if (this[prop] > 1 && factor < 1 || this[prop] < 1 && factor > 1) {
+ this[prop] = 1;
+ }
+ const newFactor = Math.floor(previousScale * factor * this[prop] * 100) / (100 * previousScale);
+ this[prop] = factor / newFactor;
+ return newFactor;
+ },
+ _centerAtPos(previousScale, x, y) {
+ const {
+ pdfViewer
+ } = this;
+ const scaleDiff = pdfViewer.currentScale / previousScale - 1;
+ if (scaleDiff !== 0) {
+ const [top, left] = pdfViewer.containerTopLeft;
+ pdfViewer.container.scrollLeft += (x - left) * scaleDiff;
+ pdfViewer.container.scrollTop += (y - top) * scaleDiff;
+ }
+ },
+ _unblockDocumentLoadEvent() {
+ document.blockUnblockOnload?.(false);
+ this._unblockDocumentLoadEvent = () => {};
+ },
+ get scriptingReady() {
+ return this.pdfScriptingManager.ready;
+ }
+};
+{
+ const HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io"];
+ var validateFileURL = function (file) {
+ if (!file) {
+ return;
+ }
+ try {
+ const viewerOrigin = new URL(window.location.href).origin || "null";
+ if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) {
+ return;
+ }
+ const fileOrigin = new URL(file, window.location.href).origin;
+ if (fileOrigin !== viewerOrigin) {
+ throw new Error("file origin does not match viewer's");
+ }
+ } catch (ex) {
+ PDFViewerApplication.l10n.get("pdfjs-loading-error").then(msg => {
+ PDFViewerApplication._documentError(msg, {
+ message: ex?.message
+ });
+ });
+ throw ex;
+ }
+ };
+}
+async function loadFakeWorker() {
+ pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.GlobalWorkerOptions.workerSrc ||= _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("workerSrc");
+ await import(/* webpackIgnore: true */ pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PDFWorker.workerSrc);
+}
+async function loadPDFBug(self) {
+ const {
+ debuggerScriptPath
+ } = self.appConfig;
+ const {
+ PDFBug
+ } = await import(/* webpackIgnore: true */ debuggerScriptPath);
+ self._PDFBug = PDFBug;
+}
+function reportPageStatsPDFBug({
+ pageNumber
+}) {
+ if (!globalThis.Stats?.enabled) {
+ return;
+ }
+ const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
+ globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats);
+}
+function webViewerPageRender({
+ pageNumber
+}) {
+ if (pageNumber === PDFViewerApplication.page) {
+ PDFViewerApplication.toolbar?.updateLoadingIndicatorState(true);
+ }
+}
+function webViewerPageRendered({
+ pageNumber,
+ error
+}) {
+ if (pageNumber === PDFViewerApplication.page) {
+ PDFViewerApplication.toolbar?.updateLoadingIndicatorState(false);
+ }
+ if (PDFViewerApplication.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) {
+ const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
+ const thumbnailView = PDFViewerApplication.pdfThumbnailViewer?.getThumbnail(pageNumber - 1);
+ if (pageView) {
+ thumbnailView?.setImage(pageView);
+ }
+ }
+ if (error) {
+ PDFViewerApplication.l10n.get("pdfjs-rendering-error").then(msg => {
+ PDFViewerApplication._otherError(msg, error);
+ });
+ }
+}
+function webViewerPageMode({
+ mode
+}) {
+ let view;
+ switch (mode) {
+ case "thumbs":
+ view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS;
+ break;
+ case "bookmarks":
+ case "outline":
+ view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE;
+ break;
+ case "attachments":
+ view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS;
+ break;
+ case "layers":
+ view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS;
+ break;
+ case "none":
+ view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE;
+ break;
+ default:
+ console.error('Invalid "pagemode" hash parameter: ' + mode);
+ return;
+ }
+ PDFViewerApplication.pdfSidebar?.switchView(view, true);
+}
+function webViewerNamedAction(evt) {
+ switch (evt.action) {
+ case "GoToPage":
+ PDFViewerApplication.appConfig.toolbar?.pageNumber.select();
+ break;
+ case "Find":
+ if (!PDFViewerApplication.supportsIntegratedFind) {
+ PDFViewerApplication?.findBar.toggle();
+ }
+ break;
+ case "Print":
+ PDFViewerApplication.triggerPrinting();
+ break;
+ case "SaveAs":
+ PDFViewerApplication.downloadOrSave();
+ break;
+ }
+}
+function webViewerPresentationModeChanged(evt) {
+ PDFViewerApplication.pdfViewer.presentationModeState = evt.state;
+}
+function webViewerSidebarViewChanged({
+ view
+}) {
+ PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS;
+ if (PDFViewerApplication.isInitialViewSet) {
+ PDFViewerApplication.store?.set("sidebarView", view).catch(() => {});
+ }
+}
+function webViewerUpdateViewarea({
+ location
+}) {
+ if (PDFViewerApplication.isInitialViewSet) {
+ PDFViewerApplication.store?.setMultiple({
+ page: location.pageNumber,
+ zoom: location.scale,
+ scrollLeft: location.left,
+ scrollTop: location.top,
+ rotation: location.rotation
+ }).catch(() => {});
+ }
+ if (PDFViewerApplication.appConfig.secondaryToolbar) {
+ const href = PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams);
+ PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href = href;
+ }
+}
+function webViewerScrollModeChanged(evt) {
+ if (PDFViewerApplication.isInitialViewSet && !PDFViewerApplication.pdfViewer.isInPresentationMode) {
+ PDFViewerApplication.store?.set("scrollMode", evt.mode).catch(() => {});
+ }
+}
+function webViewerSpreadModeChanged(evt) {
+ if (PDFViewerApplication.isInitialViewSet && !PDFViewerApplication.pdfViewer.isInPresentationMode) {
+ PDFViewerApplication.store?.set("spreadMode", evt.mode).catch(() => {});
+ }
+}
+function webViewerResize() {
+ const {
+ pdfDocument,
+ pdfViewer,
+ pdfRenderingQueue
+ } = PDFViewerApplication;
+ if (pdfRenderingQueue.printing && window.matchMedia("print").matches) {
+ return;
+ }
+ if (!pdfDocument) {
+ return;
+ }
+ const currentScaleValue = pdfViewer.currentScaleValue;
+ if (currentScaleValue === "auto" || currentScaleValue === "page-fit" || currentScaleValue === "page-width") {
+ pdfViewer.currentScaleValue = currentScaleValue;
+ }
+ pdfViewer.update();
+}
+function webViewerHashchange(evt) {
+ const hash = evt.hash;
+ if (!hash) {
+ return;
+ }
+ if (!PDFViewerApplication.isInitialViewSet) {
+ PDFViewerApplication.initialBookmark = hash;
+ } else if (!PDFViewerApplication.pdfHistory?.popStateInProgress) {
+ PDFViewerApplication.pdfLinkService.setHash(hash);
+ }
+}
+{
+ var webViewerFileInputChange = function (evt) {
+ if (PDFViewerApplication.pdfViewer?.isInPresentationMode) {
+ return;
+ }
+ const file = evt.fileInput.files[0];
+ PDFViewerApplication.open({
+ url: URL.createObjectURL(file),
+ originalUrl: file.name
+ });
+ };
+ var webViewerOpenFile = function (evt) {
+ const fileInput = PDFViewerApplication.appConfig.openFileInput;
+ fileInput.click();
+ };
+}
+function webViewerPresentationMode() {
+ PDFViewerApplication.requestPresentationMode();
+}
+function webViewerSwitchAnnotationEditorMode(evt) {
+ PDFViewerApplication.pdfViewer.annotationEditorMode = evt;
+}
+function webViewerSwitchAnnotationEditorParams(evt) {
+ PDFViewerApplication.pdfViewer.annotationEditorParams = evt;
+}
+function webViewerPrint() {
+ PDFViewerApplication.triggerPrinting();
+}
+function webViewerDownload() {
+ PDFViewerApplication.downloadOrSave();
+}
+function webViewerOpenInExternalApp() {
+ PDFViewerApplication.openInExternalApp();
+}
+function webViewerFirstPage() {
+ PDFViewerApplication.page = 1;
+}
+function webViewerLastPage() {
+ PDFViewerApplication.page = PDFViewerApplication.pagesCount;
+}
+function webViewerNextPage() {
+ PDFViewerApplication.pdfViewer.nextPage();
+}
+function webViewerPreviousPage() {
+ PDFViewerApplication.pdfViewer.previousPage();
+}
+function webViewerZoomIn() {
+ PDFViewerApplication.zoomIn();
+}
+function webViewerZoomOut() {
+ PDFViewerApplication.zoomOut();
+}
+function webViewerZoomReset() {
+ PDFViewerApplication.zoomReset();
+}
+function webViewerPageNumberChanged(evt) {
+ const pdfViewer = PDFViewerApplication.pdfViewer;
+ if (evt.value !== "") {
+ PDFViewerApplication.pdfLinkService.goToPage(evt.value);
+ }
+ if (evt.value !== pdfViewer.currentPageNumber.toString() && evt.value !== pdfViewer.currentPageLabel) {
+ PDFViewerApplication.toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
+ }
+}
+function webViewerScaleChanged(evt) {
+ PDFViewerApplication.pdfViewer.currentScaleValue = evt.value;
+}
+function webViewerRotateCw() {
+ PDFViewerApplication.rotatePages(90);
+}
+function webViewerRotateCcw() {
+ PDFViewerApplication.rotatePages(-90);
+}
+function webViewerOptionalContentConfig(evt) {
+ PDFViewerApplication.pdfViewer.optionalContentConfigPromise = evt.promise;
+}
+function webViewerSwitchScrollMode(evt) {
+ PDFViewerApplication.pdfViewer.scrollMode = evt.mode;
+}
+function webViewerSwitchSpreadMode(evt) {
+ PDFViewerApplication.pdfViewer.spreadMode = evt.mode;
+}
+function webViewerDocumentProperties() {
+ PDFViewerApplication.pdfDocumentProperties?.open();
+}
+function webViewerFindFromUrlHash(evt) {
+ PDFViewerApplication.eventBus.dispatch("find", {
+ source: evt.source,
+ type: "",
+ query: evt.query,
+ caseSensitive: false,
+ entireWord: false,
+ highlightAll: true,
+ findPrevious: false,
+ matchDiacritics: true
+ });
+}
+function webViewerUpdateFindMatchesCount({
+ matchesCount
+}) {
+ if (PDFViewerApplication.supportsIntegratedFind) {
+ PDFViewerApplication.externalServices.updateFindMatchesCount(matchesCount);
+ } else {
+ PDFViewerApplication.findBar.updateResultsCount(matchesCount);
+ }
+}
+function webViewerUpdateFindControlState({
+ state,
+ previous,
+ matchesCount,
+ rawQuery
+}) {
+ if (PDFViewerApplication.supportsIntegratedFind) {
+ PDFViewerApplication.externalServices.updateFindControlState({
+ result: state,
+ findPrevious: previous,
+ matchesCount,
+ rawQuery
+ });
+ } else {
+ PDFViewerApplication.findBar?.updateUIState(state, previous, matchesCount);
+ }
+}
+function webViewerScaleChanging(evt) {
+ PDFViewerApplication.toolbar?.setPageScale(evt.presetValue, evt.scale);
+ PDFViewerApplication.pdfViewer.update();
+}
+function webViewerRotationChanging(evt) {
+ if (PDFViewerApplication.pdfThumbnailViewer) {
+ PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;
+ }
+ PDFViewerApplication.forceRendering();
+ PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;
+}
+function webViewerPageChanging({
+ pageNumber,
+ pageLabel
+}) {
+ PDFViewerApplication.toolbar?.setPageNumber(pageNumber, pageLabel);
+ PDFViewerApplication.secondaryToolbar?.setPageNumber(pageNumber);
+ if (PDFViewerApplication.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) {
+ PDFViewerApplication.pdfThumbnailViewer?.scrollThumbnailIntoView(pageNumber);
+ }
+ const currentPage = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
+ PDFViewerApplication.toolbar?.updateLoadingIndicatorState(currentPage?.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING);
+}
+function webViewerResolutionChange(evt) {
+ PDFViewerApplication.pdfViewer.refresh();
+}
+function webViewerVisibilityChange(evt) {
+ if (document.visibilityState === "visible") {
+ setZoomDisabledTimeout();
+ }
+}
+let zoomDisabledTimeout = null;
+function setZoomDisabledTimeout() {
+ if (zoomDisabledTimeout) {
+ clearTimeout(zoomDisabledTimeout);
+ }
+ zoomDisabledTimeout = setTimeout(function () {
+ zoomDisabledTimeout = null;
+ }, WHEEL_ZOOM_DISABLED_TIMEOUT);
+}
+function webViewerWheel(evt) {
+ const {
+ pdfViewer,
+ supportsMouseWheelZoomCtrlKey,
+ supportsMouseWheelZoomMetaKey,
+ supportsPinchToZoom
+ } = PDFViewerApplication;
+ if (pdfViewer.isInPresentationMode) {
+ return;
+ }
+ const deltaMode = evt.deltaMode;
+ let scaleFactor = Math.exp(-evt.deltaY / 100);
+ const isBuiltInMac = false;
+ const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0;
+ if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) {
+ evt.preventDefault();
+ if (zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) {
+ return;
+ }
+ const previousScale = pdfViewer.currentScale;
+ if (isPinchToZoom && supportsPinchToZoom) {
+ scaleFactor = PDFViewerApplication._accumulateFactor(previousScale, scaleFactor, "_wheelUnusedFactor");
+ if (scaleFactor < 1) {
+ PDFViewerApplication.zoomOut(null, scaleFactor);
+ } else if (scaleFactor > 1) {
+ PDFViewerApplication.zoomIn(null, scaleFactor);
+ } else {
+ return;
+ }
+ } else {
+ const delta = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.normalizeWheelEventDirection)(evt);
+ let ticks = 0;
+ if (deltaMode === WheelEvent.DOM_DELTA_LINE || deltaMode === WheelEvent.DOM_DELTA_PAGE) {
+ if (Math.abs(delta) >= 1) {
+ ticks = Math.sign(delta);
+ } else {
+ ticks = PDFViewerApplication._accumulateTicks(delta, "_wheelUnusedTicks");
+ }
+ } else {
+ const PIXELS_PER_LINE_SCALE = 30;
+ ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks");
+ }
+ if (ticks < 0) {
+ PDFViewerApplication.zoomOut(-ticks);
+ } else if (ticks > 0) {
+ PDFViewerApplication.zoomIn(ticks);
+ } else {
+ return;
+ }
+ }
+ PDFViewerApplication._centerAtPos(previousScale, evt.clientX, evt.clientY);
+ } else {
+ setZoomDisabledTimeout();
+ }
+}
+function webViewerTouchStart(evt) {
+ if (PDFViewerApplication.pdfViewer.isInPresentationMode || evt.touches.length < 2) {
+ return;
+ }
+ evt.preventDefault();
+ if (evt.touches.length !== 2 || PDFViewerApplication.overlayManager.active) {
+ PDFViewerApplication._touchInfo = null;
+ return;
+ }
+ let [touch0, touch1] = evt.touches;
+ if (touch0.identifier > touch1.identifier) {
+ [touch0, touch1] = [touch1, touch0];
+ }
+ PDFViewerApplication._touchInfo = {
+ touch0X: touch0.pageX,
+ touch0Y: touch0.pageY,
+ touch1X: touch1.pageX,
+ touch1Y: touch1.pageY
+ };
+}
+function webViewerTouchMove(evt) {
+ if (!PDFViewerApplication._touchInfo || evt.touches.length !== 2) {
+ return;
+ }
+ const {
+ pdfViewer,
+ _touchInfo,
+ supportsPinchToZoom
+ } = PDFViewerApplication;
+ let [touch0, touch1] = evt.touches;
+ if (touch0.identifier > touch1.identifier) {
+ [touch0, touch1] = [touch1, touch0];
+ }
+ const {
+ pageX: page0X,
+ pageY: page0Y
+ } = touch0;
+ const {
+ pageX: page1X,
+ pageY: page1Y
+ } = touch1;
+ const {
+ touch0X: pTouch0X,
+ touch0Y: pTouch0Y,
+ touch1X: pTouch1X,
+ touch1Y: pTouch1Y
+ } = _touchInfo;
+ if (Math.abs(pTouch0X - page0X) <= 1 && Math.abs(pTouch0Y - page0Y) <= 1 && Math.abs(pTouch1X - page1X) <= 1 && Math.abs(pTouch1Y - page1Y) <= 1) {
+ return;
+ }
+ _touchInfo.touch0X = page0X;
+ _touchInfo.touch0Y = page0Y;
+ _touchInfo.touch1X = page1X;
+ _touchInfo.touch1Y = page1Y;
+ if (pTouch0X === page0X && pTouch0Y === page0Y) {
+ const v1X = pTouch1X - page0X;
+ const v1Y = pTouch1Y - page0Y;
+ const v2X = page1X - page0X;
+ const v2Y = page1Y - page0Y;
+ const det = v1X * v2Y - v1Y * v2X;
+ if (Math.abs(det) > 0.02 * Math.hypot(v1X, v1Y) * Math.hypot(v2X, v2Y)) {
+ return;
+ }
+ } else if (pTouch1X === page1X && pTouch1Y === page1Y) {
+ const v1X = pTouch0X - page1X;
+ const v1Y = pTouch0Y - page1Y;
+ const v2X = page0X - page1X;
+ const v2Y = page0Y - page1Y;
+ const det = v1X * v2Y - v1Y * v2X;
+ if (Math.abs(det) > 0.02 * Math.hypot(v1X, v1Y) * Math.hypot(v2X, v2Y)) {
+ return;
+ }
+ } else {
+ const diff0X = page0X - pTouch0X;
+ const diff1X = page1X - pTouch1X;
+ const diff0Y = page0Y - pTouch0Y;
+ const diff1Y = page1Y - pTouch1Y;
+ const dotProduct = diff0X * diff1X + diff0Y * diff1Y;
+ if (dotProduct >= 0) {
+ return;
+ }
+ }
+ evt.preventDefault();
+ const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1;
+ const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1;
+ const previousScale = pdfViewer.currentScale;
+ if (supportsPinchToZoom) {
+ const newScaleFactor = PDFViewerApplication._accumulateFactor(previousScale, distance / pDistance, "_touchUnusedFactor");
+ if (newScaleFactor < 1) {
+ PDFViewerApplication.zoomOut(null, newScaleFactor);
+ } else if (newScaleFactor > 1) {
+ PDFViewerApplication.zoomIn(null, newScaleFactor);
+ } else {
+ return;
+ }
+ } else {
+ const PIXELS_PER_LINE_SCALE = 30;
+ const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks");
+ if (ticks < 0) {
+ PDFViewerApplication.zoomOut(-ticks);
+ } else if (ticks > 0) {
+ PDFViewerApplication.zoomIn(ticks);
+ } else {
+ return;
+ }
+ }
+ PDFViewerApplication._centerAtPos(previousScale, (page0X + page1X) / 2, (page0Y + page1Y) / 2);
+}
+function webViewerTouchEnd(evt) {
+ if (!PDFViewerApplication._touchInfo) {
+ return;
+ }
+ evt.preventDefault();
+ PDFViewerApplication._touchInfo = null;
+ PDFViewerApplication._touchUnusedTicks = 0;
+ PDFViewerApplication._touchUnusedFactor = 1;
+}
+function webViewerClick(evt) {
+ if (!PDFViewerApplication.secondaryToolbar?.isOpen) {
+ return;
+ }
+ const appConfig = PDFViewerApplication.appConfig;
+ if (PDFViewerApplication.pdfViewer.containsElement(evt.target) || appConfig.toolbar?.container.contains(evt.target) && evt.target !== appConfig.secondaryToolbar?.toggleButton) {
+ PDFViewerApplication.secondaryToolbar.close();
+ }
+}
+function webViewerKeyUp(evt) {
+ if (evt.key === "Control") {
+ PDFViewerApplication._isCtrlKeyDown = false;
+ }
+}
+function webViewerKeyDown(evt) {
+ PDFViewerApplication._isCtrlKeyDown = evt.key === "Control";
+ if (PDFViewerApplication.overlayManager.active) {
+ return;
+ }
+ const {
+ eventBus,
+ pdfViewer
+ } = PDFViewerApplication;
+ const isViewerInPresentationMode = pdfViewer.isInPresentationMode;
+ let handled = false,
+ ensureViewerFocused = false;
+ const cmd = (evt.ctrlKey ? 1 : 0) | (evt.altKey ? 2 : 0) | (evt.shiftKey ? 4 : 0) | (evt.metaKey ? 8 : 0);
+ if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
+ switch (evt.keyCode) {
+ case 70:
+ if (!PDFViewerApplication.supportsIntegratedFind && !evt.shiftKey) {
+ PDFViewerApplication.findBar?.open();
+ handled = true;
+ }
+ break;
+ case 71:
+ if (!PDFViewerApplication.supportsIntegratedFind) {
+ const {
+ state
+ } = PDFViewerApplication.findController;
+ if (state) {
+ const newState = {
+ source: window,
+ type: "again",
+ findPrevious: cmd === 5 || cmd === 12
+ };
+ eventBus.dispatch("find", {
+ ...state,
+ ...newState
+ });
+ }
+ handled = true;
+ }
+ break;
+ case 61:
+ case 107:
+ case 187:
+ case 171:
+ PDFViewerApplication.zoomIn();
+ handled = true;
+ break;
+ case 173:
+ case 109:
+ case 189:
+ PDFViewerApplication.zoomOut();
+ handled = true;
+ break;
+ case 48:
+ case 96:
+ if (!isViewerInPresentationMode) {
+ setTimeout(function () {
+ PDFViewerApplication.zoomReset();
+ });
+ handled = false;
+ }
+ break;
+ case 38:
+ if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
+ PDFViewerApplication.page = 1;
+ handled = true;
+ ensureViewerFocused = true;
+ }
+ break;
+ case 40:
+ if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
+ PDFViewerApplication.page = PDFViewerApplication.pagesCount;
+ handled = true;
+ ensureViewerFocused = true;
+ }
+ break;
+ }
+ }
+ if (cmd === 1 || cmd === 8) {
+ switch (evt.keyCode) {
+ case 83:
+ eventBus.dispatch("download", {
+ source: window
+ });
+ handled = true;
+ break;
+ case 79:
+ {
+ eventBus.dispatch("openfile", {
+ source: window
+ });
+ handled = true;
+ }
+ break;
+ }
+ }
+ if (cmd === 3 || cmd === 10) {
+ switch (evt.keyCode) {
+ case 80:
+ PDFViewerApplication.requestPresentationMode();
+ handled = true;
+ PDFViewerApplication.externalServices.reportTelemetry({
+ type: "buttons",
+ data: {
+ id: "presentationModeKeyboard"
+ }
+ });
+ break;
+ case 71:
+ if (PDFViewerApplication.appConfig.toolbar) {
+ PDFViewerApplication.appConfig.toolbar.pageNumber.select();
+ handled = true;
+ }
+ break;
+ }
+ }
+ if (handled) {
+ if (ensureViewerFocused && !isViewerInPresentationMode) {
+ pdfViewer.focus();
+ }
+ evt.preventDefault();
+ return;
+ }
+ const curElement = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getActiveOrFocusedElement)();
+ const curElementTagName = curElement?.tagName.toUpperCase();
+ if (curElementTagName === "INPUT" || curElementTagName === "TEXTAREA" || curElementTagName === "SELECT" || curElementTagName === "BUTTON" && (evt.keyCode === 13 || evt.keyCode === 32) || curElement?.isContentEditable) {
+ if (evt.keyCode !== 27) {
+ return;
+ }
+ }
+ if (cmd === 0) {
+ let turnPage = 0,
+ turnOnlyIfPageFit = false;
+ switch (evt.keyCode) {
+ case 38:
+ case 33:
+ if (pdfViewer.isVerticalScrollbarEnabled) {
+ turnOnlyIfPageFit = true;
+ }
+ turnPage = -1;
+ break;
+ case 8:
+ if (!isViewerInPresentationMode) {
+ turnOnlyIfPageFit = true;
+ }
+ turnPage = -1;
+ break;
+ case 37:
+ if (pdfViewer.isHorizontalScrollbarEnabled) {
+ turnOnlyIfPageFit = true;
+ }
+ case 75:
+ case 80:
+ turnPage = -1;
+ break;
+ case 27:
+ if (PDFViewerApplication.secondaryToolbar?.isOpen) {
+ PDFViewerApplication.secondaryToolbar.close();
+ handled = true;
+ }
+ if (!PDFViewerApplication.supportsIntegratedFind && PDFViewerApplication.findBar?.opened) {
+ PDFViewerApplication.findBar.close();
+ handled = true;
+ }
+ break;
+ case 40:
+ case 34:
+ if (pdfViewer.isVerticalScrollbarEnabled) {
+ turnOnlyIfPageFit = true;
+ }
+ turnPage = 1;
+ break;
+ case 13:
+ case 32:
+ if (!isViewerInPresentationMode) {
+ turnOnlyIfPageFit = true;
+ }
+ turnPage = 1;
+ break;
+ case 39:
+ if (pdfViewer.isHorizontalScrollbarEnabled) {
+ turnOnlyIfPageFit = true;
+ }
+ case 74:
+ case 78:
+ turnPage = 1;
+ break;
+ case 36:
+ if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
+ PDFViewerApplication.page = 1;
+ handled = true;
+ ensureViewerFocused = true;
+ }
+ break;
+ case 35:
+ if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
+ PDFViewerApplication.page = PDFViewerApplication.pagesCount;
+ handled = true;
+ ensureViewerFocused = true;
+ }
+ break;
+ case 83:
+ PDFViewerApplication.pdfCursorTools?.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT);
+ break;
+ case 72:
+ PDFViewerApplication.pdfCursorTools?.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND);
+ break;
+ case 82:
+ PDFViewerApplication.rotatePages(90);
+ break;
+ case 115:
+ PDFViewerApplication.pdfSidebar?.toggle();
+ break;
+ }
+ if (turnPage !== 0 && (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === "page-fit")) {
+ if (turnPage > 0) {
+ pdfViewer.nextPage();
+ } else {
+ pdfViewer.previousPage();
+ }
+ handled = true;
+ }
+ }
+ if (cmd === 4) {
+ switch (evt.keyCode) {
+ case 13:
+ case 32:
+ if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== "page-fit") {
+ break;
+ }
+ pdfViewer.previousPage();
+ handled = true;
+ break;
+ case 82:
+ PDFViewerApplication.rotatePages(-90);
+ break;
+ }
+ }
+ if (!handled && !isViewerInPresentationMode) {
+ if (evt.keyCode >= 33 && evt.keyCode <= 40 || evt.keyCode === 32 && curElementTagName !== "BUTTON") {
+ ensureViewerFocused = true;
+ }
+ }
+ if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) {
+ pdfViewer.focus();
+ }
+ if (handled) {
+ evt.preventDefault();
+ }
+}
+function beforeUnload(evt) {
+ evt.preventDefault();
+ evt.returnValue = "";
+ return false;
+}
+function webViewerAnnotationEditorStatesChanged(data) {
+ PDFViewerApplication.externalServices.updateEditorStates(data);
+}
+function webViewerReportTelemetry({
+ details
+}) {
+ PDFViewerApplication.externalServices.reportTelemetry(details);
+}
+const PDFPrintServiceFactory = {
+ instance: {
+ supportsPrinting: false,
+ createPrintService() {
+ throw new Error("Not implemented: createPrintService");
+ }
+ }
+};
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 8961:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AppOptions: () => (/* binding */ AppOptions),
+/* harmony export */ OptionKind: () => (/* binding */ OptionKind),
+/* harmony export */ compatibilityParams: () => (/* binding */ compatibilityParams)
+/* harmony export */ });
+const compatibilityParams = Object.create(null);
+{
+ const userAgent = navigator.userAgent || "";
+ const platform = navigator.platform || "";
+ const maxTouchPoints = navigator.maxTouchPoints || 1;
+ const isAndroid = /Android/.test(userAgent);
+ const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1;
+ (function checkCanvasSizeLimitation() {
+ if (isIOS || isAndroid) {
+ compatibilityParams.maxCanvasPixels = 5242880;
+ }
+ })();
+}
+const OptionKind = {
+ BROWSER: 0x01,
+ VIEWER: 0x02,
+ API: 0x04,
+ WORKER: 0x08,
+ PREFERENCE: 0x80
+};
+const defaultOptions = {
+ canvasMaxAreaInBytes: {
+ value: -1,
+ kind: OptionKind.BROWSER + OptionKind.API
+ },
+ isInAutomation: {
+ value: false,
+ kind: OptionKind.BROWSER
+ },
+ supportsDocumentFonts: {
+ value: true,
+ kind: OptionKind.BROWSER
+ },
+ supportsIntegratedFind: {
+ value: false,
+ kind: OptionKind.BROWSER
+ },
+ supportsMouseWheelZoomCtrlKey: {
+ value: true,
+ kind: OptionKind.BROWSER
+ },
+ supportsMouseWheelZoomMetaKey: {
+ value: true,
+ kind: OptionKind.BROWSER
+ },
+ supportsPinchToZoom: {
+ value: true,
+ kind: OptionKind.BROWSER
+ },
+ annotationEditorMode: {
+ value: 0,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ annotationMode: {
+ value: 2,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ cursorToolOnLoad: {
+ value: 0,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ defaultZoomDelay: {
+ value: 400,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ defaultZoomValue: {
+ value: "",
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ disableHistory: {
+ value: false,
+ kind: OptionKind.VIEWER
+ },
+ disablePageLabels: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ enableHighlightEditor: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ enablePermissions: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ enablePrintAutoRotate: {
+ value: true,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ enableScripting: {
+ value: true,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ externalLinkRel: {
+ value: "noopener noreferrer nofollow",
+ kind: OptionKind.VIEWER
+ },
+ externalLinkTarget: {
+ value: 0,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ highlightEditorColors: {
+ value: "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F",
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ historyUpdateUrl: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ ignoreDestinationZoom: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ imageResourcesPath: {
+ value: "./images/",
+ kind: OptionKind.VIEWER
+ },
+ maxCanvasPixels: {
+ value: 16777216,
+ kind: OptionKind.VIEWER
+ },
+ forcePageColors: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ pageColorsBackground: {
+ value: "Canvas",
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ pageColorsForeground: {
+ value: "CanvasText",
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ pdfBugEnabled: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ printResolution: {
+ value: 150,
+ kind: OptionKind.VIEWER
+ },
+ sidebarViewOnLoad: {
+ value: -1,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ scrollModeOnLoad: {
+ value: -1,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ spreadModeOnLoad: {
+ value: -1,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ textLayerMode: {
+ value: 1,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ viewOnLoad: {
+ value: 0,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
+ cMapPacked: {
+ value: true,
+ kind: OptionKind.API
+ },
+ cMapUrl: {
+ value: "../web/cmaps/",
+ kind: OptionKind.API
+ },
+ disableAutoFetch: {
+ value: false,
+ kind: OptionKind.API + OptionKind.PREFERENCE
+ },
+ disableFontFace: {
+ value: false,
+ kind: OptionKind.API + OptionKind.PREFERENCE
+ },
+ disableRange: {
+ value: false,
+ kind: OptionKind.API + OptionKind.PREFERENCE
+ },
+ disableStream: {
+ value: false,
+ kind: OptionKind.API + OptionKind.PREFERENCE
+ },
+ docBaseUrl: {
+ value: "",
+ kind: OptionKind.API
+ },
+ enableXfa: {
+ value: true,
+ kind: OptionKind.API + OptionKind.PREFERENCE
+ },
+ fontExtraProperties: {
+ value: false,
+ kind: OptionKind.API
+ },
+ isEvalSupported: {
+ value: true,
+ kind: OptionKind.API
+ },
+ isOffscreenCanvasSupported: {
+ value: true,
+ kind: OptionKind.API
+ },
+ maxImageSize: {
+ value: -1,
+ kind: OptionKind.API
+ },
+ pdfBug: {
+ value: false,
+ kind: OptionKind.API
+ },
+ standardFontDataUrl: {
+ value: "../web/standard_fonts/",
+ kind: OptionKind.API
+ },
+ verbosity: {
+ value: 1,
+ kind: OptionKind.API
+ },
+ workerPort: {
+ value: null,
+ kind: OptionKind.WORKER
+ },
+ workerSrc: {
+ value: "../build/pdf.worker.mjs",
+ kind: OptionKind.WORKER
+ }
+};
+{
+ defaultOptions.defaultUrl = {
+ value: "compressed.tracemonkey-pldi-09.pdf",
+ kind: OptionKind.VIEWER
+ };
+ defaultOptions.sandboxBundleSrc = {
+ value: "../build/pdf.sandbox.mjs",
+ kind: OptionKind.VIEWER
+ };
+ defaultOptions.viewerCssTheme = {
+ value: 0,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ };
+}
+{
+ defaultOptions.disablePreferences = {
+ value: false,
+ kind: OptionKind.VIEWER
+ };
+ defaultOptions.locale = {
+ value: navigator.language || "en-US",
+ kind: OptionKind.VIEWER
+ };
+}
+const userOptions = Object.create(null);
+class AppOptions {
+ constructor() {
+ throw new Error("Cannot initialize AppOptions.");
+ }
+ static get(name) {
+ const userOption = userOptions[name];
+ if (userOption !== undefined) {
+ return userOption;
+ }
+ const defaultOption = defaultOptions[name];
+ if (defaultOption !== undefined) {
+ return compatibilityParams[name] ?? defaultOption.value;
+ }
+ return undefined;
+ }
+ static getAll(kind = null) {
+ const options = Object.create(null);
+ for (const name in defaultOptions) {
+ const defaultOption = defaultOptions[name];
+ if (kind) {
+ if (!(kind & defaultOption.kind)) {
+ continue;
+ }
+ }
+ const userOption = userOptions[name];
+ options[name] = userOption !== undefined ? userOption : compatibilityParams[name] ?? defaultOption.value;
+ }
+ return options;
+ }
+ static set(name, value) {
+ userOptions[name] = value;
+ }
+ static setAll(options, init = false) {
+ if (init) {
+ if (this.get("disablePreferences")) {
+ return;
+ }
+ if (Object.keys(userOptions).length) {
+ console.warn("setAll: The Preferences may override manually set AppOptions; " + 'please use the "disablePreferences"-option in order to prevent that.');
+ }
+ }
+ for (const name in options) {
+ userOptions[name] = options[name];
+ }
+ }
+ static remove(name) {
+ delete userOptions[name];
+ }
+}
+
+
+/***/ }),
+
+/***/ 9415:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ BaseTreeViewer: () => (/* binding */ BaseTreeViewer)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+
+const TREEITEM_OFFSET_TOP = -100;
+const TREEITEM_SELECTED_CLASS = "selected";
+class BaseTreeViewer {
+ constructor(options) {
+ if (this.constructor === BaseTreeViewer) {
+ throw new Error("Cannot initialize BaseTreeViewer.");
+ }
+ this.container = options.container;
+ this.eventBus = options.eventBus;
+ this._l10n = options.l10n;
+ this.reset();
+ }
+ reset() {
+ this._pdfDocument = null;
+ this._lastToggleIsShow = true;
+ this._currentTreeItem = null;
+ this.container.textContent = "";
+ this.container.classList.remove("treeWithDeepNesting");
+ }
+ _dispatchEvent(count) {
+ throw new Error("Not implemented: _dispatchEvent");
+ }
+ _bindLink(element, params) {
+ throw new Error("Not implemented: _bindLink");
+ }
+ _normalizeTextContent(str) {
+ return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(str, true) || "\u2013";
+ }
+ _addToggleButton(div, hidden = false) {
+ const toggler = document.createElement("div");
+ toggler.className = "treeItemToggler";
+ if (hidden) {
+ toggler.classList.add("treeItemsHidden");
+ }
+ toggler.onclick = evt => {
+ evt.stopPropagation();
+ toggler.classList.toggle("treeItemsHidden");
+ if (evt.shiftKey) {
+ const shouldShowAll = !toggler.classList.contains("treeItemsHidden");
+ this._toggleTreeItem(div, shouldShowAll);
+ }
+ };
+ div.prepend(toggler);
+ }
+ _toggleTreeItem(root, show = false) {
+ this._l10n.pause();
+ this._lastToggleIsShow = show;
+ for (const toggler of root.querySelectorAll(".treeItemToggler")) {
+ toggler.classList.toggle("treeItemsHidden", !show);
+ }
+ this._l10n.resume();
+ }
+ _toggleAllTreeItems() {
+ this._toggleTreeItem(this.container, !this._lastToggleIsShow);
+ }
+ _finishRendering(fragment, count, hasAnyNesting = false) {
+ if (hasAnyNesting) {
+ this.container.classList.add("treeWithDeepNesting");
+ this._lastToggleIsShow = !fragment.querySelector(".treeItemsHidden");
+ }
+ this._l10n.pause();
+ this.container.append(fragment);
+ this._l10n.resume();
+ this._dispatchEvent(count);
+ }
+ render(params) {
+ throw new Error("Not implemented: render");
+ }
+ _updateCurrentTreeItem(treeItem = null) {
+ if (this._currentTreeItem) {
+ this._currentTreeItem.classList.remove(TREEITEM_SELECTED_CLASS);
+ this._currentTreeItem = null;
+ }
+ if (treeItem) {
+ treeItem.classList.add(TREEITEM_SELECTED_CLASS);
+ this._currentTreeItem = treeItem;
+ }
+ }
+ _scrollToCurrentTreeItem(treeItem) {
+ if (!treeItem) {
+ return;
+ }
+ this._l10n.pause();
+ let currentNode = treeItem.parentNode;
+ while (currentNode && currentNode !== this.container) {
+ if (currentNode.classList.contains("treeItem")) {
+ const toggler = currentNode.firstElementChild;
+ toggler?.classList.remove("treeItemsHidden");
+ }
+ currentNode = currentNode.parentNode;
+ }
+ this._l10n.resume();
+ this._updateCurrentTreeItem(treeItem);
+ this.container.scrollTo(treeItem.offsetLeft, treeItem.offsetTop + TREEITEM_OFFSET_TOP);
+ }
+}
+
+
+/***/ }),
+
+/***/ 4397:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ DownloadManager: () => (/* binding */ DownloadManager)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+;
+function download(blobUrl, filename) {
+ const a = document.createElement("a");
+ if (!a.click) {
+ throw new Error('DownloadManager: "a.click()" is not supported.');
+ }
+ a.href = blobUrl;
+ a.target = "_parent";
+ if ("download" in a) {
+ a.download = filename;
+ }
+ (document.body || document.documentElement).append(a);
+ a.click();
+ a.remove();
+}
+class DownloadManager {
+ #openBlobUrls = new WeakMap();
+ downloadUrl(url, filename, _options) {
+ if (!(0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.createValidAbsoluteUrl)(url, "http://example.com")) {
+ console.error(`downloadUrl - not a valid URL: ${url}`);
+ return;
+ }
+ download(url + "#pdfjs.action=download", filename);
+ }
+ downloadData(data, filename, contentType) {
+ const blobUrl = URL.createObjectURL(new Blob([data], {
+ type: contentType
+ }));
+ download(blobUrl, filename);
+ }
+ openOrDownloadData(data, filename, dest = null) {
+ const isPdfData = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.isPdfFile)(filename);
+ const contentType = isPdfData ? "application/pdf" : "";
+ if (isPdfData) {
+ let blobUrl = this.#openBlobUrls.get(data);
+ if (!blobUrl) {
+ blobUrl = URL.createObjectURL(new Blob([data], {
+ type: contentType
+ }));
+ this.#openBlobUrls.set(data, blobUrl);
+ }
+ let viewerUrl;
+ viewerUrl = "?file=" + encodeURIComponent(blobUrl + "#" + filename);
+ if (dest) {
+ viewerUrl += `#${escape(dest)}`;
+ }
+ try {
+ window.open(viewerUrl);
+ return true;
+ } catch (ex) {
+ console.error(`openOrDownloadData: ${ex}`);
+ URL.revokeObjectURL(blobUrl);
+ this.#openBlobUrls.delete(data);
+ }
+ }
+ this.downloadData(data, filename, contentType);
+ return false;
+ }
+ download(blob, url, filename, _options) {
+ const blobUrl = URL.createObjectURL(blob);
+ download(blobUrl, filename);
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 758:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ DrawLayerBuilder: () => (/* binding */ DrawLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+class DrawLayerBuilder {
+ #drawLayer = null;
+ constructor(options) {
+ this.pageIndex = options.pageIndex;
+ }
+ async render(intent = "display") {
+ if (intent !== "display" || this.#drawLayer || this._cancelled) {
+ return;
+ }
+ this.#drawLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.DrawLayer({
+ pageIndex: this.pageIndex
+ });
+ }
+ cancel() {
+ this._cancelled = true;
+ if (!this.#drawLayer) {
+ return;
+ }
+ this.#drawLayer.destroy();
+ this.#drawLayer = null;
+ }
+ setParent(parent) {
+ this.#drawLayer?.setParent(parent);
+ }
+ getDrawLayer() {
+ return this.#drawLayer;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6554:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AutomationEventBus: () => (/* binding */ AutomationEventBus),
+/* harmony export */ EventBus: () => (/* binding */ EventBus),
+/* harmony export */ waitOnEventOrTimeout: () => (/* binding */ waitOnEventOrTimeout)
+/* harmony export */ });
+/* unused harmony export WaitOnType */
+const WaitOnType = {
+ EVENT: "event",
+ TIMEOUT: "timeout"
+};
+function waitOnEventOrTimeout({
+ target,
+ name,
+ delay = 0
+}) {
+ return new Promise(function (resolve, reject) {
+ if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) {
+ throw new Error("waitOnEventOrTimeout - invalid parameters.");
+ }
+ function handler(type) {
+ if (target instanceof EventBus) {
+ target._off(name, eventHandler);
+ } else {
+ target.removeEventListener(name, eventHandler);
+ }
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ resolve(type);
+ }
+ const eventHandler = handler.bind(null, WaitOnType.EVENT);
+ if (target instanceof EventBus) {
+ target._on(name, eventHandler);
+ } else {
+ target.addEventListener(name, eventHandler);
+ }
+ const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);
+ const timeout = setTimeout(timeoutHandler, delay);
+ });
+}
+class EventBus {
+ #listeners = Object.create(null);
+ on(eventName, listener, options = null) {
+ this._on(eventName, listener, {
+ external: true,
+ once: options?.once
+ });
+ }
+ off(eventName, listener, options = null) {
+ this._off(eventName, listener, {
+ external: true,
+ once: options?.once
+ });
+ }
+ dispatch(eventName, data) {
+ const eventListeners = this.#listeners[eventName];
+ if (!eventListeners || eventListeners.length === 0) {
+ return;
+ }
+ let externalListeners;
+ for (const {
+ listener,
+ external,
+ once
+ } of eventListeners.slice(0)) {
+ if (once) {
+ this._off(eventName, listener);
+ }
+ if (external) {
+ (externalListeners ||= []).push(listener);
+ continue;
+ }
+ listener(data);
+ }
+ if (externalListeners) {
+ for (const listener of externalListeners) {
+ listener(data);
+ }
+ externalListeners = null;
+ }
+ }
+ _on(eventName, listener, options = null) {
+ const eventListeners = this.#listeners[eventName] ||= [];
+ eventListeners.push({
+ listener,
+ external: options?.external === true,
+ once: options?.once === true
+ });
+ }
+ _off(eventName, listener, options = null) {
+ const eventListeners = this.#listeners[eventName];
+ if (!eventListeners) {
+ return;
+ }
+ for (let i = 0, ii = eventListeners.length; i < ii; i++) {
+ if (eventListeners[i].listener === listener) {
+ eventListeners.splice(i, 1);
+ return;
+ }
+ }
+ }
+}
+class AutomationEventBus extends EventBus {
+ dispatch(eventName, data) {
+ throw new Error("Not implemented: AutomationEventBus.dispatch");
+ }
+}
+
+
+/***/ }),
+
+/***/ 9170:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ GenericScripting: () => (/* binding */ GenericScripting)
+/* harmony export */ });
+/* unused harmony export docProperties */
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+async function docProperties(pdfDocument) {
+ const url = "",
+ baseUrl = url.split("#")[0];
+ let {
+ info,
+ metadata,
+ contentDispositionFilename,
+ contentLength
+ } = await pdfDocument.getMetadata();
+ if (!contentLength) {
+ const {
+ length
+ } = await pdfDocument.getDownloadInfo();
+ contentLength = length;
+ }
+ return {
+ ...info,
+ baseURL: baseUrl,
+ filesize: contentLength,
+ filename: contentDispositionFilename || getPdfFilenameFromUrl(url),
+ metadata: metadata?.getRaw(),
+ authors: metadata?.get("dc:creator"),
+ numPages: pdfDocument.numPages,
+ URL: url
+ };
+}
+class GenericScripting {
+ constructor(sandboxBundleSrc) {
+ this._ready = new Promise((resolve, reject) => {
+ const sandbox = import(/* webpackIgnore: true */ sandboxBundleSrc);
+ sandbox.then(pdfjsSandbox => {
+ resolve(pdfjsSandbox.QuickJSSandbox());
+ }).catch(reject);
+ });
+ }
+ async createSandbox(data) {
+ const sandbox = await this._ready;
+ sandbox.create(data);
+ }
+ async dispatchEventInSandbox(event) {
+ const sandbox = await this._ready;
+ setTimeout(() => sandbox.dispatchEvent(event), 0);
+ }
+ async destroySandbox() {
+ const sandbox = await this._ready;
+ sandbox.nukeSandbox();
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1546:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* unused harmony export GenericCom */
+/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(39);
+/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8961);
+/* harmony import */ var _preferences_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(216);
+/* harmony import */ var _download_manager_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4397);
+/* harmony import */ var _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(450);
+/* harmony import */ var _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9170);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_app_js__WEBPACK_IMPORTED_MODULE_0__, _download_manager_js__WEBPACK_IMPORTED_MODULE_3__, _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__, _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__]);
+([_app_js__WEBPACK_IMPORTED_MODULE_0__, _download_manager_js__WEBPACK_IMPORTED_MODULE_3__, _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__, _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+
+
+
+;
+const GenericCom = {};
+class GenericPreferences extends _preferences_js__WEBPACK_IMPORTED_MODULE_2__.BasePreferences {
+ async _writeToStorage(prefObj) {
+ localStorage.setItem("pdfjs.preferences", JSON.stringify(prefObj));
+ }
+ async _readFromStorage(prefObj) {
+ return {
+ prefs: JSON.parse(localStorage.getItem("pdfjs.preferences"))
+ };
+ }
+}
+class GenericExternalServices extends _app_js__WEBPACK_IMPORTED_MODULE_0__.DefaultExternalServices {
+ static createDownloadManager() {
+ return new _download_manager_js__WEBPACK_IMPORTED_MODULE_3__.DownloadManager();
+ }
+ static createPreferences() {
+ return new GenericPreferences();
+ }
+ static async createL10n() {
+ return new _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__.GenericL10n(_app_options_js__WEBPACK_IMPORTED_MODULE_1__.AppOptions.get("locale"));
+ }
+ static createScripting() {
+ return new _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__.GenericScripting(_app_options_js__WEBPACK_IMPORTED_MODULE_1__.AppOptions.get("sandboxBundleSrc"));
+ }
+}
+_app_js__WEBPACK_IMPORTED_MODULE_0__.PDFViewerApplication.externalServices = GenericExternalServices;
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 450:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ GenericL10n: () => (/* binding */ GenericL10n)
+/* harmony export */ });
+/* harmony import */ var fluent_bundle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8759);
+/* harmony import */ var fluent_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8275);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1869);
+/* harmony import */ var _l10n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4065);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+
+class GenericL10n extends _l10n_js__WEBPACK_IMPORTED_MODULE_3__.L10n {
+ constructor(lang) {
+ super({
+ lang
+ });
+ this._setL10n(new fluent_dom__WEBPACK_IMPORTED_MODULE_1__.DOMLocalization([], GenericL10n.#generateBundles.bind(GenericL10n, "en-us", this.getLanguage())));
+ }
+ static async *#generateBundles(defaultLang, baseLang) {
+ const {
+ baseURL,
+ paths
+ } = await this.#getPaths();
+ const langs = [baseLang];
+ if (defaultLang !== baseLang) {
+ const shortLang = baseLang.split("-", 1)[0];
+ if (shortLang !== baseLang) {
+ langs.push(shortLang);
+ }
+ langs.push(defaultLang);
+ }
+ for (const lang of langs) {
+ const bundle = await this.#createBundle(lang, baseURL, paths);
+ if (bundle) {
+ yield bundle;
+ }
+ }
+ }
+ static async #createBundle(lang, baseURL, paths) {
+ const path = paths[lang];
+ if (!path) {
+ return null;
+ }
+ const url = new URL(path, baseURL);
+ const text = await (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.fetchData)(url, "text");
+ const resource = new fluent_bundle__WEBPACK_IMPORTED_MODULE_0__.FluentResource(text);
+ const bundle = new fluent_bundle__WEBPACK_IMPORTED_MODULE_0__.FluentBundle(lang);
+ const errors = bundle.addResource(resource);
+ if (errors.length) {
+ console.error("L10n errors", errors);
+ }
+ return bundle;
+ }
+ static async #getPaths() {
+ const {
+ href
+ } = document.querySelector(`link[type="application/l10n"]`);
+ const paths = await (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.fetchData)(href, "json");
+ return {
+ baseURL: href.replace(/[^/]*$/, "") || "./",
+ paths
+ };
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6143:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ GrabToPan: () => (/* binding */ GrabToPan)
+/* harmony export */ });
+const CSS_CLASS_GRAB = "grab-to-pan-grab";
+class GrabToPan {
+ constructor({
+ element
+ }) {
+ this.element = element;
+ this.document = element.ownerDocument;
+ this.activate = this.activate.bind(this);
+ this.deactivate = this.deactivate.bind(this);
+ this.toggle = this.toggle.bind(this);
+ this._onMouseDown = this.#onMouseDown.bind(this);
+ this._onMouseMove = this.#onMouseMove.bind(this);
+ this._endPan = this.#endPan.bind(this);
+ const overlay = this.overlay = document.createElement("div");
+ overlay.className = "grab-to-pan-grabbing";
+ }
+ activate() {
+ if (!this.active) {
+ this.active = true;
+ this.element.addEventListener("mousedown", this._onMouseDown, true);
+ this.element.classList.add(CSS_CLASS_GRAB);
+ }
+ }
+ deactivate() {
+ if (this.active) {
+ this.active = false;
+ this.element.removeEventListener("mousedown", this._onMouseDown, true);
+ this._endPan();
+ this.element.classList.remove(CSS_CLASS_GRAB);
+ }
+ }
+ toggle() {
+ if (this.active) {
+ this.deactivate();
+ } else {
+ this.activate();
+ }
+ }
+ ignoreTarget(node) {
+ return node.matches("a[href], a[href] *, input, textarea, button, button *, select, option");
+ }
+ #onMouseDown(event) {
+ if (event.button !== 0 || this.ignoreTarget(event.target)) {
+ return;
+ }
+ if (event.originalTarget) {
+ try {
+ event.originalTarget.tagName;
+ } catch {
+ return;
+ }
+ }
+ this.scrollLeftStart = this.element.scrollLeft;
+ this.scrollTopStart = this.element.scrollTop;
+ this.clientXStart = event.clientX;
+ this.clientYStart = event.clientY;
+ this.document.addEventListener("mousemove", this._onMouseMove, true);
+ this.document.addEventListener("mouseup", this._endPan, true);
+ this.element.addEventListener("scroll", this._endPan, true);
+ event.preventDefault();
+ event.stopPropagation();
+ const focusedElement = document.activeElement;
+ if (focusedElement && !focusedElement.contains(event.target)) {
+ focusedElement.blur();
+ }
+ }
+ #onMouseMove(event) {
+ this.element.removeEventListener("scroll", this._endPan, true);
+ if (!(event.buttons & 1)) {
+ this._endPan();
+ return;
+ }
+ const xDiff = event.clientX - this.clientXStart;
+ const yDiff = event.clientY - this.clientYStart;
+ this.element.scrollTo({
+ top: this.scrollTopStart - yDiff,
+ left: this.scrollLeftStart - xDiff,
+ behavior: "instant"
+ });
+ if (!this.overlay.parentNode) {
+ document.body.append(this.overlay);
+ }
+ }
+ #endPan() {
+ this.element.removeEventListener("scroll", this._endPan, true);
+ this.document.removeEventListener("mousemove", this._onMouseMove, true);
+ this.document.removeEventListener("mouseup", this._endPan, true);
+ this.overlay.remove();
+ }
+}
+
+
+/***/ }),
+
+/***/ 4065:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ L10n: () => (/* binding */ L10n)
+/* harmony export */ });
+class L10n {
+ #dir;
+ #lang;
+ #l10n;
+ constructor({
+ lang,
+ isRTL
+ }, l10n = null) {
+ this.#lang = L10n.#fixupLangCode(lang);
+ this.#l10n = l10n;
+ this.#dir = isRTL ?? L10n.#isRTL(this.#lang) ? "rtl" : "ltr";
+ }
+ _setL10n(l10n) {
+ this.#l10n = l10n;
+ }
+ getLanguage() {
+ return this.#lang;
+ }
+ getDirection() {
+ return this.#dir;
+ }
+ async get(ids, args = null, fallback) {
+ if (Array.isArray(ids)) {
+ ids = ids.map(id => ({
+ id
+ }));
+ const messages = await this.#l10n.formatMessages(ids);
+ return messages.map(message => message.value);
+ }
+ const messages = await this.#l10n.formatMessages([{
+ id: ids,
+ args
+ }]);
+ return messages?.[0].value || fallback;
+ }
+ async translate(element) {
+ try {
+ this.#l10n.connectRoot(element);
+ await this.#l10n.translateRoots();
+ } catch {}
+ }
+ pause() {
+ this.#l10n.pauseObserving();
+ }
+ resume() {
+ this.#l10n.resumeObserving();
+ }
+ static #fixupLangCode(langCode) {
+ langCode = langCode?.toLowerCase() || "en-us";
+ const PARTIAL_LANG_CODES = {
+ en: "en-us",
+ es: "es-es",
+ fy: "fy-nl",
+ ga: "ga-ie",
+ gu: "gu-in",
+ hi: "hi-in",
+ hy: "hy-am",
+ nb: "nb-no",
+ ne: "ne-np",
+ nn: "nn-no",
+ pa: "pa-in",
+ pt: "pt-pt",
+ sv: "sv-se",
+ zh: "zh-cn"
+ };
+ return PARTIAL_LANG_CODES[langCode] || langCode;
+ }
+ static #isRTL(lang) {
+ const shortCode = lang.split("-", 1)[0];
+ return ["ar", "he", "fa", "ps", "ur"].includes(shortCode);
+ }
+}
+
+
+/***/ }),
+
+/***/ 7910:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ NullL10n: () => (/* binding */ NullL10n)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var fluent_bundle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8759);
+/* harmony import */ var fluent_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8275);
+/* harmony import */ var _l10n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4065);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+
+class ConstL10n extends _l10n_js__WEBPACK_IMPORTED_MODULE_3__.L10n {
+ constructor(lang) {
+ super({
+ lang
+ });
+ this._setL10n(new fluent_dom__WEBPACK_IMPORTED_MODULE_2__.DOMLocalization([], ConstL10n.#generateBundles.bind(ConstL10n, lang)));
+ }
+ static async *#generateBundles(lang) {
+ const text = 'pdfjs-previous-button =\n .title = Previous Page\npdfjs-previous-button-label = Previous\npdfjs-next-button =\n .title = Next Page\npdfjs-next-button-label = Next\npdfjs-page-input =\n .title = Page\npdfjs-of-pages = of { $pagesCount }\npdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })\npdfjs-zoom-out-button =\n .title = Zoom Out\npdfjs-zoom-out-button-label = Zoom Out\npdfjs-zoom-in-button =\n .title = Zoom In\npdfjs-zoom-in-button-label = Zoom In\npdfjs-zoom-select =\n .title = Zoom\npdfjs-presentation-mode-button =\n .title = Switch to Presentation Mode\npdfjs-presentation-mode-button-label = Presentation Mode\npdfjs-open-file-button =\n .title = Open File\npdfjs-open-file-button-label = Open\npdfjs-print-button =\n .title = Print\npdfjs-print-button-label = Print\npdfjs-save-button =\n .title = Save\npdfjs-save-button-label = Save\npdfjs-download-button =\n .title = Download\npdfjs-download-button-label = Download\npdfjs-bookmark-button =\n .title = Current Page (View URL from Current Page)\npdfjs-bookmark-button-label = Current Page\npdfjs-open-in-app-button =\n .title = Open in app\npdfjs-open-in-app-button-label = Open in app\npdfjs-tools-button =\n .title = Tools\npdfjs-tools-button-label = Tools\npdfjs-first-page-button =\n .title = Go to First Page\npdfjs-first-page-button-label = Go to First Page\npdfjs-last-page-button =\n .title = Go to Last Page\npdfjs-last-page-button-label = Go to Last Page\npdfjs-page-rotate-cw-button =\n .title = Rotate Clockwise\npdfjs-page-rotate-cw-button-label = Rotate Clockwise\npdfjs-page-rotate-ccw-button =\n .title = Rotate Counterclockwise\npdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise\npdfjs-cursor-text-select-tool-button =\n .title = Enable Text Selection Tool\npdfjs-cursor-text-select-tool-button-label = Text Selection Tool\npdfjs-cursor-hand-tool-button =\n .title = Enable Hand Tool\npdfjs-cursor-hand-tool-button-label = Hand Tool\npdfjs-scroll-page-button =\n .title = Use Page Scrolling\npdfjs-scroll-page-button-label = Page Scrolling\npdfjs-scroll-vertical-button =\n .title = Use Vertical Scrolling\npdfjs-scroll-vertical-button-label = Vertical Scrolling\npdfjs-scroll-horizontal-button =\n .title = Use Horizontal Scrolling\npdfjs-scroll-horizontal-button-label = Horizontal Scrolling\npdfjs-scroll-wrapped-button =\n .title = Use Wrapped Scrolling\npdfjs-scroll-wrapped-button-label = Wrapped Scrolling\npdfjs-spread-none-button =\n .title = Do not join page spreads\npdfjs-spread-none-button-label = No Spreads\npdfjs-spread-odd-button =\n .title = Join page spreads starting with odd-numbered pages\npdfjs-spread-odd-button-label = Odd Spreads\npdfjs-spread-even-button =\n .title = Join page spreads starting with even-numbered pages\npdfjs-spread-even-button-label = Even Spreads\npdfjs-document-properties-button =\n .title = Document Properties\u2026\npdfjs-document-properties-button-label = Document Properties\u2026\npdfjs-document-properties-file-name = File name:\npdfjs-document-properties-file-size = File size:\npdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)\npdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)\npdfjs-document-properties-title = Title:\npdfjs-document-properties-author = Author:\npdfjs-document-properties-subject = Subject:\npdfjs-document-properties-keywords = Keywords:\npdfjs-document-properties-creation-date = Creation Date:\npdfjs-document-properties-modification-date = Modification Date:\npdfjs-document-properties-date-string = { $date }, { $time }\npdfjs-document-properties-creator = Creator:\npdfjs-document-properties-producer = PDF Producer:\npdfjs-document-properties-version = PDF Version:\npdfjs-document-properties-page-count = Page Count:\npdfjs-document-properties-page-size = Page Size:\npdfjs-document-properties-page-size-unit-inches = in\npdfjs-document-properties-page-size-unit-millimeters = mm\npdfjs-document-properties-page-size-orientation-portrait = portrait\npdfjs-document-properties-page-size-orientation-landscape = landscape\npdfjs-document-properties-page-size-name-a-three = A3\npdfjs-document-properties-page-size-name-a-four = A4\npdfjs-document-properties-page-size-name-letter = Letter\npdfjs-document-properties-page-size-name-legal = Legal\npdfjs-document-properties-page-size-dimension-string = { $width } \xD7 { $height } { $unit } ({ $orientation })\npdfjs-document-properties-page-size-dimension-name-string = { $width } \xD7 { $height } { $unit } ({ $name }, { $orientation })\npdfjs-document-properties-linearized = Fast Web View:\npdfjs-document-properties-linearized-yes = Yes\npdfjs-document-properties-linearized-no = No\npdfjs-document-properties-close-button = Close\npdfjs-print-progress-message = Preparing document for printing\u2026\npdfjs-print-progress-percent = { $progress }%\npdfjs-print-progress-close-button = Cancel\npdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.\npdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.\npdfjs-toggle-sidebar-button =\n .title = Toggle Sidebar\npdfjs-toggle-sidebar-notification-button =\n .title = Toggle Sidebar (document contains outline/attachments/layers)\npdfjs-toggle-sidebar-button-label = Toggle Sidebar\npdfjs-document-outline-button =\n .title = Show Document Outline (double-click to expand/collapse all items)\npdfjs-document-outline-button-label = Document Outline\npdfjs-attachments-button =\n .title = Show Attachments\npdfjs-attachments-button-label = Attachments\npdfjs-layers-button =\n .title = Show Layers (double-click to reset all layers to the default state)\npdfjs-layers-button-label = Layers\npdfjs-thumbs-button =\n .title = Show Thumbnails\npdfjs-thumbs-button-label = Thumbnails\npdfjs-current-outline-item-button =\n .title = Find Current Outline Item\npdfjs-current-outline-item-button-label = Current Outline Item\npdfjs-findbar-button =\n .title = Find in Document\npdfjs-findbar-button-label = Find\npdfjs-additional-layers = Additional Layers\npdfjs-thumb-page-title =\n .title = Page { $page }\npdfjs-thumb-page-canvas =\n .aria-label = Thumbnail of Page { $page }\npdfjs-find-input =\n .title = Find\n .placeholder = Find in document\u2026\npdfjs-find-previous-button =\n .title = Find the previous occurrence of the phrase\npdfjs-find-previous-button-label = Previous\npdfjs-find-next-button =\n .title = Find the next occurrence of the phrase\npdfjs-find-next-button-label = Next\npdfjs-find-highlight-checkbox = Highlight All\npdfjs-find-match-case-checkbox-label = Match Case\npdfjs-find-match-diacritics-checkbox-label = Match Diacritics\npdfjs-find-entire-word-checkbox-label = Whole Words\npdfjs-find-reached-top = Reached top of document, continued from bottom\npdfjs-find-reached-bottom = Reached end of document, continued from top\npdfjs-find-match-count =\n { $total ->\n [one] { $current } of { $total } match\n *[other] { $current } of { $total } matches\n }\npdfjs-find-match-count-limit =\n { $limit ->\n [one] More than { $limit } match\n *[other] More than { $limit } matches\n }\npdfjs-find-not-found = Phrase not found\npdfjs-page-scale-width = Page Width\npdfjs-page-scale-fit = Page Fit\npdfjs-page-scale-auto = Automatic Zoom\npdfjs-page-scale-actual = Actual Size\npdfjs-page-scale-percent = { $scale }%\npdfjs-page-landmark =\n .aria-label = Page { $page }\npdfjs-loading-error = An error occurred while loading the PDF.\npdfjs-invalid-file-error = Invalid or corrupted PDF file.\npdfjs-missing-file-error = Missing PDF file.\npdfjs-unexpected-response-error = Unexpected server response.\npdfjs-rendering-error = An error occurred while rendering the page.\npdfjs-annotation-date-string = { $date }, { $time }\npdfjs-text-annotation-type =\n .alt = [{ $type } Annotation]\npdfjs-password-label = Enter the password to open this PDF file.\npdfjs-password-invalid = Invalid password. Please try again.\npdfjs-password-ok-button = OK\npdfjs-password-cancel-button = Cancel\npdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.\npdfjs-editor-free-text-button =\n .title = Text\npdfjs-editor-free-text-button-label = Text\npdfjs-editor-ink-button =\n .title = Draw\npdfjs-editor-ink-button-label = Draw\npdfjs-editor-stamp-button =\n .title = Add or edit images\npdfjs-editor-stamp-button-label = Add or edit images\npdfjs-editor-highlight-button =\n .title = Highlight\npdfjs-editor-highlight-button-label = Highlight\npdfjs-editor-remove-ink-button =\n .title = Remove drawing\npdfjs-editor-remove-freetext-button =\n .title = Remove text\npdfjs-editor-remove-stamp-button =\n .title = Remove image\npdfjs-editor-remove-highlight-button =\n .title = Remove highlight\npdfjs-editor-free-text-color-input = Color\npdfjs-editor-free-text-size-input = Size\npdfjs-editor-ink-color-input = Color\npdfjs-editor-ink-thickness-input = Thickness\npdfjs-editor-ink-opacity-input = Opacity\npdfjs-editor-stamp-add-image-button =\n .title = Add image\npdfjs-editor-stamp-add-image-button-label = Add image\npdfjs-free-text =\n .aria-label = Text Editor\npdfjs-free-text-default-content = Start typing\u2026\npdfjs-ink =\n .aria-label = Draw Editor\npdfjs-ink-canvas =\n .aria-label = User-created image\npdfjs-editor-alt-text-button-label = Alt text\npdfjs-editor-alt-text-edit-button-label = Edit alt text\npdfjs-editor-alt-text-dialog-label = Choose an option\npdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people can\u2019t see the image or when it doesn\u2019t load.\npdfjs-editor-alt-text-add-description-label = Add a description\npdfjs-editor-alt-text-add-description-description = Aim for 1-2 sentences that describe the subject, setting, or actions.\npdfjs-editor-alt-text-mark-decorative-label = Mark as decorative\npdfjs-editor-alt-text-mark-decorative-description = This is used for ornamental images, like borders or watermarks.\npdfjs-editor-alt-text-cancel-button = Cancel\npdfjs-editor-alt-text-save-button = Save\npdfjs-editor-alt-text-decorative-tooltip = Marked as decorative\npdfjs-editor-alt-text-textarea =\n .placeholder = For example, \u201CA young man sits down at a table to eat a meal\u201D\npdfjs-editor-resizer-label-top-left = Top left corner \u2014 resize\npdfjs-editor-resizer-label-top-middle = Top middle \u2014 resize\npdfjs-editor-resizer-label-top-right = Top right corner \u2014 resize\npdfjs-editor-resizer-label-middle-right = Middle right \u2014 resize\npdfjs-editor-resizer-label-bottom-right = Bottom right corner \u2014 resize\npdfjs-editor-resizer-label-bottom-middle = Bottom middle \u2014 resize\npdfjs-editor-resizer-label-bottom-left = Bottom left corner \u2014 resize\npdfjs-editor-resizer-label-middle-left = Middle left \u2014 resize\npdfjs-editor-highlight-colorpicker-label = Highlight color\npdfjs-editor-colorpicker-button =\n .title = Change color\npdfjs-editor-colorpicker-dropdown =\n .aria-label = Color choices\npdfjs-editor-colorpicker-yellow =\n .title = Yellow\npdfjs-editor-colorpicker-green =\n .title = Green\npdfjs-editor-colorpicker-blue =\n .title = Blue\npdfjs-editor-colorpicker-pink =\n .title = Pink\npdfjs-editor-colorpicker-red =\n .title = Red';
+ const resource = new fluent_bundle__WEBPACK_IMPORTED_MODULE_1__.FluentResource(text);
+ const bundle = new fluent_bundle__WEBPACK_IMPORTED_MODULE_1__.FluentBundle(lang);
+ const errors = bundle.addResource(resource);
+ if (errors.length) {
+ console.error("L10n errors", errors);
+ }
+ yield bundle;
+ }
+ static get instance() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "instance", new ConstL10n("en-us"));
+ }
+}
+const NullL10n = {
+ getLanguage() {
+ return ConstL10n.instance.getLanguage();
+ },
+ getDirection() {
+ return ConstL10n.instance.getDirection();
+ },
+ async get(ids, args = null, fallback) {
+ return ConstL10n.instance.get(ids, args, fallback);
+ },
+ async translate(element) {
+ return ConstL10n.instance.translate(element);
+ },
+ pause() {
+ return ConstL10n.instance.pause();
+ },
+ resume() {
+ return ConstL10n.instance.resume();
+ }
+};
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1996:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ OverlayManager: () => (/* binding */ OverlayManager)
+/* harmony export */ });
+class OverlayManager {
+ #overlays = new WeakMap();
+ #active = null;
+ get active() {
+ return this.#active;
+ }
+ async register(dialog, canForceClose = false) {
+ if (typeof dialog !== "object") {
+ throw new Error("Not enough parameters.");
+ } else if (this.#overlays.has(dialog)) {
+ throw new Error("The overlay is already registered.");
+ }
+ this.#overlays.set(dialog, {
+ canForceClose
+ });
+ dialog.addEventListener("cancel", evt => {
+ this.#active = null;
+ });
+ }
+ async open(dialog) {
+ if (!this.#overlays.has(dialog)) {
+ throw new Error("The overlay does not exist.");
+ } else if (this.#active) {
+ if (this.#active === dialog) {
+ throw new Error("The overlay is already active.");
+ } else if (this.#overlays.get(dialog).canForceClose) {
+ await this.close();
+ } else {
+ throw new Error("Another overlay is currently active.");
+ }
+ }
+ this.#active = dialog;
+ dialog.showModal();
+ }
+ async close(dialog = this.#active) {
+ if (!this.#overlays.has(dialog)) {
+ throw new Error("The overlay does not exist.");
+ } else if (!this.#active) {
+ throw new Error("The overlay is currently not active.");
+ } else if (this.#active !== dialog) {
+ throw new Error("Another overlay is currently active.");
+ }
+ dialog.close();
+ this.#active = null;
+ }
+}
+
+
+/***/ }),
+
+/***/ 6329:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PasswordPrompt: () => (/* binding */ PasswordPrompt)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+class PasswordPrompt {
+ #activeCapability = null;
+ #updateCallback = null;
+ #reason = null;
+ constructor(options, overlayManager, isViewerEmbedded = false) {
+ this.dialog = options.dialog;
+ this.label = options.label;
+ this.input = options.input;
+ this.submitButton = options.submitButton;
+ this.cancelButton = options.cancelButton;
+ this.overlayManager = overlayManager;
+ this._isViewerEmbedded = isViewerEmbedded;
+ this.submitButton.addEventListener("click", this.#verify.bind(this));
+ this.cancelButton.addEventListener("click", this.close.bind(this));
+ this.input.addEventListener("keydown", e => {
+ if (e.keyCode === 13) {
+ this.#verify();
+ }
+ });
+ this.overlayManager.register(this.dialog, true);
+ this.dialog.addEventListener("close", this.#cancel.bind(this));
+ }
+ async open() {
+ if (this.#activeCapability) {
+ await this.#activeCapability.promise;
+ }
+ this.#activeCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();
+ try {
+ await this.overlayManager.open(this.dialog);
+ } catch (ex) {
+ this.#activeCapability.resolve();
+ throw ex;
+ }
+ const passwordIncorrect = this.#reason === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PasswordResponses.INCORRECT_PASSWORD;
+ if (!this._isViewerEmbedded || passwordIncorrect) {
+ this.input.focus();
+ }
+ this.label.setAttribute("data-l10n-id", `pdfjs-password-${passwordIncorrect ? "invalid" : "label"}`);
+ }
+ async close() {
+ if (this.overlayManager.active === this.dialog) {
+ this.overlayManager.close(this.dialog);
+ }
+ }
+ #verify() {
+ const password = this.input.value;
+ if (password?.length > 0) {
+ this.#invokeCallback(password);
+ }
+ }
+ #cancel() {
+ this.#invokeCallback(new Error("PasswordPrompt cancelled."));
+ this.#activeCapability.resolve();
+ }
+ #invokeCallback(password) {
+ if (!this.#updateCallback) {
+ return;
+ }
+ this.close();
+ this.input.value = "";
+ this.#updateCallback(password);
+ this.#updateCallback = null;
+ }
+ async setUpdateCallback(updateCallback, reason) {
+ if (this.#activeCapability) {
+ await this.#activeCapability.promise;
+ }
+ this.#updateCallback = updateCallback;
+ this.#reason = reason;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 716:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFAttachmentViewer: () => (/* binding */ PDFAttachmentViewer)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9415);
+/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6554);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+class PDFAttachmentViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_1__.BaseTreeViewer {
+ constructor(options) {
+ super(options);
+ this.downloadManager = options.downloadManager;
+ this.eventBus._on("fileattachmentannotation", this.#appendAttachment.bind(this));
+ }
+ reset(keepRenderedCapability = false) {
+ super.reset();
+ this._attachments = null;
+ if (!keepRenderedCapability) {
+ this._renderedCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();
+ }
+ this._pendingDispatchEvent = false;
+ }
+ async _dispatchEvent(attachmentsCount) {
+ this._renderedCapability.resolve();
+ if (attachmentsCount === 0 && !this._pendingDispatchEvent) {
+ this._pendingDispatchEvent = true;
+ await (0,_event_utils_js__WEBPACK_IMPORTED_MODULE_2__.waitOnEventOrTimeout)({
+ target: this.eventBus,
+ name: "annotationlayerrendered",
+ delay: 1000
+ });
+ if (!this._pendingDispatchEvent) {
+ return;
+ }
+ }
+ this._pendingDispatchEvent = false;
+ this.eventBus.dispatch("attachmentsloaded", {
+ source: this,
+ attachmentsCount
+ });
+ }
+ _bindLink(element, {
+ content,
+ filename
+ }) {
+ element.onclick = () => {
+ this.downloadManager.openOrDownloadData(content, filename);
+ return false;
+ };
+ }
+ render({
+ attachments,
+ keepRenderedCapability = false
+ }) {
+ if (this._attachments) {
+ this.reset(keepRenderedCapability);
+ }
+ this._attachments = attachments || null;
+ if (!attachments) {
+ this._dispatchEvent(0);
+ return;
+ }
+ const fragment = document.createDocumentFragment();
+ let attachmentsCount = 0;
+ for (const name in attachments) {
+ const item = attachments[name];
+ const content = item.content,
+ filename = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.getFilenameFromUrl)(item.filename, true);
+ const div = document.createElement("div");
+ div.className = "treeItem";
+ const element = document.createElement("a");
+ this._bindLink(element, {
+ content,
+ filename
+ });
+ element.textContent = this._normalizeTextContent(filename);
+ div.append(element);
+ fragment.append(div);
+ attachmentsCount++;
+ }
+ this._finishRendering(fragment, attachmentsCount);
+ }
+ #appendAttachment({
+ filename,
+ content
+ }) {
+ const renderedPromise = this._renderedCapability.promise;
+ renderedPromise.then(() => {
+ if (renderedPromise !== this._renderedCapability.promise) {
+ return;
+ }
+ const attachments = this._attachments || Object.create(null);
+ for (const name in attachments) {
+ if (filename === name) {
+ return;
+ }
+ }
+ attachments[filename] = {
+ filename,
+ content
+ };
+ this.render({
+ attachments,
+ keepRenderedCapability: true
+ });
+ });
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 3611:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFCursorTools: () => (/* binding */ PDFCursorTools)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+/* harmony import */ var _grab_to_pan_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6143);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+class PDFCursorTools {
+ #active = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT;
+ #prevActive = null;
+ constructor({
+ container,
+ eventBus,
+ cursorToolOnLoad = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT
+ }) {
+ this.container = container;
+ this.eventBus = eventBus;
+ this.#addEventListeners();
+ Promise.resolve().then(() => {
+ this.switchTool(cursorToolOnLoad);
+ });
+ }
+ get activeTool() {
+ return this.#active;
+ }
+ switchTool(tool) {
+ if (this.#prevActive !== null) {
+ return;
+ }
+ if (tool === this.#active) {
+ return;
+ }
+ const disableActiveTool = () => {
+ switch (this.#active) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT:
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.HAND:
+ this._handTool.deactivate();
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.ZOOM:
+ }
+ };
+ switch (tool) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT:
+ disableActiveTool();
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.HAND:
+ disableActiveTool();
+ this._handTool.activate();
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.ZOOM:
+ default:
+ console.error(`switchTool: "${tool}" is an unsupported value.`);
+ return;
+ }
+ this.#active = tool;
+ this.eventBus.dispatch("cursortoolchanged", {
+ source: this,
+ tool
+ });
+ }
+ #addEventListeners() {
+ this.eventBus._on("switchcursortool", evt => {
+ this.switchTool(evt.tool);
+ });
+ let annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE,
+ presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL;
+ const disableActive = () => {
+ const prevActive = this.#active;
+ this.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT);
+ this.#prevActive ??= prevActive;
+ };
+ const enableActive = () => {
+ const prevActive = this.#prevActive;
+ if (prevActive !== null && annotationEditorMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE && presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL) {
+ this.#prevActive = null;
+ this.switchTool(prevActive);
+ }
+ };
+ this.eventBus._on("secondarytoolbarreset", evt => {
+ if (this.#prevActive !== null) {
+ annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE;
+ presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL;
+ enableActive();
+ }
+ });
+ this.eventBus._on("annotationeditormodechanged", ({
+ mode
+ }) => {
+ annotationEditorMode = mode;
+ if (mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {
+ enableActive();
+ } else {
+ disableActive();
+ }
+ });
+ this.eventBus._on("presentationmodechanged", ({
+ state
+ }) => {
+ presentationModeState = state;
+ if (state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL) {
+ enableActive();
+ } else if (state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN) {
+ disableActive();
+ }
+ });
+ }
+ get _handTool() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_handTool", new _grab_to_pan_js__WEBPACK_IMPORTED_MODULE_2__.GrabToPan({
+ element: this.container
+ }));
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6312:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFDocumentProperties: () => (/* binding */ PDFDocumentProperties)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const DEFAULT_FIELD_CONTENT = "-";
+const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"];
+const US_PAGE_NAMES = {
+ "8.5x11": "letter",
+ "8.5x14": "legal"
+};
+const METRIC_PAGE_NAMES = {
+ "297x420": "a-three",
+ "210x297": "a-four"
+};
+function getPageName(size, isPortrait, pageNames) {
+ const width = isPortrait ? size.width : size.height;
+ const height = isPortrait ? size.height : size.width;
+ return pageNames[`${width}x${height}`];
+}
+class PDFDocumentProperties {
+ #fieldData = null;
+ constructor({
+ dialog,
+ fields,
+ closeButton
+ }, overlayManager, eventBus, l10n, fileNameLookup) {
+ this.dialog = dialog;
+ this.fields = fields;
+ this.overlayManager = overlayManager;
+ this.l10n = l10n;
+ this._fileNameLookup = fileNameLookup;
+ this.#reset();
+ closeButton.addEventListener("click", this.close.bind(this));
+ this.overlayManager.register(this.dialog);
+ eventBus._on("pagechanging", evt => {
+ this._currentPageNumber = evt.pageNumber;
+ });
+ eventBus._on("rotationchanging", evt => {
+ this._pagesRotation = evt.pagesRotation;
+ });
+ this._isNonMetricLocale = NON_METRIC_LOCALES.includes(l10n.getLanguage());
+ }
+ async open() {
+ await Promise.all([this.overlayManager.open(this.dialog), this._dataAvailableCapability.promise]);
+ const currentPageNumber = this._currentPageNumber;
+ const pagesRotation = this._pagesRotation;
+ if (this.#fieldData && currentPageNumber === this.#fieldData._currentPageNumber && pagesRotation === this.#fieldData._pagesRotation) {
+ this.#updateUI();
+ return;
+ }
+ const {
+ info,
+ contentLength
+ } = await this.pdfDocument.getMetadata();
+ const [fileName, fileSize, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([this._fileNameLookup(), this.#parseFileSize(contentLength), this.#parseDate(info.CreationDate), this.#parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => {
+ return this.#parsePageSize((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getPageSizeInches)(pdfPage), pagesRotation);
+ }), this.#parseLinearization(info.IsLinearized)]);
+ this.#fieldData = Object.freeze({
+ fileName,
+ fileSize,
+ title: info.Title,
+ author: info.Author,
+ subject: info.Subject,
+ keywords: info.Keywords,
+ creationDate,
+ modificationDate,
+ creator: info.Creator,
+ producer: info.Producer,
+ version: info.PDFFormatVersion,
+ pageCount: this.pdfDocument.numPages,
+ pageSize,
+ linearized: isLinearized,
+ _currentPageNumber: currentPageNumber,
+ _pagesRotation: pagesRotation
+ });
+ this.#updateUI();
+ const {
+ length
+ } = await this.pdfDocument.getDownloadInfo();
+ if (contentLength === length) {
+ return;
+ }
+ const data = Object.assign(Object.create(null), this.#fieldData);
+ data.fileSize = await this.#parseFileSize(length);
+ this.#fieldData = Object.freeze(data);
+ this.#updateUI();
+ }
+ async close() {
+ this.overlayManager.close(this.dialog);
+ }
+ setDocument(pdfDocument) {
+ if (this.pdfDocument) {
+ this.#reset();
+ this.#updateUI(true);
+ }
+ if (!pdfDocument) {
+ return;
+ }
+ this.pdfDocument = pdfDocument;
+ this._dataAvailableCapability.resolve();
+ }
+ #reset() {
+ this.pdfDocument = null;
+ this.#fieldData = null;
+ this._dataAvailableCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ this._currentPageNumber = 1;
+ this._pagesRotation = 0;
+ }
+ #updateUI(reset = false) {
+ if (reset || !this.#fieldData) {
+ for (const id in this.fields) {
+ this.fields[id].textContent = DEFAULT_FIELD_CONTENT;
+ }
+ return;
+ }
+ if (this.overlayManager.active !== this.dialog) {
+ return;
+ }
+ for (const id in this.fields) {
+ const content = this.#fieldData[id];
+ this.fields[id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT;
+ }
+ }
+ async #parseFileSize(fileSize = 0) {
+ const kb = fileSize / 1024,
+ mb = kb / 1024;
+ if (!kb) {
+ return undefined;
+ }
+ return this.l10n.get(`pdfjs-document-properties-${mb >= 1 ? "mb" : "kb"}`, {
+ size_mb: mb >= 1 && (+mb.toPrecision(3)).toLocaleString(),
+ size_kb: mb < 1 && (+kb.toPrecision(3)).toLocaleString(),
+ size_b: fileSize.toLocaleString()
+ });
+ }
+ async #parsePageSize(pageSizeInches, pagesRotation) {
+ if (!pageSizeInches) {
+ return undefined;
+ }
+ if (pagesRotation % 180 !== 0) {
+ pageSizeInches = {
+ width: pageSizeInches.height,
+ height: pageSizeInches.width
+ };
+ }
+ const isPortrait = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isPortraitOrientation)(pageSizeInches);
+ let sizeInches = {
+ width: Math.round(pageSizeInches.width * 100) / 100,
+ height: Math.round(pageSizeInches.height * 100) / 100
+ };
+ let sizeMillimeters = {
+ width: Math.round(pageSizeInches.width * 25.4 * 10) / 10,
+ height: Math.round(pageSizeInches.height * 25.4 * 10) / 10
+ };
+ let rawName = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES);
+ if (!rawName && !(Number.isInteger(sizeMillimeters.width) && Number.isInteger(sizeMillimeters.height))) {
+ const exactMillimeters = {
+ width: pageSizeInches.width * 25.4,
+ height: pageSizeInches.height * 25.4
+ };
+ const intMillimeters = {
+ width: Math.round(sizeMillimeters.width),
+ height: Math.round(sizeMillimeters.height)
+ };
+ if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) {
+ rawName = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES);
+ if (rawName) {
+ sizeInches = {
+ width: Math.round(intMillimeters.width / 25.4 * 100) / 100,
+ height: Math.round(intMillimeters.height / 25.4 * 100) / 100
+ };
+ sizeMillimeters = intMillimeters;
+ }
+ }
+ }
+ const [{
+ width,
+ height
+ }, unit, name, orientation] = await Promise.all([this._isNonMetricLocale ? sizeInches : sizeMillimeters, this.l10n.get(`pdfjs-document-properties-page-size-unit-${this._isNonMetricLocale ? "inches" : "millimeters"}`), rawName && this.l10n.get(`pdfjs-document-properties-page-size-name-${rawName}`), this.l10n.get(`pdfjs-document-properties-page-size-orientation-${isPortrait ? "portrait" : "landscape"}`)]);
+ return this.l10n.get(`pdfjs-document-properties-page-size-dimension-${name ? "name-" : ""}string`, {
+ width: width.toLocaleString(),
+ height: height.toLocaleString(),
+ unit,
+ name,
+ orientation
+ });
+ }
+ async #parseDate(inputDate) {
+ const dateObject = pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PDFDateString.toDateObject(inputDate);
+ if (!dateObject) {
+ return undefined;
+ }
+ return this.l10n.get("pdfjs-document-properties-date-string", {
+ date: dateObject.toLocaleDateString(),
+ time: dateObject.toLocaleTimeString()
+ });
+ }
+ #parseLinearization(isLinearized) {
+ return this.l10n.get(`pdfjs-document-properties-linearized-${isLinearized ? "yes" : "no"}`);
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1795:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFFindBar: () => (/* binding */ PDFFindBar)
+/* harmony export */ });
+/* harmony import */ var _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3557);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__]);
+_pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const MATCHES_COUNT_LIMIT = 1000;
+class PDFFindBar {
+ #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this));
+ constructor(options, eventBus) {
+ this.opened = false;
+ this.bar = options.bar;
+ this.toggleButton = options.toggleButton;
+ this.findField = options.findField;
+ this.highlightAll = options.highlightAllCheckbox;
+ this.caseSensitive = options.caseSensitiveCheckbox;
+ this.matchDiacritics = options.matchDiacriticsCheckbox;
+ this.entireWord = options.entireWordCheckbox;
+ this.findMsg = options.findMsg;
+ this.findResultsCount = options.findResultsCount;
+ this.findPreviousButton = options.findPreviousButton;
+ this.findNextButton = options.findNextButton;
+ this.eventBus = eventBus;
+ this.toggleButton.addEventListener("click", () => {
+ this.toggle();
+ });
+ this.findField.addEventListener("input", () => {
+ this.dispatchEvent("");
+ });
+ this.bar.addEventListener("keydown", e => {
+ switch (e.keyCode) {
+ case 13:
+ if (e.target === this.findField) {
+ this.dispatchEvent("again", e.shiftKey);
+ }
+ break;
+ case 27:
+ this.close();
+ break;
+ }
+ });
+ this.findPreviousButton.addEventListener("click", () => {
+ this.dispatchEvent("again", true);
+ });
+ this.findNextButton.addEventListener("click", () => {
+ this.dispatchEvent("again", false);
+ });
+ this.highlightAll.addEventListener("click", () => {
+ this.dispatchEvent("highlightallchange");
+ });
+ this.caseSensitive.addEventListener("click", () => {
+ this.dispatchEvent("casesensitivitychange");
+ });
+ this.entireWord.addEventListener("click", () => {
+ this.dispatchEvent("entirewordchange");
+ });
+ this.matchDiacritics.addEventListener("click", () => {
+ this.dispatchEvent("diacriticmatchingchange");
+ });
+ }
+ reset() {
+ this.updateUIState();
+ }
+ dispatchEvent(type, findPrev = false) {
+ this.eventBus.dispatch("find", {
+ source: this,
+ type,
+ query: this.findField.value,
+ caseSensitive: this.caseSensitive.checked,
+ entireWord: this.entireWord.checked,
+ highlightAll: this.highlightAll.checked,
+ findPrevious: findPrev,
+ matchDiacritics: this.matchDiacritics.checked
+ });
+ }
+ updateUIState(state, previous, matchesCount) {
+ const {
+ findField,
+ findMsg
+ } = this;
+ let findMsgId = "",
+ status = "";
+ switch (state) {
+ case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.FOUND:
+ break;
+ case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.PENDING:
+ status = "pending";
+ break;
+ case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.NOT_FOUND:
+ findMsgId = "pdfjs-find-not-found";
+ status = "notFound";
+ break;
+ case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.WRAPPED:
+ findMsgId = `pdfjs-find-reached-${previous ? "top" : "bottom"}`;
+ break;
+ }
+ findField.setAttribute("data-status", status);
+ findField.setAttribute("aria-invalid", state === _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.NOT_FOUND);
+ findMsg.setAttribute("data-status", status);
+ if (findMsgId) {
+ findMsg.setAttribute("data-l10n-id", findMsgId);
+ } else {
+ findMsg.removeAttribute("data-l10n-id");
+ findMsg.textContent = "";
+ }
+ this.updateResultsCount(matchesCount);
+ }
+ updateResultsCount({
+ current = 0,
+ total = 0
+ } = {}) {
+ const {
+ findResultsCount
+ } = this;
+ if (total > 0) {
+ const limit = MATCHES_COUNT_LIMIT;
+ findResultsCount.setAttribute("data-l10n-id", `pdfjs-find-match-count${total > limit ? "-limit" : ""}`);
+ findResultsCount.setAttribute("data-l10n-args", JSON.stringify({
+ limit,
+ current,
+ total
+ }));
+ } else {
+ findResultsCount.removeAttribute("data-l10n-id");
+ findResultsCount.textContent = "";
+ }
+ }
+ open() {
+ if (!this.opened) {
+ this.#resizeObserver.observe(this.bar.parentNode);
+ this.#resizeObserver.observe(this.bar);
+ this.opened = true;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleExpandedBtn)(this.toggleButton, true, this.bar);
+ }
+ this.findField.select();
+ this.findField.focus();
+ }
+ close() {
+ if (!this.opened) {
+ return;
+ }
+ this.#resizeObserver.disconnect();
+ this.opened = false;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleExpandedBtn)(this.toggleButton, false, this.bar);
+ this.eventBus.dispatch("findbarclose", {
+ source: this
+ });
+ }
+ toggle() {
+ if (this.opened) {
+ this.close();
+ } else {
+ this.open();
+ }
+ }
+ #resizeObserverCallback(entries) {
+ const {
+ bar
+ } = this;
+ bar.classList.remove("wrapContainers");
+ const findbarHeight = bar.clientHeight;
+ const inputContainerHeight = bar.firstElementChild.clientHeight;
+ if (findbarHeight > inputContainerHeight) {
+ bar.classList.add("wrapContainers");
+ }
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 3557:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ FindState: () => (/* binding */ FindState),
+/* harmony export */ PDFFindController: () => (/* binding */ PDFFindController)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var _pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6839);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+const FindState = {
+ FOUND: 0,
+ NOT_FOUND: 1,
+ WRAPPED: 2,
+ PENDING: 3
+};
+const FIND_TIMEOUT = 250;
+const MATCH_SCROLL_OFFSET_TOP = -50;
+const MATCH_SCROLL_OFFSET_LEFT = -400;
+const CHARACTERS_TO_NORMALIZE = {
+ "\u2010": "-",
+ "\u2018": "'",
+ "\u2019": "'",
+ "\u201A": "'",
+ "\u201B": "'",
+ "\u201C": '"',
+ "\u201D": '"',
+ "\u201E": '"',
+ "\u201F": '"',
+ "\u00BC": "1/4",
+ "\u00BD": "1/2",
+ "\u00BE": "3/4"
+};
+const DIACRITICS_EXCEPTION = new Set([0x3099, 0x309a, 0x094d, 0x09cd, 0x0a4d, 0x0acd, 0x0b4d, 0x0bcd, 0x0c4d, 0x0ccd, 0x0d3b, 0x0d3c, 0x0d4d, 0x0dca, 0x0e3a, 0x0eba, 0x0f84, 0x1039, 0x103a, 0x1714, 0x1734, 0x17d2, 0x1a60, 0x1b44, 0x1baa, 0x1bab, 0x1bf2, 0x1bf3, 0x2d7f, 0xa806, 0xa82c, 0xa8c4, 0xa953, 0xa9c0, 0xaaf6, 0xabed, 0x0c56, 0x0f71, 0x0f72, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f80, 0x0f74]);
+let DIACRITICS_EXCEPTION_STR;
+const DIACRITICS_REG_EXP = /\p{M}+/gu;
+const SPECIAL_CHARS_REG_EXP = /([.*+?^${}()|[\]\\])|(\p{P})|(\s+)|(\p{M})|(\p{L})/gu;
+const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u;
+const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u;
+const SYLLABLES_REG_EXP = /[\uAC00-\uD7AF\uFA6C\uFACF-\uFAD1\uFAD5-\uFAD7]+/g;
+const SYLLABLES_LENGTHS = new Map();
+const FIRST_CHAR_SYLLABLES_REG_EXP = "[\\u1100-\\u1112\\ud7a4-\\ud7af\\ud84a\\ud84c\\ud850\\ud854\\ud857\\ud85f]";
+const NFKC_CHARS_TO_NORMALIZE = new Map();
+let noSyllablesRegExp = null;
+let withSyllablesRegExp = null;
+function normalize(text) {
+ const syllablePositions = [];
+ let m;
+ while ((m = SYLLABLES_REG_EXP.exec(text)) !== null) {
+ let {
+ index
+ } = m;
+ for (const char of m[0]) {
+ let len = SYLLABLES_LENGTHS.get(char);
+ if (!len) {
+ len = char.normalize("NFD").length;
+ SYLLABLES_LENGTHS.set(char, len);
+ }
+ syllablePositions.push([len, index++]);
+ }
+ }
+ let normalizationRegex;
+ if (syllablePositions.length === 0 && noSyllablesRegExp) {
+ normalizationRegex = noSyllablesRegExp;
+ } else if (syllablePositions.length > 0 && withSyllablesRegExp) {
+ normalizationRegex = withSyllablesRegExp;
+ } else {
+ const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join("");
+ const toNormalizeWithNFKC = (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getNormalizeWithNFKC)();
+ const CJK = "(?:\\p{Ideographic}|[\u3040-\u30FF])";
+ const HKDiacritics = "(?:\u3099|\u309A)";
+ const regexp = `([${replace}])|([${toNormalizeWithNFKC}])|(${HKDiacritics}\\n)|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(${CJK}\\n)|(\\n)`;
+ if (syllablePositions.length === 0) {
+ normalizationRegex = noSyllablesRegExp = new RegExp(regexp + "|(\\u0000)", "gum");
+ } else {
+ normalizationRegex = withSyllablesRegExp = new RegExp(regexp + `|(${FIRST_CHAR_SYLLABLES_REG_EXP})`, "gum");
+ }
+ }
+ const rawDiacriticsPositions = [];
+ while ((m = DIACRITICS_REG_EXP.exec(text)) !== null) {
+ rawDiacriticsPositions.push([m[0].length, m.index]);
+ }
+ let normalized = text.normalize("NFD");
+ const positions = [[0, 0]];
+ let rawDiacriticsIndex = 0;
+ let syllableIndex = 0;
+ let shift = 0;
+ let shiftOrigin = 0;
+ let eol = 0;
+ let hasDiacritics = false;
+ normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, p6, p7, p8, i) => {
+ i -= shiftOrigin;
+ if (p1) {
+ const replacement = CHARACTERS_TO_NORMALIZE[p1];
+ const jj = replacement.length;
+ for (let j = 1; j < jj; j++) {
+ positions.push([i - shift + j, shift - j]);
+ }
+ shift -= jj - 1;
+ return replacement;
+ }
+ if (p2) {
+ let replacement = NFKC_CHARS_TO_NORMALIZE.get(p2);
+ if (!replacement) {
+ replacement = p2.normalize("NFKC");
+ NFKC_CHARS_TO_NORMALIZE.set(p2, replacement);
+ }
+ const jj = replacement.length;
+ for (let j = 1; j < jj; j++) {
+ positions.push([i - shift + j, shift - j]);
+ }
+ shift -= jj - 1;
+ return replacement;
+ }
+ if (p3) {
+ hasDiacritics = true;
+ if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) {
+ ++rawDiacriticsIndex;
+ } else {
+ positions.push([i - 1 - shift + 1, shift - 1]);
+ shift -= 1;
+ shiftOrigin += 1;
+ }
+ positions.push([i - shift + 1, shift]);
+ shiftOrigin += 1;
+ eol += 1;
+ return p3.charAt(0);
+ }
+ if (p4) {
+ const hasTrailingDashEOL = p4.endsWith("\n");
+ const len = hasTrailingDashEOL ? p4.length - 2 : p4.length;
+ hasDiacritics = true;
+ let jj = len;
+ if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) {
+ jj -= rawDiacriticsPositions[rawDiacriticsIndex][0];
+ ++rawDiacriticsIndex;
+ }
+ for (let j = 1; j <= jj; j++) {
+ positions.push([i - 1 - shift + j, shift - j]);
+ }
+ shift -= jj;
+ shiftOrigin += jj;
+ if (hasTrailingDashEOL) {
+ i += len - 1;
+ positions.push([i - shift + 1, 1 + shift]);
+ shift += 1;
+ shiftOrigin += 1;
+ eol += 1;
+ return p4.slice(0, len);
+ }
+ return p4;
+ }
+ if (p5) {
+ const len = p5.length - 2;
+ positions.push([i - shift + len, 1 + shift]);
+ shift += 1;
+ shiftOrigin += 1;
+ eol += 1;
+ return p5.slice(0, -2);
+ }
+ if (p6) {
+ const len = p6.length - 1;
+ positions.push([i - shift + len, shift]);
+ shiftOrigin += 1;
+ eol += 1;
+ return p6.slice(0, -1);
+ }
+ if (p7) {
+ positions.push([i - shift + 1, shift - 1]);
+ shift -= 1;
+ shiftOrigin += 1;
+ eol += 1;
+ return " ";
+ }
+ if (i + eol === syllablePositions[syllableIndex]?.[1]) {
+ const newCharLen = syllablePositions[syllableIndex][0] - 1;
+ ++syllableIndex;
+ for (let j = 1; j <= newCharLen; j++) {
+ positions.push([i - (shift - j), shift - j]);
+ }
+ shift -= newCharLen;
+ shiftOrigin += newCharLen;
+ }
+ return p8;
+ });
+ positions.push([normalized.length, shift]);
+ return [normalized, positions, hasDiacritics];
+}
+function getOriginalIndex(diffs, pos, len) {
+ if (!diffs) {
+ return [pos, len];
+ }
+ const start = pos;
+ const end = pos + len - 1;
+ let i = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(diffs, x => x[0] >= start);
+ if (diffs[i][0] > start) {
+ --i;
+ }
+ let j = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(diffs, x => x[0] >= end, i);
+ if (diffs[j][0] > end) {
+ --j;
+ }
+ const oldStart = start + diffs[i][1];
+ const oldEnd = end + diffs[j][1];
+ const oldLen = oldEnd + 1 - oldStart;
+ return [oldStart, oldLen];
+}
+class PDFFindController {
+ #state = null;
+ #updateMatchesCountOnProgress = true;
+ #visitedPagesCount = 0;
+ constructor({
+ linkService,
+ eventBus,
+ updateMatchesCountOnProgress = true
+ }) {
+ this._linkService = linkService;
+ this._eventBus = eventBus;
+ this.#updateMatchesCountOnProgress = updateMatchesCountOnProgress;
+ this.onIsPageVisible = null;
+ this.#reset();
+ eventBus._on("find", this.#onFind.bind(this));
+ eventBus._on("findbarclose", this.#onFindBarClose.bind(this));
+ }
+ get highlightMatches() {
+ return this._highlightMatches;
+ }
+ get pageMatches() {
+ return this._pageMatches;
+ }
+ get pageMatchesLength() {
+ return this._pageMatchesLength;
+ }
+ get selected() {
+ return this._selected;
+ }
+ get state() {
+ return this.#state;
+ }
+ setDocument(pdfDocument) {
+ if (this._pdfDocument) {
+ this.#reset();
+ }
+ if (!pdfDocument) {
+ return;
+ }
+ this._pdfDocument = pdfDocument;
+ this._firstPageCapability.resolve();
+ }
+ #onFind(state) {
+ if (!state) {
+ return;
+ }
+ const pdfDocument = this._pdfDocument;
+ const {
+ type
+ } = state;
+ if (this.#state === null || this.#shouldDirtyMatch(state)) {
+ this._dirtyMatch = true;
+ }
+ this.#state = state;
+ if (type !== "highlightallchange") {
+ this.#updateUIState(FindState.PENDING);
+ }
+ this._firstPageCapability.promise.then(() => {
+ if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) {
+ return;
+ }
+ this.#extractText();
+ const findbarClosed = !this._highlightMatches;
+ const pendingTimeout = !!this._findTimeout;
+ if (this._findTimeout) {
+ clearTimeout(this._findTimeout);
+ this._findTimeout = null;
+ }
+ if (!type) {
+ this._findTimeout = setTimeout(() => {
+ this.#nextMatch();
+ this._findTimeout = null;
+ }, FIND_TIMEOUT);
+ } else if (this._dirtyMatch) {
+ this.#nextMatch();
+ } else if (type === "again") {
+ this.#nextMatch();
+ if (findbarClosed && this.#state.highlightAll) {
+ this.#updateAllPages();
+ }
+ } else if (type === "highlightallchange") {
+ if (pendingTimeout) {
+ this.#nextMatch();
+ } else {
+ this._highlightMatches = true;
+ }
+ this.#updateAllPages();
+ } else {
+ this.#nextMatch();
+ }
+ });
+ }
+ scrollMatchIntoView({
+ element = null,
+ selectedLeft = 0,
+ pageIndex = -1,
+ matchIndex = -1
+ }) {
+ if (!this._scrollMatches || !element) {
+ return;
+ } else if (matchIndex === -1 || matchIndex !== this._selected.matchIdx) {
+ return;
+ } else if (pageIndex === -1 || pageIndex !== this._selected.pageIdx) {
+ return;
+ }
+ this._scrollMatches = false;
+ const spot = {
+ top: MATCH_SCROLL_OFFSET_TOP,
+ left: selectedLeft + MATCH_SCROLL_OFFSET_LEFT
+ };
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.scrollIntoView)(element, spot, true);
+ }
+ #reset() {
+ this._highlightMatches = false;
+ this._scrollMatches = false;
+ this._pdfDocument = null;
+ this._pageMatches = [];
+ this._pageMatchesLength = [];
+ this.#visitedPagesCount = 0;
+ this.#state = null;
+ this._selected = {
+ pageIdx: -1,
+ matchIdx: -1
+ };
+ this._offset = {
+ pageIdx: null,
+ matchIdx: null,
+ wrapped: false
+ };
+ this._extractTextPromises = [];
+ this._pageContents = [];
+ this._pageDiffs = [];
+ this._hasDiacritics = [];
+ this._matchesCountTotal = 0;
+ this._pagesToSearch = null;
+ this._pendingFindMatches = new Set();
+ this._resumePageIdx = null;
+ this._dirtyMatch = false;
+ clearTimeout(this._findTimeout);
+ this._findTimeout = null;
+ this._firstPageCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.PromiseCapability();
+ }
+ get #query() {
+ const {
+ query
+ } = this.#state;
+ if (typeof query === "string") {
+ if (query !== this._rawQuery) {
+ this._rawQuery = query;
+ [this._normalizedQuery] = normalize(query);
+ }
+ return this._normalizedQuery;
+ }
+ return (query || []).filter(q => !!q).map(q => normalize(q)[0]);
+ }
+ #shouldDirtyMatch(state) {
+ const newQuery = state.query,
+ prevQuery = this.#state.query;
+ const newType = typeof newQuery,
+ prevType = typeof prevQuery;
+ if (newType !== prevType) {
+ return true;
+ }
+ if (newType === "string") {
+ if (newQuery !== prevQuery) {
+ return true;
+ }
+ } else if (JSON.stringify(newQuery) !== JSON.stringify(prevQuery)) {
+ return true;
+ }
+ switch (state.type) {
+ case "again":
+ const pageNumber = this._selected.pageIdx + 1;
+ const linkService = this._linkService;
+ return pageNumber >= 1 && pageNumber <= linkService.pagesCount && pageNumber !== linkService.page && !(this.onIsPageVisible?.(pageNumber) ?? true);
+ case "highlightallchange":
+ return false;
+ }
+ return true;
+ }
+ #isEntireWord(content, startIdx, length) {
+ let match = content.slice(0, startIdx).match(NOT_DIACRITIC_FROM_END_REG_EXP);
+ if (match) {
+ const first = content.charCodeAt(startIdx);
+ const limit = match[1].charCodeAt(0);
+ if ((0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(first) === (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(limit)) {
+ return false;
+ }
+ }
+ match = content.slice(startIdx + length).match(NOT_DIACRITIC_FROM_START_REG_EXP);
+ if (match) {
+ const last = content.charCodeAt(startIdx + length - 1);
+ const limit = match[1].charCodeAt(0);
+ if ((0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(last) === (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(limit)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ #calculateRegExpMatch(query, entireWord, pageIndex, pageContent) {
+ const matches = this._pageMatches[pageIndex] = [];
+ const matchesLength = this._pageMatchesLength[pageIndex] = [];
+ if (!query) {
+ return;
+ }
+ const diffs = this._pageDiffs[pageIndex];
+ let match;
+ while ((match = query.exec(pageContent)) !== null) {
+ if (entireWord && !this.#isEntireWord(pageContent, match.index, match[0].length)) {
+ continue;
+ }
+ const [matchPos, matchLen] = getOriginalIndex(diffs, match.index, match[0].length);
+ if (matchLen) {
+ matches.push(matchPos);
+ matchesLength.push(matchLen);
+ }
+ }
+ }
+ #convertToRegExpString(query, hasDiacritics) {
+ const {
+ matchDiacritics
+ } = this.#state;
+ let isUnicode = false;
+ query = query.replaceAll(SPECIAL_CHARS_REG_EXP, (match, p1, p2, p3, p4, p5) => {
+ if (p1) {
+ return `[ ]*\\${p1}[ ]*`;
+ }
+ if (p2) {
+ return `[ ]*${p2}[ ]*`;
+ }
+ if (p3) {
+ return "[ ]+";
+ }
+ if (matchDiacritics) {
+ return p4 || p5;
+ }
+ if (p4) {
+ return DIACRITICS_EXCEPTION.has(p4.charCodeAt(0)) ? p4 : "";
+ }
+ if (hasDiacritics) {
+ isUnicode = true;
+ return `${p5}\\p{M}*`;
+ }
+ return p5;
+ });
+ const trailingSpaces = "[ ]*";
+ if (query.endsWith(trailingSpaces)) {
+ query = query.slice(0, query.length - trailingSpaces.length);
+ }
+ if (matchDiacritics) {
+ if (hasDiacritics) {
+ DIACRITICS_EXCEPTION_STR ||= String.fromCharCode(...DIACRITICS_EXCEPTION);
+ isUnicode = true;
+ query = `${query}(?=[${DIACRITICS_EXCEPTION_STR}]|[^\\p{M}]|$)`;
+ }
+ }
+ return [isUnicode, query];
+ }
+ #calculateMatch(pageIndex) {
+ let query = this.#query;
+ if (query.length === 0) {
+ return;
+ }
+ const {
+ caseSensitive,
+ entireWord
+ } = this.#state;
+ const pageContent = this._pageContents[pageIndex];
+ const hasDiacritics = this._hasDiacritics[pageIndex];
+ let isUnicode = false;
+ if (typeof query === "string") {
+ [isUnicode, query] = this.#convertToRegExpString(query, hasDiacritics);
+ } else {
+ query = query.sort().reverse().map(q => {
+ const [isUnicodePart, queryPart] = this.#convertToRegExpString(q, hasDiacritics);
+ isUnicode ||= isUnicodePart;
+ return `(${queryPart})`;
+ }).join("|");
+ }
+ const flags = `g${isUnicode ? "u" : ""}${caseSensitive ? "" : "i"}`;
+ query = query ? new RegExp(query, flags) : null;
+ this.#calculateRegExpMatch(query, entireWord, pageIndex, pageContent);
+ if (this.#state.highlightAll) {
+ this.#updatePage(pageIndex);
+ }
+ if (this._resumePageIdx === pageIndex) {
+ this._resumePageIdx = null;
+ this.#nextPageMatch();
+ }
+ const pageMatchesCount = this._pageMatches[pageIndex].length;
+ this._matchesCountTotal += pageMatchesCount;
+ if (this.#updateMatchesCountOnProgress) {
+ if (pageMatchesCount > 0) {
+ this.#updateUIResultsCount();
+ }
+ } else if (++this.#visitedPagesCount === this._linkService.pagesCount) {
+ this.#updateUIResultsCount();
+ }
+ }
+ #extractText() {
+ if (this._extractTextPromises.length > 0) {
+ return;
+ }
+ let promise = Promise.resolve();
+ const textOptions = {
+ disableNormalization: true
+ };
+ for (let i = 0, ii = this._linkService.pagesCount; i < ii; i++) {
+ const extractTextCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.PromiseCapability();
+ this._extractTextPromises[i] = extractTextCapability.promise;
+ promise = promise.then(() => {
+ return this._pdfDocument.getPage(i + 1).then(pdfPage => {
+ return pdfPage.getTextContent(textOptions);
+ }).then(textContent => {
+ const strBuf = [];
+ for (const textItem of textContent.items) {
+ strBuf.push(textItem.str);
+ if (textItem.hasEOL) {
+ strBuf.push("\n");
+ }
+ }
+ [this._pageContents[i], this._pageDiffs[i], this._hasDiacritics[i]] = normalize(strBuf.join(""));
+ extractTextCapability.resolve();
+ }, reason => {
+ console.error(`Unable to get text content for page ${i + 1}`, reason);
+ this._pageContents[i] = "";
+ this._pageDiffs[i] = null;
+ this._hasDiacritics[i] = false;
+ extractTextCapability.resolve();
+ });
+ });
+ }
+ }
+ #updatePage(index) {
+ if (this._scrollMatches && this._selected.pageIdx === index) {
+ this._linkService.page = index + 1;
+ }
+ this._eventBus.dispatch("updatetextlayermatches", {
+ source: this,
+ pageIndex: index
+ });
+ }
+ #updateAllPages() {
+ this._eventBus.dispatch("updatetextlayermatches", {
+ source: this,
+ pageIndex: -1
+ });
+ }
+ #nextMatch() {
+ const previous = this.#state.findPrevious;
+ const currentPageIndex = this._linkService.page - 1;
+ const numPages = this._linkService.pagesCount;
+ this._highlightMatches = true;
+ if (this._dirtyMatch) {
+ this._dirtyMatch = false;
+ this._selected.pageIdx = this._selected.matchIdx = -1;
+ this._offset.pageIdx = currentPageIndex;
+ this._offset.matchIdx = null;
+ this._offset.wrapped = false;
+ this._resumePageIdx = null;
+ this._pageMatches.length = 0;
+ this._pageMatchesLength.length = 0;
+ this.#visitedPagesCount = 0;
+ this._matchesCountTotal = 0;
+ this.#updateAllPages();
+ for (let i = 0; i < numPages; i++) {
+ if (this._pendingFindMatches.has(i)) {
+ continue;
+ }
+ this._pendingFindMatches.add(i);
+ this._extractTextPromises[i].then(() => {
+ this._pendingFindMatches.delete(i);
+ this.#calculateMatch(i);
+ });
+ }
+ }
+ const query = this.#query;
+ if (query.length === 0) {
+ this.#updateUIState(FindState.FOUND);
+ return;
+ }
+ if (this._resumePageIdx) {
+ return;
+ }
+ const offset = this._offset;
+ this._pagesToSearch = numPages;
+ if (offset.matchIdx !== null) {
+ const numPageMatches = this._pageMatches[offset.pageIdx].length;
+ if (!previous && offset.matchIdx + 1 < numPageMatches || previous && offset.matchIdx > 0) {
+ offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1;
+ this.#updateMatch(true);
+ return;
+ }
+ this.#advanceOffsetPage(previous);
+ }
+ this.#nextPageMatch();
+ }
+ #matchesReady(matches) {
+ const offset = this._offset;
+ const numMatches = matches.length;
+ const previous = this.#state.findPrevious;
+ if (numMatches) {
+ offset.matchIdx = previous ? numMatches - 1 : 0;
+ this.#updateMatch(true);
+ return true;
+ }
+ this.#advanceOffsetPage(previous);
+ if (offset.wrapped) {
+ offset.matchIdx = null;
+ if (this._pagesToSearch < 0) {
+ this.#updateMatch(false);
+ return true;
+ }
+ }
+ return false;
+ }
+ #nextPageMatch() {
+ if (this._resumePageIdx !== null) {
+ console.error("There can only be one pending page.");
+ }
+ let matches = null;
+ do {
+ const pageIdx = this._offset.pageIdx;
+ matches = this._pageMatches[pageIdx];
+ if (!matches) {
+ this._resumePageIdx = pageIdx;
+ break;
+ }
+ } while (!this.#matchesReady(matches));
+ }
+ #advanceOffsetPage(previous) {
+ const offset = this._offset;
+ const numPages = this._linkService.pagesCount;
+ offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1;
+ offset.matchIdx = null;
+ this._pagesToSearch--;
+ if (offset.pageIdx >= numPages || offset.pageIdx < 0) {
+ offset.pageIdx = previous ? numPages - 1 : 0;
+ offset.wrapped = true;
+ }
+ }
+ #updateMatch(found = false) {
+ let state = FindState.NOT_FOUND;
+ const wrapped = this._offset.wrapped;
+ this._offset.wrapped = false;
+ if (found) {
+ const previousPage = this._selected.pageIdx;
+ this._selected.pageIdx = this._offset.pageIdx;
+ this._selected.matchIdx = this._offset.matchIdx;
+ state = wrapped ? FindState.WRAPPED : FindState.FOUND;
+ if (previousPage !== -1 && previousPage !== this._selected.pageIdx) {
+ this.#updatePage(previousPage);
+ }
+ }
+ this.#updateUIState(state, this.#state.findPrevious);
+ if (this._selected.pageIdx !== -1) {
+ this._scrollMatches = true;
+ this.#updatePage(this._selected.pageIdx);
+ }
+ }
+ #onFindBarClose(evt) {
+ const pdfDocument = this._pdfDocument;
+ this._firstPageCapability.promise.then(() => {
+ if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) {
+ return;
+ }
+ if (this._findTimeout) {
+ clearTimeout(this._findTimeout);
+ this._findTimeout = null;
+ }
+ if (this._resumePageIdx) {
+ this._resumePageIdx = null;
+ this._dirtyMatch = true;
+ }
+ this.#updateUIState(FindState.FOUND);
+ this._highlightMatches = false;
+ this.#updateAllPages();
+ });
+ }
+ #requestMatchesCount() {
+ const {
+ pageIdx,
+ matchIdx
+ } = this._selected;
+ let current = 0,
+ total = this._matchesCountTotal;
+ if (matchIdx !== -1) {
+ for (let i = 0; i < pageIdx; i++) {
+ current += this._pageMatches[i]?.length || 0;
+ }
+ current += matchIdx + 1;
+ }
+ if (current < 1 || current > total) {
+ current = total = 0;
+ }
+ return {
+ current,
+ total
+ };
+ }
+ #updateUIResultsCount() {
+ this._eventBus.dispatch("updatefindmatchescount", {
+ source: this,
+ matchesCount: this.#requestMatchesCount()
+ });
+ }
+ #updateUIState(state, previous = false) {
+ if (!this.#updateMatchesCountOnProgress && (this.#visitedPagesCount !== this._linkService.pagesCount || state === FindState.PENDING)) {
+ return;
+ }
+ this._eventBus.dispatch("updatefindcontrolstate", {
+ source: this,
+ state,
+ previous,
+ matchesCount: this.#requestMatchesCount(),
+ rawQuery: this.#state?.query ?? null
+ });
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6839:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ getCharacterType: () => (/* binding */ getCharacterType),
+/* harmony export */ getNormalizeWithNFKC: () => (/* binding */ getNormalizeWithNFKC)
+/* harmony export */ });
+/* unused harmony export CharacterType */
+const CharacterType = {
+ SPACE: 0,
+ ALPHA_LETTER: 1,
+ PUNCT: 2,
+ HAN_LETTER: 3,
+ KATAKANA_LETTER: 4,
+ HIRAGANA_LETTER: 5,
+ HALFWIDTH_KATAKANA_LETTER: 6,
+ THAI_LETTER: 7
+};
+function isAlphabeticalScript(charCode) {
+ return charCode < 0x2e80;
+}
+function isAscii(charCode) {
+ return (charCode & 0xff80) === 0;
+}
+function isAsciiAlpha(charCode) {
+ return charCode >= 0x61 && charCode <= 0x7a || charCode >= 0x41 && charCode <= 0x5a;
+}
+function isAsciiDigit(charCode) {
+ return charCode >= 0x30 && charCode <= 0x39;
+}
+function isAsciiSpace(charCode) {
+ return charCode === 0x20 || charCode === 0x09 || charCode === 0x0d || charCode === 0x0a;
+}
+function isHan(charCode) {
+ return charCode >= 0x3400 && charCode <= 0x9fff || charCode >= 0xf900 && charCode <= 0xfaff;
+}
+function isKatakana(charCode) {
+ return charCode >= 0x30a0 && charCode <= 0x30ff;
+}
+function isHiragana(charCode) {
+ return charCode >= 0x3040 && charCode <= 0x309f;
+}
+function isHalfwidthKatakana(charCode) {
+ return charCode >= 0xff60 && charCode <= 0xff9f;
+}
+function isThai(charCode) {
+ return (charCode & 0xff80) === 0x0e00;
+}
+function getCharacterType(charCode) {
+ if (isAlphabeticalScript(charCode)) {
+ if (isAscii(charCode)) {
+ if (isAsciiSpace(charCode)) {
+ return CharacterType.SPACE;
+ } else if (isAsciiAlpha(charCode) || isAsciiDigit(charCode) || charCode === 0x5f) {
+ return CharacterType.ALPHA_LETTER;
+ }
+ return CharacterType.PUNCT;
+ } else if (isThai(charCode)) {
+ return CharacterType.THAI_LETTER;
+ } else if (charCode === 0xa0) {
+ return CharacterType.SPACE;
+ }
+ return CharacterType.ALPHA_LETTER;
+ }
+ if (isHan(charCode)) {
+ return CharacterType.HAN_LETTER;
+ } else if (isKatakana(charCode)) {
+ return CharacterType.KATAKANA_LETTER;
+ } else if (isHiragana(charCode)) {
+ return CharacterType.HIRAGANA_LETTER;
+ } else if (isHalfwidthKatakana(charCode)) {
+ return CharacterType.HALFWIDTH_KATAKANA_LETTER;
+ }
+ return CharacterType.ALPHA_LETTER;
+}
+let NormalizeWithNFKC;
+function getNormalizeWithNFKC() {
+ NormalizeWithNFKC ||= ` ¨ª¯²-µ¸-º¼-¾IJ-ijĿ-ŀʼnſDŽ-njDZ-dzʰ-ʸ˘-ËË -ˤʹͺ;΄-΅·Ï-Ï–Ï°-ϲϴ-ϵϹևٵ-ٸक़-य़ড়-à§à§Ÿà¨³à¨¶à©™-ਜ਼ਫ਼àœ-àำຳໜ-à»à¼Œà½ƒà½à½’བྷཛྷཀྵჼᴬ-ᴮᴰ-ᴺᴼ-áµáµ-ᵪᵸᶛ-ᶿẚ-ẛάέήίόύώΆ᾽-á¿á¿‰á¿‹á¿-á¿á¿“á¿›á¿-῟ΰΎá¿-`ΌΏ´-῾ - ‑‗․-… ″-‴‶-‷‼‾â‡-â‰â—âŸâ°-â±â´-â‚Žâ‚-ₜ₨℀-℃℅-ℇ℉-â„“â„•-â„–â„™-â„â„ -™ℤΩℨK-â„ℯ-ℱℳ-ℹ℻-⅀ⅅ-â…‰â…-ⅿ↉∬-âˆâˆ¯-∰〈-〉①-⓪⨌⩴-⩶⫝̸ⱼ-ⱽⵯ⺟⻳⼀-⿕ 〶〸-〺゛-゜ゟヿㄱ-ㆎ㆒-㆟㈀-㈞㈠-㉇ã‰-㉾㊀-ã¿êšœ-êšê°êŸ²-ꟴꟸ-ꟹêœ-êŸê©ï¤€-ï¨ï¨ï¨’凞-ï¨žï¨ ï¨¢ï¨¥-都飯-ï©ï©°-龎ff-stﬓ-ﬗï¬ï¬Ÿ-זּטּ-לּמּï€-ïïƒ-ï„ï†-ﮱﯓ-ï´½ïµ-ï¶ï¶’-ﷇﷰ-ï·¼ï¸-︙︰-﹄﹇-ï¹’ï¹”-﹦﹨-﹫ﹰ-ﹲﹴﹶ-ﻼï¼-하-ᅦᅧ-ï¿ï¿’-ï¿—ï¿š-ï¿œï¿ -₩`;
+ return NormalizeWithNFKC;
+}
+
+
+/***/ }),
+
+/***/ 6418:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFHistory: () => (/* binding */ PDFHistory)
+/* harmony export */ });
+/* unused harmony exports isDestArraysEqual, isDestHashesEqual */
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6554);
+
+
+const HASH_CHANGE_TIMEOUT = 1000;
+const POSITION_UPDATED_THRESHOLD = 50;
+const UPDATE_VIEWAREA_TIMEOUT = 1000;
+function getCurrentHash() {
+ return document.location.hash;
+}
+class PDFHistory {
+ constructor({
+ linkService,
+ eventBus
+ }) {
+ this.linkService = linkService;
+ this.eventBus = eventBus;
+ this._initialized = false;
+ this._fingerprint = "";
+ this.reset();
+ this._boundEvents = null;
+ this.eventBus._on("pagesinit", () => {
+ this._isPagesLoaded = false;
+ this.eventBus._on("pagesloaded", evt => {
+ this._isPagesLoaded = !!evt.pagesCount;
+ }, {
+ once: true
+ });
+ });
+ }
+ initialize({
+ fingerprint,
+ resetHistory = false,
+ updateUrl = false
+ }) {
+ if (!fingerprint || typeof fingerprint !== "string") {
+ console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.');
+ return;
+ }
+ if (this._initialized) {
+ this.reset();
+ }
+ const reInitialized = this._fingerprint !== "" && this._fingerprint !== fingerprint;
+ this._fingerprint = fingerprint;
+ this._updateUrl = updateUrl === true;
+ this._initialized = true;
+ this._bindEvents();
+ const state = window.history.state;
+ this._popStateInProgress = false;
+ this._blockHashChange = 0;
+ this._currentHash = getCurrentHash();
+ this._numPositionUpdates = 0;
+ this._uid = this._maxUid = 0;
+ this._destination = null;
+ this._position = null;
+ if (!this._isValidState(state, true) || resetHistory) {
+ const {
+ hash,
+ page,
+ rotation
+ } = this._parseCurrentHash(true);
+ if (!hash || reInitialized || resetHistory) {
+ this._pushOrReplaceState(null, true);
+ return;
+ }
+ this._pushOrReplaceState({
+ hash,
+ page,
+ rotation
+ }, true);
+ return;
+ }
+ const destination = state.destination;
+ this._updateInternalState(destination, state.uid, true);
+ if (destination.rotation !== undefined) {
+ this._initialRotation = destination.rotation;
+ }
+ if (destination.dest) {
+ this._initialBookmark = JSON.stringify(destination.dest);
+ this._destination.page = null;
+ } else if (destination.hash) {
+ this._initialBookmark = destination.hash;
+ } else if (destination.page) {
+ this._initialBookmark = `page=${destination.page}`;
+ }
+ }
+ reset() {
+ if (this._initialized) {
+ this._pageHide();
+ this._initialized = false;
+ this._unbindEvents();
+ }
+ if (this._updateViewareaTimeout) {
+ clearTimeout(this._updateViewareaTimeout);
+ this._updateViewareaTimeout = null;
+ }
+ this._initialBookmark = null;
+ this._initialRotation = null;
+ }
+ push({
+ namedDest = null,
+ explicitDest,
+ pageNumber
+ }) {
+ if (!this._initialized) {
+ return;
+ }
+ if (namedDest && typeof namedDest !== "string") {
+ console.error("PDFHistory.push: " + `"${namedDest}" is not a valid namedDest parameter.`);
+ return;
+ } else if (!Array.isArray(explicitDest)) {
+ console.error("PDFHistory.push: " + `"${explicitDest}" is not a valid explicitDest parameter.`);
+ return;
+ } else if (!this._isValidPage(pageNumber)) {
+ if (pageNumber !== null || this._destination) {
+ console.error("PDFHistory.push: " + `"${pageNumber}" is not a valid pageNumber parameter.`);
+ return;
+ }
+ }
+ const hash = namedDest || JSON.stringify(explicitDest);
+ if (!hash) {
+ return;
+ }
+ let forceReplace = false;
+ if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) {
+ if (this._destination.page) {
+ return;
+ }
+ forceReplace = true;
+ }
+ if (this._popStateInProgress && !forceReplace) {
+ return;
+ }
+ this._pushOrReplaceState({
+ dest: explicitDest,
+ hash,
+ page: pageNumber,
+ rotation: this.linkService.rotation
+ }, forceReplace);
+ if (!this._popStateInProgress) {
+ this._popStateInProgress = true;
+ Promise.resolve().then(() => {
+ this._popStateInProgress = false;
+ });
+ }
+ }
+ pushPage(pageNumber) {
+ if (!this._initialized) {
+ return;
+ }
+ if (!this._isValidPage(pageNumber)) {
+ console.error(`PDFHistory.pushPage: "${pageNumber}" is not a valid page number.`);
+ return;
+ }
+ if (this._destination?.page === pageNumber) {
+ return;
+ }
+ if (this._popStateInProgress) {
+ return;
+ }
+ this._pushOrReplaceState({
+ dest: null,
+ hash: `page=${pageNumber}`,
+ page: pageNumber,
+ rotation: this.linkService.rotation
+ });
+ if (!this._popStateInProgress) {
+ this._popStateInProgress = true;
+ Promise.resolve().then(() => {
+ this._popStateInProgress = false;
+ });
+ }
+ }
+ pushCurrentPosition() {
+ if (!this._initialized || this._popStateInProgress) {
+ return;
+ }
+ this._tryPushCurrentPosition();
+ }
+ back() {
+ if (!this._initialized || this._popStateInProgress) {
+ return;
+ }
+ const state = window.history.state;
+ if (this._isValidState(state) && state.uid > 0) {
+ window.history.back();
+ }
+ }
+ forward() {
+ if (!this._initialized || this._popStateInProgress) {
+ return;
+ }
+ const state = window.history.state;
+ if (this._isValidState(state) && state.uid < this._maxUid) {
+ window.history.forward();
+ }
+ }
+ get popStateInProgress() {
+ return this._initialized && (this._popStateInProgress || this._blockHashChange > 0);
+ }
+ get initialBookmark() {
+ return this._initialized ? this._initialBookmark : null;
+ }
+ get initialRotation() {
+ return this._initialized ? this._initialRotation : null;
+ }
+ _pushOrReplaceState(destination, forceReplace = false) {
+ const shouldReplace = forceReplace || !this._destination;
+ const newState = {
+ fingerprint: this._fingerprint,
+ uid: shouldReplace ? this._uid : this._uid + 1,
+ destination
+ };
+ this._updateInternalState(destination, newState.uid);
+ let newUrl;
+ if (this._updateUrl && destination?.hash) {
+ const baseUrl = document.location.href.split("#")[0];
+ if (!baseUrl.startsWith("file://")) {
+ newUrl = `${baseUrl}#${destination.hash}`;
+ }
+ }
+ if (shouldReplace) {
+ window.history.replaceState(newState, "", newUrl);
+ } else {
+ window.history.pushState(newState, "", newUrl);
+ }
+ }
+ _tryPushCurrentPosition(temporary = false) {
+ if (!this._position) {
+ return;
+ }
+ let position = this._position;
+ if (temporary) {
+ position = Object.assign(Object.create(null), this._position);
+ position.temporary = true;
+ }
+ if (!this._destination) {
+ this._pushOrReplaceState(position);
+ return;
+ }
+ if (this._destination.temporary) {
+ this._pushOrReplaceState(position, true);
+ return;
+ }
+ if (this._destination.hash === position.hash) {
+ return;
+ }
+ if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) {
+ return;
+ }
+ let forceReplace = false;
+ if (this._destination.page >= position.first && this._destination.page <= position.page) {
+ if (this._destination.dest !== undefined || !this._destination.first) {
+ return;
+ }
+ forceReplace = true;
+ }
+ this._pushOrReplaceState(position, forceReplace);
+ }
+ _isValidPage(val) {
+ return Number.isInteger(val) && val > 0 && val <= this.linkService.pagesCount;
+ }
+ _isValidState(state, checkReload = false) {
+ if (!state) {
+ return false;
+ }
+ if (state.fingerprint !== this._fingerprint) {
+ if (checkReload) {
+ if (typeof state.fingerprint !== "string" || state.fingerprint.length !== this._fingerprint.length) {
+ return false;
+ }
+ const [perfEntry] = performance.getEntriesByType("navigation");
+ if (perfEntry?.type !== "reload") {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ if (!Number.isInteger(state.uid) || state.uid < 0) {
+ return false;
+ }
+ if (state.destination === null || typeof state.destination !== "object") {
+ return false;
+ }
+ return true;
+ }
+ _updateInternalState(destination, uid, removeTemporary = false) {
+ if (this._updateViewareaTimeout) {
+ clearTimeout(this._updateViewareaTimeout);
+ this._updateViewareaTimeout = null;
+ }
+ if (removeTemporary && destination?.temporary) {
+ delete destination.temporary;
+ }
+ this._destination = destination;
+ this._uid = uid;
+ this._maxUid = Math.max(this._maxUid, uid);
+ this._numPositionUpdates = 0;
+ }
+ _parseCurrentHash(checkNameddest = false) {
+ const hash = unescape(getCurrentHash()).substring(1);
+ const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash);
+ const nameddest = params.get("nameddest") || "";
+ let page = params.get("page") | 0;
+ if (!this._isValidPage(page) || checkNameddest && nameddest.length > 0) {
+ page = null;
+ }
+ return {
+ hash,
+ page,
+ rotation: this.linkService.rotation
+ };
+ }
+ _updateViewarea({
+ location
+ }) {
+ if (this._updateViewareaTimeout) {
+ clearTimeout(this._updateViewareaTimeout);
+ this._updateViewareaTimeout = null;
+ }
+ this._position = {
+ hash: location.pdfOpenParams.substring(1),
+ page: this.linkService.page,
+ first: location.pageNumber,
+ rotation: location.rotation
+ };
+ if (this._popStateInProgress) {
+ return;
+ }
+ if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) {
+ this._numPositionUpdates++;
+ }
+ if (UPDATE_VIEWAREA_TIMEOUT > 0) {
+ this._updateViewareaTimeout = setTimeout(() => {
+ if (!this._popStateInProgress) {
+ this._tryPushCurrentPosition(true);
+ }
+ this._updateViewareaTimeout = null;
+ }, UPDATE_VIEWAREA_TIMEOUT);
+ }
+ }
+ _popState({
+ state
+ }) {
+ const newHash = getCurrentHash(),
+ hashChanged = this._currentHash !== newHash;
+ this._currentHash = newHash;
+ if (!state) {
+ this._uid++;
+ const {
+ hash,
+ page,
+ rotation
+ } = this._parseCurrentHash();
+ this._pushOrReplaceState({
+ hash,
+ page,
+ rotation
+ }, true);
+ return;
+ }
+ if (!this._isValidState(state)) {
+ return;
+ }
+ this._popStateInProgress = true;
+ if (hashChanged) {
+ this._blockHashChange++;
+ (0,_event_utils_js__WEBPACK_IMPORTED_MODULE_1__.waitOnEventOrTimeout)({
+ target: window,
+ name: "hashchange",
+ delay: HASH_CHANGE_TIMEOUT
+ }).then(() => {
+ this._blockHashChange--;
+ });
+ }
+ const destination = state.destination;
+ this._updateInternalState(destination, state.uid, true);
+ if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(destination.rotation)) {
+ this.linkService.rotation = destination.rotation;
+ }
+ if (destination.dest) {
+ this.linkService.goToDestination(destination.dest);
+ } else if (destination.hash) {
+ this.linkService.setHash(destination.hash);
+ } else if (destination.page) {
+ this.linkService.page = destination.page;
+ }
+ Promise.resolve().then(() => {
+ this._popStateInProgress = false;
+ });
+ }
+ _pageHide() {
+ if (!this._destination || this._destination.temporary) {
+ this._tryPushCurrentPosition();
+ }
+ }
+ _bindEvents() {
+ if (this._boundEvents) {
+ return;
+ }
+ this._boundEvents = {
+ updateViewarea: this._updateViewarea.bind(this),
+ popState: this._popState.bind(this),
+ pageHide: this._pageHide.bind(this)
+ };
+ this.eventBus._on("updateviewarea", this._boundEvents.updateViewarea);
+ window.addEventListener("popstate", this._boundEvents.popState);
+ window.addEventListener("pagehide", this._boundEvents.pageHide);
+ }
+ _unbindEvents() {
+ if (!this._boundEvents) {
+ return;
+ }
+ this.eventBus._off("updateviewarea", this._boundEvents.updateViewarea);
+ window.removeEventListener("popstate", this._boundEvents.popState);
+ window.removeEventListener("pagehide", this._boundEvents.pageHide);
+ this._boundEvents = null;
+ }
+}
+function isDestHashesEqual(destHash, pushHash) {
+ if (typeof destHash !== "string" || typeof pushHash !== "string") {
+ return false;
+ }
+ if (destHash === pushHash) {
+ return true;
+ }
+ const nameddest = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(destHash).get("nameddest");
+ if (nameddest === pushHash) {
+ return true;
+ }
+ return false;
+}
+function isDestArraysEqual(firstDest, secondDest) {
+ function isEntryEqual(first, second) {
+ if (typeof first !== typeof second) {
+ return false;
+ }
+ if (Array.isArray(first) || Array.isArray(second)) {
+ return false;
+ }
+ if (first !== null && typeof first === "object" && second !== null) {
+ if (Object.keys(first).length !== Object.keys(second).length) {
+ return false;
+ }
+ for (const key in first) {
+ if (!isEntryEqual(first[key], second[key])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return first === second || Number.isNaN(first) && Number.isNaN(second);
+ }
+ if (!(Array.isArray(firstDest) && Array.isArray(secondDest))) {
+ return false;
+ }
+ if (firstDest.length !== secondDest.length) {
+ return false;
+ }
+ for (let i = 0, ii = firstDest.length; i < ii; i++) {
+ if (!isEntryEqual(firstDest[i], secondDest[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/***/ }),
+
+/***/ 3706:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFLayerViewer: () => (/* binding */ PDFLayerViewer)
+/* harmony export */ });
+/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9415);
+
+class PDFLayerViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__.BaseTreeViewer {
+ constructor(options) {
+ super(options);
+ this.eventBus._on("optionalcontentconfigchanged", evt => {
+ this.#updateLayers(evt.promise);
+ });
+ this.eventBus._on("resetlayers", () => {
+ this.#updateLayers();
+ });
+ this.eventBus._on("togglelayerstree", this._toggleAllTreeItems.bind(this));
+ }
+ reset() {
+ super.reset();
+ this._optionalContentConfig = null;
+ this._optionalContentHash = null;
+ }
+ _dispatchEvent(layersCount) {
+ this.eventBus.dispatch("layersloaded", {
+ source: this,
+ layersCount
+ });
+ }
+ _bindLink(element, {
+ groupId,
+ input
+ }) {
+ const setVisibility = () => {
+ this._optionalContentConfig.setVisibility(groupId, input.checked);
+ this._optionalContentHash = this._optionalContentConfig.getHash();
+ this.eventBus.dispatch("optionalcontentconfig", {
+ source: this,
+ promise: Promise.resolve(this._optionalContentConfig)
+ });
+ };
+ element.onclick = evt => {
+ if (evt.target === input) {
+ setVisibility();
+ return true;
+ } else if (evt.target !== element) {
+ return true;
+ }
+ input.checked = !input.checked;
+ setVisibility();
+ return false;
+ };
+ }
+ async _setNestedName(element, {
+ name = null
+ }) {
+ if (typeof name === "string") {
+ element.textContent = this._normalizeTextContent(name);
+ return;
+ }
+ element.textContent = await this._l10n.get("pdfjs-additional-layers");
+ element.style.fontStyle = "italic";
+ }
+ _addToggleButton(div, {
+ name = null
+ }) {
+ super._addToggleButton(div, name === null);
+ }
+ _toggleAllTreeItems() {
+ if (!this._optionalContentConfig) {
+ return;
+ }
+ super._toggleAllTreeItems();
+ }
+ render({
+ optionalContentConfig,
+ pdfDocument
+ }) {
+ if (this._optionalContentConfig) {
+ this.reset();
+ }
+ this._optionalContentConfig = optionalContentConfig || null;
+ this._pdfDocument = pdfDocument || null;
+ const groups = optionalContentConfig?.getOrder();
+ if (!groups) {
+ this._dispatchEvent(0);
+ return;
+ }
+ this._optionalContentHash = optionalContentConfig.getHash();
+ const fragment = document.createDocumentFragment(),
+ queue = [{
+ parent: fragment,
+ groups
+ }];
+ let layersCount = 0,
+ hasAnyNesting = false;
+ while (queue.length > 0) {
+ const levelData = queue.shift();
+ for (const groupId of levelData.groups) {
+ const div = document.createElement("div");
+ div.className = "treeItem";
+ const element = document.createElement("a");
+ div.append(element);
+ if (typeof groupId === "object") {
+ hasAnyNesting = true;
+ this._addToggleButton(div, groupId);
+ this._setNestedName(element, groupId);
+ const itemsDiv = document.createElement("div");
+ itemsDiv.className = "treeItems";
+ div.append(itemsDiv);
+ queue.push({
+ parent: itemsDiv,
+ groups: groupId.order
+ });
+ } else {
+ const group = optionalContentConfig.getGroup(groupId);
+ const input = document.createElement("input");
+ this._bindLink(element, {
+ groupId,
+ input
+ });
+ input.type = "checkbox";
+ input.checked = group.visible;
+ const label = document.createElement("label");
+ label.textContent = this._normalizeTextContent(group.name);
+ label.append(input);
+ element.append(label);
+ layersCount++;
+ }
+ levelData.parent.append(div);
+ }
+ }
+ this._finishRendering(fragment, layersCount, hasAnyNesting);
+ }
+ async #updateLayers(promise = null) {
+ if (!this._optionalContentConfig) {
+ return;
+ }
+ const pdfDocument = this._pdfDocument;
+ const optionalContentConfig = await (promise || pdfDocument.getOptionalContentConfig());
+ if (pdfDocument !== this._pdfDocument) {
+ return;
+ }
+ if (promise) {
+ if (optionalContentConfig.getHash() === this._optionalContentHash) {
+ return;
+ }
+ } else {
+ this.eventBus.dispatch("optionalcontentconfig", {
+ source: this,
+ promise: Promise.resolve(optionalContentConfig)
+ });
+ }
+ this.render({
+ optionalContentConfig,
+ pdfDocument: this._pdfDocument
+ });
+ }
+}
+
+
+/***/ }),
+
+/***/ 3234:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ LinkTarget: () => (/* binding */ LinkTarget),
+/* harmony export */ PDFLinkService: () => (/* binding */ PDFLinkService),
+/* harmony export */ SimpleLinkService: () => (/* binding */ SimpleLinkService)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+
+const DEFAULT_LINK_REL = "noopener noreferrer nofollow";
+const LinkTarget = {
+ NONE: 0,
+ SELF: 1,
+ BLANK: 2,
+ PARENT: 3,
+ TOP: 4
+};
+function addLinkAttributes(link, {
+ url,
+ target,
+ rel,
+ enabled = true
+} = {}) {
+ if (!url || typeof url !== "string") {
+ throw new Error('A valid "url" parameter must provided.');
+ }
+ if (enabled) {
+ link.href = link.title = url;
+ } else {
+ link.href = "";
+ link.title = `Disabled: ${url}`;
+ link.onclick = () => {
+ return false;
+ };
+ }
+ let targetStr = "";
+ switch (target) {
+ case LinkTarget.NONE:
+ break;
+ case LinkTarget.SELF:
+ targetStr = "_self";
+ break;
+ case LinkTarget.BLANK:
+ targetStr = "_blank";
+ break;
+ case LinkTarget.PARENT:
+ targetStr = "_parent";
+ break;
+ case LinkTarget.TOP:
+ targetStr = "_top";
+ break;
+ }
+ link.target = targetStr;
+ link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
+}
+class PDFLinkService {
+ #pagesRefCache = new Map();
+ constructor({
+ eventBus,
+ externalLinkTarget = null,
+ externalLinkRel = null,
+ ignoreDestinationZoom = false
+ } = {}) {
+ this.eventBus = eventBus;
+ this.externalLinkTarget = externalLinkTarget;
+ this.externalLinkRel = externalLinkRel;
+ this.externalLinkEnabled = true;
+ this._ignoreDestinationZoom = ignoreDestinationZoom;
+ this.baseUrl = null;
+ this.pdfDocument = null;
+ this.pdfViewer = null;
+ this.pdfHistory = null;
+ }
+ setDocument(pdfDocument, baseUrl = null) {
+ this.baseUrl = baseUrl;
+ this.pdfDocument = pdfDocument;
+ this.#pagesRefCache.clear();
+ }
+ setViewer(pdfViewer) {
+ this.pdfViewer = pdfViewer;
+ }
+ setHistory(pdfHistory) {
+ this.pdfHistory = pdfHistory;
+ }
+ get pagesCount() {
+ return this.pdfDocument ? this.pdfDocument.numPages : 0;
+ }
+ get page() {
+ return this.pdfViewer.currentPageNumber;
+ }
+ set page(value) {
+ this.pdfViewer.currentPageNumber = value;
+ }
+ get rotation() {
+ return this.pdfViewer.pagesRotation;
+ }
+ set rotation(value) {
+ this.pdfViewer.pagesRotation = value;
+ }
+ get isInPresentationMode() {
+ return this.pdfViewer.isInPresentationMode;
+ }
+ #goToDestinationHelper(rawDest, namedDest = null, explicitDest) {
+ const destRef = explicitDest[0];
+ let pageNumber;
+ if (typeof destRef === "object" && destRef !== null) {
+ pageNumber = this._cachedPageNumber(destRef);
+ if (!pageNumber) {
+ this.pdfDocument.getPageIndex(destRef).then(pageIndex => {
+ this.cachePageRef(pageIndex + 1, destRef);
+ this.#goToDestinationHelper(rawDest, namedDest, explicitDest);
+ }).catch(() => {
+ console.error(`PDFLinkService.#goToDestinationHelper: "${destRef}" is not ` + `a valid page reference, for dest="${rawDest}".`);
+ });
+ return;
+ }
+ } else if (Number.isInteger(destRef)) {
+ pageNumber = destRef + 1;
+ } else {
+ console.error(`PDFLinkService.#goToDestinationHelper: "${destRef}" is not ` + `a valid destination reference, for dest="${rawDest}".`);
+ return;
+ }
+ if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) {
+ console.error(`PDFLinkService.#goToDestinationHelper: "${pageNumber}" is not ` + `a valid page number, for dest="${rawDest}".`);
+ return;
+ }
+ if (this.pdfHistory) {
+ this.pdfHistory.pushCurrentPosition();
+ this.pdfHistory.push({
+ namedDest,
+ explicitDest,
+ pageNumber
+ });
+ }
+ this.pdfViewer.scrollPageIntoView({
+ pageNumber,
+ destArray: explicitDest,
+ ignoreDestinationZoom: this._ignoreDestinationZoom
+ });
+ }
+ async goToDestination(dest) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ let namedDest, explicitDest;
+ if (typeof dest === "string") {
+ namedDest = dest;
+ explicitDest = await this.pdfDocument.getDestination(dest);
+ } else {
+ namedDest = null;
+ explicitDest = await dest;
+ }
+ if (!Array.isArray(explicitDest)) {
+ console.error(`PDFLinkService.goToDestination: "${explicitDest}" is not ` + `a valid destination array, for dest="${dest}".`);
+ return;
+ }
+ this.#goToDestinationHelper(dest, namedDest, explicitDest);
+ }
+ goToPage(val) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ const pageNumber = typeof val === "string" && this.pdfViewer.pageLabelToPageNumber(val) || val | 0;
+ if (!(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.pagesCount)) {
+ console.error(`PDFLinkService.goToPage: "${val}" is not a valid page.`);
+ return;
+ }
+ if (this.pdfHistory) {
+ this.pdfHistory.pushCurrentPosition();
+ this.pdfHistory.pushPage(pageNumber);
+ }
+ this.pdfViewer.scrollPageIntoView({
+ pageNumber
+ });
+ }
+ addLinkAttributes(link, url, newWindow = false) {
+ addLinkAttributes(link, {
+ url,
+ target: newWindow ? LinkTarget.BLANK : this.externalLinkTarget,
+ rel: this.externalLinkRel,
+ enabled: this.externalLinkEnabled
+ });
+ }
+ getDestinationHash(dest) {
+ if (typeof dest === "string") {
+ if (dest.length > 0) {
+ return this.getAnchorUrl("#" + escape(dest));
+ }
+ } else if (Array.isArray(dest)) {
+ const str = JSON.stringify(dest);
+ if (str.length > 0) {
+ return this.getAnchorUrl("#" + escape(str));
+ }
+ }
+ return this.getAnchorUrl("");
+ }
+ getAnchorUrl(anchor) {
+ return this.baseUrl ? this.baseUrl + anchor : anchor;
+ }
+ setHash(hash) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ let pageNumber, dest;
+ if (hash.includes("=")) {
+ const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash);
+ if (params.has("search")) {
+ const query = params.get("search").replaceAll('"', ""),
+ phrase = params.get("phrase") === "true";
+ this.eventBus.dispatch("findfromurlhash", {
+ source: this,
+ query: phrase ? query : query.match(/\S+/g)
+ });
+ }
+ if (params.has("page")) {
+ pageNumber = params.get("page") | 0 || 1;
+ }
+ if (params.has("zoom")) {
+ const zoomArgs = params.get("zoom").split(",");
+ const zoomArg = zoomArgs[0];
+ const zoomArgNumber = parseFloat(zoomArg);
+ if (!zoomArg.includes("Fit")) {
+ dest = [null, {
+ name: "XYZ"
+ }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg];
+ } else if (zoomArg === "Fit" || zoomArg === "FitB") {
+ dest = [null, {
+ name: zoomArg
+ }];
+ } else if (zoomArg === "FitH" || zoomArg === "FitBH" || zoomArg === "FitV" || zoomArg === "FitBV") {
+ dest = [null, {
+ name: zoomArg
+ }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null];
+ } else if (zoomArg === "FitR") {
+ if (zoomArgs.length !== 5) {
+ console.error('PDFLinkService.setHash: Not enough parameters for "FitR".');
+ } else {
+ dest = [null, {
+ name: zoomArg
+ }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0];
+ }
+ } else {
+ console.error(`PDFLinkService.setHash: "${zoomArg}" is not a valid zoom value.`);
+ }
+ }
+ if (dest) {
+ this.pdfViewer.scrollPageIntoView({
+ pageNumber: pageNumber || this.page,
+ destArray: dest,
+ allowNegativeOffset: true
+ });
+ } else if (pageNumber) {
+ this.page = pageNumber;
+ }
+ if (params.has("pagemode")) {
+ this.eventBus.dispatch("pagemode", {
+ source: this,
+ mode: params.get("pagemode")
+ });
+ }
+ if (params.has("nameddest")) {
+ this.goToDestination(params.get("nameddest"));
+ }
+ return;
+ }
+ dest = unescape(hash);
+ try {
+ dest = JSON.parse(dest);
+ if (!Array.isArray(dest)) {
+ dest = dest.toString();
+ }
+ } catch {}
+ if (typeof dest === "string" || PDFLinkService.#isValidExplicitDestination(dest)) {
+ this.goToDestination(dest);
+ return;
+ }
+ console.error(`PDFLinkService.setHash: "${unescape(hash)}" is not a valid destination.`);
+ }
+ executeNamedAction(action) {
+ switch (action) {
+ case "GoBack":
+ this.pdfHistory?.back();
+ break;
+ case "GoForward":
+ this.pdfHistory?.forward();
+ break;
+ case "NextPage":
+ this.pdfViewer.nextPage();
+ break;
+ case "PrevPage":
+ this.pdfViewer.previousPage();
+ break;
+ case "LastPage":
+ this.page = this.pagesCount;
+ break;
+ case "FirstPage":
+ this.page = 1;
+ break;
+ default:
+ break;
+ }
+ this.eventBus.dispatch("namedaction", {
+ source: this,
+ action
+ });
+ }
+ async executeSetOCGState(action) {
+ const pdfDocument = this.pdfDocument;
+ const optionalContentConfig = await this.pdfViewer.optionalContentConfigPromise;
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ let operator;
+ for (const elem of action.state) {
+ switch (elem) {
+ case "ON":
+ case "OFF":
+ case "Toggle":
+ operator = elem;
+ continue;
+ }
+ switch (operator) {
+ case "ON":
+ optionalContentConfig.setVisibility(elem, true);
+ break;
+ case "OFF":
+ optionalContentConfig.setVisibility(elem, false);
+ break;
+ case "Toggle":
+ const group = optionalContentConfig.getGroup(elem);
+ if (group) {
+ optionalContentConfig.setVisibility(elem, !group.visible);
+ }
+ break;
+ }
+ }
+ this.pdfViewer.optionalContentConfigPromise = Promise.resolve(optionalContentConfig);
+ }
+ cachePageRef(pageNum, pageRef) {
+ if (!pageRef) {
+ return;
+ }
+ const refStr = pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`;
+ this.#pagesRefCache.set(refStr, pageNum);
+ }
+ _cachedPageNumber(pageRef) {
+ if (!pageRef) {
+ return null;
+ }
+ const refStr = pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`;
+ return this.#pagesRefCache.get(refStr) || null;
+ }
+ static #isValidExplicitDestination(dest) {
+ if (!Array.isArray(dest)) {
+ return false;
+ }
+ const destLength = dest.length;
+ if (destLength < 2) {
+ return false;
+ }
+ const page = dest[0];
+ if (!(typeof page === "object" && Number.isInteger(page.num) && Number.isInteger(page.gen)) && !(Number.isInteger(page) && page >= 0)) {
+ return false;
+ }
+ const zoom = dest[1];
+ if (!(typeof zoom === "object" && typeof zoom.name === "string")) {
+ return false;
+ }
+ let allowNull = true;
+ switch (zoom.name) {
+ case "XYZ":
+ if (destLength !== 5) {
+ return false;
+ }
+ break;
+ case "Fit":
+ case "FitB":
+ return destLength === 2;
+ case "FitH":
+ case "FitBH":
+ case "FitV":
+ case "FitBV":
+ if (destLength !== 3) {
+ return false;
+ }
+ break;
+ case "FitR":
+ if (destLength !== 6) {
+ return false;
+ }
+ allowNull = false;
+ break;
+ default:
+ return false;
+ }
+ for (let i = 2; i < destLength; i++) {
+ const param = dest[i];
+ if (!(typeof param === "number" || allowNull && param === null)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+class SimpleLinkService {
+ constructor() {
+ this.externalLinkEnabled = true;
+ }
+ get pagesCount() {
+ return 0;
+ }
+ get page() {
+ return 0;
+ }
+ set page(value) {}
+ get rotation() {
+ return 0;
+ }
+ set rotation(value) {}
+ get isInPresentationMode() {
+ return false;
+ }
+ async goToDestination(dest) {}
+ goToPage(val) {}
+ addLinkAttributes(link, url, newWindow = false) {
+ addLinkAttributes(link, {
+ url,
+ enabled: this.externalLinkEnabled
+ });
+ }
+ getDestinationHash(dest) {
+ return "#";
+ }
+ getAnchorUrl(hash) {
+ return "#";
+ }
+ setHash(hash) {}
+ executeNamedAction(action) {}
+ executeSetOCGState(action) {}
+ cachePageRef(pageNum, pageRef) {}
+}
+
+
+/***/ }),
+
+/***/ 1141:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFOutlineViewer: () => (/* binding */ PDFOutlineViewer)
+/* harmony export */ });
+/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9415);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+
+class PDFOutlineViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__.BaseTreeViewer {
+ constructor(options) {
+ super(options);
+ this.linkService = options.linkService;
+ this.downloadManager = options.downloadManager;
+ this.eventBus._on("toggleoutlinetree", this._toggleAllTreeItems.bind(this));
+ this.eventBus._on("currentoutlineitem", this._currentOutlineItem.bind(this));
+ this.eventBus._on("pagechanging", evt => {
+ this._currentPageNumber = evt.pageNumber;
+ });
+ this.eventBus._on("pagesloaded", evt => {
+ this._isPagesLoaded = !!evt.pagesCount;
+ if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) {
+ this._currentOutlineItemCapability.resolve(this._isPagesLoaded);
+ }
+ });
+ this.eventBus._on("sidebarviewchanged", evt => {
+ this._sidebarView = evt.view;
+ });
+ }
+ reset() {
+ super.reset();
+ this._outline = null;
+ this._pageNumberToDestHashCapability = null;
+ this._currentPageNumber = 1;
+ this._isPagesLoaded = null;
+ if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) {
+ this._currentOutlineItemCapability.resolve(false);
+ }
+ this._currentOutlineItemCapability = null;
+ }
+ _dispatchEvent(outlineCount) {
+ this._currentOutlineItemCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ if (outlineCount === 0 || this._pdfDocument?.loadingParams.disableAutoFetch) {
+ this._currentOutlineItemCapability.resolve(false);
+ } else if (this._isPagesLoaded !== null) {
+ this._currentOutlineItemCapability.resolve(this._isPagesLoaded);
+ }
+ this.eventBus.dispatch("outlineloaded", {
+ source: this,
+ outlineCount,
+ currentOutlineItemPromise: this._currentOutlineItemCapability.promise
+ });
+ }
+ _bindLink(element, {
+ url,
+ newWindow,
+ action,
+ attachment,
+ dest,
+ setOCGState
+ }) {
+ const {
+ linkService
+ } = this;
+ if (url) {
+ linkService.addLinkAttributes(element, url, newWindow);
+ return;
+ }
+ if (action) {
+ element.href = linkService.getAnchorUrl("");
+ element.onclick = () => {
+ linkService.executeNamedAction(action);
+ return false;
+ };
+ return;
+ }
+ if (attachment) {
+ element.href = linkService.getAnchorUrl("");
+ element.onclick = () => {
+ this.downloadManager.openOrDownloadData(attachment.content, attachment.filename);
+ return false;
+ };
+ return;
+ }
+ if (setOCGState) {
+ element.href = linkService.getAnchorUrl("");
+ element.onclick = () => {
+ linkService.executeSetOCGState(setOCGState);
+ return false;
+ };
+ return;
+ }
+ element.href = linkService.getDestinationHash(dest);
+ element.onclick = evt => {
+ this._updateCurrentTreeItem(evt.target.parentNode);
+ if (dest) {
+ linkService.goToDestination(dest);
+ }
+ return false;
+ };
+ }
+ _setStyles(element, {
+ bold,
+ italic
+ }) {
+ if (bold) {
+ element.style.fontWeight = "bold";
+ }
+ if (italic) {
+ element.style.fontStyle = "italic";
+ }
+ }
+ _addToggleButton(div, {
+ count,
+ items
+ }) {
+ let hidden = false;
+ if (count < 0) {
+ let totalCount = items.length;
+ if (totalCount > 0) {
+ const queue = [...items];
+ while (queue.length > 0) {
+ const {
+ count: nestedCount,
+ items: nestedItems
+ } = queue.shift();
+ if (nestedCount > 0 && nestedItems.length > 0) {
+ totalCount += nestedItems.length;
+ queue.push(...nestedItems);
+ }
+ }
+ }
+ if (Math.abs(count) === totalCount) {
+ hidden = true;
+ }
+ }
+ super._addToggleButton(div, hidden);
+ }
+ _toggleAllTreeItems() {
+ if (!this._outline) {
+ return;
+ }
+ super._toggleAllTreeItems();
+ }
+ render({
+ outline,
+ pdfDocument
+ }) {
+ if (this._outline) {
+ this.reset();
+ }
+ this._outline = outline || null;
+ this._pdfDocument = pdfDocument || null;
+ if (!outline) {
+ this._dispatchEvent(0);
+ return;
+ }
+ const fragment = document.createDocumentFragment();
+ const queue = [{
+ parent: fragment,
+ items: outline
+ }];
+ let outlineCount = 0,
+ hasAnyNesting = false;
+ while (queue.length > 0) {
+ const levelData = queue.shift();
+ for (const item of levelData.items) {
+ const div = document.createElement("div");
+ div.className = "treeItem";
+ const element = document.createElement("a");
+ this._bindLink(element, item);
+ this._setStyles(element, item);
+ element.textContent = this._normalizeTextContent(item.title);
+ div.append(element);
+ if (item.items.length > 0) {
+ hasAnyNesting = true;
+ this._addToggleButton(div, item);
+ const itemsDiv = document.createElement("div");
+ itemsDiv.className = "treeItems";
+ div.append(itemsDiv);
+ queue.push({
+ parent: itemsDiv,
+ items: item.items
+ });
+ }
+ levelData.parent.append(div);
+ outlineCount++;
+ }
+ }
+ this._finishRendering(fragment, outlineCount, hasAnyNesting);
+ }
+ async _currentOutlineItem() {
+ if (!this._isPagesLoaded) {
+ throw new Error("_currentOutlineItem: All pages have not been loaded.");
+ }
+ if (!this._outline || !this._pdfDocument) {
+ return;
+ }
+ const pageNumberToDestHash = await this._getPageNumberToDestHash(this._pdfDocument);
+ if (!pageNumberToDestHash) {
+ return;
+ }
+ this._updateCurrentTreeItem(null);
+ if (this._sidebarView !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.SidebarView.OUTLINE) {
+ return;
+ }
+ for (let i = this._currentPageNumber; i > 0; i--) {
+ const destHash = pageNumberToDestHash.get(i);
+ if (!destHash) {
+ continue;
+ }
+ const linkElement = this.container.querySelector(`a[href="${destHash}"]`);
+ if (!linkElement) {
+ continue;
+ }
+ this._scrollToCurrentTreeItem(linkElement.parentNode);
+ break;
+ }
+ }
+ async _getPageNumberToDestHash(pdfDocument) {
+ if (this._pageNumberToDestHashCapability) {
+ return this._pageNumberToDestHashCapability.promise;
+ }
+ this._pageNumberToDestHashCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ const pageNumberToDestHash = new Map(),
+ pageNumberNesting = new Map();
+ const queue = [{
+ nesting: 0,
+ items: this._outline
+ }];
+ while (queue.length > 0) {
+ const levelData = queue.shift(),
+ currentNesting = levelData.nesting;
+ for (const {
+ dest,
+ items
+ } of levelData.items) {
+ let explicitDest, pageNumber;
+ if (typeof dest === "string") {
+ explicitDest = await pdfDocument.getDestination(dest);
+ if (pdfDocument !== this._pdfDocument) {
+ return null;
+ }
+ } else {
+ explicitDest = dest;
+ }
+ if (Array.isArray(explicitDest)) {
+ const [destRef] = explicitDest;
+ if (typeof destRef === "object" && destRef !== null) {
+ pageNumber = this.linkService._cachedPageNumber(destRef);
+ if (!pageNumber) {
+ try {
+ pageNumber = (await pdfDocument.getPageIndex(destRef)) + 1;
+ if (pdfDocument !== this._pdfDocument) {
+ return null;
+ }
+ this.linkService.cachePageRef(pageNumber, destRef);
+ } catch {}
+ }
+ } else if (Number.isInteger(destRef)) {
+ pageNumber = destRef + 1;
+ }
+ if (Number.isInteger(pageNumber) && (!pageNumberToDestHash.has(pageNumber) || currentNesting > pageNumberNesting.get(pageNumber))) {
+ const destHash = this.linkService.getDestinationHash(dest);
+ pageNumberToDestHash.set(pageNumber, destHash);
+ pageNumberNesting.set(pageNumber, currentNesting);
+ }
+ }
+ if (items.length > 0) {
+ queue.push({
+ nesting: currentNesting + 1,
+ items
+ });
+ }
+ }
+ }
+ this._pageNumberToDestHashCapability.resolve(pageNumberToDestHash.size > 0 ? pageNumberToDestHash : null);
+ return this._pageNumberToDestHashCapability.promise;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 6732:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFPageView: () => (/* binding */ PDFPageView)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+/* harmony import */ var _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2640);
+/* harmony import */ var _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6735);
+/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8961);
+/* harmony import */ var _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(758);
+/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7910);
+/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3234);
+/* harmony import */ var _struct_tree_layer_builder_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(7498);
+/* harmony import */ var _text_accessibility_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(4630);
+/* harmony import */ var _text_highlighter_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(4274);
+/* harmony import */ var _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1013);
+/* harmony import */ var _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8012);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__, _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__, _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__, _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__, _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__, _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__, _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+
+
+
+
+
+
+
+
+
+
+const MAX_CANVAS_PIXELS = _app_options_js__WEBPACK_IMPORTED_MODULE_4__.compatibilityParams.maxCanvasPixels || 16777216;
+const DEFAULT_LAYER_PROPERTIES = null;
+class PDFPageView {
+ #annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS;
+ #hasRestrictedScaling = false;
+ #layerProperties = null;
+ #loadingId = null;
+ #previousRotation = null;
+ #renderError = null;
+ #renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL;
+ #textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE;
+ #useThumbnailCanvas = {
+ directDrawing: true,
+ initialOptionalContent: true,
+ regularAnnotations: true
+ };
+ #viewportMap = new WeakMap();
+ constructor(options) {
+ const container = options.container;
+ const defaultViewport = options.defaultViewport;
+ this.id = options.id;
+ this.renderingId = "page" + this.id;
+ this.#layerProperties = options.layerProperties || DEFAULT_LAYER_PROPERTIES;
+ this.pdfPage = null;
+ this.pageLabel = null;
+ this.rotation = 0;
+ this.scale = options.scale || _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE;
+ this.viewport = defaultViewport;
+ this.pdfPageRotate = defaultViewport.rotation;
+ this._optionalContentConfigPromise = options.optionalContentConfigPromise || null;
+ this.#textLayerMode = options.textLayerMode ?? _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE;
+ this.#annotationMode = options.annotationMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS;
+ this.imageResourcesPath = options.imageResourcesPath || "";
+ this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true;
+ this.maxCanvasPixels = options.maxCanvasPixels ?? MAX_CANVAS_PIXELS;
+ this.pageColors = options.pageColors || null;
+ this.eventBus = options.eventBus;
+ this.renderingQueue = options.renderingQueue;
+ this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__.NullL10n;
+ this.renderTask = null;
+ this.resume = null;
+ this._isStandalone = !this.renderingQueue?.hasViewer();
+ this._container = container;
+ this._annotationCanvasMap = null;
+ this.annotationLayer = null;
+ this.annotationEditorLayer = null;
+ this.textLayer = null;
+ this.zoomLayer = null;
+ this.xfaLayer = null;
+ this.structTreeLayer = null;
+ this.drawLayer = null;
+ const div = document.createElement("div");
+ div.className = "page";
+ div.setAttribute("data-page-number", this.id);
+ div.setAttribute("role", "region");
+ div.setAttribute("data-l10n-id", "pdfjs-page-landmark");
+ div.setAttribute("data-l10n-args", JSON.stringify({
+ page: this.id
+ }));
+ this.div = div;
+ this.#setDimensions();
+ container?.append(div);
+ if (this._isStandalone) {
+ container?.style.setProperty("--scale-factor", this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS);
+ const {
+ optionalContentConfigPromise
+ } = options;
+ if (optionalContentConfigPromise) {
+ optionalContentConfigPromise.then(optionalContentConfig => {
+ if (optionalContentConfigPromise !== this._optionalContentConfigPromise) {
+ return;
+ }
+ this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility;
+ });
+ }
+ if (this.l10n === web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__.NullL10n) {
+ this.l10n.translate(this.div);
+ }
+ }
+ }
+ get renderingState() {
+ return this.#renderingState;
+ }
+ set renderingState(state) {
+ if (state === this.#renderingState) {
+ return;
+ }
+ this.#renderingState = state;
+ if (this.#loadingId) {
+ clearTimeout(this.#loadingId);
+ this.#loadingId = null;
+ }
+ switch (state) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED:
+ this.div.classList.remove("loading");
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING:
+ this.div.classList.add("loadingIcon");
+ this.#loadingId = setTimeout(() => {
+ this.div.classList.add("loading");
+ this.#loadingId = null;
+ }, 0);
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL:
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED:
+ this.div.classList.remove("loadingIcon", "loading");
+ break;
+ }
+ }
+ #setDimensions() {
+ const {
+ viewport
+ } = this;
+ if (this.pdfPage) {
+ if (this.#previousRotation === viewport.rotation) {
+ return;
+ }
+ this.#previousRotation = viewport.rotation;
+ }
+ (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.setLayerDimensions)(this.div, viewport, true, false);
+ }
+ setPdfPage(pdfPage) {
+ if (this._isStandalone && (this.pageColors?.foreground === "CanvasText" || this.pageColors?.background === "Canvas")) {
+ this._container?.style.setProperty("--hcm-highlight-filter", pdfPage.filterFactory.addHighlightHCMFilter("CanvasText", "Canvas", "HighlightText", "Highlight"));
+ }
+ this.pdfPage = pdfPage;
+ this.pdfPageRotate = pdfPage.rotate;
+ const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = pdfPage.getViewport({
+ scale: this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS,
+ rotation: totalRotation
+ });
+ this.#setDimensions();
+ this.reset();
+ }
+ destroy() {
+ this.reset();
+ this.pdfPage?.cleanup();
+ }
+ get _textHighlighter() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_textHighlighter", new _text_highlighter_js__WEBPACK_IMPORTED_MODULE_12__.TextHighlighter({
+ pageIndex: this.id - 1,
+ eventBus: this.eventBus,
+ findController: this.#layerProperties.findController
+ }));
+ }
+ async #renderAnnotationLayer() {
+ let error = null;
+ try {
+ await this.annotationLayer.render(this.viewport, "display");
+ } catch (ex) {
+ console.error(`#renderAnnotationLayer: "${ex}".`);
+ error = ex;
+ } finally {
+ this.eventBus.dispatch("annotationlayerrendered", {
+ source: this,
+ pageNumber: this.id,
+ error
+ });
+ }
+ }
+ async #renderAnnotationEditorLayer() {
+ let error = null;
+ try {
+ await this.annotationEditorLayer.render(this.viewport, "display");
+ } catch (ex) {
+ console.error(`#renderAnnotationEditorLayer: "${ex}".`);
+ error = ex;
+ } finally {
+ this.eventBus.dispatch("annotationeditorlayerrendered", {
+ source: this,
+ pageNumber: this.id,
+ error
+ });
+ }
+ }
+ async #renderDrawLayer() {
+ try {
+ await this.drawLayer.render("display");
+ } catch (ex) {
+ console.error(`#renderDrawLayer: "${ex}".`);
+ }
+ }
+ async #renderXfaLayer() {
+ let error = null;
+ try {
+ const result = await this.xfaLayer.render(this.viewport, "display");
+ if (result?.textDivs && this._textHighlighter) {
+ this.#buildXfaTextContentItems(result.textDivs);
+ }
+ } catch (ex) {
+ console.error(`#renderXfaLayer: "${ex}".`);
+ error = ex;
+ } finally {
+ if (this.xfaLayer?.div) {
+ this.l10n.pause();
+ this.div.append(this.xfaLayer.div);
+ this.l10n.resume();
+ }
+ this.eventBus.dispatch("xfalayerrendered", {
+ source: this,
+ pageNumber: this.id,
+ error
+ });
+ }
+ }
+ async #renderTextLayer() {
+ const {
+ pdfPage,
+ textLayer,
+ viewport
+ } = this;
+ if (!textLayer) {
+ return;
+ }
+ let error = null;
+ try {
+ if (!textLayer.renderingDone) {
+ const readableStream = pdfPage.streamTextContent({
+ includeMarkedContent: true,
+ disableNormalization: true
+ });
+ textLayer.setTextContentSource(readableStream);
+ }
+ await textLayer.render(viewport);
+ } catch (ex) {
+ if (ex instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AbortException) {
+ return;
+ }
+ console.error(`#renderTextLayer: "${ex}".`);
+ error = ex;
+ }
+ this.eventBus.dispatch("textlayerrendered", {
+ source: this,
+ pageNumber: this.id,
+ numTextDivs: textLayer.numTextDivs,
+ error
+ });
+ this.#renderStructTreeLayer();
+ }
+ async #renderStructTreeLayer() {
+ if (!this.textLayer) {
+ return;
+ }
+ this.structTreeLayer ||= new _struct_tree_layer_builder_js__WEBPACK_IMPORTED_MODULE_8__.StructTreeLayerBuilder();
+ const tree = await (!this.structTreeLayer.renderingDone ? this.pdfPage.getStructTree() : null);
+ const treeDom = this.structTreeLayer?.render(tree);
+ if (treeDom) {
+ this.l10n.pause();
+ this.canvas?.append(treeDom);
+ this.l10n.resume();
+ }
+ this.structTreeLayer?.show();
+ }
+ async #buildXfaTextContentItems(textDivs) {
+ const text = await this.pdfPage.getTextContent();
+ const items = [];
+ for (const item of text.items) {
+ items.push(item.str);
+ }
+ this._textHighlighter.setTextMapping(textDivs, items);
+ this._textHighlighter.enable();
+ }
+ _resetZoomLayer(removeFromDOM = false) {
+ if (!this.zoomLayer) {
+ return;
+ }
+ const zoomLayerCanvas = this.zoomLayer.firstChild;
+ this.#viewportMap.delete(zoomLayerCanvas);
+ zoomLayerCanvas.width = 0;
+ zoomLayerCanvas.height = 0;
+ if (removeFromDOM) {
+ this.zoomLayer.remove();
+ }
+ this.zoomLayer = null;
+ }
+ reset({
+ keepZoomLayer = false,
+ keepAnnotationLayer = false,
+ keepAnnotationEditorLayer = false,
+ keepXfaLayer = false,
+ keepTextLayer = false
+ } = {}) {
+ this.cancelRendering({
+ keepAnnotationLayer,
+ keepAnnotationEditorLayer,
+ keepXfaLayer,
+ keepTextLayer
+ });
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL;
+ const div = this.div;
+ const childNodes = div.childNodes,
+ zoomLayerNode = keepZoomLayer && this.zoomLayer || null,
+ annotationLayerNode = keepAnnotationLayer && this.annotationLayer?.div || null,
+ annotationEditorLayerNode = keepAnnotationEditorLayer && this.annotationEditorLayer?.div || null,
+ xfaLayerNode = keepXfaLayer && this.xfaLayer?.div || null,
+ textLayerNode = keepTextLayer && this.textLayer?.div || null;
+ for (let i = childNodes.length - 1; i >= 0; i--) {
+ const node = childNodes[i];
+ switch (node) {
+ case zoomLayerNode:
+ case annotationLayerNode:
+ case annotationEditorLayerNode:
+ case xfaLayerNode:
+ case textLayerNode:
+ continue;
+ }
+ node.remove();
+ }
+ div.removeAttribute("data-loaded");
+ if (annotationLayerNode) {
+ this.annotationLayer.hide();
+ }
+ if (annotationEditorLayerNode) {
+ this.annotationEditorLayer.hide();
+ }
+ if (xfaLayerNode) {
+ this.xfaLayer.hide();
+ }
+ if (textLayerNode) {
+ this.textLayer.hide();
+ }
+ this.structTreeLayer?.hide();
+ if (!zoomLayerNode) {
+ if (this.canvas) {
+ this.#viewportMap.delete(this.canvas);
+ this.canvas.width = 0;
+ this.canvas.height = 0;
+ delete this.canvas;
+ }
+ this._resetZoomLayer();
+ }
+ }
+ update({
+ scale = 0,
+ rotation = null,
+ optionalContentConfigPromise = null,
+ drawingDelay = -1
+ }) {
+ this.scale = scale || this.scale;
+ if (typeof rotation === "number") {
+ this.rotation = rotation;
+ }
+ if (optionalContentConfigPromise instanceof Promise) {
+ this._optionalContentConfigPromise = optionalContentConfigPromise;
+ optionalContentConfigPromise.then(optionalContentConfig => {
+ if (optionalContentConfigPromise !== this._optionalContentConfigPromise) {
+ return;
+ }
+ this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility;
+ });
+ }
+ this.#useThumbnailCanvas.directDrawing = true;
+ const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = this.viewport.clone({
+ scale: this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS,
+ rotation: totalRotation
+ });
+ this.#setDimensions();
+ if (this._isStandalone) {
+ this._container?.style.setProperty("--scale-factor", this.viewport.scale);
+ }
+ if (this.canvas) {
+ let onlyCssZoom = false;
+ if (this.#hasRestrictedScaling) {
+ if (this.maxCanvasPixels === 0) {
+ onlyCssZoom = true;
+ } else if (this.maxCanvasPixels > 0) {
+ const {
+ width,
+ height
+ } = this.viewport;
+ const {
+ sx,
+ sy
+ } = this.outputScale;
+ onlyCssZoom = (Math.floor(width) * sx | 0) * (Math.floor(height) * sy | 0) > this.maxCanvasPixels;
+ }
+ }
+ const postponeDrawing = !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000;
+ if (postponeDrawing || onlyCssZoom) {
+ if (postponeDrawing && this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED) {
+ this.cancelRendering({
+ keepZoomLayer: true,
+ keepAnnotationLayer: true,
+ keepAnnotationEditorLayer: true,
+ keepXfaLayer: true,
+ keepTextLayer: true,
+ cancelExtraDelay: drawingDelay
+ });
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED;
+ this.#useThumbnailCanvas.directDrawing = false;
+ }
+ this.cssTransform({
+ target: this.canvas,
+ redrawAnnotationLayer: true,
+ redrawAnnotationEditorLayer: true,
+ redrawXfaLayer: true,
+ redrawTextLayer: !postponeDrawing,
+ hideTextLayer: postponeDrawing
+ });
+ if (postponeDrawing) {
+ return;
+ }
+ this.eventBus.dispatch("pagerendered", {
+ source: this,
+ pageNumber: this.id,
+ cssTransform: true,
+ timestamp: performance.now(),
+ error: this.#renderError
+ });
+ return;
+ }
+ if (!this.zoomLayer && !this.canvas.hidden) {
+ this.zoomLayer = this.canvas.parentNode;
+ this.zoomLayer.style.position = "absolute";
+ }
+ }
+ if (this.zoomLayer) {
+ this.cssTransform({
+ target: this.zoomLayer.firstChild
+ });
+ }
+ this.reset({
+ keepZoomLayer: true,
+ keepAnnotationLayer: true,
+ keepAnnotationEditorLayer: true,
+ keepXfaLayer: true,
+ keepTextLayer: true
+ });
+ }
+ cancelRendering({
+ keepAnnotationLayer = false,
+ keepAnnotationEditorLayer = false,
+ keepXfaLayer = false,
+ keepTextLayer = false,
+ cancelExtraDelay = 0
+ } = {}) {
+ if (this.renderTask) {
+ this.renderTask.cancel(cancelExtraDelay);
+ this.renderTask = null;
+ }
+ this.resume = null;
+ if (this.textLayer && (!keepTextLayer || !this.textLayer.div)) {
+ this.textLayer.cancel();
+ this.textLayer = null;
+ }
+ if (this.structTreeLayer && !this.textLayer) {
+ this.structTreeLayer = null;
+ }
+ if (this.annotationLayer && (!keepAnnotationLayer || !this.annotationLayer.div)) {
+ this.annotationLayer.cancel();
+ this.annotationLayer = null;
+ this._annotationCanvasMap = null;
+ }
+ if (this.annotationEditorLayer && (!keepAnnotationEditorLayer || !this.annotationEditorLayer.div)) {
+ if (this.drawLayer) {
+ this.drawLayer.cancel();
+ this.drawLayer = null;
+ }
+ this.annotationEditorLayer.cancel();
+ this.annotationEditorLayer = null;
+ }
+ if (this.xfaLayer && (!keepXfaLayer || !this.xfaLayer.div)) {
+ this.xfaLayer.cancel();
+ this.xfaLayer = null;
+ this._textHighlighter?.disable();
+ }
+ }
+ cssTransform({
+ target,
+ redrawAnnotationLayer = false,
+ redrawAnnotationEditorLayer = false,
+ redrawXfaLayer = false,
+ redrawTextLayer = false,
+ hideTextLayer = false
+ }) {
+ if (!target.hasAttribute("zooming")) {
+ target.setAttribute("zooming", true);
+ const {
+ style
+ } = target;
+ style.width = style.height = "";
+ }
+ const originalViewport = this.#viewportMap.get(target);
+ if (this.viewport !== originalViewport) {
+ const relativeRotation = this.viewport.rotation - originalViewport.rotation;
+ const absRotation = Math.abs(relativeRotation);
+ let scaleX = 1,
+ scaleY = 1;
+ if (absRotation === 90 || absRotation === 270) {
+ const {
+ width,
+ height
+ } = this.viewport;
+ scaleX = height / width;
+ scaleY = width / height;
+ }
+ target.style.transform = `rotate(${relativeRotation}deg) scale(${scaleX}, ${scaleY})`;
+ }
+ if (redrawAnnotationLayer && this.annotationLayer) {
+ this.#renderAnnotationLayer();
+ }
+ if (redrawAnnotationEditorLayer && this.annotationEditorLayer) {
+ if (this.drawLayer) {
+ this.#renderDrawLayer();
+ }
+ this.#renderAnnotationEditorLayer();
+ }
+ if (redrawXfaLayer && this.xfaLayer) {
+ this.#renderXfaLayer();
+ }
+ if (this.textLayer) {
+ if (hideTextLayer) {
+ this.textLayer.hide();
+ this.structTreeLayer?.hide();
+ } else if (redrawTextLayer) {
+ this.#renderTextLayer();
+ }
+ }
+ }
+ get width() {
+ return this.viewport.width;
+ }
+ get height() {
+ return this.viewport.height;
+ }
+ getPagePoint(x, y) {
+ return this.viewport.convertToPdfPoint(x, y);
+ }
+ async #finishRenderTask(renderTask, error = null) {
+ if (renderTask === this.renderTask) {
+ this.renderTask = null;
+ }
+ if (error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException) {
+ this.#renderError = null;
+ return;
+ }
+ this.#renderError = error;
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED;
+ this._resetZoomLayer(true);
+ this.#useThumbnailCanvas.regularAnnotations = !renderTask.separateAnnots;
+ this.eventBus.dispatch("pagerendered", {
+ source: this,
+ pageNumber: this.id,
+ cssTransform: false,
+ timestamp: performance.now(),
+ error: this.#renderError
+ });
+ if (error) {
+ throw error;
+ }
+ }
+ async draw() {
+ if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL) {
+ console.error("Must be in new state before drawing");
+ this.reset();
+ }
+ const {
+ div,
+ l10n,
+ pageColors,
+ pdfPage,
+ viewport
+ } = this;
+ if (!pdfPage) {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED;
+ throw new Error("pdfPage is not loaded");
+ }
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING;
+ const canvasWrapper = document.createElement("div");
+ canvasWrapper.classList.add("canvasWrapper");
+ div.append(canvasWrapper);
+ if (!this.textLayer && this.#textLayerMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.DISABLE && !pdfPage.isPureXfa) {
+ this._accessibilityManager ||= new _text_accessibility_js__WEBPACK_IMPORTED_MODULE_9__.TextAccessibilityManager();
+ this.textLayer = new _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__.TextLayerBuilder({
+ highlighter: this._textHighlighter,
+ accessibilityManager: this._accessibilityManager,
+ isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
+ enablePermissions: this.#textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS
+ });
+ this.textLayer.onAppend = textLayerDiv => {
+ this.l10n.pause();
+ this.div.append(textLayerDiv);
+ this.l10n.resume();
+ };
+ }
+ if (!this.annotationLayer && this.#annotationMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.DISABLE) {
+ const {
+ annotationStorage,
+ downloadManager,
+ enableScripting,
+ fieldObjectsPromise,
+ hasJSActionsPromise,
+ linkService
+ } = this.#layerProperties;
+ this._annotationCanvasMap ||= new Map();
+ this.annotationLayer = new _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__.AnnotationLayerBuilder({
+ pageDiv: div,
+ pdfPage,
+ annotationStorage,
+ imageResourcesPath: this.imageResourcesPath,
+ renderForms: this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS,
+ linkService,
+ downloadManager,
+ enableScripting,
+ hasJSActionsPromise,
+ fieldObjectsPromise,
+ annotationCanvasMap: this._annotationCanvasMap,
+ accessibilityManager: this._accessibilityManager
+ });
+ }
+ const renderContinueCallback = cont => {
+ showCanvas?.(false);
+ if (this.renderingQueue && !this.renderingQueue.isHighestPriority(this)) {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED;
+ this.resume = () => {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING;
+ cont();
+ };
+ return;
+ }
+ cont();
+ };
+ const {
+ width,
+ height
+ } = viewport;
+ const canvas = document.createElement("canvas");
+ canvas.setAttribute("role", "presentation");
+ canvas.hidden = true;
+ const hasHCM = !!(pageColors?.background && pageColors?.foreground);
+ let showCanvas = isLastShow => {
+ if (!hasHCM || isLastShow) {
+ canvas.hidden = false;
+ showCanvas = null;
+ }
+ };
+ canvasWrapper.append(canvas);
+ this.canvas = canvas;
+ const ctx = canvas.getContext("2d", {
+ alpha: false
+ });
+ const outputScale = this.outputScale = new _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.OutputScale();
+ if (this.maxCanvasPixels === 0) {
+ const invScale = 1 / this.scale;
+ outputScale.sx *= invScale;
+ outputScale.sy *= invScale;
+ this.#hasRestrictedScaling = true;
+ } else if (this.maxCanvasPixels > 0) {
+ const pixelsInViewport = width * height;
+ const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
+ if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
+ outputScale.sx = maxScale;
+ outputScale.sy = maxScale;
+ this.#hasRestrictedScaling = true;
+ } else {
+ this.#hasRestrictedScaling = false;
+ }
+ }
+ const sfx = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.approximateFraction)(outputScale.sx);
+ const sfy = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.approximateFraction)(outputScale.sy);
+ canvas.width = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(width * outputScale.sx, sfx[0]);
+ canvas.height = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(height * outputScale.sy, sfy[0]);
+ const {
+ style
+ } = canvas;
+ style.width = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(width, sfx[1]) + "px";
+ style.height = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(height, sfy[1]) + "px";
+ this.#viewportMap.set(canvas, viewport);
+ const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null;
+ const renderContext = {
+ canvasContext: ctx,
+ transform,
+ viewport,
+ annotationMode: this.#annotationMode,
+ optionalContentConfigPromise: this._optionalContentConfigPromise,
+ annotationCanvasMap: this._annotationCanvasMap,
+ pageColors
+ };
+ const renderTask = this.renderTask = this.pdfPage.render(renderContext);
+ renderTask.onContinue = renderContinueCallback;
+ const resultPromise = renderTask.promise.then(async () => {
+ showCanvas?.(true);
+ await this.#finishRenderTask(renderTask);
+ this.#renderTextLayer();
+ if (this.annotationLayer) {
+ await this.#renderAnnotationLayer();
+ }
+ const {
+ annotationEditorUIManager
+ } = this.#layerProperties;
+ if (!annotationEditorUIManager) {
+ return;
+ }
+ this.drawLayer ||= new _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__.DrawLayerBuilder({
+ pageIndex: this.id
+ });
+ await this.#renderDrawLayer();
+ this.drawLayer.setParent(canvasWrapper);
+ if (!this.annotationEditorLayer) {
+ this.annotationEditorLayer = new _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__.AnnotationEditorLayerBuilder({
+ uiManager: annotationEditorUIManager,
+ pageDiv: div,
+ pdfPage,
+ l10n,
+ accessibilityManager: this._accessibilityManager,
+ annotationLayer: this.annotationLayer?.annotationLayer,
+ textLayer: this.textLayer,
+ drawLayer: this.drawLayer.getDrawLayer()
+ });
+ }
+ this.#renderAnnotationEditorLayer();
+ }, error => {
+ if (!(error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException)) {
+ showCanvas?.(true);
+ }
+ return this.#finishRenderTask(renderTask, error);
+ });
+ if (pdfPage.isPureXfa) {
+ if (!this.xfaLayer) {
+ const {
+ annotationStorage,
+ linkService
+ } = this.#layerProperties;
+ this.xfaLayer = new _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__.XfaLayerBuilder({
+ pdfPage,
+ annotationStorage,
+ linkService
+ });
+ }
+ this.#renderXfaLayer();
+ }
+ div.setAttribute("data-loaded", true);
+ this.eventBus.dispatch("pagerender", {
+ source: this,
+ pageNumber: this.id
+ });
+ return resultPromise;
+ }
+ setPageLabel(label) {
+ this.pageLabel = typeof label === "string" ? label : null;
+ this.div.setAttribute("data-l10n-args", JSON.stringify({
+ page: this.pageLabel ?? this.id
+ }));
+ if (this.pageLabel !== null) {
+ this.div.setAttribute("data-page-label", this.pageLabel);
+ } else {
+ this.div.removeAttribute("data-page-label");
+ }
+ }
+ get thumbnailCanvas() {
+ const {
+ directDrawing,
+ initialOptionalContent,
+ regularAnnotations
+ } = this.#useThumbnailCanvas;
+ return directDrawing && initialOptionalContent && regularAnnotations ? this.canvas : null;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 323:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFPresentationMode: () => (/* binding */ PDFPresentationMode)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const DELAY_BEFORE_HIDING_CONTROLS = 3000;
+const ACTIVE_SELECTOR = "pdfPresentationMode";
+const CONTROLS_SELECTOR = "pdfPresentationModeControls";
+const MOUSE_SCROLL_COOLDOWN_TIME = 50;
+const PAGE_SWITCH_THRESHOLD = 0.1;
+const SWIPE_MIN_DISTANCE_THRESHOLD = 50;
+const SWIPE_ANGLE_THRESHOLD = Math.PI / 6;
+class PDFPresentationMode {
+ #state = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.UNKNOWN;
+ #args = null;
+ constructor({
+ container,
+ pdfViewer,
+ eventBus
+ }) {
+ this.container = container;
+ this.pdfViewer = pdfViewer;
+ this.eventBus = eventBus;
+ this.contextMenuOpen = false;
+ this.mouseScrollTimeStamp = 0;
+ this.mouseScrollDelta = 0;
+ this.touchSwipeState = null;
+ }
+ async request() {
+ const {
+ container,
+ pdfViewer
+ } = this;
+ if (this.active || !pdfViewer.pagesCount || !container.requestFullscreen) {
+ return false;
+ }
+ this.#addFullscreenChangeListeners();
+ this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.CHANGING);
+ const promise = container.requestFullscreen();
+ this.#args = {
+ pageNumber: pdfViewer.currentPageNumber,
+ scaleValue: pdfViewer.currentScaleValue,
+ scrollMode: pdfViewer.scrollMode,
+ spreadMode: null,
+ annotationEditorMode: null
+ };
+ if (pdfViewer.spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE && !(pdfViewer.pageViewsReady && pdfViewer.hasEqualPageSizes)) {
+ console.warn("Ignoring Spread modes when entering PresentationMode, " + "since the document may contain varying page sizes.");
+ this.#args.spreadMode = pdfViewer.spreadMode;
+ }
+ if (pdfViewer.annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.DISABLE) {
+ this.#args.annotationEditorMode = pdfViewer.annotationEditorMode;
+ }
+ try {
+ await promise;
+ pdfViewer.focus();
+ return true;
+ } catch {
+ this.#removeFullscreenChangeListeners();
+ this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL);
+ }
+ return false;
+ }
+ get active() {
+ return this.#state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.CHANGING || this.#state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.FULLSCREEN;
+ }
+ #mouseWheel(evt) {
+ if (!this.active) {
+ return;
+ }
+ evt.preventDefault();
+ const delta = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.normalizeWheelEventDelta)(evt);
+ const currentTime = Date.now();
+ const storedTime = this.mouseScrollTimeStamp;
+ if (currentTime > storedTime && currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {
+ return;
+ }
+ if (this.mouseScrollDelta > 0 && delta < 0 || this.mouseScrollDelta < 0 && delta > 0) {
+ this.#resetMouseScrollState();
+ }
+ this.mouseScrollDelta += delta;
+ if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) {
+ const totalDelta = this.mouseScrollDelta;
+ this.#resetMouseScrollState();
+ const success = totalDelta > 0 ? this.pdfViewer.previousPage() : this.pdfViewer.nextPage();
+ if (success) {
+ this.mouseScrollTimeStamp = currentTime;
+ }
+ }
+ }
+ #notifyStateChange(state) {
+ this.#state = state;
+ this.eventBus.dispatch("presentationmodechanged", {
+ source: this,
+ state
+ });
+ }
+ #enter() {
+ this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.FULLSCREEN);
+ this.container.classList.add(ACTIVE_SELECTOR);
+ setTimeout(() => {
+ this.pdfViewer.scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE;
+ if (this.#args.spreadMode !== null) {
+ this.pdfViewer.spreadMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE;
+ }
+ this.pdfViewer.currentPageNumber = this.#args.pageNumber;
+ this.pdfViewer.currentScaleValue = "page-fit";
+ if (this.#args.annotationEditorMode !== null) {
+ this.pdfViewer.annotationEditorMode = {
+ mode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.NONE
+ };
+ }
+ }, 0);
+ this.#addWindowListeners();
+ this.#showControls();
+ this.contextMenuOpen = false;
+ window.getSelection().removeAllRanges();
+ }
+ #exit() {
+ const pageNumber = this.pdfViewer.currentPageNumber;
+ this.container.classList.remove(ACTIVE_SELECTOR);
+ setTimeout(() => {
+ this.#removeFullscreenChangeListeners();
+ this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL);
+ this.pdfViewer.scrollMode = this.#args.scrollMode;
+ if (this.#args.spreadMode !== null) {
+ this.pdfViewer.spreadMode = this.#args.spreadMode;
+ }
+ this.pdfViewer.currentScaleValue = this.#args.scaleValue;
+ this.pdfViewer.currentPageNumber = pageNumber;
+ if (this.#args.annotationEditorMode !== null) {
+ this.pdfViewer.annotationEditorMode = {
+ mode: this.#args.annotationEditorMode
+ };
+ }
+ this.#args = null;
+ }, 0);
+ this.#removeWindowListeners();
+ this.#hideControls();
+ this.#resetMouseScrollState();
+ this.contextMenuOpen = false;
+ }
+ #mouseDown(evt) {
+ if (this.contextMenuOpen) {
+ this.contextMenuOpen = false;
+ evt.preventDefault();
+ return;
+ }
+ if (evt.button !== 0) {
+ return;
+ }
+ if (evt.target.href && evt.target.parentNode?.hasAttribute("data-internal-link")) {
+ return;
+ }
+ evt.preventDefault();
+ if (evt.shiftKey) {
+ this.pdfViewer.previousPage();
+ } else {
+ this.pdfViewer.nextPage();
+ }
+ }
+ #contextMenu() {
+ this.contextMenuOpen = true;
+ }
+ #showControls() {
+ if (this.controlsTimeout) {
+ clearTimeout(this.controlsTimeout);
+ } else {
+ this.container.classList.add(CONTROLS_SELECTOR);
+ }
+ this.controlsTimeout = setTimeout(() => {
+ this.container.classList.remove(CONTROLS_SELECTOR);
+ delete this.controlsTimeout;
+ }, DELAY_BEFORE_HIDING_CONTROLS);
+ }
+ #hideControls() {
+ if (!this.controlsTimeout) {
+ return;
+ }
+ clearTimeout(this.controlsTimeout);
+ this.container.classList.remove(CONTROLS_SELECTOR);
+ delete this.controlsTimeout;
+ }
+ #resetMouseScrollState() {
+ this.mouseScrollTimeStamp = 0;
+ this.mouseScrollDelta = 0;
+ }
+ #touchSwipe(evt) {
+ if (!this.active) {
+ return;
+ }
+ if (evt.touches.length > 1) {
+ this.touchSwipeState = null;
+ return;
+ }
+ switch (evt.type) {
+ case "touchstart":
+ this.touchSwipeState = {
+ startX: evt.touches[0].pageX,
+ startY: evt.touches[0].pageY,
+ endX: evt.touches[0].pageX,
+ endY: evt.touches[0].pageY
+ };
+ break;
+ case "touchmove":
+ if (this.touchSwipeState === null) {
+ return;
+ }
+ this.touchSwipeState.endX = evt.touches[0].pageX;
+ this.touchSwipeState.endY = evt.touches[0].pageY;
+ evt.preventDefault();
+ break;
+ case "touchend":
+ if (this.touchSwipeState === null) {
+ return;
+ }
+ let delta = 0;
+ const dx = this.touchSwipeState.endX - this.touchSwipeState.startX;
+ const dy = this.touchSwipeState.endY - this.touchSwipeState.startY;
+ const absAngle = Math.abs(Math.atan2(dy, dx));
+ if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && (absAngle <= SWIPE_ANGLE_THRESHOLD || absAngle >= Math.PI - SWIPE_ANGLE_THRESHOLD)) {
+ delta = dx;
+ } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && Math.abs(absAngle - Math.PI / 2) <= SWIPE_ANGLE_THRESHOLD) {
+ delta = dy;
+ }
+ if (delta > 0) {
+ this.pdfViewer.previousPage();
+ } else if (delta < 0) {
+ this.pdfViewer.nextPage();
+ }
+ break;
+ }
+ }
+ #addWindowListeners() {
+ this.showControlsBind = this.#showControls.bind(this);
+ this.mouseDownBind = this.#mouseDown.bind(this);
+ this.mouseWheelBind = this.#mouseWheel.bind(this);
+ this.resetMouseScrollStateBind = this.#resetMouseScrollState.bind(this);
+ this.contextMenuBind = this.#contextMenu.bind(this);
+ this.touchSwipeBind = this.#touchSwipe.bind(this);
+ window.addEventListener("mousemove", this.showControlsBind);
+ window.addEventListener("mousedown", this.mouseDownBind);
+ window.addEventListener("wheel", this.mouseWheelBind, {
+ passive: false
+ });
+ window.addEventListener("keydown", this.resetMouseScrollStateBind);
+ window.addEventListener("contextmenu", this.contextMenuBind);
+ window.addEventListener("touchstart", this.touchSwipeBind);
+ window.addEventListener("touchmove", this.touchSwipeBind);
+ window.addEventListener("touchend", this.touchSwipeBind);
+ }
+ #removeWindowListeners() {
+ window.removeEventListener("mousemove", this.showControlsBind);
+ window.removeEventListener("mousedown", this.mouseDownBind);
+ window.removeEventListener("wheel", this.mouseWheelBind, {
+ passive: false
+ });
+ window.removeEventListener("keydown", this.resetMouseScrollStateBind);
+ window.removeEventListener("contextmenu", this.contextMenuBind);
+ window.removeEventListener("touchstart", this.touchSwipeBind);
+ window.removeEventListener("touchmove", this.touchSwipeBind);
+ window.removeEventListener("touchend", this.touchSwipeBind);
+ delete this.showControlsBind;
+ delete this.mouseDownBind;
+ delete this.mouseWheelBind;
+ delete this.resetMouseScrollStateBind;
+ delete this.contextMenuBind;
+ delete this.touchSwipeBind;
+ }
+ #fullscreenChange() {
+ if (document.fullscreenElement) {
+ this.#enter();
+ } else {
+ this.#exit();
+ }
+ }
+ #addFullscreenChangeListeners() {
+ this.fullscreenChangeBind = this.#fullscreenChange.bind(this);
+ window.addEventListener("fullscreenchange", this.fullscreenChangeBind);
+ }
+ #removeFullscreenChangeListeners() {
+ window.removeEventListener("fullscreenchange", this.fullscreenChangeBind);
+ delete this.fullscreenChangeBind;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1834:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* unused harmony export PDFPrintService */
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39);
+/* harmony import */ var _print_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4552);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _app_js__WEBPACK_IMPORTED_MODULE_1__, _print_utils_js__WEBPACK_IMPORTED_MODULE_2__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _app_js__WEBPACK_IMPORTED_MODULE_1__, _print_utils_js__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+let activeService = null;
+let dialog = null;
+let overlayManager = null;
+function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) {
+ const scratchCanvas = activeService.scratchCanvas;
+ const PRINT_UNITS = printResolution / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF;
+ scratchCanvas.width = Math.floor(size.width * PRINT_UNITS);
+ scratchCanvas.height = Math.floor(size.height * PRINT_UNITS);
+ const ctx = scratchCanvas.getContext("2d");
+ ctx.save();
+ ctx.fillStyle = "rgb(255, 255, 255)";
+ ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height);
+ ctx.restore();
+ return Promise.all([pdfDocument.getPage(pageNumber), printAnnotationStoragePromise]).then(function ([pdfPage, printAnnotationStorage]) {
+ const renderContext = {
+ canvasContext: ctx,
+ transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
+ viewport: pdfPage.getViewport({
+ scale: 1,
+ rotation: size.rotation
+ }),
+ intent: "print",
+ annotationMode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_STORAGE,
+ optionalContentConfigPromise,
+ printAnnotationStorage
+ };
+ return pdfPage.render(renderContext).promise;
+ });
+}
+class PDFPrintService {
+ constructor(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise = null, printAnnotationStoragePromise = null) {
+ this.pdfDocument = pdfDocument;
+ this.pagesOverview = pagesOverview;
+ this.printContainer = printContainer;
+ this._printResolution = printResolution || 150;
+ this._optionalContentConfigPromise = optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
+ this._printAnnotationStoragePromise = printAnnotationStoragePromise || Promise.resolve();
+ this.currentPage = -1;
+ this.scratchCanvas = document.createElement("canvas");
+ }
+ layout() {
+ this.throwIfInactive();
+ const body = document.querySelector("body");
+ body.setAttribute("data-pdfjsprinting", true);
+ const {
+ width,
+ height
+ } = this.pagesOverview[0];
+ const hasEqualPageSizes = this.pagesOverview.every(size => size.width === width && size.height === height);
+ if (!hasEqualPageSizes) {
+ console.warn("Not all pages have the same size. The printed result may be incorrect!");
+ }
+ this.pageStyleSheet = document.createElement("style");
+ this.pageStyleSheet.textContent = `@page { size: ${width}pt ${height}pt;}`;
+ body.append(this.pageStyleSheet);
+ }
+ destroy() {
+ if (activeService !== this) {
+ return;
+ }
+ this.printContainer.textContent = "";
+ const body = document.querySelector("body");
+ body.removeAttribute("data-pdfjsprinting");
+ if (this.pageStyleSheet) {
+ this.pageStyleSheet.remove();
+ this.pageStyleSheet = null;
+ }
+ this.scratchCanvas.width = this.scratchCanvas.height = 0;
+ this.scratchCanvas = null;
+ activeService = null;
+ ensureOverlay().then(function () {
+ if (overlayManager.active === dialog) {
+ overlayManager.close(dialog);
+ }
+ });
+ }
+ renderPages() {
+ if (this.pdfDocument.isPureXfa) {
+ (0,_print_utils_js__WEBPACK_IMPORTED_MODULE_2__.getXfaHtmlForPrinting)(this.printContainer, this.pdfDocument);
+ return Promise.resolve();
+ }
+ const pageCount = this.pagesOverview.length;
+ const renderNextPage = (resolve, reject) => {
+ this.throwIfInactive();
+ if (++this.currentPage >= pageCount) {
+ renderProgress(pageCount, pageCount);
+ resolve();
+ return;
+ }
+ const index = this.currentPage;
+ renderProgress(index, pageCount);
+ renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index], this._printResolution, this._optionalContentConfigPromise, this._printAnnotationStoragePromise).then(this.useRenderedPage.bind(this)).then(function () {
+ renderNextPage(resolve, reject);
+ }, reject);
+ };
+ return new Promise(renderNextPage);
+ }
+ useRenderedPage() {
+ this.throwIfInactive();
+ const img = document.createElement("img");
+ const scratchCanvas = this.scratchCanvas;
+ if ("toBlob" in scratchCanvas) {
+ scratchCanvas.toBlob(function (blob) {
+ img.src = URL.createObjectURL(blob);
+ });
+ } else {
+ img.src = scratchCanvas.toDataURL();
+ }
+ const wrapper = document.createElement("div");
+ wrapper.className = "printedPage";
+ wrapper.append(img);
+ this.printContainer.append(wrapper);
+ return new Promise(function (resolve, reject) {
+ img.onload = resolve;
+ img.onerror = reject;
+ });
+ }
+ performPrint() {
+ this.throwIfInactive();
+ return new Promise(resolve => {
+ setTimeout(() => {
+ if (!this.active) {
+ resolve();
+ return;
+ }
+ print.call(window);
+ setTimeout(resolve, 20);
+ }, 0);
+ });
+ }
+ get active() {
+ return this === activeService;
+ }
+ throwIfInactive() {
+ if (!this.active) {
+ throw new Error("This print request was cancelled or completed.");
+ }
+ }
+}
+const print = window.print;
+window.print = function () {
+ if (activeService) {
+ console.warn("Ignored window.print() because of a pending print job.");
+ return;
+ }
+ ensureOverlay().then(function () {
+ if (activeService) {
+ overlayManager.open(dialog);
+ }
+ });
+ try {
+ dispatchEvent("beforeprint");
+ } finally {
+ if (!activeService) {
+ console.error("Expected print service to be initialized.");
+ ensureOverlay().then(function () {
+ if (overlayManager.active === dialog) {
+ overlayManager.close(dialog);
+ }
+ });
+ return;
+ }
+ const activeServiceOnEntry = activeService;
+ activeService.renderPages().then(function () {
+ return activeServiceOnEntry.performPrint();
+ }).catch(function () {}).then(function () {
+ if (activeServiceOnEntry.active) {
+ abort();
+ }
+ });
+ }
+};
+function dispatchEvent(eventType) {
+ const event = new CustomEvent(eventType, {
+ bubbles: false,
+ cancelable: false,
+ detail: "custom"
+ });
+ window.dispatchEvent(event);
+}
+function abort() {
+ if (activeService) {
+ activeService.destroy();
+ dispatchEvent("afterprint");
+ }
+}
+function renderProgress(index, total) {
+ dialog ||= document.getElementById("printServiceDialog");
+ const progress = Math.round(100 * index / total);
+ const progressBar = dialog.querySelector("progress");
+ const progressPerc = dialog.querySelector(".relative-progress");
+ progressBar.value = progress;
+ progressPerc.setAttribute("data-l10n-args", JSON.stringify({
+ progress
+ }));
+}
+window.addEventListener("keydown", function (event) {
+ if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {
+ window.print();
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+}, true);
+if ("onbeforeprint" in window) {
+ const stopPropagationIfNeeded = function (event) {
+ if (event.detail !== "custom") {
+ event.stopImmediatePropagation();
+ }
+ };
+ window.addEventListener("beforeprint", stopPropagationIfNeeded);
+ window.addEventListener("afterprint", stopPropagationIfNeeded);
+}
+let overlayPromise;
+function ensureOverlay() {
+ if (!overlayPromise) {
+ overlayManager = _app_js__WEBPACK_IMPORTED_MODULE_1__.PDFViewerApplication.overlayManager;
+ if (!overlayManager) {
+ throw new Error("The overlay manager has not yet been initialized.");
+ }
+ dialog ||= document.getElementById("printServiceDialog");
+ overlayPromise = overlayManager.register(dialog, true);
+ document.getElementById("printCancel").onclick = abort;
+ dialog.addEventListener("close", abort);
+ }
+ return overlayPromise;
+}
+_app_js__WEBPACK_IMPORTED_MODULE_1__.PDFPrintServiceFactory.instance = {
+ supportsPrinting: true,
+ createPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) {
+ if (activeService) {
+ throw new Error("The print service is created and active.");
+ }
+ activeService = new PDFPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise);
+ return activeService;
+ }
+};
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 5119:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFRenderingQueue: () => (/* binding */ PDFRenderingQueue)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const CLEANUP_TIMEOUT = 30000;
+class PDFRenderingQueue {
+ constructor() {
+ this.pdfViewer = null;
+ this.pdfThumbnailViewer = null;
+ this.onIdle = null;
+ this.highestPriorityPage = null;
+ this.idleTimeout = null;
+ this.printing = false;
+ this.isThumbnailViewEnabled = false;
+ Object.defineProperty(this, "hasViewer", {
+ value: () => !!this.pdfViewer
+ });
+ }
+ setViewer(pdfViewer) {
+ this.pdfViewer = pdfViewer;
+ }
+ setThumbnailViewer(pdfThumbnailViewer) {
+ this.pdfThumbnailViewer = pdfThumbnailViewer;
+ }
+ isHighestPriority(view) {
+ return this.highestPriorityPage === view.renderingId;
+ }
+ renderHighestPriority(currentlyVisiblePages) {
+ if (this.idleTimeout) {
+ clearTimeout(this.idleTimeout);
+ this.idleTimeout = null;
+ }
+ if (this.pdfViewer.forceRendering(currentlyVisiblePages)) {
+ return;
+ }
+ if (this.isThumbnailViewEnabled && this.pdfThumbnailViewer?.forceRendering()) {
+ return;
+ }
+ if (this.printing) {
+ return;
+ }
+ if (this.onIdle) {
+ this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT);
+ }
+ }
+ getHighestPriority(visible, views, scrolledDown, preRenderExtra = false) {
+ const visibleViews = visible.views,
+ numVisible = visibleViews.length;
+ if (numVisible === 0) {
+ return null;
+ }
+ for (let i = 0; i < numVisible; i++) {
+ const view = visibleViews[i].view;
+ if (!this.isViewFinished(view)) {
+ return view;
+ }
+ }
+ const firstId = visible.first.id,
+ lastId = visible.last.id;
+ if (lastId - firstId + 1 > numVisible) {
+ const visibleIds = visible.ids;
+ for (let i = 1, ii = lastId - firstId; i < ii; i++) {
+ const holeId = scrolledDown ? firstId + i : lastId - i;
+ if (visibleIds.has(holeId)) {
+ continue;
+ }
+ const holeView = views[holeId - 1];
+ if (!this.isViewFinished(holeView)) {
+ return holeView;
+ }
+ }
+ }
+ let preRenderIndex = scrolledDown ? lastId : firstId - 2;
+ let preRenderView = views[preRenderIndex];
+ if (preRenderView && !this.isViewFinished(preRenderView)) {
+ return preRenderView;
+ }
+ if (preRenderExtra) {
+ preRenderIndex += scrolledDown ? 1 : -1;
+ preRenderView = views[preRenderIndex];
+ if (preRenderView && !this.isViewFinished(preRenderView)) {
+ return preRenderView;
+ }
+ }
+ return null;
+ }
+ isViewFinished(view) {
+ return view.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED;
+ }
+ renderView(view) {
+ switch (view.renderingState) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED:
+ return false;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED:
+ this.highestPriorityPage = view.renderingId;
+ view.resume();
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING:
+ this.highestPriorityPage = view.renderingId;
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL:
+ this.highestPriorityPage = view.renderingId;
+ view.draw().finally(() => {
+ this.renderHighestPriority();
+ }).catch(reason => {
+ if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException) {
+ return;
+ }
+ console.error(`renderView: "${reason}"`);
+ });
+ break;
+ }
+ return true;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 2599:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFScriptingManager: () => (/* binding */ PDFScriptingManager)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+class PDFScriptingManager {
+ #closeCapability = null;
+ #destroyCapability = null;
+ #docProperties = null;
+ #eventBus = null;
+ #externalServices = null;
+ #pdfDocument = null;
+ #pdfViewer = null;
+ #ready = false;
+ #scripting = null;
+ #willPrintCapability = null;
+ constructor({
+ eventBus,
+ externalServices = null,
+ docProperties = null
+ }) {
+ this.#eventBus = eventBus;
+ this.#externalServices = externalServices;
+ this.#docProperties = docProperties;
+ }
+ setViewer(pdfViewer) {
+ this.#pdfViewer = pdfViewer;
+ }
+ async setDocument(pdfDocument) {
+ if (this.#pdfDocument) {
+ await this.#destroyScripting();
+ }
+ this.#pdfDocument = pdfDocument;
+ if (!pdfDocument) {
+ return;
+ }
+ const [objects, calculationOrder, docActions] = await Promise.all([pdfDocument.getFieldObjects(), pdfDocument.getCalculationOrderIds(), pdfDocument.getJSActions()]);
+ if (!objects && !docActions) {
+ await this.#destroyScripting();
+ return;
+ }
+ if (pdfDocument !== this.#pdfDocument) {
+ return;
+ }
+ try {
+ this.#scripting = this.#initScripting();
+ } catch (error) {
+ console.error(`setDocument: "${error.message}".`);
+ await this.#destroyScripting();
+ return;
+ }
+ this._internalEvents.set("updatefromsandbox", event => {
+ if (event?.source === window) {
+ this.#updateFromSandbox(event.detail);
+ }
+ });
+ this._internalEvents.set("dispatcheventinsandbox", event => {
+ this.#scripting?.dispatchEventInSandbox(event.detail);
+ });
+ this._internalEvents.set("pagechanging", ({
+ pageNumber,
+ previous
+ }) => {
+ if (pageNumber === previous) {
+ return;
+ }
+ this.#dispatchPageClose(previous);
+ this.#dispatchPageOpen(pageNumber);
+ });
+ this._internalEvents.set("pagerendered", ({
+ pageNumber
+ }) => {
+ if (!this._pageOpenPending.has(pageNumber)) {
+ return;
+ }
+ if (pageNumber !== this.#pdfViewer.currentPageNumber) {
+ return;
+ }
+ this.#dispatchPageOpen(pageNumber);
+ });
+ this._internalEvents.set("pagesdestroy", async () => {
+ await this.#dispatchPageClose(this.#pdfViewer.currentPageNumber);
+ await this.#scripting?.dispatchEventInSandbox({
+ id: "doc",
+ name: "WillClose"
+ });
+ this.#closeCapability?.resolve();
+ });
+ for (const [name, listener] of this._internalEvents) {
+ this.#eventBus._on(name, listener);
+ }
+ try {
+ const docProperties = await this.#docProperties(pdfDocument);
+ if (pdfDocument !== this.#pdfDocument) {
+ return;
+ }
+ await this.#scripting.createSandbox({
+ objects,
+ calculationOrder,
+ appInfo: {
+ platform: navigator.platform,
+ language: navigator.language
+ },
+ docInfo: {
+ ...docProperties,
+ actions: docActions
+ }
+ });
+ this.#eventBus.dispatch("sandboxcreated", {
+ source: this
+ });
+ } catch (error) {
+ console.error(`setDocument: "${error.message}".`);
+ await this.#destroyScripting();
+ return;
+ }
+ await this.#scripting?.dispatchEventInSandbox({
+ id: "doc",
+ name: "Open"
+ });
+ await this.#dispatchPageOpen(this.#pdfViewer.currentPageNumber, true);
+ Promise.resolve().then(() => {
+ if (pdfDocument === this.#pdfDocument) {
+ this.#ready = true;
+ }
+ });
+ }
+ async dispatchWillSave() {
+ return this.#scripting?.dispatchEventInSandbox({
+ id: "doc",
+ name: "WillSave"
+ });
+ }
+ async dispatchDidSave() {
+ return this.#scripting?.dispatchEventInSandbox({
+ id: "doc",
+ name: "DidSave"
+ });
+ }
+ async dispatchWillPrint() {
+ if (!this.#scripting) {
+ return;
+ }
+ await this.#willPrintCapability?.promise;
+ this.#willPrintCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ try {
+ await this.#scripting.dispatchEventInSandbox({
+ id: "doc",
+ name: "WillPrint"
+ });
+ } catch (ex) {
+ this.#willPrintCapability.resolve();
+ this.#willPrintCapability = null;
+ throw ex;
+ }
+ await this.#willPrintCapability.promise;
+ }
+ async dispatchDidPrint() {
+ return this.#scripting?.dispatchEventInSandbox({
+ id: "doc",
+ name: "DidPrint"
+ });
+ }
+ get destroyPromise() {
+ return this.#destroyCapability?.promise || null;
+ }
+ get ready() {
+ return this.#ready;
+ }
+ get _internalEvents() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_internalEvents", new Map());
+ }
+ get _pageOpenPending() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_pageOpenPending", new Set());
+ }
+ get _visitedPages() {
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_visitedPages", new Map());
+ }
+ async #updateFromSandbox(detail) {
+ const pdfViewer = this.#pdfViewer;
+ const isInPresentationMode = pdfViewer.isInPresentationMode || pdfViewer.isChangingPresentationMode;
+ const {
+ id,
+ siblings,
+ command,
+ value
+ } = detail;
+ if (!id) {
+ switch (command) {
+ case "clear":
+ console.clear();
+ break;
+ case "error":
+ console.error(value);
+ break;
+ case "layout":
+ if (!isInPresentationMode) {
+ const modes = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageLayoutToViewerModes)(value);
+ pdfViewer.spreadMode = modes.spreadMode;
+ }
+ break;
+ case "page-num":
+ pdfViewer.currentPageNumber = value + 1;
+ break;
+ case "print":
+ await pdfViewer.pagesPromise;
+ this.#eventBus.dispatch("print", {
+ source: this
+ });
+ break;
+ case "println":
+ console.log(value);
+ break;
+ case "zoom":
+ if (!isInPresentationMode) {
+ pdfViewer.currentScaleValue = value;
+ }
+ break;
+ case "SaveAs":
+ this.#eventBus.dispatch("download", {
+ source: this
+ });
+ break;
+ case "FirstPage":
+ pdfViewer.currentPageNumber = 1;
+ break;
+ case "LastPage":
+ pdfViewer.currentPageNumber = pdfViewer.pagesCount;
+ break;
+ case "NextPage":
+ pdfViewer.nextPage();
+ break;
+ case "PrevPage":
+ pdfViewer.previousPage();
+ break;
+ case "ZoomViewIn":
+ if (!isInPresentationMode) {
+ pdfViewer.increaseScale();
+ }
+ break;
+ case "ZoomViewOut":
+ if (!isInPresentationMode) {
+ pdfViewer.decreaseScale();
+ }
+ break;
+ case "WillPrintFinished":
+ this.#willPrintCapability?.resolve();
+ this.#willPrintCapability = null;
+ break;
+ }
+ return;
+ }
+ if (isInPresentationMode && detail.focus) {
+ return;
+ }
+ delete detail.id;
+ delete detail.siblings;
+ const ids = siblings ? [id, ...siblings] : [id];
+ for (const elementId of ids) {
+ const element = document.querySelector(`[data-element-id="${elementId}"]`);
+ if (element) {
+ element.dispatchEvent(new CustomEvent("updatefromsandbox", {
+ detail
+ }));
+ } else {
+ this.#pdfDocument?.annotationStorage.setValue(elementId, detail);
+ }
+ }
+ }
+ async #dispatchPageOpen(pageNumber, initialize = false) {
+ const pdfDocument = this.#pdfDocument,
+ visitedPages = this._visitedPages;
+ if (initialize) {
+ this.#closeCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ }
+ if (!this.#closeCapability) {
+ return;
+ }
+ const pageView = this.#pdfViewer.getPageView(pageNumber - 1);
+ if (pageView?.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) {
+ this._pageOpenPending.add(pageNumber);
+ return;
+ }
+ this._pageOpenPending.delete(pageNumber);
+ const actionsPromise = (async () => {
+ const actions = await (!visitedPages.has(pageNumber) ? pageView.pdfPage?.getJSActions() : null);
+ if (pdfDocument !== this.#pdfDocument) {
+ return;
+ }
+ await this.#scripting?.dispatchEventInSandbox({
+ id: "page",
+ name: "PageOpen",
+ pageNumber,
+ actions
+ });
+ })();
+ visitedPages.set(pageNumber, actionsPromise);
+ }
+ async #dispatchPageClose(pageNumber) {
+ const pdfDocument = this.#pdfDocument,
+ visitedPages = this._visitedPages;
+ if (!this.#closeCapability) {
+ return;
+ }
+ if (this._pageOpenPending.has(pageNumber)) {
+ return;
+ }
+ const actionsPromise = visitedPages.get(pageNumber);
+ if (!actionsPromise) {
+ return;
+ }
+ visitedPages.set(pageNumber, null);
+ await actionsPromise;
+ if (pdfDocument !== this.#pdfDocument) {
+ return;
+ }
+ await this.#scripting?.dispatchEventInSandbox({
+ id: "page",
+ name: "PageClose",
+ pageNumber
+ });
+ }
+ #initScripting() {
+ this.#destroyCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability();
+ if (this.#scripting) {
+ throw new Error("#initScripting: Scripting already exists.");
+ }
+ return this.#externalServices.createScripting();
+ }
+ async #destroyScripting() {
+ if (!this.#scripting) {
+ this.#pdfDocument = null;
+ this.#destroyCapability?.resolve();
+ return;
+ }
+ if (this.#closeCapability) {
+ await Promise.race([this.#closeCapability.promise, new Promise(resolve => {
+ setTimeout(resolve, 1000);
+ })]).catch(() => {});
+ this.#closeCapability = null;
+ }
+ this.#pdfDocument = null;
+ try {
+ await this.#scripting.destroySandbox();
+ } catch {}
+ this.#willPrintCapability?.reject(new Error("Scripting destroyed."));
+ this.#willPrintCapability = null;
+ for (const [name, listener] of this._internalEvents) {
+ this.#eventBus._off(name, listener);
+ }
+ this._internalEvents.clear();
+ this._pageOpenPending.clear();
+ this._visitedPages.clear();
+ this.#scripting = null;
+ this.#ready = false;
+ this.#destroyCapability?.resolve();
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 4487:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFSidebar: () => (/* binding */ PDFSidebar)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+
+const SIDEBAR_WIDTH_VAR = "--sidebar-width";
+const SIDEBAR_MIN_WIDTH = 200;
+const SIDEBAR_RESIZING_CLASS = "sidebarResizing";
+const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";
+class PDFSidebar {
+ #isRTL = false;
+ #mouseMoveBound = this.#mouseMove.bind(this);
+ #mouseUpBound = this.#mouseUp.bind(this);
+ #outerContainerWidth = null;
+ #width = null;
+ constructor({
+ elements,
+ eventBus,
+ l10n
+ }) {
+ this.isOpen = false;
+ this.active = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS;
+ this.isInitialViewSet = false;
+ this.isInitialEventDispatched = false;
+ this.onToggled = null;
+ this.onUpdateThumbnails = null;
+ this.outerContainer = elements.outerContainer;
+ this.sidebarContainer = elements.sidebarContainer;
+ this.toggleButton = elements.toggleButton;
+ this.resizer = elements.resizer;
+ this.thumbnailButton = elements.thumbnailButton;
+ this.outlineButton = elements.outlineButton;
+ this.attachmentsButton = elements.attachmentsButton;
+ this.layersButton = elements.layersButton;
+ this.thumbnailView = elements.thumbnailView;
+ this.outlineView = elements.outlineView;
+ this.attachmentsView = elements.attachmentsView;
+ this.layersView = elements.layersView;
+ this._currentOutlineItemButton = elements.currentOutlineItemButton;
+ this.eventBus = eventBus;
+ this.#isRTL = l10n.getDirection() === "rtl";
+ this.#addEventListeners();
+ }
+ reset() {
+ this.isInitialViewSet = false;
+ this.isInitialEventDispatched = false;
+ this.#hideUINotification(true);
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS);
+ this.outlineButton.disabled = false;
+ this.attachmentsButton.disabled = false;
+ this.layersButton.disabled = false;
+ this._currentOutlineItemButton.disabled = true;
+ }
+ get visibleView() {
+ return this.isOpen ? this.active : _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE;
+ }
+ setInitialView(view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE) {
+ if (this.isInitialViewSet) {
+ return;
+ }
+ this.isInitialViewSet = true;
+ if (view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE || view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) {
+ this.#dispatchEvent();
+ return;
+ }
+ this.switchView(view, true);
+ if (!this.isInitialEventDispatched) {
+ this.#dispatchEvent();
+ }
+ }
+ switchView(view, forceOpen = false) {
+ const isViewChanged = view !== this.active;
+ let forceRendering = false;
+ switch (view) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE:
+ if (this.isOpen) {
+ this.close();
+ }
+ return;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS:
+ if (this.isOpen && isViewChanged) {
+ forceRendering = true;
+ }
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE:
+ if (this.outlineButton.disabled) {
+ return;
+ }
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS:
+ if (this.attachmentsButton.disabled) {
+ return;
+ }
+ break;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS:
+ if (this.layersButton.disabled) {
+ return;
+ }
+ break;
+ default:
+ console.error(`PDFSidebar.switchView: "${view}" is not a valid view.`);
+ return;
+ }
+ this.active = view;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.thumbnailButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS, this.thumbnailView);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.outlineButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE, this.outlineView);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.attachmentsButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS, this.attachmentsView);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.layersButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS, this.layersView);
+ if (forceOpen && !this.isOpen) {
+ this.open();
+ return;
+ }
+ if (forceRendering) {
+ this.onUpdateThumbnails();
+ this.onToggled();
+ }
+ if (isViewChanged) {
+ this.#dispatchEvent();
+ }
+ }
+ open() {
+ if (this.isOpen) {
+ return;
+ }
+ this.isOpen = true;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(this.toggleButton, true);
+ this.outerContainer.classList.add("sidebarMoving", "sidebarOpen");
+ if (this.active === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) {
+ this.onUpdateThumbnails();
+ }
+ this.onToggled();
+ this.#dispatchEvent();
+ this.#hideUINotification();
+ }
+ close(evt = null) {
+ if (!this.isOpen) {
+ return;
+ }
+ this.isOpen = false;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(this.toggleButton, false);
+ this.outerContainer.classList.add("sidebarMoving");
+ this.outerContainer.classList.remove("sidebarOpen");
+ this.onToggled();
+ this.#dispatchEvent();
+ if (evt?.detail > 0) {
+ this.toggleButton.blur();
+ }
+ }
+ toggle(evt = null) {
+ if (this.isOpen) {
+ this.close(evt);
+ } else {
+ this.open();
+ }
+ }
+ #dispatchEvent() {
+ if (this.isInitialViewSet) {
+ this.isInitialEventDispatched ||= true;
+ }
+ this.eventBus.dispatch("sidebarviewchanged", {
+ source: this,
+ view: this.visibleView
+ });
+ }
+ #showUINotification() {
+ this.toggleButton.setAttribute("data-l10n-id", "pdfjs-toggle-sidebar-notification-button");
+ if (!this.isOpen) {
+ this.toggleButton.classList.add(UI_NOTIFICATION_CLASS);
+ }
+ }
+ #hideUINotification(reset = false) {
+ if (this.isOpen || reset) {
+ this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS);
+ }
+ if (reset) {
+ this.toggleButton.setAttribute("data-l10n-id", "pdfjs-toggle-sidebar-button");
+ }
+ }
+ #addEventListeners() {
+ this.sidebarContainer.addEventListener("transitionend", evt => {
+ if (evt.target === this.sidebarContainer) {
+ this.outerContainer.classList.remove("sidebarMoving");
+ this.eventBus.dispatch("resize", {
+ source: this
+ });
+ }
+ });
+ this.toggleButton.addEventListener("click", evt => {
+ this.toggle(evt);
+ });
+ this.thumbnailButton.addEventListener("click", () => {
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS);
+ });
+ this.outlineButton.addEventListener("click", () => {
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE);
+ });
+ this.outlineButton.addEventListener("dblclick", () => {
+ this.eventBus.dispatch("toggleoutlinetree", {
+ source: this
+ });
+ });
+ this.attachmentsButton.addEventListener("click", () => {
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS);
+ });
+ this.layersButton.addEventListener("click", () => {
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS);
+ });
+ this.layersButton.addEventListener("dblclick", () => {
+ this.eventBus.dispatch("resetlayers", {
+ source: this
+ });
+ });
+ this._currentOutlineItemButton.addEventListener("click", () => {
+ this.eventBus.dispatch("currentoutlineitem", {
+ source: this
+ });
+ });
+ const onTreeLoaded = (count, button, view) => {
+ button.disabled = !count;
+ if (count) {
+ this.#showUINotification();
+ } else if (this.active === view) {
+ this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS);
+ }
+ };
+ this.eventBus._on("outlineloaded", evt => {
+ onTreeLoaded(evt.outlineCount, this.outlineButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE);
+ evt.currentOutlineItemPromise.then(enabled => {
+ if (!this.isInitialViewSet) {
+ return;
+ }
+ this._currentOutlineItemButton.disabled = !enabled;
+ });
+ });
+ this.eventBus._on("attachmentsloaded", evt => {
+ onTreeLoaded(evt.attachmentsCount, this.attachmentsButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS);
+ });
+ this.eventBus._on("layersloaded", evt => {
+ onTreeLoaded(evt.layersCount, this.layersButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS);
+ });
+ this.eventBus._on("presentationmodechanged", evt => {
+ if (evt.state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL && this.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) {
+ this.onUpdateThumbnails();
+ }
+ });
+ this.resizer.addEventListener("mousedown", evt => {
+ if (evt.button !== 0) {
+ return;
+ }
+ this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS);
+ window.addEventListener("mousemove", this.#mouseMoveBound);
+ window.addEventListener("mouseup", this.#mouseUpBound);
+ });
+ this.eventBus._on("resize", evt => {
+ if (evt.source !== window) {
+ return;
+ }
+ this.#outerContainerWidth = null;
+ if (!this.#width) {
+ return;
+ }
+ if (!this.isOpen) {
+ this.#updateWidth(this.#width);
+ return;
+ }
+ this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS);
+ const updated = this.#updateWidth(this.#width);
+ Promise.resolve().then(() => {
+ this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS);
+ if (updated) {
+ this.eventBus.dispatch("resize", {
+ source: this
+ });
+ }
+ });
+ });
+ }
+ get outerContainerWidth() {
+ return this.#outerContainerWidth ||= this.outerContainer.clientWidth;
+ }
+ #updateWidth(width = 0) {
+ const maxWidth = Math.floor(this.outerContainerWidth / 2);
+ if (width > maxWidth) {
+ width = maxWidth;
+ }
+ if (width < SIDEBAR_MIN_WIDTH) {
+ width = SIDEBAR_MIN_WIDTH;
+ }
+ if (width === this.#width) {
+ return false;
+ }
+ this.#width = width;
+ _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.docStyle.setProperty(SIDEBAR_WIDTH_VAR, `${width}px`);
+ return true;
+ }
+ #mouseMove(evt) {
+ let width = evt.clientX;
+ if (this.#isRTL) {
+ width = this.outerContainerWidth - width;
+ }
+ this.#updateWidth(width);
+ }
+ #mouseUp(evt) {
+ this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS);
+ this.eventBus.dispatch("resize", {
+ source: this
+ });
+ window.removeEventListener("mousemove", this.#mouseMoveBound);
+ window.removeEventListener("mouseup", this.#mouseUpBound);
+ }
+}
+
+
+/***/ }),
+
+/***/ 3346:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFThumbnailView: () => (/* binding */ PDFThumbnailView),
+/* harmony export */ TempImageFactory: () => (/* binding */ TempImageFactory)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const DRAW_UPSCALE_FACTOR = 2;
+const MAX_NUM_SCALING_STEPS = 3;
+const THUMBNAIL_WIDTH = 98;
+class TempImageFactory {
+ static #tempCanvas = null;
+ static getCanvas(width, height) {
+ const tempCanvas = this.#tempCanvas ||= document.createElement("canvas");
+ tempCanvas.width = width;
+ tempCanvas.height = height;
+ const ctx = tempCanvas.getContext("2d", {
+ alpha: false
+ });
+ ctx.save();
+ ctx.fillStyle = "rgb(255, 255, 255)";
+ ctx.fillRect(0, 0, width, height);
+ ctx.restore();
+ return [tempCanvas, tempCanvas.getContext("2d")];
+ }
+ static destroyCanvas() {
+ const tempCanvas = this.#tempCanvas;
+ if (tempCanvas) {
+ tempCanvas.width = 0;
+ tempCanvas.height = 0;
+ }
+ this.#tempCanvas = null;
+ }
+}
+class PDFThumbnailView {
+ constructor({
+ container,
+ eventBus,
+ id,
+ defaultViewport,
+ optionalContentConfigPromise,
+ linkService,
+ renderingQueue,
+ pageColors
+ }) {
+ this.id = id;
+ this.renderingId = "thumbnail" + id;
+ this.pageLabel = null;
+ this.pdfPage = null;
+ this.rotation = 0;
+ this.viewport = defaultViewport;
+ this.pdfPageRotate = defaultViewport.rotation;
+ this._optionalContentConfigPromise = optionalContentConfigPromise || null;
+ this.pageColors = pageColors || null;
+ this.eventBus = eventBus;
+ this.linkService = linkService;
+ this.renderingQueue = renderingQueue;
+ this.renderTask = null;
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL;
+ this.resume = null;
+ const anchor = document.createElement("a");
+ anchor.href = linkService.getAnchorUrl("#page=" + id);
+ anchor.setAttribute("data-l10n-id", "pdfjs-thumb-page-title");
+ anchor.setAttribute("data-l10n-args", this.#pageL10nArgs);
+ anchor.onclick = function () {
+ linkService.goToPage(id);
+ return false;
+ };
+ this.anchor = anchor;
+ const div = document.createElement("div");
+ div.className = "thumbnail";
+ div.setAttribute("data-page-number", this.id);
+ this.div = div;
+ this.#updateDims();
+ const img = document.createElement("div");
+ img.className = "thumbnailImage";
+ this._placeholderImg = img;
+ div.append(img);
+ anchor.append(div);
+ container.append(anchor);
+ }
+ #updateDims() {
+ const {
+ width,
+ height
+ } = this.viewport;
+ const ratio = width / height;
+ this.canvasWidth = THUMBNAIL_WIDTH;
+ this.canvasHeight = this.canvasWidth / ratio | 0;
+ this.scale = this.canvasWidth / width;
+ const {
+ style
+ } = this.div;
+ style.setProperty("--thumbnail-width", `${this.canvasWidth}px`);
+ style.setProperty("--thumbnail-height", `${this.canvasHeight}px`);
+ }
+ setPdfPage(pdfPage) {
+ this.pdfPage = pdfPage;
+ this.pdfPageRotate = pdfPage.rotate;
+ const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = pdfPage.getViewport({
+ scale: 1,
+ rotation: totalRotation
+ });
+ this.reset();
+ }
+ reset() {
+ this.cancelRendering();
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL;
+ this.div.removeAttribute("data-loaded");
+ this.image?.replaceWith(this._placeholderImg);
+ this.#updateDims();
+ if (this.image) {
+ this.image.removeAttribute("src");
+ delete this.image;
+ }
+ }
+ update({
+ rotation = null
+ }) {
+ if (typeof rotation === "number") {
+ this.rotation = rotation;
+ }
+ const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
+ this.viewport = this.viewport.clone({
+ scale: 1,
+ rotation: totalRotation
+ });
+ this.reset();
+ }
+ cancelRendering() {
+ if (this.renderTask) {
+ this.renderTask.cancel();
+ this.renderTask = null;
+ }
+ this.resume = null;
+ }
+ _getPageDrawContext(upscaleFactor = 1) {
+ const canvas = document.createElement("canvas");
+ const ctx = canvas.getContext("2d", {
+ alpha: false
+ });
+ const outputScale = new _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.OutputScale();
+ canvas.width = upscaleFactor * this.canvasWidth * outputScale.sx | 0;
+ canvas.height = upscaleFactor * this.canvasHeight * outputScale.sy | 0;
+ const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null;
+ return {
+ ctx,
+ canvas,
+ transform
+ };
+ }
+ _convertCanvasToImage(canvas) {
+ if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) {
+ throw new Error("_convertCanvasToImage: Rendering has not finished.");
+ }
+ const reducedCanvas = this._reduceImage(canvas);
+ const image = document.createElement("img");
+ image.className = "thumbnailImage";
+ image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas");
+ image.setAttribute("data-l10n-args", this.#pageL10nArgs);
+ image.src = reducedCanvas.toDataURL();
+ this.image = image;
+ this.div.setAttribute("data-loaded", true);
+ this._placeholderImg.replaceWith(image);
+ reducedCanvas.width = 0;
+ reducedCanvas.height = 0;
+ }
+ async #finishRenderTask(renderTask, canvas, error = null) {
+ if (renderTask === this.renderTask) {
+ this.renderTask = null;
+ }
+ if (error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.RenderingCancelledException) {
+ return;
+ }
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED;
+ this._convertCanvasToImage(canvas);
+ if (error) {
+ throw error;
+ }
+ }
+ async draw() {
+ if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL) {
+ console.error("Must be in new state before drawing");
+ return undefined;
+ }
+ const {
+ pdfPage
+ } = this;
+ if (!pdfPage) {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED;
+ throw new Error("pdfPage is not loaded");
+ }
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING;
+ const {
+ ctx,
+ canvas,
+ transform
+ } = this._getPageDrawContext(DRAW_UPSCALE_FACTOR);
+ const drawViewport = this.viewport.clone({
+ scale: DRAW_UPSCALE_FACTOR * this.scale
+ });
+ const renderContinueCallback = cont => {
+ if (!this.renderingQueue.isHighestPriority(this)) {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.PAUSED;
+ this.resume = () => {
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING;
+ cont();
+ };
+ return;
+ }
+ cont();
+ };
+ const renderContext = {
+ canvasContext: ctx,
+ transform,
+ viewport: drawViewport,
+ optionalContentConfigPromise: this._optionalContentConfigPromise,
+ pageColors: this.pageColors
+ };
+ const renderTask = this.renderTask = pdfPage.render(renderContext);
+ renderTask.onContinue = renderContinueCallback;
+ const resultPromise = renderTask.promise.then(() => this.#finishRenderTask(renderTask, canvas), error => this.#finishRenderTask(renderTask, canvas, error));
+ resultPromise.finally(() => {
+ canvas.width = 0;
+ canvas.height = 0;
+ this.eventBus.dispatch("thumbnailrendered", {
+ source: this,
+ pageNumber: this.id,
+ pdfPage: this.pdfPage
+ });
+ });
+ return resultPromise;
+ }
+ setImage(pageView) {
+ if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL) {
+ return;
+ }
+ const {
+ thumbnailCanvas: canvas,
+ pdfPage,
+ scale
+ } = pageView;
+ if (!canvas) {
+ return;
+ }
+ if (!this.pdfPage) {
+ this.setPdfPage(pdfPage);
+ }
+ if (scale < this.scale) {
+ return;
+ }
+ this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED;
+ this._convertCanvasToImage(canvas);
+ }
+ _reduceImage(img) {
+ const {
+ ctx,
+ canvas
+ } = this._getPageDrawContext();
+ if (img.width <= 2 * canvas.width) {
+ ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
+ return canvas;
+ }
+ let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS;
+ let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS;
+ const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(reducedWidth, reducedHeight);
+ while (reducedWidth > img.width || reducedHeight > img.height) {
+ reducedWidth >>= 1;
+ reducedHeight >>= 1;
+ }
+ reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, reducedWidth, reducedHeight);
+ while (reducedWidth > 2 * canvas.width) {
+ reducedImageCtx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, reducedWidth >> 1, reducedHeight >> 1);
+ reducedWidth >>= 1;
+ reducedHeight >>= 1;
+ }
+ ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height);
+ return canvas;
+ }
+ get #pageL10nArgs() {
+ return JSON.stringify({
+ page: this.pageLabel ?? this.id
+ });
+ }
+ setPageLabel(label) {
+ this.pageLabel = typeof label === "string" ? label : null;
+ this.anchor.setAttribute("data-l10n-args", this.#pageL10nArgs);
+ if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) {
+ return;
+ }
+ this.image?.setAttribute("data-l10n-args", this.#pageL10nArgs);
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 3510:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFThumbnailViewer: () => (/* binding */ PDFThumbnailViewer)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3346);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__]);
+_pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+const THUMBNAIL_SCROLL_MARGIN = -19;
+const THUMBNAIL_SELECTED_CLASS = "selected";
+class PDFThumbnailViewer {
+ constructor({
+ container,
+ eventBus,
+ linkService,
+ renderingQueue,
+ pageColors
+ }) {
+ this.container = container;
+ this.eventBus = eventBus;
+ this.linkService = linkService;
+ this.renderingQueue = renderingQueue;
+ this.pageColors = pageColors || null;
+ this.scroll = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.watchScroll)(this.container, this._scrollUpdated.bind(this));
+ this._resetView();
+ }
+ _scrollUpdated() {
+ this.renderingQueue.renderHighestPriority();
+ }
+ getThumbnail(index) {
+ return this._thumbnails[index];
+ }
+ _getVisibleThumbs() {
+ return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getVisibleElements)({
+ scrollEl: this.container,
+ views: this._thumbnails
+ });
+ }
+ scrollThumbnailIntoView(pageNumber) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ const thumbnailView = this._thumbnails[pageNumber - 1];
+ if (!thumbnailView) {
+ console.error('scrollThumbnailIntoView: Invalid "pageNumber" parameter.');
+ return;
+ }
+ if (pageNumber !== this._currentPageNumber) {
+ const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1];
+ prevThumbnailView.div.classList.remove(THUMBNAIL_SELECTED_CLASS);
+ thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS);
+ }
+ const {
+ first,
+ last,
+ views
+ } = this._getVisibleThumbs();
+ if (views.length > 0) {
+ let shouldScroll = false;
+ if (pageNumber <= first.id || pageNumber >= last.id) {
+ shouldScroll = true;
+ } else {
+ for (const {
+ id,
+ percent
+ } of views) {
+ if (id !== pageNumber) {
+ continue;
+ }
+ shouldScroll = percent < 100;
+ break;
+ }
+ }
+ if (shouldScroll) {
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.scrollIntoView)(thumbnailView.div, {
+ top: THUMBNAIL_SCROLL_MARGIN
+ });
+ }
+ }
+ this._currentPageNumber = pageNumber;
+ }
+ get pagesRotation() {
+ return this._pagesRotation;
+ }
+ set pagesRotation(rotation) {
+ if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(rotation)) {
+ throw new Error("Invalid thumbnails rotation angle.");
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ if (this._pagesRotation === rotation) {
+ return;
+ }
+ this._pagesRotation = rotation;
+ const updateArgs = {
+ rotation
+ };
+ for (const thumbnail of this._thumbnails) {
+ thumbnail.update(updateArgs);
+ }
+ }
+ cleanup() {
+ for (const thumbnail of this._thumbnails) {
+ if (thumbnail.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) {
+ thumbnail.reset();
+ }
+ }
+ _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__.TempImageFactory.destroyCanvas();
+ }
+ _resetView() {
+ this._thumbnails = [];
+ this._currentPageNumber = 1;
+ this._pageLabels = null;
+ this._pagesRotation = 0;
+ this.container.textContent = "";
+ }
+ setDocument(pdfDocument) {
+ if (this.pdfDocument) {
+ this._cancelRendering();
+ this._resetView();
+ }
+ this.pdfDocument = pdfDocument;
+ if (!pdfDocument) {
+ return;
+ }
+ const firstPagePromise = pdfDocument.getPage(1);
+ const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
+ firstPagePromise.then(firstPdfPage => {
+ const pagesCount = pdfDocument.numPages;
+ const viewport = firstPdfPage.getViewport({
+ scale: 1
+ });
+ for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+ const thumbnail = new _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__.PDFThumbnailView({
+ container: this.container,
+ eventBus: this.eventBus,
+ id: pageNum,
+ defaultViewport: viewport.clone(),
+ optionalContentConfigPromise,
+ linkService: this.linkService,
+ renderingQueue: this.renderingQueue,
+ pageColors: this.pageColors
+ });
+ this._thumbnails.push(thumbnail);
+ }
+ this._thumbnails[0]?.setPdfPage(firstPdfPage);
+ const thumbnailView = this._thumbnails[this._currentPageNumber - 1];
+ thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS);
+ }).catch(reason => {
+ console.error("Unable to initialize thumbnail viewer", reason);
+ });
+ }
+ _cancelRendering() {
+ for (const thumbnail of this._thumbnails) {
+ thumbnail.cancelRendering();
+ }
+ }
+ setPageLabels(labels) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ if (!labels) {
+ this._pageLabels = null;
+ } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) {
+ this._pageLabels = null;
+ console.error("PDFThumbnailViewer_setPageLabels: Invalid page labels.");
+ } else {
+ this._pageLabels = labels;
+ }
+ for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {
+ this._thumbnails[i].setPageLabel(this._pageLabels?.[i] ?? null);
+ }
+ }
+ async #ensurePdfPageLoaded(thumbView) {
+ if (thumbView.pdfPage) {
+ return thumbView.pdfPage;
+ }
+ try {
+ const pdfPage = await this.pdfDocument.getPage(thumbView.id);
+ if (!thumbView.pdfPage) {
+ thumbView.setPdfPage(pdfPage);
+ }
+ return pdfPage;
+ } catch (reason) {
+ console.error("Unable to get page for thumb view", reason);
+ return null;
+ }
+ }
+ #getScrollAhead(visible) {
+ if (visible.first?.id === 1) {
+ return true;
+ } else if (visible.last?.id === this._thumbnails.length) {
+ return false;
+ }
+ return this.scroll.down;
+ }
+ forceRendering() {
+ const visibleThumbs = this._getVisibleThumbs();
+ const scrollAhead = this.#getScrollAhead(visibleThumbs);
+ const thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this._thumbnails, scrollAhead);
+ if (thumbView) {
+ this.#ensurePdfPageLoaded(thumbView).then(() => {
+ this.renderingQueue.renderView(thumbView);
+ });
+ return true;
+ }
+ return false;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 9290:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFViewer: () => (/* binding */ PDFViewer),
+/* harmony export */ PagesCountLimit: () => (/* binding */ PagesCountLimit)
+/* harmony export */ });
+/* unused harmony export PDFPageViewBuffer */
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7910);
+/* harmony import */ var _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6732);
+/* harmony import */ var _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5119);
+/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3234);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__, _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__, _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+
+
+
+const DEFAULT_CACHE_SIZE = 10;
+const PagesCountLimit = {
+ FORCE_SCROLL_MODE_PAGE: 15000,
+ FORCE_LAZY_PAGE_INIT: 7500,
+ PAUSE_EAGER_PAGE_INIT: 250
+};
+function isValidAnnotationEditorMode(mode) {
+ return Object.values(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType).includes(mode) && mode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE;
+}
+class PDFPageViewBuffer {
+ #buf = new Set();
+ #size = 0;
+ constructor(size) {
+ this.#size = size;
+ }
+ push(view) {
+ const buf = this.#buf;
+ if (buf.has(view)) {
+ buf.delete(view);
+ }
+ buf.add(view);
+ if (buf.size > this.#size) {
+ this.#destroyFirstView();
+ }
+ }
+ resize(newSize, idsToKeep = null) {
+ this.#size = newSize;
+ const buf = this.#buf;
+ if (idsToKeep) {
+ const ii = buf.size;
+ let i = 1;
+ for (const view of buf) {
+ if (idsToKeep.has(view.id)) {
+ buf.delete(view);
+ buf.add(view);
+ }
+ if (++i > ii) {
+ break;
+ }
+ }
+ }
+ while (buf.size > this.#size) {
+ this.#destroyFirstView();
+ }
+ }
+ has(view) {
+ return this.#buf.has(view);
+ }
+ [Symbol.iterator]() {
+ return this.#buf.keys();
+ }
+ #destroyFirstView() {
+ const firstView = this.#buf.keys().next().value;
+ firstView?.destroy();
+ this.#buf.delete(firstView);
+ }
+}
+class PDFViewer {
+ #buffer = null;
+ #altTextManager = null;
+ #annotationEditorHighlightColors = null;
+ #annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE;
+ #annotationEditorUIManager = null;
+ #annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS;
+ #containerTopLeft = null;
+ #copyCallbackBound = null;
+ #enablePermissions = false;
+ #getAllTextInProgress = false;
+ #hiddenCopyElement = null;
+ #interruptCopyCondition = false;
+ #previousContainerHeight = 0;
+ #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this));
+ #scrollModePageState = null;
+ #onVisibilityChange = null;
+ #scaleTimeoutId = null;
+ #textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE;
+ constructor(options) {
+ const viewerVersion = '4.0.379';
+ if (pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.version !== viewerVersion) {
+ throw new Error(`The API version "${pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.version}" does not match the Viewer version "${viewerVersion}".`);
+ }
+ this.container = options.container;
+ this.viewer = options.viewer || options.container.firstElementChild;
+ if (this.container?.tagName !== "DIV" || this.viewer?.tagName !== "DIV") {
+ throw new Error("Invalid `container` and/or `viewer` option.");
+ }
+ if (this.container.offsetParent && getComputedStyle(this.container).position !== "absolute") {
+ throw new Error("The `container` must be absolutely positioned.");
+ }
+ this.#resizeObserver.observe(this.container);
+ this.eventBus = options.eventBus;
+ this.linkService = options.linkService || new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_5__.SimpleLinkService();
+ this.downloadManager = options.downloadManager || null;
+ this.findController = options.findController || null;
+ this.#altTextManager = options.altTextManager || null;
+ if (this.findController) {
+ this.findController.onIsPageVisible = pageNumber => this._getVisiblePages().ids.has(pageNumber);
+ }
+ this._scriptingManager = options.scriptingManager || null;
+ this.#textLayerMode = options.textLayerMode ?? _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE;
+ this.#annotationMode = options.annotationMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS;
+ this.#annotationEditorMode = options.annotationEditorMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE;
+ this.#annotationEditorHighlightColors = options.annotationEditorHighlightColors || null;
+ this.imageResourcesPath = options.imageResourcesPath || "";
+ this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
+ this.removePageBorders = options.removePageBorders || false;
+ this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true;
+ this.maxCanvasPixels = options.maxCanvasPixels;
+ this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__.NullL10n;
+ this.#enablePermissions = options.enablePermissions || false;
+ this.pageColors = options.pageColors || null;
+ this.defaultRenderingQueue = !options.renderingQueue;
+ if (this.defaultRenderingQueue) {
+ this.renderingQueue = new _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__.PDFRenderingQueue();
+ this.renderingQueue.setViewer(this);
+ } else {
+ this.renderingQueue = options.renderingQueue;
+ }
+ this.scroll = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.watchScroll)(this.container, this._scrollUpdate.bind(this));
+ this.presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.UNKNOWN;
+ this._onBeforeDraw = this._onAfterDraw = null;
+ this._resetView();
+ if (this.removePageBorders) {
+ this.viewer.classList.add("removePageBorders");
+ }
+ this.#updateContainerHeightCss();
+ this.eventBus._on("thumbnailrendered", ({
+ pageNumber,
+ pdfPage
+ }) => {
+ const pageView = this._pages[pageNumber - 1];
+ if (!this.#buffer.has(pageView)) {
+ pdfPage?.cleanup();
+ }
+ });
+ if (this.l10n === web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__.NullL10n) {
+ this.l10n.translate(this.container);
+ }
+ }
+ get pagesCount() {
+ return this._pages.length;
+ }
+ getPageView(index) {
+ return this._pages[index];
+ }
+ getCachedPageViews() {
+ return new Set(this.#buffer);
+ }
+ get pageViewsReady() {
+ return this._pagesCapability.settled && this._pages.every(pageView => pageView?.pdfPage);
+ }
+ get renderForms() {
+ return this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS;
+ }
+ get enableScripting() {
+ return !!this._scriptingManager;
+ }
+ get currentPageNumber() {
+ return this._currentPageNumber;
+ }
+ set currentPageNumber(val) {
+ if (!Number.isInteger(val)) {
+ throw new Error("Invalid page number.");
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ if (!this._setCurrentPageNumber(val, true)) {
+ console.error(`currentPageNumber: "${val}" is not a valid page.`);
+ }
+ }
+ _setCurrentPageNumber(val, resetCurrentPageView = false) {
+ if (this._currentPageNumber === val) {
+ if (resetCurrentPageView) {
+ this.#resetCurrentPageView();
+ }
+ return true;
+ }
+ if (!(0 < val && val <= this.pagesCount)) {
+ return false;
+ }
+ const previous = this._currentPageNumber;
+ this._currentPageNumber = val;
+ this.eventBus.dispatch("pagechanging", {
+ source: this,
+ pageNumber: val,
+ pageLabel: this._pageLabels?.[val - 1] ?? null,
+ previous
+ });
+ if (resetCurrentPageView) {
+ this.#resetCurrentPageView();
+ }
+ return true;
+ }
+ get currentPageLabel() {
+ return this._pageLabels?.[this._currentPageNumber - 1] ?? null;
+ }
+ set currentPageLabel(val) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ let page = val | 0;
+ if (this._pageLabels) {
+ const i = this._pageLabels.indexOf(val);
+ if (i >= 0) {
+ page = i + 1;
+ }
+ }
+ if (!this._setCurrentPageNumber(page, true)) {
+ console.error(`currentPageLabel: "${val}" is not a valid page.`);
+ }
+ }
+ get currentScale() {
+ return this._currentScale !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE ? this._currentScale : _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE;
+ }
+ set currentScale(val) {
+ if (isNaN(val)) {
+ throw new Error("Invalid numeric scale.");
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ this.#setScale(val, {
+ noScroll: false
+ });
+ }
+ get currentScaleValue() {
+ return this._currentScaleValue;
+ }
+ set currentScaleValue(val) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ this.#setScale(val, {
+ noScroll: false
+ });
+ }
+ get pagesRotation() {
+ return this._pagesRotation;
+ }
+ set pagesRotation(rotation) {
+ if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidRotation)(rotation)) {
+ throw new Error("Invalid pages rotation angle.");
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ rotation %= 360;
+ if (rotation < 0) {
+ rotation += 360;
+ }
+ if (this._pagesRotation === rotation) {
+ return;
+ }
+ this._pagesRotation = rotation;
+ const pageNumber = this._currentPageNumber;
+ this.refresh(true, {
+ rotation
+ });
+ if (this._currentScaleValue) {
+ this.#setScale(this._currentScaleValue, {
+ noScroll: true
+ });
+ }
+ this.eventBus.dispatch("rotationchanging", {
+ source: this,
+ pagesRotation: rotation,
+ pageNumber
+ });
+ if (this.defaultRenderingQueue) {
+ this.update();
+ }
+ }
+ get firstPagePromise() {
+ return this.pdfDocument ? this._firstPageCapability.promise : null;
+ }
+ get onePageRendered() {
+ return this.pdfDocument ? this._onePageRenderedCapability.promise : null;
+ }
+ get pagesPromise() {
+ return this.pdfDocument ? this._pagesCapability.promise : null;
+ }
+ get _layerProperties() {
+ const self = this;
+ return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_layerProperties", {
+ get annotationEditorUIManager() {
+ return self.#annotationEditorUIManager;
+ },
+ get annotationStorage() {
+ return self.pdfDocument?.annotationStorage;
+ },
+ get downloadManager() {
+ return self.downloadManager;
+ },
+ get enableScripting() {
+ return !!self._scriptingManager;
+ },
+ get fieldObjectsPromise() {
+ return self.pdfDocument?.getFieldObjects();
+ },
+ get findController() {
+ return self.findController;
+ },
+ get hasJSActionsPromise() {
+ return self.pdfDocument?.hasJSActions();
+ },
+ get linkService() {
+ return self.linkService;
+ }
+ });
+ }
+ #initializePermissions(permissions) {
+ const params = {
+ annotationEditorMode: this.#annotationEditorMode,
+ annotationMode: this.#annotationMode,
+ textLayerMode: this.#textLayerMode
+ };
+ if (!permissions) {
+ return params;
+ }
+ if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.COPY) && this.#textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE) {
+ params.textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS;
+ }
+ if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.MODIFY_CONTENTS)) {
+ params.annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE;
+ }
+ if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.MODIFY_ANNOTATIONS) && !permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.FILL_INTERACTIVE_FORMS) && this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS) {
+ params.annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE;
+ }
+ return params;
+ }
+ #onePageRenderedOrForceFetch() {
+ if (document.visibilityState === "hidden" || !this.container.offsetParent || this._getVisiblePages().views.length === 0) {
+ return Promise.resolve();
+ }
+ const visibilityChangePromise = new Promise(resolve => {
+ this.#onVisibilityChange = () => {
+ if (document.visibilityState !== "hidden") {
+ return;
+ }
+ resolve();
+ document.removeEventListener("visibilitychange", this.#onVisibilityChange);
+ this.#onVisibilityChange = null;
+ };
+ document.addEventListener("visibilitychange", this.#onVisibilityChange);
+ });
+ return Promise.race([this._onePageRenderedCapability.promise, visibilityChangePromise]);
+ }
+ async getAllText() {
+ const texts = [];
+ const buffer = [];
+ for (let pageNum = 1, pagesCount = this.pdfDocument.numPages; pageNum <= pagesCount; ++pageNum) {
+ if (this.#interruptCopyCondition) {
+ return null;
+ }
+ buffer.length = 0;
+ const page = await this.pdfDocument.getPage(pageNum);
+ const {
+ items
+ } = await page.getTextContent();
+ for (const item of items) {
+ if (item.str) {
+ buffer.push(item.str);
+ }
+ if (item.hasEOL) {
+ buffer.push("\n");
+ }
+ }
+ texts.push((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.removeNullCharacters)(buffer.join("")));
+ }
+ return texts.join("\n");
+ }
+ #copyCallback(textLayerMode, event) {
+ const selection = document.getSelection();
+ const {
+ focusNode,
+ anchorNode
+ } = selection;
+ if (anchorNode && focusNode && selection.containsNode(this.#hiddenCopyElement)) {
+ if (this.#getAllTextInProgress || textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS) {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+ this.#getAllTextInProgress = true;
+ const savedCursor = this.container.style.cursor;
+ this.container.style.cursor = "wait";
+ const interruptCopy = ev => this.#interruptCopyCondition = ev.key === "Escape";
+ window.addEventListener("keydown", interruptCopy);
+ this.getAllText().then(async text => {
+ if (text !== null) {
+ await navigator.clipboard.writeText(text);
+ }
+ }).catch(reason => {
+ console.warn(`Something goes wrong when extracting the text: ${reason.message}`);
+ }).finally(() => {
+ this.#getAllTextInProgress = false;
+ this.#interruptCopyCondition = false;
+ window.removeEventListener("keydown", interruptCopy);
+ this.container.style.cursor = savedCursor;
+ });
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ setDocument(pdfDocument) {
+ if (this.pdfDocument) {
+ this.eventBus.dispatch("pagesdestroy", {
+ source: this
+ });
+ this._cancelRendering();
+ this._resetView();
+ this.findController?.setDocument(null);
+ this._scriptingManager?.setDocument(null);
+ if (this.#annotationEditorUIManager) {
+ this.#annotationEditorUIManager.destroy();
+ this.#annotationEditorUIManager = null;
+ }
+ }
+ this.pdfDocument = pdfDocument;
+ if (!pdfDocument) {
+ return;
+ }
+ const pagesCount = pdfDocument.numPages;
+ const firstPagePromise = pdfDocument.getPage(1);
+ const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
+ const permissionsPromise = this.#enablePermissions ? pdfDocument.getPermissions() : Promise.resolve();
+ if (pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) {
+ console.warn("Forcing PAGE-scrolling for performance reasons, given the length of the document.");
+ const mode = this._scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE;
+ this.eventBus.dispatch("scrollmodechanged", {
+ source: this,
+ mode
+ });
+ }
+ this._pagesCapability.promise.then(() => {
+ this.eventBus.dispatch("pagesloaded", {
+ source: this,
+ pagesCount
+ });
+ }, () => {});
+ this._onBeforeDraw = evt => {
+ const pageView = this._pages[evt.pageNumber - 1];
+ if (!pageView) {
+ return;
+ }
+ this.#buffer.push(pageView);
+ };
+ this.eventBus._on("pagerender", this._onBeforeDraw);
+ this._onAfterDraw = evt => {
+ if (evt.cssTransform || this._onePageRenderedCapability.settled) {
+ return;
+ }
+ this._onePageRenderedCapability.resolve({
+ timestamp: evt.timestamp
+ });
+ this.eventBus._off("pagerendered", this._onAfterDraw);
+ this._onAfterDraw = null;
+ if (this.#onVisibilityChange) {
+ document.removeEventListener("visibilitychange", this.#onVisibilityChange);
+ this.#onVisibilityChange = null;
+ }
+ };
+ this.eventBus._on("pagerendered", this._onAfterDraw);
+ Promise.all([firstPagePromise, permissionsPromise]).then(([firstPdfPage, permissions]) => {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ this._firstPageCapability.resolve(firstPdfPage);
+ this._optionalContentConfigPromise = optionalContentConfigPromise;
+ const {
+ annotationEditorMode,
+ annotationMode,
+ textLayerMode
+ } = this.#initializePermissions(permissions);
+ if (textLayerMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.DISABLE) {
+ const element = this.#hiddenCopyElement = document.createElement("div");
+ element.id = "hiddenCopyElement";
+ this.viewer.before(element);
+ }
+ if (annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE) {
+ const mode = annotationEditorMode;
+ if (pdfDocument.isPureXfa) {
+ console.warn("Warning: XFA-editing is not implemented.");
+ } else if (isValidAnnotationEditorMode(mode)) {
+ this.#annotationEditorUIManager = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorUIManager(this.container, this.viewer, this.#altTextManager, this.eventBus, pdfDocument, this.pageColors, this.#annotationEditorHighlightColors);
+ this.eventBus.dispatch("annotationeditoruimanager", {
+ source: this,
+ uiManager: this.#annotationEditorUIManager
+ });
+ if (mode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) {
+ this.#annotationEditorUIManager.updateMode(mode);
+ }
+ } else {
+ console.error(`Invalid AnnotationEditor mode: ${mode}`);
+ }
+ }
+ const viewerElement = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE ? null : this.viewer;
+ const scale = this.currentScale;
+ const viewport = firstPdfPage.getViewport({
+ scale: scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS
+ });
+ this.viewer.style.setProperty("--scale-factor", viewport.scale);
+ if (this.pageColors?.foreground === "CanvasText" || this.pageColors?.background === "Canvas") {
+ this.viewer.style.setProperty("--hcm-highlight-filter", pdfDocument.filterFactory.addHighlightHCMFilter("CanvasText", "Canvas", "HighlightText", "Highlight"));
+ }
+ for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
+ const pageView = new _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__.PDFPageView({
+ container: viewerElement,
+ eventBus: this.eventBus,
+ id: pageNum,
+ scale,
+ defaultViewport: viewport.clone(),
+ optionalContentConfigPromise,
+ renderingQueue: this.renderingQueue,
+ textLayerMode,
+ annotationMode,
+ imageResourcesPath: this.imageResourcesPath,
+ isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
+ maxCanvasPixels: this.maxCanvasPixels,
+ pageColors: this.pageColors,
+ l10n: this.l10n,
+ layerProperties: this._layerProperties
+ });
+ this._pages.push(pageView);
+ }
+ const firstPageView = this._pages[0];
+ if (firstPageView) {
+ firstPageView.setPdfPage(firstPdfPage);
+ this.linkService.cachePageRef(1, firstPdfPage.ref);
+ }
+ if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ this.#ensurePageViewVisible();
+ } else if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) {
+ this._updateSpreadMode();
+ }
+ this.#onePageRenderedOrForceFetch().then(async () => {
+ this.findController?.setDocument(pdfDocument);
+ this._scriptingManager?.setDocument(pdfDocument);
+ if (this.#hiddenCopyElement) {
+ this.#copyCallbackBound = this.#copyCallback.bind(this, textLayerMode);
+ document.addEventListener("copy", this.#copyCallbackBound);
+ }
+ if (this.#annotationEditorUIManager) {
+ this.eventBus.dispatch("annotationeditormodechanged", {
+ source: this,
+ mode: this.#annotationEditorMode
+ });
+ }
+ if (pdfDocument.loadingParams.disableAutoFetch || pagesCount > PagesCountLimit.FORCE_LAZY_PAGE_INIT) {
+ this._pagesCapability.resolve();
+ return;
+ }
+ let getPagesLeft = pagesCount - 1;
+ if (getPagesLeft <= 0) {
+ this._pagesCapability.resolve();
+ return;
+ }
+ for (let pageNum = 2; pageNum <= pagesCount; ++pageNum) {
+ const promise = pdfDocument.getPage(pageNum).then(pdfPage => {
+ const pageView = this._pages[pageNum - 1];
+ if (!pageView.pdfPage) {
+ pageView.setPdfPage(pdfPage);
+ }
+ this.linkService.cachePageRef(pageNum, pdfPage.ref);
+ if (--getPagesLeft === 0) {
+ this._pagesCapability.resolve();
+ }
+ }, reason => {
+ console.error(`Unable to get page ${pageNum} to initialize viewer`, reason);
+ if (--getPagesLeft === 0) {
+ this._pagesCapability.resolve();
+ }
+ });
+ if (pageNum % PagesCountLimit.PAUSE_EAGER_PAGE_INIT === 0) {
+ await promise;
+ }
+ }
+ });
+ this.eventBus.dispatch("pagesinit", {
+ source: this
+ });
+ pdfDocument.getMetadata().then(({
+ info
+ }) => {
+ if (pdfDocument !== this.pdfDocument) {
+ return;
+ }
+ if (info.Language) {
+ this.viewer.lang = info.Language;
+ }
+ });
+ if (this.defaultRenderingQueue) {
+ this.update();
+ }
+ }).catch(reason => {
+ console.error("Unable to initialize viewer", reason);
+ this._pagesCapability.reject(reason);
+ });
+ }
+ setPageLabels(labels) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ if (!labels) {
+ this._pageLabels = null;
+ } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) {
+ this._pageLabels = null;
+ console.error(`setPageLabels: Invalid page labels.`);
+ } else {
+ this._pageLabels = labels;
+ }
+ for (let i = 0, ii = this._pages.length; i < ii; i++) {
+ this._pages[i].setPageLabel(this._pageLabels?.[i] ?? null);
+ }
+ }
+ _resetView() {
+ this._pages = [];
+ this._currentPageNumber = 1;
+ this._currentScale = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE;
+ this._currentScaleValue = null;
+ this._pageLabels = null;
+ this.#buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
+ this._location = null;
+ this._pagesRotation = 0;
+ this._optionalContentConfigPromise = null;
+ this._firstPageCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();
+ this._onePageRenderedCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();
+ this._pagesCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability();
+ this._scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL;
+ this._previousScrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.UNKNOWN;
+ this._spreadMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE;
+ this.#scrollModePageState = {
+ previousPageNumber: 1,
+ scrollDown: true,
+ pages: []
+ };
+ if (this._onBeforeDraw) {
+ this.eventBus._off("pagerender", this._onBeforeDraw);
+ this._onBeforeDraw = null;
+ }
+ if (this._onAfterDraw) {
+ this.eventBus._off("pagerendered", this._onAfterDraw);
+ this._onAfterDraw = null;
+ }
+ if (this.#onVisibilityChange) {
+ document.removeEventListener("visibilitychange", this.#onVisibilityChange);
+ this.#onVisibilityChange = null;
+ }
+ this.viewer.textContent = "";
+ this._updateScrollMode();
+ this.viewer.removeAttribute("lang");
+ if (this.#hiddenCopyElement) {
+ document.removeEventListener("copy", this.#copyCallbackBound);
+ this.#copyCallbackBound = null;
+ this.#hiddenCopyElement.remove();
+ this.#hiddenCopyElement = null;
+ }
+ }
+ #ensurePageViewVisible() {
+ if (this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ throw new Error("#ensurePageViewVisible: Invalid scrollMode value.");
+ }
+ const pageNumber = this._currentPageNumber,
+ state = this.#scrollModePageState,
+ viewer = this.viewer;
+ viewer.textContent = "";
+ state.pages.length = 0;
+ if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && !this.isInPresentationMode) {
+ const pageView = this._pages[pageNumber - 1];
+ viewer.append(pageView.div);
+ state.pages.push(pageView);
+ } else {
+ const pageIndexSet = new Set(),
+ parity = this._spreadMode - 1;
+ if (parity === -1) {
+ pageIndexSet.add(pageNumber - 1);
+ } else if (pageNumber % 2 !== parity) {
+ pageIndexSet.add(pageNumber - 1);
+ pageIndexSet.add(pageNumber);
+ } else {
+ pageIndexSet.add(pageNumber - 2);
+ pageIndexSet.add(pageNumber - 1);
+ }
+ const spread = document.createElement("div");
+ spread.className = "spread";
+ if (this.isInPresentationMode) {
+ const dummyPage = document.createElement("div");
+ dummyPage.className = "dummyPage";
+ spread.append(dummyPage);
+ }
+ for (const i of pageIndexSet) {
+ const pageView = this._pages[i];
+ if (!pageView) {
+ continue;
+ }
+ spread.append(pageView.div);
+ state.pages.push(pageView);
+ }
+ viewer.append(spread);
+ }
+ state.scrollDown = pageNumber >= state.previousPageNumber;
+ state.previousPageNumber = pageNumber;
+ }
+ _scrollUpdate() {
+ if (this.pagesCount === 0) {
+ return;
+ }
+ this.update();
+ }
+ #scrollIntoView(pageView, pageSpot = null) {
+ const {
+ div,
+ id
+ } = pageView;
+ if (this._currentPageNumber !== id) {
+ this._setCurrentPageNumber(id);
+ }
+ if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ this.#ensurePageViewVisible();
+ this.update();
+ }
+ if (!pageSpot && !this.isInPresentationMode) {
+ const left = div.offsetLeft + div.clientLeft,
+ right = left + div.clientWidth;
+ const {
+ scrollLeft,
+ clientWidth
+ } = this.container;
+ if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL || left < scrollLeft || right > scrollLeft + clientWidth) {
+ pageSpot = {
+ left: 0,
+ top: 0
+ };
+ }
+ }
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.scrollIntoView)(div, pageSpot);
+ if (!this._currentScaleValue && this._location) {
+ this._location = null;
+ }
+ }
+ #isSameScale(newScale) {
+ return newScale === this._currentScale || Math.abs(newScale - this._currentScale) < 1e-15;
+ }
+ #setScaleUpdatePages(newScale, newValue, {
+ noScroll = false,
+ preset = false,
+ drawingDelay = -1
+ }) {
+ this._currentScaleValue = newValue.toString();
+ if (this.#isSameScale(newScale)) {
+ if (preset) {
+ this.eventBus.dispatch("scalechanging", {
+ source: this,
+ scale: newScale,
+ presetValue: newValue
+ });
+ }
+ return;
+ }
+ this.viewer.style.setProperty("--scale-factor", newScale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS);
+ const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000;
+ this.refresh(true, {
+ scale: newScale,
+ drawingDelay: postponeDrawing ? drawingDelay : -1
+ });
+ if (postponeDrawing) {
+ this.#scaleTimeoutId = setTimeout(() => {
+ this.#scaleTimeoutId = null;
+ this.refresh();
+ }, drawingDelay);
+ }
+ this._currentScale = newScale;
+ if (!noScroll) {
+ let page = this._currentPageNumber,
+ dest;
+ if (this._location && !(this.isInPresentationMode || this.isChangingPresentationMode)) {
+ page = this._location.pageNumber;
+ dest = [null, {
+ name: "XYZ"
+ }, this._location.left, this._location.top, null];
+ }
+ this.scrollPageIntoView({
+ pageNumber: page,
+ destArray: dest,
+ allowNegativeOffset: true
+ });
+ }
+ this.eventBus.dispatch("scalechanging", {
+ source: this,
+ scale: newScale,
+ presetValue: preset ? newValue : undefined
+ });
+ if (this.defaultRenderingQueue) {
+ this.update();
+ }
+ }
+ get #pageWidthScaleFactor() {
+ if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL) {
+ return 2;
+ }
+ return 1;
+ }
+ #setScale(value, options) {
+ let scale = parseFloat(value);
+ if (scale > 0) {
+ options.preset = false;
+ this.#setScaleUpdatePages(scale, value, options);
+ } else {
+ const currentPage = this._pages[this._currentPageNumber - 1];
+ if (!currentPage) {
+ return;
+ }
+ let hPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SCROLLBAR_PADDING,
+ vPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.VERTICAL_PADDING;
+ if (this.isInPresentationMode) {
+ hPadding = vPadding = 4;
+ if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) {
+ hPadding *= 2;
+ }
+ } else if (this.removePageBorders) {
+ hPadding = vPadding = 0;
+ } else if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL) {
+ [hPadding, vPadding] = [vPadding, hPadding];
+ }
+ const pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale / this.#pageWidthScaleFactor;
+ const pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale;
+ switch (value) {
+ case "page-actual":
+ scale = 1;
+ break;
+ case "page-width":
+ scale = pageWidthScale;
+ break;
+ case "page-height":
+ scale = pageHeightScale;
+ break;
+ case "page-fit":
+ scale = Math.min(pageWidthScale, pageHeightScale);
+ break;
+ case "auto":
+ const horizontalScale = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isPortraitOrientation)(currentPage) ? pageWidthScale : Math.min(pageHeightScale, pageWidthScale);
+ scale = Math.min(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_AUTO_SCALE, horizontalScale);
+ break;
+ default:
+ console.error(`#setScale: "${value}" is an unknown zoom value.`);
+ return;
+ }
+ options.preset = true;
+ this.#setScaleUpdatePages(scale, value, options);
+ }
+ }
+ #resetCurrentPageView() {
+ const pageView = this._pages[this._currentPageNumber - 1];
+ if (this.isInPresentationMode) {
+ this.#setScale(this._currentScaleValue, {
+ noScroll: true
+ });
+ }
+ this.#scrollIntoView(pageView);
+ }
+ pageLabelToPageNumber(label) {
+ if (!this._pageLabels) {
+ return null;
+ }
+ const i = this._pageLabels.indexOf(label);
+ if (i < 0) {
+ return null;
+ }
+ return i + 1;
+ }
+ scrollPageIntoView({
+ pageNumber,
+ destArray = null,
+ allowNegativeOffset = false,
+ ignoreDestinationZoom = false
+ }) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ const pageView = Number.isInteger(pageNumber) && this._pages[pageNumber - 1];
+ if (!pageView) {
+ console.error(`scrollPageIntoView: "${pageNumber}" is not a valid pageNumber parameter.`);
+ return;
+ }
+ if (this.isInPresentationMode || !destArray) {
+ this._setCurrentPageNumber(pageNumber, true);
+ return;
+ }
+ let x = 0,
+ y = 0;
+ let width = 0,
+ height = 0,
+ widthScale,
+ heightScale;
+ const changeOrientation = pageView.rotation % 180 !== 0;
+ const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS;
+ const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS;
+ let scale = 0;
+ switch (destArray[1].name) {
+ case "XYZ":
+ x = destArray[2];
+ y = destArray[3];
+ scale = destArray[4];
+ x = x !== null ? x : 0;
+ y = y !== null ? y : pageHeight;
+ break;
+ case "Fit":
+ case "FitB":
+ scale = "page-fit";
+ break;
+ case "FitH":
+ case "FitBH":
+ y = destArray[2];
+ scale = "page-width";
+ if (y === null && this._location) {
+ x = this._location.left;
+ y = this._location.top;
+ } else if (typeof y !== "number" || y < 0) {
+ y = pageHeight;
+ }
+ break;
+ case "FitV":
+ case "FitBV":
+ x = destArray[2];
+ width = pageWidth;
+ height = pageHeight;
+ scale = "page-height";
+ break;
+ case "FitR":
+ x = destArray[2];
+ y = destArray[3];
+ width = destArray[4] - x;
+ height = destArray[5] - y;
+ let hPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SCROLLBAR_PADDING,
+ vPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.VERTICAL_PADDING;
+ if (this.removePageBorders) {
+ hPadding = vPadding = 0;
+ }
+ widthScale = (this.container.clientWidth - hPadding) / width / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS;
+ heightScale = (this.container.clientHeight - vPadding) / height / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS;
+ scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
+ break;
+ default:
+ console.error(`scrollPageIntoView: "${destArray[1].name}" is not a valid destination type.`);
+ return;
+ }
+ if (!ignoreDestinationZoom) {
+ if (scale && scale !== this._currentScale) {
+ this.currentScaleValue = scale;
+ } else if (this._currentScale === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE) {
+ this.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_VALUE;
+ }
+ }
+ if (scale === "page-fit" && !destArray[4]) {
+ this.#scrollIntoView(pageView);
+ return;
+ }
+ const boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)];
+ let left = Math.min(boundingRect[0][0], boundingRect[1][0]);
+ let top = Math.min(boundingRect[0][1], boundingRect[1][1]);
+ if (!allowNegativeOffset) {
+ left = Math.max(left, 0);
+ top = Math.max(top, 0);
+ }
+ this.#scrollIntoView(pageView, {
+ left,
+ top
+ });
+ }
+ _updateLocation(firstPage) {
+ const currentScale = this._currentScale;
+ const currentScaleValue = this._currentScaleValue;
+ const normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue;
+ const pageNumber = firstPage.id;
+ const currentPageView = this._pages[pageNumber - 1];
+ const container = this.container;
+ const topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y);
+ const intLeft = Math.round(topLeft[0]);
+ const intTop = Math.round(topLeft[1]);
+ let pdfOpenParams = `#page=${pageNumber}`;
+ if (!this.isInPresentationMode) {
+ pdfOpenParams += `&zoom=${normalizedScaleValue},${intLeft},${intTop}`;
+ }
+ this._location = {
+ pageNumber,
+ scale: normalizedScaleValue,
+ top: intTop,
+ left: intLeft,
+ rotation: this._pagesRotation,
+ pdfOpenParams
+ };
+ }
+ update() {
+ const visible = this._getVisiblePages();
+ const visiblePages = visible.views,
+ numVisiblePages = visiblePages.length;
+ if (numVisiblePages === 0) {
+ return;
+ }
+ const newCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * numVisiblePages + 1);
+ this.#buffer.resize(newCacheSize, visible.ids);
+ this.renderingQueue.renderHighestPriority(visible);
+ const isSimpleLayout = this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE || this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL);
+ const currentId = this._currentPageNumber;
+ let stillFullyVisible = false;
+ for (const page of visiblePages) {
+ if (page.percent < 100) {
+ break;
+ }
+ if (page.id === currentId && isSimpleLayout) {
+ stillFullyVisible = true;
+ break;
+ }
+ }
+ this._setCurrentPageNumber(stillFullyVisible ? currentId : visiblePages[0].id);
+ this._updateLocation(visible.first);
+ this.eventBus.dispatch("updateviewarea", {
+ source: this,
+ location: this._location
+ });
+ }
+ containsElement(element) {
+ return this.container.contains(element);
+ }
+ focus() {
+ this.container.focus();
+ }
+ get _isContainerRtl() {
+ return getComputedStyle(this.container).direction === "rtl";
+ }
+ get isInPresentationMode() {
+ return this.presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN;
+ }
+ get isChangingPresentationMode() {
+ return this.presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.CHANGING;
+ }
+ get isHorizontalScrollbarEnabled() {
+ return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth;
+ }
+ get isVerticalScrollbarEnabled() {
+ return this.isInPresentationMode ? false : this.container.scrollHeight > this.container.clientHeight;
+ }
+ _getVisiblePages() {
+ const views = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE ? this.#scrollModePageState.pages : this._pages,
+ horizontal = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL,
+ rtl = horizontal && this._isContainerRtl;
+ return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.getVisibleElements)({
+ scrollEl: this.container,
+ views,
+ sortByVisibility: true,
+ horizontal,
+ rtl
+ });
+ }
+ cleanup() {
+ for (const pageView of this._pages) {
+ if (pageView.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED) {
+ pageView.reset();
+ }
+ }
+ }
+ _cancelRendering() {
+ for (const pageView of this._pages) {
+ pageView.cancelRendering();
+ }
+ }
+ async #ensurePdfPageLoaded(pageView) {
+ if (pageView.pdfPage) {
+ return pageView.pdfPage;
+ }
+ try {
+ const pdfPage = await this.pdfDocument.getPage(pageView.id);
+ if (!pageView.pdfPage) {
+ pageView.setPdfPage(pdfPage);
+ }
+ if (!this.linkService._cachedPageNumber?.(pdfPage.ref)) {
+ this.linkService.cachePageRef(pageView.id, pdfPage.ref);
+ }
+ return pdfPage;
+ } catch (reason) {
+ console.error("Unable to get page for page view", reason);
+ return null;
+ }
+ }
+ #getScrollAhead(visible) {
+ if (visible.first?.id === 1) {
+ return true;
+ } else if (visible.last?.id === this.pagesCount) {
+ return false;
+ }
+ switch (this._scrollMode) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE:
+ return this.#scrollModePageState.scrollDown;
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL:
+ return this.scroll.right;
+ }
+ return this.scroll.down;
+ }
+ forceRendering(currentlyVisiblePages) {
+ const visiblePages = currentlyVisiblePages || this._getVisiblePages();
+ const scrollAhead = this.#getScrollAhead(visiblePages);
+ const preRenderExtra = this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL;
+ const pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, scrollAhead, preRenderExtra);
+ if (pageView) {
+ this.#ensurePdfPageLoaded(pageView).then(() => {
+ this.renderingQueue.renderView(pageView);
+ });
+ return true;
+ }
+ return false;
+ }
+ get hasEqualPageSizes() {
+ const firstPageView = this._pages[0];
+ for (let i = 1, ii = this._pages.length; i < ii; ++i) {
+ const pageView = this._pages[i];
+ if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) {
+ return false;
+ }
+ }
+ return true;
+ }
+ getPagesOverview() {
+ let initialOrientation;
+ return this._pages.map(pageView => {
+ const viewport = pageView.pdfPage.getViewport({
+ scale: 1
+ });
+ const orientation = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isPortraitOrientation)(viewport);
+ if (initialOrientation === undefined) {
+ initialOrientation = orientation;
+ } else if (this.enablePrintAutoRotate && orientation !== initialOrientation) {
+ return {
+ width: viewport.height,
+ height: viewport.width,
+ rotation: (viewport.rotation - 90) % 360
+ };
+ }
+ return {
+ width: viewport.width,
+ height: viewport.height,
+ rotation: viewport.rotation
+ };
+ });
+ }
+ get optionalContentConfigPromise() {
+ if (!this.pdfDocument) {
+ return Promise.resolve(null);
+ }
+ if (!this._optionalContentConfigPromise) {
+ console.error("optionalContentConfigPromise: Not initialized yet.");
+ return this.pdfDocument.getOptionalContentConfig();
+ }
+ return this._optionalContentConfigPromise;
+ }
+ set optionalContentConfigPromise(promise) {
+ if (!(promise instanceof Promise)) {
+ throw new Error(`Invalid optionalContentConfigPromise: ${promise}`);
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ if (!this._optionalContentConfigPromise) {
+ return;
+ }
+ this._optionalContentConfigPromise = promise;
+ this.refresh(false, {
+ optionalContentConfigPromise: promise
+ });
+ this.eventBus.dispatch("optionalcontentconfigchanged", {
+ source: this,
+ promise
+ });
+ }
+ get scrollMode() {
+ return this._scrollMode;
+ }
+ set scrollMode(mode) {
+ if (this._scrollMode === mode) {
+ return;
+ }
+ if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidScrollMode)(mode)) {
+ throw new Error(`Invalid scroll mode: ${mode}`);
+ }
+ if (this.pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) {
+ return;
+ }
+ this._previousScrollMode = this._scrollMode;
+ this._scrollMode = mode;
+ this.eventBus.dispatch("scrollmodechanged", {
+ source: this,
+ mode
+ });
+ this._updateScrollMode(this._currentPageNumber);
+ }
+ _updateScrollMode(pageNumber = null) {
+ const scrollMode = this._scrollMode,
+ viewer = this.viewer;
+ viewer.classList.toggle("scrollHorizontal", scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL);
+ viewer.classList.toggle("scrollWrapped", scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.WRAPPED);
+ if (!this.pdfDocument || !pageNumber) {
+ return;
+ }
+ if (scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ this.#ensurePageViewVisible();
+ } else if (this._previousScrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ this._updateSpreadMode();
+ }
+ if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
+ this.#setScale(this._currentScaleValue, {
+ noScroll: true
+ });
+ }
+ this._setCurrentPageNumber(pageNumber, true);
+ this.update();
+ }
+ get spreadMode() {
+ return this._spreadMode;
+ }
+ set spreadMode(mode) {
+ if (this._spreadMode === mode) {
+ return;
+ }
+ if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidSpreadMode)(mode)) {
+ throw new Error(`Invalid spread mode: ${mode}`);
+ }
+ this._spreadMode = mode;
+ this.eventBus.dispatch("spreadmodechanged", {
+ source: this,
+ mode
+ });
+ this._updateSpreadMode(this._currentPageNumber);
+ }
+ _updateSpreadMode(pageNumber = null) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ const viewer = this.viewer,
+ pages = this._pages;
+ if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) {
+ this.#ensurePageViewVisible();
+ } else {
+ viewer.textContent = "";
+ if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) {
+ for (const pageView of this._pages) {
+ viewer.append(pageView.div);
+ }
+ } else {
+ const parity = this._spreadMode - 1;
+ let spread = null;
+ for (let i = 0, ii = pages.length; i < ii; ++i) {
+ if (spread === null) {
+ spread = document.createElement("div");
+ spread.className = "spread";
+ viewer.append(spread);
+ } else if (i % 2 === parity) {
+ spread = spread.cloneNode(false);
+ viewer.append(spread);
+ }
+ spread.append(pages[i].div);
+ }
+ }
+ }
+ if (!pageNumber) {
+ return;
+ }
+ if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
+ this.#setScale(this._currentScaleValue, {
+ noScroll: true
+ });
+ }
+ this._setCurrentPageNumber(pageNumber, true);
+ this.update();
+ }
+ _getPageAdvance(currentPageNumber, previous = false) {
+ switch (this._scrollMode) {
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.WRAPPED:
+ {
+ const {
+ views
+ } = this._getVisiblePages(),
+ pageLayout = new Map();
+ for (const {
+ id,
+ y,
+ percent,
+ widthPercent
+ } of views) {
+ if (percent === 0 || widthPercent < 100) {
+ continue;
+ }
+ let yArray = pageLayout.get(y);
+ if (!yArray) {
+ pageLayout.set(y, yArray ||= []);
+ }
+ yArray.push(id);
+ }
+ for (const yArray of pageLayout.values()) {
+ const currentIndex = yArray.indexOf(currentPageNumber);
+ if (currentIndex === -1) {
+ continue;
+ }
+ const numPages = yArray.length;
+ if (numPages === 1) {
+ break;
+ }
+ if (previous) {
+ for (let i = currentIndex - 1, ii = 0; i >= ii; i--) {
+ const currentId = yArray[i],
+ expectedId = yArray[i + 1] - 1;
+ if (currentId < expectedId) {
+ return currentPageNumber - expectedId;
+ }
+ }
+ } else {
+ for (let i = currentIndex + 1, ii = numPages; i < ii; i++) {
+ const currentId = yArray[i],
+ expectedId = yArray[i - 1] + 1;
+ if (currentId > expectedId) {
+ return expectedId - currentPageNumber;
+ }
+ }
+ }
+ if (previous) {
+ const firstId = yArray[0];
+ if (firstId < currentPageNumber) {
+ return currentPageNumber - firstId + 1;
+ }
+ } else {
+ const lastId = yArray[numPages - 1];
+ if (lastId > currentPageNumber) {
+ return lastId - currentPageNumber + 1;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL:
+ {
+ break;
+ }
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE:
+ case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL:
+ {
+ if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) {
+ break;
+ }
+ const parity = this._spreadMode - 1;
+ if (previous && currentPageNumber % 2 !== parity) {
+ break;
+ } else if (!previous && currentPageNumber % 2 === parity) {
+ break;
+ }
+ const {
+ views
+ } = this._getVisiblePages(),
+ expectedId = previous ? currentPageNumber - 1 : currentPageNumber + 1;
+ for (const {
+ id,
+ percent,
+ widthPercent
+ } of views) {
+ if (id !== expectedId) {
+ continue;
+ }
+ if (percent > 0 && widthPercent === 100) {
+ return 2;
+ }
+ break;
+ }
+ break;
+ }
+ }
+ return 1;
+ }
+ nextPage() {
+ const currentPageNumber = this._currentPageNumber,
+ pagesCount = this.pagesCount;
+ if (currentPageNumber >= pagesCount) {
+ return false;
+ }
+ const advance = this._getPageAdvance(currentPageNumber, false) || 1;
+ this.currentPageNumber = Math.min(currentPageNumber + advance, pagesCount);
+ return true;
+ }
+ previousPage() {
+ const currentPageNumber = this._currentPageNumber;
+ if (currentPageNumber <= 1) {
+ return false;
+ }
+ const advance = this._getPageAdvance(currentPageNumber, true) || 1;
+ this.currentPageNumber = Math.max(currentPageNumber - advance, 1);
+ return true;
+ }
+ increaseScale({
+ drawingDelay,
+ scaleFactor,
+ steps
+ } = {}) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ let newScale = this._currentScale;
+ if (scaleFactor > 1) {
+ newScale = Math.round(newScale * scaleFactor * 100) / 100;
+ } else {
+ steps ??= 1;
+ do {
+ newScale = Math.ceil((newScale * _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10;
+ } while (--steps > 0 && newScale < _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE);
+ }
+ this.#setScale(Math.min(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE, newScale), {
+ noScroll: false,
+ drawingDelay
+ });
+ }
+ decreaseScale({
+ drawingDelay,
+ scaleFactor,
+ steps
+ } = {}) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ let newScale = this._currentScale;
+ if (scaleFactor > 0 && scaleFactor < 1) {
+ newScale = Math.round(newScale * scaleFactor * 100) / 100;
+ } else {
+ steps ??= 1;
+ do {
+ newScale = Math.floor((newScale / _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10;
+ } while (--steps > 0 && newScale > _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE);
+ }
+ this.#setScale(Math.max(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE, newScale), {
+ noScroll: false,
+ drawingDelay
+ });
+ }
+ #updateContainerHeightCss(height = this.container.clientHeight) {
+ if (height !== this.#previousContainerHeight) {
+ this.#previousContainerHeight = height;
+ _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.docStyle.setProperty("--viewer-container-height", `${height}px`);
+ }
+ }
+ #resizeObserverCallback(entries) {
+ for (const entry of entries) {
+ if (entry.target === this.container) {
+ this.#updateContainerHeightCss(Math.floor(entry.borderBoxSize[0].blockSize));
+ this.#containerTopLeft = null;
+ break;
+ }
+ }
+ }
+ get containerTopLeft() {
+ return this.#containerTopLeft ||= [this.container.offsetTop, this.container.offsetLeft];
+ }
+ get annotationEditorMode() {
+ return this.#annotationEditorUIManager ? this.#annotationEditorMode : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE;
+ }
+ set annotationEditorMode({
+ mode,
+ editId = null,
+ isFromKeyboard = false
+ }) {
+ if (!this.#annotationEditorUIManager) {
+ throw new Error(`The AnnotationEditor is not enabled.`);
+ }
+ if (this.#annotationEditorMode === mode) {
+ return;
+ }
+ if (!isValidAnnotationEditorMode(mode)) {
+ throw new Error(`Invalid AnnotationEditor mode: ${mode}`);
+ }
+ if (!this.pdfDocument) {
+ return;
+ }
+ this.#annotationEditorMode = mode;
+ this.eventBus.dispatch("annotationeditormodechanged", {
+ source: this,
+ mode
+ });
+ this.#annotationEditorUIManager.updateMode(mode, editId, isFromKeyboard);
+ }
+ set annotationEditorParams({
+ type,
+ value
+ }) {
+ if (!this.#annotationEditorUIManager) {
+ throw new Error(`The AnnotationEditor is not enabled.`);
+ }
+ this.#annotationEditorUIManager.updateParams(type, value);
+ }
+ refresh(noUpdate = false, updateArgs = Object.create(null)) {
+ if (!this.pdfDocument) {
+ return;
+ }
+ for (const pageView of this._pages) {
+ pageView.update(updateArgs);
+ }
+ if (this.#scaleTimeoutId !== null) {
+ clearTimeout(this.#scaleTimeoutId);
+ this.#scaleTimeoutId = null;
+ }
+ if (!noUpdate) {
+ this.update();
+ }
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1869:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AbortException: () => (/* binding */ AbortException),
+/* harmony export */ AnnotationEditorLayer: () => (/* binding */ AnnotationEditorLayer),
+/* harmony export */ AnnotationEditorParamsType: () => (/* binding */ AnnotationEditorParamsType),
+/* harmony export */ AnnotationEditorType: () => (/* binding */ AnnotationEditorType),
+/* harmony export */ AnnotationEditorUIManager: () => (/* binding */ AnnotationEditorUIManager),
+/* harmony export */ AnnotationLayer: () => (/* binding */ AnnotationLayer),
+/* harmony export */ AnnotationMode: () => (/* binding */ AnnotationMode),
+/* harmony export */ ColorPicker: () => (/* binding */ ColorPicker),
+/* harmony export */ DOMSVGFactory: () => (/* binding */ DOMSVGFactory),
+/* harmony export */ DrawLayer: () => (/* binding */ DrawLayer),
+/* harmony export */ FeatureTest: () => (/* binding */ FeatureTest),
+/* harmony export */ GlobalWorkerOptions: () => (/* binding */ GlobalWorkerOptions),
+/* harmony export */ InvalidPDFException: () => (/* binding */ InvalidPDFException),
+/* harmony export */ MissingPDFException: () => (/* binding */ MissingPDFException),
+/* harmony export */ PDFDateString: () => (/* binding */ PDFDateString),
+/* harmony export */ PDFWorker: () => (/* binding */ PDFWorker),
+/* harmony export */ PasswordResponses: () => (/* binding */ PasswordResponses),
+/* harmony export */ PermissionFlag: () => (/* binding */ PermissionFlag),
+/* harmony export */ PixelsPerInch: () => (/* binding */ PixelsPerInch),
+/* harmony export */ PromiseCapability: () => (/* binding */ PromiseCapability),
+/* harmony export */ RenderingCancelledException: () => (/* binding */ RenderingCancelledException),
+/* harmony export */ UnexpectedResponseException: () => (/* binding */ UnexpectedResponseException),
+/* harmony export */ XfaLayer: () => (/* binding */ XfaLayer),
+/* harmony export */ build: () => (/* binding */ build),
+/* harmony export */ createValidAbsoluteUrl: () => (/* binding */ createValidAbsoluteUrl),
+/* harmony export */ fetchData: () => (/* binding */ fetchData),
+/* harmony export */ getDocument: () => (/* binding */ getDocument),
+/* harmony export */ getFilenameFromUrl: () => (/* binding */ getFilenameFromUrl),
+/* harmony export */ getPdfFilenameFromUrl: () => (/* binding */ getPdfFilenameFromUrl),
+/* harmony export */ getXfaPageViewport: () => (/* binding */ getXfaPageViewport),
+/* harmony export */ isDataScheme: () => (/* binding */ isDataScheme),
+/* harmony export */ isPdfFile: () => (/* binding */ isPdfFile),
+/* harmony export */ noContextMenu: () => (/* binding */ noContextMenu),
+/* harmony export */ normalizeUnicode: () => (/* binding */ normalizeUnicode),
+/* harmony export */ renderTextLayer: () => (/* binding */ renderTextLayer),
+/* harmony export */ setLayerDimensions: () => (/* binding */ setLayerDimensions),
+/* harmony export */ shadow: () => (/* binding */ shadow),
+/* harmony export */ updateTextLayer: () => (/* binding */ updateTextLayer),
+/* harmony export */ version: () => (/* binding */ version)
+/* harmony export */ });
+/* unused harmony exports CMapCompressionType, ImageKind, OPS, Outliner, PDFDataRangeTransport, Util, VerbosityLevel */
+if (!globalThis.pdfjsLib) {
+ await globalThis.pdfjsLibPromise;
+}
+const {
+ AbortException,
+ AnnotationEditorLayer,
+ AnnotationEditorParamsType,
+ AnnotationEditorType,
+ AnnotationEditorUIManager,
+ AnnotationLayer,
+ AnnotationMode,
+ build,
+ CMapCompressionType,
+ ColorPicker,
+ createValidAbsoluteUrl,
+ DOMSVGFactory,
+ DrawLayer,
+ FeatureTest,
+ fetchData,
+ getDocument,
+ getFilenameFromUrl,
+ getPdfFilenameFromUrl,
+ getXfaPageViewport,
+ GlobalWorkerOptions,
+ ImageKind,
+ InvalidPDFException,
+ isDataScheme,
+ isPdfFile,
+ MissingPDFException,
+ noContextMenu,
+ normalizeUnicode,
+ OPS,
+ Outliner,
+ PasswordResponses,
+ PDFDataRangeTransport,
+ PDFDateString,
+ PDFWorker,
+ PermissionFlag,
+ PixelsPerInch,
+ PromiseCapability,
+ RenderingCancelledException,
+ renderTextLayer,
+ setLayerDimensions,
+ shadow,
+ UnexpectedResponseException,
+ updateTextLayer,
+ Util,
+ VerbosityLevel,
+ version,
+ XfaLayer
+} = globalThis.pdfjsLib;
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } }, 1);
+
+/***/ }),
+
+/***/ 216:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ BasePreferences: () => (/* binding */ BasePreferences)
+/* harmony export */ });
+/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8961);
+
+class BasePreferences {
+ #defaults = Object.freeze({
+ "annotationEditorMode": 0,
+ "annotationMode": 2,
+ "cursorToolOnLoad": 0,
+ "defaultZoomDelay": 400,
+ "defaultZoomValue": "",
+ "disablePageLabels": false,
+ "enableHighlightEditor": false,
+ "enablePermissions": false,
+ "enablePrintAutoRotate": true,
+ "enableScripting": true,
+ "externalLinkTarget": 0,
+ "highlightEditorColors": "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F",
+ "historyUpdateUrl": false,
+ "ignoreDestinationZoom": false,
+ "forcePageColors": false,
+ "pageColorsBackground": "Canvas",
+ "pageColorsForeground": "CanvasText",
+ "pdfBugEnabled": false,
+ "sidebarViewOnLoad": -1,
+ "scrollModeOnLoad": -1,
+ "spreadModeOnLoad": -1,
+ "textLayerMode": 1,
+ "viewOnLoad": 0,
+ "disableAutoFetch": false,
+ "disableFontFace": false,
+ "disableRange": false,
+ "disableStream": false,
+ "enableXfa": true,
+ "viewerCssTheme": 0
+ });
+ #prefs = Object.create(null);
+ #initializedPromise = null;
+ constructor() {
+ if (this.constructor === BasePreferences) {
+ throw new Error("Cannot initialize BasePreferences.");
+ }
+ this.#initializedPromise = this._readFromStorage(this.#defaults).then(({
+ browserPrefs,
+ prefs
+ }) => {
+ const BROWSER_PREFS = {
+ "canvasMaxAreaInBytes": -1,
+ "isInAutomation": false,
+ "supportsDocumentFonts": true,
+ "supportsIntegratedFind": false,
+ "supportsMouseWheelZoomCtrlKey": true,
+ "supportsMouseWheelZoomMetaKey": true,
+ "supportsPinchToZoom": true
+ };
+ const options = Object.create(null);
+ for (const [name, defaultVal] of Object.entries(BROWSER_PREFS)) {
+ const prefVal = browserPrefs?.[name];
+ options[name] = typeof prefVal === typeof defaultVal ? prefVal : defaultVal;
+ }
+ for (const [name, defaultVal] of Object.entries(this.#defaults)) {
+ const prefVal = prefs?.[name];
+ options[name] = this.#prefs[name] = typeof prefVal === typeof defaultVal ? prefVal : defaultVal;
+ }
+ _app_options_js__WEBPACK_IMPORTED_MODULE_0__.AppOptions.setAll(options, true);
+ });
+ }
+ async _writeToStorage(prefObj) {
+ throw new Error("Not implemented: _writeToStorage");
+ }
+ async _readFromStorage(prefObj) {
+ throw new Error("Not implemented: _readFromStorage");
+ }
+ async reset() {
+ await this.#initializedPromise;
+ const prefs = this.#prefs;
+ this.#prefs = Object.create(null);
+ return this._writeToStorage(this.#defaults).catch(reason => {
+ this.#prefs = prefs;
+ throw reason;
+ });
+ }
+ async set(name, value) {
+ await this.#initializedPromise;
+ const defaultValue = this.#defaults[name],
+ prefs = this.#prefs;
+ if (defaultValue === undefined) {
+ throw new Error(`Set preference: "${name}" is undefined.`);
+ } else if (value === undefined) {
+ throw new Error("Set preference: no value is specified.");
+ }
+ const valueType = typeof value,
+ defaultType = typeof defaultValue;
+ if (valueType !== defaultType) {
+ if (valueType === "number" && defaultType === "string") {
+ value = value.toString();
+ } else {
+ throw new Error(`Set preference: "${value}" is a ${valueType}, expected a ${defaultType}.`);
+ }
+ } else if (valueType === "number" && !Number.isInteger(value)) {
+ throw new Error(`Set preference: "${value}" must be an integer.`);
+ }
+ this.#prefs[name] = value;
+ return this._writeToStorage(this.#prefs).catch(reason => {
+ this.#prefs = prefs;
+ throw reason;
+ });
+ }
+ async get(name) {
+ await this.#initializedPromise;
+ const defaultValue = this.#defaults[name];
+ if (defaultValue === undefined) {
+ throw new Error(`Get preference: "${name}" is undefined.`);
+ }
+ return this.#prefs[name] ?? defaultValue;
+ }
+ get initializedPromise() {
+ return this.#initializedPromise;
+ }
+}
+
+
+/***/ }),
+
+/***/ 4552:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ getXfaHtmlForPrinting: () => (/* binding */ getXfaHtmlForPrinting)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3234);
+/* harmony import */ var _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8012);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__]);
+([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+function getXfaHtmlForPrinting(printContainer, pdfDocument) {
+ const xfaHtml = pdfDocument.allXfaHtml;
+ const linkService = new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_1__.SimpleLinkService();
+ const scale = Math.round(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS * 100) / 100;
+ for (const xfaPage of xfaHtml.children) {
+ const page = document.createElement("div");
+ page.className = "xfaPrintedPage";
+ printContainer.append(page);
+ const builder = new _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__.XfaLayerBuilder({
+ pdfPage: null,
+ annotationStorage: pdfDocument.annotationStorage,
+ linkService,
+ xfaHtml: xfaPage
+ });
+ const viewport = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.getXfaPageViewport)(xfaPage, {
+ scale
+ });
+ builder.render(viewport, "print");
+ page.append(builder.div);
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 1544:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ SecondaryToolbar: () => (/* binding */ SecondaryToolbar)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+/* harmony import */ var _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9290);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__]);
+_pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+class SecondaryToolbar {
+ #opts;
+ constructor(options, eventBus) {
+ this.#opts = options;
+ const buttons = [{
+ element: options.presentationModeButton,
+ eventName: "presentationmode",
+ close: true
+ }, {
+ element: options.printButton,
+ eventName: "print",
+ close: true
+ }, {
+ element: options.downloadButton,
+ eventName: "download",
+ close: true
+ }, {
+ element: options.viewBookmarkButton,
+ eventName: null,
+ close: true
+ }, {
+ element: options.firstPageButton,
+ eventName: "firstpage",
+ close: true
+ }, {
+ element: options.lastPageButton,
+ eventName: "lastpage",
+ close: true
+ }, {
+ element: options.pageRotateCwButton,
+ eventName: "rotatecw",
+ close: false
+ }, {
+ element: options.pageRotateCcwButton,
+ eventName: "rotateccw",
+ close: false
+ }, {
+ element: options.cursorSelectToolButton,
+ eventName: "switchcursortool",
+ eventDetails: {
+ tool: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT
+ },
+ close: true
+ }, {
+ element: options.cursorHandToolButton,
+ eventName: "switchcursortool",
+ eventDetails: {
+ tool: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND
+ },
+ close: true
+ }, {
+ element: options.scrollPageButton,
+ eventName: "switchscrollmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE
+ },
+ close: true
+ }, {
+ element: options.scrollVerticalButton,
+ eventName: "switchscrollmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL
+ },
+ close: true
+ }, {
+ element: options.scrollHorizontalButton,
+ eventName: "switchscrollmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL
+ },
+ close: true
+ }, {
+ element: options.scrollWrappedButton,
+ eventName: "switchscrollmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.WRAPPED
+ },
+ close: true
+ }, {
+ element: options.spreadNoneButton,
+ eventName: "switchspreadmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE
+ },
+ close: true
+ }, {
+ element: options.spreadOddButton,
+ eventName: "switchspreadmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.ODD
+ },
+ close: true
+ }, {
+ element: options.spreadEvenButton,
+ eventName: "switchspreadmode",
+ eventDetails: {
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.EVEN
+ },
+ close: true
+ }, {
+ element: options.documentPropertiesButton,
+ eventName: "documentproperties",
+ close: true
+ }];
+ buttons.push({
+ element: options.openFileButton,
+ eventName: "openfile",
+ close: true
+ });
+ this.eventBus = eventBus;
+ this.opened = false;
+ this.#bindListeners(buttons);
+ this.reset();
+ }
+ get isOpen() {
+ return this.opened;
+ }
+ setPageNumber(pageNumber) {
+ this.pageNumber = pageNumber;
+ this.#updateUIState();
+ }
+ setPagesCount(pagesCount) {
+ this.pagesCount = pagesCount;
+ this.#updateUIState();
+ }
+ reset() {
+ this.pageNumber = 0;
+ this.pagesCount = 0;
+ this.#updateUIState();
+ this.#scrollModeChanged({
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL
+ });
+ this.#spreadModeChanged({
+ mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE
+ });
+ }
+ #updateUIState() {
+ const {
+ firstPageButton,
+ lastPageButton,
+ pageRotateCwButton,
+ pageRotateCcwButton
+ } = this.#opts;
+ firstPageButton.disabled = this.pageNumber <= 1;
+ lastPageButton.disabled = this.pageNumber >= this.pagesCount;
+ pageRotateCwButton.disabled = this.pagesCount === 0;
+ pageRotateCcwButton.disabled = this.pagesCount === 0;
+ }
+ #bindListeners(buttons) {
+ const {
+ eventBus
+ } = this;
+ const {
+ toggleButton
+ } = this.#opts;
+ toggleButton.addEventListener("click", this.toggle.bind(this));
+ for (const {
+ element,
+ eventName,
+ close,
+ eventDetails
+ } of buttons) {
+ element.addEventListener("click", evt => {
+ if (eventName !== null) {
+ eventBus.dispatch(eventName, {
+ source: this,
+ ...eventDetails
+ });
+ }
+ if (close) {
+ this.close();
+ }
+ eventBus.dispatch("reporttelemetry", {
+ source: this,
+ details: {
+ type: "buttons",
+ data: {
+ id: element.id
+ }
+ }
+ });
+ });
+ }
+ eventBus._on("cursortoolchanged", this.#cursorToolChanged.bind(this));
+ eventBus._on("scrollmodechanged", this.#scrollModeChanged.bind(this));
+ eventBus._on("spreadmodechanged", this.#spreadModeChanged.bind(this));
+ }
+ #cursorToolChanged({
+ tool
+ }) {
+ const {
+ cursorSelectToolButton,
+ cursorHandToolButton
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(cursorSelectToolButton, tool === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(cursorHandToolButton, tool === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND);
+ }
+ #scrollModeChanged({
+ mode
+ }) {
+ const {
+ scrollPageButton,
+ scrollVerticalButton,
+ scrollHorizontalButton,
+ scrollWrappedButton,
+ spreadNoneButton,
+ spreadOddButton,
+ spreadEvenButton
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollPageButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollVerticalButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollHorizontalButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollWrappedButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.WRAPPED);
+ const forceScrollModePage = this.pagesCount > _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__.PagesCountLimit.FORCE_SCROLL_MODE_PAGE;
+ scrollPageButton.disabled = forceScrollModePage;
+ scrollVerticalButton.disabled = forceScrollModePage;
+ scrollHorizontalButton.disabled = forceScrollModePage;
+ scrollWrappedButton.disabled = forceScrollModePage;
+ const isHorizontal = mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL;
+ spreadNoneButton.disabled = isHorizontal;
+ spreadOddButton.disabled = isHorizontal;
+ spreadEvenButton.disabled = isHorizontal;
+ }
+ #spreadModeChanged({
+ mode
+ }) {
+ const {
+ spreadNoneButton,
+ spreadOddButton,
+ spreadEvenButton
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadNoneButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadOddButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.ODD);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadEvenButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.EVEN);
+ }
+ open() {
+ if (this.opened) {
+ return;
+ }
+ this.opened = true;
+ const {
+ toggleButton,
+ toolbar
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(toggleButton, true, toolbar);
+ }
+ close() {
+ if (!this.opened) {
+ return;
+ }
+ this.opened = false;
+ const {
+ toggleButton,
+ toolbar
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(toggleButton, false, toolbar);
+ }
+ toggle() {
+ if (this.opened) {
+ this.close();
+ } else {
+ this.open();
+ }
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 7498:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ StructTreeLayerBuilder: () => (/* binding */ StructTreeLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+
+const PDF_ROLE_TO_HTML_ROLE = {
+ Document: null,
+ DocumentFragment: null,
+ Part: "group",
+ Sect: "group",
+ Div: "group",
+ Aside: "note",
+ NonStruct: "none",
+ P: null,
+ H: "heading",
+ Title: null,
+ FENote: "note",
+ Sub: "group",
+ Lbl: null,
+ Span: null,
+ Em: null,
+ Strong: null,
+ Link: "link",
+ Annot: "note",
+ Form: "form",
+ Ruby: null,
+ RB: null,
+ RT: null,
+ RP: null,
+ Warichu: null,
+ WT: null,
+ WP: null,
+ L: "list",
+ LI: "listitem",
+ LBody: null,
+ Table: "table",
+ TR: "row",
+ TH: "columnheader",
+ TD: "cell",
+ THead: "columnheader",
+ TBody: null,
+ TFoot: null,
+ Caption: null,
+ Figure: "figure",
+ Formula: null,
+ Artifact: null
+};
+const HEADING_PATTERN = /^H(\d+)$/;
+class StructTreeLayerBuilder {
+ #treeDom = undefined;
+ get renderingDone() {
+ return this.#treeDom !== undefined;
+ }
+ render(structTree) {
+ if (this.#treeDom !== undefined) {
+ return this.#treeDom;
+ }
+ const treeDom = this.#walk(structTree);
+ treeDom?.classList.add("structTree");
+ return this.#treeDom = treeDom;
+ }
+ hide() {
+ if (this.#treeDom && !this.#treeDom.hidden) {
+ this.#treeDom.hidden = true;
+ }
+ }
+ show() {
+ if (this.#treeDom?.hidden) {
+ this.#treeDom.hidden = false;
+ }
+ }
+ #setAttributes(structElement, htmlElement) {
+ const {
+ alt,
+ id,
+ lang
+ } = structElement;
+ if (alt !== undefined) {
+ htmlElement.setAttribute("aria-label", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(alt));
+ }
+ if (id !== undefined) {
+ htmlElement.setAttribute("aria-owns", id);
+ }
+ if (lang !== undefined) {
+ htmlElement.setAttribute("lang", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(lang, true));
+ }
+ }
+ #walk(node) {
+ if (!node) {
+ return null;
+ }
+ const element = document.createElement("span");
+ if ("role" in node) {
+ const {
+ role
+ } = node;
+ const match = role.match(HEADING_PATTERN);
+ if (match) {
+ element.setAttribute("role", "heading");
+ element.setAttribute("aria-level", match[1]);
+ } else if (PDF_ROLE_TO_HTML_ROLE[role]) {
+ element.setAttribute("role", PDF_ROLE_TO_HTML_ROLE[role]);
+ }
+ }
+ this.#setAttributes(node, element);
+ if (node.children) {
+ if (node.children.length === 1 && "id" in node.children[0]) {
+ this.#setAttributes(node.children[0], element);
+ } else {
+ for (const kid of node.children) {
+ element.append(this.#walk(kid));
+ }
+ }
+ }
+ return element;
+ }
+}
+
+
+/***/ }),
+
+/***/ 4630:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ TextAccessibilityManager: () => (/* binding */ TextAccessibilityManager)
+/* harmony export */ });
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927);
+
+class TextAccessibilityManager {
+ #enabled = false;
+ #textChildren = null;
+ #textNodes = new Map();
+ #waitingElements = new Map();
+ setTextMapping(textDivs) {
+ this.#textChildren = textDivs;
+ }
+ static #compareElementPositions(e1, e2) {
+ const rect1 = e1.getBoundingClientRect();
+ const rect2 = e2.getBoundingClientRect();
+ if (rect1.width === 0 && rect1.height === 0) {
+ return +1;
+ }
+ if (rect2.width === 0 && rect2.height === 0) {
+ return -1;
+ }
+ const top1 = rect1.y;
+ const bot1 = rect1.y + rect1.height;
+ const mid1 = rect1.y + rect1.height / 2;
+ const top2 = rect2.y;
+ const bot2 = rect2.y + rect2.height;
+ const mid2 = rect2.y + rect2.height / 2;
+ if (mid1 <= top2 && mid2 >= bot1) {
+ return -1;
+ }
+ if (mid2 <= top1 && mid1 >= bot2) {
+ return +1;
+ }
+ const centerX1 = rect1.x + rect1.width / 2;
+ const centerX2 = rect2.x + rect2.width / 2;
+ return centerX1 - centerX2;
+ }
+ enable() {
+ if (this.#enabled) {
+ throw new Error("TextAccessibilityManager is already enabled.");
+ }
+ if (!this.#textChildren) {
+ throw new Error("Text divs and strings have not been set.");
+ }
+ this.#enabled = true;
+ this.#textChildren = this.#textChildren.slice();
+ this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions);
+ if (this.#textNodes.size > 0) {
+ const textChildren = this.#textChildren;
+ for (const [id, nodeIndex] of this.#textNodes) {
+ const element = document.getElementById(id);
+ if (!element) {
+ this.#textNodes.delete(id);
+ continue;
+ }
+ this.#addIdToAriaOwns(id, textChildren[nodeIndex]);
+ }
+ }
+ for (const [element, isRemovable] of this.#waitingElements) {
+ this.addPointerInTextLayer(element, isRemovable);
+ }
+ this.#waitingElements.clear();
+ }
+ disable() {
+ if (!this.#enabled) {
+ return;
+ }
+ this.#waitingElements.clear();
+ this.#textChildren = null;
+ this.#enabled = false;
+ }
+ removePointerInTextLayer(element) {
+ if (!this.#enabled) {
+ this.#waitingElements.delete(element);
+ return;
+ }
+ const children = this.#textChildren;
+ if (!children || children.length === 0) {
+ return;
+ }
+ const {
+ id
+ } = element;
+ const nodeIndex = this.#textNodes.get(id);
+ if (nodeIndex === undefined) {
+ return;
+ }
+ const node = children[nodeIndex];
+ this.#textNodes.delete(id);
+ let owns = node.getAttribute("aria-owns");
+ if (owns?.includes(id)) {
+ owns = owns.split(" ").filter(x => x !== id).join(" ");
+ if (owns) {
+ node.setAttribute("aria-owns", owns);
+ } else {
+ node.removeAttribute("aria-owns");
+ node.setAttribute("role", "presentation");
+ }
+ }
+ }
+ #addIdToAriaOwns(id, node) {
+ const owns = node.getAttribute("aria-owns");
+ if (!owns?.includes(id)) {
+ node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id);
+ }
+ node.removeAttribute("role");
+ }
+ addPointerInTextLayer(element, isRemovable) {
+ const {
+ id
+ } = element;
+ if (!id) {
+ return null;
+ }
+ if (!this.#enabled) {
+ this.#waitingElements.set(element, isRemovable);
+ return null;
+ }
+ if (isRemovable) {
+ this.removePointerInTextLayer(element);
+ }
+ const children = this.#textChildren;
+ if (!children || children.length === 0) {
+ return null;
+ }
+ const index = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(element, node) < 0);
+ const nodeIndex = Math.max(0, index - 1);
+ const child = children[nodeIndex];
+ this.#addIdToAriaOwns(id, child);
+ this.#textNodes.set(id, nodeIndex);
+ const parent = child.parentNode;
+ return parent?.classList.contains("markedContent") ? parent.id : null;
+ }
+ moveElementInDOM(container, element, contentElement, isRemovable) {
+ const id = this.addPointerInTextLayer(contentElement, isRemovable);
+ if (!container.hasChildNodes()) {
+ container.append(element);
+ return id;
+ }
+ const children = Array.from(container.childNodes).filter(node => node !== element);
+ if (children.length === 0) {
+ return id;
+ }
+ const elementToCompare = contentElement || element;
+ const index = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(elementToCompare, node) < 0);
+ if (index === 0) {
+ children[0].before(element);
+ } else {
+ children[index - 1].after(element);
+ }
+ return id;
+ }
+}
+
+
+/***/ }),
+
+/***/ 4274:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ TextHighlighter: () => (/* binding */ TextHighlighter)
+/* harmony export */ });
+class TextHighlighter {
+ constructor({
+ findController,
+ eventBus,
+ pageIndex
+ }) {
+ this.findController = findController;
+ this.matches = [];
+ this.eventBus = eventBus;
+ this.pageIdx = pageIndex;
+ this._onUpdateTextLayerMatches = null;
+ this.textDivs = null;
+ this.textContentItemsStr = null;
+ this.enabled = false;
+ }
+ setTextMapping(divs, texts) {
+ this.textDivs = divs;
+ this.textContentItemsStr = texts;
+ }
+ enable() {
+ if (!this.textDivs || !this.textContentItemsStr) {
+ throw new Error("Text divs and strings have not been set.");
+ }
+ if (this.enabled) {
+ throw new Error("TextHighlighter is already enabled.");
+ }
+ this.enabled = true;
+ if (!this._onUpdateTextLayerMatches) {
+ this._onUpdateTextLayerMatches = evt => {
+ if (evt.pageIndex === this.pageIdx || evt.pageIndex === -1) {
+ this._updateMatches();
+ }
+ };
+ this.eventBus._on("updatetextlayermatches", this._onUpdateTextLayerMatches);
+ }
+ this._updateMatches();
+ }
+ disable() {
+ if (!this.enabled) {
+ return;
+ }
+ this.enabled = false;
+ if (this._onUpdateTextLayerMatches) {
+ this.eventBus._off("updatetextlayermatches", this._onUpdateTextLayerMatches);
+ this._onUpdateTextLayerMatches = null;
+ }
+ this._updateMatches(true);
+ }
+ _convertMatches(matches, matchesLength) {
+ if (!matches) {
+ return [];
+ }
+ const {
+ textContentItemsStr
+ } = this;
+ let i = 0,
+ iIndex = 0;
+ const end = textContentItemsStr.length - 1;
+ const result = [];
+ for (let m = 0, mm = matches.length; m < mm; m++) {
+ let matchIdx = matches[m];
+ while (i !== end && matchIdx >= iIndex + textContentItemsStr[i].length) {
+ iIndex += textContentItemsStr[i].length;
+ i++;
+ }
+ if (i === textContentItemsStr.length) {
+ console.error("Could not find a matching mapping");
+ }
+ const match = {
+ begin: {
+ divIdx: i,
+ offset: matchIdx - iIndex
+ }
+ };
+ matchIdx += matchesLength[m];
+ while (i !== end && matchIdx > iIndex + textContentItemsStr[i].length) {
+ iIndex += textContentItemsStr[i].length;
+ i++;
+ }
+ match.end = {
+ divIdx: i,
+ offset: matchIdx - iIndex
+ };
+ result.push(match);
+ }
+ return result;
+ }
+ _renderMatches(matches) {
+ if (matches.length === 0) {
+ return;
+ }
+ const {
+ findController,
+ pageIdx
+ } = this;
+ const {
+ textContentItemsStr,
+ textDivs
+ } = this;
+ const isSelectedPage = pageIdx === findController.selected.pageIdx;
+ const selectedMatchIdx = findController.selected.matchIdx;
+ const highlightAll = findController.state.highlightAll;
+ let prevEnd = null;
+ const infinity = {
+ divIdx: -1,
+ offset: undefined
+ };
+ function beginText(begin, className) {
+ const divIdx = begin.divIdx;
+ textDivs[divIdx].textContent = "";
+ return appendTextToDiv(divIdx, 0, begin.offset, className);
+ }
+ function appendTextToDiv(divIdx, fromOffset, toOffset, className) {
+ let div = textDivs[divIdx];
+ if (div.nodeType === Node.TEXT_NODE) {
+ const span = document.createElement("span");
+ div.before(span);
+ span.append(div);
+ textDivs[divIdx] = span;
+ div = span;
+ }
+ const content = textContentItemsStr[divIdx].substring(fromOffset, toOffset);
+ const node = document.createTextNode(content);
+ if (className) {
+ const span = document.createElement("span");
+ span.className = `${className} appended`;
+ span.append(node);
+ div.append(span);
+ return className.includes("selected") ? span.offsetLeft : 0;
+ }
+ div.append(node);
+ return 0;
+ }
+ let i0 = selectedMatchIdx,
+ i1 = i0 + 1;
+ if (highlightAll) {
+ i0 = 0;
+ i1 = matches.length;
+ } else if (!isSelectedPage) {
+ return;
+ }
+ let lastDivIdx = -1;
+ let lastOffset = -1;
+ for (let i = i0; i < i1; i++) {
+ const match = matches[i];
+ const begin = match.begin;
+ if (begin.divIdx === lastDivIdx && begin.offset === lastOffset) {
+ continue;
+ }
+ lastDivIdx = begin.divIdx;
+ lastOffset = begin.offset;
+ const end = match.end;
+ const isSelected = isSelectedPage && i === selectedMatchIdx;
+ const highlightSuffix = isSelected ? " selected" : "";
+ let selectedLeft = 0;
+ if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
+ if (prevEnd !== null) {
+ appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
+ }
+ beginText(begin);
+ } else {
+ appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset);
+ }
+ if (begin.divIdx === end.divIdx) {
+ selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, end.offset, "highlight" + highlightSuffix);
+ } else {
+ selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, "highlight begin" + highlightSuffix);
+ for (let n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) {
+ textDivs[n0].className = "highlight middle" + highlightSuffix;
+ }
+ beginText(end, "highlight end" + highlightSuffix);
+ }
+ prevEnd = end;
+ if (isSelected) {
+ findController.scrollMatchIntoView({
+ element: textDivs[begin.divIdx],
+ selectedLeft,
+ pageIndex: pageIdx,
+ matchIndex: selectedMatchIdx
+ });
+ }
+ }
+ if (prevEnd) {
+ appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
+ }
+ }
+ _updateMatches(reset = false) {
+ if (!this.enabled && !reset) {
+ return;
+ }
+ const {
+ findController,
+ matches,
+ pageIdx
+ } = this;
+ const {
+ textContentItemsStr,
+ textDivs
+ } = this;
+ let clearedUntilDivIdx = -1;
+ for (const match of matches) {
+ const begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
+ for (let n = begin, end = match.end.divIdx; n <= end; n++) {
+ const div = textDivs[n];
+ div.textContent = textContentItemsStr[n];
+ div.className = "";
+ }
+ clearedUntilDivIdx = match.end.divIdx + 1;
+ }
+ if (!findController?.highlightMatches || reset) {
+ return;
+ }
+ const pageMatches = findController.pageMatches[pageIdx] || null;
+ const pageMatchesLength = findController.pageMatchesLength[pageIdx] || null;
+ this.matches = this._convertMatches(pageMatches, pageMatchesLength);
+ this._renderMatches(this.matches);
+ }
+}
+
+
+/***/ }),
+
+/***/ 1013:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ TextLayerBuilder: () => (/* binding */ TextLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+class TextLayerBuilder {
+ #enablePermissions = false;
+ #rotation = 0;
+ #scale = 0;
+ #textContentSource = null;
+ constructor({
+ highlighter = null,
+ accessibilityManager = null,
+ isOffscreenCanvasSupported = true,
+ enablePermissions = false
+ }) {
+ this.textContentItemsStr = [];
+ this.renderingDone = false;
+ this.textDivs = [];
+ this.textDivProperties = new WeakMap();
+ this.textLayerRenderTask = null;
+ this.highlighter = highlighter;
+ this.accessibilityManager = accessibilityManager;
+ this.isOffscreenCanvasSupported = isOffscreenCanvasSupported;
+ this.#enablePermissions = enablePermissions === true;
+ this.onAppend = null;
+ this.div = document.createElement("div");
+ this.div.className = "textLayer";
+ }
+ #finishRendering() {
+ this.renderingDone = true;
+ const endOfContent = document.createElement("div");
+ endOfContent.className = "endOfContent";
+ this.div.append(endOfContent);
+ this.#bindMouse();
+ }
+ get numTextDivs() {
+ return this.textDivs.length;
+ }
+ async render(viewport) {
+ if (!this.#textContentSource) {
+ throw new Error('No "textContentSource" parameter specified.');
+ }
+ const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
+ const {
+ rotation
+ } = viewport;
+ if (this.renderingDone) {
+ const mustRotate = rotation !== this.#rotation;
+ const mustRescale = scale !== this.#scale;
+ if (mustRotate || mustRescale) {
+ this.hide();
+ (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.updateTextLayer)({
+ container: this.div,
+ viewport,
+ textDivs: this.textDivs,
+ textDivProperties: this.textDivProperties,
+ isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
+ mustRescale,
+ mustRotate
+ });
+ this.#scale = scale;
+ this.#rotation = rotation;
+ }
+ this.show();
+ return;
+ }
+ this.cancel();
+ this.highlighter?.setTextMapping(this.textDivs, this.textContentItemsStr);
+ this.accessibilityManager?.setTextMapping(this.textDivs);
+ this.textLayerRenderTask = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.renderTextLayer)({
+ textContentSource: this.#textContentSource,
+ container: this.div,
+ viewport,
+ textDivs: this.textDivs,
+ textDivProperties: this.textDivProperties,
+ textContentItemsStr: this.textContentItemsStr,
+ isOffscreenCanvasSupported: this.isOffscreenCanvasSupported
+ });
+ await this.textLayerRenderTask.promise;
+ this.#finishRendering();
+ this.#scale = scale;
+ this.#rotation = rotation;
+ this.onAppend(this.div);
+ this.highlighter?.enable();
+ this.accessibilityManager?.enable();
+ }
+ hide() {
+ if (!this.div.hidden && this.renderingDone) {
+ this.highlighter?.disable();
+ this.div.hidden = true;
+ }
+ }
+ show() {
+ if (this.div.hidden && this.renderingDone) {
+ this.div.hidden = false;
+ this.highlighter?.enable();
+ }
+ }
+ cancel() {
+ if (this.textLayerRenderTask) {
+ this.textLayerRenderTask.cancel();
+ this.textLayerRenderTask = null;
+ }
+ this.highlighter?.disable();
+ this.accessibilityManager?.disable();
+ this.textContentItemsStr.length = 0;
+ this.textDivs.length = 0;
+ this.textDivProperties = new WeakMap();
+ }
+ setTextContentSource(source) {
+ this.cancel();
+ this.#textContentSource = source;
+ }
+ #bindMouse() {
+ const {
+ div
+ } = this;
+ div.addEventListener("mousedown", evt => {
+ const end = div.querySelector(".endOfContent");
+ if (!end) {
+ return;
+ }
+ let adjustTop = evt.target !== div;
+ adjustTop &&= getComputedStyle(end).getPropertyValue("-moz-user-select") !== "none";
+ if (adjustTop) {
+ const divBounds = div.getBoundingClientRect();
+ const r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height);
+ end.style.top = (r * 100).toFixed(2) + "%";
+ }
+ end.classList.add("active");
+ });
+ div.addEventListener("mouseup", () => {
+ const end = div.querySelector(".endOfContent");
+ if (!end) {
+ return;
+ }
+ end.style.top = "";
+ end.classList.remove("active");
+ });
+ div.addEventListener("copy", event => {
+ if (!this.#enablePermissions) {
+ const selection = document.getSelection();
+ event.clipboardData.setData("text/plain", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.removeNullCharacters)((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.normalizeUnicode)(selection.toString())));
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ });
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 276:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ Toolbar: () => (/* binding */ Toolbar)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+class Toolbar {
+ #opts;
+ constructor(options, eventBus) {
+ this.#opts = options;
+ this.eventBus = eventBus;
+ const buttons = [{
+ element: options.previous,
+ eventName: "previouspage"
+ }, {
+ element: options.next,
+ eventName: "nextpage"
+ }, {
+ element: options.zoomIn,
+ eventName: "zoomin"
+ }, {
+ element: options.zoomOut,
+ eventName: "zoomout"
+ }, {
+ element: options.print,
+ eventName: "print"
+ }, {
+ element: options.download,
+ eventName: "download"
+ }, {
+ element: options.editorFreeTextButton,
+ eventName: "switchannotationeditormode",
+ eventDetails: {
+ get mode() {
+ const {
+ classList
+ } = options.editorFreeTextButton;
+ return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.FREETEXT;
+ }
+ }
+ }, {
+ element: options.editorHighlightButton,
+ eventName: "switchannotationeditormode",
+ eventDetails: {
+ get mode() {
+ const {
+ classList
+ } = options.editorHighlightButton;
+ return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT;
+ }
+ }
+ }, {
+ element: options.editorInkButton,
+ eventName: "switchannotationeditormode",
+ eventDetails: {
+ get mode() {
+ const {
+ classList
+ } = options.editorInkButton;
+ return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.INK;
+ }
+ }
+ }, {
+ element: options.editorStampButton,
+ eventName: "switchannotationeditormode",
+ eventDetails: {
+ get mode() {
+ const {
+ classList
+ } = options.editorStampButton;
+ return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.STAMP;
+ }
+ }
+ }];
+ this.#bindListeners(buttons);
+ if (options.editorHighlightColorPicker) {
+ eventBus._on("annotationeditoruimanager", ({
+ uiManager
+ }) => {
+ this.#setAnnotationEditorUIManager(uiManager, options.editorHighlightColorPicker);
+ }, {
+ once: true
+ });
+ }
+ this.reset();
+ }
+ #setAnnotationEditorUIManager(uiManager, parentContainer) {
+ const colorPicker = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.ColorPicker({
+ uiManager
+ });
+ uiManager.setMainHighlightColorPicker(colorPicker);
+ parentContainer.append(colorPicker.renderMainDropdown());
+ }
+ setPageNumber(pageNumber, pageLabel) {
+ this.pageNumber = pageNumber;
+ this.pageLabel = pageLabel;
+ this.#updateUIState(false);
+ }
+ setPagesCount(pagesCount, hasPageLabels) {
+ this.pagesCount = pagesCount;
+ this.hasPageLabels = hasPageLabels;
+ this.#updateUIState(true);
+ }
+ setPageScale(pageScaleValue, pageScale) {
+ this.pageScaleValue = (pageScaleValue || pageScale).toString();
+ this.pageScale = pageScale;
+ this.#updateUIState(false);
+ }
+ reset() {
+ this.pageNumber = 0;
+ this.pageLabel = null;
+ this.hasPageLabels = false;
+ this.pagesCount = 0;
+ this.pageScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_VALUE;
+ this.pageScale = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE;
+ this.#updateUIState(true);
+ this.updateLoadingIndicatorState();
+ this.#editorModeChanged({
+ mode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE
+ });
+ }
+ #bindListeners(buttons) {
+ const {
+ eventBus
+ } = this;
+ const {
+ pageNumber,
+ scaleSelect
+ } = this.#opts;
+ const self = this;
+ for (const {
+ element,
+ eventName,
+ eventDetails
+ } of buttons) {
+ element.addEventListener("click", evt => {
+ if (eventName !== null) {
+ eventBus.dispatch(eventName, {
+ source: this,
+ ...eventDetails,
+ isFromKeyboard: evt.detail === 0
+ });
+ }
+ });
+ }
+ pageNumber.addEventListener("click", function () {
+ this.select();
+ });
+ pageNumber.addEventListener("change", function () {
+ eventBus.dispatch("pagenumberchanged", {
+ source: self,
+ value: this.value
+ });
+ });
+ scaleSelect.addEventListener("change", function () {
+ if (this.value === "custom") {
+ return;
+ }
+ eventBus.dispatch("scalechanged", {
+ source: self,
+ value: this.value
+ });
+ });
+ scaleSelect.addEventListener("click", function ({
+ target
+ }) {
+ if (this.value === self.pageScaleValue && target.tagName.toUpperCase() === "OPTION") {
+ this.blur();
+ }
+ });
+ scaleSelect.oncontextmenu = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.noContextMenu;
+ eventBus._on("annotationeditormodechanged", this.#editorModeChanged.bind(this));
+ }
+ #editorModeChanged({
+ mode
+ }) {
+ const {
+ editorFreeTextButton,
+ editorFreeTextParamsToolbar,
+ editorHighlightButton,
+ editorHighlightParamsToolbar,
+ editorInkButton,
+ editorInkParamsToolbar,
+ editorStampButton,
+ editorStampParamsToolbar
+ } = this.#opts;
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorFreeTextButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.FREETEXT, editorFreeTextParamsToolbar);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorHighlightButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT, editorHighlightParamsToolbar);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorInkButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.INK, editorInkParamsToolbar);
+ (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorStampButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.STAMP, editorStampParamsToolbar);
+ const isDisable = mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE;
+ editorFreeTextButton.disabled = isDisable;
+ editorHighlightButton.disabled = isDisable;
+ editorInkButton.disabled = isDisable;
+ editorStampButton.disabled = isDisable;
+ }
+ #updateUIState(resetNumPages = false) {
+ const {
+ pageNumber,
+ pagesCount,
+ pageScaleValue,
+ pageScale
+ } = this;
+ const opts = this.#opts;
+ if (resetNumPages) {
+ if (this.hasPageLabels) {
+ opts.pageNumber.type = "text";
+ opts.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages");
+ } else {
+ opts.pageNumber.type = "number";
+ opts.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages");
+ opts.numPages.setAttribute("data-l10n-args", JSON.stringify({
+ pagesCount
+ }));
+ }
+ opts.pageNumber.max = pagesCount;
+ }
+ if (this.hasPageLabels) {
+ opts.pageNumber.value = this.pageLabel;
+ opts.numPages.setAttribute("data-l10n-args", JSON.stringify({
+ pageNumber,
+ pagesCount
+ }));
+ } else {
+ opts.pageNumber.value = pageNumber;
+ }
+ opts.previous.disabled = pageNumber <= 1;
+ opts.next.disabled = pageNumber >= pagesCount;
+ opts.zoomOut.disabled = pageScale <= _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE;
+ opts.zoomIn.disabled = pageScale >= _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE;
+ let predefinedValueFound = false;
+ for (const option of opts.scaleSelect.options) {
+ if (option.value !== pageScaleValue) {
+ option.selected = false;
+ continue;
+ }
+ option.selected = true;
+ predefinedValueFound = true;
+ }
+ if (!predefinedValueFound) {
+ opts.customScaleOption.selected = true;
+ opts.customScaleOption.setAttribute("data-l10n-args", JSON.stringify({
+ scale: Math.round(pageScale * 10000) / 100
+ }));
+ }
+ }
+ updateLoadingIndicatorState(loading = false) {
+ const {
+ pageNumber
+ } = this.#opts;
+ pageNumber.classList.toggle("loading", loading);
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 4927:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ AutoPrintRegExp: () => (/* binding */ AutoPrintRegExp),
+/* harmony export */ CursorTool: () => (/* binding */ CursorTool),
+/* harmony export */ DEFAULT_SCALE: () => (/* binding */ DEFAULT_SCALE),
+/* harmony export */ DEFAULT_SCALE_DELTA: () => (/* binding */ DEFAULT_SCALE_DELTA),
+/* harmony export */ DEFAULT_SCALE_VALUE: () => (/* binding */ DEFAULT_SCALE_VALUE),
+/* harmony export */ MAX_AUTO_SCALE: () => (/* binding */ MAX_AUTO_SCALE),
+/* harmony export */ MAX_SCALE: () => (/* binding */ MAX_SCALE),
+/* harmony export */ MIN_SCALE: () => (/* binding */ MIN_SCALE),
+/* harmony export */ OutputScale: () => (/* binding */ OutputScale),
+/* harmony export */ PresentationModeState: () => (/* binding */ PresentationModeState),
+/* harmony export */ ProgressBar: () => (/* binding */ ProgressBar),
+/* harmony export */ RenderingStates: () => (/* binding */ RenderingStates),
+/* harmony export */ SCROLLBAR_PADDING: () => (/* binding */ SCROLLBAR_PADDING),
+/* harmony export */ ScrollMode: () => (/* binding */ ScrollMode),
+/* harmony export */ SidebarView: () => (/* binding */ SidebarView),
+/* harmony export */ SpreadMode: () => (/* binding */ SpreadMode),
+/* harmony export */ TextLayerMode: () => (/* binding */ TextLayerMode),
+/* harmony export */ UNKNOWN_SCALE: () => (/* binding */ UNKNOWN_SCALE),
+/* harmony export */ VERTICAL_PADDING: () => (/* binding */ VERTICAL_PADDING),
+/* harmony export */ animationStarted: () => (/* binding */ animationStarted),
+/* harmony export */ apiPageLayoutToViewerModes: () => (/* binding */ apiPageLayoutToViewerModes),
+/* harmony export */ apiPageModeToSidebarView: () => (/* binding */ apiPageModeToSidebarView),
+/* harmony export */ approximateFraction: () => (/* binding */ approximateFraction),
+/* harmony export */ binarySearchFirstItem: () => (/* binding */ binarySearchFirstItem),
+/* harmony export */ docStyle: () => (/* binding */ docStyle),
+/* harmony export */ getActiveOrFocusedElement: () => (/* binding */ getActiveOrFocusedElement),
+/* harmony export */ getPageSizeInches: () => (/* binding */ getPageSizeInches),
+/* harmony export */ getVisibleElements: () => (/* binding */ getVisibleElements),
+/* harmony export */ isPortraitOrientation: () => (/* binding */ isPortraitOrientation),
+/* harmony export */ isValidRotation: () => (/* binding */ isValidRotation),
+/* harmony export */ isValidScrollMode: () => (/* binding */ isValidScrollMode),
+/* harmony export */ isValidSpreadMode: () => (/* binding */ isValidSpreadMode),
+/* harmony export */ normalizeWheelEventDelta: () => (/* binding */ normalizeWheelEventDelta),
+/* harmony export */ normalizeWheelEventDirection: () => (/* binding */ normalizeWheelEventDirection),
+/* harmony export */ parseQueryString: () => (/* binding */ parseQueryString),
+/* harmony export */ removeNullCharacters: () => (/* binding */ removeNullCharacters),
+/* harmony export */ roundToDivide: () => (/* binding */ roundToDivide),
+/* harmony export */ scrollIntoView: () => (/* binding */ scrollIntoView),
+/* harmony export */ toggleCheckedBtn: () => (/* binding */ toggleCheckedBtn),
+/* harmony export */ toggleExpandedBtn: () => (/* binding */ toggleExpandedBtn),
+/* harmony export */ watchScroll: () => (/* binding */ watchScroll)
+/* harmony export */ });
+/* unused harmony export backtrackBeforeAllVisibleElements */
+const DEFAULT_SCALE_VALUE = "auto";
+const DEFAULT_SCALE = 1.0;
+const DEFAULT_SCALE_DELTA = 1.1;
+const MIN_SCALE = 0.1;
+const MAX_SCALE = 10.0;
+const UNKNOWN_SCALE = 0;
+const MAX_AUTO_SCALE = 1.25;
+const SCROLLBAR_PADDING = 40;
+const VERTICAL_PADDING = 5;
+const RenderingStates = {
+ INITIAL: 0,
+ RUNNING: 1,
+ PAUSED: 2,
+ FINISHED: 3
+};
+const PresentationModeState = {
+ UNKNOWN: 0,
+ NORMAL: 1,
+ CHANGING: 2,
+ FULLSCREEN: 3
+};
+const SidebarView = {
+ UNKNOWN: -1,
+ NONE: 0,
+ THUMBS: 1,
+ OUTLINE: 2,
+ ATTACHMENTS: 3,
+ LAYERS: 4
+};
+const TextLayerMode = {
+ DISABLE: 0,
+ ENABLE: 1,
+ ENABLE_PERMISSIONS: 2
+};
+const ScrollMode = {
+ UNKNOWN: -1,
+ VERTICAL: 0,
+ HORIZONTAL: 1,
+ WRAPPED: 2,
+ PAGE: 3
+};
+const SpreadMode = {
+ UNKNOWN: -1,
+ NONE: 0,
+ ODD: 1,
+ EVEN: 2
+};
+const CursorTool = {
+ SELECT: 0,
+ HAND: 1,
+ ZOOM: 2
+};
+const AutoPrintRegExp = /\bprint\s*\(/;
+class OutputScale {
+ constructor() {
+ const pixelRatio = window.devicePixelRatio || 1;
+ this.sx = pixelRatio;
+ this.sy = pixelRatio;
+ }
+ get scaled() {
+ return this.sx !== 1 || this.sy !== 1;
+ }
+}
+function scrollIntoView(element, spot, scrollMatches = false) {
+ let parent = element.offsetParent;
+ if (!parent) {
+ console.error("offsetParent is not set -- cannot scroll");
+ return;
+ }
+ let offsetY = element.offsetTop + element.clientTop;
+ let offsetX = element.offsetLeft + element.clientLeft;
+ while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) {
+ offsetY += parent.offsetTop;
+ offsetX += parent.offsetLeft;
+ parent = parent.offsetParent;
+ if (!parent) {
+ return;
+ }
+ }
+ if (spot) {
+ if (spot.top !== undefined) {
+ offsetY += spot.top;
+ }
+ if (spot.left !== undefined) {
+ offsetX += spot.left;
+ parent.scrollLeft = offsetX;
+ }
+ }
+ parent.scrollTop = offsetY;
+}
+function watchScroll(viewAreaElement, callback) {
+ const debounceScroll = function (evt) {
+ if (rAF) {
+ return;
+ }
+ rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
+ rAF = null;
+ const currentX = viewAreaElement.scrollLeft;
+ const lastX = state.lastX;
+ if (currentX !== lastX) {
+ state.right = currentX > lastX;
+ }
+ state.lastX = currentX;
+ const currentY = viewAreaElement.scrollTop;
+ const lastY = state.lastY;
+ if (currentY !== lastY) {
+ state.down = currentY > lastY;
+ }
+ state.lastY = currentY;
+ callback(state);
+ });
+ };
+ const state = {
+ right: true,
+ down: true,
+ lastX: viewAreaElement.scrollLeft,
+ lastY: viewAreaElement.scrollTop,
+ _eventHandler: debounceScroll
+ };
+ let rAF = null;
+ viewAreaElement.addEventListener("scroll", debounceScroll, true);
+ return state;
+}
+function parseQueryString(query) {
+ const params = new Map();
+ for (const [key, value] of new URLSearchParams(query)) {
+ params.set(key.toLowerCase(), value);
+ }
+ return params;
+}
+const InvisibleCharactersRegExp = /[\x00-\x1F]/g;
+function removeNullCharacters(str, replaceInvisible = false) {
+ if (!InvisibleCharactersRegExp.test(str)) {
+ return str;
+ }
+ if (replaceInvisible) {
+ return str.replaceAll(InvisibleCharactersRegExp, m => {
+ return m === "\x00" ? "" : " ";
+ });
+ }
+ return str.replaceAll("\x00", "");
+}
+function binarySearchFirstItem(items, condition, start = 0) {
+ let minIndex = start;
+ let maxIndex = items.length - 1;
+ if (maxIndex < 0 || !condition(items[maxIndex])) {
+ return items.length;
+ }
+ if (condition(items[minIndex])) {
+ return minIndex;
+ }
+ while (minIndex < maxIndex) {
+ const currentIndex = minIndex + maxIndex >> 1;
+ const currentItem = items[currentIndex];
+ if (condition(currentItem)) {
+ maxIndex = currentIndex;
+ } else {
+ minIndex = currentIndex + 1;
+ }
+ }
+ return minIndex;
+}
+function approximateFraction(x) {
+ if (Math.floor(x) === x) {
+ return [x, 1];
+ }
+ const xinv = 1 / x;
+ const limit = 8;
+ if (xinv > limit) {
+ return [1, limit];
+ } else if (Math.floor(xinv) === xinv) {
+ return [1, xinv];
+ }
+ const x_ = x > 1 ? xinv : x;
+ let a = 0,
+ b = 1,
+ c = 1,
+ d = 1;
+ while (true) {
+ const p = a + c,
+ q = b + d;
+ if (q > limit) {
+ break;
+ }
+ if (x_ <= p / q) {
+ c = p;
+ d = q;
+ } else {
+ a = p;
+ b = q;
+ }
+ }
+ let result;
+ if (x_ - a / b < c / d - x_) {
+ result = x_ === x ? [a, b] : [b, a];
+ } else {
+ result = x_ === x ? [c, d] : [d, c];
+ }
+ return result;
+}
+function roundToDivide(x, div) {
+ const r = x % div;
+ return r === 0 ? x : Math.round(x - r + div);
+}
+function getPageSizeInches({
+ view,
+ userUnit,
+ rotate
+}) {
+ const [x1, y1, x2, y2] = view;
+ const changeOrientation = rotate % 180 !== 0;
+ const width = (x2 - x1) / 72 * userUnit;
+ const height = (y2 - y1) / 72 * userUnit;
+ return {
+ width: changeOrientation ? height : width,
+ height: changeOrientation ? width : height
+ };
+}
+function backtrackBeforeAllVisibleElements(index, views, top) {
+ if (index < 2) {
+ return index;
+ }
+ let elt = views[index].div;
+ let pageTop = elt.offsetTop + elt.clientTop;
+ if (pageTop >= top) {
+ elt = views[index - 1].div;
+ pageTop = elt.offsetTop + elt.clientTop;
+ }
+ for (let i = index - 2; i >= 0; --i) {
+ elt = views[i].div;
+ if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) {
+ break;
+ }
+ index = i;
+ }
+ return index;
+}
+function getVisibleElements({
+ scrollEl,
+ views,
+ sortByVisibility = false,
+ horizontal = false,
+ rtl = false
+}) {
+ const top = scrollEl.scrollTop,
+ bottom = top + scrollEl.clientHeight;
+ const left = scrollEl.scrollLeft,
+ right = left + scrollEl.clientWidth;
+ function isElementBottomAfterViewTop(view) {
+ const element = view.div;
+ const elementBottom = element.offsetTop + element.clientTop + element.clientHeight;
+ return elementBottom > top;
+ }
+ function isElementNextAfterViewHorizontally(view) {
+ const element = view.div;
+ const elementLeft = element.offsetLeft + element.clientLeft;
+ const elementRight = elementLeft + element.clientWidth;
+ return rtl ? elementLeft < right : elementRight > left;
+ }
+ const visible = [],
+ ids = new Set(),
+ numViews = views.length;
+ let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
+ if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) {
+ firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top);
+ }
+ let lastEdge = horizontal ? right : -1;
+ for (let i = firstVisibleElementInd; i < numViews; i++) {
+ const view = views[i],
+ element = view.div;
+ const currentWidth = element.offsetLeft + element.clientLeft;
+ const currentHeight = element.offsetTop + element.clientTop;
+ const viewWidth = element.clientWidth,
+ viewHeight = element.clientHeight;
+ const viewRight = currentWidth + viewWidth;
+ const viewBottom = currentHeight + viewHeight;
+ if (lastEdge === -1) {
+ if (viewBottom >= bottom) {
+ lastEdge = viewBottom;
+ }
+ } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) {
+ break;
+ }
+ if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) {
+ continue;
+ }
+ const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom);
+ const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right);
+ const fractionHeight = (viewHeight - hiddenHeight) / viewHeight,
+ fractionWidth = (viewWidth - hiddenWidth) / viewWidth;
+ const percent = fractionHeight * fractionWidth * 100 | 0;
+ visible.push({
+ id: view.id,
+ x: currentWidth,
+ y: currentHeight,
+ view,
+ percent,
+ widthPercent: fractionWidth * 100 | 0
+ });
+ ids.add(view.id);
+ }
+ const first = visible[0],
+ last = visible.at(-1);
+ if (sortByVisibility) {
+ visible.sort(function (a, b) {
+ const pc = a.percent - b.percent;
+ if (Math.abs(pc) > 0.001) {
+ return -pc;
+ }
+ return a.id - b.id;
+ });
+ }
+ return {
+ first,
+ last,
+ views: visible,
+ ids
+ };
+}
+function normalizeWheelEventDirection(evt) {
+ let delta = Math.hypot(evt.deltaX, evt.deltaY);
+ const angle = Math.atan2(evt.deltaY, evt.deltaX);
+ if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
+ delta = -delta;
+ }
+ return delta;
+}
+function normalizeWheelEventDelta(evt) {
+ const deltaMode = evt.deltaMode;
+ let delta = normalizeWheelEventDirection(evt);
+ const MOUSE_PIXELS_PER_LINE = 30;
+ const MOUSE_LINES_PER_PAGE = 30;
+ if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
+ delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;
+ } else if (deltaMode === WheelEvent.DOM_DELTA_LINE) {
+ delta /= MOUSE_LINES_PER_PAGE;
+ }
+ return delta;
+}
+function isValidRotation(angle) {
+ return Number.isInteger(angle) && angle % 90 === 0;
+}
+function isValidScrollMode(mode) {
+ return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN;
+}
+function isValidSpreadMode(mode) {
+ return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN;
+}
+function isPortraitOrientation(size) {
+ return size.width <= size.height;
+}
+const animationStarted = new Promise(function (resolve) {
+ window.requestAnimationFrame(resolve);
+});
+const docStyle = document.documentElement.style;
+function clamp(v, min, max) {
+ return Math.min(Math.max(v, min), max);
+}
+class ProgressBar {
+ #classList = null;
+ #disableAutoFetchTimeout = null;
+ #percent = 0;
+ #style = null;
+ #visible = true;
+ constructor(bar) {
+ this.#classList = bar.classList;
+ this.#style = bar.style;
+ }
+ get percent() {
+ return this.#percent;
+ }
+ set percent(val) {
+ this.#percent = clamp(val, 0, 100);
+ if (isNaN(val)) {
+ this.#classList.add("indeterminate");
+ return;
+ }
+ this.#classList.remove("indeterminate");
+ this.#style.setProperty("--progressBar-percent", `${this.#percent}%`);
+ }
+ setWidth(viewer) {
+ if (!viewer) {
+ return;
+ }
+ const container = viewer.parentNode;
+ const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
+ if (scrollbarWidth > 0) {
+ this.#style.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`);
+ }
+ }
+ setDisableAutoFetch(delay = 5000) {
+ if (isNaN(this.#percent)) {
+ return;
+ }
+ if (this.#disableAutoFetchTimeout) {
+ clearTimeout(this.#disableAutoFetchTimeout);
+ }
+ this.show();
+ this.#disableAutoFetchTimeout = setTimeout(() => {
+ this.#disableAutoFetchTimeout = null;
+ this.hide();
+ }, delay);
+ }
+ hide() {
+ if (!this.#visible) {
+ return;
+ }
+ this.#visible = false;
+ this.#classList.add("hidden");
+ }
+ show() {
+ if (this.#visible) {
+ return;
+ }
+ this.#visible = true;
+ this.#classList.remove("hidden");
+ }
+}
+function getActiveOrFocusedElement() {
+ let curRoot = document;
+ let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
+ while (curActiveOrFocused?.shadowRoot) {
+ curRoot = curActiveOrFocused.shadowRoot;
+ curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
+ }
+ return curActiveOrFocused;
+}
+function apiPageLayoutToViewerModes(layout) {
+ let scrollMode = ScrollMode.VERTICAL,
+ spreadMode = SpreadMode.NONE;
+ switch (layout) {
+ case "SinglePage":
+ scrollMode = ScrollMode.PAGE;
+ break;
+ case "OneColumn":
+ break;
+ case "TwoPageLeft":
+ scrollMode = ScrollMode.PAGE;
+ case "TwoColumnLeft":
+ spreadMode = SpreadMode.ODD;
+ break;
+ case "TwoPageRight":
+ scrollMode = ScrollMode.PAGE;
+ case "TwoColumnRight":
+ spreadMode = SpreadMode.EVEN;
+ break;
+ }
+ return {
+ scrollMode,
+ spreadMode
+ };
+}
+function apiPageModeToSidebarView(mode) {
+ switch (mode) {
+ case "UseNone":
+ return SidebarView.NONE;
+ case "UseThumbs":
+ return SidebarView.THUMBS;
+ case "UseOutlines":
+ return SidebarView.OUTLINE;
+ case "UseAttachments":
+ return SidebarView.ATTACHMENTS;
+ case "UseOC":
+ return SidebarView.LAYERS;
+ }
+ return SidebarView.NONE;
+}
+function toggleCheckedBtn(button, toggle, view = null) {
+ button.classList.toggle("toggled", toggle);
+ button.setAttribute("aria-checked", toggle);
+ view?.classList.toggle("hidden", !toggle);
+}
+function toggleExpandedBtn(button, toggle, view = null) {
+ button.classList.toggle("toggled", toggle);
+ button.setAttribute("aria-expanded", toggle);
+ view?.classList.toggle("hidden", !toggle);
+}
+
+
+/***/ }),
+
+/***/ 1096:
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ ViewHistory: () => (/* binding */ ViewHistory)
+/* harmony export */ });
+const DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20;
+class ViewHistory {
+ constructor(fingerprint, cacheSize = DEFAULT_VIEW_HISTORY_CACHE_SIZE) {
+ this.fingerprint = fingerprint;
+ this.cacheSize = cacheSize;
+ this._initializedPromise = this._readFromStorage().then(databaseStr => {
+ const database = JSON.parse(databaseStr || "{}");
+ let index = -1;
+ if (!Array.isArray(database.files)) {
+ database.files = [];
+ } else {
+ while (database.files.length >= this.cacheSize) {
+ database.files.shift();
+ }
+ for (let i = 0, ii = database.files.length; i < ii; i++) {
+ const branch = database.files[i];
+ if (branch.fingerprint === this.fingerprint) {
+ index = i;
+ break;
+ }
+ }
+ }
+ if (index === -1) {
+ index = database.files.push({
+ fingerprint: this.fingerprint
+ }) - 1;
+ }
+ this.file = database.files[index];
+ this.database = database;
+ });
+ }
+ async _writeToStorage() {
+ const databaseStr = JSON.stringify(this.database);
+ localStorage.setItem("pdfjs.history", databaseStr);
+ }
+ async _readFromStorage() {
+ return localStorage.getItem("pdfjs.history");
+ }
+ async set(name, val) {
+ await this._initializedPromise;
+ this.file[name] = val;
+ return this._writeToStorage();
+ }
+ async setMultiple(properties) {
+ await this._initializedPromise;
+ for (const name in properties) {
+ this.file[name] = properties[name];
+ }
+ return this._writeToStorage();
+ }
+ async get(name, defaultValue) {
+ await this._initializedPromise;
+ const val = this.file[name];
+ return val !== undefined ? val : defaultValue;
+ }
+ async getMultiple(properties) {
+ await this._initializedPromise;
+ const values = Object.create(null);
+ for (const name in properties) {
+ const val = this.file[name];
+ values[name] = val !== undefined ? val : properties[name];
+ }
+ return values;
+ }
+}
+
+
+/***/ }),
+
+/***/ 6400:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ PDFViewerApplication: () => (/* reexport safe */ _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication),
+/* harmony export */ PDFViewerApplicationConstants: () => (/* binding */ AppConstants),
+/* harmony export */ PDFViewerApplicationOptions: () => (/* reexport safe */ _app_options_js__WEBPACK_IMPORTED_MODULE_3__.AppOptions)
+/* harmony export */ });
+/* harmony import */ var web_com__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1546);
+/* harmony import */ var web_print_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1834);
+/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4927);
+/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8961);
+/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3234);
+/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(39);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([web_com__WEBPACK_IMPORTED_MODULE_0__, web_print_service__WEBPACK_IMPORTED_MODULE_1__, _app_js__WEBPACK_IMPORTED_MODULE_5__]);
+([web_com__WEBPACK_IMPORTED_MODULE_0__, web_print_service__WEBPACK_IMPORTED_MODULE_1__, _app_js__WEBPACK_IMPORTED_MODULE_5__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
+
+
+
+
+
+
+const pdfjsVersion = '4.0.379';
+const pdfjsBuild = '9e14d04fd';
+const AppConstants = {
+ LinkTarget: _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget,
+ RenderingStates: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.RenderingStates,
+ ScrollMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.ScrollMode,
+ SpreadMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.SpreadMode
+};
+window.PDFViewerApplication = _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication;
+window.PDFViewerApplicationConstants = AppConstants;
+window.PDFViewerApplicationOptions = _app_options_js__WEBPACK_IMPORTED_MODULE_3__.AppOptions;
+function getViewerConfiguration() {
+ return {
+ appContainer: document.body,
+ mainContainer: document.getElementById("viewerContainer"),
+ viewerContainer: document.getElementById("viewer"),
+ toolbar: {
+ container: document.getElementById("toolbarViewer"),
+ numPages: document.getElementById("numPages"),
+ pageNumber: document.getElementById("pageNumber"),
+ scaleSelect: document.getElementById("scaleSelect"),
+ customScaleOption: document.getElementById("customScaleOption"),
+ previous: document.getElementById("previous"),
+ next: document.getElementById("next"),
+ zoomIn: document.getElementById("zoomIn"),
+ zoomOut: document.getElementById("zoomOut"),
+ viewFind: document.getElementById("viewFind"),
+ print: document.getElementById("print"),
+ editorFreeTextButton: document.getElementById("editorFreeText"),
+ editorFreeTextParamsToolbar: document.getElementById("editorFreeTextParamsToolbar"),
+ editorHighlightButton: document.getElementById("editorHighlight"),
+ editorHighlightParamsToolbar: document.getElementById("editorHighlightParamsToolbar"),
+ editorHighlightColorPicker: document.getElementById("editorHighlightColorPicker"),
+ editorInkButton: document.getElementById("editorInk"),
+ editorInkParamsToolbar: document.getElementById("editorInkParamsToolbar"),
+ editorStampButton: document.getElementById("editorStamp"),
+ editorStampParamsToolbar: document.getElementById("editorStampParamsToolbar"),
+ download: document.getElementById("download")
+ },
+ secondaryToolbar: {
+ toolbar: document.getElementById("secondaryToolbar"),
+ toggleButton: document.getElementById("secondaryToolbarToggle"),
+ presentationModeButton: document.getElementById("presentationMode"),
+ openFileButton: document.getElementById("secondaryOpenFile"),
+ printButton: document.getElementById("secondaryPrint"),
+ downloadButton: document.getElementById("secondaryDownload"),
+ viewBookmarkButton: document.getElementById("viewBookmark"),
+ firstPageButton: document.getElementById("firstPage"),
+ lastPageButton: document.getElementById("lastPage"),
+ pageRotateCwButton: document.getElementById("pageRotateCw"),
+ pageRotateCcwButton: document.getElementById("pageRotateCcw"),
+ cursorSelectToolButton: document.getElementById("cursorSelectTool"),
+ cursorHandToolButton: document.getElementById("cursorHandTool"),
+ scrollPageButton: document.getElementById("scrollPage"),
+ scrollVerticalButton: document.getElementById("scrollVertical"),
+ scrollHorizontalButton: document.getElementById("scrollHorizontal"),
+ scrollWrappedButton: document.getElementById("scrollWrapped"),
+ spreadNoneButton: document.getElementById("spreadNone"),
+ spreadOddButton: document.getElementById("spreadOdd"),
+ spreadEvenButton: document.getElementById("spreadEven"),
+ documentPropertiesButton: document.getElementById("documentProperties")
+ },
+ sidebar: {
+ outerContainer: document.getElementById("outerContainer"),
+ sidebarContainer: document.getElementById("sidebarContainer"),
+ toggleButton: document.getElementById("sidebarToggle"),
+ resizer: document.getElementById("sidebarResizer"),
+ thumbnailButton: document.getElementById("viewThumbnail"),
+ outlineButton: document.getElementById("viewOutline"),
+ attachmentsButton: document.getElementById("viewAttachments"),
+ layersButton: document.getElementById("viewLayers"),
+ thumbnailView: document.getElementById("thumbnailView"),
+ outlineView: document.getElementById("outlineView"),
+ attachmentsView: document.getElementById("attachmentsView"),
+ layersView: document.getElementById("layersView"),
+ currentOutlineItemButton: document.getElementById("currentOutlineItem")
+ },
+ findBar: {
+ bar: document.getElementById("findbar"),
+ toggleButton: document.getElementById("viewFind"),
+ findField: document.getElementById("findInput"),
+ highlightAllCheckbox: document.getElementById("findHighlightAll"),
+ caseSensitiveCheckbox: document.getElementById("findMatchCase"),
+ matchDiacriticsCheckbox: document.getElementById("findMatchDiacritics"),
+ entireWordCheckbox: document.getElementById("findEntireWord"),
+ findMsg: document.getElementById("findMsg"),
+ findResultsCount: document.getElementById("findResultsCount"),
+ findPreviousButton: document.getElementById("findPrevious"),
+ findNextButton: document.getElementById("findNext")
+ },
+ passwordOverlay: {
+ dialog: document.getElementById("passwordDialog"),
+ label: document.getElementById("passwordText"),
+ input: document.getElementById("password"),
+ submitButton: document.getElementById("passwordSubmit"),
+ cancelButton: document.getElementById("passwordCancel")
+ },
+ documentProperties: {
+ dialog: document.getElementById("documentPropertiesDialog"),
+ closeButton: document.getElementById("documentPropertiesClose"),
+ fields: {
+ fileName: document.getElementById("fileNameField"),
+ fileSize: document.getElementById("fileSizeField"),
+ title: document.getElementById("titleField"),
+ author: document.getElementById("authorField"),
+ subject: document.getElementById("subjectField"),
+ keywords: document.getElementById("keywordsField"),
+ creationDate: document.getElementById("creationDateField"),
+ modificationDate: document.getElementById("modificationDateField"),
+ creator: document.getElementById("creatorField"),
+ producer: document.getElementById("producerField"),
+ version: document.getElementById("versionField"),
+ pageCount: document.getElementById("pageCountField"),
+ pageSize: document.getElementById("pageSizeField"),
+ linearized: document.getElementById("linearizedField")
+ }
+ },
+ altTextDialog: {
+ dialog: document.getElementById("altTextDialog"),
+ optionDescription: document.getElementById("descriptionButton"),
+ optionDecorative: document.getElementById("decorativeButton"),
+ textarea: document.getElementById("descriptionTextarea"),
+ cancelButton: document.getElementById("altTextCancel"),
+ saveButton: document.getElementById("altTextSave")
+ },
+ annotationEditorParams: {
+ editorFreeTextFontSize: document.getElementById("editorFreeTextFontSize"),
+ editorFreeTextColor: document.getElementById("editorFreeTextColor"),
+ editorInkColor: document.getElementById("editorInkColor"),
+ editorInkThickness: document.getElementById("editorInkThickness"),
+ editorInkOpacity: document.getElementById("editorInkOpacity"),
+ editorStampAddImage: document.getElementById("editorStampAddImage")
+ },
+ printContainer: document.getElementById("printContainer"),
+ openFileInput: document.getElementById("fileInput"),
+ debuggerScriptPath: "./debugger.mjs"
+ };
+}
+function webViewerLoad() {
+ const config = getViewerConfiguration();
+ const event = new CustomEvent("webviewerloaded", {
+ bubbles: true,
+ cancelable: true,
+ detail: {
+ source: window
+ }
+ });
+ try {
+ parent.document.dispatchEvent(event);
+ } catch (ex) {
+ console.error(`webviewerloaded: ${ex}`);
+ document.dispatchEvent(event);
+ }
+ _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication.run(config);
+}
+document.blockUnblockOnload?.(true);
+if (document.readyState === "interactive" || document.readyState === "complete") {
+ webViewerLoad();
+} else {
+ document.addEventListener("DOMContentLoaded", webViewerLoad, true);
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+
+/***/ 8012:
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ XfaLayerBuilder: () => (/* binding */ XfaLayerBuilder)
+/* harmony export */ });
+/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]);
+pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+class XfaLayerBuilder {
+ constructor({
+ pdfPage,
+ annotationStorage = null,
+ linkService,
+ xfaHtml = null
+ }) {
+ this.pdfPage = pdfPage;
+ this.annotationStorage = annotationStorage;
+ this.linkService = linkService;
+ this.xfaHtml = xfaHtml;
+ this.div = null;
+ this._cancelled = false;
+ }
+ async render(viewport, intent = "display") {
+ if (intent === "print") {
+ const parameters = {
+ viewport: viewport.clone({
+ dontFlip: true
+ }),
+ div: this.div,
+ xfaHtml: this.xfaHtml,
+ annotationStorage: this.annotationStorage,
+ linkService: this.linkService,
+ intent
+ };
+ this.div = document.createElement("div");
+ parameters.div = this.div;
+ return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.render(parameters);
+ }
+ const xfaHtml = await this.pdfPage.getXfa();
+ if (this._cancelled || !xfaHtml) {
+ return {
+ textDivs: []
+ };
+ }
+ const parameters = {
+ viewport: viewport.clone({
+ dontFlip: true
+ }),
+ div: this.div,
+ xfaHtml,
+ annotationStorage: this.annotationStorage,
+ linkService: this.linkService,
+ intent
+ };
+ if (this.div) {
+ return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.update(parameters);
+ }
+ this.div = document.createElement("div");
+ parameters.div = this.div;
+ return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.render(parameters);
+ }
+ cancel() {
+ this._cancelled = true;
+ }
+ hide() {
+ if (!this.div) {
+ return;
+ }
+ this.div.hidden = true;
+ }
+}
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/async module */
+/******/ (() => {
+/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";
+/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";
+/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";
+/******/ var resolveQueue = (queue) => {
+/******/ if(queue && queue.d < 1) {
+/******/ queue.d = 1;
+/******/ queue.forEach((fn) => (fn.r--));
+/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));
+/******/ }
+/******/ }
+/******/ var wrapDeps = (deps) => (deps.map((dep) => {
+/******/ if(dep !== null && typeof dep === "object") {
+/******/ if(dep[webpackQueues]) return dep;
+/******/ if(dep.then) {
+/******/ var queue = [];
+/******/ queue.d = 0;
+/******/ dep.then((r) => {
+/******/ obj[webpackExports] = r;
+/******/ resolveQueue(queue);
+/******/ }, (e) => {
+/******/ obj[webpackError] = e;
+/******/ resolveQueue(queue);
+/******/ });
+/******/ var obj = {};
+/******/ obj[webpackQueues] = (fn) => (fn(queue));
+/******/ return obj;
+/******/ }
+/******/ }
+/******/ var ret = {};
+/******/ ret[webpackQueues] = x => {};
+/******/ ret[webpackExports] = dep;
+/******/ return ret;
+/******/ }));
+/******/ __webpack_require__.a = (module, body, hasAwait) => {
+/******/ var queue;
+/******/ hasAwait && ((queue = []).d = -1);
+/******/ var depQueues = new Set();
+/******/ var exports = module.exports;
+/******/ var currentDeps;
+/******/ var outerResolve;
+/******/ var reject;
+/******/ var promise = new Promise((resolve, rej) => {
+/******/ reject = rej;
+/******/ outerResolve = resolve;
+/******/ });
+/******/ promise[webpackExports] = exports;
+/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {}));
+/******/ module.exports = promise;
+/******/ body((deps) => {
+/******/ currentDeps = wrapDeps(deps);
+/******/ var fn;
+/******/ var getResult = () => (currentDeps.map((d) => {
+/******/ if(d[webpackError]) throw d[webpackError];
+/******/ return d[webpackExports];
+/******/ }))
+/******/ var promise = new Promise((resolve) => {
+/******/ fn = () => (resolve(getResult));
+/******/ fn.r = 0;
+/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));
+/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue)));
+/******/ });
+/******/ return fn.r ? promise : getResult();
+/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));
+/******/ queue && queue.d < 0 && (queue.d = 0);
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ (() => {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = (exports, definition) => {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ })();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ (() => {
+/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+/******/ })();
+/******/
+/************************************************************************/
+/******/
+/******/ // startup
+/******/ // Load entry module and return exports
+/******/ // This entry module used 'module' so it can't be inlined
+/******/ var __webpack_exports__ = __webpack_require__(6400);
+/******/ __webpack_exports__ = await __webpack_exports__;
+/******/ var __webpack_exports__PDFViewerApplication = __webpack_exports__.PDFViewerApplication;
+/******/ var __webpack_exports__PDFViewerApplicationConstants = __webpack_exports__.PDFViewerApplicationConstants;
+/******/ var __webpack_exports__PDFViewerApplicationOptions = __webpack_exports__.PDFViewerApplicationOptions;
+/******/ export { __webpack_exports__PDFViewerApplication as PDFViewerApplication, __webpack_exports__PDFViewerApplicationConstants as PDFViewerApplicationConstants, __webpack_exports__PDFViewerApplicationOptions as PDFViewerApplicationOptions };
+/******/
+
+//# sourceMappingURL=viewer.mjs.map
\ No newline at end of file
diff --git a/www/lib/pdfjs/modern/web/viewer.mjs.map b/www/lib/pdfjs/modern/web/viewer.mjs.map
new file mode 100644
index 000000000..2ade1af7a
--- /dev/null
+++ b/www/lib/pdfjs/modern/web/viewer.mjs.map
@@ -0,0 +1 @@
+{"version":3,"file":"viewer.mjs","mappings":"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","sources":["webpack://pdf.js/node_modules/@fluent/bundle/esm/types.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/resolver.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/scope.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/builtins.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/memoizer.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/bundle.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/resource.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/index.js","webpack://pdf.js/node_modules/@fluent/dom/esm/overlay.js","webpack://pdf.js/node_modules/cached-iterable/src/cached_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/cached_sync_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/cached_async_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/index.mjs","webpack://pdf.js/node_modules/@fluent/dom/esm/localization.js","webpack://pdf.js/node_modules/@fluent/dom/esm/dom_localization.js","webpack://pdf.js/node_modules/@fluent/dom/esm/index.js","webpack://pdf.js/web/alt_text_manager.js","webpack://pdf.js/web/annotation_editor_layer_builder.js","webpack://pdf.js/web/annotation_editor_params.js","webpack://pdf.js/web/annotation_layer_builder.js","webpack://pdf.js/web/app.js","webpack://pdf.js/web/app_options.js","webpack://pdf.js/web/base_tree_viewer.js","webpack://pdf.js/web/download_manager.js","webpack://pdf.js/web/draw_layer_builder.js","webpack://pdf.js/web/event_utils.js","webpack://pdf.js/web/generic_scripting.js","webpack://pdf.js/web/genericcom.js","webpack://pdf.js/web/genericl10n.js","webpack://pdf.js/web/grab_to_pan.js","webpack://pdf.js/web/l10n.js","webpack://pdf.js/web/l10n_utils.js","webpack://pdf.js/web/overlay_manager.js","webpack://pdf.js/web/password_prompt.js","webpack://pdf.js/web/pdf_attachment_viewer.js","webpack://pdf.js/web/pdf_cursor_tools.js","webpack://pdf.js/web/pdf_document_properties.js","webpack://pdf.js/web/pdf_find_bar.js","webpack://pdf.js/web/pdf_find_controller.js","webpack://pdf.js/web/pdf_find_utils.js","webpack://pdf.js/web/pdf_history.js","webpack://pdf.js/web/pdf_layer_viewer.js","webpack://pdf.js/web/pdf_link_service.js","webpack://pdf.js/web/pdf_outline_viewer.js","webpack://pdf.js/web/pdf_page_view.js","webpack://pdf.js/web/pdf_presentation_mode.js","webpack://pdf.js/web/pdf_print_service.js","webpack://pdf.js/web/pdf_rendering_queue.js","webpack://pdf.js/web/pdf_scripting_manager.js","webpack://pdf.js/web/pdf_sidebar.js","webpack://pdf.js/web/pdf_thumbnail_view.js","webpack://pdf.js/web/pdf_thumbnail_viewer.js","webpack://pdf.js/web/pdf_viewer.js","webpack://pdf.js/web/pdfjs.js","webpack://pdf.js/web/preferences.js","webpack://pdf.js/web/print_utils.js","webpack://pdf.js/web/secondary_toolbar.js","webpack://pdf.js/web/struct_tree_layer_builder.js","webpack://pdf.js/web/text_accessibility.js","webpack://pdf.js/web/text_highlighter.js","webpack://pdf.js/web/text_layer_builder.js","webpack://pdf.js/web/toolbar.js","webpack://pdf.js/web/ui_utils.js","webpack://pdf.js/web/view_history.js","webpack://pdf.js/web/viewer.js","webpack://pdf.js/web/xfa_layer_builder.js","webpack://pdf.js/webpack/bootstrap","webpack://pdf.js/webpack/runtime/async module","webpack://pdf.js/webpack/runtime/define property getters","webpack://pdf.js/webpack/runtime/hasOwnProperty shorthand","webpack://pdf.js/webpack/before-startup","webpack://pdf.js/webpack/startup","webpack://pdf.js/webpack/after-startup"],"sourcesContent":["/**\n * The `FluentType` class is the base of Fluent's type system.\n *\n * Fluent types wrap JavaScript values and store additional configuration for\n * them, which can then be used in the `toString` method together with a proper\n * `Intl` formatter.\n */\nexport class FluentType {\n /**\n * Create a `FluentType` instance.\n *\n * @param value The JavaScript value to wrap.\n */\n constructor(value) {\n this.value = value;\n }\n /**\n * Unwrap the raw value stored by this `FluentType`.\n */\n valueOf() {\n return this.value;\n }\n}\n/**\n * A `FluentType` representing no correct value.\n */\nexport class FluentNone extends FluentType {\n /**\n * Create an instance of `FluentNone` with an optional fallback value.\n * @param value The fallback value of this `FluentNone`.\n */\n constructor(value = \"???\") {\n super(value);\n }\n /**\n * Format this `FluentNone` to the fallback string.\n */\n toString(scope) {\n return `{${this.value}}`;\n }\n}\n/**\n * A `FluentType` representing a number.\n *\n * A `FluentNumber` instance stores the number value of the number it\n * represents. It may also store an option bag of options which will be passed\n * to `Intl.NumerFormat` when the `FluentNumber` is formatted to a string.\n */\nexport class FluentNumber extends FluentType {\n /**\n * Create an instance of `FluentNumber` with options to the\n * `Intl.NumberFormat` constructor.\n *\n * @param value The number value of this `FluentNumber`.\n * @param opts Options which will be passed to `Intl.NumberFormat`.\n */\n constructor(value, opts = {}) {\n super(value);\n this.opts = opts;\n }\n /**\n * Format this `FluentNumber` to a string.\n */\n toString(scope) {\n try {\n const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);\n return nf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n return this.value.toString(10);\n }\n }\n}\n/**\n * A `FluentType` representing a date and time.\n *\n * A `FluentDateTime` instance stores the number value of the date it\n * represents, as a numerical timestamp in milliseconds. It may also store an\n * option bag of options which will be passed to `Intl.DateTimeFormat` when the\n * `FluentDateTime` is formatted to a string.\n */\nexport class FluentDateTime extends FluentType {\n /**\n * Create an instance of `FluentDateTime` with options to the\n * `Intl.DateTimeFormat` constructor.\n *\n * @param value The number value of this `FluentDateTime`, in milliseconds.\n * @param opts Options which will be passed to `Intl.DateTimeFormat`.\n */\n constructor(value, opts = {}) {\n super(value);\n this.opts = opts;\n }\n /**\n * Format this `FluentDateTime` to a string.\n */\n toString(scope) {\n try {\n const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);\n return dtf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n return new Date(this.value).toISOString();\n }\n }\n}\n","/* global Intl */\n/**\n * @overview\n *\n * The role of the Fluent resolver is to format a `Pattern` to an instance of\n * `FluentValue`. For performance reasons, primitive strings are considered\n * such instances, too.\n *\n * Translations can contain references to other messages or variables,\n * conditional logic in form of select expressions, traits which describe their\n * grammatical features, and can use Fluent builtins which make use of the\n * `Intl` formatters to format numbers and dates into the bundle's languages.\n * See the documentation of the Fluent syntax for more information.\n *\n * In case of errors the resolver will try to salvage as much of the\n * translation as possible. In rare situations where the resolver didn't know\n * how to recover from an error it will return an instance of `FluentNone`.\n *\n * All expressions resolve to an instance of `FluentValue`. The caller should\n * use the `toString` method to convert the instance to a native value.\n *\n * Functions in this file pass around an instance of the `Scope` class, which\n * stores the data required for successful resolution and error recovery.\n */\nimport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n/**\n * The maximum number of placeables which can be expanded in a single call to\n * `formatPattern`. The limit protects against the Billion Laughs and Quadratic\n * Blowup attacks. See https://msdn.microsoft.com/en-us/magazine/ee335713.aspx.\n */\nconst MAX_PLACEABLES = 100;\n/** Unicode bidi isolation characters. */\nconst FSI = \"\\u2068\";\nconst PDI = \"\\u2069\";\n/** Helper: match a variant key to the given selector. */\nfunction match(scope, selector, key) {\n if (key === selector) {\n // Both are strings.\n return true;\n }\n // XXX Consider comparing options too, e.g. minimumFractionDigits.\n if (key instanceof FluentNumber &&\n selector instanceof FluentNumber &&\n key.value === selector.value) {\n return true;\n }\n if (selector instanceof FluentNumber && typeof key === \"string\") {\n let category = scope\n .memoizeIntlObject(Intl.PluralRules, selector.opts)\n .select(selector.value);\n if (key === category) {\n return true;\n }\n }\n return false;\n}\n/** Helper: resolve the default variant from a list of variants. */\nfunction getDefault(scope, variants, star) {\n if (variants[star]) {\n return resolvePattern(scope, variants[star].value);\n }\n scope.reportError(new RangeError(\"No default\"));\n return new FluentNone();\n}\n/** Helper: resolve arguments to a call expression. */\nfunction getArguments(scope, args) {\n const positional = [];\n const named = Object.create(null);\n for (const arg of args) {\n if (arg.type === \"narg\") {\n named[arg.name] = resolveExpression(scope, arg.value);\n }\n else {\n positional.push(resolveExpression(scope, arg));\n }\n }\n return { positional, named };\n}\n/** Resolve an expression to a Fluent type. */\nfunction resolveExpression(scope, expr) {\n switch (expr.type) {\n case \"str\":\n return expr.value;\n case \"num\":\n return new FluentNumber(expr.value, {\n minimumFractionDigits: expr.precision,\n });\n case \"var\":\n return resolveVariableReference(scope, expr);\n case \"mesg\":\n return resolveMessageReference(scope, expr);\n case \"term\":\n return resolveTermReference(scope, expr);\n case \"func\":\n return resolveFunctionReference(scope, expr);\n case \"select\":\n return resolveSelectExpression(scope, expr);\n default:\n return new FluentNone();\n }\n}\n/** Resolve a reference to a variable. */\nfunction resolveVariableReference(scope, { name }) {\n let arg;\n if (scope.params) {\n // We're inside a TermReference. It's OK to reference undefined parameters.\n if (Object.prototype.hasOwnProperty.call(scope.params, name)) {\n arg = scope.params[name];\n }\n else {\n return new FluentNone(`$${name}`);\n }\n }\n else if (scope.args &&\n Object.prototype.hasOwnProperty.call(scope.args, name)) {\n // We're in the top-level Pattern or inside a MessageReference. Missing\n // variables references produce ReferenceErrors.\n arg = scope.args[name];\n }\n else {\n scope.reportError(new ReferenceError(`Unknown variable: $${name}`));\n return new FluentNone(`$${name}`);\n }\n // Return early if the argument already is an instance of FluentType.\n if (arg instanceof FluentType) {\n return arg;\n }\n // Convert the argument to a Fluent type.\n switch (typeof arg) {\n case \"string\":\n return arg;\n case \"number\":\n return new FluentNumber(arg);\n case \"object\":\n if (arg instanceof Date) {\n return new FluentDateTime(arg.getTime());\n }\n // eslint-disable-next-line no-fallthrough\n default:\n scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`));\n return new FluentNone(`$${name}`);\n }\n}\n/** Resolve a reference to another message. */\nfunction resolveMessageReference(scope, { name, attr }) {\n const message = scope.bundle._messages.get(name);\n if (!message) {\n scope.reportError(new ReferenceError(`Unknown message: ${name}`));\n return new FluentNone(name);\n }\n if (attr) {\n const attribute = message.attributes[attr];\n if (attribute) {\n return resolvePattern(scope, attribute);\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${name}.${attr}`);\n }\n if (message.value) {\n return resolvePattern(scope, message.value);\n }\n scope.reportError(new ReferenceError(`No value: ${name}`));\n return new FluentNone(name);\n}\n/** Resolve a call to a Term with key-value arguments. */\nfunction resolveTermReference(scope, { name, attr, args }) {\n const id = `-${name}`;\n const term = scope.bundle._terms.get(id);\n if (!term) {\n scope.reportError(new ReferenceError(`Unknown term: ${id}`));\n return new FluentNone(id);\n }\n if (attr) {\n const attribute = term.attributes[attr];\n if (attribute) {\n // Every TermReference has its own variables.\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, attribute);\n scope.params = null;\n return resolved;\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${id}.${attr}`);\n }\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, term.value);\n scope.params = null;\n return resolved;\n}\n/** Resolve a call to a Function with positional and key-value arguments. */\nfunction resolveFunctionReference(scope, { name, args }) {\n // Some functions are built-in. Others may be provided by the runtime via\n // the `FluentBundle` constructor.\n let func = scope.bundle._functions[name];\n if (!func) {\n scope.reportError(new ReferenceError(`Unknown function: ${name}()`));\n return new FluentNone(`${name}()`);\n }\n if (typeof func !== \"function\") {\n scope.reportError(new TypeError(`Function ${name}() is not callable`));\n return new FluentNone(`${name}()`);\n }\n try {\n let resolved = getArguments(scope, args);\n return func(resolved.positional, resolved.named);\n }\n catch (err) {\n scope.reportError(err);\n return new FluentNone(`${name}()`);\n }\n}\n/** Resolve a select expression to the member object. */\nfunction resolveSelectExpression(scope, { selector, variants, star }) {\n let sel = resolveExpression(scope, selector);\n if (sel instanceof FluentNone) {\n return getDefault(scope, variants, star);\n }\n // Match the selector against keys of each variant, in order.\n for (const variant of variants) {\n const key = resolveExpression(scope, variant.key);\n if (match(scope, sel, key)) {\n return resolvePattern(scope, variant.value);\n }\n }\n return getDefault(scope, variants, star);\n}\n/** Resolve a pattern (a complex string with placeables). */\nexport function resolveComplexPattern(scope, ptn) {\n if (scope.dirty.has(ptn)) {\n scope.reportError(new RangeError(\"Cyclic reference\"));\n return new FluentNone();\n }\n // Tag the pattern as dirty for the purpose of the current resolution.\n scope.dirty.add(ptn);\n const result = [];\n // Wrap interpolations with Directional Isolate Formatting characters\n // only when the pattern has more than one element.\n const useIsolating = scope.bundle._useIsolating && ptn.length > 1;\n for (const elem of ptn) {\n if (typeof elem === \"string\") {\n result.push(scope.bundle._transform(elem));\n continue;\n }\n scope.placeables++;\n if (scope.placeables > MAX_PLACEABLES) {\n scope.dirty.delete(ptn);\n // This is a fatal error which causes the resolver to instantly bail out\n // on this pattern. The length check protects against excessive memory\n // usage, and throwing protects against eating up the CPU when long\n // placeables are deeply nested.\n throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` +\n `max allowed is ${MAX_PLACEABLES}`);\n }\n if (useIsolating) {\n result.push(FSI);\n }\n result.push(resolveExpression(scope, elem).toString(scope));\n if (useIsolating) {\n result.push(PDI);\n }\n }\n scope.dirty.delete(ptn);\n return result.join(\"\");\n}\n/**\n * Resolve a simple or a complex Pattern to a FluentString\n * (which is really the string primitive).\n */\nfunction resolvePattern(scope, value) {\n // Resolve a simple pattern.\n if (typeof value === \"string\") {\n return scope.bundle._transform(value);\n }\n return resolveComplexPattern(scope, value);\n}\n","export class Scope {\n constructor(bundle, errors, args) {\n /**\n * The Set of patterns already encountered during this resolution.\n * Used to detect and prevent cyclic resolutions.\n * @ignore\n */\n this.dirty = new WeakSet();\n /** A dict of parameters passed to a TermReference. */\n this.params = null;\n /**\n * The running count of placeables resolved so far.\n * Used to detect the Billion Laughs and Quadratic Blowup attacks.\n * @ignore\n */\n this.placeables = 0;\n this.bundle = bundle;\n this.errors = errors;\n this.args = args;\n }\n reportError(error) {\n if (!this.errors || !(error instanceof Error)) {\n throw error;\n }\n this.errors.push(error);\n }\n memoizeIntlObject(ctor, opts) {\n let cache = this.bundle._intls.get(ctor);\n if (!cache) {\n cache = {};\n this.bundle._intls.set(ctor, cache);\n }\n let id = JSON.stringify(opts);\n if (!cache[id]) {\n cache[id] = new ctor(this.bundle.locales, opts);\n }\n return cache[id];\n }\n}\n","/**\n * @overview\n *\n * The FTL resolver ships with a number of functions built-in.\n *\n * Each function take two arguments:\n * - args - an array of positional args\n * - opts - an object of key-value args\n *\n * Arguments to functions are guaranteed to already be instances of\n * `FluentValue`. Functions must return `FluentValues` as well.\n */\nimport { FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\nfunction values(opts, allowed) {\n const unwrapped = Object.create(null);\n for (const [name, opt] of Object.entries(opts)) {\n if (allowed.includes(name)) {\n unwrapped[name] = opt.valueOf();\n }\n }\n return unwrapped;\n}\nconst NUMBER_ALLOWED = [\n \"unitDisplay\",\n \"currencyDisplay\",\n \"useGrouping\",\n \"minimumIntegerDigits\",\n \"minimumFractionDigits\",\n \"maximumFractionDigits\",\n \"minimumSignificantDigits\",\n \"maximumSignificantDigits\",\n];\n/**\n * The implementation of the `NUMBER()` builtin available to translations.\n *\n * Translations may call the `NUMBER()` builtin in order to specify formatting\n * options of a number. For example:\n *\n * pi = The value of π is {NUMBER($pi, maximumFractionDigits: 2)}.\n *\n * The implementation expects an array of `FluentValues` representing the\n * positional arguments, and an object of named `FluentValues` representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * unitDisplay\n * currencyDisplay\n * useGrouping\n * minimumIntegerDigits\n * minimumFractionDigits\n * maximumFractionDigits\n * minimumSignificantDigits\n * maximumSignificantDigits\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `NUMBER()`.\n * @param opts The named argments passed to this `NUMBER()`.\n */\nexport function NUMBER(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`NUMBER(${arg.valueOf()})`);\n }\n if (arg instanceof FluentNumber) {\n return new FluentNumber(arg.valueOf(), {\n ...arg.opts,\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n if (arg instanceof FluentDateTime) {\n return new FluentNumber(arg.valueOf(), {\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n throw new TypeError(\"Invalid argument to NUMBER\");\n}\nconst DATETIME_ALLOWED = [\n \"dateStyle\",\n \"timeStyle\",\n \"fractionalSecondDigits\",\n \"dayPeriod\",\n \"hour12\",\n \"weekday\",\n \"era\",\n \"year\",\n \"month\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n \"timeZoneName\",\n];\n/**\n * The implementation of the `DATETIME()` builtin available to translations.\n *\n * Translations may call the `DATETIME()` builtin in order to specify\n * formatting options of a number. For example:\n *\n * now = It's {DATETIME($today, month: \"long\")}.\n *\n * The implementation expects an array of `FluentValues` representing the\n * positional arguments, and an object of named `FluentValues` representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * dateStyle\n * timeStyle\n * fractionalSecondDigits\n * dayPeriod\n * hour12\n * weekday\n * era\n * year\n * month\n * day\n * hour\n * minute\n * second\n * timeZoneName\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `DATETIME()`.\n * @param opts The named argments passed to this `DATETIME()`.\n */\nexport function DATETIME(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`DATETIME(${arg.valueOf()})`);\n }\n if (arg instanceof FluentDateTime) {\n return new FluentDateTime(arg.valueOf(), {\n ...arg.opts,\n ...values(opts, DATETIME_ALLOWED),\n });\n }\n if (arg instanceof FluentNumber) {\n return new FluentDateTime(arg.valueOf(), {\n ...values(opts, DATETIME_ALLOWED),\n });\n }\n throw new TypeError(\"Invalid argument to DATETIME\");\n}\n","const cache = new Map();\nexport function getMemoizerForLocale(locales) {\n const stringLocale = Array.isArray(locales) ? locales.join(\" \") : locales;\n let memoizer = cache.get(stringLocale);\n if (memoizer === undefined) {\n memoizer = new Map();\n cache.set(stringLocale, memoizer);\n }\n return memoizer;\n}\n","import { resolveComplexPattern } from \"./resolver.js\";\nimport { Scope } from \"./scope.js\";\nimport { FluentNone } from \"./types.js\";\nimport { NUMBER, DATETIME } from \"./builtins.js\";\nimport { getMemoizerForLocale } from \"./memoizer.js\";\n/**\n * Message bundles are single-language stores of translation resources. They are\n * responsible for formatting message values and attributes to strings.\n */\nexport class FluentBundle {\n /**\n * Create an instance of `FluentBundle`.\n *\n * @example\n * ```js\n * let bundle = new FluentBundle([\"en-US\", \"en\"]);\n *\n * let bundle = new FluentBundle(locales, {useIsolating: false});\n *\n * let bundle = new FluentBundle(locales, {\n * useIsolating: true,\n * functions: {\n * NODE_ENV: () => process.env.NODE_ENV\n * }\n * });\n * ```\n *\n * @param locales - Used to instantiate `Intl` formatters used by translations.\n * @param options - Optional configuration for the bundle.\n */\n constructor(locales, { functions, useIsolating = true, transform = (v) => v, } = {}) {\n /** @ignore */\n this._terms = new Map();\n /** @ignore */\n this._messages = new Map();\n this.locales = Array.isArray(locales) ? locales : [locales];\n this._functions = {\n NUMBER,\n DATETIME,\n ...functions,\n };\n this._useIsolating = useIsolating;\n this._transform = transform;\n this._intls = getMemoizerForLocale(locales);\n }\n /**\n * Check if a message is present in the bundle.\n *\n * @param id - The identifier of the message to check.\n */\n hasMessage(id) {\n return this._messages.has(id);\n }\n /**\n * Return a raw unformatted message object from the bundle.\n *\n * Raw messages are `{value, attributes}` shapes containing translation units\n * called `Patterns`. `Patterns` are implementation-specific; they should be\n * treated as black boxes and formatted with `FluentBundle.formatPattern`.\n *\n * @param id - The identifier of the message to check.\n */\n getMessage(id) {\n return this._messages.get(id);\n }\n /**\n * Add a translation resource to the bundle.\n *\n * @example\n * ```js\n * let res = new FluentResource(\"foo = Foo\");\n * bundle.addResource(res);\n * bundle.getMessage(\"foo\");\n * // → {value: .., attributes: {..}}\n * ```\n *\n * @param res\n * @param options\n */\n addResource(res, { allowOverrides = false, } = {}) {\n const errors = [];\n for (let i = 0; i < res.body.length; i++) {\n let entry = res.body[i];\n if (entry.id.startsWith(\"-\")) {\n // Identifiers starting with a dash (-) define terms. Terms are private\n // and cannot be retrieved from FluentBundle.\n if (allowOverrides === false && this._terms.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing term: \"${entry.id}\"`));\n continue;\n }\n this._terms.set(entry.id, entry);\n }\n else {\n if (allowOverrides === false && this._messages.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing message: \"${entry.id}\"`));\n continue;\n }\n this._messages.set(entry.id, entry);\n }\n }\n return errors;\n }\n /**\n * Format a `Pattern` to a string.\n *\n * Format a raw `Pattern` into a string. `args` will be used to resolve\n * references to variables passed as arguments to the translation.\n *\n * In case of errors `formatPattern` will try to salvage as much of the\n * translation as possible and will still return a string. For performance\n * reasons, the encountered errors are not returned but instead are appended\n * to the `errors` array passed as the third argument.\n *\n * If `errors` is omitted, the first encountered error will be thrown.\n *\n * @example\n * ```js\n * let errors = [];\n * bundle.addResource(\n * new FluentResource(\"hello = Hello, {$name}!\"));\n *\n * let hello = bundle.getMessage(\"hello\");\n * if (hello.value) {\n * bundle.formatPattern(hello.value, {name: \"Jane\"}, errors);\n * // Returns \"Hello, Jane!\" and `errors` is empty.\n *\n * bundle.formatPattern(hello.value, undefined, errors);\n * // Returns \"Hello, {$name}!\" and `errors` is now:\n * // []\n * }\n * ```\n */\n formatPattern(pattern, args = null, errors = null) {\n // Resolve a simple pattern without creating a scope. No error handling is\n // required; by definition simple patterns don't have placeables.\n if (typeof pattern === \"string\") {\n return this._transform(pattern);\n }\n // Resolve a complex pattern.\n let scope = new Scope(this, errors, args);\n try {\n let value = resolveComplexPattern(scope, pattern);\n return value.toString(scope);\n }\n catch (err) {\n if (scope.errors && err instanceof Error) {\n scope.errors.push(err);\n return new FluentNone().toString(scope);\n }\n throw err;\n }\n }\n}\n","// This regex is used to iterate through the beginnings of messages and terms.\n// With the /m flag, the ^ matches at the beginning of every line.\nconst RE_MESSAGE_START = /^(-?[a-zA-Z][\\w-]*) *= */gm;\n// Both Attributes and Variants are parsed in while loops. These regexes are\n// used to break out of them.\nconst RE_ATTRIBUTE_START = /\\.([a-zA-Z][\\w-]*) *= */y;\nconst RE_VARIANT_START = /\\*?\\[/y;\nconst RE_NUMBER_LITERAL = /(-?[0-9]+(?:\\.([0-9]+))?)/y;\nconst RE_IDENTIFIER = /([a-zA-Z][\\w-]*)/y;\nconst RE_REFERENCE = /([$-])?([a-zA-Z][\\w-]*)(?:\\.([a-zA-Z][\\w-]*))?/y;\nconst RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/;\n// A \"run\" is a sequence of text or string literal characters which don't\n// require any special handling. For TextElements such special characters are: {\n// (starts a placeable), and line breaks which require additional logic to check\n// if the next line is indented. For StringLiterals they are: \\ (starts an\n// escape sequence), \" (ends the literal), and line breaks which are not allowed\n// in StringLiterals. Note that string runs may be empty; text runs may not.\nconst RE_TEXT_RUN = /([^{}\\n\\r]+)/y;\nconst RE_STRING_RUN = /([^\\\\\"\\n\\r]*)/y;\n// Escape sequences.\nconst RE_STRING_ESCAPE = /\\\\([\\\\\"])/y;\nconst RE_UNICODE_ESCAPE = /\\\\u([a-fA-F0-9]{4})|\\\\U([a-fA-F0-9]{6})/y;\n// Used for trimming TextElements and indents.\nconst RE_LEADING_NEWLINES = /^\\n+/;\nconst RE_TRAILING_SPACES = / +$/;\n// Used in makeIndent to strip spaces from blank lines and normalize CRLF to LF.\nconst RE_BLANK_LINES = / *\\r?\\n/g;\n// Used in makeIndent to measure the indentation.\nconst RE_INDENT = /( *)$/;\n// Common tokens.\nconst TOKEN_BRACE_OPEN = /{\\s*/y;\nconst TOKEN_BRACE_CLOSE = /\\s*}/y;\nconst TOKEN_BRACKET_OPEN = /\\[\\s*/y;\nconst TOKEN_BRACKET_CLOSE = /\\s*] */y;\nconst TOKEN_PAREN_OPEN = /\\s*\\(\\s*/y;\nconst TOKEN_ARROW = /\\s*->\\s*/y;\nconst TOKEN_COLON = /\\s*:\\s*/y;\n// Note the optional comma. As a deviation from the Fluent EBNF, the parser\n// doesn't enforce commas between call arguments.\nconst TOKEN_COMMA = /\\s*,?\\s*/y;\nconst TOKEN_BLANK = /\\s+/y;\n/**\n * Fluent Resource is a structure storing parsed localization entries.\n */\nexport class FluentResource {\n constructor(source) {\n this.body = [];\n RE_MESSAGE_START.lastIndex = 0;\n let cursor = 0;\n // Iterate over the beginnings of messages and terms to efficiently skip\n // comments and recover from errors.\n while (true) {\n let next = RE_MESSAGE_START.exec(source);\n if (next === null) {\n break;\n }\n cursor = RE_MESSAGE_START.lastIndex;\n try {\n this.body.push(parseMessage(next[1]));\n }\n catch (err) {\n if (err instanceof SyntaxError) {\n // Don't report any Fluent syntax errors. Skip directly to the\n // beginning of the next message or term.\n continue;\n }\n throw err;\n }\n }\n // The parser implementation is inlined below for performance reasons,\n // as well as for convenience of accessing `source` and `cursor`.\n // The parser focuses on minimizing the number of false negatives at the\n // expense of increasing the risk of false positives. In other words, it\n // aims at parsing valid Fluent messages with a success rate of 100%, but it\n // may also parse a few invalid messages which the reference parser would\n // reject. The parser doesn't perform any validation and may produce entries\n // which wouldn't make sense in the real world. For best results users are\n // advised to validate translations with the fluent-syntax parser\n // pre-runtime.\n // The parser makes an extensive use of sticky regexes which can be anchored\n // to any offset of the source string without slicing it. Errors are thrown\n // to bail out of parsing of ill-formed messages.\n function test(re) {\n re.lastIndex = cursor;\n return re.test(source);\n }\n // Advance the cursor by the char if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeChar(char, errorClass) {\n if (source[cursor] === char) {\n cursor++;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${char}`);\n }\n return false;\n }\n // Advance the cursor by the token if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeToken(re, errorClass) {\n if (test(re)) {\n cursor = re.lastIndex;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${re.toString()}`);\n }\n return false;\n }\n // Execute a regex, advance the cursor, and return all capture groups.\n function match(re) {\n re.lastIndex = cursor;\n let result = re.exec(source);\n if (result === null) {\n throw new SyntaxError(`Expected ${re.toString()}`);\n }\n cursor = re.lastIndex;\n return result;\n }\n // Execute a regex, advance the cursor, and return the capture group.\n function match1(re) {\n return match(re)[1];\n }\n function parseMessage(id) {\n let value = parsePattern();\n let attributes = parseAttributes();\n if (value === null && Object.keys(attributes).length === 0) {\n throw new SyntaxError(\"Expected message value or attributes\");\n }\n return { id, value, attributes };\n }\n function parseAttributes() {\n let attrs = Object.create(null);\n while (test(RE_ATTRIBUTE_START)) {\n let name = match1(RE_ATTRIBUTE_START);\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected attribute value\");\n }\n attrs[name] = value;\n }\n return attrs;\n }\n function parsePattern() {\n let first;\n // First try to parse any simple text on the same line as the id.\n if (test(RE_TEXT_RUN)) {\n first = match1(RE_TEXT_RUN);\n }\n // If there's a placeable on the first line, parse a complex pattern.\n if (source[cursor] === \"{\" || source[cursor] === \"}\") {\n // Re-use the text parsed above, if possible.\n return parsePatternElements(first ? [first] : [], Infinity);\n }\n // RE_TEXT_VALUE stops at newlines. Only continue parsing the pattern if\n // what comes after the newline is indented.\n let indent = parseIndent();\n if (indent) {\n if (first) {\n // If there's text on the first line, the blank block is part of the\n // translation content in its entirety.\n return parsePatternElements([first, indent], indent.length);\n }\n // Otherwise, we're dealing with a block pattern, i.e. a pattern which\n // starts on a new line. Discrad the leading newlines but keep the\n // inline indent; it will be used by the dedentation logic.\n indent.value = trim(indent.value, RE_LEADING_NEWLINES);\n return parsePatternElements([indent], indent.length);\n }\n if (first) {\n // It was just a simple inline text after all.\n return trim(first, RE_TRAILING_SPACES);\n }\n return null;\n }\n // Parse a complex pattern as an array of elements.\n function parsePatternElements(elements = [], commonIndent) {\n while (true) {\n if (test(RE_TEXT_RUN)) {\n elements.push(match1(RE_TEXT_RUN));\n continue;\n }\n if (source[cursor] === \"{\") {\n elements.push(parsePlaceable());\n continue;\n }\n if (source[cursor] === \"}\") {\n throw new SyntaxError(\"Unbalanced closing brace\");\n }\n let indent = parseIndent();\n if (indent) {\n elements.push(indent);\n commonIndent = Math.min(commonIndent, indent.length);\n continue;\n }\n break;\n }\n let lastIndex = elements.length - 1;\n let lastElement = elements[lastIndex];\n // Trim the trailing spaces in the last element if it's a TextElement.\n if (typeof lastElement === \"string\") {\n elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES);\n }\n let baked = [];\n for (let element of elements) {\n if (element instanceof Indent) {\n // Dedent indented lines by the maximum common indent.\n element = element.value.slice(0, element.value.length - commonIndent);\n }\n if (element) {\n baked.push(element);\n }\n }\n return baked;\n }\n function parsePlaceable() {\n consumeToken(TOKEN_BRACE_OPEN, SyntaxError);\n let selector = parseInlineExpression();\n if (consumeToken(TOKEN_BRACE_CLOSE)) {\n return selector;\n }\n if (consumeToken(TOKEN_ARROW)) {\n let variants = parseVariants();\n consumeToken(TOKEN_BRACE_CLOSE, SyntaxError);\n return {\n type: \"select\",\n selector,\n ...variants,\n };\n }\n throw new SyntaxError(\"Unclosed placeable\");\n }\n function parseInlineExpression() {\n if (source[cursor] === \"{\") {\n // It's a nested placeable.\n return parsePlaceable();\n }\n if (test(RE_REFERENCE)) {\n let [, sigil, name, attr = null] = match(RE_REFERENCE);\n if (sigil === \"$\") {\n return { type: \"var\", name };\n }\n if (consumeToken(TOKEN_PAREN_OPEN)) {\n let args = parseArguments();\n if (sigil === \"-\") {\n // A parameterized term: -term(...).\n return { type: \"term\", name, attr, args };\n }\n if (RE_FUNCTION_NAME.test(name)) {\n return { type: \"func\", name, args };\n }\n throw new SyntaxError(\"Function names must be all upper-case\");\n }\n if (sigil === \"-\") {\n // A non-parameterized term: -term.\n return {\n type: \"term\",\n name,\n attr,\n args: [],\n };\n }\n return { type: \"mesg\", name, attr };\n }\n return parseLiteral();\n }\n function parseArguments() {\n let args = [];\n while (true) {\n switch (source[cursor]) {\n case \")\": // End of the argument list.\n cursor++;\n return args;\n case undefined: // EOF\n throw new SyntaxError(\"Unclosed argument list\");\n }\n args.push(parseArgument());\n // Commas between arguments are treated as whitespace.\n consumeToken(TOKEN_COMMA);\n }\n }\n function parseArgument() {\n let expr = parseInlineExpression();\n if (expr.type !== \"mesg\") {\n return expr;\n }\n if (consumeToken(TOKEN_COLON)) {\n // The reference is the beginning of a named argument.\n return {\n type: \"narg\",\n name: expr.name,\n value: parseLiteral(),\n };\n }\n // It's a regular message reference.\n return expr;\n }\n function parseVariants() {\n let variants = [];\n let count = 0;\n let star;\n while (test(RE_VARIANT_START)) {\n if (consumeChar(\"*\")) {\n star = count;\n }\n let key = parseVariantKey();\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected variant value\");\n }\n variants[count++] = { key, value };\n }\n if (count === 0) {\n return null;\n }\n if (star === undefined) {\n throw new SyntaxError(\"Expected default variant\");\n }\n return { variants, star };\n }\n function parseVariantKey() {\n consumeToken(TOKEN_BRACKET_OPEN, SyntaxError);\n let key;\n if (test(RE_NUMBER_LITERAL)) {\n key = parseNumberLiteral();\n }\n else {\n key = {\n type: \"str\",\n value: match1(RE_IDENTIFIER),\n };\n }\n consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError);\n return key;\n }\n function parseLiteral() {\n if (test(RE_NUMBER_LITERAL)) {\n return parseNumberLiteral();\n }\n if (source[cursor] === '\"') {\n return parseStringLiteral();\n }\n throw new SyntaxError(\"Invalid expression\");\n }\n function parseNumberLiteral() {\n let [, value, fraction = \"\"] = match(RE_NUMBER_LITERAL);\n let precision = fraction.length;\n return {\n type: \"num\",\n value: parseFloat(value),\n precision,\n };\n }\n function parseStringLiteral() {\n consumeChar('\"', SyntaxError);\n let value = \"\";\n while (true) {\n value += match1(RE_STRING_RUN);\n if (source[cursor] === \"\\\\\") {\n value += parseEscapeSequence();\n continue;\n }\n if (consumeChar('\"')) {\n return { type: \"str\", value };\n }\n // We've reached an EOL of EOF.\n throw new SyntaxError(\"Unclosed string literal\");\n }\n }\n // Unescape known escape sequences.\n function parseEscapeSequence() {\n if (test(RE_STRING_ESCAPE)) {\n return match1(RE_STRING_ESCAPE);\n }\n if (test(RE_UNICODE_ESCAPE)) {\n let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE);\n let codepoint = parseInt(codepoint4 || codepoint6, 16);\n return codepoint <= 0xd7ff || 0xe000 <= codepoint\n ? // It's a Unicode scalar value.\n String.fromCodePoint(codepoint)\n : // Lonely surrogates can cause trouble when the parsing result is\n // saved using UTF-8. Use U+FFFD REPLACEMENT CHARACTER instead.\n \"�\";\n }\n throw new SyntaxError(\"Unknown escape sequence\");\n }\n // Parse blank space. Return it if it looks like indent before a pattern\n // line. Skip it othwerwise.\n function parseIndent() {\n let start = cursor;\n consumeToken(TOKEN_BLANK);\n // Check the first non-blank character after the indent.\n switch (source[cursor]) {\n case \".\":\n case \"[\":\n case \"*\":\n case \"}\":\n case undefined: // EOF\n // A special character. End the Pattern.\n return false;\n case \"{\":\n // Placeables don't require indentation (in EBNF: block-placeable).\n // Continue the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // If the first character on the line is not one of the special characters\n // listed above, it's a regular text character. Check if there's at least\n // one space of indent before it.\n if (source[cursor - 1] === \" \") {\n // It's an indented text character (in EBNF: indented-char). Continue\n // the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // A not-indented text character is likely the identifier of the next\n // message. End the Pattern.\n return false;\n }\n // Trim blanks in text according to the given regex.\n function trim(text, re) {\n return text.replace(re, \"\");\n }\n // Normalize a blank block and extract the indent details.\n function makeIndent(blank) {\n let value = blank.replace(RE_BLANK_LINES, \"\\n\");\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let length = RE_INDENT.exec(blank)[1].length;\n return new Indent(value, length);\n }\n }\n}\nclass Indent {\n constructor(value, length) {\n this.value = value;\n this.length = length;\n }\n}\n","/**\n * @module fluent\n * @overview\n *\n * `fluent` is a JavaScript implementation of Project Fluent, a localization\n * framework designed to unleash the expressive power of the natural language.\n *\n */\nexport { FluentBundle } from \"./bundle.js\";\nexport { FluentResource } from \"./resource.js\";\nexport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n","/* eslint no-console: [\"error\", {allow: [\"warn\"]}] */\n/* global console */\n// Match the opening angle bracket (<) in HTML tags, and HTML entities like\n// &, &, &.\nconst reOverlay = /<|?\\w+;/;\n/**\n * Elements allowed in translations even if they are not present in the source\n * HTML. They are text-level elements as defined by the HTML5 spec:\n * https://www.w3.org/TR/html5/text-level-semantics.html with the exception of:\n *\n * - a - because we don't allow href on it anyways,\n * - ruby, rt, rp - because we don't allow nested elements to be inserted.\n */\nconst TEXT_LEVEL_ELEMENTS = {\n \"http://www.w3.org/1999/xhtml\": [\n \"em\",\n \"strong\",\n \"small\",\n \"s\",\n \"cite\",\n \"q\",\n \"dfn\",\n \"abbr\",\n \"data\",\n \"time\",\n \"code\",\n \"var\",\n \"samp\",\n \"kbd\",\n \"sub\",\n \"sup\",\n \"i\",\n \"b\",\n \"u\",\n \"mark\",\n \"bdi\",\n \"bdo\",\n \"span\",\n \"br\",\n \"wbr\",\n ],\n};\nconst LOCALIZABLE_ATTRIBUTES = {\n \"http://www.w3.org/1999/xhtml\": {\n global: [\"title\", \"aria-label\", \"aria-valuetext\"],\n a: [\"download\"],\n area: [\"download\", \"alt\"],\n // value is special-cased in isAttrNameLocalizable\n input: [\"alt\", \"placeholder\"],\n menuitem: [\"label\"],\n menu: [\"label\"],\n optgroup: [\"label\"],\n option: [\"label\"],\n track: [\"label\"],\n img: [\"alt\"],\n textarea: [\"placeholder\"],\n th: [\"abbr\"],\n },\n \"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul\": {\n global: [\n \"accesskey\",\n \"aria-label\",\n \"aria-valuetext\",\n \"label\",\n \"title\",\n \"tooltiptext\",\n ],\n description: [\"value\"],\n key: [\"key\", \"keycode\"],\n label: [\"value\"],\n textbox: [\"placeholder\", \"value\"],\n },\n};\n/**\n * Translate an element.\n *\n * Translate the element's text content and attributes. Some HTML markup is\n * allowed in the translation. The element's children with the data-l10n-name\n * attribute will be treated as arguments to the translation. If the\n * translation defines the same children, their attributes and text contents\n * will be used for translating the matching source child.\n *\n * @param {Element} element\n * @param {Object} translation\n * @private\n */\nexport default function translateElement(element, translation) {\n const { value } = translation;\n if (typeof value === \"string\") {\n if (element.localName === \"title\" &&\n element.namespaceURI === \"http://www.w3.org/1999/xhtml\") {\n // A special case for the HTML title element whose content must be text.\n element.textContent = value;\n }\n else if (!reOverlay.test(value)) {\n // If the translation doesn't contain any markup skip the overlay logic.\n element.textContent = value;\n }\n else {\n // Else parse the translation's HTML using an inert template element,\n // sanitize it and replace the element's content.\n const templateElement = element.ownerDocument.createElementNS(\"http://www.w3.org/1999/xhtml\", \"template\");\n templateElement.innerHTML = value;\n overlayChildNodes(templateElement.content, element);\n }\n }\n // Even if the translation doesn't define any localizable attributes, run\n // overlayAttributes to remove any localizable attributes set by previous\n // translations.\n overlayAttributes(translation, element);\n}\n/**\n * Replace child nodes of an element with child nodes of another element.\n *\n * The contents of the target element will be cleared and fully replaced with\n * sanitized contents of the source element.\n *\n * @param {DocumentFragment} fromFragment - The source of children to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayChildNodes(fromFragment, toElement) {\n for (const childNode of fromFragment.childNodes) {\n if (childNode.nodeType === childNode.TEXT_NODE) {\n // Keep the translated text node.\n continue;\n }\n if (childNode.hasAttribute(\"data-l10n-name\")) {\n const sanitized = getNodeForNamedElement(toElement, childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n if (isElementAllowed(childNode)) {\n const sanitized = createSanitizedElement(childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n console.warn(`An element of forbidden type \"${childNode.localName}\" was found in ` +\n \"the translation. Only safe text-level elements and elements with \" +\n \"data-l10n-name are allowed.\");\n // If all else fails, replace the element with its text content.\n fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode);\n }\n toElement.textContent = \"\";\n toElement.appendChild(fromFragment);\n}\nfunction hasAttribute(attributes, name) {\n if (!attributes) {\n return false;\n }\n for (let attr of attributes) {\n if (attr.name === name) {\n return true;\n }\n }\n return false;\n}\n/**\n * Transplant localizable attributes of an element to another element.\n *\n * Any localizable attributes already set on the target element will be\n * cleared.\n *\n * @param {Element|Object} fromElement - The source of child nodes to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayAttributes(fromElement, toElement) {\n const explicitlyAllowed = toElement.hasAttribute(\"data-l10n-attrs\")\n ? toElement\n .getAttribute(\"data-l10n-attrs\")\n .split(\",\")\n .map(i => i.trim())\n : null;\n // Remove existing localizable attributes if they\n // will not be used in the new translation.\n for (const attr of Array.from(toElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n !hasAttribute(fromElement.attributes, attr.name)) {\n toElement.removeAttribute(attr.name);\n }\n }\n // fromElement might be a {value, attributes} object as returned by\n // Localization.messageFromBundle. In which case attributes may be null to\n // save GC cycles.\n if (!fromElement.attributes) {\n return;\n }\n // Set localizable attributes.\n for (const attr of Array.from(fromElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n toElement.getAttribute(attr.name) !== attr.value) {\n toElement.setAttribute(attr.name, attr.value);\n }\n }\n}\n/**\n * Sanitize a child element created by the translation.\n *\n * Try to find a corresponding child in sourceElement and use it as the base\n * for the sanitization. This will preserve functional attribtues defined on\n * the child element in the source HTML.\n *\n * @param {Element} sourceElement - The source for data-l10n-name lookups.\n * @param {Element} translatedChild - The translated child to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction getNodeForNamedElement(sourceElement, translatedChild) {\n const childName = translatedChild.getAttribute(\"data-l10n-name\");\n const sourceChild = sourceElement.querySelector(`[data-l10n-name=\"${childName}\"]`);\n if (!sourceChild) {\n console.warn(`An element named \"${childName}\" wasn't found in the source.`);\n return createTextNodeFromTextContent(translatedChild);\n }\n if (sourceChild.localName !== translatedChild.localName) {\n console.warn(`An element named \"${childName}\" was found in the translation ` +\n `but its type ${translatedChild.localName} didn't match the ` +\n `element found in the source (${sourceChild.localName}).`);\n return createTextNodeFromTextContent(translatedChild);\n }\n // Remove it from sourceElement so that the translation cannot use\n // the same reference name again.\n sourceElement.removeChild(sourceChild);\n // We can't currently guarantee that a translation won't remove\n // sourceChild from the element completely, which could break the app if\n // it relies on an event handler attached to the sourceChild. Let's make\n // this limitation explicit for now by breaking the identitiy of the\n // sourceChild by cloning it. This will destroy all event handlers\n // attached to sourceChild via addEventListener and via on\n // properties.\n const clone = sourceChild.cloneNode(false);\n return shallowPopulateUsing(translatedChild, clone);\n}\n/**\n * Sanitize an allowed element.\n *\n * Text-level elements allowed in translations may only use safe attributes\n * and will have any nested markup stripped to text content.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction createSanitizedElement(element) {\n // Start with an empty element of the same type to remove nested children\n // and non-localizable attributes defined by the translation.\n const clone = element.ownerDocument.createElement(element.localName);\n return shallowPopulateUsing(element, clone);\n}\n/**\n * Convert an element to a text node.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Node}\n * @private\n */\nfunction createTextNodeFromTextContent(element) {\n return element.ownerDocument.createTextNode(element.textContent);\n}\n/**\n * Check if element is allowed in the translation.\n *\n * This method is used by the sanitizer when the translation markup contains\n * an element which is not present in the source code.\n *\n * @param {Element} element\n * @returns {boolean}\n * @private\n */\nfunction isElementAllowed(element) {\n const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];\n return allowed && allowed.includes(element.localName);\n}\n/**\n * Check if attribute is allowed for the given element.\n *\n * This method is used by the sanitizer when the translation markup contains\n * DOM attributes, or when the translation has traits which map to DOM\n * attributes.\n *\n * `explicitlyAllowed` can be passed as a list of attributes explicitly\n * allowed on this element.\n *\n * @param {string} name\n * @param {Element} element\n * @param {Array} explicitlyAllowed\n * @returns {boolean}\n * @private\n */\nfunction isAttrNameLocalizable(name, element, explicitlyAllowed = null) {\n if (explicitlyAllowed && explicitlyAllowed.includes(name)) {\n return true;\n }\n const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];\n if (!allowed) {\n return false;\n }\n const attrName = name.toLowerCase();\n const elemName = element.localName;\n // Is it a globally safe attribute?\n if (allowed.global.includes(attrName)) {\n return true;\n }\n // Are there no allowed attributes for this element?\n if (!allowed[elemName]) {\n return false;\n }\n // Is it allowed on this element?\n if (allowed[elemName].includes(attrName)) {\n return true;\n }\n // Special case for value on HTML inputs with type button, reset, submit\n if (element.namespaceURI === \"http://www.w3.org/1999/xhtml\" &&\n elemName === \"input\" &&\n attrName === \"value\") {\n const type = element.type.toLowerCase();\n if (type === \"submit\" || type === \"button\" || type === \"reset\") {\n return true;\n }\n }\n return false;\n}\n/**\n * Helper to set textContent and localizable attributes on an element.\n *\n * @param {Element} fromElement\n * @param {Element} toElement\n * @returns {Element}\n * @private\n */\nfunction shallowPopulateUsing(fromElement, toElement) {\n toElement.textContent = fromElement.textContent;\n overlayAttributes(fromElement, toElement);\n return toElement;\n}\n","/*\n * Base CachedIterable class.\n */\nexport default class CachedIterable extends Array {\n /**\n * Create a `CachedIterable` instance from an iterable or, if another\n * instance of `CachedIterable` is passed, return it without any\n * modifications.\n *\n * @param {Iterable} iterable\n * @returns {CachedIterable}\n */\n static from(iterable) {\n if (iterable instanceof this) {\n return iterable;\n }\n\n return new this(iterable);\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedSyncIterable caches the elements yielded by an iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedSyncIterable extends CachedIterable {\n /**\n * Create an `CachedSyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedSyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n [Symbol.iterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && last.done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedAsyncIterable caches the elements yielded by an async iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedAsyncIterable extends CachedIterable {\n /**\n * Create an `CachedAsyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedAsyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.asyncIterator in Object(iterable)) {\n this.iterator = iterable[Symbol.asyncIterator]();\n } else if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n /**\n * Asynchronous iterator caching the yielded elements.\n *\n * Elements yielded by the original iterable will be cached and available\n * synchronously. Returns an async generator object implementing the\n * iterator protocol over the elements of the original (async or sync)\n * iterable.\n */\n [Symbol.asyncIterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n async next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n async touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && (await last).done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","export {default as CachedSyncIterable} from \"./cached_sync_iterable.mjs\";\nexport {default as CachedAsyncIterable} from \"./cached_async_iterable.mjs\";\n","/* eslint no-console: [\"error\", { allow: [\"warn\", \"error\"] }] */\n/* global console */\nimport { CachedAsyncIterable } from \"cached-iterable\";\n/**\n * The `Localization` class is a central high-level API for vanilla\n * JavaScript use of Fluent.\n * It combines language negotiation, FluentBundle and I/O to\n * provide a scriptable API to format translations.\n */\nexport default class Localization {\n /**\n * @param {Array} resourceIds - List of resource IDs\n * @param {Function} generateBundles - Function that returns a\n * generator over FluentBundles\n *\n * @returns {Localization}\n */\n constructor(resourceIds = [], generateBundles) {\n this.resourceIds = resourceIds;\n this.generateBundles = generateBundles;\n this.onChange(true);\n }\n addResourceIds(resourceIds, eager = false) {\n this.resourceIds.push(...resourceIds);\n this.onChange(eager);\n return this.resourceIds.length;\n }\n removeResourceIds(resourceIds) {\n this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));\n this.onChange();\n return this.resourceIds.length;\n }\n /**\n * Format translations and handle fallback if needed.\n *\n * Format translations for `keys` from `FluentBundle` instances on this\n * DOMLocalization. In case of errors, fetch the next context in the\n * fallback chain.\n *\n * @param {Array