UNPKG

2.2 MBSource Map (JSON)View Raw
1{"version":3,"file":"vivliostyle.js","sources":["../src/vivliostyle/constants.ts","../src/vivliostyle/logging.ts","../src/vivliostyle/plugin.ts","../src/vivliostyle/profile.ts","../src/vivliostyle/base.ts","../src/vivliostyle/cfi.ts","../src/vivliostyle/exprs.ts","../src/vivliostyle/css.ts","../src/vivliostyle/geometry-util.ts","../src/vivliostyle/css-prop.ts","../src/vivliostyle/counters.ts","../src/vivliostyle/css-tokenizer.ts","../src/vivliostyle/task.ts","../src/vivliostyle/task-util.ts","../src/vivliostyle/net.ts","../src/vivliostyle/css-parser.ts","../src/vivliostyle/matchers.ts","../src/vivliostyle/css-cascade.ts","../src/vivliostyle/css-logical-util.ts","../src/vivliostyle/sizing.ts","../../../node_modules/fast-diff/diff.js","../src/vivliostyle/types.ts","../src/vivliostyle/diff.ts","../src/vivliostyle/vtree.ts","../src/vivliostyle/page-floats.ts","../src/vivliostyle/footnotes.ts","../src/vivliostyle/break.ts","../src/vivliostyle/layout-helper.ts","../src/vivliostyle/break-position.ts","../src/vivliostyle/display.ts","../src/vivliostyle/layout-processor.ts","../src/vivliostyle/layout-retryers.ts","../src/vivliostyle/layout-util.ts","../src/vivliostyle/shared.ts","../src/vivliostyle/pseudo-element.ts","../src/vivliostyle/layout.ts","../src/vivliostyle/repetitive-element.ts","../src/vivliostyle/table.ts","../src/vivliostyle/math-util.ts","../src/vivliostyle/columns.ts","../src/vivliostyle/css-styler.ts","../src/vivliostyle/css-validator.ts","../src/vivliostyle/font.ts","../src/vivliostyle/page-master.ts","../src/vivliostyle/css-page.ts","../src/vivliostyle/urls.ts","../src/vivliostyle/vgen.ts","../src/vivliostyle/xml-doc.ts","../src/vivliostyle/ops.ts","../src/vivliostyle/sha1.ts","../src/vivliostyle/toc.ts","../src/vivliostyle/epub.ts","../src/vivliostyle/adaptive-viewer.ts","../src/vivliostyle/core-viewer.ts","../src/vivliostyle/print.ts"],"sourcesContent":["/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Constants\n */\n\n/**\n * Debug flag.\n */\nexport let isDebug: boolean = false;\nexport function setDebug(value: boolean): void {\n isDebug = value;\n}\n\n/**\n * Page progression direction.\n * @enum {string}\n */\nexport enum PageProgression {\n LTR = \"ltr\",\n RTL = \"rtl\",\n}\n\n/**\n * Return PageProgression corresponding to the specified string\n */\nexport function pageProgressionOf(str: string): PageProgression {\n switch (str) {\n case \"ltr\":\n return PageProgression.LTR;\n case \"rtl\":\n return PageProgression.RTL;\n default:\n throw new Error(`unknown PageProgression: ${str}`);\n }\n}\n\n/**\n * Page side (left/right).\n * @enum {string}\n */\nexport enum PageSide {\n LEFT = \"left\",\n RIGHT = \"right\",\n}\n\n/**\n * Viewer ready state.\n * @enum {string}\n */\nexport enum ReadyState {\n LOADING = \"loading\",\n INTERACTIVE = \"interactive\",\n COMPLETE = \"complete\",\n}\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const constants = {\n PageProgression,\n PageSide,\n ReadyState,\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Logging - Logging utility\n */\n\n/**\n * Log level.\n * @enum {number}\n */\nexport enum LogLevel {\n DEBUG = 1,\n INFO,\n WARN,\n ERROR,\n}\n\nexport type ErrorInfo = {\n error: Error;\n messages: any[];\n};\n\n/**\n * Class logging error, warning, information or debug messages.\n */\nexport class Logger {\n private listeners: { [key in LogLevel]?: ((p1: ErrorInfo) => void)[] } = {};\n\n constructor(private opt_console?: Console) {}\n\n private consoleDebug(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.debug) {\n this.opt_console.debug(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.debug(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleInfo(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.info) {\n this.opt_console.info(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.info(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleWarn(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.warn) {\n this.opt_console.warn(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.warn(...msg); // eslint-disable-line no-console\n }\n }\n\n private consoleError(msg: any[]) {\n if (this.opt_console) {\n if (this.opt_console.error) {\n this.opt_console.error(...msg);\n } else {\n this.opt_console.log(...msg);\n }\n } else {\n console.error(...msg); // eslint-disable-line no-console\n }\n }\n\n private triggerListeners(level: LogLevel, args: ErrorInfo) {\n const listeners = this.listeners[level];\n if (listeners) {\n listeners.forEach((listener) => {\n listener(args);\n });\n }\n }\n\n /**\n * Add a listener function invoked when a log event with the specified level\n * occurs.\n */\n addListener(level: LogLevel, listener: (p1: ErrorInfo) => void) {\n let listeners = this.listeners[level];\n if (!listeners) {\n listeners = this.listeners[level] = [];\n }\n listeners.push(listener);\n }\n\n debug(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleDebug(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.DEBUG, args);\n }\n\n info(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleInfo(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.INFO, args);\n }\n\n warn(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleWarn(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.WARN, args);\n }\n\n error(...var_args: any[]) {\n const args = argumentsToErrorInfo(arguments);\n this.consoleError(buildMessageAndStackTrace(args));\n this.triggerListeners(LogLevel.ERROR, args);\n }\n}\n\n/**\n * @param args\n */\nfunction argumentsToErrorInfo(args: IArguments): ErrorInfo {\n const a = Array.from(args);\n let e: Error = null;\n if (a[0] instanceof Error) {\n e = a.shift();\n }\n return { error: e, messages: a };\n}\n\nfunction buildMessageAndStackTrace(args: ErrorInfo): string[] {\n const e = args.error;\n const stack = e && (e[\"frameTrace\"] || e[\"stack\"]);\n let messages = [].concat(args[\"messages\"]);\n if (e) {\n if (messages.length > 0) {\n messages = messages.concat([\"\\n\"]);\n }\n messages = messages.concat([e[\"toString\"]()]);\n if (stack) {\n messages = messages.concat([\"\\n\"]).concat(stack);\n }\n }\n return messages;\n}\n\nexport const logger = new Logger();\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Plugin - Plugin mechanism\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * Type of implemented hooks.\n * @enum {string}\n */\nexport enum HOOKS {\n /**\n * Called when a single property declaration is parsed.\n *\n * The hook is called with an object with the following properties:\n * {string} name: Property name\n * {!Css.Val} value: Property value\n * {boolean} important: Whether '!important' flag is present or not\n * Functions called by this hook are expected to return a value with the same\n * type as the above. The declaration is then replaced by the returned value.\n *\n * Note that a shorthand declaration is not directly passed to this hook.\n * After the shorthand declaration is interpreted and broken into\n * non-shorthand declarations, the hook is called for each of the\n * non-shorthand declarations.\n */\n SIMPLE_PROPERTY = \"SIMPLE_PROPERTY\",\n\n /**\n * Called when a single document (i.e. a single spine item) has been fetched,\n * before parsing.\n *\n * The hook is called with the Document object.\n */\n PREPROCESS_SINGLE_DOCUMENT = \"PREPROCESS_SINGLE_DOCUMENT\",\n\n /**\n * Called before creating a text node for modifying a text content.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {string} sourceTextContent\n *\n * Functions called by this hook are expected to return a\n * Task.Result.<string>. The text content is then replaced by the\n * returned value.\n */\n PREPROCESS_TEXT_CONTENT = \"PREPROCESS_TEXT_CONTENT\",\n\n /**\n * Called before creating a element for modifying a element style.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {!Object} style\n */\n PREPROCESS_ELEMENT_STYLE = \"PREPROCESS_ELEMENT_STYLE\",\n\n /**\n * Called before geting CssCascade.polyfilledInheritedProps.\n *\n * The hook return a array of polyfilled inherited property name.\n */\n POLYFILLED_INHERITED_PROPS = \"POLYFILLED_INHERITED_PROPS\",\n\n /**\n * Called when a Viewer is configured.\n *\n * The hook is called with an object with the following properties:\n * {Base.JSON} command\n */\n CONFIGURATION = \"CONFIGURATION\",\n\n /**\n * Called when resolving a text node breaker\n * which detects an acceptable breakpoint and break text node at this point.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n *\n * Functions called by this hook are expected to\n * return an instnce of {Layout.TextNodeBreaker} or null.\n */\n RESOLVE_TEXT_NODE_BREAKER = \"RESOLVE_TEXT_NODE_BREAKER\",\n\n /**\n * Called when resolving a formatting context.\n *\n * The hook is called with the following parameters:\n * nodeContext: a NodeContext object\n * firstTime: a boolean flag representing whether this node is encountered\n * for the first time or not display: an Css.Ident value representing\n * 'display' value of the node position: an Css.Ident value representing\n * 'position' value of the node float: an Css.Ident value representing\n * 'float' value of the node isRoot: a boolean flag representing whether this\n * node is a root (of a flow) or not Functions called by this hook are\n * expected to return a formatting context for the NodeContext.\n */\n RESOLVE_FORMATTING_CONTEXT = \"RESOLVE_FORMATTING_CONTEXT\",\n\n /**\n * Called when resolving a layout processor (LayoutProcessor) for\n * a formatting context.\n *\n * The hook is called with a formatting context\n * (Vtree.FormattingContext). Functions called by this hook are expected\n * to return a layout processor corresponding to the formatting context.\n */\n RESOLVE_LAYOUT_PROCESSOR = \"RESOLVE_LAYOUT_PROCESSOR\",\n\n /**\n * Called after laid out a block contents.\n *\n * The hook is called with an object with the following properties:\n * {Vtree.NodeContext} nodeContext\n * {Array.<Vtree.NodeContext>} checkPoints\n * {Layout.Column} column\n */\n POST_LAYOUT_BLOCK = \"POST_LAYOUT_BLOCK\",\n}\n\nexport type PreProcessSingleDocumentHook = (p1: Document) => any;\n\nexport type PreProcessTextContentHook = (\n p1: Vtree.NodeContext,\n p2: string,\n) => Task.Result<string>;\n\nexport type PreProcessElementStyleHook = (\n p1: Vtree.NodeContext,\n p2: object,\n) => void;\n\nexport type PolyfilledInheritedPropsHook = () => string[];\n\nexport type ConfigurationHook = (\n p1: Base.JSON,\n) => {\n needResize: boolean | null | undefined;\n needRefresh: boolean | null | undefined;\n};\n\nexport type ResolveTextNodeBreakerHook = (\n p1: Vtree.NodeContext,\n) => Layout.TextNodeBreaker;\n\nexport type ResolveFormattingContextHook = (\n p1: Vtree.NodeContext,\n p2: boolean,\n p3: Css.Ident,\n p4: Css.Ident,\n p5: Css.Ident,\n p6: boolean,\n) => Vtree.FormattingContext;\n\nexport type ResolveLayoutProcessorHook = (\n p1: Vtree.FormattingContext,\n) => LayoutProcessor.LayoutProcessor;\n\nexport type PostLayoutBlockHook = (\n p1: Vtree.NodeContext,\n p2: Vtree.NodeContext[],\n p3: Layout.Column,\n) => void;\n\nconst hooks = {};\n\n/**\n * Register a function to a hook with the specified name.\n * The registered function is called at appropriate timings by the core code.\n * Arguments passed to the function depend on the hook.\n * When multiple functions are registered, they are called by the order in which\n * they are registered.\n * @param name Name of the hook.\n * @param fn Function to be registered to the hook.\n */\nexport function registerHook(name: string, fn: (...p1) => any): void {\n if (!HOOKS[name]) {\n Logging.logger.warn(new Error(`Skipping unknown plugin hook '${name}'.`));\n } else {\n let hooksForName = hooks[name];\n if (!hooksForName) {\n hooksForName = hooks[name] = [];\n }\n hooksForName.push(fn);\n }\n}\n\n/**\n * Remove a function already registered to the specified name.\n * Note that even if the same function are registered multiple times, this\n * method removes only the first one.\n * @param name Name of the hook.\n * @param fn Function to be removed from the hook.\n */\nexport function removeHook(name: string, fn: (...p1) => any): void {\n if (!HOOKS[name]) {\n Logging.logger.warn(new Error(`Ignoring unknown plugin hook '${name}'.`));\n } else {\n const hooksForName = hooks[name];\n if (hooksForName) {\n const index = hooksForName.indexOf(fn);\n if (index >= 0) {\n hooksForName.splice(index, 1);\n }\n }\n }\n}\n\n/**\n * Get all hooks registered to the specified name.\n * This method is for internal use (from the core code).\n */\nexport function getHooksForName(name: string): ((...p1) => any)[] {\n const hooksForName = hooks[name];\n return hooksForName || [];\n}\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const plugin = {\n registerHook,\n removeHook,\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Profile - Utility for profiling\n */\nimport * as Logging from \"./logging\";\n\n/**\n * Performance profiler measuring execution time of the script.\n */\nexport class Profiler {\n timestamps: { [key: string]: { [key: string]: number } } = {};\n private registerTiming: (p1: string, p2: string, p3?: number) => any;\n registerStartTiming: (name: string, timestamp?: number) => any;\n registerEndTiming: (name: string, timestamp?: number) => any;\n\n constructor(public readonly performanceInstance: Performance) {\n this.registerTiming = noop;\n\n // hack to export (non-prototype) methods\n this[\"registerStartTiming\"] = this.registerStartTiming = noop;\n this[\"registerEndTiming\"] = this.registerEndTiming = noop;\n }\n\n /**\n * Registers start timing of some event, even if profile is disabled.\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\n forceRegisterStartTiming(name: string, timestamp?: number) {\n registerTiming.call(this, name, \"start\", timestamp);\n }\n\n /**\n * Registers end timing of some event, even if profile is disabled.\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\n forceRegisterEndTiming(name: string, timestamp?: number) {\n registerTiming.call(this, name, \"end\", timestamp);\n }\n\n /**\n * Log registered timings (start/end/duration).\n * All values are printed in ms unit.\n */\n printTimings() {\n const timestamps = this.timestamps;\n let st = \"\";\n Object.keys(timestamps).forEach((name) => {\n const stamps = timestamps[name];\n const l = stamps.length;\n for (let i = 0; i < l; i++) {\n const t = stamps[i];\n st += name;\n if (l > 1) {\n st += `(${i})`;\n }\n st += ` => start: ${t[\"start\"]}, end: ${t[\"end\"]}, duration: ${t[\n \"end\"\n ] - t[\"start\"]}\\n`;\n }\n });\n Logging.logger.info(st);\n }\n\n /**\n * Disable profiling.\n */\n disable() {\n this.registerTiming = noop;\n\n // hack to export (non-prototype) methods\n this[\"registerStartTiming\"] = this.registerStartTiming = noop;\n this[\"registerEndTiming\"] = this.registerEndTiming = noop;\n }\n\n /**\n * Enable profiling.\n */\n enable() {\n this.registerTiming = registerTiming;\n\n // hack to export (non-prototype) methods\n this[\n \"registerStartTiming\"\n ] = this.registerStartTiming = registerStartTiming;\n this[\"registerEndTiming\"] = this.registerEndTiming = registerEndTiming;\n }\n\n /**\n * Returns if profiling is enabled or not.\n */\n isEnabled(): boolean {\n return this.registerStartTiming === registerStartTiming;\n }\n}\n\nfunction noop(): void {}\n\n/**\n * Registers start/end timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param startEnd Either of \"start\" or \"end\"\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerTiming(\n name: string,\n startEnd: string,\n timestamp?: number,\n): void {\n if (!timestamp) {\n timestamp = this.performanceInstance.now();\n }\n let timestamps = this.timestamps[name];\n if (!timestamps) {\n timestamps = this.timestamps[name] = [];\n }\n let t;\n const l = timestamps.length;\n for (let i = l - 1; i >= 0; i--) {\n t = timestamps[i];\n if (t && !t[startEnd]) {\n break;\n }\n t = null;\n }\n if (!t) {\n t = {};\n timestamps.push(t);\n }\n t[startEnd] = timestamp;\n}\n\n/**\n * Registers start timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerStartTiming(name: string, timestamp?: number): void {\n this.registerTiming(name, \"start\", timestamp);\n}\n\n/**\n * Registers end timing of some event.\n * @this {Profile.Profiler}\n * @param name Name of event\n * @param timestamp Used as the actual timestamp of the event if specified,\n * instead of \"now\"\n */\nfunction registerEndTiming(name: string, timestamp?: number): void {\n this.registerTiming(name, \"end\", timestamp);\n}\nconst fallbackPerformanceInstance = { now: Date.now } as Performance;\nconst performanceInstance = window && window.performance;\nexport const profiler = new Profiler(\n performanceInstance || fallbackPerformanceInstance,\n);\nprofiler.forceRegisterStartTiming(\"load_vivliostyle\");\n\n/**\n * Pubilc members of the bundled library.\n */\nexport const profile = {\n profiler: {\n registerStartTiming: profiler.registerStartTiming,\n registerEndTiming: profiler.registerEndTiming,\n printTimings: profiler.printTimings,\n disable: profiler.disable,\n enable: profiler.enable,\n },\n};\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Base - Common utilities.\n */\nimport * as Logging from \"./logging\";\nimport * as Asserts from \"./asserts\";\n\nexport let emptyObj = {};\n\nexport type JSON = any;\n\nexport function jsonToString(json: JSON): string {\n return JSON.stringify(json);\n}\n\nexport function stringToJSON(str: string): JSON {\n return JSON.parse(str);\n}\n\nexport function stripFragment(url: string): string {\n const r = url.match(/^([^#]*)/);\n if (r) {\n return r[1];\n }\n return url;\n}\n\nexport function stripFragmentAndQuery(url: string): string {\n const r = url.match(/^([^#?]*)/);\n if (r) {\n return r[1];\n }\n return url;\n}\n\n/**\n * Base URL relative to which URLs of resources are resolved.\n */\nexport let baseURL = window.location.href;\nexport function setBaseURL(value: string): void {\n baseURL = value;\n}\n\n/**\n * Base URL relative to which URLs of resources such as validation.txt and\n * user-agent.css are resolved.\n */\nexport let resourceBaseURL = window.location.href;\nexport function setResourceBaseURL(value: string): void {\n resourceBaseURL = value;\n}\n\n/**\n * @param relURL relative URL\n * @param baseURL base (absolute) URL\n * @return resolved (absolute) URL\n */\nexport function resolveURL(relURL: string, baseURL: string): string {\n if (baseURL.startsWith(\"data:\")) {\n return relURL || baseURL;\n }\n if (!baseURL || relURL.match(/^\\w{2,}:/)) {\n if (relURL.toLowerCase().match(\"^javascript:\")) {\n return \"#\";\n }\n if (relURL.match(/^\\w{2,}:\\/\\/[^\\/]+$/)) {\n relURL = `${relURL}/`;\n }\n return relURL;\n }\n if (baseURL.match(/^\\w{2,}:\\/\\/[^\\/]+$/)) {\n baseURL = `${baseURL}/`;\n }\n let r: string[];\n if (relURL.match(/^\\/\\//)) {\n r = baseURL.match(/^(\\w{2,}:)\\/\\//);\n if (r) {\n return r[1] + relURL;\n }\n return relURL;\n }\n if (relURL.match(/^\\//)) {\n r = baseURL.match(/^(\\w{2,}:\\/\\/[^\\/]+)\\//);\n if (r) {\n return r[1] + relURL;\n }\n return relURL;\n }\n if (relURL.match(/^\\.(\\/|$)/)) {\n relURL = relURL.substr(2); // './foo' => 'foo'\n }\n baseURL = stripFragmentAndQuery(baseURL);\n if (relURL.match(/^#/)) {\n return baseURL + relURL;\n }\n let i = baseURL.lastIndexOf(\"/\");\n if (i < 0) {\n return relURL;\n }\n if (i < baseURL.length - 1) {\n const j = baseURL.lastIndexOf(\".\");\n if (j < i) {\n // Assume the last part without '.' to be a directory name.\n if (relURL == \"\") {\n return baseURL;\n }\n baseURL += \"/\";\n i = baseURL.length - 1;\n }\n }\n let url = baseURL.substr(0, i + 1) + relURL;\n let urlOption = \"\";\n r = url.match(/^([^?#]*)([?#].*)$/);\n if (r) {\n url = r[1];\n urlOption = r[2];\n }\n\n while (true) {\n i = url.indexOf(\"/../\");\n if (i <= 0) {\n break;\n }\n const j = url.lastIndexOf(\"/\", i - 1);\n if (j <= 0) {\n break;\n }\n url = url.substr(0, j) + url.substr(i + 3);\n }\n return url.replace(/\\/(\\.\\/)+/g, \"/\") + urlOption;\n}\n\n/**\n * @return converted URL\n */\nexport function convertSpecialURL(url: string): string {\n let r: RegExpMatchArray;\n if (\n (r = /^(https?:)\\/\\/github\\.com\\/([^/]+\\/[^/]+)\\/(blob\\/|tree\\/|raw\\/)?(.*)$/.exec(\n url,\n ))\n ) {\n // Convert GitHub URL to GitHub raw URL\n url = `${r[1]}//raw.githubusercontent.com/${r[2]}/${r[3] ? \"\" : \"master/\"}${\n r[4]\n }`;\n } else if (\n (r = /^(https?:)\\/\\/www\\.aozora\\.gr\\.jp\\/(cards\\/[^/]+\\/files\\/[^/.]+\\.html)$/.exec(\n url,\n ))\n ) {\n // Convert Aozorabunko (X)HTML URL to GitHub raw URL\n url = `${r[1]}//raw.githubusercontent.com/aozorabunko/aozorabunko/master/${r[2]}`;\n } else if (\n (r = /^(https?:)\\/\\/gist\\.github\\.com\\/([^/]+\\/\\w+)(\\/|$)(raw(\\/|$))?(.*)$/.exec(\n url,\n ))\n ) {\n // Convert Gist URL to Gist raw URL\n url = `${r[1]}//gist.githubusercontent.com/${r[2]}/raw/${r[6]}`;\n } else if (\n (r = /^(https?:)\\/\\/(?:[^/.]+\\.)?jsbin\\.com\\/(?!(?:blog|help)\\b)(\\w+)((\\/\\d+)?).*$/.exec(\n url,\n ))\n ) {\n // Convert JS Bin URL to JS Bin output URL\n url = `${r[1]}//output.jsbin.com/${r[2]}${r[3]}/`;\n }\n return url;\n}\n\nexport interface DocumentURLTransformer {\n transformFragment(fragment: string, baseURL: string): string;\n\n transformURL(url: string, baseURL: string): string;\n\n restoreURL(encoded: string): string[];\n}\n\n/**\n * Various namespaces.\n * @enum {string}\n */\nexport enum NS {\n FB2 = \"http://www.gribuser.ru/xml/fictionbook/2.0\",\n epub = \"http://www.idpf.org/2007/ops\",\n EV = \"http://www.w3.org/2001/xml-events\",\n MATHML = \"http://www.w3.org/1998/Math/MathML\",\n XML = \"http://www.w3.org/XML/1998/namespace\",\n XHTML = \"http://www.w3.org/1999/xhtml\",\n XLINK = \"http://www.w3.org/1999/xlink\",\n SHADOW = \"http://www.pyroxy.com/ns/shadow\",\n SVG = \"http://www.w3.org/2000/svg\",\n DC = \"http://purl.org/dc/elements/1.1/\",\n NCX = \"http://www.daisy.org/z3986/2005/ncx/\",\n SSE = \"http://example.com/sse\", // temporary dummy namespace\n}\n\n/**\n * @param name parameter name\n * @param opt_url URL; window.location.href is used if not provided\n * @return parameter value\n */\nexport function getURLParam(name: string, opt_url?: string): string | null {\n const rg = new RegExp(`#(.*&)?${escapeRegExp(name)}=([^#&]*)`);\n const url = opt_url || window.location.href;\n const r = url.match(rg);\n if (r) {\n return r[2];\n }\n return null;\n}\n\n/**\n * @param name parameter name\n * @param value parameter value\n * @return new url\n */\nexport function setURLParam(url: string, name: string, value: string): string {\n const rg = new RegExp(`#(.*&)?${escapeRegExp(name)}=([^#&]*)`);\n const r = url.match(rg);\n if (r) {\n const length = r[2].length;\n const index = r.index + r[0].length - length;\n return url.substr(0, index) + value + url.substr(index + length);\n }\n if (!url.match(/#/)) {\n return `${url}#${name}=${value}`;\n } else {\n return `${url}&${name}=${value}`;\n }\n}\n\n/**\n * @return ?string\n */\nexport function asString(v: any): any {\n if (v == null) {\n return v;\n }\n return v.toString();\n}\n\nexport interface Comparable {\n /**\n * @return -1 when this less then other, 0 when this equals other\n */\n compare(other: Comparable): number;\n}\n\n/**\n * A priority queue.\n */\nexport class PriorityQueue {\n queue: Comparable[] = [null];\n\n length(): number {\n return this.queue.length - 1;\n }\n\n add(item: Comparable): void {\n let index = this.queue.length;\n while (index > 1) {\n const parentIndex = Math.floor(index / 2);\n const parent = this.queue[parentIndex];\n if (parent.compare(item) > 0) {\n this.queue[index] = item;\n return;\n }\n this.queue[index] = parent;\n index = parentIndex;\n }\n this.queue[1] = item;\n }\n\n /**\n * @return highest priority Comparable.\n */\n peek(): Comparable {\n return this.queue[1];\n }\n\n /**\n * Remove the highest-priority item from the queue.\n * @return removed item.\n */\n remove(): Comparable {\n const result = this.queue[1] as Comparable;\n const curr = this.queue.pop() as Comparable;\n const size = this.queue.length;\n if (size > 1) {\n let index = 1;\n while (true) {\n let childIndex = index * 2;\n if (childIndex >= size) {\n break;\n }\n if (this.queue[childIndex].compare(curr) > 0) {\n if (\n childIndex + 1 < size &&\n this.queue[childIndex + 1].compare(\n this.queue[childIndex] as Comparable,\n ) > 0\n ) {\n childIndex++;\n }\n } else if (\n childIndex + 1 < size &&\n this.queue[childIndex + 1].compare(curr) > 0\n ) {\n childIndex++;\n } else {\n break;\n }\n this.queue[index] = this.queue[childIndex];\n index = childIndex;\n }\n this.queue[index] = curr;\n }\n return result;\n }\n}\n\n/**\n * @param prefix Prefix (containing leading and trailing hyphens)\n * @param cssPropName CSS property name\n * @return JavaScript property name\n */\nexport function cssToJSProp(prefix: string, cssPropName: string): string {\n if (prefix) {\n cssPropName = `-${cssPropName}`;\n prefix = prefix.replace(/-/g, \"\");\n if (prefix === \"moz\") {\n prefix = \"Moz\";\n }\n }\n return (\n prefix +\n cssPropName.replace(/-[a-z]/g, (txt) => txt.substr(1).toUpperCase())\n );\n}\n\nexport const knownPrefixes = [\"\", \"-webkit-\", \"-moz-\", \"-ms-\", \"-o-\", \"-epub-\"];\n\nexport const propNameMap = {};\n\nexport function checkIfPropertySupported(\n prefix: string,\n prop: string,\n): boolean {\n // Special case\n if (prop === \"writing-mode\") {\n const probe = document.createElement(\"span\");\n if (prefix === \"-ms-\") {\n probe.style.setProperty(prefix + prop, \"tb-rl\");\n return probe.style[\"writing-mode\"] === \"tb-rl\";\n } else {\n probe.style.setProperty(prefix + prop, \"vertical-rl\");\n return probe.style[prefix + prop] === \"vertical-rl\";\n }\n } else {\n const style = document.documentElement.style;\n return typeof style[cssToJSProp(prefix, prop)] === \"string\";\n }\n}\n\nexport function getPrefixedPropertyNames(prop: string): string[] | null {\n let prefixed = propNameMap[prop];\n if (prefixed || prefixed === null) {\n // null means the browser does not support the property\n return prefixed;\n }\n switch (prop) {\n case \"text-combine-upright\":\n // Special case for Safari\n if (\n checkIfPropertySupported(\"-webkit-\", \"text-combine\") &&\n !checkIfPropertySupported(\"\", \"text-combine-upright\")\n ) {\n propNameMap[prop] = [\"-webkit-text-combine\"];\n return [\"-webkit-text-combine\"];\n }\n break;\n case \"writing-mode\":\n // Special case: prefer '-ms-writing-mode' to 'writing-mode'\n if (checkIfPropertySupported(\"-ms-\", \"writing-mode\")) {\n propNameMap[prop] = [\"-ms-writing-mode\"];\n return [\"-ms-writing-mode\"];\n }\n break;\n case \"filter\":\n // Special case: prefer '-webkit-filter' to 'filter'\n if (checkIfPropertySupported(\"-webkit-\", \"filter\")) {\n propNameMap[prop] = [\"-webkit-filter\"];\n return [\"-webkit-filter\"];\n }\n break;\n case \"clip-path\":\n // Special case for chrome.\n if (checkIfPropertySupported(\"-webkit-\", \"clip-path\")) {\n return (propNameMap[prop] = [\"-webkit-clip-path\", \"clip-path\"]);\n }\n break;\n case \"margin-inline-start\":\n if (checkIfPropertySupported(\"-webkit-\", \"margin-start\")) {\n propNameMap[prop] = [\"-webkit-margin-start\"];\n return [\"-webkit-margin-start\"];\n }\n break;\n case \"margin-inline-end\":\n if (checkIfPropertySupported(\"-webkit-\", \"margin-end\")) {\n propNameMap[prop] = [\"-webkit-margin-end\"];\n return [\"-webkit-margin-end\"];\n }\n break;\n case \"padding-inline-start\":\n if (checkIfPropertySupported(\"-webkit-\", \"padding-start\")) {\n propNameMap[prop] = [\"-webkit-padding-start\"];\n return [\"-webkit-padding-start\"];\n }\n break;\n case \"padding-inline-end\":\n if (checkIfPropertySupported(\"-webkit-\", \"padding-end\")) {\n propNameMap[prop] = [\"-webkit-padding-end\"];\n return [\"-webkit-padding-end\"];\n }\n break;\n }\n for (const prefix of knownPrefixes) {\n if (checkIfPropertySupported(prefix, prop)) {\n prefixed = prefix + prop;\n propNameMap[prop] = [prefixed];\n return [prefixed];\n }\n }\n\n // Not supported by the browser\n Logging.logger.warn(\"Property not supported by the browser: \", prop);\n propNameMap[prop] = null;\n return null;\n}\n\nexport function setCSSProperty(\n elem: Element,\n prop: string,\n value: string,\n): void {\n try {\n const prefixedPropertyNames = getPrefixedPropertyNames(prop);\n if (!prefixedPropertyNames) {\n return;\n }\n prefixedPropertyNames.forEach((prefixed) => {\n if (prefixed === \"-ms-writing-mode\") {\n switch (value) {\n case \"horizontal-tb\":\n value = \"lr-tb\";\n break;\n case \"vertical-rl\":\n value = \"tb-rl\";\n break;\n case \"vertical-lr\":\n value = \"tb-lr\";\n break;\n }\n } else if (prefixed === \"-webkit-text-combine\") {\n switch (value) {\n case \"all\":\n value = \"horizontal\";\n break;\n }\n }\n if (elem && (elem as HTMLElement).style) {\n (elem as HTMLElement).style.setProperty(prefixed, value);\n }\n });\n } catch (err) {\n Logging.logger.warn(err);\n }\n}\n\nexport function getCSSProperty(\n elem: Element,\n prop: string,\n opt_value?: string,\n): string {\n try {\n const propertyNames = propNameMap[prop];\n return (elem as HTMLElement).style.getPropertyValue(\n propertyNames ? propertyNames[0] : prop,\n );\n } catch (err) {}\n return opt_value || \"\";\n}\n\nexport function getLangAttribute(element: Element): string {\n let lang = element.getAttributeNS(NS.XML, \"lang\");\n if (!lang && element.namespaceURI == NS.XHTML) {\n lang = element.getAttribute(\"lang\");\n }\n return lang;\n}\n\nexport class StringBuffer {\n list: string[] = [];\n\n append(str: string): StringBuffer {\n this.list.push(str);\n return this;\n }\n\n clear(): void {\n this.list = [];\n }\n\n /**\n * @override\n */\n toString(): string {\n const str = this.list.join(\"\");\n this.list = [str];\n return str;\n }\n}\n\nexport function escapeChar(str: string): string {\n // not called for surrogate pairs, no need to worry about them\n return `\\\\${str.charCodeAt(0).toString(16)} `;\n}\n\nexport function escapeCSSIdent(name: string): string {\n return name.replace(/[^-_a-zA-Z0-9\\u0080-\\uFFFF]/g, escapeChar);\n}\n\nexport function escapeCSSStr(str: string): string {\n return str.replace(/[\\u0000-\\u001F\"\\\\]/g, escapeChar);\n}\n\nexport function lightURLEncode(str: string): string {\n return str.replace(/[\\s+&?=#\\u007F-\\uFFFF]+/g, encodeURIComponent);\n}\n\nexport function isLetter(ch: string): boolean {\n return !!ch.match(\n /^[a-zA-Z\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u024F\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]$/,\n );\n}\n\nexport function escapeCharToHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n return prefix + (65536 | str.charCodeAt(0)).toString(16).substr(1);\n}\n\nexport function escapeNameStrToHex(str: string, prefix?: string): string {\n function escapeChar(s) {\n return escapeCharToHex(s, prefix);\n }\n return str.replace(/[^-a-zA-Z0-9_]/g, escapeChar);\n}\n\nexport function escapeRegExp(str: string): string {\n return escapeNameStrToHex(str);\n}\n\nexport function unescapeCharFromHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n if (str.indexOf(prefix) === 0) {\n return String.fromCharCode(parseInt(str.substring(prefix.length), 16));\n } else {\n return str;\n }\n}\n\nexport function unescapeStrFromHex(str: string, prefix?: string): string {\n prefix = typeof prefix === \"string\" ? prefix : \"\\\\u\";\n\n function unescapeChar(s) {\n return unescapeCharFromHex(s, prefix);\n }\n const regexp = new RegExp(`${escapeRegExp(prefix)}[0-9a-fA-F]{4}`, \"g\");\n return str.replace(regexp, unescapeChar);\n}\n\n/**\n * Function good is defined for ints from 0 to high-1. It is such that for\n * each i between 1 and high-1 !good(i-1) || good(i) is true. In other words,\n * it goes like false ... false true ... true.\n * Find i such that (i == 0 || !good(i-1)) && (i == h || good(i))\n * In other words, good(i) is the \"first\" good = true.\n */\nexport function binarySearch(\n high: number,\n good: (p1: number) => boolean,\n): number {\n let l = 0;\n let h = high;\n while (true) {\n Asserts.assert(l <= h);\n Asserts.assert(l == 0 || !good(l - 1));\n Asserts.assert(h == high || good(h));\n if (l == h) {\n return l;\n }\n const m = (l + h) >> 1;\n if (good(m)) {\n h = m;\n } else {\n l = m + 1;\n }\n }\n}\n\n/**\n * Function to sort numbers low to high\n */\nexport function numberCompare(a: number, b: number): number {\n return a - b;\n}\n\nexport const base64Chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport function appendBase64(sb: StringBuffer, data: string): void {\n const length = data.length;\n const length3 = Math.floor(length / 3) * 3;\n for (let i = 0; i < length3; i += 3) {\n const c1 = data.charCodeAt(i) & 255;\n const c2 = data.charCodeAt(i + 1) & 255;\n const c3 = data.charCodeAt(i + 2) & 255;\n sb.append(base64Chars.charAt(c1 >> 2));\n sb.append(base64Chars.charAt(((c1 << 4) | (c2 >> 4)) & 63));\n sb.append(base64Chars.charAt(((c2 << 2) | (c3 >> 6)) & 63));\n sb.append(base64Chars.charAt(c3 & 63));\n }\n switch (length - length3) {\n case 1: {\n const p1 = data.charCodeAt(length3) & 255;\n sb.append(base64Chars.charAt(p1 >> 2));\n sb.append(base64Chars.charAt((p1 << 4) & 63));\n sb.append(\"==\");\n break;\n }\n case 2: {\n const q1 = data.charCodeAt(length3) & 255;\n const q2 = data.charCodeAt(length3 + 1) & 255;\n sb.append(base64Chars.charAt(q1 >> 2));\n sb.append(base64Chars.charAt(((q1 << 4) | (q2 >> 4)) & 63));\n sb.append(base64Chars.charAt((q2 << 2) & 63));\n sb.append(\"=\");\n break;\n }\n }\n}\n\n/**\n * Index array using key function. First encountered item wins on collision.\n * Elements with empty and null keys are dropped.\n */\nexport function indexArray<T>(\n arr: T[],\n key: (p1: T) => string | null,\n): { [key: string]: T } {\n const map: { [key: string]: T } = {};\n for (const v of arr) {\n const k: string | null = key(v);\n if (k && !map[k]) {\n map[k] = v;\n }\n }\n return map;\n}\n\n/**\n * Convert array of strings to an object with the values in the array set to\n * true.\n */\nexport function arrayToSet(arr: string[]): { [key: string]: boolean } {\n const set = {};\n for (let i = 0; i < arr.length; i++) {\n set[arr[i]] = true;\n }\n return set;\n}\n\n/**\n * Index array using key function. Repeated indices are all combined into\n * arrays. Elements with empty and null keys are dropped. Ordering of the\n * elements in arrays is preserved.\n */\nexport function multiIndexArray<T>(\n arr: T[],\n key: (p1: T) => string | null,\n): { [key: string]: T[] } {\n const map: { [key: string]: T[] } = {};\n for (const v of arr) {\n const k = key(v);\n if (k) {\n if (map[k]) {\n map[k].push(v);\n } else {\n map[k] = [v];\n }\n }\n }\n return map;\n}\n\n/**\n * Apply function to each value of the object\n * @param fn second parameter is the key\n */\nexport function mapObj<P, R>(\n obj: { [key: string]: P },\n fn: (p1: P, p2: string) => R,\n): { [key: string]: R } {\n const res: { [key: string]: R } = {};\n for (const n in obj) {\n res[n] = fn(obj[n], n);\n }\n return res;\n}\n\nexport function mapSize(obj: object): number {\n let n = 0;\n for (const key in obj) {\n n++;\n }\n return n;\n}\n\nexport type Event = {\n type: string;\n target?;\n currentTarget?;\n preventDefault?;\n newPage?;\n anchorElement?;\n href?;\n content?;\n};\n\nexport type EventListener = (p1: Event) => void;\n\n/**\n * Extemely simple-minded EventTarget implementation. Consider using\n * goog.events.EventTarget if you are using Closure library.\n */\nexport class SimpleEventTarget {\n listeners: { [key: string]: EventListener[] } = {};\n\n dispatchEvent(evt: Event): void {\n const list = this.listeners[evt.type];\n if (list) {\n evt.target = this;\n evt.currentTarget = this;\n for (let i = 0; i < list.length; i++) {\n list[i](evt);\n }\n }\n }\n\n addEventListener(\n type: string,\n listener: EventListener,\n capture?: boolean,\n ): void {\n if (capture) {\n return;\n }\n const list = this.listeners[type];\n if (list) {\n list.push(listener);\n } else {\n this.listeners[type] = [listener];\n }\n }\n\n removeEventListener(\n type: string,\n listener: EventListener,\n capture?: boolean,\n ): void {\n if (capture) {\n return;\n }\n const list = this.listeners[type];\n if (list) {\n const index = list.indexOf(listener);\n if (index >= 0) {\n list.splice(index, 1);\n }\n }\n }\n}\nexport type EventTarget = SimpleEventTarget;\n\nexport let hasLShapeFloatBug: boolean | null = null;\n\n/**\n * Check if there is a bug with L-shape floats overlapping text.\n */\nexport function checkLShapeFloatBug(body: HTMLElement): boolean {\n if (hasLShapeFloatBug == null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"100px\";\n container.style.height = \"100px\";\n container.style.overflow = \"hidden\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n body.appendChild(container);\n const f1 = doc.createElement(\"div\") as HTMLElement;\n f1.style.width = \"0px\";\n f1.style.height = \"14px\";\n f1.style.cssFloat = \"left\";\n container.appendChild(f1);\n const f2 = doc.createElement(\"div\") as HTMLElement;\n f2.style.width = \"50px\";\n f2.style.height = \"50px\";\n f2.style.cssFloat = \"left\";\n f2.style.clear = \"left\";\n container.appendChild(f2);\n const t = doc.createTextNode(\"a a a a a a a a a a a a a a a a\");\n container.appendChild(t);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 1);\n const leftEdge = range.getBoundingClientRect().left;\n hasLShapeFloatBug = leftEdge < 40;\n body.removeChild(container);\n }\n return hasLShapeFloatBug;\n}\n\nexport let hasVerticalBBoxBug: boolean | null = null;\n\n/**\n * Check if there is a bug with the bounding boxes of vertical text characters.\n * Though method used to be used check Chrome bug, it seems that the bug has\n * been already fixed:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=297808\n * We now use this method to check Firefox bug:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1159309\n */\nexport function checkVerticalBBoxBug(body: HTMLElement): boolean {\n if (hasVerticalBBoxBug == null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"100px\";\n container.style.height = \"100px\";\n container.style.overflow = \"hidden\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n setCSSProperty(container, \"writing-mode\", \"vertical-rl\");\n body.appendChild(container);\n const t = doc.createTextNode(\"a a a a a a a a a a a a a a a a\");\n container.appendChild(t);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 1);\n const box = range.getBoundingClientRect();\n hasVerticalBBoxBug = box.right - box.left < 10;\n body.removeChild(container);\n }\n return hasVerticalBBoxBug;\n}\n\nexport let hasInlineBlockJustificationBug: boolean | null = null;\n\nexport function checkInlineBlockJustificationBug(body: HTMLElement): boolean {\n if (hasInlineBlockJustificationBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"30px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a | \");\n container.appendChild(t);\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"30px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 0);\n range.setEnd(t, 3);\n const box = range.getBoundingClientRect();\n hasInlineBlockJustificationBug = box.right < 27;\n body.removeChild(container);\n }\n return hasInlineBlockJustificationBug;\n}\n\nexport let hasSoftWrapOpportunityAfterHyphenBug: boolean | null = null;\n\nexport function checkSoftWrapOpportunityAfterHyphenBug(\n body: HTMLElement,\n): boolean {\n if (hasSoftWrapOpportunityAfterHyphenBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"40px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a a-\");\n container.appendChild(t);\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"40px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 2);\n range.setEnd(t, 4);\n const box = range.getBoundingClientRect();\n hasSoftWrapOpportunityAfterHyphenBug = box.right < 37;\n body.removeChild(container);\n }\n return hasSoftWrapOpportunityAfterHyphenBug;\n}\n\nexport let hasSoftWrapOpportunityByWbrBug: boolean | null = null;\n\nexport function checkSoftWrapOpportunityByWbrBug(body: HTMLElement): boolean {\n if (hasSoftWrapOpportunityByWbrBug === null) {\n const doc = body.ownerDocument;\n const container = doc.createElement(\"div\") as HTMLElement;\n container.style.position = \"absolute\";\n container.style.top = \"0px\";\n container.style.left = \"0px\";\n container.style.width = \"40px\";\n container.style.height = \"100px\";\n container.style.lineHeight = \"16px\";\n container.style.fontSize = \"16px\";\n container.style.textAlign = \"justify\";\n body.appendChild(container);\n const t = doc.createTextNode(\"a a-\");\n container.appendChild(t);\n container.appendChild(doc.createElement(\"wbr\"));\n const inlineBlock = doc.createElement(\"span\");\n inlineBlock.style.display = \"inline-block\";\n inlineBlock.style.width = \"40px\";\n container.appendChild(inlineBlock);\n const range = doc.createRange();\n range.setStart(t, 2);\n range.setEnd(t, 4);\n const box = range.getBoundingClientRect();\n hasSoftWrapOpportunityByWbrBug = box.right < 37;\n body.removeChild(container);\n }\n return hasSoftWrapOpportunityByWbrBug;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Cfi - Support for EPUB Canonical Fragment Identifiers.\n */\nimport * as Base from \"./base\";\n\nexport type Position = {\n node: Node;\n offset: number;\n after: boolean;\n sideBias: string | null;\n ref: Fragment;\n};\n\nexport function getId(node: Node): string | null {\n if (node.nodeType == 1) {\n const idtxt = (node as Element).getAttribute(\"id\");\n if (idtxt && idtxt.match(/^[-a-zA-Z_0-9.\\u007F-\\uFFFF]+$/)) {\n return idtxt;\n }\n }\n return null;\n}\n\nexport function escapeChar(ch: string): string {\n return `^${ch}`;\n}\n\nexport function escape(str: string): string {\n return str.replace(/[\\[\\]\\(\\),=;^]/g, escapeChar);\n}\n\nexport function unescapeChar(str: string): string {\n return str.substr(1);\n}\n\nexport function unescape(str: string): string {\n if (!str) {\n return str;\n }\n return str.replace(/\\^[\\[\\]\\(\\),=;^]/g, unescapeChar);\n}\n\nexport function parseExtVal(extstr: string): string | string[] {\n const result = [];\n do {\n const r = extstr.match(/^(\\^,|[^,])*/);\n const p = unescape(r[0]);\n extstr = extstr.substr(r[0].length + 1);\n if (!extstr && !result.length) {\n return p;\n }\n result.push(p);\n } while (extstr);\n return result;\n}\n\nexport function parseExt(extstr: string): { [key: string]: string | string[] } {\n const ext = {};\n while (extstr) {\n const r = extstr.match(/^;([^;=]+)=(([^;]|\\^;)*)/);\n if (!r) {\n return ext;\n }\n ext[r[1]] = parseExtVal(r[2]);\n extstr = extstr.substr(r[0].length);\n }\n return ext;\n}\n\nexport interface Step {\n appendTo(sb: Base.StringBuffer): void;\n\n applyTo(pos: Position): boolean;\n}\n\nexport class RefStep implements Step {\n appendTo(sb: Base.StringBuffer) {\n sb.append(\"!\");\n }\n\n /**\n * @override\n */\n applyTo(pos: Position): boolean {\n return false;\n }\n}\n\nexport class ChildStep implements Step {\n constructor(\n public readonly index: number,\n public readonly id: string | null,\n public readonly sideBias: string | null,\n ) {}\n\n /**\n * @override\n */\n appendTo(sb: Base.StringBuffer): void {\n sb.append(\"/\");\n sb.append(this.index.toString());\n if (this.id || this.sideBias) {\n sb.append(\"[\");\n if (this.id) {\n sb.append(this.id);\n }\n if (this.sideBias) {\n sb.append(\";s=\");\n sb.append(this.sideBias);\n }\n sb.append(\"]\");\n }\n }\n\n /**\n * @override\n */\n applyTo(pos: Position): boolean {\n if (pos.node.nodeType != 1) {\n throw new Error(\"E_CFI_NOT_ELEMENT\");\n }\n const elem = pos.node as Element;\n const childElements = elem.children;\n const childElementCount = childElements.length;\n let child: Node;\n const childIndex = Math.floor(this.index / 2) - 1;\n if (childIndex < 0 || childElementCount == 0) {\n child = elem.firstChild;\n pos.node = child || elem;\n } else {\n child = childElements[Math.min(childIndex, childElementCount - 1)];\n if (this.index & 1) {\n const next = child.nextSibling;\n if (!next || next.nodeType == 1) {\n pos.after = true;\n } else {\n child = next;\n }\n }\n pos.node = child;\n }\n if (this.id && (pos.after || this.id != getId(pos.node))) {\n throw new Error(\"E_CFI_ID_MISMATCH\");\n }\n pos.sideBias = this.sideBias;\n return true;\n }\n}\n\nexport class OffsetStep implements Step {\n constructor(\n public readonly offset: number,\n public readonly textBefore: string | null,\n public readonly textAfter: string | null,\n public readonly sideBias: string | null,\n ) {}\n\n applyTo(pos: Position): boolean {\n if (this.offset > 0 && !pos.after) {\n let offset = this.offset;\n let node = pos.node;\n while (true) {\n const nodeType = node.nodeType;\n if (nodeType == 1) {\n break;\n }\n const next = node.nextSibling;\n if (3 <= nodeType && nodeType <= 5) {\n const textLength = node.textContent.length;\n if (offset <= textLength) {\n break;\n }\n if (!next) {\n offset = textLength;\n break;\n }\n offset -= textLength;\n }\n if (!next) {\n offset = 0;\n break;\n }\n node = next;\n }\n pos.node = node;\n pos.offset = offset;\n }\n pos.sideBias = this.sideBias;\n return true;\n }\n\n /**\n * @override\n */\n appendTo(sb: Base.StringBuffer): void {\n sb.append(\":\");\n sb.append(this.offset.toString());\n if (this.textBefore || this.textAfter || this.sideBias) {\n sb.append(\"[\");\n if (this.textBefore || this.textAfter) {\n if (this.textBefore) {\n sb.append(escape(this.textBefore));\n }\n sb.append(\",\");\n if (this.textAfter) {\n sb.append(escape(this.textAfter));\n }\n }\n if (this.sideBias) {\n sb.append(\";s=\");\n sb.append(this.sideBias);\n }\n sb.append(\"]\");\n }\n }\n}\n\nexport class Fragment {\n steps: Step[] = null;\n\n fromString(fragstr: string): void {\n let r = fragstr.match(/^#?epubcfi\\((.*)\\)$/);\n if (!r) {\n throw new Error(\"E_CFI_NOT_CFI\");\n }\n const str = r[1];\n let i = 0;\n const steps = [];\n while (true) {\n let ext: {\n [key: string]: string | string[];\n };\n switch (str.charAt(i)) {\n case \"/\": {\n i++;\n r = str\n .substr(i)\n .match(\n /^(0|[1-9][0-9]*)(\\[([-a-zA-Z_0-9.\\u007F-\\uFFFF]+)(;([^\\]]|\\^\\])*)?\\])?/,\n );\n if (!r) {\n throw new Error(\"E_CFI_NUMBER_EXPECTED\");\n }\n i += r[0].length;\n const index = parseInt(r[1], 10);\n const id = r[3];\n ext = parseExt(r[4]);\n steps.push(new ChildStep(index, id, Base.asString(ext[\"s\"])));\n break;\n }\n case \":\": {\n i++;\n r = str\n .substr(i)\n .match(\n /^(0|[1-9][0-9]*)(\\[((([^\\];,]|\\^[\\];,])*)(,(([^\\];,]|\\^[\\];,])*))?)(;([^]]|\\^\\])*)?\\])?/,\n );\n if (!r) {\n throw new Error(\"E_CFI_NUMBER_EXPECTED\");\n }\n i += r[0].length;\n const offset = parseInt(r[1], 10);\n let textBefore = r[4];\n if (textBefore) {\n textBefore = unescape(textBefore);\n }\n let textAfter = r[7];\n if (textAfter) {\n textAfter = unescape(textAfter);\n }\n ext = parseExt(r[10]);\n steps.push(\n new OffsetStep(\n offset,\n textBefore,\n textAfter,\n Base.asString(ext[\"s\"]),\n ),\n );\n break;\n }\n case \"!\":\n i++;\n steps.push(new RefStep());\n break;\n case \"~\":\n case \"@\":\n\n // Time/space terminus; only useful for highlights/selections which are\n // not yet supported, skip for now. fall through\n case \"\":\n this.steps = steps;\n return;\n default:\n throw new Error(\"E_CFI_PARSE_ERROR\");\n }\n }\n }\n\n navigate(doc: Document): Position {\n const pos = {\n node: doc.documentElement,\n offset: 0,\n after: false,\n sideBias: null,\n ref: null,\n };\n for (let i = 0; i < this.steps.length; i++) {\n if (!this.steps[i].applyTo(pos)) {\n pos.ref = new Fragment();\n pos.ref.steps = this.steps.slice(i + 1);\n break;\n }\n }\n return pos;\n }\n\n trim(text: string, after: boolean): string {\n return text\n .replace(/\\s+/g, \" \")\n .match(\n after\n ? /^[ -\\uD7FF\\uE000-\\uFFFF]{0,8}/\n : /[ -\\uD7FF\\uE000-\\uFFFF]{0,8}$/,\n )[0]\n .replace(/^\\s/, \"\")\n .replace(/\\s$/, \"\");\n }\n\n /**\n * Initialize from a node and an offset.\n */\n prependPathFromNode(\n node: Node,\n offset: number,\n after: boolean,\n sideBias: string | null,\n ) {\n const steps = [];\n let parent = node.parentNode;\n let textBefore = \"\";\n let textAfter = \"\";\n while (node) {\n switch (node.nodeType) {\n case 3: // Text nodes\n case 4:\n case 5: {\n const text = node.textContent;\n const textLength = text.length;\n if (after) {\n offset += textLength;\n if (!textBefore) {\n textBefore = text;\n }\n } else {\n if (offset > textLength) {\n offset = textLength;\n }\n after = true;\n textBefore = text.substr(0, offset);\n textAfter = text.substr(offset);\n }\n node = node.previousSibling;\n continue;\n }\n case 8: // Comment Node\n node = node.previousSibling;\n continue;\n }\n break;\n }\n if (offset > 0 || textBefore || textAfter) {\n textBefore = this.trim(textBefore, false);\n textAfter = this.trim(textAfter, true);\n steps.push(new OffsetStep(offset, textBefore, textAfter, sideBias));\n sideBias = null;\n }\n while (parent) {\n if (!parent || parent.nodeType == 9) {\n break;\n }\n const id = after ? null : getId(node);\n let index = after ? 1 : 0;\n while (node) {\n if (node.nodeType == 1) {\n index += 2;\n }\n node = node.previousSibling;\n }\n steps.push(new ChildStep(index, id, sideBias));\n sideBias = null;\n node = parent;\n parent = parent.parentNode;\n after = false;\n }\n steps.reverse();\n if (this.steps) {\n steps.push(new RefStep());\n this.steps = steps.concat(this.steps);\n } else {\n this.steps = steps;\n }\n }\n\n toString(): string {\n if (!this.steps) {\n return \"\";\n }\n const sb = new Base.StringBuffer();\n sb.append(\"epubcfi(\");\n for (let i = 0; i < this.steps.length; i++) {\n this.steps[i].appendTo(sb);\n }\n sb.append(\")\");\n return sb.toString();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Exprs - `-epubx-expr` Adaptive Layout expressions.\n */\nimport * as Base from \"./base\";\n\nexport type Preferences = {\n fontFamily: string;\n lineHeight: number;\n margin: number;\n hyphenate: boolean;\n columnWidth: number;\n horizontal: boolean;\n nightMode: boolean;\n spreadView: boolean;\n pageBorder: number;\n enabledMediaTypes: { [key: string]: boolean };\n defaultPaperSize?: { [key: string]: number };\n};\n\nexport function defaultPreferences(): Preferences {\n return {\n fontFamily: \"serif\",\n lineHeight: 1.25,\n margin: 8,\n hyphenate: false,\n columnWidth: 25,\n horizontal: false,\n nightMode: false,\n spreadView: false,\n pageBorder: 1,\n enabledMediaTypes: { vivliostyle: true, print: true },\n defaultPaperSize: undefined,\n };\n}\n\nexport function clonePreferences(pref: Preferences): Preferences {\n return {\n fontFamily: pref.fontFamily,\n lineHeight: pref.lineHeight,\n margin: pref.margin,\n hyphenate: pref.hyphenate,\n columnWidth: pref.columnWidth,\n horizontal: pref.horizontal,\n nightMode: pref.nightMode,\n spreadView: pref.spreadView,\n pageBorder: pref.pageBorder,\n enabledMediaTypes: Object.assign({}, pref.enabledMediaTypes),\n defaultPaperSize: pref.defaultPaperSize\n ? Object.assign({}, pref.defaultPaperSize)\n : undefined,\n };\n}\n\nexport const defaultPreferencesInstance = defaultPreferences();\n\ninterface Pending {}\ntype Special = Pending;\n\n/**\n * Special marker value that indicates that the expression result is being\n * calculated.\n */\nexport const Special = {\n PENDING: {} as Pending,\n};\n\nexport type Result = string | number | boolean | undefined;\n\nexport type PendingResult = Special | Result;\n\nexport function letterbox(\n viewW: number,\n viewH: number,\n objW: number,\n objH: number,\n): string {\n const scale = Math.min((viewW - 0) / objW, (viewH - 0) / objH);\n return `matrix(${scale},0,0,${scale},0,0)`;\n}\n\n/**\n * @return string that can be parsed as CSS string with value str\n */\nexport function cssString(str: string): string {\n return `\"${Base.escapeCSSStr(`${str}`)}\"`;\n}\n\n/**\n * @return string that can be parsed as CSS name\n */\nexport function cssIdent(name: string): string {\n return Base.escapeCSSIdent(`${name}`);\n}\n\nexport function makeQualifiedName(\n objName: string | null,\n memberName: string,\n): string {\n if (objName) {\n return `${Base.escapeCSSIdent(objName)}.${Base.escapeCSSIdent(memberName)}`;\n }\n return Base.escapeCSSIdent(memberName);\n}\n\nexport let nextKeyIndex: number = 0;\n\n/**\n * Lexical scope of the expression.\n */\nexport class LexicalScope {\n scopeKey: string;\n children: LexicalScope[] = [];\n zero: Const;\n one: Const;\n _true: Const;\n _false: Const;\n values: { [key: string]: Val } = {};\n funcs: { [key: string]: Val } = {};\n builtIns: { [key: string]: (...p1: Result[]) => Result } = {};\n\n constructor(\n public parent: LexicalScope,\n public resolver?: (p1: string, p2: boolean) => Val,\n ) {\n this.scopeKey = `S${nextKeyIndex++}`;\n this.zero = new Const(this, 0);\n this.one = new Const(this, 1);\n this._true = new Const(this, true);\n this._false = new Const(this, false);\n if (parent) {\n parent.children.push(this);\n }\n if (!parent) {\n // root scope\n const builtIns = this.builtIns;\n builtIns[\"floor\"] = Math.floor;\n builtIns[\"ceil\"] = Math.ceil;\n builtIns[\"round\"] = Math.round;\n builtIns[\"sqrt\"] = Math.sqrt;\n builtIns[\"min\"] = Math.min;\n builtIns[\"max\"] = Math.max;\n builtIns[\"letterbox\"] = letterbox;\n builtIns[\"css-string\"] = cssString;\n builtIns[\"css-name\"] = cssIdent;\n builtIns[\"typeof\"] = (x) => typeof x;\n this.defineBuiltInName(\"page-width\", function() {\n return this.pageWidth();\n });\n this.defineBuiltInName(\"page-height\", function() {\n return this.pageHeight();\n });\n this.defineBuiltInName(\"pref-font-family\", function() {\n return this.pref.fontFamily;\n });\n this.defineBuiltInName(\"pref-night-mode\", function() {\n return this.pref.nightMode;\n });\n this.defineBuiltInName(\"pref-hyphenate\", function() {\n return this.pref.hyphenate;\n });\n this.defineBuiltInName(\"pref-margin\", function() {\n return this.pref.margin;\n });\n this.defineBuiltInName(\"pref-line-height\", function() {\n return this.pref.lineHeight;\n });\n this.defineBuiltInName(\"pref-column-width\", function() {\n return this.pref.columnWidth * this.fontSize;\n });\n this.defineBuiltInName(\"pref-horizontal\", function() {\n return this.pref.horizontal;\n });\n this.defineBuiltInName(\"pref-spread-view\", function() {\n return this.pref.spreadView;\n });\n\n // For env(pub-title) and env(doc-title)\n this.defineBuiltInName(\"pub-title\", function() {\n return cssString(this.pubTitle ? this.pubTitle : \"\");\n });\n this.defineBuiltInName(\"doc-title\", function() {\n return cssString(this.docTitle ? this.docTitle : \"\");\n });\n }\n }\n\n defineBuiltInName(name: string, fn: () => Result) {\n this.values[name] = new Native(this, fn, name);\n }\n\n defineName(qualifiedName: string, val: Val): void {\n this.values[qualifiedName] = val;\n }\n\n defineFunc(qualifiedName: string, val: Val): void {\n this.funcs[qualifiedName] = val;\n }\n\n defineBuiltIn(qualifiedName: string, fn: (...p1: Result[]) => Result): void {\n this.builtIns[qualifiedName] = fn;\n }\n}\n\nexport function isAbsoluteLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"px\":\n case \"in\":\n case \"pt\":\n case \"pc\":\n case \"cm\":\n case \"mm\":\n case \"q\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isViewportRelativeLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"vw\":\n case \"vh\":\n case \"vi\":\n case \"vb\":\n case \"vmin\":\n case \"vmax\":\n case \"pvw\":\n case \"pvh\":\n case \"pvi\":\n case \"pvb\":\n case \"pvmin\":\n case \"pvmax\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isFontRelativeLengthUnit(unit: string): boolean {\n switch (unit.toLowerCase()) {\n case \"em\":\n case \"ex\":\n case \"rem\":\n return true;\n default:\n return false;\n }\n}\n\nexport const defaultUnitSizes: { [key: string]: number } = {\n px: 1,\n in: 96,\n pt: 4 / 3,\n pc: 96 / 6,\n cm: 96 / 2.54,\n mm: 96 / 25.4,\n q: 96 / 2.54 / 40,\n em: 16,\n rem: 16,\n ex: 8,\n // <resolution>\n dppx: 1,\n dpi: 1 / 96,\n dpcm: 2.54 / 96,\n};\n\n/**\n * Returns if a unit should be converted to px before applied to the raw DOM.\n */\nexport function needUnitConversion(unit: string): boolean {\n switch (unit) {\n case \"q\":\n case \"rem\":\n return true;\n default:\n return false;\n }\n}\n\nexport type ScopeContext = {\n [key: string]: Result;\n};\n\n/**\n * Run-time instance of a scope and its children.\n */\nexport class Context {\n protected actualPageWidth: number | null = null;\n pageWidth: () => number;\n protected actualPageHeight: number | null = null;\n pageHeight: () => number;\n initialFontSize: number;\n rootFontSize: number | null = null;\n fontSize: () => number;\n pref: Preferences;\n scopes: { [key: string]: ScopeContext } = {};\n pageAreaWidth: number | null = null;\n pageAreaHeight: number | null = null;\n pageVertical: boolean | null = null;\n pubTitle: string | null = null;\n docTitle: string | null = null;\n\n constructor(\n public readonly rootScope: LexicalScope,\n public readonly viewportWidth: number,\n public readonly viewportHeight: number,\n fontSize: number,\n ) {\n this.pageWidth = function() {\n if (this.actualPageWidth) {\n return this.actualPageWidth;\n } else {\n return this.pref.spreadView\n ? Math.floor(viewportWidth / 2) - this.pref.pageBorder\n : viewportWidth;\n }\n };\n this.pageHeight = function() {\n if (this.actualPageHeight) {\n return this.actualPageHeight;\n } else {\n return viewportHeight;\n }\n };\n this.initialFontSize = fontSize;\n this.fontSize = function() {\n if (this.rootFontSize) {\n return this.rootFontSize;\n } else {\n return fontSize;\n }\n };\n this.pref = defaultPreferencesInstance;\n }\n\n private getScopeContext(scope: LexicalScope): ScopeContext {\n let s = this.scopes[scope.scopeKey];\n if (!s) {\n s = {};\n this.scopes[scope.scopeKey] = s;\n }\n return s;\n }\n\n clearScope(scope: LexicalScope): void {\n this.scopes[scope.scopeKey] = {};\n for (let k = 0; k < scope.children.length; k++) {\n this.clearScope(scope.children[k]);\n }\n }\n\n queryUnitSize(unit: string, isRoot: boolean): number {\n if (isViewportRelativeLengthUnit(unit)) {\n const pvw = this.pageWidth() / 100;\n const pvh = this.pageHeight() / 100;\n const vw = this.pageAreaWidth != null ? this.pageAreaWidth / 100 : pvw;\n const vh = this.pageAreaHeight != null ? this.pageAreaHeight / 100 : pvh;\n\n switch (unit) {\n case \"vw\":\n return vw;\n case \"vh\":\n return vh;\n case \"vi\":\n return this.pageVertical ? vh : vw;\n case \"vb\":\n return this.pageVertical ? vw : vh;\n case \"vmin\":\n return vw < vh ? vw : vh;\n case \"vmax\":\n return vw > vh ? vw : vh;\n case \"pvw\":\n return pvw;\n case \"pvh\":\n return pvh;\n case \"pvi\":\n return this.pageVertical ? pvh : pvw;\n case \"pvb\":\n return this.pageVertical ? pvw : pvh;\n case \"pvmin\":\n return pvw < pvh ? pvw : pvh;\n case \"pvmax\":\n return pvw > pvh ? pvw : pvh;\n }\n }\n if (unit == \"em\" || unit == \"rem\") {\n return isRoot ? this.initialFontSize : this.fontSize();\n }\n if (unit == \"ex\") {\n return (\n (defaultUnitSizes[\"ex\"] *\n (isRoot ? this.initialFontSize : this.fontSize())) /\n defaultUnitSizes[\"em\"]\n );\n }\n return defaultUnitSizes[unit];\n }\n\n evalName(scope: LexicalScope, qualifiedName: string): Val {\n do {\n let val = scope.values[qualifiedName];\n if (val) {\n return val;\n }\n if (scope.resolver) {\n val = scope.resolver.call(this, qualifiedName, false);\n if (val) {\n return val;\n }\n }\n scope = scope.parent;\n } while (scope);\n throw new Error(`Name '${qualifiedName}' is undefined`);\n }\n\n /**\n * @param noBuiltInEval don't evaluate built-ins (for dependency calculations)\n */\n evalCall(\n scope: LexicalScope,\n qualifiedName: string,\n params: Val[],\n noBuiltInEval: boolean,\n ): Val {\n do {\n let body = scope.funcs[qualifiedName];\n if (body) {\n return body; // will be expanded by callee\n }\n if (scope.resolver) {\n body = scope.resolver.call(this, qualifiedName, true);\n if (body) {\n return body;\n }\n }\n const fn = scope.builtIns[qualifiedName];\n if (fn) {\n if (noBuiltInEval) {\n return scope.zero;\n }\n const args = Array(params.length);\n for (let i = 0; i < params.length; i++) {\n args[i] = params[i].evaluate(this);\n }\n return new Const(scope, fn.apply(this, args));\n }\n scope = scope.parent;\n } while (scope);\n throw new Error(`Function '${qualifiedName}' is undefined`);\n }\n\n evalMediaName(name: string, not: boolean): boolean {\n const enabled = name === \"all\" || !!this.pref.enabledMediaTypes[name];\n return not ? !enabled : enabled;\n }\n\n evalMediaTest(feature: string, value: Val): boolean {\n let prefix = \"\";\n const r = feature.match(/^(min|max)-(.*)$/);\n if (r) {\n prefix = r[1];\n feature = r[2];\n }\n let req: Result | null = null;\n let actual: number | null = null;\n switch (feature) {\n case \"width\":\n case \"height\":\n case \"device-width\":\n case \"device-height\":\n case \"color\":\n if (value) {\n req = value.evaluate(this);\n }\n break;\n }\n switch (feature) {\n case \"width\":\n actual = this.pageWidth();\n break;\n case \"height\":\n actual = this.pageHeight();\n break;\n case \"device-width\":\n actual = window.screen.availWidth;\n break;\n case \"device-height\":\n actual = window.screen.availHeight;\n break;\n case \"color\":\n actual = window.screen.pixelDepth;\n break;\n }\n if (actual != null && req != null) {\n switch (prefix) {\n case \"min\":\n return actual >= req;\n case \"max\":\n return actual <= req;\n default:\n return actual == req;\n }\n } else if (actual != null && value == null) {\n return actual !== 0;\n }\n return false;\n }\n\n queryVal(scope: LexicalScope, key: string): Result | undefined {\n const s = this.scopes[scope.scopeKey];\n return s ? s[key] : undefined;\n }\n\n storeVal(scope: LexicalScope, key: string, val: Result): void {\n this.getScopeContext(scope)[key] = val;\n }\n}\n\n//---------- name resolution --------------\nexport type DependencyCache = {\n [key: string]: boolean | Special;\n};\n\nexport class Val {\n key: string;\n\n constructor(public scope: LexicalScope) {\n this.scope = scope;\n this.key = `_${nextKeyIndex++}`;\n }\n\n /**\n * @override\n */\n toString(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, 0);\n return buf.toString();\n }\n\n appendTo(buf: Base.StringBuffer, priority: number): void {\n throw new Error(\"F_ABSTRACT\");\n }\n\n protected evaluateCore(context: Context): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n expand(context: Context, params: Val[]): Val {\n return this;\n }\n\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return other === this;\n }\n\n dependOuter(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n const cached = dependencyCache[this.key];\n if (cached != null) {\n if (cached === Special.PENDING) {\n return false;\n }\n return cached as boolean;\n } else {\n dependencyCache[this.key] = Special.PENDING;\n const result = this.dependCore(other, context, dependencyCache);\n dependencyCache[this.key] = result;\n return result;\n }\n }\n\n depend(other: Val, context: Context): boolean {\n return this.dependOuter(other, context, {});\n }\n\n evaluate(context: Context): Result {\n let result = context.queryVal(this.scope, this.key);\n if (typeof result != \"undefined\") {\n return result;\n }\n result = this.evaluateCore(context);\n context.storeVal(this.scope, this.key, result);\n return result;\n }\n\n isMediaName(): boolean {\n return false;\n }\n}\n\nexport class Prefix extends Val {\n constructor(scope: LexicalScope, public val: Val) {\n super(scope);\n }\n\n protected getOp(): string {\n throw new Error(\"F_ABSTRACT\");\n }\n\n evalPrefix(val: Result): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const val = this.val.evaluate(context);\n return this.evalPrefix(val);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.val.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (10 < priority) {\n buf.append(\"(\");\n }\n buf.append(this.getOp());\n this.val.appendTo(buf, 10);\n if (10 < priority) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const val = this.val.expand(context, params);\n if (val === this.val) {\n return this;\n }\n const r = new (this.constructor as any)(this.scope, val);\n return r;\n }\n}\n\nexport class Infix extends Val {\n constructor(scope: LexicalScope, public lhs: Val, public rhs: Val) {\n super(scope);\n }\n\n getPriority(): number {\n throw new Error(\"F_ABSTRACT\");\n }\n\n getOp(): string {\n throw new Error(\"F_ABSTRACT\");\n }\n\n evalInfix(lhs: Result, rhs: Result): Result {\n throw new Error(\"F_ABSTRACT\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const lhs = this.lhs.evaluate(context);\n const rhs = this.rhs.evaluate(context);\n return this.evalInfix(lhs, rhs);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n this.lhs.dependOuter(other, context, dependencyCache) ||\n this.rhs.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n const thisPriority = this.getPriority();\n if (thisPriority <= priority) {\n buf.append(\"(\");\n }\n this.lhs.appendTo(buf, thisPriority);\n buf.append(this.getOp());\n this.rhs.appendTo(buf, thisPriority);\n if (thisPriority <= priority) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const lhs = this.lhs.expand(context, params);\n const rhs = this.rhs.expand(context, params);\n if (lhs === this.lhs && rhs === this.rhs) {\n return this;\n }\n const r = new (this.constructor as any)(this.scope, lhs, rhs);\n return r;\n }\n}\n\nexport class Logical extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class Comparison extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 2;\n }\n}\n\nexport class Additive extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 3;\n }\n}\n\nexport class Multiplicative extends Infix {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class Not extends Prefix {\n constructor(scope: LexicalScope, val: Val) {\n super(scope, val);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"!\";\n }\n\n /**\n * @override\n */\n evalPrefix(val: Result): Result {\n return !val;\n }\n}\n\nexport class Negate extends Prefix {\n constructor(scope: LexicalScope, val: Val) {\n super(scope, val);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"-\";\n }\n\n /**\n * @override\n */\n evalPrefix(val: Result): Result {\n return -val;\n }\n}\n\nexport class And extends Logical {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"&&\";\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.lhs.evaluate(context) && this.rhs.evaluate(context);\n }\n}\n\nexport class AndMedia extends And {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \" and \";\n }\n}\n\nexport class Or extends Logical {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"||\";\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.lhs.evaluate(context) || this.rhs.evaluate(context);\n }\n}\n\nexport class OrMedia extends Or {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \", \";\n }\n}\n\nexport class Lt extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"<\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs < rhs;\n }\n}\n\nexport class Le extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"<=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs <= rhs;\n }\n}\n\nexport class Gt extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \">\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs > rhs;\n }\n}\n\nexport class Ge extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \">=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs >= rhs;\n }\n}\n\nexport class Eq extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"==\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs == rhs;\n }\n}\n\nexport class Ne extends Comparison {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"!=\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return lhs != rhs;\n }\n}\n\nexport class Add extends Additive {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"+\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) + rhs;\n }\n}\n\nexport class Subtract extends Additive {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \" - \";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) - (rhs as any);\n }\n}\n\nexport class Multiply extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"*\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) * (rhs as any);\n }\n}\n\nexport class Divide extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"/\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) / (rhs as any);\n }\n}\n\nexport class Modulo extends Multiplicative {\n constructor(scope: LexicalScope, lhs: Val, rhs: Val) {\n super(scope, lhs, rhs);\n }\n\n /**\n * @override\n */\n getOp(): string {\n return \"%\";\n }\n\n /**\n * @override\n */\n evalInfix(lhs: Result, rhs: Result): Result {\n return (lhs as any) % (rhs as any);\n }\n}\n\n/**\n * Numerical value with a unit.\n */\nexport class Numeric extends Val {\n unit: string;\n\n constructor(scope: LexicalScope, public num: number, unit: string) {\n super(scope);\n this.unit = unit.toLowerCase();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.num.toString());\n buf.append(Base.escapeCSSIdent(this.unit));\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.num * context.queryUnitSize(this.unit, false);\n }\n}\n\n/**\n * Named value.\n * @param qualifiedName CSS-escaped name sequence separated by dots.\n */\nexport class Named extends Val {\n constructor(scope: LexicalScope, public qualifiedName: string) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.qualifiedName);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalName(this.scope, this.qualifiedName).evaluate(context);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n context\n .evalName(this.scope, this.qualifiedName)\n .dependOuter(other, context, dependencyCache)\n );\n }\n}\n\n/**\n * Named value.\n */\nexport class MediaName extends Val {\n // FIXME: This property is added to reduce TypeScript error on `dependCore`\n // but it is never initialized. Is it really correct code?\n value: Val;\n\n constructor(scope: LexicalScope, public not: boolean, public name: string) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (this.not) {\n buf.append(\"not \");\n }\n buf.append(Base.escapeCSSIdent(this.name));\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalMediaName(this.name, this.not);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.value.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n isMediaName(): boolean {\n return true;\n }\n}\n\n/**\n * A value that is calculated by calling a JavaScript function. Note that the\n * result is cached and this function will be called only once between any\n * clears for its scope in the context.\n * @param fn function to call.\n * @param str a way to represent this value in toString() call.\n */\nexport class Native extends Val {\n constructor(\n scope: LexicalScope,\n public fn: () => Result,\n public str: string,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.str);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.fn.call(context);\n }\n}\n\nexport function appendValArray(buf: Base.StringBuffer, arr: Val[]): void {\n buf.append(\"(\");\n for (let i = 0; i < arr.length; i++) {\n if (i) {\n buf.append(\",\");\n }\n arr[i].appendTo(buf, 0);\n }\n buf.append(\")\");\n}\n\nexport function expandValArray(\n context: Context,\n arr: Val[],\n params: Val[],\n): Val[] {\n let expanded: Val[] = arr;\n for (let i = 0; i < arr.length; i++) {\n const p = arr[i].expand(context, params);\n if (arr !== expanded) {\n expanded[i] = p;\n } else if (p !== arr[i]) {\n expanded = Array(arr.length);\n for (let j = 0; j < i; j++) {\n expanded[j] = arr[j];\n }\n expanded[i] = p;\n }\n }\n return expanded;\n}\n\nexport function evalValArray(context: Context, arr: Val[]): Result[] {\n const result: Result[] = Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n result[i] = arr[i].evaluate(context);\n }\n return result;\n}\n\nexport class Call extends Val {\n constructor(\n scope: LexicalScope,\n public qualifiedName: string,\n public params: Val[],\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(this.qualifiedName);\n appendValArray(buf, this.params);\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n const body = context.evalCall(\n this.scope,\n this.qualifiedName,\n this.params,\n false,\n );\n return body.expand(context, this.params).evaluate(context);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n if (other === this) {\n return true;\n }\n for (let i = 0; i < this.params.length; i++) {\n if (this.params[i].dependOuter(other, context, dependencyCache)) {\n return true;\n }\n }\n const body = context.evalCall(\n this.scope,\n this.qualifiedName,\n this.params,\n true,\n );\n\n // No expansion here!\n return body.dependOuter(other, context, dependencyCache);\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const expandedParams = expandValArray(context, this.params, params);\n if (expandedParams === this.params) {\n return this;\n }\n return new Call(this.scope, this.qualifiedName, expandedParams);\n }\n}\n\nexport class Cond extends Val {\n constructor(\n scope: LexicalScope,\n public cond: Val,\n public ifTrue: Val,\n public ifFalse: Val,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n if (priority > 0) {\n buf.append(\"(\");\n }\n this.cond.appendTo(buf, 0);\n buf.append(\"?\");\n this.ifTrue.appendTo(buf, 0);\n buf.append(\":\");\n this.ifFalse.appendTo(buf, 0);\n if (priority > 0) {\n buf.append(\")\");\n }\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n if (this.cond.evaluate(context)) {\n return this.ifTrue.evaluate(context);\n } else {\n return this.ifFalse.evaluate(context);\n }\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this ||\n this.cond.dependOuter(other, context, dependencyCache) ||\n this.ifTrue.dependOuter(other, context, dependencyCache) ||\n this.ifFalse.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const cond = this.cond.expand(context, params);\n const ifTrue = this.ifTrue.expand(context, params);\n const ifFalse = this.ifFalse.expand(context, params);\n if (\n cond === this.cond &&\n ifTrue === this.ifTrue &&\n ifFalse === this.ifFalse\n ) {\n return this;\n }\n const r = new Cond(this.scope, cond, ifTrue, ifFalse);\n return r;\n }\n}\n\nexport class Const extends Val {\n constructor(scope: LexicalScope, public val: Result) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n switch (typeof this.val) {\n case \"number\":\n case \"boolean\":\n buf.append(this.val.toString());\n break;\n case \"string\":\n buf.append('\"');\n buf.append(Base.escapeCSSStr(this.val));\n buf.append('\"');\n break;\n default:\n throw new Error(\"F_UNEXPECTED_STATE\");\n }\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return this.val;\n }\n}\n\nexport class MediaTest extends Val {\n constructor(scope: LexicalScope, public name: MediaName, public value: Val) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(\"(\");\n buf.append(Base.escapeCSSStr(this.name.name));\n buf.append(\":\");\n this.value.appendTo(buf, 0);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n evaluateCore(context: Context): Result {\n return context.evalMediaTest(this.name.name, this.value);\n }\n\n /**\n * @override\n */\n dependCore(\n other: Val,\n context: Context,\n dependencyCache: DependencyCache,\n ): boolean {\n return (\n other === this || this.value.dependOuter(other, context, dependencyCache)\n );\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const value = this.value.expand(context, params);\n if (value === this.value) {\n return this;\n }\n const r = new MediaTest(this.scope, this.name, value);\n return r;\n }\n}\n\nexport class Param extends Val {\n constructor(scope: LexicalScope, public index: number) {\n super(scope);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, priority: number): void {\n buf.append(\"$\");\n buf.append(this.index.toString());\n }\n\n /**\n * @override\n */\n expand(context: Context, params: Val[]): Val {\n const v = params[this.index];\n if (!v) {\n throw new Error(`Parameter missing: ${this.index}`);\n }\n return v as Val;\n }\n}\n\nexport function and(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (\n v1 === scope._false ||\n v1 === scope.zero ||\n v2 == scope._false ||\n v2 == scope.zero\n ) {\n return scope._false;\n }\n if (v1 === scope._true || v1 === scope.one) {\n return v2;\n }\n if (v2 === scope._true || v2 === scope.one) {\n return v1;\n }\n return new And(scope, v1, v2);\n}\n\nexport function add(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return v2;\n }\n if (v2 === scope.zero) {\n return v1;\n }\n return new Add(scope, v1, v2);\n}\n\nexport function sub(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return new Negate(scope, v2);\n }\n if (v2 === scope.zero) {\n return v1;\n }\n return new Subtract(scope, v1, v2);\n}\n\nexport function mul(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero || v2 === scope.zero) {\n return scope.zero;\n }\n if (v1 === scope.one) {\n return v2;\n }\n if (v2 === scope.one) {\n return v1;\n }\n return new Multiply(scope, v1, v2);\n}\n\nexport function div(scope: LexicalScope, v1: Val, v2: Val): Val {\n if (v1 === scope.zero) {\n return scope.zero;\n }\n if (v2 === scope.one) {\n return v1;\n }\n return new Divide(scope, v1, v2);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Css - CSS Values and utilities to handle them.\n */\nimport * as Base from \"./base\";\nimport * as Exprs from \"./exprs\";\n\nexport class Visitor {\n /**\n * @return void\n */\n visitValues(values: Val[]): any {\n for (let i = 0; i < values.length; i++) {\n values[i].visit(this);\n }\n }\n\n visitEmpty(empty: Val): Val {\n throw new Error(\"E_CSS_EMPTY_NOT_ALLOWED\");\n }\n\n visitSlash(slash: Val): Val {\n throw new Error(\"E_CSS_SLASH_NOT_ALLOWED\");\n }\n\n visitStr(str: Str): Val {\n throw new Error(\"E_CSS_STR_NOT_ALLOWED\");\n }\n\n visitIdent(ident: Ident): Val {\n throw new Error(\"E_CSS_IDENT_NOT_ALLOWED\");\n }\n\n visitNumeric(numeric: Numeric): Val {\n throw new Error(\"E_CSS_NUMERIC_NOT_ALLOWED\");\n }\n\n visitNum(num: Num): Val {\n throw new Error(\"E_CSS_NUM_NOT_ALLOWED\");\n }\n\n visitInt(num: Int): Val {\n return this.visitNum(num);\n }\n\n visitColor(color: Color): Val {\n throw new Error(\"E_CSS_COLOR_NOT_ALLOWED\");\n }\n\n visitURL(url: URL): Val {\n throw new Error(\"E_CSS_URL_NOT_ALLOWED\");\n }\n\n visitSpaceList(list: SpaceList): Val {\n throw new Error(\"E_CSS_LIST_NOT_ALLOWED\");\n }\n\n visitCommaList(list: CommaList): Val {\n throw new Error(\"E_CSS_COMMA_NOT_ALLOWED\");\n }\n\n visitFunc(func: Func): Val {\n throw new Error(\"E_CSS_FUNC_NOT_ALLOWED\");\n }\n\n visitExpr(expr: Expr): Val {\n throw new Error(\"E_CSS_EXPR_NOT_ALLOWED\");\n }\n}\n\nexport class FilterVisitor extends Visitor {\n constructor() {\n super();\n }\n\n visitValues(values: Val[]): Val[] {\n let arr: Val[] = null;\n for (let i = 0; i < values.length; i++) {\n const before = values[i];\n const after = before.visit(this);\n if (arr) {\n arr[i] = after;\n } else if (before !== after) {\n arr = new Array(values.length);\n for (let k = 0; k < i; k++) {\n arr[k] = values[k];\n }\n arr[i] = after;\n }\n }\n return arr || values;\n }\n\n /**\n * @override\n */\n visitStr(str: Str): Val {\n return str;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Ident): Val {\n return ident;\n }\n\n /**\n * @override\n */\n visitSlash(slash: Val): Val {\n return slash;\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Numeric): Val {\n return numeric;\n }\n\n /**\n * @override\n */\n visitNum(num: Num): Val {\n return num;\n }\n\n /**\n * @override\n */\n visitInt(num: Int): Val {\n return num;\n }\n\n /**\n * @override\n */\n visitColor(color: Color): Val {\n return color;\n }\n\n /**\n * @override\n */\n visitURL(url: URL): Val {\n return url;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: SpaceList): Val {\n const values = this.visitValues(list.values);\n if (values === list.values) {\n return list;\n }\n return new SpaceList(values);\n }\n\n /**\n * @override\n */\n visitCommaList(list: CommaList): Val {\n const values = this.visitValues(list.values);\n if (values === list.values) {\n return list;\n }\n return new CommaList(values);\n }\n\n /**\n * @override\n */\n visitFunc(func: Func): Val {\n const values = this.visitValues(func.values);\n if (values === func.values) {\n return func;\n }\n return new Func(func.name, values);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Expr): Val {\n return expr;\n }\n}\n\nexport class Val {\n /**\n * @override\n */\n toString(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, true);\n return buf.toString();\n }\n\n stringValue(): string {\n const buf = new Base.StringBuffer();\n this.appendTo(buf, false);\n return buf.toString();\n }\n\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n throw new Error(\"F_ABSTRACT\");\n }\n\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"[error]\");\n }\n\n isExpr(): boolean {\n return false;\n }\n\n isNumeric(): boolean {\n return false;\n }\n\n isNum(): boolean {\n return false;\n }\n\n isIdent(): boolean {\n return false;\n }\n\n isSpaceList(): boolean {\n return false;\n }\n\n visit(visitor: any): any {\n throw new Error(\"F_ABSTRACT\");\n }\n}\n\nexport class Empty extends Val {\n private static empty: Empty;\n\n public static get instance(): Empty {\n if (!this.empty) {\n this.empty = new Empty();\n }\n return this.empty;\n }\n\n private constructor() {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, \"\");\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {}\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitEmpty(this);\n }\n}\n\nexport const empty: Empty = Empty.instance;\n\nexport class Slash extends Val {\n private static slash: Slash;\n\n public static get instance(): Slash {\n if (!this.slash) {\n this.slash = new Slash();\n }\n return this.slash;\n }\n\n private constructor() {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, \"/\");\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"/\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitSlash(this);\n }\n}\n\nexport const slash: Slash = Slash.instance;\n\nexport class Str extends Val {\n constructor(public str: string) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, this.str);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n if (toString) {\n buf.append('\"');\n buf.append(Base.escapeCSSStr(this.str));\n buf.append('\"');\n } else {\n buf.append(this.str);\n }\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitStr(this);\n }\n}\n\nconst nameTable = {};\n\nexport class Ident extends Val {\n constructor(public name: string) {\n super();\n if (nameTable[name]) {\n throw new Error(\"E_INVALID_CALL\");\n }\n nameTable[name] = this;\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n return new Exprs.Const(scope, this.name);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n if (toString) {\n buf.append(Base.escapeCSSIdent(this.name));\n } else {\n buf.append(this.name);\n }\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitIdent(this);\n }\n\n /**\n * @override\n */\n isIdent(): boolean {\n return true;\n }\n}\n\nexport function getName(name: string): Ident {\n let r = nameTable[name];\n if (!r) {\n r = new Ident(name);\n }\n return r;\n}\n\nexport class Numeric extends Val {\n unit: string;\n\n constructor(public num: number, unit: string) {\n super();\n this.unit = unit.toLowerCase(); // units are case-insensitive in CSS\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n if (this.num == 0) {\n return scope.zero;\n }\n if (ref && this.unit == \"%\") {\n if (this.num == 100) {\n return ref;\n }\n return new Exprs.Multiply(\n scope,\n ref,\n new Exprs.Const(scope, this.num / 100),\n );\n }\n return new Exprs.Numeric(scope, this.num, this.unit);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(this.num.toString());\n buf.append(this.unit);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitNumeric(this);\n }\n\n /**\n * @override\n */\n isNumeric(): boolean {\n return true;\n }\n}\n\nexport class Num extends Val {\n constructor(public num: number) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(scope: Exprs.LexicalScope, ref: Exprs.Val): Exprs.Val {\n if (this.num == 0) {\n return scope.zero;\n }\n if (this.num == 1) {\n return scope.one;\n }\n return new Exprs.Const(scope, this.num);\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(this.num.toString());\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitNum(this);\n }\n\n /**\n * @override\n */\n isNum(): boolean {\n return true;\n }\n}\n\nexport class Int extends Num {\n constructor(num: number) {\n super(num);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitInt(this);\n }\n}\n\nexport class Color extends Val {\n constructor(public rgb: number) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"#\");\n const str = this.rgb.toString(16);\n buf.append(\"000000\".substr(str.length));\n buf.append(str);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitColor(this);\n }\n}\n\nexport class URL extends Val {\n constructor(public url: string) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append('url(\"');\n buf.append(Base.escapeCSSStr(this.url));\n buf.append('\")');\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitURL(this);\n }\n}\n\nexport function appendList(\n buf: Base.StringBuffer,\n values: Val[],\n separator: string,\n toString: boolean,\n): void {\n const length = values.length;\n values[0].appendTo(buf, toString);\n for (let i = 1; i < length; i++) {\n buf.append(separator);\n values[i].appendTo(buf, toString);\n }\n}\n\nexport class SpaceList extends Val {\n constructor(public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n appendList(buf, this.values, \" \", toString);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitSpaceList(this);\n }\n\n /**\n * @override\n */\n isSpaceList(): boolean {\n return true;\n }\n}\n\nexport class CommaList extends Val {\n constructor(public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n appendList(buf, this.values, \",\", toString);\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitCommaList(this);\n }\n}\n\nexport class Func extends Val {\n constructor(public name: string, public values: Val[]) {\n super();\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(Base.escapeCSSIdent(this.name));\n buf.append(\"(\");\n appendList(buf, this.values, \",\", toString);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitFunc(this);\n }\n}\n\nexport class Expr extends Val {\n constructor(public expr: Exprs.Val) {\n super();\n }\n\n /**\n * @override\n */\n toExpr(): Exprs.Val {\n return this.expr;\n }\n\n /**\n * @override\n */\n appendTo(buf: Base.StringBuffer, toString: boolean): void {\n buf.append(\"-epubx-expr(\");\n this.expr.appendTo(buf, 0);\n buf.append(\")\");\n }\n\n /**\n * @override\n */\n visit(visitor: any): any {\n return visitor.visitExpr(this);\n }\n\n /**\n * @override\n */\n isExpr(): boolean {\n return true;\n }\n}\n\nexport function toNumber(val: Val, context: Exprs.Context): number {\n if (val) {\n if (val.isNumeric()) {\n const numeric = val as Numeric;\n return context.queryUnitSize(numeric.unit, false) * numeric.num;\n }\n if (val.isNum()) {\n return (val as Num).num;\n }\n }\n return 0;\n}\n\n/**\n * Convert numeric value to px\n */\nexport function convertNumericToPx(val: Val, context: Exprs.Context): Numeric {\n return new Numeric(toNumber(val, context), \"px\");\n}\n\nexport const ident: { [key: string]: Ident } = {\n absolute: getName(\"absolute\"),\n all: getName(\"all\"),\n always: getName(\"always\"),\n auto: getName(\"auto\"),\n avoid: getName(\"avoid\"),\n balance: getName(\"balance\"),\n balance_all: getName(\"balance-all\"),\n block: getName(\"block\"),\n block_end: getName(\"block-end\"),\n block_start: getName(\"block-start\"),\n both: getName(\"both\"),\n bottom: getName(\"bottom\"),\n border_box: getName(\"border-box\"),\n break_all: getName(\"break-all\"),\n break_word: getName(\"break-word\"),\n crop: getName(\"crop\"),\n cross: getName(\"cross\"),\n column: getName(\"column\"),\n exclusive: getName(\"exclusive\"),\n _false: getName(\"false\"),\n fixed: getName(\"fixed\"),\n flex: getName(\"flex\"),\n footnote: getName(\"footnote\"),\n footer: getName(\"footer\"),\n header: getName(\"header\"),\n hidden: getName(\"hidden\"),\n horizontal_tb: getName(\"horizontal-tb\"),\n inherit: getName(\"inherit\"),\n inline: getName(\"inline\"),\n inline_block: getName(\"inline-block\"),\n inline_end: getName(\"inline-end\"),\n inline_start: getName(\"inline-start\"),\n landscape: getName(\"landscape\"),\n left: getName(\"left\"),\n line: getName(\"line\"),\n list_item: getName(\"list-item\"),\n ltr: getName(\"ltr\"),\n manual: getName(\"manual\"),\n none: getName(\"none\"),\n normal: getName(\"normal\"),\n oeb_page_foot: getName(\"oeb-page-foot\"),\n oeb_page_head: getName(\"oeb-page-head\"),\n page: getName(\"page\"),\n relative: getName(\"relative\"),\n right: getName(\"right\"),\n same: getName(\"same\"),\n scale: getName(\"scale\"),\n snap_block: getName(\"snap-block\"),\n spread: getName(\"spread\"),\n _static: getName(\"static\"),\n rtl: getName(\"rtl\"),\n table: getName(\"table\"),\n table_caption: getName(\"table-caption\"),\n table_cell: getName(\"table-cell\"),\n table_footer_group: getName(\"table-footer-group\"),\n table_header_group: getName(\"table-header-group\"),\n table_row: getName(\"table-row\"),\n top: getName(\"top\"),\n transparent: getName(\"transparent\"),\n vertical_lr: getName(\"vertical-lr\"),\n vertical_rl: getName(\"vertical-rl\"),\n visible: getName(\"visible\"),\n _true: getName(\"true\"),\n};\n\nexport const hundredPercent: Numeric = new Numeric(100, \"%\");\n\nexport const fullWidth: Numeric = new Numeric(100, \"pvw\");\n\nexport const fullHeight: Numeric = new Numeric(100, \"pvh\");\n\nexport const numericZero: Numeric = new Numeric(0, \"px\");\n\nexport const processingOrder = {\n \"font-size\": 1,\n color: 2,\n};\n\n/**\n * Function to sort property names in the order they should be processed\n */\nexport function processingOrderFn(name1: string, name2: string): number {\n const n1 = processingOrder[name1] || Number.MAX_VALUE;\n const n2 = processingOrder[name2] || Number.MAX_VALUE;\n return n1 - n2;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview GeometryUtil - Geometric utilities.\n */\nimport * as Logging from \"./logging\";\n\nexport class Rect {\n constructor(\n public x1: number,\n public y1: number,\n public x2: number,\n public y2: number,\n ) {}\n}\n\nexport class Point {\n constructor(public x: number, public y: number) {}\n}\n\nexport class Insets {\n constructor(\n public left: number,\n public top: number,\n public right: number,\n public bottom: number,\n ) {}\n}\n\nexport class Segment {\n constructor(\n public low: Point,\n public high: Point,\n public winding: number,\n public shapeId: number,\n ) {}\n}\n\n/**\n * A single band for exclusion result. Left float is from the left box edge\n * to x1. Right float is from x2 to the right box edge.\n */\nexport class Band {\n /** Left float. */\n left: Element | null = null;\n\n /** Right float. */\n right: Element | null = null;\n\n constructor(\n public y1: number,\n public y2: number,\n public x1: number,\n public x2: number,\n ) {}\n}\n\nexport function segmentCompare(s1: Segment, s2: Segment): number {\n return s1.low.y - s2.low.y || s1.low.x - s2.low.x;\n}\n\nexport class Shape {\n constructor(public points: Point[]) {}\n\n /**\n * Converts this shape to a sequence of Segments and adds segments to the\n * given array.\n * @param arr array to add segments.\n * @param id shapeId to write into segments.\n */\n addSegments(arr: Segment[], id: number): void {\n const points = this.points;\n const length = points.length;\n let prev = points[length - 1];\n for (let i = 0; i < length; i++) {\n const curr = points[i];\n let s: Segment;\n if (prev.y < curr.y) {\n s = new Segment(prev, curr, 1, id);\n } else {\n s = new Segment(curr, prev, -1, id);\n }\n arr.push(s);\n prev = curr;\n }\n }\n\n withOffset(offsetX: number, offsetY: number): Shape {\n const points = [];\n for (const p of this.points) {\n points.push(new Point(p.x + offsetX, p.y + offsetY));\n }\n return new Shape(points);\n }\n}\n\nexport function shapeForEllipse(\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n): Shape {\n const count = 20;\n const points: Point[] = [];\n for (let i = 0; i < count; i++) {\n const a = (i * 2 * Math.PI) / count;\n points.push(new Point(cx + rx * Math.sin(a), cy + ry * Math.cos(a)));\n }\n return new Shape(points);\n}\n\nexport function shapeForRect(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): Shape {\n return new Shape([\n new Point(x1, y1),\n new Point(x2, y1),\n new Point(x2, y2),\n new Point(x1, y2),\n ]);\n}\n\nexport function shapeForRectObj(r: Rect): Shape {\n return new Shape([\n new Point(r.x1, r.y1),\n new Point(r.x2, r.y1),\n new Point(r.x2, r.y2),\n new Point(r.x1, r.y2),\n ]);\n}\n\nexport class BandIntersection {\n constructor(\n public x: number,\n public winding: number,\n public shapeId: number,\n public lowOrHigh: number,\n ) {}\n}\n\nexport function intersectY(s: Segment, y: number): number {\n const x =\n s.low.x + ((s.high.x - s.low.x) * (y - s.low.y)) / (s.high.y - s.low.y);\n if (isNaN(x)) {\n throw new Error(\"Bad intersection\");\n }\n return x;\n}\n\nexport function addBandIntersections(\n intersections: BandIntersection[],\n s: Segment,\n y1: number,\n y2: number,\n): void {\n let x1: number;\n let w1: number;\n let x2: number;\n let w2: number;\n if (s.high.y < y1) {\n Logging.logger.warn(\"Error: inconsistent segment (1)\");\n }\n if (s.low.y <= y1) {\n // outside\n x1 = intersectY(s, y1);\n w1 = s.winding;\n } else {\n x1 = s.low.x;\n w1 = 0;\n }\n if (s.high.y >= y2) {\n // outside\n x2 = intersectY(s, y2);\n w2 = s.winding;\n } else {\n x2 = s.high.x;\n w2 = 0;\n }\n if (x1 < x2) {\n intersections.push(new BandIntersection(x1, w1, s.shapeId, -1));\n intersections.push(new BandIntersection(x2, w2, s.shapeId, 1));\n } else {\n intersections.push(new BandIntersection(x2, w2, s.shapeId, -1));\n intersections.push(new BandIntersection(x1, w1, s.shapeId, 1));\n }\n}\n\nexport function mergeIntersections(\n intersections: BandIntersection[],\n includeCount: number,\n excludeCount: number,\n): number[] {\n const shapeCount = includeCount + excludeCount;\n const windings1: number[] = Array(shapeCount);\n const windings2: number[] = Array(shapeCount);\n let i: number;\n for (i = 0; i <= shapeCount; i++) {\n windings1[i] = 0;\n windings2[i] = 0;\n }\n const xranges: number[] = [];\n let inside: boolean = false;\n const intersectionCount = intersections.length;\n for (let k = 0; k < intersectionCount; k++) {\n const intersection = intersections[k];\n windings1[intersection.shapeId] += intersection.winding;\n windings2[intersection.shapeId] += intersection.lowOrHigh;\n let stillInside = false;\n for (i = 0; i < includeCount; i++) {\n if (windings1[i] && !windings2[i]) {\n stillInside = true;\n break;\n }\n }\n if (stillInside) {\n for (i = includeCount; i <= shapeCount; i++) {\n if (windings1[i] || windings2[i]) {\n stillInside = false;\n break;\n }\n }\n }\n if (inside != stillInside) {\n xranges.push(intersection.x);\n inside = stillInside;\n }\n }\n return xranges;\n}\n\n/**\n * Round v up to make it a multiple of unit. If unit is zero, return v.\n */\nexport function ceil(v: number, unit: number): number {\n return unit ? Math.ceil(v / unit) * unit : v;\n}\n\n/**\n * Round v down to make it a multiple of unit. If unit is zero, return v.\n */\nexport function floor(v: number, unit: number): number {\n return unit ? Math.floor(v / unit) * unit : v;\n}\n\nexport function rotatePoint(point: Point): Point {\n return new Point(point.y, -point.x);\n}\n\n/**\n * Vertical box to pseudo-horizontal coords.\n */\nexport function rotateBox(box: Rect): Rect {\n return new Rect(box.y1, -box.x2, box.y2, -box.x1);\n}\n\n/**\n * Pseudo-horizontal coords to vertical.\n */\nexport function unrotateBox(box: Rect): Rect {\n return new Rect(-box.y2, box.x1, -box.y1, box.x2);\n}\n\nexport function rotateShape(shape: Shape): Shape {\n return new Shape(shape.points.map((point) => rotatePoint(point)));\n}\n\nexport function shapesToBands(\n box: Rect,\n include: Shape[],\n exclude: Shape[],\n granularity: number,\n snapHeight: number,\n vertical: boolean,\n): Band[] {\n if (vertical) {\n box = rotateBox(box);\n include = include.map((shape) => rotateShape(shape));\n exclude = exclude.map((shape) => rotateShape(shape));\n }\n const includeCount = include.length;\n const excludeCount = exclude ? exclude.length : 0;\n const result: Band[] = [];\n const segments: Segment[] = [];\n let i: number;\n let k: number;\n let segment: Segment;\n for (i = 0; i < includeCount; i++) {\n include[i].addSegments(segments, i);\n }\n for (i = 0; i < excludeCount; i++) {\n exclude[i].addSegments(segments, i + includeCount);\n }\n const segmentCount = segments.length;\n segments.sort(segmentCompare);\n let lowestIncludeIndex = 0;\n while (segments[lowestIncludeIndex].shapeId >= includeCount) {\n lowestIncludeIndex++;\n }\n let y = segments[lowestIncludeIndex].low.y;\n if (y > box.y1) {\n result.push(new Band(box.y1, y, box.x2, box.x2));\n }\n let segmentIndex = 0;\n const activeSegments: Segment[] = [];\n while (\n segmentIndex < segmentCount &&\n (segment = segments[segmentIndex]).low.y < y\n ) {\n if (segment.high.y > y) {\n activeSegments.push(segment);\n }\n segmentIndex++;\n }\n\n // process the segments from low to high y values\n while (segmentIndex < segmentCount || activeSegments.length > 0) {\n // calculate the height of the band to work with\n let y2 = box.y2; // band bottom\n // min possible y2\n const y2min = Math.min(\n ceil(Math.ceil(y + granularity), snapHeight),\n box.y2,\n );\n for (k = 0; k < activeSegments.length && y2 > y2min; k++) {\n segment = activeSegments[k];\n if (segment.low.x == segment.high.x) {\n // vertical\n if (segment.high.y < y2) {\n y2 = Math.max(floor(segment.high.y, snapHeight), y2min);\n }\n } else if (segment.low.x != segment.high.x) {\n // TODO: should we compare y???\n // slanted (not horizontal)\n y2 = y2min;\n }\n }\n if (y2 > box.y2) {\n y2 = box.y2;\n }\n\n // include new segments, decreasing y2 if needed\n while (\n segmentIndex < segmentCount &&\n (segment = segments[segmentIndex]).low.y < y2\n ) {\n if (segment.high.y < y) {\n segmentIndex++;\n continue;\n }\n if (segment.low.y < y2min) {\n if (segment.low.y == segment.high.y && segment.low.y == y) {\n // Horizontal segment that goes right at y is not active,\n // but consume it anyway\n } else {\n activeSegments.push(segment);\n y2 = y2min;\n }\n segmentIndex++;\n } else {\n // Do not consume it, consider bottom edge \"outside\"\n const yn = floor(segment.low.y, snapHeight);\n if (yn < y2) {\n y2 = yn;\n }\n break;\n }\n }\n\n // now look at the band with top at y and bottom at y2\n // activeSegments should list all segments that intersect that band\n\n // find all intersections with the band\n const bandIntersections: BandIntersection[] = [];\n for (k = 0; k < activeSegments.length; k++) {\n addBandIntersections(bandIntersections, activeSegments[k], y, y2);\n }\n bandIntersections.sort(\n (bi1, bi2) => bi1.x - bi2.x || bi1.lowOrHigh - bi2.lowOrHigh,\n );\n const xranges = mergeIntersections(\n bandIntersections,\n includeCount,\n excludeCount,\n );\n if (xranges.length == 0) {\n result.push(new Band(y, y2, box.x2, box.x2));\n } else {\n // get the widest\n let width = 0;\n let x = box.x1;\n for (k = 0; k < xranges.length; k += 2) {\n const rx = Math.max(box.x1, xranges[k]);\n const rw = Math.min(box.x2, xranges[k + 1]) - rx;\n if (rw > width) {\n width = rw;\n x = rx;\n }\n }\n if (width == 0) {\n // no space left\n result.push(new Band(y, y2, box.x2, box.x2));\n } else {\n result.push(\n new Band(y, y2, Math.max(x, box.x1), Math.min(x + width, box.x2)),\n );\n }\n }\n if (y2 == box.y2) {\n break;\n }\n y = y2;\n for (k = activeSegments.length - 1; k >= 0; k--) {\n if (activeSegments[k].high.y <= y2) {\n activeSegments.splice(k, 1);\n }\n }\n }\n normalize(box, result);\n return result;\n}\n\nexport function normalize(box: Rect, bands: Band[]): void {\n let k = bands.length - 1;\n\n // Merge bands with the same x1, x2 and remove unneeded bands at the end.\n // Create fictious last band to merge unneeded bands at the end\n let currBand = new Band(box.y2, box.y2, box.x1, box.x2);\n while (k >= 0) {\n const prevBand = currBand; // result[k+1]\n currBand = bands[k];\n if (\n currBand.y2 - currBand.y1 < 1 || // Remove bands with height less than 1px\n (currBand.x1 == prevBand.x1 && currBand.x2 == prevBand.x2)\n ) {\n prevBand.y1 = currBand.y1; // merge\n bands.splice(k, 1);\n currBand = prevBand;\n }\n k--;\n }\n}\n\n/**\n * Find the index of the bottommost band so that y < band.y2\n */\nexport function findBand(bands: Band[], y: number): number {\n let low = 0;\n let high = bands.length;\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n if (y >= bands[mid].y2) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n}\n\n/**\n * Find the uppermost rectangle contained in the specified rect which occupies\n * full width of the rect without overlapping with any band in the specified\n * bands.\n * @returns Returns null if such rectangle does not exist.\n */\nexport function findUppermostFullyOpenRect(\n bands: Band[],\n rect: Rect,\n): Rect | null {\n if (!bands.length) {\n return rect;\n }\n let topEdge = rect.y1;\n let band: Band;\n let i: number;\n for (i = 0; i < bands.length; i++) {\n band = bands[i];\n if (\n band.y2 > rect.y1 &&\n band.x1 - 0.1 <= rect.x1 &&\n band.x2 + 0.1 >= rect.x2\n ) {\n break;\n } else {\n topEdge = Math.max(topEdge, band.y2);\n }\n }\n let bottomEdge = topEdge;\n for (; i < bands.length; i++) {\n band = bands[i];\n if (\n band.y1 >= rect.y2 ||\n band.x1 - 0.1 > rect.x1 ||\n band.x2 + 0.1 < rect.x2\n ) {\n break;\n } else {\n bottomEdge = band.y2;\n }\n }\n if (i === bands.length) {\n bottomEdge = rect.y2;\n } else {\n bottomEdge = Math.min(bottomEdge, rect.y2);\n }\n if (bottomEdge <= topEdge) {\n return null;\n } else {\n return new Rect(rect.x1, topEdge, rect.x2, bottomEdge);\n }\n}\n\n/**\n * Find the bottommost rectangle contained in the specified rect which occupies\n * full width of the rect without overlapping with any band in the specified\n * bands.\n * @returns Returns null if such rectangle does not exist.\n */\nexport function findBottommostFullyOpenRect(\n bands: Band[],\n rect: Rect,\n): Rect | null {\n if (!bands.length) {\n return rect;\n }\n let bottomEdge = rect.y2;\n let band: Band;\n let i: number;\n for (i = bands.length - 1; i >= 0; i--) {\n band = bands[i];\n if (i === bands.length - 1 && band.y2 < rect.y2) {\n break;\n } else if (\n band.y1 < rect.y2 &&\n band.x1 - 0.1 <= rect.x1 &&\n band.x2 + 0.1 >= rect.x2\n ) {\n break;\n } else {\n bottomEdge = Math.min(bottomEdge, band.y1);\n }\n }\n let topEdge = Math.min(bottomEdge, band.y2);\n for (; i >= 0; i--) {\n band = bands[i];\n if (\n band.y2 <= rect.y1 ||\n band.x1 - 0.1 > rect.x1 ||\n band.x2 + 0.1 < rect.x2\n ) {\n break;\n } else {\n topEdge = band.y1;\n }\n }\n topEdge = Math.max(topEdge, rect.y1);\n if (bottomEdge <= topEdge) {\n return null;\n } else {\n return new Rect(rect.x1, topEdge, rect.x2, bottomEdge);\n }\n}\n\n/**\n * @param side either \"left\" or \"right\"\n */\nexport function positionFloat(\n box: Rect,\n bands: Band[],\n floatBox: Rect,\n side: string,\n): boolean {\n let y = floatBox.y1;\n const floatWidth = floatBox.x2 - floatBox.x1;\n const floatHeight = floatBox.y2 - floatBox.y1;\n let index = findBand(bands, y);\n while (true) {\n // Check if it fits\n const floatBottom = y + floatHeight;\n if (floatBottom > box.y2) {\n return false;\n }\n\n // does not fit vertically\n let x1 = box.x1;\n let x2 = box.x2;\n for (let i = index; i < bands.length && bands[i].y1 < floatBottom; i++) {\n const band = bands[i];\n if (band.x1 > x1) {\n x1 = band.x1;\n }\n if (band.x2 < x2) {\n x2 = band.x2;\n }\n }\n if (x1 + floatWidth <= x2 || index >= bands.length) {\n if (side == \"left\") {\n floatBox.x1 = x1;\n floatBox.x2 = x1 + floatWidth;\n } else {\n floatBox.x1 = x2 - floatWidth;\n floatBox.x2 = x2;\n }\n floatBox.y2 += y - floatBox.y1;\n floatBox.y1 = y;\n return true;\n }\n y = bands[index].y2;\n index++;\n }\n}\n\nexport function addFloatToBands(\n box: Rect,\n bands: Band[],\n floatBox: Rect,\n floatBands: Band[],\n side: string,\n): void {\n if (!floatBands) {\n floatBands = [new Band(floatBox.y1, floatBox.y2, floatBox.x1, floatBox.x2)];\n }\n while (floatBands.length > 0 && floatBands[0].y2 <= box.y1) {\n floatBands.shift();\n }\n if (floatBands.length == 0) {\n return;\n }\n if (floatBands[0].y1 < box.y1) {\n floatBands[0].y1 = box.y1;\n }\n let band: Band;\n const lastY = bands.length == 0 ? box.y1 : bands[bands.length - 1].y2;\n if (lastY < box.y2) {\n // add the tail band that we typically don't keep, it will be cleared by\n // normalize()\n bands.push(new Band(lastY, box.y2, box.x1, box.x2));\n }\n let index = findBand(bands, floatBands[0].y1);\n for (const floatBand of floatBands) {\n if (index == bands.length) {\n break;\n }\n if (bands[index].y1 < floatBand.y1) {\n // split it\n band = bands[index];\n index++;\n bands.splice(index, 0, new Band(floatBand.y1, band.y2, band.x1, band.x2));\n band.y2 = floatBand.y1;\n }\n while (index < bands.length) {\n band = bands[index++];\n if (band.y2 > floatBand.y2) {\n // split it\n bands.splice(\n index,\n 0,\n new Band(floatBand.y2, band.y2, band.x1, band.x2),\n );\n band.y2 = floatBand.y2;\n }\n if (floatBand.x1 != floatBand.x2) {\n // non-empty floatBand\n if (side == \"left\") {\n band.x1 = Math.min(floatBand.x2, box.x2);\n } else {\n band.x2 = Math.max(floatBand.x1, box.x1);\n }\n }\n if (band.y2 == floatBand.y2) {\n break;\n }\n }\n }\n normalize(box, bands);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssProp - Support utilities to extract information\n * from various (parsed) CSS values.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Logging from \"./logging\";\n\n//---------------------- value parsers ----------------------------------\nexport class SetVisitor extends Css.Visitor {\n propSet: { [key: string]: boolean } = {};\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n this.propSet[ident.name] = true;\n return ident;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return list;\n }\n}\n\nexport function toSet(val: Css.Val): { [key: string]: boolean } {\n if (val) {\n const visitor = new SetVisitor();\n try {\n val.visit(visitor);\n return visitor.propSet;\n } catch (err) {\n Logging.logger.warn(err, \"toSet:\");\n }\n }\n return {};\n}\n\nexport class IntVisitor extends Css.Visitor {\n constructor(public value: number) {\n super();\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n this.value = num.num;\n return num;\n }\n}\n\nexport function toInt(val: Css.Val, def: number): number {\n if (val) {\n const visitor = new IntVisitor(def);\n try {\n val.visit(visitor);\n return visitor.value;\n } catch (err) {\n Logging.logger.warn(err, \"toInt: \");\n }\n }\n return def;\n}\n\nexport class ShapeVisitor extends Css.Visitor {\n collect: boolean = false;\n coords: Css.Numeric[] = [];\n name: string | null = null;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n if (this.collect) {\n this.coords.push(numeric);\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n if (this.collect && num.num == 0) {\n this.coords.push(new Css.Numeric(0, \"px\"));\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (!this.collect) {\n this.collect = true;\n this.visitValues(func.values);\n this.collect = false;\n this.name = func.name.toLowerCase();\n }\n return null;\n }\n\n getShape(\n x: number,\n y: number,\n width: number,\n height: number,\n context: Exprs.Context,\n ): GeometryUtil.Shape {\n if (this.coords.length > 0) {\n const numbers: number[] = [];\n this.coords.forEach((coord, i) => {\n if (coord.unit == \"%\") {\n let ref = i % 2 == 0 ? width : height;\n if (i == 3 && this.name == \"circle\") {\n ref = Math.sqrt((width * width + height * height) / 2);\n }\n numbers.push((coord.num * ref) / 100);\n } else {\n numbers.push(coord.num * context.queryUnitSize(coord.unit, false));\n }\n });\n switch (this.name) {\n case \"polygon\":\n if (numbers.length % 2 == 0) {\n const points: GeometryUtil.Point[] = [];\n for (let k = 0; k < numbers.length; k += 2) {\n points.push(\n new GeometryUtil.Point(x + numbers[k], y + numbers[k + 1]),\n );\n }\n return new GeometryUtil.Shape(points);\n }\n break;\n case \"rectangle\":\n if (numbers.length == 4) {\n return GeometryUtil.shapeForRect(\n x + numbers[0],\n y + numbers[1],\n x + numbers[0] + numbers[2],\n y + numbers[1] + numbers[3],\n );\n }\n break;\n case \"ellipse\":\n if (numbers.length == 4) {\n return GeometryUtil.shapeForEllipse(\n x + numbers[0],\n y + numbers[1],\n numbers[2],\n numbers[3],\n );\n }\n break;\n case \"circle\":\n if (numbers.length == 3) {\n return GeometryUtil.shapeForEllipse(\n x + numbers[0],\n y + numbers[1],\n numbers[2],\n numbers[2],\n );\n }\n break;\n }\n }\n return null;\n }\n}\n\nexport function toShape(\n val: Css.Val,\n x: number,\n y: number,\n width: number,\n height: number,\n context: Exprs.Context,\n): GeometryUtil.Shape {\n if (val) {\n const visitor = new ShapeVisitor();\n try {\n val.visit(visitor);\n return visitor.getShape(x, y, width, height, context);\n } catch (err) {\n Logging.logger.warn(err, \"toShape:\");\n }\n }\n return GeometryUtil.shapeForRect(x, y, x + width, y + height);\n}\n\nexport class CountersVisitor extends Css.Visitor {\n counters: { [key: string]: number } = {};\n name: string | null = null;\n\n constructor(public readonly reset: boolean) {\n super();\n }\n\n /** @override */\n visitIdent(ident: Css.Ident): Css.Val {\n this.name = ident.toString();\n if (this.reset) {\n this.counters[this.name] = 0;\n } else {\n this.counters[this.name] = (this.counters[this.name] || 0) + 1;\n }\n return ident;\n }\n\n /** @override */\n visitInt(num: Css.Int): Css.Val {\n if (this.name) {\n this.counters[this.name] += num.num - (this.reset ? 0 : 1);\n }\n return num;\n }\n\n /** @override */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return list;\n }\n}\n\nexport function toCounters(\n val: Css.Val,\n reset: boolean,\n): { [key: string]: number } {\n const visitor = new CountersVisitor(reset);\n try {\n val.visit(visitor);\n } catch (err) {\n Logging.logger.warn(err, \"toCounters:\");\n }\n return visitor.counters;\n}\n\nexport class UrlTransformVisitor extends Css.FilterVisitor {\n constructor(\n public baseUrl: string,\n public transformer: Base.DocumentURLTransformer,\n ) {\n super();\n }\n\n /** @override */\n visitURL(url: Css.URL): Css.Val {\n return new Css.URL(this.transformer.transformURL(url.url, this.baseUrl));\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Counters\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Exprs from \"./exprs\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\n/**\n * Clone counter values.\n */\nfunction cloneCounterValues(\n counters: CssCascade.CounterValues,\n): CssCascade.CounterValues {\n const result = {};\n Object.keys(counters).forEach((name) => {\n result[name] = Array.from(counters[name]);\n });\n return result;\n}\n\n/**\n * Class representing a reference by target-counter(s).\n * @param targetId ID of the referenced element (transformed by\n * DocumentURLTransformer to handle a reference across multiple source\n * documents)\n * @param resolved If the reference is already resolved or not\n */\nexport class TargetCounterReference {\n pageCounters: CssCascade.CounterValues = null;\n spineIndex: number = -1;\n pageIndex: number = -1;\n\n constructor(public readonly targetId: string, public resolved: boolean) {}\n\n equals(other: TargetCounterReference): boolean {\n if (this === other) {\n return true;\n }\n if (!other) {\n return false;\n }\n return (\n this.targetId === other.targetId &&\n this.resolved === other.resolved &&\n this.spineIndex === other.spineIndex &&\n this.pageIndex === other.pageIndex\n );\n }\n\n /**\n * Returns if the reference is resolved or not.\n */\n isResolved(): boolean {\n return this.resolved;\n }\n\n /**\n * Marks that this reference is resolved.\n */\n resolve() {\n this.resolved = true;\n }\n\n /**\n * Marks that this reference is unresolved.\n */\n unresolve() {\n this.resolved = false;\n }\n}\n\nclass CounterListener implements CssCascade.CounterListener {\n constructor(\n public readonly counterStore: CounterStore,\n public readonly baseURL: string,\n ) {}\n\n /**\n * @override\n */\n countersOfId(id: string, counters: CssCascade.CounterValues) {\n id = this.counterStore.documentURLTransformer.transformFragment(\n id,\n this.baseURL,\n );\n this.counterStore.countersById[id] = counters;\n }\n\n getExprContentListener(): Vtree.ExprContentListener {\n return this.counterStore.getExprContentListener();\n }\n}\n\nclass CounterResolver implements CssCascade.CounterResolver {\n styler: CssStyler.Styler | null = null;\n\n constructor(\n public readonly counterStore: CounterStore,\n public readonly baseURL: string,\n public readonly rootScope: Exprs.LexicalScope,\n public readonly pageScope: Exprs.LexicalScope,\n ) {}\n\n setStyler(styler: CssStyler.Styler) {\n this.styler = styler;\n }\n\n private getFragment(url: string): string | null {\n const r = url.match(/^[^#]*#(.*)$/);\n return r ? r[1] : null;\n }\n\n private getTransformedId(url: string): string {\n let transformedId = this.counterStore.documentURLTransformer.transformURL(\n Base.resolveURL(url, this.baseURL),\n this.baseURL,\n );\n if (transformedId.charAt(0) === \"#\") {\n transformedId = transformedId.substring(1);\n }\n return transformedId;\n }\n\n /**\n * @override\n */\n getPageCounterVal(\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val {\n const self = this;\n\n function getCounterNumber() {\n const values = self.counterStore.currentPageCounters[name];\n return values && values.length ? values[values.length - 1] : null;\n }\n const expr = new Exprs.Native(\n this.pageScope,\n () => format(getCounterNumber()),\n `page-counter-${name}`,\n );\n\n function arrayFormat(arr) {\n return format(arr[0]);\n }\n this.counterStore.registerPageCounterExpr(name, arrayFormat, expr);\n return expr;\n }\n\n /**\n * @override\n */\n getPageCountersVal(\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val {\n const self = this;\n\n function getCounterNumbers() {\n return self.counterStore.currentPageCounters[name] || [];\n }\n const expr = new Exprs.Native(\n this.pageScope,\n () => format(getCounterNumbers()),\n `page-counters-${name}`,\n );\n this.counterStore.registerPageCounterExpr(name, format, expr);\n return expr;\n }\n\n /**\n * Returns (non page-based) counter values for an element with the specified\n * ID. Returns null if the style of the elements has not been calculated yet\n * (i.e. the element does not exit or it is in a source document which is not\n * loaded yet).\n * @param id Original ID value\n * @param transformedId ID transformed by DocumentURLTransformer to handle a\n * reference across multiple source documents\n * @param lookForElement If true, look ahead for an element with the ID in the\n * current source document when such an element has not appeared yet. Do\n * not set to true during Styler.styleUntil is being called, since in that\n * case Styler.styleUntil can be called again and may lead to internal\n * inconsistency.\n */\n private getTargetCounters(\n id: string | null,\n transformedId: string,\n lookForElement: boolean,\n ): CssCascade.CounterValues | null {\n let targetCounters = this.counterStore.countersById[transformedId];\n if (!targetCounters && lookForElement && id) {\n this.styler.styleUntilIdIsReached(id);\n targetCounters = this.counterStore.countersById[transformedId];\n }\n return targetCounters || null;\n }\n\n /**\n * Returns page-based counter values for an element with the specified ID.\n * Returns null if the element has not been laid out yet.\n * @param transformedId ID transformed by DocumentURLTransformer to handle a\n * reference across multiple source documents\n */\n private getTargetPageCounters(\n transformedId: string,\n ): CssCascade.CounterValues | null {\n if (this.counterStore.currentPage.elementsById[transformedId]) {\n return this.counterStore.currentPageCounters;\n } else {\n return this.counterStore.pageCountersById[transformedId] || null;\n }\n }\n\n /**\n * @override\n */\n getTargetCounterVal(\n url: string,\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val {\n const id = this.getFragment(url);\n const transformedId = this.getTransformedId(url);\n\n // Since this method is executed during Styler.styleUntil is being called,\n // set false to lookForElement argument.\n let counters = this.getTargetCounters(id, transformedId, false);\n if (counters && counters[name]) {\n // Since an element-based counter is defined, any page-based counter is\n // obscured even if it exists.\n const countersOfName = counters[name];\n return new Exprs.Const(\n this.rootScope,\n format(countersOfName[countersOfName.length - 1] || null),\n );\n }\n const self = this;\n return new Exprs.Native(\n this.pageScope,\n () => {\n // Since This block is evaluated during layout, lookForElement\n // argument can be set to true.\n counters = self.getTargetCounters(id, transformedId, true);\n\n if (counters) {\n if (counters[name]) {\n // Since an element-based counter is defined, any page-based\n // counter is obscured even if it exists.\n const countersOfName = counters[name];\n return format(countersOfName[countersOfName.length - 1] || null);\n } else {\n const pageCounters = self.getTargetPageCounters(transformedId);\n if (pageCounters) {\n // The target element has already been laid out.\n self.counterStore.resolveReference(transformedId);\n if (pageCounters[name]) {\n const pageCountersOfName = pageCounters[name];\n return format(\n pageCountersOfName[pageCountersOfName.length - 1] || null,\n );\n } else {\n // No corresponding counter with the name.\n return format(0);\n }\n } else {\n // The target element has not been laid out yet.\n self.counterStore.saveReferenceOfCurrentPage(\n transformedId,\n false,\n );\n return \"??\"; // TODO more reasonable placeholder?\n }\n }\n } else {\n // The style of target element has not been calculated yet.\n // (The element is in another source document that is not parsed\n // yet)\n self.counterStore.saveReferenceOfCurrentPage(transformedId, false);\n return \"??\"; // TODO more reasonable placeholder?\n }\n },\n `target-counter-${name}-of-${url}`,\n );\n }\n\n /**\n * @override\n */\n getTargetCountersVal(\n url: string,\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val {\n const id = this.getFragment(url);\n const transformedId = this.getTransformedId(url);\n const self = this;\n return new Exprs.Native(\n this.pageScope,\n () => {\n const pageCounters = self.getTargetPageCounters(transformedId);\n\n if (!pageCounters) {\n // The target element has not been laid out yet.\n self.counterStore.saveReferenceOfCurrentPage(transformedId, false);\n return \"??\"; // TODO more reasonable placeholder?\n } else {\n self.counterStore.resolveReference(transformedId);\n const pageCountersOfName = pageCounters[name] || [];\n const elementCounters = self.getTargetCounters(\n id,\n transformedId,\n true,\n );\n const elementCountersOfName = elementCounters[name] || [];\n return format(pageCountersOfName.concat(elementCountersOfName));\n }\n },\n `target-counters-${name}-of-${url}`,\n );\n }\n}\n\nexport class CounterStore {\n countersById: { [key: string]: CssCascade.CounterValues } = {};\n pageCountersById: { [key: string]: CssCascade.CounterValues } = {};\n currentPageCounters: CssCascade.CounterValues = {};\n previousPageCounters: CssCascade.CounterValues = {};\n currentPageCountersStack: CssCascade.CounterValues[] = [];\n pageIndicesById: {\n [key: string]: { spineIndex: number; pageIndex: number };\n } = {};\n currentPage: Vtree.Page = null;\n newReferencesOfCurrentPage: TargetCounterReference[] = [];\n referencesToSolve: TargetCounterReference[] = [];\n referencesToSolveStack: TargetCounterReference[][] = [];\n unresolvedReferences: { [key: string]: TargetCounterReference[] } = {};\n resolvedReferences: { [key: string]: TargetCounterReference[] } = {};\n private pagesCounterExprs: {\n expr: Exprs.Val;\n format: (p1: number[]) => string;\n }[] = [];\n\n constructor(\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n ) {\n this.currentPageCounters[\"page\"] = [0];\n }\n\n createCounterListener(baseURL: string): CssCascade.CounterListener {\n return new CounterListener(this, baseURL);\n }\n\n createCounterResolver(\n baseURL: string,\n rootScope: Exprs.LexicalScope,\n pageScope: Exprs.LexicalScope,\n ): CssCascade.CounterResolver {\n return new CounterResolver(this, baseURL, rootScope, pageScope);\n }\n\n setCurrentPage(page: Vtree.Page) {\n this.currentPage = page;\n }\n\n private definePageCounter(counterName: string, value: number) {\n if (this.currentPageCounters[counterName]) {\n this.currentPageCounters[counterName].push(value);\n } else {\n this.currentPageCounters[counterName] = [value];\n }\n }\n\n /**\n * Forcefully set the `page` page-based counter to the specified value.\n */\n forceSetPageCounter(pageNumber: number) {\n const counters = this.currentPageCounters[\"page\"];\n if (!counters || !counters.length) {\n this.currentPageCounters[\"page\"] = [pageNumber];\n } else {\n counters[counters.length - 1] = pageNumber;\n }\n }\n\n /**\n * Update the page-based counters with 'counter-reset' and 'counter-increment'\n * properties within the page context. Call before starting layout of the\n * page.\n */\n updatePageCounters(\n cascadedPageStyle: CssCascade.ElementStyle,\n context: Exprs.Context,\n ) {\n // Save page counters to previousPageCounters before updating\n this.previousPageCounters = cloneCounterValues(this.currentPageCounters);\n let resetMap: { [key: string]: number };\n const reset = cascadedPageStyle[\"counter-reset\"];\n if (reset) {\n const resetVal = reset.evaluate(context);\n if (resetVal) {\n resetMap = CssProp.toCounters(resetVal, true);\n }\n }\n if (resetMap) {\n for (const resetCounterName in resetMap) {\n this.definePageCounter(resetCounterName, resetMap[resetCounterName]);\n }\n }\n let incrementMap: { [key: string]: number };\n const increment = cascadedPageStyle[\"counter-increment\"];\n if (increment) {\n const incrementVal = increment.evaluate(context);\n if (incrementVal) {\n incrementMap = CssProp.toCounters(incrementVal, false);\n }\n }\n\n // If 'counter-increment' for the builtin 'page' counter is absent, add it\n // with value 1.\n if (incrementMap) {\n if (!(\"page\" in incrementMap)) {\n incrementMap[\"page\"] = 1;\n }\n } else {\n incrementMap = {};\n incrementMap[\"page\"] = 1;\n }\n for (const incrementCounterName in incrementMap) {\n if (!this.currentPageCounters[incrementCounterName]) {\n this.definePageCounter(incrementCounterName, 0);\n }\n const counterValues = this.currentPageCounters[incrementCounterName];\n counterValues[counterValues.length - 1] +=\n incrementMap[incrementCounterName];\n }\n }\n\n /**\n * Save current page-based counters values and set them to the values passed\n * in. The saved counter values can be restored by popPageCounters method.\n */\n pushPageCounters(counters: CssCascade.CounterValues) {\n this.currentPageCountersStack.push(this.currentPageCounters);\n this.currentPageCounters = cloneCounterValues(counters);\n }\n\n /**\n * Restore previously saved page-based counter values.\n */\n popPageCounters() {\n this.currentPageCounters = this.currentPageCountersStack.pop();\n }\n\n /**\n * Resolve a reference with the specified ID.\n */\n resolveReference(id: string) {\n const unresolvedRefs = this.unresolvedReferences[id];\n let resolvedRefs = this.resolvedReferences[id];\n if (!resolvedRefs) {\n resolvedRefs = this.resolvedReferences[id] = [];\n }\n let pushed = false;\n for (let i = 0; i < this.referencesToSolve.length; ) {\n const ref = this.referencesToSolve[i];\n if (ref.targetId === id) {\n ref.resolve();\n this.referencesToSolve.splice(i, 1);\n if (unresolvedRefs) {\n const j = unresolvedRefs.indexOf(ref);\n if (j >= 0) {\n unresolvedRefs.splice(j, 1);\n }\n }\n resolvedRefs.push(ref);\n pushed = true;\n } else {\n i++;\n }\n }\n if (!pushed) {\n this.saveReferenceOfCurrentPage(id, true);\n }\n }\n\n /**\n * Save a reference appeared in the current page.\n * @param resolved If the reference is already resolved or not.\n */\n saveReferenceOfCurrentPage(id: string, resolved: boolean) {\n if (!this.newReferencesOfCurrentPage.some((ref) => ref.targetId === id)) {\n const ref = new TargetCounterReference(id, resolved);\n this.newReferencesOfCurrentPage.push(ref);\n }\n }\n\n /**\n * Finish the current page; elements with ID are collected and saved with\n * current page-based counter values internally.\n * @param spineIndex Index of the currently laid out spine item\n * @param pageIndex Index of the currently laid out page in its spine item\n */\n finishPage(spineIndex: number, pageIndex: number) {\n const ids = Object.keys(this.currentPage.elementsById);\n if (ids.length > 0) {\n const currentPageCounters = cloneCounterValues(this.currentPageCounters);\n ids.forEach((id) => {\n this.pageCountersById[id] = currentPageCounters;\n const oldPageIndex = this.pageIndicesById[id];\n if (oldPageIndex && oldPageIndex.pageIndex < pageIndex) {\n const resolvedRefs = this.resolvedReferences[id];\n if (resolvedRefs) {\n let unresolvedRefs = this.unresolvedReferences[id];\n if (!unresolvedRefs) {\n unresolvedRefs = this.unresolvedReferences[id] = [];\n }\n let ref: TargetCounterReference;\n while ((ref = resolvedRefs.shift())) {\n ref.unresolve();\n unresolvedRefs.push(ref);\n }\n }\n }\n this.pageIndicesById[id] = { spineIndex, pageIndex };\n });\n }\n const prevPageCounters = this.previousPageCounters;\n let ref: TargetCounterReference;\n while ((ref = this.newReferencesOfCurrentPage.shift())) {\n ref.pageCounters = prevPageCounters;\n ref.spineIndex = spineIndex;\n ref.pageIndex = pageIndex;\n let arr: TargetCounterReference[];\n if (ref.isResolved()) {\n arr = this.resolvedReferences[ref.targetId];\n if (!arr) {\n arr = this.resolvedReferences[ref.targetId] = [];\n }\n } else {\n arr = this.unresolvedReferences[ref.targetId];\n if (!arr) {\n arr = this.unresolvedReferences[ref.targetId] = [];\n }\n }\n if (arr.every((r) => !ref.equals(r))) {\n arr.push(ref);\n }\n }\n this.currentPage = null;\n }\n\n /**\n * Returns unresolved references pointing to the specified page.\n */\n getUnresolvedRefsToPage(\n page: Vtree.Page,\n ): {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n }[] {\n let refs: TargetCounterReference[] = [];\n const ids = Object.keys(page.elementsById);\n ids.forEach((id) => {\n const idRefs = this.unresolvedReferences[id];\n if (idRefs) {\n refs = refs.concat(idRefs);\n }\n });\n refs.sort(\n (r1, r2) => r1.spineIndex - r2.spineIndex || r1.pageIndex - r2.pageIndex,\n );\n const result: {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n }[] = [];\n let o: {\n spineIndex: number;\n pageIndex: number;\n pageCounters: CssCascade.CounterValues;\n refs: TargetCounterReference[];\n } = null;\n refs.forEach((ref) => {\n if (\n !o ||\n o.spineIndex !== ref.spineIndex ||\n o.pageIndex !== ref.pageIndex\n ) {\n o = {\n spineIndex: ref.spineIndex,\n pageIndex: ref.pageIndex,\n pageCounters: ref.pageCounters,\n refs: [ref],\n };\n result.push(o);\n } else {\n o.refs.push(ref);\n }\n });\n return result;\n }\n\n /**\n * Save current references to solve and set them to the values passed in.\n * The saved references can be restored by popReferencesToSolve method.\n */\n pushReferencesToSolve(refs: TargetCounterReference[]) {\n this.referencesToSolveStack.push(this.referencesToSolve);\n this.referencesToSolve = refs;\n }\n\n /**\n * Restore previously saved references to solve.\n */\n popReferencesToSolve() {\n this.referencesToSolve = this.referencesToSolveStack.pop();\n }\n\n registerPageCounterExpr(\n name: string,\n format: (p1: number[]) => string,\n expr: Exprs.Val,\n ) {\n if (name === \"pages\") {\n this.pagesCounterExprs.push({ expr, format });\n }\n }\n\n getExprContentListener(): Vtree.ExprContentListener {\n return this.exprContentListener.bind(this);\n }\n\n private exprContentListener(expr, val, document) {\n const found = this.pagesCounterExprs.findIndex((o) => o.expr === expr) >= 0;\n if (found) {\n const node = document.createElement(\"span\");\n node.textContent = val;\n node.setAttribute(PAGES_COUNTER_ATTR, expr.key);\n return node;\n } else {\n return null;\n }\n }\n\n finishLastPage(viewport: Vgen.Viewport) {\n const nodes = viewport.root.querySelectorAll(`[${PAGES_COUNTER_ATTR}]`);\n const pages = this.currentPageCounters[\"page\"][0];\n Array.from(nodes).forEach((node) => {\n const key = node.getAttribute(PAGES_COUNTER_ATTR);\n const i = this.pagesCounterExprs.findIndex((o) => o.expr.key === key);\n Asserts.assert(i >= 0);\n node.textContent = this.pagesCounterExprs[i].format([pages]);\n });\n }\n\n createLayoutConstraint(pageIndex: number): Layout.LayoutConstraint {\n return new LayoutConstraint(this, pageIndex);\n }\n}\n\nexport const PAGES_COUNTER_ATTR = \"data-vivliostyle-pages-counter\";\n\nclass LayoutConstraint implements Layout.LayoutConstraint {\n constructor(\n public readonly counterStore: CounterStore,\n public readonly pageIndex: number,\n ) {}\n\n /**\n * @override\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext || nodeContext.after) {\n return true;\n }\n const viewNode = nodeContext.viewNode;\n if (!viewNode || viewNode.nodeType !== 1) {\n return true;\n }\n const id =\n (viewNode as Element).getAttribute(\"id\") ||\n (viewNode as Element).getAttribute(\"name\");\n if (!id) {\n return true;\n }\n if (\n !this.counterStore.resolvedReferences[id] &&\n !this.counterStore.unresolvedReferences[id]\n ) {\n return true;\n }\n const pageIndex = this.counterStore.pageIndicesById[id];\n if (!pageIndex) {\n return true;\n }\n return this.pageIndex >= pageIndex.pageIndex;\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssTokenizer - CSS Tokenizer.\n */\n\nexport interface TokenizerHandler {\n error(mnemonics: string, token: Token): void;\n}\n\nexport function escapeParseSingle(str: string): string {\n str = str.substr(1);\n if (str.match(/^[^0-9a-fA-F\\n\\r]$/)) {\n return str;\n }\n const code = parseInt(str, 16);\n if (isNaN(code)) {\n return \"\";\n }\n if (code <= 65535) {\n return String.fromCharCode(code);\n }\n if (code <= 1114111) {\n // non-BMP characters: convert to a surrogate pair\n return String.fromCharCode(\n 55296 | ((code >> 10) & 1023),\n 56320 | (code & 1023),\n );\n }\n\n // not a valid Unicode value\n return \"\\ufffd\";\n}\n\nexport function escapeParse(str: string): string {\n return str.replace(\n /\\\\([0-9a-fA-F]{0,6}(\\r\\n|[ \\n\\r\\t\\f])?|[^0-9a-fA-F\\n\\r])/g,\n escapeParseSingle,\n );\n}\n\n/**\n * @enum {number}\n */\nexport enum TokenType {\n EOF,\n IDENT,\n STR,\n NUMERIC,\n NUM,\n INT,\n FUNC,\n HASH,\n URL,\n CLASS,\n O_PAR,\n C_PAR,\n O_BRC,\n C_BRC,\n O_BRK,\n C_BRK,\n COMMA,\n SEMICOL,\n COLON,\n SLASH,\n AT,\n PERCENT,\n QMARK,\n PLUS,\n MINUS,\n BAR_BAR,\n AMP_AMP,\n\n // those can have \"=\" at the end\n BANG = 31,\n DOLLAR,\n HAT,\n BAR,\n TILDE,\n STAR,\n GT,\n LT,\n EQ,\n\n // tokens above plus \"=\" at the end, order must be the same\n BANG_EQ = 41,\n DOLLAR_EQ,\n HAT_EQ,\n BAR_EQ,\n TILDE_EQ,\n STAR_EQ,\n GT_EQ,\n LT_EQ,\n EQ_EQ,\n COL_COL,\n INVALID,\n LAST = 51,\n}\n\nexport class Token {\n type: TokenType;\n precededBySpace: boolean = false;\n num: number = 0;\n text: string = \"\";\n position: number = 0;\n\n constructor() {\n this.type = TokenType.EOF;\n }\n}\n\n/**\n * @enum {number}\n */\nexport enum Action {\n SPACE = 1,\n INT,\n IDENT,\n BANG,\n HASH = 6,\n DOLLAR,\n PERCENT,\n AMP,\n O_PAR,\n C_PAR,\n STAR,\n PLUS,\n COMMA,\n MINUS,\n DOT,\n SLASH,\n COLON,\n SEMICOL,\n LT,\n EQ,\n GT,\n QMARK,\n AT,\n O_BRK,\n C_BRK,\n O_BRC,\n C_BRC,\n BSLASH,\n HAT,\n BAR,\n TILDE,\n STR1,\n STR2,\n END,\n EQTAIL,\n ENDINT,\n ENDNUM,\n CONT,\n UNIT,\n PCUNIT,\n NUMBER,\n ENDIDNT,\n IDNTESC,\n ENDIDES,\n\n // end of identifier with escapes\n ENDSTR,\n ENDESTR,\n\n // end of string with escapes\n STR1ESC,\n STR2ESC,\n BAR_BAR,\n AMP_AMP,\n FUNC,\n FUNCES,\n COMMENT,\n COMMST,\n ENDNOTK,\n MINMIN,\n TOINT,\n TONUM,\n TOIDENT,\n TOIDES,\n KILL1,\n KILL2,\n URL,\n URL1,\n URL2,\n ENDURL,\n TERMURL,\n FINURL,\n LT_BG,\n LT_BG_M,\n INVALID,\n CHKPOSS,\n CHKPOSN,\n URLESC,\n IDESCH,\n COL_COL,\n TOCLASS,\n CHKSP,\n EOF,\n}\n\nexport function makeActions(def: Action, spec: Action[]): Action[] {\n const a: number[] = Array(128);\n let i: number;\n for (i = 0; i < 128; i++) {\n a[i] = def;\n }\n a[NaN] = def == Action.END ? Action.END : Action.INVALID;\n for (i = 0; i < spec.length; i += 2) {\n a[spec[i]] = spec[i + 1];\n }\n return a;\n}\n\n/**\n * Start of the token.\n */\nexport const actionsNormal: Action[] = [\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x00-0x07\n Action.INVALID,\n Action.SPACE,\n Action.SPACE,\n Action.INVALID,\n Action.SPACE,\n Action.SPACE,\n Action.INVALID,\n Action.INVALID, // 0x08-0x0F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x10-0x17\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x18-0x1F\n Action.SPACE,\n Action.BANG,\n Action.STR2,\n Action.HASH,\n Action.DOLLAR,\n Action.PERCENT,\n Action.AMP,\n Action.STR1, // 0x20-0x27\n Action.O_PAR,\n Action.C_PAR,\n Action.STAR,\n Action.PLUS,\n Action.COMMA,\n Action.MINUS,\n Action.DOT,\n Action.SLASH, // 0x28-0x2F\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT,\n Action.INT, // 0x30-0x37\n Action.INT,\n Action.INT,\n Action.COLON,\n Action.SEMICOL,\n Action.LT,\n Action.EQ,\n Action.GT,\n Action.QMARK, // 0x38-0x3F\n Action.AT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x40-0x47\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x48-0x4F\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x50-0x57\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.O_BRK,\n Action.BSLASH,\n Action.C_BRK,\n Action.HAT,\n Action.IDENT, // 0x58-0x5F\n Action.INVALID,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x60-0x67\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x68-0x6F\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.IDENT, // 0x70-0x77\n Action.IDENT,\n Action.IDENT,\n Action.IDENT,\n Action.O_BRC,\n Action.BAR,\n Action.C_BRC,\n Action.TILDE,\n Action.INVALID, // 0x78-0x7F\n];\n\nactionsNormal[NaN] = Action.EOF;\n\n/**\n * Inside identifier.\n */\nexport const actionsIdent: Action[] = [\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x00-0x07\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x08-0x0F\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x10-0x17\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x18-0x1F\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x20-0x27\n Action.FUNC,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x38-0x3F\n Action.ENDIDNT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x40-0x47\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x48-0x4F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x50-0x57\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.IDNTESC,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.CONT, // 0x58-0x5F\n Action.ENDIDNT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x60-0x67\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x68-0x6F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x70-0x77\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT,\n Action.ENDIDNT, // 0x78-0x7F\n];\n\nactionsIdent[NaN] = Action.ENDIDNT;\n\n/**\n * After dot (either .class or .123)\n */\nexport const actionsNumOrClass: Action[] = [\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x00-0x07\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x08-0x0F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x10-0x17\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x18-0x1F\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x20-0x27\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.TOCLASS,\n Action.TONUM,\n Action.INVALID, // 0x28-0x2F\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM,\n Action.TONUM, // 0x30-0x37\n Action.TONUM,\n Action.TONUM,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x38-0x3F\n Action.INVALID,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x40-0x47\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x48-0x4F\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x50-0x57\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.INVALID,\n Action.TOIDES,\n Action.INVALID,\n Action.INVALID,\n Action.TOCLASS, // 0x58-0x5F\n Action.INVALID,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x60-0x67\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x68-0x6F\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS, // 0x70-0x77\n Action.TOCLASS,\n Action.TOCLASS,\n Action.TOCLASS,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID,\n Action.INVALID, // 0x78-0x7F\n];\n\nactionsIdent[NaN] = Action.ENDIDNT;\n\n/**\n * after '-'\n */\nexport const actionsMinus: Action[] = [\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x00-0x07\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x08-0x0F\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x10-0x17\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x18-0x1F\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x20-0x27\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.MINMIN,\n Action.TONUM,\n Action.END, // 0x28-0x2F\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT,\n Action.TOINT, // 0x30-0x37\n Action.TOINT,\n Action.TOINT,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x38-0x3F\n Action.END,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x40-0x47\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x48-0x4F\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x50-0x57\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.END,\n Action.TOIDES,\n Action.END,\n Action.END,\n Action.TOIDENT, // 0x58-0x5F\n Action.END,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x60-0x67\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x68-0x6F\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT, // 0x70-0x77\n Action.TOIDENT,\n Action.TOIDENT,\n Action.TOIDENT,\n Action.END,\n Action.END,\n Action.END,\n Action.END,\n Action.END, // 0x78-0x7F\n];\n\nactionsMinus[NaN] = Action.END;\n\n/**\n * Inside identifier with escape sequence\n */\nexport const actionsIdentEsc: Action[] = [\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x00-0x07\n Action.ENDIDES,\n Action.CHKPOSS,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x08-0x0F\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x10-0x17\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x18-0x1F\n Action.CHKPOSS,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x20-0x27\n Action.FUNCES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x38-0x3F\n Action.ENDIDES,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x40-0x47\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x48-0x4F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x50-0x57\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.IDNTESC,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.CONT, // 0x58-0x5F\n Action.ENDIDES,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x60-0x67\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x68-0x6F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x70-0x77\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES,\n Action.ENDIDES, // 0x78-0x7F\n];\n\nactionsIdentEsc[NaN] = Action.ENDIDES;\n\n/**\n * Inside integer\n */\nexport const actionsInt: Action[] = [\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x00-0x07\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x08-0x0F\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x10-0x17\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x18-0x1F\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.PCUNIT,\n Action.ENDINT,\n Action.ENDINT, // 0x20-0x27\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.NUMBER,\n Action.ENDINT, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x38-0x3F\n Action.ENDINT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x40-0x47\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x48-0x4F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x50-0x57\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.UNIT, // 0x58-0x5F\n Action.ENDINT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x60-0x67\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x68-0x6F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x70-0x77\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT,\n Action.ENDINT, // 0x78-0x7F\n];\n\nactionsInt[NaN] = Action.ENDINT;\n\n/**\n * inside real, after dot\n */\nexport const actionsNumber: Action[] = [\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x00-0x07\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x08-0x0F\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x10-0x17\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x18-0x1F\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.PCUNIT,\n Action.ENDNUM,\n Action.ENDNUM, // 0x20-0x27\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x28-0x2F\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT,\n Action.CONT, // 0x30-0x37\n Action.CONT,\n Action.CONT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x38-0x3F\n Action.ENDNUM,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x40-0x47\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x48-0x4F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x50-0x57\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.UNIT, // 0x58-0x5F\n Action.ENDNUM,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x60-0x67\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x68-0x6F\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.UNIT, // 0x70-0x77\n Action.UNIT,\n Action.UNIT,\n Action.UNIT,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM,\n Action.ENDNUM, // 0x78-0x7F\n];\n\nactionsNumber[NaN] = Action.ENDNUM;\n\nexport const actionsCheckEq: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n]);\n\nexport const actionsColon: Action[] = makeActions(Action.END, [\n 58 /*:*/,\n Action.COL_COL,\n]);\n\nexport const actionsBar: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n 124 /*|*/,\n Action.BAR_BAR,\n]);\n\nexport const actionsAmp: Action[] = makeActions(Action.END, [\n 38 /*&*/,\n Action.AMP_AMP,\n]);\n\nexport const actionsSlash: Action[] = makeActions(Action.END, [\n 42 /* * */,\n Action.COMMENT,\n]);\n\nexport const actionsComment: Action[] = makeActions(Action.CONT, [\n 42 /* * */,\n Action.COMMST,\n]);\n\nexport const actionsCommentStar: Action[] = makeActions(Action.COMMENT, [\n 42 /* * */,\n Action.COMMST,\n 47 /* / */,\n Action.ENDNOTK,\n]);\n\nexport const actionsMinusMinus: Action[] = makeActions(Action.KILL1, [\n 62 /* > */,\n Action.ENDNOTK,\n]);\n\nexport const actionsLt: Action[] = makeActions(Action.END, [\n 61 /*=*/,\n Action.EQTAIL,\n 33 /*!*/,\n Action.LT_BG,\n]);\n\nexport const actionsLtBang: Action[] = makeActions(Action.KILL1, [\n 45 /*-*/,\n Action.LT_BG_M,\n]);\n\nexport const actionsLtBangMinus: Action[] = makeActions(Action.KILL2, [\n 45 /*-*/,\n Action.ENDNOTK,\n]);\n\nexport const actionsIdentEscChr: Action[] = makeActions(Action.IDESCH, [\n 9 /*tab*/,\n Action.INVALID,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 32 /*sp*/,\n Action.INVALID,\n]);\n\nexport const actionsStr1: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.ENDSTR,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 92 /*\\*/,\n Action.STR1ESC,\n]);\n\nexport const actionsStr2: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.ENDSTR,\n 10 /*LF*/,\n Action.INVALID,\n 13 /*CR*/,\n Action.INVALID,\n 92 /*\\*/,\n Action.STR2ESC,\n]);\n\nexport const actionsStr1Esc: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.ENDESTR,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.STR1ESC,\n]);\n\nexport const actionsStr2Esc: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.ENDESTR,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.STR2ESC,\n]);\n\nexport const actionsURL: Action[] = makeActions(Action.URL, [\n 9 /*tab*/,\n Action.CONT,\n 32 /*sp*/,\n Action.CONT,\n 34 /*\"*/,\n Action.URL2,\n 39 /*'*/,\n Action.URL1,\n 41 /*)*/,\n Action.INVALID,\n 10 /*LF*/,\n Action.CONT,\n 13 /*CR*/,\n Action.CONT,\n]);\n\nexport const actionsURLInside: Action[] = makeActions(Action.CONT, [\n 41 /*)*/,\n Action.ENDURL,\n 9 /*TAB*/,\n Action.CHKSP,\n 10 /*LF*/,\n Action.CHKSP,\n 13 /*CR*/,\n Action.CHKSP,\n 32 /*sp*/,\n Action.CHKSP,\n 92 /*\\*/,\n Action.URLESC,\n 40 /*(*/,\n Action.INVALID,\n 91 /*[*/,\n Action.INVALID,\n 93 /*]*/,\n Action.INVALID,\n 123 /*{*/,\n Action.INVALID,\n 125 /*}*/,\n Action.INVALID,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLInside1: Action[] = makeActions(Action.CONT, [\n 39 /*'*/,\n Action.TERMURL,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.URLESC,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLInside2: Action[] = makeActions(Action.CONT, [\n 34 /*\"*/,\n Action.TERMURL,\n 10 /*LF*/,\n Action.CHKPOSN,\n 13 /*CR*/,\n Action.CHKPOSN,\n 92 /*\\*/,\n Action.URLESC,\n NaN,\n Action.ENDURL,\n]);\n\nexport const actionsURLTail: Action[] = makeActions(Action.INVALID, [\n 9 /*tab*/,\n Action.CONT,\n 10 /*LF*/,\n Action.CONT,\n 13 /*CR*/,\n Action.CONT,\n 32 /*sp*/,\n Action.CONT,\n 41 /*)*/,\n Action.FINURL,\n]);\n\nexport const INITIAL_INDEX_MASK = 15;\n\nexport class Tokenizer {\n indexMask: number;\n buffer: Token[];\n head: number = -1; // saved, occupied if >= 0\n tail: number = 0; // available, ready to write\n curr: number = 0; // ready to read\n position: number = 0;\n\n constructor(public input: string, public readonly handler: TokenizerHandler) {\n this.indexMask = INITIAL_INDEX_MASK;\n this.buffer = Array(this.indexMask + 1);\n for (let i = 0; i <= this.indexMask; i++) {\n this.buffer[i] = new Token();\n }\n }\n\n token(): Token {\n if (this.tail == this.curr) {\n this.fillBuffer();\n }\n return this.buffer[this.curr];\n }\n\n nthToken(n: number): Token {\n if (((this.tail - this.curr) & this.indexMask) <= n) {\n this.fillBuffer();\n }\n return this.buffer[(this.curr + n) & this.indexMask];\n }\n\n consume(): void {\n this.curr = (this.curr + 1) & this.indexMask;\n }\n\n mark(): void {\n if (this.head >= 0) {\n throw new Error(\"F_CSSTOK_BAD_CALL mark\");\n }\n this.head = this.curr;\n }\n\n reset(): void {\n if (this.head < 0) {\n throw new Error(\"F_CSSTOK_BAD_CALL reset\");\n }\n this.curr = this.head;\n this.head = -1;\n }\n\n unmark(): void {\n this.head = -1;\n }\n\n hasMark(): boolean {\n return this.head >= 0;\n }\n\n private reallocate(): void {\n const newIndexMask = 2 * (this.indexMask + 1) - 1;\n const newBuffer: Token[] = Array(newIndexMask + 1);\n let oldIndex = this.head;\n let newIndex = 0;\n while (oldIndex != this.tail) {\n newBuffer[newIndex] = this.buffer[oldIndex];\n if (oldIndex == this.curr) {\n this.curr = newIndex;\n }\n oldIndex = (oldIndex + 1) & this.indexMask;\n newIndex++;\n }\n this.head = 0;\n this.tail = newIndex;\n this.indexMask = newIndexMask;\n this.buffer = newBuffer;\n while (newIndex <= newIndexMask) {\n newBuffer[newIndex++] = new Token();\n }\n }\n\n private error(position, token, mnemonics) {\n if (this.handler) {\n this.handler.error(mnemonics, token);\n }\n }\n\n private fillBuffer(): void {\n let tail = this.tail;\n let head = this.head >= 0 ? this.head : this.curr;\n let indexMask = this.indexMask;\n if (tail >= head) {\n head += indexMask;\n } else {\n head--;\n }\n if (head == tail) {\n // only expect to get here when mark is in effect\n if (this.head < 0) {\n throw new Error(\"F_CSSTOK_INTERNAL\");\n }\n this.reallocate();\n tail = this.tail;\n indexMask = this.indexMask;\n head = indexMask; // this.head is zero\n }\n let actions = actionsNormal;\n const input = this.input;\n let position = this.position;\n const buffer = this.buffer;\n let tokenType: TokenType = TokenType.EOF;\n let tokenPosition: number = 0;\n let tokenText: string = \"\";\n let tokenNum: number = 0;\n let seenSpace = false;\n let token: Token = buffer[tail];\n let backslashPos = -9; // far enough before the start of the string\n while (true) {\n const charCode = input.charCodeAt(position);\n switch (actions[charCode] || actions[65] /*A*/) {\n case Action.INVALID:\n tokenType = TokenType.INVALID;\n if (isNaN(charCode)) {\n tokenText = \"E_CSS_UNEXPECTED_EOF\";\n } else {\n tokenText = \"E_CSS_UNEXPECTED_CHAR\";\n }\n actions = actionsNormal;\n position++;\n break;\n case Action.SPACE:\n position++;\n seenSpace = true;\n continue;\n case Action.INT:\n tokenPosition = position++;\n actions = actionsInt;\n continue;\n case Action.IDENT:\n tokenType = TokenType.IDENT;\n tokenPosition = position++;\n actions = actionsIdent;\n continue;\n case Action.BANG:\n tokenPosition = position++;\n tokenType = TokenType.BANG;\n actions = actionsCheckEq;\n continue;\n case Action.STR1:\n tokenType = TokenType.STR;\n tokenPosition = ++position; // after quote\n actions = actionsStr1;\n continue;\n case Action.STR2:\n tokenType = TokenType.STR;\n tokenPosition = ++position; // after quote\n actions = actionsStr2;\n continue;\n case Action.HASH:\n tokenPosition = ++position; // after hash\n tokenType = TokenType.HASH;\n actions = actionsIdent;\n continue;\n case Action.DOLLAR:\n tokenPosition = position++;\n tokenType = TokenType.DOLLAR;\n actions = actionsCheckEq;\n continue;\n case Action.PERCENT:\n tokenPosition = position++;\n tokenType = TokenType.PERCENT;\n break;\n case Action.AMP:\n tokenPosition = position++;\n tokenType = TokenType.DOLLAR;\n actions = actionsAmp;\n continue;\n case Action.O_PAR:\n tokenPosition = position++;\n tokenType = TokenType.O_PAR;\n break;\n case Action.C_PAR:\n tokenPosition = position++;\n tokenType = TokenType.C_PAR;\n break;\n case Action.STAR:\n tokenPosition = position++;\n tokenType = TokenType.STAR;\n actions = actionsCheckEq;\n continue;\n case Action.PLUS:\n tokenPosition = position++;\n tokenType = TokenType.PLUS;\n break;\n case Action.COMMA:\n tokenPosition = position++;\n tokenType = TokenType.COMMA;\n break;\n case Action.MINUS:\n tokenType = TokenType.MINUS;\n tokenPosition = position++;\n actions = actionsMinus;\n continue;\n case Action.DOT:\n tokenPosition = position++;\n actions = actionsNumOrClass;\n continue;\n case Action.TOCLASS:\n tokenPosition = position++;\n tokenType = TokenType.CLASS;\n actions = actionsIdent;\n continue;\n case Action.SLASH:\n tokenPosition = position++;\n tokenType = TokenType.SLASH;\n actions = actionsSlash;\n continue;\n case Action.COLON:\n tokenPosition = position++;\n tokenType = TokenType.COLON;\n actions = actionsColon;\n continue;\n case Action.COL_COL:\n position++;\n tokenType = TokenType.COL_COL;\n break;\n case Action.SEMICOL:\n tokenPosition = position++;\n tokenType = TokenType.SEMICOL;\n break;\n case Action.LT:\n tokenPosition = position++;\n tokenType = TokenType.LT;\n actions = actionsLt;\n continue;\n case Action.EQ:\n tokenPosition = position++;\n tokenType = TokenType.EQ;\n actions = actionsCheckEq;\n continue;\n case Action.GT:\n tokenPosition = position++;\n tokenType = TokenType.GT;\n actions = actionsCheckEq;\n continue;\n case Action.QMARK:\n tokenPosition = position++;\n tokenType = TokenType.QMARK;\n break;\n case Action.AT:\n tokenPosition = ++position; // after \"at\" sign\n tokenType = TokenType.AT;\n actions = actionsIdent;\n continue;\n case Action.O_BRK:\n tokenPosition = position++;\n tokenType = TokenType.O_BRK;\n break;\n case Action.C_BRK:\n tokenPosition = position++;\n tokenType = TokenType.C_BRK;\n break;\n case Action.O_BRC:\n tokenPosition = position++;\n tokenType = TokenType.O_BRC;\n break;\n case Action.C_BRC:\n tokenPosition = position++;\n tokenType = TokenType.C_BRC;\n break;\n case Action.BSLASH:\n tokenPosition = position++;\n backslashPos = tokenPosition;\n tokenType = TokenType.IDENT;\n actions = actionsIdentEscChr;\n continue;\n case Action.HAT:\n tokenPosition = position++;\n tokenType = TokenType.HAT;\n actions = actionsCheckEq;\n continue;\n case Action.BAR:\n tokenPosition = position++;\n tokenType = TokenType.BAR;\n actions = actionsBar;\n continue;\n case Action.TILDE:\n tokenPosition = position++;\n tokenType = TokenType.TILDE;\n actions = actionsCheckEq;\n continue;\n case Action.END:\n // don't consume current char\n break;\n case Action.EQTAIL:\n position++;\n tokenType = (tokenType +\n TokenType.BANG_EQ -\n TokenType.BANG) as TokenType;\n break;\n case Action.ENDINT:\n // don't consume current char\n tokenType = TokenType.INT;\n tokenNum = parseInt(input.substring(tokenPosition, position), 10);\n break;\n case Action.ENDNUM:\n // don't consume current char\n tokenType = TokenType.NUM;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n break;\n case Action.CONT:\n // just consume current char\n position++;\n continue;\n case Action.UNIT:\n tokenType = TokenType.NUMERIC;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n tokenPosition = position++;\n actions = actionsIdent;\n continue;\n case Action.PCUNIT:\n tokenType = TokenType.NUMERIC;\n tokenNum = parseFloat(input.substring(tokenPosition, position));\n tokenText = \"%\";\n tokenPosition = position++; // for consistency with alphabetic units\n break;\n case Action.NUMBER:\n position++;\n actions = actionsNumber;\n continue;\n case Action.ENDIDNT:\n // don't consume current char\n // tokenType should be set already\n tokenText = input.substring(tokenPosition, position);\n break;\n case Action.IDNTESC:\n backslashPos = position++;\n actions = actionsIdentEscChr;\n continue;\n case Action.ENDIDES:\n // end of identifier with escapes\n // don't consume current char\n // tokenType should be set already\n tokenText = escapeParse(input.substring(tokenPosition, position));\n break;\n case Action.ENDSTR:\n tokenText = input.substring(tokenPosition, position); // consume closing quote\n position++;\n break;\n case Action.ENDESTR:\n tokenText = escapeParse(input.substring(tokenPosition, position)); // consume closing quote\n position++;\n break;\n case Action.STR1ESC:\n backslashPos = position;\n position += 2; // consume character after backslash in any case\n actions = actionsStr1Esc;\n continue;\n case Action.STR2ESC:\n backslashPos = position;\n position += 2; // consume character after backslash in any case\n actions = actionsStr2Esc;\n continue;\n case Action.BAR_BAR:\n position++;\n tokenType = TokenType.BAR_BAR;\n break;\n case Action.AMP_AMP:\n position++;\n tokenType = TokenType.AMP_AMP;\n break;\n case Action.FUNC:\n // tokenType can be TokenType.IDENT,\n // TokenType.CLASS, TokenType.AT,\n // TokenType.HASH, TokenType.NUMERIC\n tokenText = input.substring(tokenPosition, position);\n if (tokenType == TokenType.IDENT) {\n position++; // consume\n if (tokenText.toLowerCase() == \"url\") {\n actions = actionsURL;\n continue;\n }\n tokenType = TokenType.FUNC;\n }\n break;\n case Action.FUNCES:\n // tokenType can be TokenType.IDENT,\n // TokenType.CLASS, TokenType.AT,\n // TokenType.HASH, T_NUMERIC\n tokenText = escapeParse(input.substring(tokenPosition, position));\n if (tokenType == TokenType.IDENT) {\n position++; // consume\n if (tokenText.toLowerCase() == \"url\") {\n actions = actionsURL;\n continue;\n }\n tokenType = TokenType.FUNC;\n }\n break;\n case Action.COMMENT:\n actions = actionsComment;\n position++;\n continue;\n case Action.COMMST:\n actions = actionsCommentStar;\n position++;\n continue;\n case Action.ENDNOTK:\n actions = actionsNormal;\n position++;\n continue;\n case Action.MINMIN:\n actions = actionsMinusMinus;\n position++;\n continue;\n case Action.TOINT:\n tokenType = TokenType.INT;\n actions = actionsInt;\n position++;\n continue;\n case Action.TONUM:\n tokenType = TokenType.NUM;\n actions = actionsNumber;\n position++;\n continue;\n case Action.TOIDENT:\n tokenType = TokenType.IDENT;\n actions = actionsIdent;\n position++;\n continue;\n case Action.TOIDES:\n tokenType = TokenType.IDENT;\n actions = actionsIdentEscChr;\n backslashPos = position++;\n continue;\n case Action.KILL1:\n position--;\n break;\n case Action.KILL2:\n position -= 2;\n break;\n case Action.URL:\n tokenPosition = position++;\n actions = actionsURLInside;\n continue;\n case Action.URL1:\n tokenPosition = ++position; // skip quote\n actions = actionsURLInside1;\n continue;\n case Action.URL2:\n tokenPosition = ++position; // skip quote\n actions = actionsURLInside2;\n continue;\n case Action.ENDURL:\n tokenType = TokenType.URL;\n tokenText = escapeParse(input.substring(tokenPosition, position));\n position++; // skip ')'\n break;\n case Action.FINURL:\n position++; // skip ')'\n break;\n case Action.LT_BG:\n actions = actionsLtBang;\n position++;\n continue;\n case Action.LT_BG_M:\n actions = actionsLtBangMinus;\n position++;\n continue;\n case Action.CHKSP:\n // newline in non-quoted URL - check if end of url\n if (position - backslashPos < 8) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position + 1)\n .match(/^[0-9a-fA-F]{0,6}(\\r\\n|[\\n\\r])|[ \\t]$/)\n ) {\n // valid, keep going\n position++;\n continue;\n }\n }\n\n // end of url\n // fall through\n case Action.TERMURL:\n tokenType = TokenType.URL;\n tokenText = escapeParse(input.substring(tokenPosition, position));\n position++; // skip quote (or newline)\n actions = actionsURLTail;\n continue;\n case Action.CHKPOSN:\n // newline in string or quoted URL - check validity\n position++;\n if (position - backslashPos < 9) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position)\n .match(/^[0-9a-fA-F]{0,6}(\\r\\n|[\\n\\r])$/)\n ) {\n // valid, keep going\n continue;\n }\n }\n\n // invalid token\n tokenType = TokenType.INVALID;\n tokenText = \"E_CSS_UNEXPECTED_NEWLINE\";\n actions = actionsNormal;\n break;\n case Action.CHKPOSS:\n // space in identifier - check validity\n if (position - backslashPos < 9) {\n // close enough: may be valid\n if (\n input\n .substring(backslashPos + 1, position + 1)\n .match(/^[0-9a-fA-F]{0,6}[ \\t]$/)\n ) {\n // valid, keep going\n position++;\n continue;\n }\n }\n\n // end of identifier\n // don't consume current char\n // tokenType should be set already\n tokenText = escapeParse(input.substring(tokenPosition, position));\n break;\n case Action.URLESC:\n backslashPos = position++;\n continue;\n case Action.IDESCH:\n position++;\n actions = actionsIdentEsc;\n continue;\n default:\n // EOF\n if (actions !== actionsNormal) {\n tokenType = TokenType.INVALID;\n tokenText = \"E_CSS_UNEXPECTED_STATE\";\n break;\n }\n tokenPosition = position;\n tokenType = TokenType.EOF;\n }\n token.type = tokenType;\n token.precededBySpace = seenSpace;\n token.num = tokenNum;\n token.text = tokenText;\n token.position = tokenPosition;\n tail++;\n if (tail >= head) {\n break;\n }\n actions = actionsNormal;\n seenSpace = false;\n token = buffer[tail & indexMask];\n }\n this.position = position;\n this.tail = tail & indexMask;\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Task - Support for asynchronous execution and cooperative\n * multitasking.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\n\n/**\n * External timer. Only needed for testing.\n */\nexport interface Timer {\n /**\n * @return current time in milliseconds.\n */\n currentTime(): number;\n\n /**\n * Calls function after a given timeout.\n * @param fn function to call.\n * @param delay timeout in milliseconds.\n * @return unique number that can be used to clear the timeout.\n */\n setTimeout(fn: () => void, delay: number): number;\n\n /**\n * Calls function after a given timeout.\n * @param token timeout token.\n * @return.\n */\n clearTimeout(token: number): void;\n}\n\n/**\n * Result of an asynchronous function that may be available immediately or\n * some time later. Similar to Deferred.\n * @template T\n */\nexport interface Result<T> {\n /**\n * Call the given function when asynchronous function is finished. Callback\n * is executed in the task's context.\n */\n then(callback: (p1: T) => void): void;\n\n /**\n * Call the given asynchronous function when some asynchronous function is\n * finished. Callback is executed in the task's context.\n * @template T1\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>): Result<T1>;\n\n /**\n * Produce a Result that resolves to the given value when this Result is\n * resolved.\n * @template T1\n */\n thenReturn<T1>(result: T1): Result<T1>;\n\n /**\n * Finish given frame with the result value when result becomes ready.\n */\n thenFinish(frame: Frame<T>): void;\n\n /**\n * Check if this Result is still pending.\n */\n isPending(): boolean;\n\n /**\n * If this Result is resolved, return the value that it holds.\n */\n get(): T | null;\n}\n\nexport let privateCurrentTask: Task | null = null;\n\nexport let primaryScheduler: Scheduler | null = null;\n\n/**\n * Returns current task.\n */\nexport function currentTask(): Task | null {\n return privateCurrentTask;\n}\n\n/**\n * Create and return a new frame with the given name.\n */\nexport function newFrame<T>(name: string): Frame<T> {\n if (!privateCurrentTask) {\n throw new Error(\"E_TASK_NO_CONTEXT\");\n }\n if (!privateCurrentTask.name) {\n privateCurrentTask.name = name;\n }\n const task = privateCurrentTask;\n const frame = new Frame<T>(task, task.top, name);\n task.top = frame;\n frame.state = FrameState.ACTIVE;\n return frame;\n}\n\nexport function newEventSource(): EventSource {\n return new EventSource();\n}\n\nexport function newScheduler(opt_timer?: Timer): Scheduler {\n return new Scheduler(opt_timer || new TimerImpl());\n}\n\n/**\n * @template T\n */\nexport function newResult<T>(opt_value: T): Result<T> {\n return new SyncResultImpl<T>(opt_value);\n}\n\n/**\n * Creates a new frame and runs code in its context, catching synchronous and\n * asynchronous errors. If an error occurs, onErr is run (in the context of\n * the same frame). As usual, onErr is supposed either produce a result or raise\n * an exception.\n */\nexport function handle<T>(\n name: any,\n code: (p1: Frame<T>) => void,\n onErr: (p1: Frame<T>, p2: Error) => void,\n): Result<T> {\n const frame = newFrame<T>(name);\n frame.handler = onErr;\n try {\n code(frame);\n } catch (err) {\n // synchronous exception\n frame.task.raise(err, frame);\n }\n return frame.result();\n}\n\nexport function start<T>(func: () => Result<T>, opt_name?: string): Task {\n const scheduler = privateCurrentTask\n ? privateCurrentTask.getScheduler()\n : primaryScheduler || newScheduler();\n return scheduler.run(func, opt_name);\n}\n\n/**\n * Frame state.\n * @enum {number}\n */\nexport enum FrameState {\n INIT, // before newFrame call\n ACTIVE, // before finish call\n FINISHED, // before callback complete\n DEAD, // when callback is complete\n}\nexport class TimerImpl implements Timer {\n /**\n * @override\n */\n currentTime(): number {\n return new Date().valueOf();\n }\n\n /**\n * @override\n */\n setTimeout(fn: () => void, delay: number) {\n // HACK: casting to unknown type to prevent TypeScript error\n // [TS2352] Conversion of type 'Timer' to type 'number' may be a mistake because neither type sufficiently overlaps with the other.\n const timer: unknown = setTimeout(fn, delay);\n return timer as number;\n }\n\n /**\n * @override\n */\n clearTimeout(token: number): void {\n clearTimeout(token);\n }\n}\n\n/**\n * A class to create tasks.\n */\nexport class Scheduler {\n timeout: number = 1;\n slice: number = 25;\n sliceOverTime: number = 0;\n queue: Base.PriorityQueue;\n wakeupTime: number | null = null;\n timeoutToken: number | null = null;\n inTimeSlice: boolean = false;\n order: number = 0;\n\n constructor(public timer: Timer) {\n this.queue = new Base.PriorityQueue();\n if (!primaryScheduler) {\n primaryScheduler = this;\n }\n }\n\n /**\n * Sets time slice length.\n * @param slice length in milliseconds.\n */\n setSlice(slice: number) {\n this.slice = slice;\n }\n\n /**\n * Sets timeout between time slices.\n * @param timeout in milliseconds.\n */\n setTimeout(timeout: number) {\n this.timeout = timeout;\n }\n\n /**\n * Checks if the current time slice is over.\n */\n isTimeSliceOver(): boolean {\n const now = this.timer.currentTime();\n return now >= this.sliceOverTime;\n }\n\n private arm(): void {\n if (this.inTimeSlice) {\n return;\n }\n const nextInQueue = this.queue.peek() as Continuation<any>;\n const newTime = nextInQueue.scheduledTime;\n const now = this.timer.currentTime();\n if (this.timeoutToken != null) {\n if (now + this.timeout > this.wakeupTime) {\n return; // no use re-arming\n }\n this.timer.clearTimeout(this.timeoutToken);\n }\n let timeout = newTime - now;\n if (timeout <= this.timeout) {\n timeout = this.timeout;\n }\n this.wakeupTime = now + timeout;\n const self = this;\n this.timeoutToken = this.timer.setTimeout(() => {\n self.timeoutToken = null;\n self.doTimeSlice();\n }, timeout);\n }\n\n schedule(continuation: Continuation<any>, opt_delay?: number): void {\n const c = continuation as Continuation<any>;\n const now = this.timer.currentTime();\n c.order = this.order++;\n c.scheduledTime = now + (opt_delay || 0);\n this.queue.add(c);\n this.arm();\n }\n\n private doTimeSlice(): void {\n if (this.timeoutToken != null) {\n this.timer.clearTimeout(this.timeoutToken);\n this.timeoutToken = null;\n }\n this.inTimeSlice = true;\n try {\n let now = this.timer.currentTime();\n this.sliceOverTime = now + this.slice;\n while (this.queue.length()) {\n const continuation = this.queue.peek() as Continuation<any>;\n if (continuation.scheduledTime > now) {\n break; // too early\n }\n this.queue.remove();\n if (!continuation.canceled) {\n continuation.resumeInternal();\n }\n now = this.timer.currentTime();\n if (now >= this.sliceOverTime) {\n break;\n }\n }\n } catch (err) {\n Logging.logger.error(err);\n }\n this.inTimeSlice = false;\n if (this.queue.length()) {\n this.arm();\n }\n }\n\n run(func: () => Result<any>, opt_name?: string): Task {\n const task = new Task(this, opt_name || \"\");\n task.top = new Frame<any>(task, null, \"bootstrap\");\n task.top.state = FrameState.ACTIVE;\n task.top.then(() => {\n const done = () => {\n task.running = false;\n for (const callback of task.callbacks) {\n try {\n callback();\n } catch (err) {\n Logging.logger.error(err);\n }\n }\n };\n try {\n func().then((result) => {\n task.result = result;\n done();\n });\n } catch (err) {\n task.raise(err);\n done();\n }\n });\n const savedTask = privateCurrentTask;\n privateCurrentTask = task;\n this.schedule(task.top.suspend(\"bootstrap\"));\n privateCurrentTask = savedTask;\n return task;\n }\n}\n\n/**\n * Task suspension point.\n * @template T\n */\nexport class Continuation<T> implements Base.Comparable {\n scheduledTime: number = 0;\n order: number = 0;\n result: T = null;\n canceled: boolean = false;\n\n constructor(public task: Task) {}\n\n /**\n * @override\n */\n compare(otherComp: Base.Comparable): number {\n // earlier wins\n const other = otherComp as Continuation<any>;\n return other.scheduledTime - this.scheduledTime || other.order - this.order;\n }\n\n /**\n * Continuation's task\n */\n getTask(): Task {\n return this.task;\n }\n\n /**\n * Schedule task continuation after the given (optional) delay.\n * @param opt_delay optional delay in milliseconds.\n */\n schedule(result: T, opt_delay?: number) {\n this.result = result;\n this.task.scheduler.schedule(this, opt_delay);\n }\n\n resumeInternal(): boolean {\n const task = this.task;\n this.task = null;\n if (task && task.continuation == this) {\n task.continuation = null;\n const savedTask = privateCurrentTask;\n privateCurrentTask = task;\n task.top.finish(this.result);\n privateCurrentTask = savedTask;\n return true;\n }\n return false;\n }\n\n /**\n * Cancel continuation\n */\n cancel() {\n this.canceled = true;\n }\n}\n\n/**\n * An asynchronous, time-sliced task.\n */\nexport class Task {\n callbacks: (() => void)[] = [];\n exception: Error | null = null;\n running: boolean = true;\n result: any = null;\n waitTarget: string | null = null;\n top: Frame<any> | null = null;\n continuation: Continuation<any> | null = null;\n\n constructor(public scheduler: Scheduler, public name: string) {}\n\n /**\n * @return task name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * @param err exception to throw in the task's context.\n */\n interrupt(err: Error): void {\n this.raise(err || new Error(\"E_TASK_INTERRUPT\"));\n if (this !== privateCurrentTask && this.continuation) {\n // blocked on something\n this.continuation.cancel();\n const continuation = new Continuation(this);\n this.waitTarget = \"interrupt\";\n this.continuation = continuation;\n this.scheduler.schedule(continuation);\n }\n }\n\n /**\n * @return this task's scheduler.\n */\n getScheduler(): Scheduler {\n return this.scheduler;\n }\n\n /**\n * @return true if task is still running.\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Register a callback to be called when the task is done. Callback is not\n * executed in any task context. Multiple callbacks can be registered and\n * they will be called in the registration order.\n */\n whenDone(callback: () => void): void {\n this.callbacks.push(callback);\n }\n\n /**\n * Wait for task to finish (from another task).\n */\n join(): Result<any> {\n const frame = newFrame<any>(\"Task.join\");\n if (!this.running) {\n frame.finish(this.result);\n } else {\n const continuation = frame.suspend(this);\n const self = this;\n this.whenDone(() => {\n continuation.schedule(self.result);\n });\n }\n return frame.result();\n }\n\n /**\n * Unwind the stack. We have two stacks: async (maintained by frame\n * parent link) and sync (regular JavaScript stack).\n */\n unwind() {\n // We have a sequence of frames on the stack.\n while (this.top && !this.top.handler) {\n this.top = this.top.parent;\n }\n if (this.top && this.top.handler && this.exception) {\n // found a handler\n const err = this.exception;\n this.exception = null;\n this.top.handler(this.top, err);\n } else {\n if (this.exception) {\n Logging.logger.error(\n this.exception,\n \"Unhandled exception in task\",\n this.name,\n );\n }\n }\n }\n\n raise(err: Error, opt_frame?: Frame<any>): void {\n this.fillStack(err);\n if (opt_frame) {\n let f = this.top;\n while (f && f != opt_frame) {\n f = f.parent;\n }\n if (f == opt_frame) {\n this.top = f;\n }\n }\n this.exception = err;\n this.unwind();\n }\n\n /**\n * Fill the stack trace in the exception\n * @param err exception\n */\n fillStack(err: Error) {\n let out = err[\"frameTrace\"];\n if (!out) {\n out = err[\"stack\"] ? `${err[\"stack\"]}\\n\\t---- async ---\\n` : \"\";\n for (let f = this.top; f; f = f.parent) {\n out += \"\\t\";\n out += f.getName();\n out += \"\\n\";\n }\n err[\"frameTrace\"] = out;\n }\n }\n}\n\n/**\n * @template T\n */\nexport class SyncResultImpl<T> implements Result<T> {\n constructor(public value: T) {}\n\n /**\n * @override\n */\n then(callback: (T: any) => void) {\n callback(this.value);\n }\n\n /**\n * @override\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>) {\n return callback(this.value);\n }\n\n /**\n * @override\n */\n thenReturn<T1>(result: T1) {\n return new SyncResultImpl(result);\n }\n\n /**\n * @override\n */\n thenFinish(frame: Frame<T>): void {\n frame.finish(this.value);\n }\n\n /**\n * @override\n */\n isPending(): boolean {\n return false;\n }\n\n /**\n * @override\n */\n get(): T | null {\n return this.value;\n }\n}\n\n/**\n * @template T\n */\nexport class ResultImpl<T> implements Result<T> {\n constructor(public readonly frame: Frame<T>) {}\n\n /**\n * @override\n */\n then(callback: (p1: T) => void): void {\n this.frame.then(callback);\n }\n\n /**\n * @override\n */\n thenAsync<T1>(callback: (p1: T) => Result<T1>): Result<T1> {\n if (this.isPending()) {\n // thenAsync is special, do the trick with the context\n const frame = new Frame<T | T1>(\n this.frame.task,\n this.frame.parent,\n \"AsyncResult.thenAsync\",\n );\n frame.state = FrameState.ACTIVE;\n this.frame.parent = frame as Frame<T>;\n this.frame.then((res1) => {\n callback(res1).then((res2) => {\n frame.finish(res2);\n });\n });\n return frame.result() as Result<T1>;\n } else {\n return callback(this.frame.res);\n }\n }\n\n /**\n * @override\n */\n thenReturn<T1>(result: T1) {\n if (this.isPending()) {\n return this.thenAsync(() => new SyncResultImpl(result));\n } else {\n return new SyncResultImpl(result);\n }\n }\n\n /**\n * @override\n */\n thenFinish(frame: Frame<T>): void {\n if (this.isPending()) {\n this.then((res) => {\n frame.finish(res);\n });\n } else {\n frame.finish(this.frame.res);\n }\n }\n\n /**\n * @override\n */\n isPending(): boolean {\n return this.frame.state == FrameState.ACTIVE;\n }\n\n /**\n * @override\n */\n get(): T | null {\n if (this.isPending()) {\n throw new Error(\"Result is pending\");\n }\n return this.frame.res;\n }\n}\n\n/**\n * Asynchronous execution frame. Corresponds to an asynchronous function\n * invocation.\n * @template T\n */\nexport class Frame<T> {\n res: T = null;\n state: FrameState;\n callback: ((p1: any) => void) | null = null;\n handler: ((p1: Frame<any>, p2: Error) => void) | null = null;\n\n constructor(public task: Task, public parent: Frame<T>, public name: string) {\n this.state = FrameState.INIT;\n }\n\n private checkEnvironment(): void {\n if (!privateCurrentTask) {\n throw new Error(\"F_TASK_NO_CONTEXT\");\n }\n if (this !== privateCurrentTask.top) {\n throw new Error(\"F_TASK_NOT_TOP_FRAME\");\n }\n }\n\n /**\n * @return to be returned as this asynchronous function return value.\n */\n result(): Result<T> {\n return new ResultImpl<T>(this);\n }\n\n finish(res: T) {\n this.checkEnvironment();\n if (privateCurrentTask && !privateCurrentTask.exception) {\n this.res = res;\n }\n this.state = FrameState.FINISHED;\n const frame = this.parent;\n if (privateCurrentTask) {\n privateCurrentTask.top = frame;\n }\n if (this.callback) {\n try {\n this.callback(res);\n } catch (err) {\n this.task.raise(err, frame);\n }\n\n // callback was called\n this.state = FrameState.DEAD;\n }\n }\n\n getTask(): Task {\n return this.task;\n }\n\n /**\n * @return frame name.\n */\n getName(): string {\n return this.name;\n }\n\n getScheduler(): Scheduler {\n return this.task.scheduler;\n }\n\n then(callback: (p1: T) => void): void {\n // legal to call when currentTask is null\n switch (this.state) {\n case FrameState.ACTIVE:\n if (this.callback) {\n throw new Error(\"F_TASK_FRAME_ALREADY_HAS_CALLBACK\");\n } else {\n this.callback = callback;\n }\n break;\n case FrameState.FINISHED: {\n const task = this.task;\n const frame = this.parent;\n try {\n callback(this.res);\n this.state = FrameState.DEAD;\n } catch (err) {\n this.state = FrameState.DEAD;\n task.raise(err, frame);\n }\n break;\n }\n case FrameState.DEAD:\n throw new Error(\"F_TASK_DEAD_FRAME\");\n default:\n throw new Error(`F_TASK_UNEXPECTED_FRAME_STATE ${this.state}`);\n }\n }\n\n /**\n * If this task was executed longer than task's slice parameter.\n * @return holds true\n */\n timeSlice(): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.timeSlice\");\n const scheduler = frame.getScheduler();\n if (scheduler.isTimeSliceOver()) {\n Logging.logger.debug(\"-- time slice --\");\n frame.suspend().schedule(true);\n } else {\n frame.finish(true);\n }\n return frame.result();\n }\n\n /**\n * Yield to other tasks for the specified time.\n * @param delay in milliseconds.\n * @return holds true\n */\n sleep(delay: number): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.sleep\");\n frame.suspend().schedule(true, delay);\n return frame.result();\n }\n\n /**\n * Repeatedly execute the given function asynchronously until it returns\n * false.\n * @return holds true.\n */\n loop(func: () => Result<boolean>): Result<boolean> {\n const frame = newFrame<boolean>(\"Frame.loop\");\n const step = (more) => {\n try {\n while (more) {\n const result = func();\n if (result.isPending()) {\n result.then(step);\n return;\n } else {\n result.then((m) => {\n more = m;\n });\n }\n }\n frame.finish(true);\n } catch (err) {\n frame.task.raise(err, frame);\n }\n };\n step(true);\n return frame.result();\n }\n\n /**\n * Similar to loop(), but provides a Frame for loop body function.\n * @return holds true.\n */\n loopWithFrame(func: (p1: LoopBodyFrame) => void): Result<boolean> {\n const task = privateCurrentTask;\n if (!task) {\n throw new Error(\"E_TASK_NO_CONTEXT\");\n }\n return this.loop(() => {\n let result: Result<boolean>;\n do {\n const frame = new LoopBodyFrame(task as Task, task.top);\n task.top = frame;\n frame.state = FrameState.ACTIVE;\n func(frame);\n result = frame.result();\n } while (!result.isPending() && result.get());\n return result;\n });\n }\n\n suspend(opt_waitTarget?: any): Continuation<T> {\n this.checkEnvironment();\n if (this.task.continuation) {\n throw new Error(\"E_TASK_ALREADY_SUSPENDED\");\n }\n const continuation: Continuation<T> = new Continuation(this.task);\n this.task.continuation = continuation;\n privateCurrentTask = null;\n this.task.waitTarget = opt_waitTarget || null;\n return continuation;\n }\n}\n\nexport class LoopBodyFrame extends Frame<boolean> {\n constructor(task: Task, parent: Frame<boolean>) {\n super(task, parent, \"loop\");\n }\n\n continueLoop(): void {\n this.finish(true);\n }\n\n breakLoop(): void {\n this.finish(false);\n }\n}\n\nexport class EventItem {\n next: EventItem = null;\n\n constructor(public event: Base.Event) {}\n}\n\n/**\n * An class to listen to evens and present them as a readable asynchronous\n * stream to tasks.\n */\nexport class EventSource {\n continuation: Continuation<boolean> = null;\n listeners: {\n target: Base.EventTarget;\n type: string;\n listener: Base.EventListener;\n }[] = [];\n head: EventItem;\n tail: EventItem;\n\n constructor() {\n this.head = new EventItem(null);\n this.tail = this.head;\n }\n\n /**\n * Attaches as an event listener to an EventTarget.\n */\n attach(\n target: Base.EventTarget,\n type: string,\n opt_preventDefault?: boolean,\n ): void {\n const self = this;\n const listener = (event) => {\n if (opt_preventDefault) {\n event.preventDefault();\n }\n if (self.tail.event) {\n self.tail.next = new EventItem(event);\n self.tail = self.tail.next;\n } else {\n self.tail.event = event;\n const continuation = self.continuation;\n if (continuation) {\n self.continuation = null;\n continuation.schedule(true);\n }\n }\n };\n target.addEventListener(type, listener, false);\n this.listeners.push({ target, type, listener });\n }\n\n detach(target: Base.EventTarget, type: string): void {\n let i = 0;\n let item: {\n target: Base.SimpleEventTarget;\n type: string;\n listener: Base.EventListener;\n } = null;\n while (i < this.listeners.length) {\n item = this.listeners[i];\n if (item.type == type && item.target === target) {\n this.listeners.splice(i, 1);\n item.target.removeEventListener(item.type, item.listener, false);\n return;\n }\n i++;\n }\n throw new Error(\"E_TASK_EVENT_SOURCE_NOT_ATTACHED\");\n }\n\n /**\n * Read next dispatched event, blocking the current task if needed.\n */\n nextEvent(): Result<Base.Event> {\n const frame: Frame<Base.Event> = newFrame(\"EventSource.nextEvent\");\n const self = this;\n const readEvent = () => {\n if (self.head.event) {\n const event = self.head.event;\n if (self.head.next) {\n self.head = self.head.next;\n } else {\n self.head.event = null;\n }\n frame.finish(event);\n } else if (self.continuation) {\n throw new Error(\"E_TASK_EVENT_SOURCE_OTHER_TASK_WAITING\");\n } else {\n const frameInternal: Frame<boolean> = newFrame(\n \"EventSource.nextEventInternal\",\n );\n self.continuation = frameInternal.suspend(self);\n frameInternal.result().then(readEvent);\n }\n };\n readEvent();\n return frame.result();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview TaskUtil - Utilities asynchronous execution and cooperative\n * multitasking.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\n\n/**\n * A class that can fetch or compute a resource that may be needed by multiple\n * tasks. The first time a resource is requested, it is fetched and then given\n * to everyone requesting it.\n * @template T\n * @param fetch function that fetches/computes\n * a resource; it will be run in a separate task.\n */\nexport class Fetcher<T> {\n name: string;\n arrived: boolean = false;\n resource: T = null;\n task: Task.Task = null;\n piggybacks: ((p1: any) => void)[] | null = [];\n\n constructor(public readonly fetch: () => Task.Result<T>, opt_name?: string) {\n this.name = opt_name;\n }\n\n /**\n * Start fetching/computing a resource, don't block current task.\n */\n start(): void {\n if (!this.task) {\n const self = this;\n this.task = Task.currentTask()\n .getScheduler()\n .run(() => {\n const frame = Task.newFrame(\"Fetcher.run\");\n self.fetch().then((resource) => {\n const piggibacks = self.piggybacks;\n self.arrived = true;\n self.resource = resource;\n self.task = null;\n self.piggybacks = [];\n if (piggibacks) {\n for (let i = 0; i < piggibacks.length; i++) {\n try {\n piggibacks[i](resource);\n } catch (err) {\n Logging.logger.error(err, \"Error:\");\n }\n }\n }\n frame.finish(resource);\n });\n return frame.result();\n }, this.name);\n }\n }\n\n piggyback(fn: (p1: T) => void): void {\n if (this.arrived) {\n fn(this.resource);\n } else {\n this.piggybacks.push(fn);\n }\n }\n\n /**\n * Fetches the resource, waits for it to arrive if it is already being\n * fetched.\n */\n get(): Task.Result<T> {\n if (this.arrived) {\n return Task.newResult(this.resource);\n }\n this.start();\n return this.task.join() as Task.Result<T>;\n }\n\n hasArrived(): boolean {\n return this.arrived;\n }\n}\n\n/**\n * Wait for all Fetcher objects in the array to arrive\n */\nexport const waitForFetchers = <T>(\n fetchers: Fetcher<T>[],\n): Task.Result<boolean> => {\n if (fetchers.length == 0) {\n return Task.newResult(true);\n }\n if (fetchers.length == 1) {\n return fetchers[0].get().thenReturn(true);\n }\n const frame = Task.newFrame<boolean>(\"waitForFetches\");\n let i = 0;\n frame\n .loop(() => {\n while (i < fetchers.length) {\n const fetcher = fetchers[i++];\n if (!fetcher.hasArrived()) {\n return fetcher.get().thenReturn(true);\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n};\n\n/**\n * @return holding event type (load/error/abort)\n */\nexport function loadElement(elem: Element, src: string): Fetcher<string> {\n let width: string | null = null;\n let height: string | null = null;\n if (elem.localName == \"img\") {\n width = elem.getAttribute(\"width\");\n height = elem.getAttribute(\"height\");\n }\n const fetcher = new Fetcher(() => {\n const frame: Task.Frame<string> = Task.newFrame(\"loadImage\");\n const continuation = frame.suspend(elem);\n let done = false;\n const handler = (evt: Event) => {\n if (done) {\n return;\n } else {\n done = true;\n }\n if (elem.localName == \"img\") {\n // IE puts these bogus attributes, even if they were not present\n if (!width) {\n elem.removeAttribute(\"width\");\n }\n if (!height) {\n elem.removeAttribute(\"height\");\n }\n }\n continuation.schedule(evt ? evt.type : \"timeout\");\n };\n elem.addEventListener(\"load\", handler, false);\n elem.addEventListener(\"error\", handler, false);\n elem.addEventListener(\"abort\", handler, false);\n if (elem.namespaceURI == Base.NS.SVG) {\n elem.setAttributeNS(Base.NS.XLINK, \"xlink:href\", src);\n\n // SVG handlers are not reliable\n setTimeout(handler, 300);\n } else {\n (elem as any).src = src;\n }\n return frame.result();\n }, `loadElement ${src}`);\n fetcher.start();\n return fetcher;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Net - Fetch resource from a URL.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport { Net, XmlDoc } from \"./types\";\nimport UserAgentXml from \"./assets/user-agent.xml\";\n\n/**\n * @enum {string}\n */\nexport enum XMLHttpRequestResponseType {\n DEFAULT = \"\",\n ARRAYBUFFER = \"arraybuffer\",\n BLOB = \"blob\",\n DOCUMENT = \"document\",\n JSON = \"json\",\n TEXT = \"text\",\n}\n\nexport type Response = Net.Response;\n\nexport function ajax(\n url: string,\n opt_type?: XMLHttpRequestResponseType,\n opt_method?: string,\n opt_data?: string,\n opt_contentType?: string,\n): Task.Result<Response> {\n const frame: Task.Frame<Response> = Task.newFrame(\"ajax\");\n const request = new XMLHttpRequest();\n const continuation = frame.suspend(request);\n const response: Response = {\n status: 0,\n statusText: \"\",\n url,\n contentType: null,\n responseText: null,\n responseXML: null,\n responseBlob: null,\n };\n request.open(opt_method || \"GET\", url, true);\n if (opt_type) {\n request.responseType = opt_type;\n }\n request.onreadystatechange = () => {\n if (request.readyState === 4) {\n response.status = request.status;\n response.statusText =\n request.statusText || (request.status == 404 && \"Not Found\") || \"\";\n if (response.status == 200 || response.status == 0) {\n if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.DOCUMENT) &&\n request.responseXML &&\n request.responseXML.documentElement.localName != \"parsererror\"\n ) {\n response.responseXML = request.responseXML;\n response.contentType = (request.responseXML as any).contentType;\n } else if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.DOCUMENT) &&\n request.response instanceof HTMLDocument\n ) {\n response.responseXML = request.response;\n response.contentType = (request.response as any).contentType;\n } else {\n const text = request.response;\n if (\n (!opt_type || opt_type === XMLHttpRequestResponseType.TEXT) &&\n typeof text == \"string\"\n ) {\n response.responseText = text;\n } else if (!text) {\n Logging.logger.warn(\"Unexpected empty success response for\", url);\n } else {\n if (typeof text == \"string\") {\n response.responseBlob = makeBlob([text]);\n } else {\n response.responseBlob = text as Blob;\n }\n }\n const contentTypeHeader = request.getResponseHeader(\"Content-Type\");\n if (contentTypeHeader) {\n response.contentType = contentTypeHeader.replace(/(.*);.*$/, \"$1\");\n }\n }\n }\n continuation.schedule(response);\n }\n };\n try {\n if (opt_data) {\n request.setRequestHeader(\n \"Content-Type\",\n opt_contentType || \"text/plain; charset=UTF-8\",\n );\n request.send(opt_data);\n } else {\n if (/^file:|^https?:\\/\\/[^/]+\\.githubusercontent\\.com|\\.opf$/.test(url)) {\n // File or GitHub raw URL or .opf\n if (\n /\\/aozorabunko\\/[^/]+\\/cards\\/[^/]+\\/files\\/[^/.]+\\.html$/.test(url)\n ) {\n // Aozorabunko's (X)HTML support\n request.overrideMimeType(\"text/html; charset=Shift_JIS\");\n } else if (/\\.(html|htm)$/.test(url)) {\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n } else if (/\\.(xhtml|xht|xml|opf)$/.test(url)) {\n request.overrideMimeType(\"application/xml; charset=UTF-8\");\n } else if (/\\.(txt|css)$/.test(url)) {\n request.overrideMimeType(\"text/plain; charset=UTF-8\");\n } else {\n // fallback to HTML\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n }\n } else if (/^data:,(<|%3C|%3c)/.test(url)) {\n request.overrideMimeType(\"text/html; charset=UTF-8\");\n } else if (/^data:,/.test(url)) {\n request.overrideMimeType(\"text/plain; charset=UTF-8\");\n }\n request.send(null);\n }\n } catch (e) {\n Logging.logger.warn(e, `Error fetching ${url}`);\n continuation.schedule(response);\n }\n return frame.result();\n}\n\n/**\n * @return Blob\n */\nexport function makeBlob(\n parts: (string | Blob | ArrayBuffer | ArrayBufferView)[],\n opt_type?: string,\n): any {\n const type = opt_type || \"application/octet-stream\";\n const builderCtr = window[\"WebKitBlobBuilder\"] || window[\"MSBlobBuilder\"]; // deprecated\n if (builderCtr) {\n const builder = new builderCtr();\n for (let i = 0; i < parts.length; i++) {\n builder.append(parts[i]);\n }\n return builder.getBlob(type);\n }\n return new Blob(parts, { type });\n}\n\n/**\n * @return Task.Result.<ArrayBuffer>\n */\nexport function readBlob(blob: Blob): any {\n const frame: Task.Frame<ArrayBuffer> = Task.newFrame(\"readBlob\");\n const fileReader = new FileReader();\n const continuation = frame.suspend(fileReader);\n fileReader.addEventListener(\n \"load\",\n () => {\n continuation.schedule(fileReader.result as ArrayBuffer);\n },\n false,\n );\n fileReader.readAsArrayBuffer(blob);\n return frame.result();\n}\n\nexport function revokeObjectURL(url: string): void {\n (window[\"URL\"] || window[\"webkitURL\"]).revokeObjectURL(url);\n}\n\n/**\n * @return url\n */\nexport function createObjectURL(blob: Blob): string {\n return (window[\"URL\"] || window[\"webkitURL\"]).createObjectURL(blob);\n}\n\n/**\n * @template Resource\n */\nexport class ResourceStore<Resource> implements Net.ResourceStore<Resource> {\n resources: { [key: string]: Resource } = {};\n fetchers: { [key: string]: TaskUtil.Fetcher<Resource> } = {};\n\n constructor(\n public readonly parser: (\n p1: Response,\n p2: ResourceStore<Resource>,\n ) => Task.Result<Resource>,\n public readonly type: XMLHttpRequestResponseType,\n ) {}\n\n /**\n * @return resource for the given URL\n */\n load(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource> {\n url = Base.stripFragment(url);\n const resource = this.resources[url];\n if (typeof resource != \"undefined\") {\n return Task.newResult(resource);\n }\n return this.fetch(url, opt_required, opt_message).get();\n }\n\n private fetchInner(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource> {\n const self = this;\n const frame: Task.Frame<Resource> = Task.newFrame(\"fetch\");\n\n // Hack for TOCView.showTOC()\n const isTocBox = url.endsWith(\"?viv-toc-box\");\n if (isTocBox) {\n url = url.replace(\"?viv-toc-box\", \"\");\n }\n const userAgentXmlUrl = Base.resolveURL(\n \"user-agent.xml\",\n Base.resourceBaseURL,\n );\n const isUserAgentXml = !isTocBox && url === userAgentXmlUrl;\n if (isUserAgentXml) {\n // Change \"user-agent.xml\" URL to data URL\n url = `data:application/xml,${encodeURIComponent(UserAgentXml)}`;\n }\n\n ajax(url, self.type).then((response) => {\n if (response.status >= 400) {\n if (opt_required) {\n throw new Error(\n (opt_message || `Failed to fetch required resource: ${url}`) +\n ` (${response.status}${\n response.statusText ? \" \" + response.statusText : \"\"\n })`,\n );\n }\n }\n if (isTocBox) {\n // Hack for TOCView.showTOC()\n url += \"?viv-toc-box\";\n response.url += \"?viv-toc-box\";\n } else if (isUserAgentXml) {\n // Restore \"user-agent.xml\" URL\n response.url = url = userAgentXmlUrl;\n }\n self.parser(response, self).then((resource) => {\n delete self.fetchers[url];\n self.resources[url] = resource;\n frame.finish(resource);\n });\n });\n return frame.result();\n }\n\n /**\n * @return fetcher for the resource for the given URL\n */\n fetch(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): TaskUtil.Fetcher<Resource> {\n url = Base.stripFragment(url);\n const resource = this.resources[url];\n if (resource) {\n return null;\n }\n let fetcher = this.fetchers[url];\n if (!fetcher) {\n const self = this;\n fetcher = new TaskUtil.Fetcher(\n () => self.fetchInner(url, opt_required, opt_message),\n `Fetch ${url}`,\n );\n self.fetchers[url] = fetcher;\n fetcher.start();\n }\n return fetcher;\n }\n\n get(url: string): XmlDoc.XMLDocHolder {\n const resource: unknown = this.resources[Base.stripFragment(url)];\n return resource as XmlDoc.XMLDocHolder;\n }\n\n delete(url: string) {\n delete this.resources[Base.stripFragment(url)];\n }\n}\n\nexport type JSONStore = ResourceStore<Base.JSON>;\n\nexport function parseJSONResource(\n response: Response,\n store: JSONStore,\n): Task.Result<Base.JSON> {\n const text = response.responseText;\n return Task.newResult(text ? Base.stringToJSON(text) : null);\n}\n\nexport function newJSONStore(): JSONStore {\n return new ResourceStore(parseJSONResource, XMLHttpRequestResponseType.TEXT);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssParser - CSS Parser.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\n\n/**\n * User agent stylesheet base specificity.\n */\nexport const SPECIFICITY_USER_AGENT: number = 0;\n\n/**\n * User stylesheet base specificity.\n */\nexport const SPECIFICITY_USER: number = 16777216;\n\n/**\n * Author stylesheet (\"normal\" stylesheet) base specificity.\n */\nexport const SPECIFICITY_AUTHOR: number = 33554432;\n\n/**\n * Style attribute base specificity.\n */\nexport const SPECIFICITY_STYLE: number = 50331648;\n\n/**\n * Style attribute base specificity when !important is used.\n */\nexport const SPECIFICITY_STYLE_IMPORTANT: number = 67108864;\n\n/**\n * Author stylesheet base specificity when !important is used.\n */\nexport const SPECIFICITY_AUTHOR_IMPORTANT: number = 83886080;\n\n/**\n * User stylesheet base specificity when !important is used.\n */\nexport const SPECIFICITY_USER_IMPORTANT: number = 100663296;\n\n/**\n * @enum {string}\n */\nexport enum StylesheetFlavor {\n USER_AGENT = \"UA\",\n USER = \"User\",\n AUTHOR = \"Author\",\n}\n\n/**\n * CSS Color value from hash text (without '#' character).\n */\nexport function colorFromHash(text: string): Css.Color {\n let num = parseInt(text, 16);\n if (isNaN(num)) {\n throw new Error(\"E_CSS_COLOR\");\n }\n if (text.length == 6) {\n return new Css.Color(num);\n }\n if (text.length == 3) {\n num =\n (num & 15) |\n ((num & 15) << 4) |\n ((num & 240) << 4) |\n ((num & 240) << 8) |\n ((num & 3840) << 8) |\n ((num & 3840) << 12);\n return new Css.Color(num);\n }\n throw new Error(\"E_CSS_COLOR\");\n}\n\nexport class ParserHandler implements CssTokenizer.TokenizerHandler {\n flavor: StylesheetFlavor;\n\n constructor(public scope: Exprs.LexicalScope) {\n this.flavor = StylesheetFlavor.AUTHOR;\n }\n\n getCurrentToken(): CssTokenizer.Token {\n return null;\n }\n\n getScope(): Exprs.LexicalScope {\n return this.scope;\n }\n\n error(mnemonics: string, token: CssTokenizer.Token): void {}\n\n startStylesheet(flavor: StylesheetFlavor): void {\n this.flavor = flavor;\n }\n\n tagSelector(ns: string | null, name: string | null): void {}\n\n classSelector(name: string): void {}\n\n pseudoclassSelector(name: string, params: (number | string)[]): void {}\n\n pseudoelementSelector(name: string, params: (number | string)[]): void {}\n\n idSelector(id: string): void {}\n\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {}\n\n descendantSelector(): void {}\n\n childSelector(): void {}\n\n adjacentSiblingSelector(): void {}\n\n followingSiblingSelector(): void {}\n\n nextSelector(): void {}\n\n startSelectorRule(): void {}\n\n startFontFaceRule(): void {}\n\n startFootnoteRule(pseudoelem: string | null): void {}\n\n startViewportRule(): void {}\n\n startDefineRule(): void {}\n\n startRegionRule(): void {}\n\n startPageRule(): void {}\n\n startPageMarginBoxRule(name: string): void {}\n\n startWhenRule(expr: Css.Expr): void {}\n\n startMediaRule(expr: Css.Expr): void {\n this.startWhenRule(expr);\n }\n\n startFlowRule(flowName: string): void {}\n\n startPageTemplateRule(): void {}\n\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {}\n\n startRuleBody(): void {}\n\n property(name: string, value: Css.Val, important: boolean): void {}\n\n endRule(): void {}\n\n /**\n * @param funcName The name of the function taking a selector list as an\n * argument\n */\n startFuncWithSelector(funcName: string): void {}\n\n endFuncWithSelector(): void {}\n\n getImportantSpecificity(): number {\n switch (this.flavor) {\n case StylesheetFlavor.USER_AGENT:\n return SPECIFICITY_USER_AGENT;\n case StylesheetFlavor.USER:\n return SPECIFICITY_USER_IMPORTANT;\n default:\n return SPECIFICITY_AUTHOR_IMPORTANT;\n }\n }\n\n getBaseSpecificity(): number {\n switch (this.flavor) {\n case StylesheetFlavor.USER_AGENT:\n return SPECIFICITY_USER_AGENT;\n case StylesheetFlavor.USER:\n return SPECIFICITY_USER;\n default:\n return SPECIFICITY_AUTHOR;\n }\n }\n}\n\nexport class DispatchParserHandler extends ParserHandler {\n stack: ParserHandler[] = [];\n tokenizer: CssTokenizer.Tokenizer = null;\n slave: ParserHandler = null;\n\n constructor() {\n super(null);\n }\n\n pushHandler(slave: ParserHandler): void {\n this.stack.push(this.slave);\n this.slave = slave;\n }\n\n popHandler(): void {\n this.slave = this.stack.pop();\n }\n\n /**\n * @override\n */\n getCurrentToken(): CssTokenizer.Token {\n if (this.tokenizer) {\n return this.tokenizer.token();\n }\n return null;\n }\n\n /**\n * @override\n */\n getScope(): Exprs.LexicalScope {\n return this.slave.getScope();\n }\n\n /**\n * Forwards call to slave.\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n this.slave.error(mnemonics, token);\n }\n\n /**\n * Called by a slave.\n */\n errorMsg(mnemonics: string, token: CssTokenizer.Token): void {\n Logging.logger.warn(mnemonics);\n }\n\n /**\n * @override\n */\n startStylesheet(flavor: StylesheetFlavor): void {\n super.startStylesheet(flavor);\n if (this.stack.length > 0) {\n // This can occur as a result of an error\n this.slave = this.stack[0];\n this.stack = [];\n }\n this.slave.startStylesheet(flavor);\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n this.slave.tagSelector(ns, name);\n }\n\n /**\n * @override\n */\n classSelector(name: string): void {\n this.slave.classSelector(name);\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n this.slave.pseudoclassSelector(name, params);\n }\n\n /**\n * @override\n */\n pseudoelementSelector(name: string, params: (number | string)[]): void {\n this.slave.pseudoelementSelector(name, params);\n }\n\n /**\n * @override\n */\n idSelector(id: string): void {\n this.slave.idSelector(id);\n }\n\n /**\n * @override\n */\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {\n this.slave.attributeSelector(ns, name, op, value);\n }\n\n /**\n * @override\n */\n descendantSelector(): void {\n this.slave.descendantSelector();\n }\n\n /**\n * @override\n */\n childSelector(): void {\n this.slave.childSelector();\n }\n\n /**\n * @override\n */\n adjacentSiblingSelector(): void {\n this.slave.adjacentSiblingSelector();\n }\n\n /**\n * @override\n */\n followingSiblingSelector(): void {\n this.slave.followingSiblingSelector();\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.slave.nextSelector();\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n this.slave.startSelectorRule();\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n this.slave.startFontFaceRule();\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n this.slave.startFootnoteRule(pseudoelem);\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n this.slave.startViewportRule();\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.slave.startDefineRule();\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.slave.startRegionRule();\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.slave.startPageRule();\n }\n\n /**\n * @override\n */\n startPageMarginBoxRule(name: string): void {\n this.slave.startPageMarginBoxRule(name);\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n this.slave.startWhenRule(expr);\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n this.slave.startFlowRule(flowName);\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {\n this.slave.startPageTemplateRule();\n }\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPageMasterRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPartitionRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.slave.startPartitionGroupRule(name, pseudoName, classes);\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.slave.startRuleBody();\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.slave.property(name, value, important);\n }\n\n /**\n * @override\n */\n endRule(): void {\n this.slave.endRule();\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n this.slave.startFuncWithSelector(funcName);\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n this.slave.endFuncWithSelector();\n }\n}\n\nexport class SkippingParserHandler extends ParserHandler {\n depth: number = 0;\n flavor: StylesheetFlavor;\n\n constructor(\n scope: Exprs.LexicalScope,\n public owner: DispatchParserHandler,\n public readonly topLevel,\n ) {\n super(scope);\n if (owner) {\n this.flavor = owner.flavor;\n }\n }\n\n /**\n * @override\n */\n getCurrentToken(): CssTokenizer.Token {\n return this.owner.getCurrentToken();\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n this.owner.errorMsg(mnemonics, token);\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.depth++;\n }\n\n /**\n * @override\n */\n endRule(): void {\n if (--this.depth == 0 && !this.topLevel) {\n this.owner.popHandler();\n }\n }\n}\n\nexport class SlaveParserHandler extends SkippingParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: DispatchParserHandler,\n topLevel: boolean,\n ) {\n super(scope, owner, topLevel);\n }\n\n report(message: string): void {\n this.error(message, this.getCurrentToken());\n }\n\n reportAndSkip(message: string): void {\n this.report(message);\n this.owner.pushHandler(\n new SkippingParserHandler(this.scope, this.owner, false),\n );\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_SELECTOR\");\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FONT_FACE\");\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FOOTNOTE\");\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_VIEWPORT\");\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_DEFINE\");\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_REGION\");\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE\");\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_WHEN\");\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_FLOW\");\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE_TEMPLATE\");\n }\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PAGE_MASTER\");\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PARTITION\");\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_PARTITION_GROUP\");\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_SELECTOR_FUNC\");\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_END_SELECTOR_FUNC\");\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.error(\"E_CSS_UNEXPECTED_PROPERTY\", this.getCurrentToken());\n }\n}\n\nexport const actionsBase: Action[] = [];\n\nexport const actionsStyleAttribute: Action[] = [];\n\nexport const actionsSelector: Action[] = [];\n\nexport const actionsSelectorInFunc: Action[] = [];\n\nexport const actionsSelectorCont: Action[] = [];\n\nexport const actionsSelectorStart: Action[] = [];\n\nexport const actionsPropVal: Action[] = [];\n\nexport const actionsExprVal: Action[] = [];\n\nexport const actionsExprOp: Action[] = [];\n\nexport const actionsError: Action[] = [];\n\nexport const actionsErrorDecl: Action[] = [];\n\nexport const actionsErrorSelector: Action[] = [];\n\nexport const priority: number[] = [];\n\n/**\n * @enum {number}\n */\nexport enum Action {\n SELECTOR_NAME_1 = 1,\n SELECTOR_NAME,\n SELECTOR_ANY_1,\n SELECTOR_ANY,\n SELECTOR_ID_1,\n SELECTOR_ID,\n SELECTOR_CLASS_1,\n SELECTOR_CLASS,\n SELECTOR_ATTR_1,\n SELECTOR_ATTR,\n SELECTOR_CHILD,\n SELECTOR_SIBLING,\n SELECTOR_BODY,\n SELECTOR_PSEUDOCLASS,\n VAL_IDENT,\n VAL_HASH,\n VAL_NUM,\n VAL_INT,\n VAL_NUMERIC,\n VAL_STR,\n VAL_URL,\n VAL_COMMA,\n VAL_SLASH,\n VAL_FUNC,\n VAL_C_PAR,\n VAL_END,\n RULE_END,\n IDENT,\n SELECTOR_START,\n AT,\n EXPR_IDENT,\n EXPR_NUM,\n EXPR_NUMERIC,\n EXPR_STR,\n EXPR_PARAM,\n EXPR_PREFIX,\n EXPR_INFIX,\n EXPR_FUNC,\n EXPR_C_PAR,\n EXPR_O_PAR,\n SELECTOR_NEXT,\n SELECTOR_PSEUDOELEM,\n EXPR_O_BRC,\n VAL_FINISH,\n EXPR_INFIX_NAME,\n PROP,\n VAL_BANG,\n VAL_BRC,\n EXPR_SEMICOL,\n ERROR_PUSH,\n ERROR_POP,\n ERROR_POP_DECL,\n ERROR_SEMICOL,\n VAL_PLUS,\n SELECTOR_PSEUDOCLASS_1,\n SELECTOR_FOLLOWING_SIBLING,\n DONE = 200,\n}\n\nexport const OP_MEDIA_AND: number = CssTokenizer.TokenType.LAST + 1;\n\n(() => {\n actionsBase[CssTokenizer.TokenType.IDENT] = Action.IDENT;\n actionsBase[CssTokenizer.TokenType.STAR] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.HASH] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.COLON] = Action.SELECTOR_START;\n actionsBase[CssTokenizer.TokenType.AT] = Action.AT;\n actionsBase[CssTokenizer.TokenType.C_BRC] = Action.RULE_END;\n actionsBase[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsStyleAttribute[CssTokenizer.TokenType.IDENT] = Action.PROP;\n actionsStyleAttribute[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsSelectorStart[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME;\n actionsSelectorStart[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY;\n actionsSelectorStart[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID;\n actionsSelectorStart[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS;\n actionsSelectorStart[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR;\n actionsSelectorStart[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS;\n\n actionsSelector[CssTokenizer.TokenType.GT] = Action.SELECTOR_CHILD;\n actionsSelector[CssTokenizer.TokenType.PLUS] = Action.SELECTOR_SIBLING;\n actionsSelector[CssTokenizer.TokenType.TILDE] =\n Action.SELECTOR_FOLLOWING_SIBLING;\n actionsSelector[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME_1;\n actionsSelector[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY_1;\n actionsSelector[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID_1;\n actionsSelector[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS_1;\n actionsSelector[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR_1;\n actionsSelector[CssTokenizer.TokenType.O_BRC] = Action.SELECTOR_BODY;\n actionsSelector[CssTokenizer.TokenType.COLON] = Action.SELECTOR_PSEUDOCLASS_1;\n actionsSelector[CssTokenizer.TokenType.COL_COL] = Action.SELECTOR_PSEUDOELEM;\n actionsSelector[CssTokenizer.TokenType.COMMA] = Action.SELECTOR_NEXT;\n actionsSelectorInFunc[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR_1;\n actionsSelectorInFunc[CssTokenizer.TokenType.C_PAR] = Action.DONE;\n actionsSelectorInFunc[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS_1;\n actionsSelectorCont[CssTokenizer.TokenType.IDENT] = Action.SELECTOR_NAME;\n actionsSelectorCont[CssTokenizer.TokenType.STAR] = Action.SELECTOR_ANY;\n actionsSelectorCont[CssTokenizer.TokenType.HASH] = Action.SELECTOR_ID;\n actionsSelectorCont[CssTokenizer.TokenType.CLASS] = Action.SELECTOR_CLASS;\n actionsSelectorCont[CssTokenizer.TokenType.COLON] =\n Action.SELECTOR_PSEUDOCLASS;\n actionsSelectorCont[CssTokenizer.TokenType.COL_COL] =\n Action.SELECTOR_PSEUDOELEM;\n actionsSelectorCont[CssTokenizer.TokenType.O_BRK] = Action.SELECTOR_ATTR;\n actionsSelectorCont[CssTokenizer.TokenType.O_BRC] = Action.SELECTOR_BODY;\n actionsPropVal[CssTokenizer.TokenType.IDENT] = Action.VAL_IDENT;\n actionsPropVal[CssTokenizer.TokenType.HASH] = Action.VAL_HASH;\n actionsPropVal[CssTokenizer.TokenType.NUM] = Action.VAL_NUM;\n actionsPropVal[CssTokenizer.TokenType.INT] = Action.VAL_INT;\n actionsPropVal[CssTokenizer.TokenType.NUMERIC] = Action.VAL_NUMERIC;\n actionsPropVal[CssTokenizer.TokenType.STR] = Action.VAL_STR;\n actionsPropVal[CssTokenizer.TokenType.URL] = Action.VAL_URL;\n actionsPropVal[CssTokenizer.TokenType.COMMA] = Action.VAL_COMMA;\n actionsPropVal[CssTokenizer.TokenType.SLASH] = Action.VAL_SLASH;\n actionsPropVal[CssTokenizer.TokenType.FUNC] = Action.VAL_FUNC;\n actionsPropVal[CssTokenizer.TokenType.C_PAR] = Action.VAL_C_PAR;\n actionsPropVal[CssTokenizer.TokenType.SEMICOL] = Action.VAL_END;\n actionsPropVal[CssTokenizer.TokenType.C_BRC] = Action.VAL_BRC;\n actionsPropVal[CssTokenizer.TokenType.BANG] = Action.VAL_BANG;\n actionsPropVal[CssTokenizer.TokenType.PLUS] = Action.VAL_PLUS;\n actionsPropVal[CssTokenizer.TokenType.EOF] = Action.VAL_FINISH;\n actionsExprVal[CssTokenizer.TokenType.IDENT] = Action.EXPR_IDENT;\n actionsExprVal[CssTokenizer.TokenType.NUM] = Action.EXPR_NUM;\n actionsExprVal[CssTokenizer.TokenType.INT] = Action.EXPR_NUM;\n actionsExprVal[CssTokenizer.TokenType.NUMERIC] = Action.EXPR_NUMERIC;\n actionsExprVal[CssTokenizer.TokenType.STR] = Action.EXPR_STR;\n actionsExprVal[CssTokenizer.TokenType.O_PAR] = Action.EXPR_O_PAR;\n actionsExprVal[CssTokenizer.TokenType.FUNC] = Action.EXPR_FUNC;\n actionsExprVal[CssTokenizer.TokenType.BANG] = Action.EXPR_PREFIX;\n actionsExprVal[CssTokenizer.TokenType.MINUS] = Action.EXPR_PREFIX;\n actionsExprVal[CssTokenizer.TokenType.DOLLAR] = Action.EXPR_PARAM;\n actionsExprOp[CssTokenizer.TokenType.IDENT] = Action.EXPR_INFIX_NAME;\n actionsExprOp[CssTokenizer.TokenType.COMMA] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.GT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.LT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.GT_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.LT_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.EQ_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.BANG_EQ] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.AMP_AMP] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.BAR_BAR] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.PLUS] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.MINUS] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.SLASH] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.PERCENT] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.STAR] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.COLON] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.QMARK] = Action.EXPR_INFIX;\n actionsExprOp[CssTokenizer.TokenType.C_PAR] = Action.EXPR_C_PAR;\n actionsExprOp[CssTokenizer.TokenType.O_BRC] = Action.EXPR_O_BRC;\n actionsExprOp[CssTokenizer.TokenType.SEMICOL] = Action.EXPR_SEMICOL;\n actionsError[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsError[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsError[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n actionsError[CssTokenizer.TokenType.SEMICOL] = Action.ERROR_SEMICOL;\n actionsErrorDecl[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsErrorDecl[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP_DECL;\n actionsErrorDecl[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsErrorDecl[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsErrorDecl[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n actionsErrorDecl[CssTokenizer.TokenType.SEMICOL] = Action.ERROR_SEMICOL;\n actionsErrorSelector[CssTokenizer.TokenType.EOF] = Action.DONE;\n actionsErrorSelector[CssTokenizer.TokenType.O_BRC] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_BRC] = Action.ERROR_POP;\n actionsErrorSelector[CssTokenizer.TokenType.O_BRK] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_BRK] = Action.ERROR_POP;\n actionsErrorSelector[CssTokenizer.TokenType.O_PAR] = Action.ERROR_PUSH;\n actionsErrorSelector[CssTokenizer.TokenType.C_PAR] = Action.ERROR_POP;\n priority[CssTokenizer.TokenType.C_PAR] = 0;\n priority[CssTokenizer.TokenType.COMMA] = 0;\n priority[CssTokenizer.TokenType.QMARK] = 1;\n priority[CssTokenizer.TokenType.COLON] = 1;\n priority[CssTokenizer.TokenType.AMP_AMP] = 2;\n priority[CssTokenizer.TokenType.BAR_BAR] = 2;\n priority[CssTokenizer.TokenType.LT] = 3;\n priority[CssTokenizer.TokenType.GT] = 3;\n priority[CssTokenizer.TokenType.LT_EQ] = 3;\n priority[CssTokenizer.TokenType.GT_EQ] = 3;\n priority[CssTokenizer.TokenType.EQ] = 3;\n priority[CssTokenizer.TokenType.EQ_EQ] = 3;\n priority[CssTokenizer.TokenType.BANG_EQ] = 3;\n priority[CssTokenizer.TokenType.PLUS] = 4;\n priority[CssTokenizer.TokenType.MINUS] = 4;\n priority[CssTokenizer.TokenType.STAR] = 5;\n priority[CssTokenizer.TokenType.SLASH] = 5;\n priority[CssTokenizer.TokenType.PERCENT] = 5;\n priority[CssTokenizer.TokenType.EOF] = 6;\n priority[OP_MEDIA_AND] = 2;\n})();\n\n/**\n * @enum {number}\n */\nexport enum ExprContext {\n PROP,\n WHEN,\n MEDIA,\n IMPORT,\n}\n\nexport class Parser {\n valStack: any[] = [];\n namespacePrefixToURI: { [key: string]: string } = {};\n defaultNamespaceURI: string | null = null;\n propName: string | null = null;\n propImportant: boolean = false;\n exprContext: ExprContext;\n result: Css.Val = null;\n importReady: boolean = false;\n importURL: string | null = null;\n importCondition: Css.Expr = null;\n errorBrackets: number[] = [];\n ruleStack: string[] = [];\n regionRule: boolean = false;\n pageRule: boolean = false;\n\n constructor(\n public actions: Action[],\n public tokenizer: CssTokenizer.Tokenizer,\n public readonly handler: ParserHandler,\n public baseURL: string,\n ) {\n this.exprContext = ExprContext.MEDIA;\n }\n\n extractVals(sep: string, index: number): Css.Val[] {\n const arr: Css.Val[] = [];\n const valStack = this.valStack;\n while (true) {\n arr.push(valStack[index++] as Css.Val);\n if (index == valStack.length) {\n break;\n }\n if (valStack[index++] != sep) {\n throw new Error(\"Unexpected state\");\n }\n }\n return arr;\n }\n\n valStackReduce(sep: string, token: CssTokenizer.Token): Css.Val {\n const valStack = this.valStack;\n let index = valStack.length;\n let v;\n do {\n v = valStack[--index];\n } while (typeof v != \"undefined\" && typeof v != \"string\");\n let count = valStack.length - (index + 1);\n if (count > 1) {\n valStack.splice(\n index + 1,\n count,\n new Css.SpaceList(valStack.slice(index + 1, valStack.length)),\n );\n }\n if (sep == \",\") {\n return null;\n }\n index++;\n do {\n v = valStack[--index];\n } while (typeof v != \"undefined\" && (typeof v != \"string\" || v == \",\"));\n count = valStack.length - (index + 1);\n if (v == \"(\") {\n if (sep != \")\") {\n this.handler.error(\"E_CSS_MISMATCHED_C_PAR\", token);\n this.actions = actionsErrorDecl;\n return null;\n }\n const func = new Css.Func(\n valStack[index - 1] as string,\n this.extractVals(\",\", index + 1),\n );\n valStack.splice(index - 1, count + 2, func);\n return null;\n }\n if (sep != \";\" || index >= 0) {\n this.handler.error(\"E_CSS_UNEXPECTED_VAL_END\", token);\n this.actions = actionsErrorDecl;\n return null;\n }\n if (count > 1) {\n return new Css.CommaList(this.extractVals(\",\", index + 1));\n }\n return valStack[0] as Css.Val;\n }\n\n exprError(mnemonics: string, token: CssTokenizer.Token) {\n this.actions = this.propName ? actionsErrorDecl : actionsError;\n this.handler.error(mnemonics, token);\n }\n\n exprStackReduce(op: number, token: CssTokenizer.Token): boolean {\n const valStack = this.valStack;\n const handler = this.handler;\n let val = valStack.pop() as Exprs.Val;\n let val2: Exprs.Val;\n while (true) {\n let tok = valStack.pop();\n if (op == CssTokenizer.TokenType.C_PAR) {\n const args: Exprs.Val[] = [val];\n while (tok == CssTokenizer.TokenType.COMMA) {\n args.unshift(valStack.pop());\n tok = valStack.pop();\n }\n if (typeof tok == \"string\") {\n if (tok == \"{\") {\n // reached CSS portion of the stack\n while (args.length >= 2) {\n const e1 = args.shift();\n const e2 = args.shift();\n const er = new Exprs.OrMedia(handler.getScope(), e1, e2);\n args.unshift(er);\n }\n valStack.push(new Css.Expr(args[0]));\n return true;\n } else if (tok == \"(\") {\n // call\n const name2 = valStack.pop() as string;\n const name1 = valStack.pop() as string | null;\n val = new Exprs.Call(\n handler.getScope(),\n Exprs.makeQualifiedName(name1, name2),\n args,\n );\n op = CssTokenizer.TokenType.EOF;\n continue;\n }\n }\n if (tok == CssTokenizer.TokenType.O_PAR) {\n if (val.isMediaName()) {\n val = new Exprs.MediaTest(\n handler.getScope(),\n val as Exprs.MediaName,\n null,\n );\n }\n op = CssTokenizer.TokenType.EOF;\n continue;\n }\n } else {\n if (typeof tok == \"string\") {\n // reached CSS portion of the stack or a call\n valStack.push(tok);\n break;\n }\n }\n if ((tok as number) < 0) {\n // prefix\n if (tok == -CssTokenizer.TokenType.BANG) {\n val = new Exprs.Not(handler.getScope(), val);\n } else if (tok == -CssTokenizer.TokenType.MINUS) {\n val = new Exprs.Negate(handler.getScope(), val);\n } else {\n this.exprError(\"F_UNEXPECTED_STATE\", token);\n return false;\n }\n } else {\n // infix\n if (priority[op] > priority[tok as number]) {\n valStack.push(tok);\n break;\n }\n val2 = valStack.pop() as Exprs.Val;\n switch (tok) {\n case CssTokenizer.TokenType.AMP_AMP:\n val = new Exprs.And(handler.getScope(), val2, val);\n break;\n case OP_MEDIA_AND:\n val = new Exprs.AndMedia(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.BAR_BAR:\n val = new Exprs.Or(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.LT:\n val = new Exprs.Lt(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.GT:\n val = new Exprs.Gt(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.LT_EQ:\n val = new Exprs.Le(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.GT_EQ:\n val = new Exprs.Ge(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.EQ:\n case CssTokenizer.TokenType.EQ_EQ:\n val = new Exprs.Eq(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.BANG_EQ:\n val = new Exprs.Ne(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.PLUS:\n val = new Exprs.Add(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.MINUS:\n val = new Exprs.Subtract(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.STAR:\n val = new Exprs.Multiply(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.SLASH:\n val = new Exprs.Divide(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.PERCENT:\n val = new Exprs.Modulo(handler.getScope(), val2, val);\n break;\n case CssTokenizer.TokenType.COLON:\n if (valStack.length > 1) {\n switch (valStack[valStack.length - 1]) {\n case CssTokenizer.TokenType.QMARK:\n valStack.pop();\n val = new Exprs.Cond(\n handler.getScope(),\n valStack.pop() as Exprs.Val,\n val2,\n val,\n );\n break;\n case CssTokenizer.TokenType.O_PAR:\n if (val2.isMediaName()) {\n val = new Exprs.MediaTest(\n handler.getScope(),\n val2 as Exprs.MediaName,\n val,\n );\n } else {\n this.exprError(\"E_CSS_MEDIA_TEST\", token);\n return false;\n }\n break;\n }\n } else {\n this.exprError(\"E_CSS_EXPR_COND\", token);\n return false;\n }\n break;\n case CssTokenizer.TokenType.QMARK:\n if (op != CssTokenizer.TokenType.COLON) {\n this.exprError(\"E_CSS_EXPR_COND\", token);\n return false;\n }\n\n // fall through\n case CssTokenizer.TokenType.O_PAR:\n // don't reduce\n valStack.push(val2);\n valStack.push(tok);\n valStack.push(val);\n return false;\n default:\n this.exprError(\"F_UNEXPECTED_STATE\", token);\n return false;\n }\n }\n }\n valStack.push(val);\n return false;\n }\n\n readPseudoParams(): (number | string)[] {\n const arr = [];\n while (true) {\n const token = this.tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n arr.push(token.text);\n break;\n case CssTokenizer.TokenType.PLUS:\n arr.push(\"+\");\n break;\n case CssTokenizer.TokenType.NUM:\n case CssTokenizer.TokenType.INT:\n arr.push(token.num);\n break;\n default:\n return arr;\n }\n this.tokenizer.consume();\n }\n }\n\n /**\n * Read `an+b` argument of pseudoclasses. Roughly based on the algorithm at\n * https://drafts.csswg.org/css-syntax/#the-anb-type\n */\n private readNthPseudoParams(): number[] | null {\n let hasLeadingPlus = false;\n let token = this.tokenizer.token();\n if (token.type === CssTokenizer.TokenType.PLUS) {\n // '+'\n hasLeadingPlus = true;\n this.tokenizer.consume();\n token = this.tokenizer.token();\n } else if (\n token.type === CssTokenizer.TokenType.IDENT &&\n (token.text === \"even\" || token.text === \"odd\")\n ) {\n // 'even' or 'odd'\n this.tokenizer.consume();\n return [2, token.text === \"odd\" ? 1 : 0];\n }\n switch (token.type) {\n case CssTokenizer.TokenType.NUMERIC:\n if (hasLeadingPlus && token.num < 0) {\n // reject '+-an'\n return null;\n }\n\n // FALLTHROUGH\n case CssTokenizer.TokenType.IDENT:\n if (hasLeadingPlus && token.text.charAt(0) === \"-\") {\n // reject '+-n'\n return null;\n }\n if (token.text === \"n\" || token.text === \"-n\") {\n // 'an', 'an +b', 'an -b', 'n', 'n +b', 'n -b', '-n', '-n +b' '-n -b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an'\n return null;\n }\n let a = token.text === \"-n\" ? -1 : 1;\n if (token.type === CssTokenizer.TokenType.NUMERIC) {\n a = token.num;\n }\n let b = 0;\n this.tokenizer.consume();\n token = this.tokenizer.token();\n const hasMinusSign = token.type === CssTokenizer.TokenType.MINUS;\n const hasSign =\n token.type === CssTokenizer.TokenType.PLUS || hasMinusSign;\n if (hasSign) {\n // 'an +b', 'an - b'\n this.tokenizer.consume();\n token = this.tokenizer.token();\n }\n if (token.type === CssTokenizer.TokenType.INT) {\n b = token.num;\n\n if (1 / b === 1 / -0) {\n // negative zero: 'an -0'\n b = 0;\n if (hasSign) {\n return null; // reject 'an + -0', 'an - -0'\n }\n } else if (b < 0) {\n // negative: 'an -b'\n if (hasSign) {\n return null; // reject 'an + -b', 'an - -b'\n }\n } else if (b >= 0) {\n // positive or positive zero: 'an +b'\n if (!hasSign) {\n return null;\n }\n }\n this.tokenizer.consume();\n } else if (hasSign) {\n // reject 'an + (non-integer)'\n return null;\n }\n return [a, hasMinusSign && b > 0 ? -b : b];\n } else if (token.text === \"n-\" || token.text === \"-n-\") {\n // 'an- b', '-n- b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an- b'\n return null;\n }\n let a = token.text === \"-n-\" ? -1 : 1;\n if (token.type === CssTokenizer.TokenType.NUMERIC) {\n a = token.num;\n }\n this.tokenizer.consume();\n token = this.tokenizer.token();\n if (token.type === CssTokenizer.TokenType.INT) {\n if (token.num < 0 || 1 / token.num === 1 / -0) {\n // reject 'an- -b', 'an- -0'\n return null;\n } else {\n this.tokenizer.consume();\n return [a, token.num];\n }\n }\n } else {\n let r = token.text.match(/^n(-[0-9]+)$/);\n if (r) {\n // 'n-b', 'an-b'\n if (hasLeadingPlus && token.precededBySpace) {\n // reject '+ an-b'\n return null;\n }\n this.tokenizer.consume();\n return [\n token.type === CssTokenizer.TokenType.NUMERIC ? token.num : 1,\n parseInt(r[1], 10),\n ];\n }\n r = token.text.match(/^-n(-[0-9]+)$/);\n\n // '-n-b'\n if (r) {\n this.tokenizer.consume();\n return [-1, parseInt(r[1], 10)];\n }\n }\n return null;\n case CssTokenizer.TokenType.INT:\n if (hasLeadingPlus && (token.precededBySpace || token.num < 0)) {\n return null;\n }\n this.tokenizer.consume();\n return [0, token.num];\n }\n return null;\n }\n\n makeCondition(classes: string | null, condition: Exprs.Val): Css.Expr {\n const scope = this.handler.getScope();\n if (!scope) {\n return null;\n }\n condition = condition || scope._true;\n if (classes) {\n const classList = classes.split(/\\s+/);\n for (const className of classList) {\n switch (className) {\n case \"vertical\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Not(scope, new Exprs.Named(scope, \"pref-horizontal\")),\n );\n break;\n case \"horizontal\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Named(scope, \"pref-horizontal\"),\n );\n break;\n case \"day\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Not(scope, new Exprs.Named(scope, \"pref-night-mode\")),\n );\n break;\n case \"night\":\n condition = Exprs.and(\n scope,\n condition,\n new Exprs.Named(scope, \"pref-night-mode\"),\n );\n break;\n default:\n condition = scope._false;\n }\n }\n }\n if (condition === scope._true) {\n return null;\n }\n return new Css.Expr(condition);\n }\n\n isInsidePropertyOnlyRule(): boolean {\n switch (this.ruleStack[this.ruleStack.length - 1]) {\n case \"[selector]\":\n case \"font-face\":\n case \"-epubx-flow\":\n case \"-epubx-viewport\":\n case \"-epubx-define\":\n case \"-adapt-footnote-area\":\n return true;\n }\n return false;\n }\n\n runParser(\n count: number,\n parsingValue,\n parsingStyleAttr: boolean,\n parsingMediaQuery,\n parsingFunctionParam,\n ): boolean {\n const handler = this.handler;\n const tokenizer = this.tokenizer;\n const valStack = this.valStack;\n let token: CssTokenizer.Token;\n let token1: CssTokenizer.Token;\n let ns: string | null;\n let text: string | null;\n let num: number;\n let val: Css.Val;\n let params: (number | string)[];\n if (parsingMediaQuery) {\n this.exprContext = ExprContext.MEDIA;\n this.valStack.push(\"{\");\n }\n parserLoop: for (; count > 0; --count) {\n token = tokenizer.token();\n switch (this.actions[token.type]) {\n case Action.IDENT:\n // figure out if this is a property assignment or selector\n if (tokenizer.nthToken(1).type != CssTokenizer.TokenType.COLON) {\n // cannot be property assignment\n if (this.isInsidePropertyOnlyRule()) {\n handler.error(\"E_CSS_COLON_EXPECTED\", tokenizer.nthToken(1));\n this.actions = actionsErrorDecl;\n } else {\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n }\n continue;\n }\n token1 = tokenizer.nthToken(2);\n if (\n token1.precededBySpace ||\n (token1.type != CssTokenizer.TokenType.IDENT &&\n token1.type != CssTokenizer.TokenType.FUNC)\n ) {\n // cannot be a selector\n } else {\n // can be either a selector or a property assignment\n tokenizer.mark();\n }\n this.propName = token.text;\n this.propImportant = false;\n tokenizer.consume();\n tokenizer.consume();\n this.actions = actionsPropVal;\n valStack.splice(0, valStack.length);\n continue;\n case Action.PROP:\n // figure out if this is a property assignment or selector\n if (tokenizer.nthToken(1).type != CssTokenizer.TokenType.COLON) {\n // cannot be property assignment\n this.actions = actionsErrorDecl;\n handler.error(\"E_CSS_COLON_EXPECTED\", tokenizer.nthToken(1));\n continue;\n }\n this.propName = token.text;\n this.propImportant = false;\n tokenizer.consume();\n tokenizer.consume();\n this.actions = actionsPropVal;\n valStack.splice(0, valStack.length);\n continue;\n case Action.SELECTOR_START:\n // don't consume, process again\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n case Action.SELECTOR_NAME_1:\n if (!token.precededBySpace) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_SPACE_EXPECTED\", token);\n continue;\n }\n handler.descendantSelector();\n\n // fall through\n case Action.SELECTOR_NAME:\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.BAR) {\n tokenizer.consume();\n tokenizer.consume();\n ns = this.namespacePrefixToURI[token.text];\n if (ns != null) {\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.tagSelector(ns, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n case CssTokenizer.TokenType.STAR:\n handler.tagSelector(ns, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n default:\n this.actions = actionsError;\n handler.error(\"E_CSS_NAMESPACE\", token);\n }\n } else {\n this.actions = actionsError;\n handler.error(\"E_CSS_UNDECLARED_PREFIX\", token);\n }\n } else {\n handler.tagSelector(this.defaultNamespaceURI, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n }\n continue;\n case Action.SELECTOR_ANY_1:\n if (!token.precededBySpace) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_SPACE_EXPECTED\", token);\n continue;\n }\n handler.descendantSelector();\n\n // fall through\n case Action.SELECTOR_ANY:\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.BAR) {\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.tagSelector(null, token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n case CssTokenizer.TokenType.STAR:\n handler.tagSelector(null, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n break;\n default:\n this.actions = actionsError;\n handler.error(\"E_CSS_NAMESPACE\", token);\n }\n } else {\n handler.tagSelector(this.defaultNamespaceURI, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n }\n continue;\n case Action.SELECTOR_ID_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_ID:\n handler.idSelector(token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_CLASS_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_CLASS:\n handler.classSelector(token.text);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_PSEUDOCLASS_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_PSEUDOCLASS:\n tokenizer.consume();\n token = tokenizer.token();\n pseudoclassType: switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.pseudoclassSelector(token.text, null);\n tokenizer.consume();\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n continue;\n case CssTokenizer.TokenType.FUNC:\n text = token.text;\n tokenizer.consume();\n switch (text) {\n case \"not\":\n this.actions = actionsSelectorStart;\n handler.startFuncWithSelector(\"not\");\n if (\n this.runParser(\n Number.POSITIVE_INFINITY,\n false,\n false,\n false,\n true,\n )\n ) {\n this.actions = actionsSelector;\n } else {\n this.actions = actionsErrorSelector;\n }\n break parserLoop;\n case \"lang\":\n case \"href-epub-type\":\n token = tokenizer.token();\n if (token.type === CssTokenizer.TokenType.IDENT) {\n params = [token.text];\n tokenizer.consume();\n break;\n } else {\n break pseudoclassType;\n }\n case \"nth-child\":\n case \"nth-of-type\":\n case \"nth-last-child\":\n case \"nth-last-of-type\":\n params = this.readNthPseudoParams();\n if (!params) {\n break pseudoclassType;\n } else {\n break;\n }\n default:\n // TODO\n params = this.readPseudoParams();\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.C_PAR) {\n handler.pseudoclassSelector(text as string, params);\n tokenizer.consume();\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_PSEUDOCLASS_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case Action.SELECTOR_PSEUDOELEM:\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n handler.pseudoelementSelector(token.text, null);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case CssTokenizer.TokenType.FUNC:\n text = token.text;\n tokenizer.consume();\n if (text == \"nth-fragment\") {\n params = this.readNthPseudoParams();\n if (params === null) {\n break;\n }\n } else {\n params = this.readPseudoParams();\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.C_PAR) {\n handler.pseudoelementSelector(text as string, params);\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_PSEUDOELEM_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case Action.SELECTOR_ATTR_1:\n if (token.precededBySpace) {\n handler.descendantSelector();\n }\n\n // fall through\n case Action.SELECTOR_ATTR:\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.IDENT) {\n text = token.text;\n tokenizer.consume();\n } else if (token.type == CssTokenizer.TokenType.STAR) {\n text = null;\n tokenizer.consume();\n } else if (token.type == CssTokenizer.TokenType.BAR) {\n text = \"\";\n } else {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR\", token);\n tokenizer.consume();\n continue;\n }\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.BAR) {\n ns = text ? this.namespacePrefixToURI[text] : text;\n if (ns == null) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_UNDECLARED_PREFIX\", token);\n tokenizer.consume();\n continue;\n }\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type != CssTokenizer.TokenType.IDENT) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_NAME_EXPECTED\", token);\n continue;\n }\n text = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n } else {\n ns = \"\";\n }\n switch (token.type) {\n case CssTokenizer.TokenType.EQ:\n case CssTokenizer.TokenType.TILDE_EQ:\n case CssTokenizer.TokenType.BAR_EQ:\n case CssTokenizer.TokenType.HAT_EQ:\n case CssTokenizer.TokenType.DOLLAR_EQ:\n case CssTokenizer.TokenType.STAR_EQ:\n case CssTokenizer.TokenType.COL_COL:\n num = token.type;\n tokenizer.consume();\n token = tokenizer.token();\n break;\n case CssTokenizer.TokenType.C_BRK:\n handler.attributeSelector(\n ns as string,\n text as string,\n CssTokenizer.TokenType.EOF,\n null,\n );\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n default:\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_OP_EXPECTED\", token);\n continue;\n }\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n case CssTokenizer.TokenType.STR:\n handler.attributeSelector(\n ns as string,\n text as string,\n num,\n token.text,\n );\n tokenizer.consume();\n token = tokenizer.token();\n break;\n default:\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR_VAL_EXPECTED\", token);\n continue;\n }\n if (token.type != CssTokenizer.TokenType.C_BRK) {\n this.actions = actionsErrorSelector;\n handler.error(\"E_CSS_ATTR\", token);\n continue;\n }\n if (parsingFunctionParam) {\n this.actions = actionsSelectorInFunc;\n } else {\n this.actions = actionsSelector;\n }\n tokenizer.consume();\n continue;\n case Action.SELECTOR_CHILD:\n handler.childSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_SIBLING:\n handler.adjacentSiblingSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_FOLLOWING_SIBLING:\n handler.followingSiblingSelector();\n this.actions = actionsSelectorCont;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_BODY:\n if (this.regionRule) {\n this.ruleStack.push(\"-epubx-region\");\n this.regionRule = false;\n } else if (this.pageRule) {\n this.ruleStack.push(\"page\");\n this.pageRule = false;\n } else {\n this.ruleStack.push(\"[selector]\");\n }\n handler.startRuleBody();\n this.actions = actionsBase;\n tokenizer.consume();\n continue;\n case Action.SELECTOR_NEXT:\n handler.nextSelector();\n this.actions = actionsSelectorStart;\n tokenizer.consume();\n continue;\n case Action.VAL_IDENT:\n valStack.push(Css.getName(token.text));\n tokenizer.consume();\n continue;\n case Action.VAL_HASH:\n num = parseInt(token.text, 16);\n try {\n valStack.push(colorFromHash(token.text));\n } catch (err) {\n handler.error(\"E_CSS_COLOR\", token);\n this.actions = actionsError;\n }\n tokenizer.consume();\n continue;\n case Action.VAL_NUM:\n valStack.push(new Css.Num(token.num));\n tokenizer.consume();\n continue;\n case Action.VAL_INT:\n valStack.push(new Css.Int(token.num));\n tokenizer.consume();\n continue;\n case Action.VAL_NUMERIC:\n if (Exprs.isViewportRelativeLengthUnit(token.text)) {\n // Treat numeric value with viewport unit as numeric in expr.\n valStack.push(\n new Css.Expr(\n new Exprs.Numeric(handler.getScope(), token.num, token.text),\n ),\n );\n } else {\n valStack.push(new Css.Numeric(token.num, token.text));\n }\n tokenizer.consume();\n continue;\n case Action.VAL_STR:\n valStack.push(new Css.Str(token.text));\n tokenizer.consume();\n continue;\n case Action.VAL_URL:\n valStack.push(new Css.URL(Base.resolveURL(token.text, this.baseURL)));\n tokenizer.consume();\n continue;\n case Action.VAL_COMMA:\n this.valStackReduce(\",\", token);\n valStack.push(\",\");\n tokenizer.consume();\n continue;\n case Action.VAL_SLASH:\n valStack.push(Css.slash);\n tokenizer.consume();\n continue;\n case Action.VAL_FUNC:\n text = token.text.toLowerCase();\n if (text == \"-epubx-expr\" || text == \"calc\" || text == \"env\") {\n // special case\n this.actions = actionsExprVal;\n this.exprContext = ExprContext.PROP;\n valStack.push(\"{\");\n } else {\n valStack.push(text);\n valStack.push(\"(\");\n }\n tokenizer.consume();\n continue;\n case Action.VAL_C_PAR:\n this.valStackReduce(\")\", token);\n tokenizer.consume();\n continue;\n case Action.VAL_BANG:\n tokenizer.consume();\n token = tokenizer.token();\n token1 = tokenizer.nthToken(1);\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n token.text.toLowerCase() == \"important\" &&\n (token1.type == CssTokenizer.TokenType.SEMICOL ||\n token1.type == CssTokenizer.TokenType.EOF ||\n token1.type == CssTokenizer.TokenType.C_BRC)\n ) {\n tokenizer.consume();\n this.propImportant = true;\n continue;\n }\n this.exprError(\"E_CSS_SYNTAX\", token);\n continue;\n case Action.VAL_PLUS:\n token1 = tokenizer.nthToken(1);\n switch (token1.type) {\n case CssTokenizer.TokenType.NUM:\n case CssTokenizer.TokenType.NUMERIC:\n case CssTokenizer.TokenType.INT:\n if (!token1.precededBySpace) {\n // Plus before number, ignore\n tokenizer.consume();\n continue;\n }\n }\n if (this.actions === actionsPropVal && tokenizer.hasMark()) {\n tokenizer.reset();\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n } else {\n this.exprError(\"E_CSS_UNEXPECTED_PLUS\", token);\n continue;\n }\n case Action.VAL_END:\n tokenizer.consume();\n\n // fall through\n case Action.VAL_BRC:\n tokenizer.unmark();\n val = this.valStackReduce(\";\", token);\n if (val && this.propName) {\n handler.property(this.propName as string, val, this.propImportant);\n }\n this.actions = parsingStyleAttr ? actionsStyleAttribute : actionsBase;\n continue;\n case Action.VAL_FINISH:\n tokenizer.consume();\n tokenizer.unmark();\n val = this.valStackReduce(\";\", token);\n if (parsingValue) {\n this.result = val;\n return true;\n }\n if (this.propName && val) {\n handler.property(this.propName as string, val, this.propImportant);\n }\n if (parsingStyleAttr) {\n return true;\n }\n this.exprError(\"E_CSS_SYNTAX\", token);\n continue;\n case Action.EXPR_IDENT:\n token1 = tokenizer.nthToken(1);\n if (token1.type == CssTokenizer.TokenType.CLASS) {\n if (\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.O_PAR &&\n !tokenizer.nthToken(2).precededBySpace\n ) {\n valStack.push(token.text, token1.text, \"(\");\n tokenizer.consume();\n } else {\n valStack.push(\n new Exprs.Named(\n handler.getScope(),\n Exprs.makeQualifiedName(token.text, token1.text),\n ),\n );\n this.actions = actionsExprOp;\n }\n tokenizer.consume();\n } else {\n if (\n this.exprContext == ExprContext.MEDIA ||\n this.exprContext == ExprContext.IMPORT\n ) {\n if (token.text.toLowerCase() == \"not\") {\n tokenizer.consume();\n valStack.push(\n new Exprs.MediaName(handler.getScope(), true, token1.text),\n );\n } else {\n if (token.text.toLowerCase() == \"only\") {\n tokenizer.consume();\n token = token1;\n }\n valStack.push(\n new Exprs.MediaName(handler.getScope(), false, token.text),\n );\n }\n } else {\n valStack.push(new Exprs.Named(handler.getScope(), token.text));\n }\n this.actions = actionsExprOp;\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_FUNC:\n valStack.push(null, token.text, \"(\");\n tokenizer.consume();\n continue;\n case Action.EXPR_NUM:\n valStack.push(new Exprs.Const(handler.getScope(), token.num));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_NUMERIC:\n text = token.text;\n if (text == \"%\") {\n if (this.propName && this.propName.match(/height|^(top|bottom)$/)) {\n text = \"vh\";\n } else {\n text = \"vw\";\n }\n }\n valStack.push(new Exprs.Numeric(handler.getScope(), token.num, text));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_STR:\n valStack.push(new Exprs.Const(handler.getScope(), token.text));\n tokenizer.consume();\n this.actions = actionsExprOp;\n continue;\n case Action.EXPR_PARAM:\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type != CssTokenizer.TokenType.INT ||\n token.precededBySpace\n ) {\n this.exprError(\"E_CSS_SYNTAX\", token);\n } else {\n valStack.push(new Exprs.Param(handler.getScope(), token.num));\n tokenizer.consume();\n this.actions = actionsExprOp;\n }\n continue;\n case Action.EXPR_PREFIX:\n valStack.push(-token.type);\n tokenizer.consume();\n continue;\n case Action.EXPR_INFIX:\n this.actions = actionsExprVal;\n this.exprStackReduce(token.type, token);\n valStack.push(token.type);\n tokenizer.consume();\n continue;\n case Action.EXPR_INFIX_NAME:\n if (token.text.toLowerCase() == \"and\") {\n this.actions = actionsExprVal;\n this.exprStackReduce(OP_MEDIA_AND, token);\n valStack.push(OP_MEDIA_AND);\n tokenizer.consume();\n } else {\n this.exprError(\"E_CSS_SYNTAX\", token);\n }\n continue;\n case Action.EXPR_C_PAR:\n if (this.exprStackReduce(token.type, token)) {\n if (this.propName) {\n this.actions = actionsPropVal;\n } else {\n this.exprError(\"E_CSS_UNBALANCED_PAR\", token);\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_O_BRC:\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n if (this.propName || this.exprContext == ExprContext.IMPORT) {\n this.exprError(\"E_CSS_UNEXPECTED_BRC\", token);\n } else {\n if (this.exprContext == ExprContext.WHEN) {\n handler.startWhenRule(valStack.pop() as Css.Expr);\n } else {\n handler.startMediaRule(valStack.pop() as Css.Expr);\n }\n this.ruleStack.push(\"media\");\n handler.startRuleBody();\n this.actions = actionsBase;\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_SEMICOL:\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n if (this.propName || this.exprContext != ExprContext.IMPORT) {\n this.exprError(\"E_CSS_UNEXPECTED_SEMICOL\", token);\n } else {\n this.importCondition = valStack.pop() as Css.Expr;\n this.importReady = true;\n this.actions = actionsBase;\n tokenizer.consume();\n return false;\n }\n }\n tokenizer.consume();\n continue;\n case Action.EXPR_O_PAR:\n valStack.push(token.type);\n tokenizer.consume();\n continue;\n case Action.RULE_END:\n this.actions = actionsBase;\n tokenizer.consume();\n handler.endRule();\n if (this.ruleStack.length) {\n this.ruleStack.pop();\n }\n continue;\n case Action.AT:\n text = token.text.toLowerCase();\n switch (text) {\n case \"import\":\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.STR ||\n token.type == CssTokenizer.TokenType.URL\n ) {\n this.importURL = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.SEMICOL ||\n token.type == CssTokenizer.TokenType.EOF\n ) {\n this.importReady = true;\n tokenizer.consume();\n return false;\n } else {\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.IMPORT;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n }\n }\n handler.error(\"E_CSS_IMPORT_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"namespace\":\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n text = token.text; // Prefix\n tokenizer.consume();\n token = tokenizer.token();\n if (\n (token.type == CssTokenizer.TokenType.STR ||\n token.type == CssTokenizer.TokenType.URL) &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n this.namespacePrefixToURI[text] = token.text;\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n break;\n case CssTokenizer.TokenType.STR:\n case CssTokenizer.TokenType.URL:\n if (\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n this.defaultNamespaceURI = token.text;\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n break;\n }\n handler.error(\"E_CSS_NAMESPACE_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"charset\":\n // Useless in EPUB (only UTF-8 or UTF-16 is allowed anyway and\n // we are at the mercy of the browser charset handling anyway).\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.STR &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.SEMICOL\n ) {\n text = token.text.toLowerCase();\n if (text != \"utf-8\" && text != \"utf-16\") {\n handler.error(`E_CSS_UNEXPECTED_CHARSET ${text}`, token);\n }\n tokenizer.consume();\n tokenizer.consume();\n continue;\n }\n handler.error(\"E_CSS_CHARSET_SYNTAX\", token);\n this.actions = actionsError;\n continue;\n case \"font-face\":\n case \"-epubx-page-template\":\n case \"-epubx-define\":\n case \"-epubx-viewport\":\n if (tokenizer.nthToken(1).type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n tokenizer.consume();\n switch (text) {\n case \"font-face\":\n handler.startFontFaceRule();\n break;\n case \"-epubx-page-template\":\n handler.startPageTemplateRule();\n break;\n case \"-epubx-define\":\n handler.startDefineRule();\n break;\n case \"-epubx-viewport\":\n handler.startViewportRule();\n break;\n }\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-adapt-footnote-area\":\n tokenizer.consume();\n token = tokenizer.token();\n switch (token.type) {\n case CssTokenizer.TokenType.O_BRC:\n tokenizer.consume();\n handler.startFootnoteRule(null);\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n case CssTokenizer.TokenType.COL_COL:\n tokenizer.consume();\n token = tokenizer.token();\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.O_BRC\n ) {\n text = token.text;\n tokenizer.consume();\n tokenizer.consume();\n handler.startFootnoteRule(text);\n this.ruleStack.push(\"-adapt-footnote-area\");\n handler.startRuleBody();\n continue;\n }\n break;\n }\n break;\n case \"-epubx-region\":\n tokenizer.consume();\n handler.startRegionRule();\n this.regionRule = true;\n this.actions = actionsSelectorStart;\n continue;\n case \"page\":\n tokenizer.consume();\n handler.startPageRule();\n this.pageRule = true;\n this.actions = actionsSelectorCont;\n continue;\n case \"top-left-corner\":\n case \"top-left\":\n case \"top-center\":\n case \"top-right\":\n case \"top-right-corner\":\n case \"right-top\":\n case \"right-middle\":\n case \"right-bottom\":\n case \"bottom-right-corner\":\n case \"bottom-right\":\n case \"bottom-center\":\n case \"bottom-left\":\n case \"bottom-left-corner\":\n case \"left-bottom\":\n case \"left-middle\":\n case \"left-top\":\n tokenizer.consume();\n token = tokenizer.token();\n if (token.type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n handler.startPageMarginBoxRule(text);\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-epubx-when\":\n tokenizer.consume();\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.WHEN;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n case \"media\":\n tokenizer.consume();\n this.propName = null; // signals @ rule\n this.exprContext = ExprContext.MEDIA;\n this.actions = actionsExprVal;\n valStack.push(\"{\");\n continue;\n case \"-epubx-flow\":\n if (\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.O_BRC\n ) {\n handler.startFlowRule(tokenizer.nthToken(1).text);\n tokenizer.consume();\n tokenizer.consume();\n tokenizer.consume();\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n case \"-epubx-page-master\":\n case \"-epubx-partition\":\n case \"-epubx-partition-group\": {\n tokenizer.consume();\n token = tokenizer.token();\n let ruleName: string | null = null;\n let rulePseudoName: string | null = null;\n const classes: string[] = [];\n if (token.type == CssTokenizer.TokenType.IDENT) {\n ruleName = token.text;\n tokenizer.consume();\n token = tokenizer.token();\n }\n if (\n token.type == CssTokenizer.TokenType.COLON &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT\n ) {\n rulePseudoName = tokenizer.nthToken(1).text;\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n }\n while (\n token.type == CssTokenizer.TokenType.FUNC &&\n token.text.toLowerCase() == \"class\" &&\n tokenizer.nthToken(1).type == CssTokenizer.TokenType.IDENT &&\n tokenizer.nthToken(2).type == CssTokenizer.TokenType.C_PAR\n ) {\n classes.push(tokenizer.nthToken(1).text);\n tokenizer.consume();\n tokenizer.consume();\n tokenizer.consume();\n token = tokenizer.token();\n }\n if (token.type == CssTokenizer.TokenType.O_BRC) {\n tokenizer.consume();\n switch (text) {\n case \"-epubx-page-master\":\n handler.startPageMasterRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n case \"-epubx-partition\":\n handler.startPartitionRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n case \"-epubx-partition-group\":\n handler.startPartitionGroupRule(\n ruleName,\n rulePseudoName,\n classes,\n );\n break;\n }\n this.ruleStack.push(text);\n handler.startRuleBody();\n continue;\n }\n break;\n }\n case \"\":\n // No text after @\n handler.error(`E_CSS_UNEXPECTED_AT${text}`, token);\n\n // Error recovery using selector rules.\n this.actions = actionsErrorSelector;\n continue;\n default:\n handler.error(`E_CSS_AT_UNKNOWN ${text}`, token);\n this.actions = actionsError;\n continue;\n }\n handler.error(`E_CSS_AT_SYNTAX ${text}`, token);\n this.actions = actionsError;\n continue;\n case Action.ERROR_PUSH:\n // Open bracket while skipping error syntax\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n this.errorBrackets.push(token.type + 1);\n\n // Expected closing bracket\n tokenizer.consume();\n continue;\n case Action.ERROR_POP_DECL:\n // Close bracket while skipping error syntax in declaration\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (this.errorBrackets.length == 0) {\n this.actions = actionsBase;\n\n // Don't consume closing brace\n continue;\n }\n\n // fall through\n case Action.ERROR_POP:\n // Close bracket while skipping error syntax\n if (\n this.errorBrackets.length > 0 &&\n this.errorBrackets[this.errorBrackets.length - 1] == token.type\n ) {\n this.errorBrackets.pop();\n }\n if (\n this.errorBrackets.length == 0 &&\n token.type == CssTokenizer.TokenType.C_BRC\n ) {\n this.actions = actionsBase;\n }\n tokenizer.consume();\n continue;\n case Action.ERROR_SEMICOL:\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (this.errorBrackets.length == 0) {\n this.actions = actionsBase;\n }\n tokenizer.consume();\n continue;\n case Action.DONE:\n if (parsingFunctionParam) {\n tokenizer.consume();\n handler.endFuncWithSelector();\n }\n return true;\n default:\n if (parsingValue || parsingStyleAttr) {\n return true;\n }\n if (parsingMediaQuery) {\n if (this.exprStackReduce(CssTokenizer.TokenType.C_PAR, token)) {\n this.result = valStack.pop() as Css.Val;\n return true;\n }\n return false;\n }\n if (parsingFunctionParam) {\n if (token.type == CssTokenizer.TokenType.INVALID) {\n handler.error(token.text, token);\n } else {\n handler.error(\"E_CSS_SYNTAX\", token);\n }\n return false;\n }\n if (this.actions === actionsPropVal && tokenizer.hasMark()) {\n tokenizer.reset();\n this.actions = actionsSelectorStart;\n handler.startSelectorRule();\n continue;\n }\n if (\n this.actions !== actionsError &&\n this.actions !== actionsErrorSelector &&\n this.actions !== actionsErrorDecl\n ) {\n if (token.type == CssTokenizer.TokenType.INVALID) {\n handler.error(token.text, token);\n } else {\n handler.error(\"E_CSS_SYNTAX\", token);\n }\n if (this.isInsidePropertyOnlyRule()) {\n this.actions = actionsErrorDecl;\n } else {\n this.actions = actionsErrorSelector;\n }\n continue; // Let error-recovery to re-process the offending token\n }\n tokenizer.consume();\n continue;\n }\n }\n return false; // Not done yet.\n }\n}\n\nexport class ErrorHandler extends ParserHandler {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super(null);\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n throw new Error(mnemonics);\n }\n\n /**\n * @override\n */\n getScope(): Exprs.LexicalScope {\n return this.scope;\n }\n}\n\nexport function parseStylesheet(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\"parseStylesheet\");\n const parser = new Parser(actionsBase, tokenizer, handler, baseURL);\n let condition: Css.Expr = null;\n if (media) {\n condition = parseMediaQuery(\n new CssTokenizer.Tokenizer(media, handler),\n handler,\n baseURL,\n );\n }\n condition = parser.makeCondition(classes, condition && condition.toExpr());\n if (condition) {\n handler.startMediaRule(condition);\n handler.startRuleBody();\n }\n frame\n .loop(() => {\n while (!parser.runParser(100, false, false, false, false)) {\n if (parser.importReady) {\n const resolvedURL = Base.resolveURL(\n parser.importURL as string,\n baseURL,\n );\n if (parser.importCondition) {\n handler.startMediaRule(parser.importCondition);\n handler.startRuleBody();\n }\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"parseStylesheet.import\",\n );\n parseStylesheetFromURL(resolvedURL, handler, null, null).then(() => {\n if (parser.importCondition) {\n handler.endRule();\n }\n parser.importReady = false;\n parser.importURL = null;\n parser.importCondition = null;\n innerFrame.finish(true);\n });\n return innerFrame.result();\n }\n const r = frame.timeSlice();\n if (r.isPending) {\n return r;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n if (condition) {\n handler.endRule();\n }\n frame.finish(true);\n });\n return frame.result();\n}\n\nexport function parseStylesheetFromText(\n text: string,\n handler: ParserHandler,\n baseURL: string,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n return Task.handle(\n \"parseStylesheetFromText\",\n (frame) => {\n const tok = new CssTokenizer.Tokenizer(text, handler);\n parseStylesheet(tok, handler, baseURL, classes, media).thenFinish(frame);\n },\n (frame, err) => {\n Logging.logger.warn(err, `Failed to parse stylesheet text: ${text}`);\n frame.finish(false);\n },\n );\n}\n\nexport function parseStylesheetFromURL(\n url: string,\n handler: ParserHandler,\n classes: string | null,\n media: string | null,\n): Task.Result<boolean> {\n return Task.handle(\n \"parseStylesheetFromURL\",\n (frame) => {\n Net.ajax(url).then((xhr) => {\n if (!xhr.responseText) {\n frame.finish(true);\n } else {\n parseStylesheetFromText(\n xhr.responseText,\n handler,\n url,\n classes,\n media,\n ).then((result) => {\n if (!result) {\n Logging.logger.warn(`Failed to parse stylesheet from ${url}`);\n }\n frame.finish(true);\n });\n }\n });\n },\n (frame, err) => {\n Logging.logger.warn(err, \"Exception while fetching and parsing:\", url);\n frame.finish(true);\n },\n );\n}\n\nexport function parseValue(\n scope: Exprs.LexicalScope,\n tokenizer: CssTokenizer.Tokenizer,\n baseURL: string,\n): Css.Val {\n const parser = new Parser(\n actionsPropVal,\n tokenizer,\n new ErrorHandler(scope),\n baseURL,\n );\n parser.runParser(Number.POSITIVE_INFINITY, true, false, false, false);\n return parser.result;\n}\n\nexport function parseStyleAttribute(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n): void {\n const parser = new Parser(actionsStyleAttribute, tokenizer, handler, baseURL);\n parser.runParser(Number.POSITIVE_INFINITY, false, true, false, false);\n}\n\nexport function parseMediaQuery(\n tokenizer: CssTokenizer.Tokenizer,\n handler: ParserHandler,\n baseURL: string,\n): Css.Expr {\n const parser = new Parser(actionsExprVal, tokenizer, handler, baseURL);\n parser.runParser(Number.POSITIVE_INFINITY, false, false, true, false);\n return parser.result as Css.Expr;\n}\n\nexport const numProp: { [key: string]: boolean } = {\n \"z-index\": true,\n \"column-count\": true,\n \"flow-linger\": true,\n opacity: true,\n page: true,\n \"flow-priority\": true,\n utilization: true,\n};\n\nexport function takesOnlyNum(propName: string): boolean {\n return !!numProp[propName];\n}\n\n/**\n * @return val\n */\nexport function evaluateExprToCSS(\n context: Exprs.Context,\n val: Exprs.Val,\n propName: string,\n): Css.Val {\n const result = val.evaluate(context);\n switch (typeof result) {\n case \"number\":\n if (!takesOnlyNum(propName)) {\n return new Css.Numeric(result as number, \"px\");\n } else if (result == Math.round(result as number)) {\n return new Css.Int(result as number);\n } else {\n return new Css.Num(result as number);\n }\n case \"string\":\n if (!result) {\n return Css.empty;\n }\n\n // TODO: where baseURL should come from???\n return parseValue(\n val.scope,\n new CssTokenizer.Tokenizer(result as string, null),\n \"\",\n );\n case \"boolean\":\n return result ? Css.ident._true : Css.ident._false;\n case \"undefined\":\n return Css.empty;\n }\n throw new Error(\"E_UNEXPECTED\");\n}\n\n/**\n * @return val\n */\nexport function evaluateCSSToCSS(\n context: Exprs.Context,\n val: Css.Val,\n propName: string,\n): Css.Val {\n if (val.isExpr()) {\n return evaluateExprToCSS(context, (val as Css.Expr).expr, propName);\n }\n return val;\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Matchers - Definitions of Matcher.\n */\nimport * as Asserts from \"./asserts\";\n\n/**\n * Checkes whether given order can be represented as an+b with a non-negative\n * interger n\n */\nexport function matchANPlusB(order: number, a: number, b: number): boolean {\n order -= b;\n if (a === 0) {\n return order === 0;\n } else {\n return order % a === 0 && order / a >= 0;\n }\n}\n\nexport interface Matcher {\n matches(): boolean;\n}\n\nexport class AnyMatcher implements Matcher {\n constructor(public readonly matchers: Matcher[]) {}\n\n /** @override */\n matches(): boolean {\n return this.matchers.some((matcher) => matcher.matches());\n }\n}\n\nexport class AllMatcher implements Matcher {\n constructor(public readonly matchers: Matcher[]) {}\n\n /** @override */\n matches(): boolean {\n return this.matchers.every((matcher) => matcher.matches());\n }\n}\n\nexport class NthFragmentMatcher implements Matcher {\n static fragmentIndices = {};\n\n static registerFragmentIndex(\n elementOffset: number,\n fragmentIndex: number,\n priority: number,\n ) {\n const indices = NthFragmentMatcher.fragmentIndices;\n if (\n !indices[elementOffset] ||\n indices[elementOffset].priority <= priority\n ) {\n indices[elementOffset] = { fragmentIndex, priority };\n }\n }\n\n static clearFragmentIndices() {\n NthFragmentMatcher.fragmentIndices = {};\n }\n\n constructor(\n public readonly elementOffset: number,\n public readonly a: number,\n public readonly b: number,\n ) {}\n\n /** @override */\n matches(): boolean {\n const entry = NthFragmentMatcher.fragmentIndices[this.elementOffset];\n return (\n entry != null &&\n entry.fragmentIndex != null &&\n matchANPlusB(entry.fragmentIndex, this.a, this.b)\n );\n }\n}\n\nexport class MatcherBuilder {\n static buildViewConditionMatcher(\n elementOffset: number,\n viewCondition: string,\n ): Matcher {\n const strs = viewCondition.split(\"_\");\n if (strs[0] == \"NFS\") {\n return new NthFragmentMatcher(\n elementOffset,\n parseInt(strs[1], 10),\n parseInt(strs[2], 10),\n );\n } else {\n Asserts.fail(`unknown view condition. condition=${viewCondition}`);\n return null;\n }\n }\n\n static buildAllMatcher(matchers: Matcher[]): Matcher {\n return new AllMatcher(matchers);\n }\n\n static buildAnyMatcher(matchers: Matcher[]): Matcher {\n return new AnyMatcher(matchers);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssCascade - CSS Cascade.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Matchers from \"./matchers\";\nimport * as Plugin from \"./plugin\";\nimport * as Vtree from \"./vtree\";\nimport { CssCascade } from \"./types\";\n\nexport interface ElementStyle extends CssCascade.ElementStyle {}\n\nexport const inheritedProps = {\n azimuth: true,\n \"border-collapse\": true,\n \"border-spacing\": true,\n \"caption-side\": true,\n \"clip-rule\": true,\n color: true,\n \"color-interpolation\": true,\n \"color-rendering\": true,\n cursor: true,\n direction: true,\n elevation: true,\n \"empty-cells\": true,\n fill: true,\n \"fill-opacity\": true,\n \"fill-rule\": true,\n \"font-kerning\": true,\n \"font-size\": true,\n \"font-size-adjust\": true,\n \"font-family\": true,\n \"font-feature-settings\": true,\n \"font-style\": true,\n \"font-stretch\": true,\n \"font-variant\": true,\n \"font-weight\": true,\n \"glyph-orientation-vertical\": true,\n hyphens: true,\n \"hyphenate-character\": true,\n \"hyphenate-limit-chars\": true,\n \"hyphenate-limit-last\": true,\n \"image-rendering\": true,\n \"image-resolution\": true,\n \"letter-spacing\": true,\n \"line-break\": true,\n \"line-height\": true,\n \"list-style-image\": true,\n \"list-style-position\": true,\n \"list-style-type\": true,\n marker: true,\n \"marker-end\": true,\n \"marker-mid\": true,\n \"marker-start\": true,\n orphans: true,\n \"overflow-wrap\": true,\n \"paint-order\": true,\n \"pointer-events\": true,\n \"pitch-range\": true,\n quotes: true,\n richness: true,\n \"ruby-align\": true,\n \"ruby-position\": true,\n \"speak-header\": true,\n \"speak-numeral\": true,\n \"speak-punctuation\": true,\n \"speech-rate\": true,\n \"shape-rendering\": true,\n stress: true,\n stroke: true,\n \"stroke-dasharray\": true,\n \"stroke-dashoffset\": true,\n \"stroke-linecap\": true,\n \"stroke-linejoin\": true,\n \"stroke-miterlimit\": true,\n \"stroke-opacity\": true,\n \"stroke-width\": true,\n \"tab-size\": true,\n \"text-align\": true,\n \"text-align-last\": true,\n \"text-anchor\": true,\n \"text-decoration-skip\": true,\n \"text-emphasis-color\": true,\n \"text-emphasis-position\": true,\n \"text-emphasis-style\": true,\n \"text-combine-upright\": true,\n \"text-indent\": true,\n \"text-justify\": true,\n \"text-rendering\": true,\n \"text-size-adjust\": true,\n \"text-transform\": true,\n \"text-underline-position\": true,\n visibility: true,\n \"voice-family\": true,\n volume: true,\n \"white-space\": true,\n widows: true,\n \"word-break\": true,\n \"word-spacing\": true,\n \"word-wrap\": true,\n \"writing-mode\": true,\n};\n\nexport const polyfilledInheritedProps = [\n \"box-decoration-break\",\n // TODO: box-decoration-block should not be inherited.\n // https://github.com/vivliostyle/vivliostyle.js/issues/259\n \"image-resolution\",\n \"orphans\",\n \"widows\",\n];\n\nexport function getPolyfilledInheritedProps(): string[] {\n const hooks: Plugin.PolyfilledInheritedPropsHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.POLYFILLED_INHERITED_PROPS,\n );\n return hooks.reduce(\n (props, f) => props.concat(f()),\n [].concat(polyfilledInheritedProps),\n );\n}\n\nexport const supportedNamespaces = {\n \"http://www.idpf.org/2007/ops\": true,\n \"http://www.w3.org/1999/xhtml\": true,\n \"http://www.w3.org/2000/svg\": true,\n};\n\nexport const coupledPatterns = [\n \"margin-%\",\n \"padding-%\",\n \"border-%-width\",\n \"border-%-style\",\n \"border-%-color\",\n \"%\",\n];\n\nexport const coupledExtentPatterns = [\"max-%\", \"min-%\", \"%\"];\n\nexport const geomNames: { [key: string]: boolean } = (() => {\n const sides = [\"left\", \"right\", \"top\", \"bottom\"];\n const names = {\n width: true,\n height: true,\n \"max-width\": true,\n \"max-height\": true,\n \"min-width\": true,\n \"min-height\": true,\n };\n for (let i = 0; i < coupledPatterns.length; i++) {\n for (let k = 0; k < sides.length; k++) {\n const name = coupledPatterns[i].replace(\"%\", sides[k]);\n names[name] = true;\n }\n }\n return names;\n})();\n\nexport function buildCouplingMap(\n sideMap: { [key: string]: string },\n extentMap: { [key: string]: string },\n): { [key: string]: string } {\n const map = {};\n for (const pattern of coupledPatterns) {\n for (const side in sideMap) {\n const name1 = pattern.replace(\"%\", side);\n const name2 = pattern.replace(\"%\", sideMap[side]);\n map[name1] = name2;\n map[name2] = name1;\n }\n }\n for (const extentPattern of coupledExtentPatterns) {\n for (const extent in extentMap) {\n const name1 = extentPattern.replace(\"%\", extent);\n const name2 = extentPattern.replace(\"%\", extentMap[extent]);\n map[name1] = name2;\n map[name2] = name1;\n }\n }\n return map;\n}\n\nexport const couplingMapVert = buildCouplingMap(\n {\n \"block-start\": \"right\",\n \"block-end\": \"left\",\n \"inline-start\": \"top\",\n \"inline-end\": \"bottom\",\n },\n { \"block-size\": \"width\", \"inline-size\": \"height\" },\n);\n\nexport const couplingMapHor = buildCouplingMap(\n {\n \"block-start\": \"top\",\n \"block-end\": \"bottom\",\n \"inline-start\": \"left\",\n \"inline-end\": \"right\",\n },\n { \"block-size\": \"height\", \"inline-size\": \"width\" },\n);\n\nexport const couplingMapVertRtl = buildCouplingMap(\n {\n \"block-start\": \"right\",\n \"block-end\": \"left\",\n \"inline-start\": \"bottom\",\n \"inline-end\": \"top\",\n },\n { \"block-size\": \"width\", \"inline-size\": \"height\" },\n);\n\nexport const couplingMapHorRtl = buildCouplingMap(\n {\n \"block-start\": \"top\",\n \"block-end\": \"bottom\",\n \"inline-start\": \"right\",\n \"inline-end\": \"left\",\n },\n { \"block-size\": \"height\", \"inline-size\": \"width\" },\n);\n\nexport class CascadeValue {\n constructor(\n public readonly value: Css.Val,\n public readonly priority: number,\n ) {}\n\n getBaseValue(): CascadeValue {\n return this;\n }\n\n filterValue(visitor: Css.Visitor): CascadeValue {\n const value = this.value.visit(visitor);\n if (value === this.value) {\n return this;\n }\n return new CascadeValue(value, this.priority);\n }\n\n increaseSpecificity(specificity: number): CascadeValue {\n if (specificity == 0) {\n return this;\n }\n return new CascadeValue(this.value, this.priority + specificity);\n }\n\n evaluate(context: Exprs.Context, propName: string): Css.Val {\n return CssParser.evaluateCSSToCSS(context, this.value, propName);\n }\n\n isEnabled(context: Exprs.Context): boolean {\n return true;\n }\n}\n\n/**\n * Internal subclass of CascadeValue. Should never be seen outside of the\n * cascade engine.\n */\nexport class ConditionalCascadeValue extends CascadeValue {\n constructor(\n value: Css.Val,\n priority: number,\n public readonly condition: Exprs.Val,\n ) {\n super(value, priority);\n }\n\n /**\n * @override\n */\n getBaseValue(): CascadeValue {\n return new CascadeValue(this.value, this.priority);\n }\n\n /**\n * @override\n */\n filterValue(visitor: Css.Visitor): CascadeValue {\n const value = this.value.visit(visitor);\n if (value === this.value) {\n return this;\n }\n return new ConditionalCascadeValue(value, this.priority, this.condition);\n }\n\n /**\n * @override\n */\n increaseSpecificity(specificity: number): CascadeValue {\n if (specificity == 0) {\n return this;\n }\n return new ConditionalCascadeValue(\n this.value,\n this.priority + specificity,\n this.condition,\n );\n }\n\n isEnabled(context: Exprs.Context): boolean {\n return !!this.condition.evaluate(context);\n }\n}\n\n/**\n * @param tv current value (cannot be conditional)\n * @param av cascaded value (can be conditional)\n */\nexport function cascadeValues(\n context: Exprs.Context,\n tv: CascadeValue,\n av: CascadeValue,\n): CascadeValue {\n if ((tv == null || av.priority > tv.priority) && av.isEnabled(context)) {\n return av.getBaseValue();\n }\n return tv;\n}\n\nexport type ElementStyleMap = {\n [key: string]: ElementStyle;\n};\n\nexport const SPECIALS = {\n \"region-id\": true,\n \"fragment-selector-id\": true,\n};\n\nexport function isSpecialName(name: string): boolean {\n return !!SPECIALS[name];\n}\n\nexport function isMapName(name: string): boolean {\n return name.charAt(0) == \"_\";\n}\n\nexport function isPropName(name: string): boolean {\n return name.charAt(0) != \"_\" && !SPECIALS[name];\n}\n\nexport function isInherited(name: string): boolean {\n return !!inheritedProps[name];\n}\n\nexport function getProp(style: ElementStyle, name: string): CascadeValue {\n return style[name] as CascadeValue;\n}\n\n/**\n * @return void\n */\nexport function setProp(\n style: ElementStyle,\n name: string,\n value: CascadeValue,\n): any {\n if (!value) {\n delete style[name];\n } else {\n style[name] = value;\n }\n}\n\nexport function getStyleMap(\n style: ElementStyle,\n name: string,\n): ElementStyleMap {\n return style[name] as ElementStyleMap;\n}\n\nexport function getMutableStyleMap(\n style: ElementStyle,\n name: string,\n): ElementStyleMap {\n let r = style[name] as ElementStyleMap;\n if (!r) {\n r = {};\n style[name] = r;\n }\n return r;\n}\n\nexport const getViewConditionalStyleMap = (\n style: ElementStyle,\n): { matcher: Matchers.Matcher; styles: ElementStyleMap }[] => {\n let r = style[\"_viewConditionalStyles\"] as {\n matcher: Matchers.Matcher;\n styles: ElementStyleMap;\n }[];\n if (!r) {\n r = [];\n style[\"_viewConditionalStyles\"] = r;\n }\n return r;\n};\n\nexport function getSpecial(style: ElementStyle, name: string): CascadeValue[] {\n return style[name] as CascadeValue[];\n}\n\nexport function getMutableSpecial(\n style: ElementStyle,\n name: string,\n): CascadeValue[] {\n let r = style[name] as CascadeValue[];\n if (!r) {\n r = [];\n style[name] = r;\n }\n return r;\n}\n\nexport function mergeIn(\n context: Exprs.Context,\n target: ElementStyle,\n style: ElementStyle,\n specificity: number,\n pseudoelement: string | null,\n regionId: string | null,\n viewConditionMatcher: Matchers.Matcher | null,\n): void {\n const hierarchy = [\n { id: pseudoelement, styleKey: \"_pseudos\" },\n { id: regionId, styleKey: \"_regions\" },\n ];\n hierarchy.forEach((item) => {\n if (item.id) {\n const styleMap = getMutableStyleMap(target, item.styleKey);\n target = styleMap[item.id];\n if (!target) {\n target = {} as ElementStyle;\n styleMap[item.id] = target;\n }\n }\n });\n if (viewConditionMatcher) {\n const styleMap = getViewConditionalStyleMap(target);\n target = {} as ElementStyle;\n styleMap.push({\n styles: target as ElementStyleMap,\n matcher: viewConditionMatcher,\n });\n }\n for (const prop in style) {\n if (isMapName(prop)) {\n continue;\n }\n if (isSpecialName(prop)) {\n // special properties: list of all assigned values\n const as = getSpecial(style, prop);\n const ts = getMutableSpecial(target, prop);\n Array.prototype.push.apply(ts, as);\n } else {\n // regular properties: higher priority wins\n const av = getProp(style, prop).increaseSpecificity(specificity);\n const tv = getProp(target, prop);\n setProp(target, prop, cascadeValues(context, tv, av));\n }\n }\n}\n\nexport function mergeAll(\n context: Exprs.Context,\n styles: ElementStyle[],\n): ElementStyle {\n const target = {} as ElementStyle;\n for (let k = 0; k < styles.length; k++) {\n mergeIn(context, target, styles[k], 0, null, null, null);\n }\n return target;\n}\n\nexport function chainActions(\n chain: ChainedAction[],\n action: CascadeAction,\n): CascadeAction {\n if (chain.length > 0) {\n chain.sort((a, b) => b.getPriority() - a.getPriority());\n let chained: ChainedAction | null = null;\n for (let i = chain.length - 1; i >= 0; i--) {\n chained = chain[i];\n chained.chained = action;\n action = chained;\n }\n return chained;\n }\n return action;\n}\n\nexport class InheritanceVisitor extends Css.FilterVisitor {\n propName: string = \"\";\n\n constructor(\n public readonly props: ElementStyle,\n public readonly context: Exprs.Context,\n ) {\n super();\n }\n\n setPropName(name: string): void {\n this.propName = name;\n }\n\n private getFontSize() {\n const cascval = getProp(this.props, \"font-size\");\n const n = cascval.value as Css.Numeric;\n if (!Exprs.isAbsoluteLengthUnit(n.unit)) {\n throw new Error(\"Unexpected state\");\n }\n return n.num * Exprs.defaultUnitSizes[n.unit];\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n Asserts.assert(this.context);\n if (this.propName === \"font-size\") {\n return convertFontSizeToPx(numeric, this.getFontSize(), this.context);\n } else if (\n numeric.unit == \"em\" ||\n numeric.unit == \"ex\" ||\n numeric.unit == \"rem\"\n ) {\n return convertFontRelativeLengthToPx(\n numeric,\n this.getFontSize(),\n this.context,\n );\n } else if (numeric.unit == \"%\") {\n if (this.propName === \"line-height\") {\n return numeric;\n }\n const unit = this.propName.match(/height|^(top|bottom)$/) ? \"vh\" : \"vw\";\n return new Css.Numeric(numeric.num, unit);\n }\n return numeric;\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n if (this.propName == \"font-size\") {\n const val = CssParser.evaluateCSSToCSS(this.context, expr, this.propName);\n return val.visit(this);\n }\n return expr;\n }\n}\n\nexport function convertFontRelativeLengthToPx(\n numeric: Css.Numeric,\n baseFontSize: number,\n context: Exprs.Context,\n): Css.Numeric {\n const unit = numeric.unit;\n const num = numeric.num;\n if (unit === \"em\" || unit === \"ex\") {\n const ratio = Exprs.defaultUnitSizes[unit] / Exprs.defaultUnitSizes[\"em\"];\n return new Css.Numeric(num * ratio * baseFontSize, \"px\");\n } else if (unit === \"rem\") {\n return new Css.Numeric(num * context.fontSize(), \"px\");\n } else {\n return numeric;\n }\n}\n\nexport function convertFontSizeToPx(\n numeric: Css.Numeric,\n parentFontSize: number,\n context: Exprs.Context,\n): Css.Numeric {\n numeric = convertFontRelativeLengthToPx(numeric, parentFontSize, context);\n const unit = numeric.unit;\n const num = numeric.num;\n if (unit === \"px\") {\n return numeric;\n } else if (unit === \"%\") {\n return new Css.Numeric((num / 100) * parentFontSize, \"px\");\n } else {\n return new Css.Numeric(num * context.queryUnitSize(unit, false), \"px\");\n }\n}\n\nexport type ActionTable = {\n [key: string]: CascadeAction;\n};\n\nexport class CascadeAction {\n apply(cascadeInstance: CascadeInstance): void {}\n\n mergeWith(other: CascadeAction): CascadeAction {\n return new CompoundAction([this, other]);\n }\n\n clone(): CascadeAction {\n // Mutable actions will override\n return this;\n }\n}\n\nexport class ConditionItemAction extends CascadeAction {\n constructor(public readonly conditionItem: ConditionItem) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n cascadeInstance.pushConditionItem(\n this.conditionItem.fresh(cascadeInstance),\n );\n }\n}\n\nexport class CompoundAction extends CascadeAction {\n constructor(public readonly list: CascadeAction[]) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n for (let i = 0; i < this.list.length; i++) {\n this.list[i].apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n mergeWith(other: CascadeAction): CascadeAction {\n this.list.push(other);\n return this;\n }\n\n /**\n * @override\n */\n clone(): CascadeAction {\n return new CompoundAction([].concat(this.list));\n }\n}\n\nexport class ApplyRuleAction extends CascadeAction {\n constructor(\n public readonly style: ElementStyle,\n public readonly specificity: number,\n public readonly pseudoelement: string | null,\n public readonly regionId: string | null,\n public readonly viewConditionId: string | null,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n mergeIn(\n cascadeInstance.context,\n cascadeInstance.currentStyle,\n this.style,\n this.specificity,\n this.pseudoelement,\n this.regionId,\n cascadeInstance.buildViewConditionMatcher(this.viewConditionId),\n );\n }\n}\n\nexport class ChainedAction extends CascadeAction {\n chained: CascadeAction = null;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.chained.apply(cascadeInstance);\n }\n\n getPriority(): number {\n return 0;\n }\n\n makePrimary(cascade: Cascade): boolean {\n // cannot be made primary\n return false;\n }\n}\n\nexport class CheckClassAction extends ChainedAction {\n constructor(public readonly className: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentClassNames.includes(this.className)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 10;\n }\n // class should be checked after id\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.classes, this.className, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckIdAction extends ChainedAction {\n constructor(public readonly id: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentId == this.id ||\n cascadeInstance.currentXmlId == this.id\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 11;\n }\n // id should be checked after :root\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.ids, this.id, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckLocalNameAction extends ChainedAction {\n constructor(public readonly localName: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentLocalName == this.localName) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 8;\n }\n // tag is a pretty good thing to check, after epub:type\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.tags, this.localName, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckNSTagAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly localName: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentLocalName == this.localName &&\n cascadeInstance.currentNamespace == this.ns\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 8;\n }\n // tag is a pretty good thing to check, after epub:type\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.chained) {\n let prefix = cascade.nsPrefix[this.ns];\n if (!prefix) {\n prefix = `ns${cascade.nsCount++}:`;\n cascade.nsPrefix[this.ns] = prefix;\n }\n const nsTag = prefix + this.localName;\n cascade.insertInTable(cascade.nstags, nsTag, this.chained);\n }\n return true;\n }\n}\n\nexport class CheckTargetEpubTypeAction extends ChainedAction {\n constructor(public readonly epubTypePatt: RegExp) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if (elem && cascadeInstance.currentLocalName == \"a\") {\n const href = elem.getAttribute(\"href\");\n if (href && href.match(/^#/)) {\n const id = href.substring(1);\n const target = elem.ownerDocument.getElementById(id);\n if (target) {\n const epubType = target.getAttributeNS(Base.NS.epub, \"type\");\n if (epubType && epubType.match(this.epubTypePatt)) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n }\n }\n}\n\nexport class CheckNamespaceAction extends ChainedAction {\n constructor(public readonly ns: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentNamespace == this.ns) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class CheckAttributePresentAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly name: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentElement &&\n cascadeInstance.currentElement.hasAttributeNS(this.ns, this.name)\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class CheckAttributeEqAction extends ChainedAction {\n constructor(\n public readonly ns: string,\n public readonly name: string,\n public readonly value: string,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (\n cascadeInstance.currentElement &&\n cascadeInstance.currentElement.getAttributeNS(this.ns, this.name) ==\n this.value\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n if (this.name == \"type\" && this.ns == Base.NS.epub) {\n return 9; // epub:type is a pretty good thing to check\n }\n return 0;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n if (this.name == \"type\" && this.ns == Base.NS.epub) {\n if (this.chained) {\n cascade.insertInTable(cascade.epubtypes, this.value, this.chained);\n }\n return true;\n }\n return false;\n }\n}\n\nexport class CheckNamespaceSupportedAction extends ChainedAction {\n constructor(public readonly ns: string, public readonly name: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentElement) {\n const ns = cascadeInstance.currentElement.getAttributeNS(\n this.ns,\n this.name,\n );\n if (ns && supportedNamespaces[ns]) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 0;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: Cascade): boolean {\n return false;\n }\n}\n\nexport class CheckAttributeRegExpAction extends ChainedAction {\n constructor(\n public readonly ns: string,\n public readonly name: string,\n public readonly regexp: RegExp,\n ) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.currentElement) {\n const attr = cascadeInstance.currentElement.getAttributeNS(\n this.ns,\n this.name,\n );\n if (attr && attr.match(this.regexp)) {\n this.chained.apply(cascadeInstance);\n }\n }\n }\n}\n\nexport class CheckLangAction extends ChainedAction {\n constructor(public readonly langRegExp: RegExp) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.lang.match(this.langRegExp)) {\n this.chained.apply(cascadeInstance);\n }\n }\n}\n\nexport class IsFirstAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.isFirst) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 6;\n }\n}\n\nexport class IsRootAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.isRoot) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 12; // :root is the first thing to check\n }\n}\n\nexport class IsNthAction extends ChainedAction {\n constructor(public readonly a: number, public readonly b: number) {\n super();\n }\n\n /**\n * Checkes whether given order can be represented as an+b with a non-negative\n * interger n\n */\n protected matchANPlusB(order: number): boolean {\n return Matchers.matchANPlusB(order, this.a, this.b);\n }\n}\n\nexport class IsNthSiblingAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (this.matchANPlusB(cascadeInstance.currentSiblingOrder)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsNthSiblingOfTypeAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const order =\n cascadeInstance.currentSiblingTypeCounts[\n cascadeInstance.currentNamespace\n ][cascadeInstance.currentLocalName];\n if (this.matchANPlusB(order)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsNthLastSiblingAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n let order = cascadeInstance.currentFollowingSiblingOrder;\n if (order === null) {\n order = cascadeInstance.currentFollowingSiblingOrder =\n cascadeInstance.currentElement.parentNode.childElementCount -\n cascadeInstance.currentSiblingOrder +\n 1;\n }\n if (this.matchANPlusB(order)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsNthLastSiblingOfTypeAction extends IsNthAction {\n constructor(a: number, b: number) {\n super(a, b);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const counts = cascadeInstance.currentFollowingSiblingTypeCounts;\n if (!counts[cascadeInstance.currentNamespace]) {\n let elem = cascadeInstance.currentElement;\n do {\n const ns = elem.namespaceURI;\n const localName = elem.localName;\n let nsCounts = counts[ns];\n if (!nsCounts) {\n nsCounts = counts[ns] = {};\n }\n nsCounts[localName] = (nsCounts[localName] || 0) + 1;\n } while ((elem = elem.nextElementSibling));\n }\n if (\n this.matchANPlusB(\n counts[cascadeInstance.currentNamespace][\n cascadeInstance.currentLocalName\n ],\n )\n ) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsEmptyAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n let node: Node | null = cascadeInstance.currentElement.firstChild;\n while (node) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n return;\n case Node.TEXT_NODE:\n if ((node as Text).length > 0) {\n return;\n }\n }\n node = node.nextSibling;\n }\n this.chained.apply(cascadeInstance);\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 4;\n }\n}\n\nexport class IsEnabledAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).disabled === false) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsDisabledAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).disabled === true) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class IsCheckedAction extends ChainedAction {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n const elem = cascadeInstance.currentElement;\n if ((elem as any).selected === true || (elem as any).checked === true) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class CheckConditionAction extends ChainedAction {\n constructor(public readonly condition: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n if (cascadeInstance.conditions[this.condition]) {\n try {\n cascadeInstance.dependentConditions.push(this.condition);\n this.chained.apply(cascadeInstance);\n } finally {\n cascadeInstance.dependentConditions.pop();\n }\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 5;\n }\n}\n\nexport class CheckAppliedAction extends CascadeAction {\n applied = false;\n\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.applied = true;\n }\n\n /**\n * @override\n */\n clone(): CascadeAction {\n const cloned = new CheckAppliedAction();\n cloned.applied = this.applied;\n return cloned;\n }\n}\n\nexport class NegateActionsSet extends ChainedAction {\n checkAppliedAction: CheckAppliedAction;\n firstAction: CascadeAction;\n\n constructor(list: ChainedAction[]) {\n super();\n this.checkAppliedAction = new CheckAppliedAction();\n this.firstAction = chainActions(list, this.checkAppliedAction);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CascadeInstance): void {\n this.firstAction.apply(cascadeInstance);\n if (!this.checkAppliedAction.applied) {\n this.chained.apply(cascadeInstance);\n }\n this.checkAppliedAction.applied = false;\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return (this.firstAction as ChainedAction).getPriority();\n }\n}\n\n/**\n * An object that is notified as elements are pushed and popped and typically\n * controls a \"named condition\" (which is a count associated with a name).\n */\nexport interface ConditionItem {\n /**\n * Returns a \"fresh\" copy of this item. May be this if immutable.\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem;\n\n /**\n * Depth is 0 for element itself and its siblings, 1 for direct children and\n * -1 for the parent.\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean;\n\n /**\n * @return return true if no more notifications are desired\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean;\n}\n\nexport class AbstractConditionItem {\n constructor(\n public readonly condition: string,\n public readonly viewConditionId: string | null,\n public readonly viewCondition: Matchers.Matcher,\n ) {}\n\n increment(cascadeInstance: CascadeInstance) {\n cascadeInstance.increment(this.condition, this.viewCondition);\n }\n\n decrement(cascadeInstance: CascadeInstance) {\n cascadeInstance.decrement(this.condition, this.viewCondition);\n }\n\n buildViewConditionMatcher(\n cascadeInstance: CascadeInstance,\n ): Matchers.Matcher {\n return cascadeInstance.buildViewConditionMatcher(this.viewConditionId);\n }\n}\n\nexport class DescendantConditionItem extends AbstractConditionItem\n implements ConditionItem {\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new DescendantConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.increment(cascadeInstance);\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.decrement(cascadeInstance);\n return true;\n }\n return false;\n }\n}\n\nexport class ChildConditionItem extends AbstractConditionItem\n implements ConditionItem {\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new ChildConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.increment(cascadeInstance);\n } else if (depth == 1) {\n this.decrement(cascadeInstance);\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n this.decrement(cascadeInstance);\n return true;\n } else if (depth == 1) {\n this.increment(cascadeInstance);\n }\n return false;\n }\n}\n\nexport class AdjacentSiblingConditionItem extends AbstractConditionItem\n implements ConditionItem {\n fired: boolean = false;\n\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new AdjacentSiblingConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n this.decrement(cascadeInstance);\n return true;\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n this.decrement(cascadeInstance);\n return true;\n }\n if (depth == 0) {\n // Leaving element that triggered this item.\n this.fired = true;\n this.increment(cascadeInstance);\n }\n return false;\n }\n}\n\nexport class FollowingSiblingConditionItem extends AbstractConditionItem\n implements ConditionItem {\n fired: boolean = false;\n\n constructor(\n condition: string,\n viewConditionId: string | null,\n viewCondition: Matchers.Matcher,\n ) {\n super(condition, viewConditionId, viewCondition);\n }\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return new FollowingSiblingConditionItem(\n this.condition,\n this.viewConditionId,\n this.buildViewConditionMatcher(cascadeInstance),\n );\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n if (depth == -1) {\n this.increment(cascadeInstance);\n } else if (depth == 0) {\n this.decrement(cascadeInstance);\n }\n }\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (this.fired) {\n if (depth == -1) {\n this.decrement(cascadeInstance);\n return true;\n } else if (depth == 0) {\n this.increment(cascadeInstance);\n }\n } else {\n if (depth == 0) {\n // Leaving element that triggered this item.\n this.fired = true;\n this.increment(cascadeInstance);\n }\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class manages proper handling of \"after\"\n * pseudoelement.\n */\nexport class AfterPseudoelementItem implements ConditionItem {\n constructor(\n public readonly afterprop: ElementStyle,\n public readonly element: Element,\n ) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.processPseudoelementProps(this.afterprop, this.element);\n return true;\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class restores current language.\n */\nexport class RestoreLangItem implements ConditionItem {\n constructor(public readonly lang: string) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.lang = this.lang;\n return true;\n }\n return false;\n }\n}\n\n/**\n * Not a true condition item, this class manages inheritance of quotes property\n */\nexport class QuotesScopeItem implements ConditionItem {\n constructor(public readonly oldQuotes: Css.Str[]) {}\n\n /**\n * @override\n */\n fresh(cascadeInstance: CascadeInstance): ConditionItem {\n return this;\n }\n\n /**\n * @override\n */\n push(cascadeInstance: CascadeInstance, depth: number): boolean {\n return false;\n }\n\n /**\n * @override\n */\n pop(cascadeInstance: CascadeInstance, depth: number): boolean {\n if (depth == 0) {\n cascadeInstance.quotes = this.oldQuotes;\n return true;\n }\n return false;\n }\n}\nexport type CounterValues = {\n [key: string]: number[];\n};\n\nexport interface CounterListener {\n countersOfId(id: string, counters: CounterValues);\n\n getExprContentListener(): Vtree.ExprContentListener;\n}\n\nexport interface CounterResolver {\n /**\n * Returns an Exprs.Val, whose value is calculated at the layout time by\n * retrieving the innermost page-based counter (null if it does not exist) by\n * its name and formatting the value into a string.\n * @param name Name of the page-based counter to be retrieved\n * @param format A function that formats the counter value into a string\n */\n getPageCounterVal(\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val;\n\n /**\n * Returns an Exprs.Val, whose value is calculated at the layout time by\n * retrieving the page-based counters by its name and formatting the values\n * into a string.\n * @param name Name of the page-based counters to be retrieved\n * @param format A function that formats the counter values (passed as an\n * array ordered by the nesting depth with the outermost counter first and\n * the innermost last) into a string\n */\n getPageCountersVal(name: string, format: (p1: number[]) => string): Exprs.Val;\n\n getTargetCounterVal(\n url: string,\n name: string,\n format: (p1: number | null) => string,\n ): Exprs.Val;\n\n getTargetCountersVal(\n url: string,\n name: string,\n format: (p1: number[]) => string,\n ): Exprs.Val;\n\n setStyler(styler: any);\n}\n\nexport class AttrValueFilterVisitor extends Css.FilterVisitor {\n constructor(public element: Element) {\n super();\n }\n\n private createValueFromString(str: string | null, type: string): Css.Val {\n switch (type) {\n case \"url\":\n if (str) {\n return new Css.URL(str); // TODO should convert to absolute path\n }\n return new Css.URL(\"about:invalid\");\n case \"string\":\n default:\n if (str) {\n return new Css.Str(str);\n }\n return new Css.Str(\"\");\n }\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (func.name !== \"attr\") {\n return super.visitFunc(func);\n }\n let type = \"string\";\n let attributeName: string | null = null;\n let defaultValue: Css.Val = null;\n if (func.values[0] instanceof Css.SpaceList) {\n const values = (func.values[0] as Css.SpaceList).values;\n if (values.length >= 2) {\n type = values[1].stringValue();\n }\n attributeName = values[0].stringValue();\n } else {\n attributeName = func.values[0].stringValue();\n }\n if (func.values.length > 1) {\n defaultValue = this.createValueFromString(\n func.values[1].stringValue(),\n type,\n );\n } else {\n defaultValue = this.createValueFromString(null, type);\n }\n if (this.element && this.element.hasAttribute(attributeName)) {\n return this.createValueFromString(\n this.element.getAttribute(attributeName),\n type,\n );\n }\n return defaultValue;\n }\n}\n\nexport class ContentPropVisitor extends Css.FilterVisitor {\n constructor(\n public cascade: CascadeInstance,\n public element: Element,\n public readonly counterResolver: CounterResolver,\n ) {\n super();\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const cascade = this.cascade;\n const quotes = cascade.quotes;\n const maxDepth = Math.floor(quotes.length / 2) - 1;\n switch (ident.name) {\n case \"open-quote\": {\n const result = quotes[2 * Math.min(maxDepth, cascade.quoteDepth)];\n cascade.quoteDepth++;\n return result;\n }\n case \"close-quote\":\n if (cascade.quoteDepth > 0) {\n cascade.quoteDepth--;\n }\n return quotes[2 * Math.min(maxDepth, cascade.quoteDepth) + 1];\n case \"no-open-quote\":\n cascade.quoteDepth++;\n return new Css.Str(\"\");\n case \"no-close-quote\":\n if (cascade.quoteDepth > 0) {\n cascade.quoteDepth--;\n }\n return new Css.Str(\"\");\n }\n return ident;\n }\n\n private format(num: number, type: string): string {\n let upper = false; // type == \"armenian\";\n // content-counter-10.xht assumes armenian is uppercase, enable if desired\n\n let lower = false;\n let r: RegExpMatchArray;\n if ((r = type.match(/^upper-(.*)/)) != null) {\n upper = true;\n type = r[1];\n } else if ((r = type.match(/^lower-(.*)/)) != null) {\n lower = true;\n type = r[1];\n }\n let result = \"\";\n if (additiveNumbering[type]) {\n result = additiveFormat(additiveNumbering[type], num);\n } else if (alphabeticNumbering[type]) {\n result = alphabeticFormat(alphabeticNumbering[type], num);\n } else if (fixed[type] != null) {\n result = fixed[type];\n } else if (type == \"decimal-leading-zero\") {\n result = `${num}`;\n if (result.length == 1) {\n result = `0${result}`;\n }\n } else if (type == \"cjk-ideographic\" || type == \"trad-chinese-informal\") {\n result = chineseCounter(num, chineseTradInformal);\n } else {\n result = `${num}`;\n }\n if (upper) {\n return result.toUpperCase();\n }\n if (lower) {\n return result.toLowerCase();\n }\n return result;\n }\n\n visitFuncCounter(values: Css.Val[]): Css.Val {\n const counterName = values[0].toString();\n const type = values.length > 1 ? values[1].stringValue() : \"decimal\";\n const arr = this.cascade.counters[counterName];\n if (arr && arr.length) {\n const numval = (arr && arr.length && arr[arr.length - 1]) || 0;\n return new Css.Str(this.format(numval, type));\n } else {\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getPageCounterVal(counterName, (numval) =>\n self.format(numval || 0, type),\n ),\n );\n return new Css.SpaceList([c]);\n }\n }\n\n visitFuncCounters(values: Css.Val[]): Css.Val {\n const counterName = values[0].toString();\n const separator = values[1].stringValue();\n const type = values.length > 2 ? values[2].stringValue() : \"decimal\";\n const arr = this.cascade.counters[counterName];\n const sb = new Base.StringBuffer();\n if (arr && arr.length) {\n for (let i = 0; i < arr.length; i++) {\n if (i > 0) {\n sb.append(separator);\n }\n sb.append(this.format(arr[i], type));\n }\n }\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getPageCountersVal(counterName, (numvals) => {\n const parts = [] as string[];\n if (numvals.length) {\n for (let i = 0; i < numvals.length; i++) {\n parts.push(self.format(numvals[i], type));\n }\n }\n const elementCounters = sb.toString();\n if (elementCounters.length) {\n parts.push(elementCounters);\n }\n if (parts.length) {\n return parts.join(separator);\n } else {\n return self.format(0, type);\n }\n }),\n );\n return new Css.SpaceList([c]);\n }\n\n visitFuncTargetCounter(values: Css.Val[]): Css.Val {\n const targetUrl = values[0];\n let targetUrlStr: string;\n if (targetUrl instanceof Css.URL) {\n targetUrlStr = targetUrl.url;\n } else {\n targetUrlStr = targetUrl.stringValue();\n }\n const counterName = values[1].toString();\n const type = values.length > 2 ? values[2].stringValue() : \"decimal\";\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getTargetCounterVal(\n targetUrlStr,\n counterName,\n (numval) => self.format(numval || 0, type),\n ),\n );\n return new Css.SpaceList([c]);\n }\n\n visitFuncTargetCounters(values: Css.Val[]): Css.Val {\n const targetUrl = values[0];\n let targetUrlStr: string;\n if (targetUrl instanceof Css.URL) {\n targetUrlStr = targetUrl.url;\n } else {\n targetUrlStr = targetUrl.stringValue();\n }\n const counterName = values[1].toString();\n const separator = values[2].stringValue();\n const type = values.length > 3 ? values[3].stringValue() : \"decimal\";\n const self = this;\n const c = new Css.Expr(\n this.counterResolver.getTargetCountersVal(\n targetUrlStr,\n counterName,\n (numvals) => {\n const parts = numvals.map((numval) => self.format(numval, type));\n if (parts.length) {\n return parts.join(separator);\n } else {\n return self.format(0, type);\n }\n },\n ),\n );\n return new Css.SpaceList([c]);\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n switch (func.name) {\n case \"counter\":\n if (func.values.length <= 2) {\n return this.visitFuncCounter(func.values);\n }\n break;\n case \"counters\":\n if (func.values.length <= 3) {\n return this.visitFuncCounters(func.values);\n }\n break;\n case \"target-counter\":\n if (func.values.length <= 3) {\n return this.visitFuncTargetCounter(func.values);\n }\n break;\n case \"target-counters\":\n if (func.values.length <= 4) {\n return this.visitFuncTargetCounters(func.values);\n }\n break;\n }\n Logging.logger.warn(\"E_CSS_CONTENT_PROP:\", func.toString());\n return new Css.Str(\"\");\n }\n}\n\nexport function roman(num: number): string {\n if (num <= 0 || num != Math.round(num) || num > 3999) {\n return \"\";\n }\n const digits = [\"I\", \"V\", \"X\", \"L\", \"C\", \"D\", \"M\"];\n let offset = 0;\n let acc = \"\";\n while (num > 0) {\n let digit = num % 10;\n num = (num - digit) / 10;\n let result = \"\";\n if (digit == 9) {\n result += digits[offset] + digits[offset + 2];\n } else if (digit == 4) {\n result += digits[offset] + digits[offset + 1];\n } else {\n if (digit >= 5) {\n result += digits[offset + 1];\n digit -= 5;\n }\n while (digit > 0) {\n result += digits[offset];\n digit--;\n }\n }\n acc = result + acc;\n offset += 2;\n }\n return acc;\n}\n\nexport const additiveNumbering = {\n roman: [\n 4999,\n 1000,\n \"M\",\n 900,\n \"CM\",\n 500,\n \"D\",\n 400,\n \"CD\",\n 100,\n \"C\",\n 90,\n \"XC\",\n 50,\n \"L\",\n 40,\n \"XL\",\n 10,\n \"X\",\n 9,\n \"IX\",\n 5,\n \"V\",\n 4,\n \"IV\",\n 1,\n \"I\",\n ],\n armenian: [\n 9999,\n 9000,\n \"\\u0584\",\n 8000,\n \"\\u0583\",\n 7000,\n \"\\u0582\",\n 6000,\n \"\\u0581\",\n 5000,\n \"\\u0580\",\n 4000,\n \"\\u057f\",\n 3000,\n \"\\u057e\",\n 2000,\n \"\\u057d\",\n 1000,\n \"\\u057c\",\n 900,\n \"\\u057b\",\n 800,\n \"\\u057a\",\n 700,\n \"\\u0579\",\n 600,\n \"\\u0578\",\n 500,\n \"\\u0577\",\n 400,\n \"\\u0576\",\n 300,\n \"\\u0575\",\n 200,\n \"\\u0574\",\n 100,\n \"\\u0573\",\n 90,\n \"\\u0572\",\n 80,\n \"\\u0571\",\n 70,\n \"\\u0570\",\n 60,\n \"\\u056f\",\n 50,\n \"\\u056e\",\n 40,\n \"\\u056d\",\n 30,\n \"\\u056c\",\n 20,\n \"\\u056b\",\n 10,\n \"\\u056a\",\n 9,\n \"\\u0569\",\n 8,\n \"\\u0568\",\n 7,\n \"\\u0567\",\n 6,\n \"\\u0566\",\n 5,\n \"\\u0565\",\n 4,\n \"\\u0564\",\n 3,\n \"\\u0563\",\n 2,\n \"\\u0562\",\n 1,\n \"\\u0561\",\n ],\n georgian: [\n 19999,\n 10000,\n \"\\u10f5\",\n 9000,\n \"\\u10f0\",\n 8000,\n \"\\u10ef\",\n 7000,\n \"\\u10f4\",\n 6000,\n \"\\u10ee\",\n 5000,\n \"\\u10ed\",\n 4000,\n \"\\u10ec\",\n 3000,\n \"\\u10eb\",\n 2000,\n \"\\u10ea\",\n 1000,\n \"\\u10e9\",\n 900,\n \"\\u10e8\",\n 800,\n \"\\u10e7\",\n 700,\n \"\\u10e6\",\n 600,\n \"\\u10e5\",\n 500,\n \"\\u10e4\",\n 400,\n \"\\u10f3\",\n 300,\n \"\\u10e2\",\n 200,\n \"\\u10e1\",\n 100,\n \"\\u10e0\",\n 90,\n \"\\u10df\",\n 80,\n \"\\u10de\",\n 70,\n \"\\u10dd\",\n 60,\n \"\\u10f2\",\n 50,\n \"\\u10dc\",\n 40,\n \"\\u10db\",\n 30,\n \"\\u10da\",\n 20,\n \"\\u10d9\",\n 10,\n \"\\u10d8\",\n 9,\n \"\\u10d7\",\n 8,\n \"\\u10f1\",\n 7,\n \"\\u10d6\",\n 6,\n \"\\u10d5\",\n 5,\n \"\\u10d4\",\n 4,\n \"\\u10d3\",\n 3,\n \"\\u10d2\",\n 2,\n \"\\u10d1\",\n 1,\n \"\\u10d0\",\n ],\n hebrew: [\n 999,\n 400,\n \"\\u05ea\",\n 300,\n \"\\u05e9\",\n 200,\n \"\\u05e8\",\n 100,\n \"\\u05e7\",\n 90,\n \"\\u05e6\",\n 80,\n \"\\u05e4\",\n 70,\n \"\\u05e2\",\n 60,\n \"\\u05e1\",\n 50,\n \"\\u05e0\",\n 40,\n \"\\u05de\",\n 30,\n \"\\u05dc\",\n 20,\n \"\\u05db\",\n 19,\n \"\\u05d9\\u05d8\",\n 18,\n \"\\u05d9\\u05d7\",\n 17,\n \"\\u05d9\\u05d6\",\n 16,\n \"\\u05d8\\u05d6\",\n 15,\n \"\\u05d8\\u05d5\",\n 10,\n \"\\u05d9\",\n 9,\n \"\\u05d8\",\n 8,\n \"\\u05d7\",\n 7,\n \"\\u05d6\",\n 6,\n \"\\u05d5\",\n 5,\n \"\\u05d4\",\n 4,\n \"\\u05d3\",\n 3,\n \"\\u05d2\",\n 2,\n \"\\u05d1\",\n 1,\n \"\\u05d0\",\n ],\n};\n\nexport const alphabeticNumbering = {\n latin: \"a-z\",\n alpha: \"a-z\",\n greek: \"\\u03b1-\\u03c1\\u03c3-\\u03c9\",\n russian: \"\\u0430-\\u0438\\u043a-\\u0449\\u044d-\\u044f\",\n};\n\nexport const fixed = {\n square: \"\\u25a0\",\n disc: \"\\u2022\",\n circle: \"\\u25e6\",\n none: \"\",\n};\n\nexport function additiveFormat(entries: any[], num: number): string {\n const max = entries[0] as number;\n if (num > max || num <= 0 || num != Math.round(num)) {\n return \"\";\n }\n let result = \"\";\n for (let i = 1; i < entries.length; i += 2) {\n const value = entries[i] as number;\n let count = Math.floor(num / value);\n if (count > 20) {\n return \"\";\n }\n num -= count * value;\n while (count > 0) {\n result += entries[i + 1];\n count--;\n }\n }\n return result;\n}\n\nexport function expandAlphabet(str: string): string[] | null {\n const arr = [];\n let i = 0;\n while (i < str.length) {\n if (str.substr(i + 1, 1) == \"-\") {\n const first = str.charCodeAt(i);\n const last = str.charCodeAt(i + 2);\n i += 3;\n for (let k = first; k <= last; k++) {\n arr.push(String.fromCharCode(k));\n }\n } else {\n arr.push(str.substr(i++, 1));\n }\n }\n return arr;\n}\n\nexport function alphabeticFormat(alphabetStr: string, num: number): string {\n if (num <= 0 || num != Math.round(num)) {\n return \"\";\n }\n const alphabet = expandAlphabet(alphabetStr);\n let result = \"\";\n do {\n num--;\n const digit = num % alphabet.length;\n result = alphabet[digit] + result;\n num = (num - digit) / alphabet.length;\n } while (num > 0);\n return result;\n}\n\nexport type ChineseNumbering = {\n digits: string;\n markers: string;\n negative: string;\n formal: boolean;\n};\n\n/**\n * From http://www.w3.org/TR/css3-lists/\n */\nexport const chineseTradInformal: ChineseNumbering = {\n formal: false,\n digits: \"\\u96f6\\u4e00\\u4e8c\\u4e09\\u56db\\u4e94\\u516d\\u4e03\\u516b\\u4e5d\",\n markers: \"\\u5341\\u767e\\u5343\",\n negative: \"\\u8ca0\",\n};\n\nexport function chineseCounter(\n num: number,\n numbering: ChineseNumbering,\n): string {\n if (num > 9999 || num < -9999) {\n return `${num}`; // TODO: should be cjk-decimal\n }\n if (num == 0) {\n return numbering.digits.charAt(0);\n }\n const res = new Base.StringBuffer();\n if (num < 0) {\n res.append(numbering.negative);\n num = -num;\n }\n if (num < 10) {\n res.append(numbering.digits.charAt(num));\n } else if (!numbering.formal && num <= 19) {\n res.append(numbering.markers.charAt(0));\n if (num != 0) {\n res.append(numbering.digits.charAt(num - 10));\n }\n } else {\n const thousands = Math.floor(num / 1000);\n if (thousands) {\n res.append(numbering.digits.charAt(thousands));\n res.append(numbering.markers.charAt(2));\n }\n const hundreds = Math.floor(num / 100) % 10;\n if (hundreds) {\n res.append(numbering.digits.charAt(hundreds));\n res.append(numbering.markers.charAt(1));\n }\n const tens = Math.floor(num / 10) % 10;\n if (tens) {\n res.append(numbering.digits.charAt(tens));\n res.append(numbering.markers.charAt(0));\n }\n const ones = num % 10;\n if (ones) {\n res.append(numbering.digits.charAt(ones));\n }\n }\n\n // res.append(\"\\u3001\");\n return res.toString();\n}\n\n/**\n * Fitting order and specificity in the same number. Order is recorded in the\n * fractional part. Select value so that\n *\n * 0x7FFFFFFF != 0x7FFFFFFF + ORDER_INCREMENT\n *\n */\nexport const ORDER_INCREMENT = 1 / 1048576;\n\nexport function copyTable(src: ActionTable, dst: ActionTable): void {\n for (const n in src) {\n dst[n] = src[n].clone();\n }\n}\n\nexport class Cascade {\n nsCount: number = 0;\n nsPrefix: { [key: string]: string } = {};\n tags: ActionTable = {};\n nstags: ActionTable = {};\n epubtypes: ActionTable = {};\n classes: ActionTable = {};\n ids: ActionTable = {};\n pagetypes: ActionTable = {};\n order: number = 0;\n\n clone(): Cascade {\n const r = new Cascade();\n r.nsCount = this.nsCount;\n for (const p in this.nsPrefix) {\n r.nsPrefix[p] = this.nsPrefix[p];\n }\n copyTable(this.tags, r.tags);\n copyTable(this.nstags, r.nstags);\n copyTable(this.epubtypes, r.epubtypes);\n copyTable(this.classes, r.classes);\n copyTable(this.ids, r.ids);\n copyTable(this.pagetypes, r.pagetypes);\n r.order = this.order;\n return r;\n }\n\n insertInTable(table: ActionTable, key: string, action: CascadeAction): void {\n const a = table[key];\n if (a) {\n action = a.mergeWith(action);\n }\n table[key] = action;\n }\n\n createInstance(\n context: Exprs.Context,\n counterListener: CounterListener,\n counterResolver: CounterResolver,\n lang,\n ): CascadeInstance {\n return new CascadeInstance(\n this,\n context,\n counterListener,\n counterResolver,\n lang,\n );\n }\n\n nextOrder(): number {\n return (this.order += ORDER_INCREMENT);\n }\n}\n\nexport class CascadeInstance {\n code: Cascade;\n stack = [[], []] as ConditionItem[][];\n conditions = {} as { [key: string]: number };\n currentElement: Element | null = null;\n currentElementOffset: number | null = null;\n currentStyle: ElementStyle | null = null;\n currentClassNames: string[] | null = null;\n currentLocalName: string = \"\";\n currentNamespace: string = \"\";\n currentId: string = \"\";\n currentXmlId: string = \"\";\n currentNSTag: string = \"\";\n currentEpubTypes: string[] | null = null;\n currentPageType: string | null = null;\n isFirst: boolean = true;\n isRoot: boolean = true;\n counters: { [key: string]: number[] } = {};\n counterScoping: { [key: string]: boolean }[] = [{}];\n quotes: Css.Str[];\n quoteDepth: number = 0;\n lang: string = \"\";\n siblingOrderStack: number[] = [0];\n currentSiblingOrder: number = 0;\n siblingTypeCountsStack: { [key: string]: { [key: string]: number } }[] = [{}];\n currentSiblingTypeCounts: { [key: string]: { [key: string]: number } };\n currentFollowingSiblingOrder: number | null = null;\n followingSiblingOrderStack: (number | null)[];\n followingSiblingTypeCountsStack: {\n [key: string]: { [key: string]: number };\n }[] = [{}];\n currentFollowingSiblingTypeCounts: {\n [key: string]: { [key: string]: number };\n };\n viewConditions: { [key: string]: Matchers.Matcher[] } = {};\n dependentConditions: string[] = [];\n elementStack: Element[];\n currentDoc?: Document | null;\n\n constructor(\n cascade: Cascade,\n public readonly context: Exprs.Context,\n public readonly counterListener: CounterListener,\n public readonly counterResolver: CounterResolver,\n lang: string,\n ) {\n this.code = cascade;\n this.quotes = [\n new Css.Str(\"\\u201c\"),\n new Css.Str(\"\\u201d\"),\n new Css.Str(\"\\u2018\"),\n new Css.Str(\"\\u2019\"),\n ];\n this.currentSiblingTypeCounts = this.siblingTypeCountsStack[0];\n this.followingSiblingOrderStack = [this.currentFollowingSiblingOrder];\n this.currentFollowingSiblingTypeCounts = this.siblingTypeCountsStack[0];\n if (VIVLIOSTYLE_DEBUG) {\n this.elementStack = [];\n }\n }\n\n pushConditionItem(item: ConditionItem): void {\n this.stack[this.stack.length - 1].push(item);\n }\n\n increment(condition: string, viewCondition: Matchers.Matcher): void {\n this.conditions[condition] = (this.conditions[condition] || 0) + 1;\n if (!viewCondition) {\n return;\n }\n if (this.viewConditions[condition]) {\n this.viewConditions[condition].push(viewCondition);\n } else {\n this.viewConditions[condition] = [viewCondition];\n }\n }\n\n decrement(condition: string, viewCondition: Matchers.Matcher): void {\n this.conditions[condition]--;\n if (!this.viewConditions[condition]) {\n return;\n }\n this.viewConditions[condition] = this.viewConditions[condition].filter(\n (item) => item !== viewCondition,\n );\n if (this.viewConditions[condition].length === 0) {\n delete this.viewConditions[condition];\n }\n }\n\n buildViewConditionMatcher(viewConditionId: string | null): Matchers.Matcher {\n let matcher: Matchers.Matcher = null;\n if (viewConditionId) {\n Asserts.assert(this.currentElementOffset);\n matcher = Matchers.MatcherBuilder.buildViewConditionMatcher(\n this.currentElementOffset,\n viewConditionId,\n );\n }\n const dependentConditionMatchers = this.dependentConditions\n .map((conditionId) => {\n const conditions = this.viewConditions[conditionId];\n if (conditions && conditions.length > 0) {\n return conditions.length === 1\n ? conditions[0]\n : Matchers.MatcherBuilder.buildAnyMatcher([].concat(conditions));\n } else {\n return null;\n }\n })\n .filter((item) => item);\n if (dependentConditionMatchers.length <= 0) {\n return matcher;\n }\n if (matcher === null) {\n return dependentConditionMatchers.length === 1\n ? dependentConditionMatchers[0]\n : Matchers.MatcherBuilder.buildAllMatcher(dependentConditionMatchers);\n }\n return Matchers.MatcherBuilder.buildAllMatcher(\n [matcher].concat(dependentConditionMatchers),\n );\n }\n\n applyAction(table: ActionTable, key: string): void {\n const action = table[key];\n if (action) {\n action.apply(this);\n }\n }\n\n pushRule(\n classes: string[],\n pageType: string | null,\n baseStyle: ElementStyle,\n ): void {\n this.currentElement = null;\n this.currentElementOffset = null;\n this.currentStyle = baseStyle;\n this.currentNamespace = \"\";\n this.currentLocalName = \"\";\n this.currentId = \"\";\n this.currentXmlId = \"\";\n this.currentClassNames = classes;\n this.currentNSTag = \"\";\n this.currentEpubTypes = EMPTY;\n this.currentPageType = pageType;\n this.applyActions();\n }\n\n defineCounter(counterName: string, value: number) {\n if (this.counters[counterName]) {\n this.counters[counterName].push(value);\n } else {\n this.counters[counterName] = [value];\n }\n let scoping = this.counterScoping[this.counterScoping.length - 1];\n if (!scoping) {\n scoping = {};\n this.counterScoping[this.counterScoping.length - 1] = scoping;\n }\n scoping[counterName] = true;\n }\n\n pushCounters(props: ElementStyle): void {\n let displayVal = Css.ident.inline;\n const display = props[\"display\"];\n if (display) {\n displayVal = display.evaluate(this.context);\n }\n let resetMap: { [key: string]: number } = null;\n let incrementMap: { [key: string]: number } = null;\n let setMap: { [key: string]: number } = null;\n const reset = props[\"counter-reset\"];\n if (reset) {\n const resetVal = reset.evaluate(this.context);\n if (resetVal) {\n resetMap = CssProp.toCounters(resetVal, true);\n }\n }\n const set = props[\"counter-set\"];\n if (set) {\n const setVal = set.evaluate(this.context);\n if (setVal) {\n setMap = CssProp.toCounters(setVal, false);\n }\n }\n const increment = props[\"counter-increment\"];\n if (increment) {\n const incrementVal = increment.evaluate(this.context);\n if (incrementVal) {\n incrementMap = CssProp.toCounters(incrementVal, false);\n }\n }\n if (\n (this.currentLocalName == \"ol\" || this.currentLocalName == \"ul\") &&\n this.currentNamespace == Base.NS.XHTML\n ) {\n if (!resetMap) {\n resetMap = {};\n }\n resetMap[\"ua-list-item\"] = 0;\n }\n if (displayVal === Css.ident.list_item) {\n if (!incrementMap) {\n incrementMap = {};\n }\n incrementMap[\"ua-list-item\"] = 1;\n }\n if (resetMap) {\n for (const resetCounterName in resetMap) {\n this.defineCounter(resetCounterName, resetMap[resetCounterName]);\n }\n }\n if (setMap) {\n for (const setCounterName in setMap) {\n if (!this.counters[setCounterName]) {\n this.defineCounter(setCounterName, setMap[setCounterName]);\n } else {\n const counterValues = this.counters[setCounterName];\n counterValues[counterValues.length - 1] = setMap[setCounterName];\n }\n }\n }\n if (incrementMap) {\n for (const incrementCounterName in incrementMap) {\n if (!this.counters[incrementCounterName]) {\n this.defineCounter(incrementCounterName, 0);\n }\n const counterValues = this.counters[incrementCounterName];\n counterValues[counterValues.length - 1] +=\n incrementMap[incrementCounterName];\n }\n }\n if (displayVal === Css.ident.list_item) {\n const listItemCounts = this.counters[\"ua-list-item\"];\n const listItemCount = listItemCounts[listItemCounts.length - 1];\n props[\"ua-list-item-count\"] = new CascadeValue(\n new Css.Num(listItemCount),\n 0,\n );\n }\n this.counterScoping.push(null);\n }\n\n popCounters(): void {\n const scoping = this.counterScoping.pop();\n if (scoping) {\n for (const counterName in scoping) {\n const arr = this.counters[counterName];\n if (arr) {\n if (arr.length == 1) {\n delete this.counters[counterName];\n } else {\n arr.pop();\n }\n }\n }\n }\n }\n\n processPseudoelementProps(pseudoprops: ElementStyle, element: Element): void {\n this.pushCounters(pseudoprops);\n if (pseudoprops[\"content\"]) {\n pseudoprops[\"content\"] = pseudoprops[\"content\"].filterValue(\n new ContentPropVisitor(this, element, this.counterResolver),\n );\n }\n this.popCounters();\n }\n\n pushElement(\n element: Element,\n baseStyle: ElementStyle,\n elementOffset: number,\n ): void {\n if (VIVLIOSTYLE_DEBUG) {\n this.elementStack.push(element);\n }\n\n // do not apply page rules\n this.currentPageType = null;\n this.currentElement = element;\n this.currentElementOffset = elementOffset;\n this.currentStyle = baseStyle;\n this.currentNamespace = element.namespaceURI;\n this.currentLocalName = element.localName;\n const prefix = this.code.nsPrefix[this.currentNamespace];\n if (prefix) {\n this.currentNSTag = prefix + this.currentLocalName;\n } else {\n this.currentNSTag = \"\";\n }\n this.currentId = element.getAttribute(\"id\");\n this.currentXmlId = element.getAttributeNS(Base.NS.XML, \"id\");\n const classes = element.getAttribute(\"class\");\n if (classes) {\n this.currentClassNames = classes.split(/\\s+/);\n } else {\n this.currentClassNames = EMPTY;\n }\n const types = element.getAttributeNS(Base.NS.epub, \"type\");\n if (types) {\n this.currentEpubTypes = types.split(/\\s+/);\n } else {\n this.currentEpubTypes = EMPTY;\n }\n if (\n this.currentLocalName == \"style\" &&\n this.currentNamespace == Base.NS.FB2\n ) {\n // special case\n const className = element.getAttribute(\"name\") || \"\";\n this.currentClassNames = [className];\n }\n const lang = Base.getLangAttribute(element);\n if (lang) {\n this.stack[this.stack.length - 1].push(new RestoreLangItem(this.lang));\n this.lang = lang.toLowerCase();\n }\n const isRoot = this.isRoot;\n const siblingOrderStack = this.siblingOrderStack;\n this.currentSiblingOrder = ++siblingOrderStack[\n siblingOrderStack.length - 1\n ];\n siblingOrderStack.push(0);\n const siblingTypeCountsStack = this.siblingTypeCountsStack;\n const currentSiblingTypeCounts = (this.currentSiblingTypeCounts =\n siblingTypeCountsStack[siblingTypeCountsStack.length - 1]);\n let currentNamespaceTypeCounts =\n currentSiblingTypeCounts[this.currentNamespace];\n if (!currentNamespaceTypeCounts) {\n currentNamespaceTypeCounts = currentSiblingTypeCounts[\n this.currentNamespace\n ] = {};\n }\n currentNamespaceTypeCounts[this.currentLocalName] =\n (currentNamespaceTypeCounts[this.currentLocalName] || 0) + 1;\n siblingTypeCountsStack.push({});\n const followingSiblingOrderStack = this.followingSiblingOrderStack;\n if (\n followingSiblingOrderStack[followingSiblingOrderStack.length - 1] !== null\n ) {\n this.currentFollowingSiblingOrder = --followingSiblingOrderStack[\n followingSiblingOrderStack.length - 1\n ];\n } else {\n this.currentFollowingSiblingOrder = null;\n }\n followingSiblingOrderStack.push(null);\n const followingSiblingTypeCountsStack = this\n .followingSiblingTypeCountsStack;\n const currentFollowingSiblingTypeCounts = (this.currentFollowingSiblingTypeCounts =\n followingSiblingTypeCountsStack[\n followingSiblingTypeCountsStack.length - 1\n ]);\n if (\n currentFollowingSiblingTypeCounts &&\n currentFollowingSiblingTypeCounts[this.currentNamespace]\n ) {\n currentFollowingSiblingTypeCounts[this.currentNamespace][\n this.currentLocalName\n ]--;\n }\n followingSiblingTypeCountsStack.push({});\n this.applyActions();\n this.applyAttrFilter(element);\n const quotesCasc = baseStyle[\"quotes\"];\n let itemToPushLast: QuotesScopeItem | null = null;\n if (quotesCasc) {\n const quotesVal = quotesCasc.evaluate(this.context);\n if (quotesVal) {\n itemToPushLast = new QuotesScopeItem(this.quotes);\n if (quotesVal === Css.ident.none) {\n this.quotes = [new Css.Str(\"\"), new Css.Str(\"\")];\n } else if (quotesVal instanceof Css.SpaceList) {\n this.quotes = (quotesVal as Css.SpaceList).values as Css.Str[];\n }\n }\n }\n this.pushCounters(this.currentStyle);\n const id =\n this.currentId || this.currentXmlId || element.getAttribute(\"name\") || \"\";\n if (isRoot || id) {\n const counters: { [key: string]: number[] } = {};\n Object.keys(this.counters).forEach((name) => {\n counters[name] = Array.from(this.counters[name]);\n });\n this.counterListener.countersOfId(id, counters);\n }\n const pseudos = getStyleMap(this.currentStyle, \"_pseudos\");\n if (pseudos) {\n let before = true;\n for (const pseudoName of pseudoNames) {\n if (!pseudoName) {\n // content\n before = false;\n }\n const pseudoProps = pseudos[pseudoName];\n if (pseudoProps) {\n if (before) {\n this.processPseudoelementProps(pseudoProps, element);\n } else {\n this.stack[this.stack.length - 2].push(\n new AfterPseudoelementItem(pseudoProps, element),\n );\n }\n }\n }\n }\n if (itemToPushLast) {\n this.stack[this.stack.length - 2].push(itemToPushLast);\n }\n }\n\n private applyAttrFilterInner(visitor, elementStyle): void {\n for (const propName in elementStyle) {\n if (isPropName(propName)) {\n elementStyle[propName] = elementStyle[propName].filterValue(visitor);\n }\n }\n }\n\n private applyAttrFilter(element): void {\n const visitor = new AttrValueFilterVisitor(element);\n const currentStyle = this.currentStyle;\n const pseudoMap = getStyleMap(currentStyle, \"_pseudos\");\n for (const pseudoName in pseudoMap) {\n this.applyAttrFilterInner(visitor, pseudoMap[pseudoName]);\n }\n this.applyAttrFilterInner(visitor, currentStyle);\n }\n\n private applyActions(): void {\n let i: number;\n for (i = 0; i < this.currentClassNames.length; i++) {\n this.applyAction(this.code.classes, this.currentClassNames[i]);\n }\n for (i = 0; i < this.currentEpubTypes.length; i++) {\n this.applyAction(this.code.epubtypes, this.currentEpubTypes[i]);\n }\n this.applyAction(this.code.ids, this.currentId);\n this.applyAction(this.code.tags, this.currentLocalName);\n if (this.currentLocalName != \"\") {\n // Universal selector does not apply to page-master-related rules.\n this.applyAction(this.code.tags, \"*\");\n }\n this.applyAction(this.code.nstags, this.currentNSTag);\n\n // Apply page rules only when currentPageType is not null\n if (this.currentPageType !== null) {\n this.applyAction(this.code.pagetypes, this.currentPageType);\n\n // We represent page rules without selectors by *, though it is illegal in\n // CSS\n this.applyAction(this.code.pagetypes, \"*\");\n }\n this.currentElement = null;\n this.currentDoc = null;\n this.stack.push([]);\n for (let depth = 1; depth >= -1; --depth) {\n const list = this.stack[this.stack.length - depth - 2];\n i = 0;\n while (i < list.length) {\n if (list[i].push(this, depth)) {\n // done\n list.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n this.isFirst = true;\n this.isRoot = false;\n }\n\n private pop(): void {\n for (let depth = 1; depth >= -1; --depth) {\n const list = this.stack[this.stack.length - depth - 2];\n let i = 0;\n while (i < list.length) {\n if (list[i].pop(this, depth)) {\n // done\n list.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n this.stack.pop();\n this.isFirst = false;\n }\n\n popRule(): void {\n this.pop();\n }\n\n popElement(element: Element): void {\n if (VIVLIOSTYLE_DEBUG) {\n const e = this.elementStack.pop();\n if (e !== element) {\n throw new Error(\"Invalid call to popElement\");\n }\n }\n this.siblingOrderStack.pop();\n this.siblingTypeCountsStack.pop();\n this.followingSiblingOrderStack.pop();\n this.followingSiblingTypeCountsStack.pop();\n this.pop();\n this.popCounters();\n }\n}\n\nexport const EMPTY = [];\n\n/**\n * Pseudoelement names in the order they should be processed, empty string is\n * the place where the element's DOM children are processed.\n */\nexport const pseudoNames = [\n \"before\",\n \"transclusion-before\",\n \"footnote-call\",\n \"footnote-marker\",\n \"inner\",\n \"first-letter\",\n \"first-line\",\n \"\",\n /* content */\n \"transclusion-after\",\n \"after\",\n];\n\n/**\n * @enum {number}\n */\nexport enum ParseState {\n TOP,\n SELECTOR,\n RULE,\n}\n\n/**\n * Cascade for base User Agent stylesheet.\n */\nexport let uaBaseCascade: Cascade = null;\nexport function setUABaseCascade(value: Cascade): void {\n uaBaseCascade = value;\n}\n\n//------------- parsing ------------\nexport class CascadeParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n chain: ChainedAction[] = null;\n specificity: number = 0;\n elementStyle: ElementStyle = null;\n conditionCount: number = 0;\n pseudoelement: string | null = null;\n footnoteContent: boolean = false;\n cascade: Cascade;\n state: ParseState;\n viewConditionId: string | null = null;\n insideSelectorRule: ParseState;\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly condition: Exprs.Val,\n parent: CascadeParserHandler,\n public readonly regionId: string | null,\n public readonly validatorSet: CssValidator.ValidatorSet,\n topLevel: boolean,\n ) {\n super(scope, owner, topLevel);\n this.cascade = parent\n ? parent.cascade\n : uaBaseCascade\n ? uaBaseCascade.clone()\n : new Cascade();\n this.state = ParseState.TOP;\n }\n\n protected insertNonPrimary(action: CascadeAction): void {\n this.cascade.insertInTable(this.cascade.tags, \"*\", action);\n }\n\n processChain(action: CascadeAction): void {\n const chained = chainActions(this.chain, action);\n if (\n chained !== action &&\n (chained as ChainedAction).makePrimary(this.cascade)\n ) {\n return;\n }\n this.insertNonPrimary(chained);\n }\n\n isInsideSelectorRule(mnemonics: string): boolean {\n if (this.state != ParseState.TOP) {\n this.reportAndSkip(mnemonics);\n return true;\n }\n return false;\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n if (!name && !ns) {\n return;\n }\n this.specificity += 1;\n if (name && ns) {\n this.chain.push(new CheckNSTagAction(ns, name.toLowerCase()));\n } else if (name) {\n this.chain.push(new CheckLocalNameAction(name.toLowerCase()));\n } else {\n this.chain.push(new CheckNamespaceAction(ns as string));\n }\n }\n\n /**\n * @override\n */\n classSelector(name: string): void {\n if (this.pseudoelement) {\n Logging.logger.warn(`::${this.pseudoelement}`, `followed by .${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n return;\n }\n this.specificity += 256;\n this.chain.push(new CheckClassAction(name));\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n if (this.pseudoelement) {\n Logging.logger.warn(`::${this.pseudoelement}`, `followed by :${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n return;\n }\n switch (name.toLowerCase()) {\n case \"enabled\":\n this.chain.push(new IsEnabledAction());\n break;\n case \"disabled\":\n this.chain.push(new IsDisabledAction());\n break;\n case \"checked\":\n this.chain.push(new IsCheckedAction());\n break;\n case \"root\":\n this.chain.push(new IsRootAction());\n break;\n case \"link\":\n this.chain.push(new CheckLocalNameAction(\"a\"));\n this.chain.push(new CheckAttributePresentAction(\"\", \"href\"));\n break;\n case \"-adapt-href-epub-type\":\n case \"href-epub-type\":\n if (params && params.length == 1 && typeof params[0] == \"string\") {\n const value = params[0] as string;\n const patt = new RegExp(`(^|s)${Base.escapeRegExp(value)}(\\$|s)`);\n this.chain.push(new CheckTargetEpubTypeAction(patt));\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n case \"-adapt-footnote-content\":\n case \"footnote-content\":\n // content inside the footnote\n this.footnoteContent = true;\n break;\n case \"visited\":\n case \"active\":\n case \"hover\":\n case \"focus\":\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n case \"lang\":\n if (params && params.length == 1 && typeof params[0] == \"string\") {\n const langValue = params[0] as string;\n this.chain.push(\n new CheckLangAction(\n new RegExp(\n `^${Base.escapeRegExp(langValue.toLowerCase())}(\\$|-)`,\n ),\n ),\n );\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fais\n }\n break;\n case \"nth-child\":\n case \"nth-last-child\":\n case \"nth-of-type\":\n case \"nth-last-of-type\": {\n const ActionClass = nthSelectorActionClasses[name.toLowerCase()];\n if (params && params.length == 2) {\n this.chain.push(\n new ActionClass(params[0] as number, params[1] as number),\n );\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n }\n case \"first-child\":\n this.chain.push(new IsFirstAction());\n break;\n case \"last-child\":\n this.chain.push(new IsNthLastSiblingAction(0, 1));\n break;\n case \"first-of-type\":\n this.chain.push(new IsNthSiblingOfTypeAction(0, 1));\n break;\n case \"last-of-type\":\n this.chain.push(new IsNthLastSiblingOfTypeAction(0, 1));\n break;\n case \"only-child\":\n this.chain.push(new IsFirstAction());\n this.chain.push(new IsNthLastSiblingAction(0, 1));\n break;\n case \"only-of-type\":\n this.chain.push(new IsNthSiblingOfTypeAction(0, 1));\n this.chain.push(new IsNthLastSiblingOfTypeAction(0, 1));\n break;\n case \"empty\":\n this.chain.push(new IsEmptyAction());\n break;\n case \"before\":\n case \"after\":\n case \"first-line\":\n case \"first-letter\":\n this.pseudoelementSelector(name, params);\n return;\n default:\n Logging.logger.warn(`unknown pseudo-class selector: ${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n }\n this.specificity += 256;\n }\n\n /**\n * @override\n */\n pseudoelementSelector(name: string, params: (number | string)[]): void {\n switch (name) {\n case \"before\":\n case \"after\":\n case \"first-line\":\n case \"first-letter\":\n case \"footnote-call\":\n case \"footnote-marker\":\n case \"inner\":\n case \"after-if-continues\":\n if (!this.pseudoelement) {\n this.pseudoelement = name;\n } else {\n Logging.logger.warn(\n `Double pseudoelement ::${this.pseudoelement}::${name}`,\n );\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n case \"first-n-lines\":\n if (params && params.length == 1 && typeof params[0] == \"number\") {\n const n = Math.round(params[0] as number);\n if (n > 0 && n == params[0]) {\n if (!this.pseudoelement) {\n this.pseudoelement = `first-${n}-lines`;\n } else {\n Logging.logger.warn(\n `Double pseudoelement ::${this.pseudoelement}::${name}`,\n );\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n }\n }\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n case \"nth-fragment\":\n if (params && params.length == 2) {\n this.viewConditionId = `NFS_${params[0]}_${params[1]}`;\n } else {\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n }\n break;\n default:\n Logging.logger.warn(`Unrecognized pseudoelement: ::${name}`);\n this.chain.push(new CheckConditionAction(\"\")); // always fails\n break;\n }\n this.specificity += 1;\n }\n\n /**\n * @override\n */\n idSelector(id: string): void {\n this.specificity += 65536;\n this.chain.push(new CheckIdAction(id));\n }\n\n /**\n * @override\n */\n attributeSelector(\n ns: string,\n name: string,\n op: CssTokenizer.TokenType,\n value: string | null,\n ): void {\n this.specificity += 256;\n name = name.toLowerCase();\n value = value || \"\";\n let action;\n switch (op) {\n case CssTokenizer.TokenType.EOF:\n action = new CheckAttributePresentAction(ns, name);\n break;\n case CssTokenizer.TokenType.EQ:\n action = new CheckAttributeEqAction(ns, name, value);\n break;\n case CssTokenizer.TokenType.TILDE_EQ:\n if (!value || value.match(/\\s/)) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`(^|\\\\s)${Base.escapeRegExp(value)}(\\$|\\\\s)`),\n );\n }\n break;\n case CssTokenizer.TokenType.BAR_EQ:\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`^${Base.escapeRegExp(value)}(\\$|-)`),\n );\n break;\n case CssTokenizer.TokenType.HAT_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`^${Base.escapeRegExp(value)}`),\n );\n }\n break;\n case CssTokenizer.TokenType.DOLLAR_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(`${Base.escapeRegExp(value)}\\$`),\n );\n }\n break;\n case CssTokenizer.TokenType.STAR_EQ:\n if (!value) {\n action = new CheckConditionAction(\"\"); // always fails\n } else {\n action = new CheckAttributeRegExpAction(\n ns,\n name,\n new RegExp(Base.escapeRegExp(value)),\n );\n }\n break;\n case CssTokenizer.TokenType.COL_COL:\n if (value == \"supported\") {\n action = new CheckNamespaceSupportedAction(ns, name);\n } else {\n Logging.logger.warn(\"Unsupported :: attr selector op:\", value);\n action = new CheckConditionAction(\"\"); // always fails\n }\n break;\n default:\n Logging.logger.warn(\"Unsupported attr selector:\", op);\n action = new CheckConditionAction(\"\"); // always fails\n }\n this.chain.push(action);\n }\n\n /**\n * @override\n */\n descendantSelector(): void {\n const condition = `d${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new DescendantConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n childSelector(): void {\n const condition = `c${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new ChildConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n adjacentSiblingSelector(): void {\n const condition = `a${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new AdjacentSiblingConditionItem(condition, this.viewConditionId, null),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n followingSiblingSelector(): void {\n const condition = `f${conditionCount++}`;\n this.processChain(\n new ConditionItemAction(\n new FollowingSiblingConditionItem(\n condition,\n this.viewConditionId,\n null,\n ),\n ),\n );\n this.chain = [new CheckConditionAction(condition)];\n this.viewConditionId = null;\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.finishChain();\n this.pseudoelement = null;\n this.footnoteContent = false;\n this.specificity = 0;\n this.chain = [];\n }\n\n /**\n * @override\n */\n startSelectorRule(): void {\n if (this.isInsideSelectorRule(\"E_CSS_UNEXPECTED_SELECTOR\")) {\n return;\n }\n this.state = ParseState.SELECTOR;\n this.elementStyle = {} as ElementStyle;\n this.pseudoelement = null;\n this.specificity = 0;\n this.footnoteContent = false;\n this.chain = [];\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n super.error(mnemonics, token);\n if (this.state == ParseState.SELECTOR) {\n this.state = ParseState.TOP;\n }\n }\n\n /**\n * @override\n */\n startStylesheet(flavor: CssParser.StylesheetFlavor): void {\n super.startStylesheet(flavor);\n this.state = ParseState.TOP;\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.finishChain();\n super.startRuleBody();\n if (this.state == ParseState.SELECTOR) {\n this.state = ParseState.TOP;\n }\n }\n\n /**\n * @override\n */\n endRule(): void {\n super.endRule();\n this.insideSelectorRule = ParseState.TOP;\n }\n\n finishChain(): void {\n if (this.chain) {\n const specificity: number = this.specificity + this.cascade.nextOrder();\n this.processChain(this.makeApplyRuleAction(specificity));\n this.chain = null;\n this.pseudoelement = null;\n this.viewConditionId = null;\n this.footnoteContent = false;\n this.specificity = 0;\n }\n }\n\n protected makeApplyRuleAction(specificity: number): ApplyRuleAction {\n let regionId = this.regionId;\n if (this.footnoteContent) {\n if (regionId) {\n regionId = \"xxx-bogus-xxx\";\n } else {\n regionId = \"footnote\";\n }\n }\n return new ApplyRuleAction(\n this.elementStyle,\n specificity,\n this.pseudoelement,\n regionId,\n this.viewConditionId,\n );\n }\n\n special(name: string, value: Css.Val) {\n let val: CascadeValue;\n if (!this.condition) {\n val = new CascadeValue(value, 0);\n } else {\n val = new ConditionalCascadeValue(value, 0, this.condition);\n }\n const arr = getMutableSpecial(this.elementStyle, name);\n arr.push(val);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n if (\n name == \"display\" &&\n (value === Css.ident.oeb_page_head || value === Css.ident.oeb_page_foot)\n ) {\n this.simpleProperty(\n \"flow-options\",\n new Css.SpaceList([Css.ident.exclusive, Css.ident._static]),\n important,\n );\n this.simpleProperty(\"flow-into\", value, important);\n value = Css.ident.block;\n }\n const hooks = Plugin.getHooksForName(\"SIMPLE_PROPERTY\");\n hooks.forEach((hook) => {\n const original = { name: name, value: value, important: important };\n const converted = hook(original);\n name = converted[\"name\"];\n value = converted[\"value\"];\n important = converted[\"important\"];\n });\n const specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n const cascval = this.condition\n ? new ConditionalCascadeValue(value, specificity, this.condition)\n : new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, cascval);\n }\n\n finish(): Cascade {\n return this.cascade;\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n switch (funcName) {\n case \"not\": {\n const notParserHandler = new NotParameterParserHandler(this);\n notParserHandler.startSelectorRule();\n this.owner.pushHandler(notParserHandler);\n break;\n }\n default:\n // TODO\n break;\n }\n }\n}\n\nexport const nthSelectorActionClasses: { [key: string]: typeof IsNthAction } = {\n \"nth-child\": IsNthSiblingAction,\n \"nth-of-type\": IsNthSiblingOfTypeAction,\n \"nth-last-child\": IsNthLastSiblingAction,\n \"nth-last-of-type\": IsNthLastSiblingOfTypeAction,\n};\n\nexport let conditionCount: number = 0;\n\nexport class NotParameterParserHandler extends CascadeParserHandler {\n parentChain: ChainedAction[];\n\n constructor(public readonly parent: CascadeParserHandler) {\n super(\n parent.scope,\n parent.owner,\n parent.condition,\n parent,\n parent.regionId,\n parent.validatorSet,\n false,\n );\n this.parentChain = parent.chain;\n }\n\n /**\n * @override\n */\n startFuncWithSelector(funcName: string): void {\n if (funcName == \"not\") {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_NOT\");\n }\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_RULE_BODY\");\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.reportAndSkip(\"E_CSS_UNEXPECTED_NEXT_SELECTOR\");\n }\n\n /**\n * @override\n */\n endFuncWithSelector(): void {\n if (this.chain && this.chain.length > 0) {\n this.parentChain.push(new NegateActionsSet(this.chain));\n }\n this.parent.specificity += this.specificity;\n this.owner.popHandler();\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n super.error(mnemonics, token);\n this.owner.popHandler();\n }\n}\n\n/**\n * @override\n */\nexport class DefineParserHandler extends CssParser.SlaveParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n if (this.scope.values[name]) {\n this.error(`E_CSS_NAME_REDEFINED ${name}`, this.getCurrentToken());\n } else {\n const unit = name.match(/height|^(top|bottom)$/) ? \"vh\" : \"vw\";\n const dim = new Exprs.Numeric(this.scope, 100, unit);\n this.scope.defineName(name, value.toExpr(this.scope, dim));\n }\n }\n}\n\nexport class PropSetParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n order: number;\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly condition: Exprs.Val,\n public readonly elementStyle: ElementStyle,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, false);\n this.order = 0;\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n if (important) {\n Logging.logger.warn(\"E_IMPORTANT_NOT_ALLOWED\");\n } else {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n Logging.logger.warn(\n \"E_INVALID_PROPERTY_VALUE\",\n `${name}:`,\n value.toString(),\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n Logging.logger.warn(\"E_INVALID_PROPERTY\", `${name}:`, value.toString());\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n let specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n specificity += this.order;\n this.order += ORDER_INCREMENT;\n const av = this.condition\n ? new ConditionalCascadeValue(value, specificity, this.condition)\n : new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, av);\n }\n}\n\nexport class PropertyParserHandler extends CssParser.ErrorHandler\n implements CssValidator.PropertyReceiver {\n elementStyle = {} as ElementStyle;\n order: number = 0;\n\n constructor(\n scope: Exprs.LexicalScope,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n Logging.logger.warn(\n \"E_INVALID_PROPERTY_VALUE\",\n `${name}:`,\n value.toString(),\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n Logging.logger.warn(\"E_INVALID_PROPERTY\", `${name}:`, value.toString());\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n let specificity = important\n ? CssParser.SPECIFICITY_STYLE_IMPORTANT\n : CssParser.SPECIFICITY_STYLE;\n specificity += this.order;\n this.order += ORDER_INCREMENT;\n const cascval = new CascadeValue(value, specificity);\n setProp(this.elementStyle, name, cascval);\n }\n}\n\nexport function forEachViewConditionalStyles(\n style: ElementStyle,\n callback: (p1: ElementStyle) => any,\n): void {\n const viewConditionalStyles = getViewConditionalStyleMap(style);\n if (!viewConditionalStyles) {\n return;\n }\n viewConditionalStyles.forEach((entry) => {\n if (!entry.matcher.matches()) {\n return;\n }\n callback(entry.styles);\n });\n}\n\nexport function mergeViewConditionalStyles(\n cascMap: { [key: string]: CascadeValue },\n context: Exprs.Context,\n style: ElementStyle,\n): void {\n forEachViewConditionalStyles(style, (viewConditionalStyles) => {\n mergeStyle(cascMap, viewConditionalStyles, context);\n });\n}\n\nexport function parseStyleAttribute(\n scope: Exprs.LexicalScope,\n validatorSet: CssValidator.ValidatorSet,\n baseURL: string,\n styleAttrValue: string,\n): ElementStyle {\n const handler = new PropertyParserHandler(scope, validatorSet);\n const tokenizer = new CssTokenizer.Tokenizer(styleAttrValue, handler);\n try {\n CssParser.parseStyleAttribute(tokenizer, handler, baseURL);\n } catch (err) {\n Logging.logger.warn(err, \"Style attribute parse error:\");\n }\n return handler.elementStyle;\n}\n\nexport function isVertical(\n cascaded: { [key: string]: CascadeValue },\n context: Exprs.Context,\n vertical: boolean,\n): boolean {\n const writingModeCasc = cascaded[\"writing-mode\"];\n if (writingModeCasc) {\n const writingMode = writingModeCasc.evaluate(context, \"writing-mode\");\n if (writingMode && writingMode !== Css.ident.inherit) {\n return writingMode === Css.ident.vertical_rl;\n }\n }\n return vertical;\n}\n\nexport function isRtl(\n cascaded: { [key: string]: CascadeValue },\n context: Exprs.Context,\n rtl: boolean,\n): boolean {\n const directionCasc = cascaded[\"direction\"];\n if (directionCasc) {\n const direction = directionCasc.evaluate(context, \"direction\");\n if (direction && direction !== Css.ident.inherit) {\n return direction === Css.ident.rtl;\n }\n }\n return rtl;\n}\n\nexport function flattenCascadedStyle(\n style: ElementStyle,\n context: Exprs.Context,\n regionIds: string[],\n isFootnote: boolean,\n nodeContext: Vtree.NodeContext,\n): { [key: string]: CascadeValue } {\n const cascMap = {} as { [key: string]: CascadeValue };\n for (const n in style) {\n if (isPropName(n)) {\n cascMap[n] = getProp(style, n);\n }\n }\n mergeViewConditionalStyles(cascMap, context, style);\n forEachStylesInRegion(\n style,\n regionIds,\n isFootnote,\n (regionId, regionStyle) => {\n mergeStyle(cascMap, regionStyle, context);\n mergeViewConditionalStyles(cascMap, context, regionStyle);\n },\n );\n return cascMap;\n}\n\nexport function forEachStylesInRegion(\n style: ElementStyle,\n regionIds: string[],\n isFootnote: boolean,\n callback: (p1: string, p2: ElementStyle) => any,\n): void {\n const regions = getStyleMap(style, \"_regions\");\n if ((regionIds || isFootnote) && regions) {\n if (isFootnote) {\n const footnoteRegion = [\"footnote\"];\n if (!regionIds) {\n regionIds = footnoteRegion;\n } else {\n regionIds = regionIds.concat(footnoteRegion);\n }\n }\n for (const regionId of regionIds) {\n const regionStyle = regions[regionId];\n if (regionStyle) {\n callback(regionId, regionStyle);\n }\n }\n }\n}\n\nexport function mergeStyle(\n to: { [key: string]: CascadeValue },\n from: ElementStyle,\n context: Exprs.Context,\n): void {\n for (const property in from) {\n if (isPropName(property)) {\n const newVal = getProp(from, property);\n const oldVal = to[property];\n to[property] = cascadeValues(context, oldVal, newVal as CascadeValue);\n }\n }\n}\n\n/**\n * Convert logical properties to physical ones, taking specificity into account.\n * @param src Source properties map\n * @param dest Destination map\n * @param transform If supplied, property values are transformed by this\n * function before inserted into the destination map. The first parameter is\n * the property name and the second one is the property value.\n * @template T\n */\nexport const convertToPhysical = <T>(\n src: { [key: string]: CascadeValue },\n dest: { [key: string]: T },\n vertical: boolean,\n rtl: boolean,\n transform: (p1: string, p2: CascadeValue) => T,\n) => {\n const couplingMap = vertical\n ? rtl\n ? couplingMapVertRtl\n : couplingMapVert\n : rtl\n ? couplingMapHorRtl\n : couplingMapHor;\n for (const propName in src) {\n if (src.hasOwnProperty(propName)) {\n const cascVal = src[propName];\n if (!cascVal) {\n continue;\n }\n const coupledName = couplingMap[propName];\n let targetName: string;\n if (coupledName) {\n const coupledCascVal = src[coupledName];\n if (coupledCascVal && coupledCascVal.priority > cascVal.priority) {\n continue;\n }\n targetName = geomNames[coupledName] ? coupledName : propName;\n } else {\n targetName = propName;\n }\n dest[targetName] = transform(propName, cascVal);\n }\n }\n};\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssLogicalUtil - Utilities related to CSS Logical Properties and Values https://drafts.csswg.org/css-logical/\n */\ntype ConversionMap = {\n regexp: RegExp;\n to: string;\n};\n\nfunction createRegExpMap(\n valueMaps: {\n [key: string]: { [key: string]: { logical: string; physical: string }[] };\n },\n toPhysical: boolean,\n): { [key: string]: { [key: string]: ConversionMap[] } } {\n const map = {};\n Object.keys(valueMaps as object).forEach((writingMode) => {\n const dest = (map[writingMode] = {});\n const src = valueMaps[writingMode];\n Object.keys(src as object).forEach((direction) => {\n dest[direction] = src[direction].map((p) => {\n const from = toPhysical ? p.logical : p.physical;\n const to = toPhysical ? p.physical : p.logical;\n return { regexp: new RegExp(`(-?)${from}(-?)`), to: `\\$1${to}\\$2` };\n });\n });\n });\n return map;\n}\n\nfunction convert(\n value: string,\n writingMode: string,\n direction: string | null,\n maps: { [key: string]: { [key: string]: ConversionMap[] } },\n): string {\n const maps2 = maps[writingMode];\n if (!maps2) {\n throw new Error(`unknown writing-mode: ${writingMode}`);\n }\n const map = maps2[direction || \"ltr\"];\n if (!map) {\n throw new Error(`unknown direction: ${direction}`);\n }\n for (const p of map) {\n const replaced = value.replace(p.regexp, p.to);\n if (replaced !== value) {\n return replaced;\n }\n }\n return value;\n}\nconst values: {\n [key: string]: { [key: string]: { logical: string; physical: string }[] };\n} = {\n \"horizontal-tb\": {\n ltr: [\n { logical: \"inline-start\", physical: \"left\" },\n { logical: \"inline-end\", physical: \"right\" },\n { logical: \"block-start\", physical: \"top\" },\n { logical: \"block-end\", physical: \"bottom\" },\n { logical: \"inline-size\", physical: \"width\" },\n { logical: \"block-size\", physical: \"height\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"right\" },\n { logical: \"inline-end\", physical: \"left\" },\n { logical: \"block-start\", physical: \"top\" },\n { logical: \"block-end\", physical: \"bottom\" },\n { logical: \"inline-size\", physical: \"width\" },\n { logical: \"block-size\", physical: \"height\" },\n ],\n },\n \"vertical-rl\": {\n ltr: [\n { logical: \"inline-start\", physical: \"top\" },\n { logical: \"inline-end\", physical: \"bottom\" },\n { logical: \"block-start\", physical: \"right\" },\n { logical: \"block-end\", physical: \"left\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"bottom\" },\n { logical: \"inline-end\", physical: \"top\" },\n { logical: \"block-start\", physical: \"right\" },\n { logical: \"block-end\", physical: \"left\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n },\n \"vertical-lr\": {\n ltr: [\n { logical: \"inline-start\", physical: \"top\" },\n { logical: \"inline-end\", physical: \"bottom\" },\n { logical: \"block-start\", physical: \"left\" },\n { logical: \"block-end\", physical: \"right\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n rtl: [\n { logical: \"inline-start\", physical: \"bottom\" },\n { logical: \"inline-end\", physical: \"top\" },\n { logical: \"block-start\", physical: \"left\" },\n { logical: \"block-end\", physical: \"right\" },\n { logical: \"inline-size\", physical: \"height\" },\n { logical: \"block-size\", physical: \"width\" },\n ],\n },\n};\nconst toPhysicalMaps = createRegExpMap(values, true);\n\nexport function toPhysical(\n value: string,\n writingMode: string,\n direction?: string | null,\n): string {\n return convert(value, writingMode, direction || null, toPhysicalMaps);\n}\nconst toLogicalMaps = createRegExpMap(values, false);\n\nexport function toLogical(\n value: string,\n writingMode: string,\n direction?: string | null,\n): string {\n return convert(value, writingMode, direction || null, toLogicalMaps);\n}\nconst lineRelativeValues: {\n [key: string]: { logical: string; physical: string }[];\n} = {\n \"horizontal-tb\": [\n { logical: \"line-left\", physical: \"left\" },\n { logical: \"line-right\", physical: \"right\" },\n { logical: \"over\", physical: \"top\" },\n { logical: \"under\", physical: \"bottom\" },\n ],\n \"vertical-rl\": [\n { logical: \"line-left\", physical: \"top\" },\n { logical: \"line-right\", physical: \"bottom\" },\n { logical: \"over\", physical: \"right\" },\n { logical: \"under\", physical: \"left\" },\n ],\n \"vertical-lr\": [\n { logical: \"line-left\", physical: \"top\" },\n { logical: \"line-right\", physical: \"bottom\" },\n { logical: \"over\", physical: \"right\" },\n { logical: \"under\", physical: \"left\" },\n ],\n};\n\nexport function toLineRelative(value: string, writingMode: string): string {\n const maps = lineRelativeValues[writingMode];\n if (!maps) {\n throw new Error(`unknown writing-mode: ${writingMode}`);\n }\n for (let i = 0; i < maps.length; i++) {\n if (maps[i].physical === value) {\n return maps[i].logical;\n }\n }\n return value;\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Sizing - CSS Intrinsic & Extrinsic Sizing\n */\nimport * as Base from \"./base\";\nimport * as Vtree from \"./vtree\";\n\n/**\n * Box sizes defined in css-sizing.\n * @enum {string}\n */\nexport enum Size {\n FILL_AVAILABLE_INLINE_SIZE = \"fill-available inline size\",\n FILL_AVAILABLE_BLOCK_SIZE = \"fill-available block size\",\n FILL_AVAILABLE_WIDTH = \"fill-available width\",\n FILL_AVAILABLE_HEIGHT = \"fill-available height\",\n MAX_CONTENT_INLINE_SIZE = \"max-content inline size\",\n MAX_CONTENT_BLOCK_SIZE = \"max-content block size\",\n MAX_CONTENT_WIDTH = \"max-content width\",\n MAX_CONTENT_HEIGHT = \"max-content height\",\n MIN_CONTENT_INLINE_SIZE = \"min-content inline size\",\n MIN_CONTENT_BLOCK_SIZE = \"min-content block size\",\n MIN_CONTENT_WIDTH = \"min-content width\",\n MIN_CONTENT_HEIGHT = \"min-content height\",\n FIT_CONTENT_INLINE_SIZE = \"fit-content inline size\",\n FIT_CONTENT_BLOCK_SIZE = \"fit-content block size\",\n FIT_CONTENT_WIDTH = \"fit-content width\",\n FIT_CONTENT_HEIGHT = \"fit-content height\",\n}\n\n/**\n * Get specified sizes for the element.\n */\nexport function getSize(\n clientLayout: Vtree.ClientLayout,\n element: Element,\n sizes: Size[],\n): { [key in Size]: number } {\n const original = {\n display: (element as any).style.display,\n position: (element as any).style.position,\n width: (element as any).style.width as string,\n maxWidth: (element as any).style.maxWidth as string,\n minWidth: (element as any).style.minWidth as string,\n height: (element as any).style.height as string,\n maxHeight: (element as any).style.maxHeight as string,\n minHeight: (element as any).style.minHeight as string,\n };\n const doc = element.ownerDocument;\n const parent = element.parentNode;\n\n // wrap the element with a dummy container element\n const container = doc.createElement(\"div\");\n Base.setCSSProperty(container, \"position\", original.position);\n parent.insertBefore(container, element);\n container.appendChild(element);\n Base.setCSSProperty(element, \"width\", \"auto\");\n Base.setCSSProperty(element, \"max-width\", \"none\");\n Base.setCSSProperty(element, \"min-width\", \"0\");\n Base.setCSSProperty(element, \"height\", \"auto\");\n Base.setCSSProperty(element, \"max-height\", \"none\");\n Base.setCSSProperty(element, \"min-height\", \"0\");\n\n function getComputedValue(name: string): string {\n return clientLayout.getElementComputedStyle(element).getPropertyValue(name);\n }\n const writingModeProperty = Base.getPrefixedPropertyNames(\"writing-mode\");\n const writingModeValue =\n (writingModeProperty ? getComputedValue(writingModeProperty[0]) : null) ||\n getComputedValue(\"writing-mode\");\n const isVertical =\n writingModeValue === \"vertical-rl\" ||\n writingModeValue === \"tb-rl\" ||\n writingModeValue === \"vertical-lr\" ||\n writingModeValue === \"tb-lr\";\n const inlineSizeName = isVertical ? \"height\" : \"width\";\n const blockSizeName = isVertical ? \"width\" : \"height\";\n\n function getFillAvailableInline(): string {\n Base.setCSSProperty(element, \"display\", \"block\");\n Base.setCSSProperty(element, \"position\", \"static\");\n return getComputedValue(inlineSizeName);\n }\n\n // Inline size of an inline-block element is the fit-content\n // (shrink-to-fit) inline size.\n function getMaxContentInline(): string {\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n\n // When the available inline size is sufficiently large, the fit-content\n // inline size equals to the max-content inline size.\n Base.setCSSProperty(container, inlineSizeName, \"99999999px\"); // 'sufficiently large' value\n const r = getComputedValue(inlineSizeName);\n Base.setCSSProperty(container, inlineSizeName, \"\");\n return r;\n }\n\n function getMinContentInline(): string {\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n\n // When the available inline size is zero, the fit-content inline size\n // equals to the min-content inline size.\n Base.setCSSProperty(container, inlineSizeName, \"0\");\n const r = getComputedValue(inlineSizeName);\n Base.setCSSProperty(container, inlineSizeName, \"\");\n return r;\n }\n\n function getFitContentInline(): string {\n const fillAvailableInline = getFillAvailableInline();\n const minContentInline = getMinContentInline();\n const parsedFillAvailable = parseFloat(fillAvailableInline);\n if (parsedFillAvailable <= parseFloat(minContentInline)) {\n return minContentInline;\n } else {\n const maxContentInline = getMaxContentInline();\n if (parsedFillAvailable <= parseFloat(maxContentInline)) {\n return fillAvailableInline;\n } else {\n return maxContentInline;\n }\n }\n }\n\n function getIdealBlock(): string {\n return getComputedValue(blockSizeName);\n }\n\n function getFillAvailableBlock(): string {\n throw new Error(\"Getting fill-available block size is not implemented\");\n }\n const result = {} as { [key in Size]: number };\n sizes.forEach((size) => {\n let r: string;\n switch (size) {\n case Size.FILL_AVAILABLE_INLINE_SIZE:\n r = getFillAvailableInline();\n break;\n case Size.MAX_CONTENT_INLINE_SIZE:\n r = getMaxContentInline();\n break;\n case Size.MIN_CONTENT_INLINE_SIZE:\n r = getMinContentInline();\n break;\n case Size.FIT_CONTENT_INLINE_SIZE:\n r = getFitContentInline();\n break;\n case Size.FILL_AVAILABLE_BLOCK_SIZE:\n r = getFillAvailableBlock();\n break;\n case Size.MAX_CONTENT_BLOCK_SIZE:\n case Size.MIN_CONTENT_BLOCK_SIZE:\n case Size.FIT_CONTENT_BLOCK_SIZE:\n r = getIdealBlock();\n break;\n case Size.FILL_AVAILABLE_WIDTH:\n r = isVertical ? getFillAvailableBlock() : getFillAvailableInline();\n break;\n case Size.FILL_AVAILABLE_HEIGHT:\n r = isVertical ? getFillAvailableInline() : getFillAvailableBlock();\n break;\n case Size.MAX_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getMaxContentInline();\n break;\n case Size.MAX_CONTENT_HEIGHT:\n r = isVertical ? getMaxContentInline() : getIdealBlock();\n break;\n case Size.MIN_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getMinContentInline();\n break;\n case Size.MIN_CONTENT_HEIGHT:\n r = isVertical ? getMinContentInline() : getIdealBlock();\n break;\n case Size.FIT_CONTENT_WIDTH:\n r = isVertical ? getIdealBlock() : getFitContentInline();\n break;\n case Size.FIT_CONTENT_HEIGHT:\n r = isVertical ? getFitContentInline() : getIdealBlock();\n break;\n }\n result[size] = parseFloat(r);\n Base.setCSSProperty(element, \"position\", original.position);\n Base.setCSSProperty(element, \"display\", original.display);\n });\n Base.setCSSProperty(element, \"width\", original.width);\n Base.setCSSProperty(element, \"max-width\", original.maxWidth);\n Base.setCSSProperty(element, \"min-width\", original.minWidth);\n Base.setCSSProperty(element, \"height\", original.height);\n Base.setCSSProperty(element, \"max-height\", original.maxHeight);\n Base.setCSSProperty(element, \"min-height\", original.minHeight);\n parent.insertBefore(element, container);\n parent.removeChild(container);\n return result;\n}\n","/**\n * This library modifies the diff-patch-match library by Neil Fraser\n * by removing the patch and match functionality and certain advanced\n * options in the diff function. The original license is as follows:\n *\n * ===\n *\n * Diff Match and Patch\n *\n * Copyright 2006 Google Inc.\n * http://code.google.com/p/google-diff-match-patch/\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, 'Hello'], [DIFF_INSERT, 'Goodbye'], [DIFF_EQUAL, ' world.']]\n * which means: delete 'Hello', add 'Goodbye' and keep ' world.'\n */\nvar DIFF_DELETE = -1;\nvar DIFF_INSERT = 1;\nvar DIFF_EQUAL = 0;\n\n\n/**\n * Find the differences between two texts. Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {Int|Object} [cursor_pos] Edit position in text1 or object with more info\n * @return {Array} Array of diff tuples.\n */\nfunction diff_main(text1, text2, cursor_pos, _fix_unicode) {\n // Check for equality\n if (text1 === text2) {\n if (text1) {\n return [[DIFF_EQUAL, text1]];\n }\n return [];\n }\n\n if (cursor_pos != null) {\n var editdiff = find_cursor_edit_diff(text1, text2, cursor_pos);\n if (editdiff) {\n return editdiff;\n }\n }\n\n // Trim off common prefix (speedup).\n var commonlength = diff_commonPrefix(text1, text2);\n var commonprefix = text1.substring(0, commonlength);\n text1 = text1.substring(commonlength);\n text2 = text2.substring(commonlength);\n\n // Trim off common suffix (speedup).\n commonlength = diff_commonSuffix(text1, text2);\n var commonsuffix = text1.substring(text1.length - commonlength);\n text1 = text1.substring(0, text1.length - commonlength);\n text2 = text2.substring(0, text2.length - commonlength);\n\n // Compute the diff on the middle block.\n var diffs = diff_compute_(text1, text2);\n\n // Restore the prefix and suffix.\n if (commonprefix) {\n diffs.unshift([DIFF_EQUAL, commonprefix]);\n }\n if (commonsuffix) {\n diffs.push([DIFF_EQUAL, commonsuffix]);\n }\n diff_cleanupMerge(diffs, _fix_unicode);\n return diffs;\n};\n\n\n/**\n * Find the differences between two texts. Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @return {Array} Array of diff tuples.\n */\nfunction diff_compute_(text1, text2) {\n var diffs;\n\n if (!text1) {\n // Just add some text (speedup).\n return [[DIFF_INSERT, text2]];\n }\n\n if (!text2) {\n // Just delete some text (speedup).\n return [[DIFF_DELETE, text1]];\n }\n\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n var i = longtext.indexOf(shorttext);\n if (i !== -1) {\n // Shorter text is inside the longer text (speedup).\n diffs = [\n [DIFF_INSERT, longtext.substring(0, i)],\n [DIFF_EQUAL, shorttext],\n [DIFF_INSERT, longtext.substring(i + shorttext.length)]\n ];\n // Swap insertions for deletions if diff is reversed.\n if (text1.length > text2.length) {\n diffs[0][0] = diffs[2][0] = DIFF_DELETE;\n }\n return diffs;\n }\n\n if (shorttext.length === 1) {\n // Single character string.\n // After the previous speedup, the character can't be an equality.\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n }\n\n // Check to see if the problem can be split in two.\n var hm = diff_halfMatch_(text1, text2);\n if (hm) {\n // A half-match was found, sort out the return data.\n var text1_a = hm[0];\n var text1_b = hm[1];\n var text2_a = hm[2];\n var text2_b = hm[3];\n var mid_common = hm[4];\n // Send both pairs off for separate processing.\n var diffs_a = diff_main(text1_a, text2_a);\n var diffs_b = diff_main(text1_b, text2_b);\n // Merge the results.\n return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);\n }\n\n return diff_bisect_(text1, text2);\n};\n\n\n/**\n * Find the 'middle snake' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @return {Array} Array of diff tuples.\n * @private\n */\nfunction diff_bisect_(text1, text2) {\n // Cache the text lengths to prevent multiple calls.\n var text1_length = text1.length;\n var text2_length = text2.length;\n var max_d = Math.ceil((text1_length + text2_length) / 2);\n var v_offset = max_d;\n var v_length = 2 * max_d;\n var v1 = new Array(v_length);\n var v2 = new Array(v_length);\n // Setting all elements to -1 is faster in Chrome & Firefox than mixing\n // integers and undefined.\n for (var x = 0; x < v_length; x++) {\n v1[x] = -1;\n v2[x] = -1;\n }\n v1[v_offset + 1] = 0;\n v2[v_offset + 1] = 0;\n var delta = text1_length - text2_length;\n // If the total number of characters is odd, then the front path will collide\n // with the reverse path.\n var front = (delta % 2 !== 0);\n // Offsets for start and end of k loop.\n // Prevents mapping of space beyond the grid.\n var k1start = 0;\n var k1end = 0;\n var k2start = 0;\n var k2end = 0;\n for (var d = 0; d < max_d; d++) {\n // Walk the front path one step.\n for (var k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {\n var k1_offset = v_offset + k1;\n var x1;\n if (k1 === -d || (k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1])) {\n x1 = v1[k1_offset + 1];\n } else {\n x1 = v1[k1_offset - 1] + 1;\n }\n var y1 = x1 - k1;\n while (\n x1 < text1_length && y1 < text2_length &&\n text1.charAt(x1) === text2.charAt(y1)\n ) {\n x1++;\n y1++;\n }\n v1[k1_offset] = x1;\n if (x1 > text1_length) {\n // Ran off the right of the graph.\n k1end += 2;\n } else if (y1 > text2_length) {\n // Ran off the bottom of the graph.\n k1start += 2;\n } else if (front) {\n var k2_offset = v_offset + delta - k1;\n if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) {\n // Mirror x2 onto top-left coordinate system.\n var x2 = text1_length - v2[k2_offset];\n if (x1 >= x2) {\n // Overlap detected.\n return diff_bisectSplit_(text1, text2, x1, y1);\n }\n }\n }\n }\n\n // Walk the reverse path one step.\n for (var k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {\n var k2_offset = v_offset + k2;\n var x2;\n if (k2 === -d || (k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1])) {\n x2 = v2[k2_offset + 1];\n } else {\n x2 = v2[k2_offset - 1] + 1;\n }\n var y2 = x2 - k2;\n while (\n x2 < text1_length && y2 < text2_length &&\n text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1)\n ) {\n x2++;\n y2++;\n }\n v2[k2_offset] = x2;\n if (x2 > text1_length) {\n // Ran off the left of the graph.\n k2end += 2;\n } else if (y2 > text2_length) {\n // Ran off the top of the graph.\n k2start += 2;\n } else if (!front) {\n var k1_offset = v_offset + delta - k2;\n if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) {\n var x1 = v1[k1_offset];\n var y1 = v_offset + x1 - k1_offset;\n // Mirror x2 onto top-left coordinate system.\n x2 = text1_length - x2;\n if (x1 >= x2) {\n // Overlap detected.\n return diff_bisectSplit_(text1, text2, x1, y1);\n }\n }\n }\n }\n }\n // Diff took too long and hit the deadline or\n // number of diffs equals number of characters, no commonality at all.\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n};\n\n\n/**\n * Given the location of the 'middle snake', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @return {Array} Array of diff tuples.\n */\nfunction diff_bisectSplit_(text1, text2, x, y) {\n var text1a = text1.substring(0, x);\n var text2a = text2.substring(0, y);\n var text1b = text1.substring(x);\n var text2b = text2.substring(y);\n\n // Compute both diffs serially.\n var diffs = diff_main(text1a, text2a);\n var diffsb = diff_main(text1b, text2b);\n\n return diffs.concat(diffsb);\n};\n\n\n/**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n * string.\n */\nfunction diff_commonPrefix(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerstart = 0;\n while (pointermin < pointermid) {\n if (\n text1.substring(pointerstart, pointermid) ==\n text2.substring(pointerstart, pointermid)\n ) {\n pointermin = pointermid;\n pointerstart = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n if (is_surrogate_pair_start(text1.charCodeAt(pointermid - 1))) {\n pointermid--;\n }\n\n return pointermid;\n};\n\n\n/**\n * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\nfunction diff_commonSuffix(text1, text2) {\n // Quick check for common null cases.\n if (!text1 || !text2 || text1.slice(-1) !== text2.slice(-1)) {\n return 0;\n }\n // Binary search.\n // Performance analysis: http://neil.fraser.name/news/2007/10/09/\n var pointermin = 0;\n var pointermax = Math.min(text1.length, text2.length);\n var pointermid = pointermax;\n var pointerend = 0;\n while (pointermin < pointermid) {\n if (\n text1.substring(text1.length - pointermid, text1.length - pointerend) ==\n text2.substring(text2.length - pointermid, text2.length - pointerend)\n ) {\n pointermin = pointermid;\n pointerend = pointermin;\n } else {\n pointermax = pointermid;\n }\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n if (is_surrogate_pair_end(text1.charCodeAt(text1.length - pointermid))) {\n pointermid--;\n }\n\n return pointermid;\n};\n\n\n/**\n * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * text1, the suffix of text1, the prefix of text2, the suffix of\n * text2 and the common middle. Or null if there was no match.\n */\nfunction diff_halfMatch_(text1, text2) {\n var longtext = text1.length > text2.length ? text1 : text2;\n var shorttext = text1.length > text2.length ? text2 : text1;\n if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {\n return null; // Pointless.\n }\n\n /**\n * Does a substring of shorttext exist within longtext such that the substring\n * is at least half the length of longtext?\n * Closure, but does not reference any external variables.\n * @param {string} longtext Longer string.\n * @param {string} shorttext Shorter string.\n * @param {number} i Start index of quarter length substring within longtext.\n * @return {Array.<string>} Five element Array, containing the prefix of\n * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n * of shorttext and the common middle. Or null if there was no match.\n * @private\n */\n function diff_halfMatchI_(longtext, shorttext, i) {\n // Start with a 1/4 length substring at position i as a seed.\n var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));\n var j = -1;\n var best_common = '';\n var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;\n while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {\n var prefixLength = diff_commonPrefix(\n longtext.substring(i), shorttext.substring(j));\n var suffixLength = diff_commonSuffix(\n longtext.substring(0, i), shorttext.substring(0, j));\n if (best_common.length < suffixLength + prefixLength) {\n best_common = shorttext.substring(\n j - suffixLength, j) + shorttext.substring(j, j + prefixLength);\n best_longtext_a = longtext.substring(0, i - suffixLength);\n best_longtext_b = longtext.substring(i + prefixLength);\n best_shorttext_a = shorttext.substring(0, j - suffixLength);\n best_shorttext_b = shorttext.substring(j + prefixLength);\n }\n }\n if (best_common.length * 2 >= longtext.length) {\n return [\n best_longtext_a, best_longtext_b,\n best_shorttext_a, best_shorttext_b, best_common\n ];\n } else {\n return null;\n }\n }\n\n // First check if the second quarter is the seed for a half-match.\n var hm1 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 4));\n // Check again based on the third quarter.\n var hm2 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 2));\n var hm;\n if (!hm1 && !hm2) {\n return null;\n } else if (!hm2) {\n hm = hm1;\n } else if (!hm1) {\n hm = hm2;\n } else {\n // Both matched. Select the longest.\n hm = hm1[4].length > hm2[4].length ? hm1 : hm2;\n }\n\n // A half-match was found, sort out the return data.\n var text1_a, text1_b, text2_a, text2_b;\n if (text1.length > text2.length) {\n text1_a = hm[0];\n text1_b = hm[1];\n text2_a = hm[2];\n text2_b = hm[3];\n } else {\n text2_a = hm[0];\n text2_b = hm[1];\n text1_a = hm[2];\n text1_b = hm[3];\n }\n var mid_common = hm[4];\n return [text1_a, text1_b, text2_a, text2_b, mid_common];\n};\n\n\n/**\n * Reorder and merge like edit sections. Merge equalities.\n * Any edit section can move as long as it doesn't cross an equality.\n * @param {Array} diffs Array of diff tuples.\n * @param {boolean} fix_unicode Whether to normalize to a unicode-correct diff\n */\nfunction diff_cleanupMerge(diffs, fix_unicode) {\n diffs.push([DIFF_EQUAL, '']); // Add a dummy entry at the end.\n var pointer = 0;\n var count_delete = 0;\n var count_insert = 0;\n var text_delete = '';\n var text_insert = '';\n var commonlength;\n while (pointer < diffs.length) {\n if (pointer < diffs.length - 1 && !diffs[pointer][1]) {\n diffs.splice(pointer, 1);\n continue;\n }\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n\n count_insert++;\n text_insert += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_DELETE:\n count_delete++;\n text_delete += diffs[pointer][1];\n pointer++;\n break;\n case DIFF_EQUAL:\n var previous_equality = pointer - count_insert - count_delete - 1;\n if (fix_unicode) {\n // prevent splitting of unicode surrogate pairs. when fix_unicode is true,\n // we assume that the old and new text in the diff are complete and correct\n // unicode-encoded JS strings, but the tuple boundaries may fall between\n // surrogate pairs. we fix this by shaving off stray surrogates from the end\n // of the previous equality and the beginning of this equality. this may create\n // empty equalities or a common prefix or suffix. for example, if AB and AC are\n // emojis, `[[0, 'A'], [-1, 'BA'], [0, 'C']]` would turn into deleting 'ABAC' and\n // inserting 'AC', and then the common suffix 'AC' will be eliminated. in this\n // particular case, both equalities go away, we absorb any previous inequalities,\n // and we keep scanning for the next equality before rewriting the tuples.\n if (previous_equality >= 0 && ends_with_pair_start(diffs[previous_equality][1])) {\n var stray = diffs[previous_equality][1].slice(-1);\n diffs[previous_equality][1] = diffs[previous_equality][1].slice(0, -1);\n text_delete = stray + text_delete;\n text_insert = stray + text_insert;\n if (!diffs[previous_equality][1]) {\n // emptied out previous equality, so delete it and include previous delete/insert\n diffs.splice(previous_equality, 1);\n pointer--;\n var k = previous_equality - 1;\n if (diffs[k] && diffs[k][0] === DIFF_INSERT) {\n count_insert++;\n text_insert = diffs[k][1] + text_insert;\n k--;\n }\n if (diffs[k] && diffs[k][0] === DIFF_DELETE) {\n count_delete++;\n text_delete = diffs[k][1] + text_delete;\n k--;\n }\n previous_equality = k;\n }\n }\n if (starts_with_pair_end(diffs[pointer][1])) {\n var stray = diffs[pointer][1].charAt(0);\n diffs[pointer][1] = diffs[pointer][1].slice(1);\n text_delete += stray;\n text_insert += stray;\n }\n }\n if (pointer < diffs.length - 1 && !diffs[pointer][1]) {\n // for empty equality not at end, wait for next equality\n diffs.splice(pointer, 1);\n break;\n }\n if (text_delete.length > 0 || text_insert.length > 0) {\n // note that diff_commonPrefix and diff_commonSuffix are unicode-aware\n if (text_delete.length > 0 && text_insert.length > 0) {\n // Factor out any common prefixes.\n commonlength = diff_commonPrefix(text_insert, text_delete);\n if (commonlength !== 0) {\n if (previous_equality >= 0) {\n diffs[previous_equality][1] += text_insert.substring(0, commonlength);\n } else {\n diffs.splice(0, 0, [DIFF_EQUAL, text_insert.substring(0, commonlength)]);\n pointer++;\n }\n text_insert = text_insert.substring(commonlength);\n text_delete = text_delete.substring(commonlength);\n }\n // Factor out any common suffixes.\n commonlength = diff_commonSuffix(text_insert, text_delete);\n if (commonlength !== 0) {\n diffs[pointer][1] =\n text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];\n text_insert = text_insert.substring(0, text_insert.length - commonlength);\n text_delete = text_delete.substring(0, text_delete.length - commonlength);\n }\n }\n // Delete the offending records and add the merged ones.\n var n = count_insert + count_delete;\n if (text_delete.length === 0 && text_insert.length === 0) {\n diffs.splice(pointer - n, n);\n pointer = pointer - n;\n } else if (text_delete.length === 0) {\n diffs.splice(pointer - n, n, [DIFF_INSERT, text_insert]);\n pointer = pointer - n + 1;\n } else if (text_insert.length === 0) {\n diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete]);\n pointer = pointer - n + 1;\n } else {\n diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete], [DIFF_INSERT, text_insert]);\n pointer = pointer - n + 2;\n }\n }\n if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {\n // Merge this equality with the previous one.\n diffs[pointer - 1][1] += diffs[pointer][1];\n diffs.splice(pointer, 1);\n } else {\n pointer++;\n }\n count_insert = 0;\n count_delete = 0;\n text_delete = '';\n text_insert = '';\n break;\n }\n }\n if (diffs[diffs.length - 1][1] === '') {\n diffs.pop(); // Remove the dummy entry at the end.\n }\n\n // Second pass: look for single edits surrounded on both sides by equalities\n // which can be shifted sideways to eliminate an equality.\n // e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC\n var changes = false;\n pointer = 1;\n // Intentionally ignore the first and last element (don't need checking).\n while (pointer < diffs.length - 1) {\n if (diffs[pointer - 1][0] === DIFF_EQUAL &&\n diffs[pointer + 1][0] === DIFF_EQUAL) {\n // This is a single edit surrounded by equalities.\n if (diffs[pointer][1].substring(diffs[pointer][1].length -\n diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {\n // Shift the edit over the previous equality.\n diffs[pointer][1] = diffs[pointer - 1][1] +\n diffs[pointer][1].substring(0, diffs[pointer][1].length -\n diffs[pointer - 1][1].length);\n diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];\n diffs.splice(pointer - 1, 1);\n changes = true;\n } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) ==\n diffs[pointer + 1][1]) {\n // Shift the edit over the next equality.\n diffs[pointer - 1][1] += diffs[pointer + 1][1];\n diffs[pointer][1] =\n diffs[pointer][1].substring(diffs[pointer + 1][1].length) +\n diffs[pointer + 1][1];\n diffs.splice(pointer + 1, 1);\n changes = true;\n }\n }\n pointer++;\n }\n // If shifts were made, the diff needs reordering and another shift sweep.\n if (changes) {\n diff_cleanupMerge(diffs, fix_unicode);\n }\n};\n\nfunction is_surrogate_pair_start(charCode) {\n return charCode >= 0xD800 && charCode <= 0xDBFF;\n}\n\nfunction is_surrogate_pair_end(charCode) {\n return charCode >= 0xDC00 && charCode <= 0xDFFF;\n}\n\nfunction starts_with_pair_end(str) {\n return is_surrogate_pair_end(str.charCodeAt(0));\n}\n\nfunction ends_with_pair_start(str) {\n return is_surrogate_pair_start(str.charCodeAt(str.length - 1));\n}\n\nfunction remove_empty_tuples(tuples) {\n var ret = [];\n for (var i = 0; i < tuples.length; i++) {\n if (tuples[i][1].length > 0) {\n ret.push(tuples[i]);\n }\n }\n return ret;\n}\n\nfunction make_edit_splice(before, oldMiddle, newMiddle, after) {\n if (ends_with_pair_start(before) || starts_with_pair_end(after)) {\n return null;\n }\n return remove_empty_tuples([\n [DIFF_EQUAL, before],\n [DIFF_DELETE, oldMiddle],\n [DIFF_INSERT, newMiddle],\n [DIFF_EQUAL, after]\n ]);\n}\n\nfunction find_cursor_edit_diff(oldText, newText, cursor_pos) {\n // note: this runs after equality check has ruled out exact equality\n var oldRange = typeof cursor_pos === 'number' ?\n { index: cursor_pos, length: 0 } : cursor_pos.oldRange;\n var newRange = typeof cursor_pos === 'number' ?\n null : cursor_pos.newRange;\n // take into account the old and new selection to generate the best diff\n // possible for a text edit. for example, a text change from \"xxx\" to \"xx\"\n // could be a delete or forwards-delete of any one of the x's, or the\n // result of selecting two of the x's and typing \"x\".\n var oldLength = oldText.length;\n var newLength = newText.length;\n if (oldRange.length === 0 && (newRange === null || newRange.length === 0)) {\n // see if we have an insert or delete before or after cursor\n var oldCursor = oldRange.index;\n var oldBefore = oldText.slice(0, oldCursor);\n var oldAfter = oldText.slice(oldCursor);\n var maybeNewCursor = newRange ? newRange.index : null;\n editBefore: {\n // is this an insert or delete right before oldCursor?\n var newCursor = oldCursor + newLength - oldLength;\n if (maybeNewCursor !== null && maybeNewCursor !== newCursor) {\n break editBefore;\n }\n if (newCursor < 0 || newCursor > newLength) {\n break editBefore;\n }\n var newBefore = newText.slice(0, newCursor);\n var newAfter = newText.slice(newCursor);\n if (newAfter !== oldAfter) {\n break editBefore;\n }\n var prefixLength = Math.min(oldCursor, newCursor);\n var oldPrefix = oldBefore.slice(0, prefixLength);\n var newPrefix = newBefore.slice(0, prefixLength);\n if (oldPrefix !== newPrefix) {\n break editBefore;\n }\n var oldMiddle = oldBefore.slice(prefixLength);\n var newMiddle = newBefore.slice(prefixLength);\n return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldAfter);\n }\n editAfter: {\n // is this an insert or delete right after oldCursor?\n if (maybeNewCursor !== null && maybeNewCursor !== oldCursor) {\n break editAfter;\n }\n var cursor = oldCursor;\n var newBefore = newText.slice(0, cursor);\n var newAfter = newText.slice(cursor);\n if (newBefore !== oldBefore) {\n break editAfter;\n }\n var suffixLength = Math.min(oldLength - cursor, newLength - cursor);\n var oldSuffix = oldAfter.slice(oldAfter.length - suffixLength);\n var newSuffix = newAfter.slice(newAfter.length - suffixLength);\n if (oldSuffix !== newSuffix) {\n break editAfter;\n }\n var oldMiddle = oldAfter.slice(0, oldAfter.length - suffixLength);\n var newMiddle = newAfter.slice(0, newAfter.length - suffixLength);\n return make_edit_splice(oldBefore, oldMiddle, newMiddle, oldSuffix);\n }\n }\n if (oldRange.length > 0 && newRange && newRange.length === 0) {\n replaceRange: {\n // see if diff could be a splice of the old selection range\n var oldPrefix = oldText.slice(0, oldRange.index);\n var oldSuffix = oldText.slice(oldRange.index + oldRange.length);\n var prefixLength = oldPrefix.length;\n var suffixLength = oldSuffix.length;\n if (newLength < prefixLength + suffixLength) {\n break replaceRange;\n }\n var newPrefix = newText.slice(0, prefixLength);\n var newSuffix = newText.slice(newLength - suffixLength);\n if (oldPrefix !== newPrefix || oldSuffix !== newSuffix) {\n break replaceRange;\n }\n var oldMiddle = oldText.slice(prefixLength, oldLength - suffixLength);\n var newMiddle = newText.slice(prefixLength, newLength - suffixLength);\n return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldSuffix);\n }\n }\n\n return null;\n}\n\nfunction diff(text1, text2, cursor_pos) {\n // only pass fix_unicode=true at the top level, not when diff_main is\n // recursively invoked\n return diff_main(text1, text2, cursor_pos, true);\n}\n\ndiff.INSERT = DIFF_INSERT;\ndiff.DELETE = DIFF_DELETE;\ndiff.EQUAL = DIFF_EQUAL;\n\nmodule.exports = diff;\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Types - Type definiions.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as Diff from \"./diff\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\n\nexport type FormattingContextType =\n | \"Block\"\n | \"RepetitiveElementsOwner\"\n | \"Table\";\n\nexport type FragmentLayoutConstraintType =\n | \"AfterIfContinue\"\n | \"EntireTable\"\n | \"RepetitiveElementsOwner\"\n | \"TableRow\";\n\nexport namespace CssCascade {\n export interface ElementStyle {}\n}\n\nexport namespace CssStyler {\n export interface AbstractStyler {\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle;\n processContent(element: Element, styles: { [key: string]: Css.Val });\n }\n}\n\nexport namespace Layout {\n /**\n * Represents a constraint on layout\n */\n export interface LayoutConstraint {\n /**\n * Returns if this constraint allows the node context to be laid out at the\n * current position.\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean;\n }\n /**\n * Represents constraints on laying out fragments\n */\n export interface FragmentLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType;\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Column,\n ): boolean;\n nextCandidate(nodeContext: Vtree.NodeContext): boolean;\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Column,\n );\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Column,\n ): Task.Result<boolean>;\n equalsTo(constraint: FragmentLayoutConstraint): boolean;\n getPriorityOfFinishBreak(): number;\n }\n\n /**\n * Potential breaking position.\n */\n export interface BreakPosition {\n /**\n * @return break position, if found\n */\n findAcceptableBreak(column: Column, penalty: number): Vtree.NodeContext;\n /**\n * @return penalty for this break position\n */\n getMinBreakPenalty(): number;\n calculateOffset(column: Column): { current: number; minimum: number };\n breakPositionChosen(column: Column): void;\n }\n\n export interface AbstractBreakPosition extends BreakPosition {\n getNodeContext(): Vtree.NodeContext;\n }\n\n export type BreakPositionAndNodeContext = {\n breakPosition: BreakPosition;\n nodeContext: Vtree.NodeContext;\n };\n\n /**\n * Potential breaking position inside CSS box (between lines).\n * @param checkPoints array of breaking points for\n * breakable block\n */\n export interface BoxBreakPosition extends AbstractBreakPosition {\n breakNodeContext: Vtree.NodeContext;\n readonly checkPoints: Vtree.NodeContext[];\n readonly penalty: number;\n }\n\n /**\n * Potential edge breaking position.\n */\n export interface EdgeBreakPosition extends AbstractBreakPosition {\n overflowIfRepetitiveElementsDropped: boolean;\n readonly position: Vtree.NodeContext;\n readonly breakOnEdge: string | null;\n overflows: boolean;\n readonly computedBlockSize: number;\n }\n\n export interface Column extends Vtree.Container {\n last: Node;\n viewDocument: Document;\n flowRootFormattingContext: Vtree.FormattingContext;\n isFloat: boolean;\n isFootnote: boolean;\n startEdge: number;\n endEdge: number;\n beforeEdge: number;\n afterEdge: number;\n footnoteEdge: number;\n box: GeometryUtil.Rect;\n chunkPositions: Vtree.ChunkPosition[];\n bands: GeometryUtil.Band[];\n overflown: boolean;\n breakPositions: BreakPosition[];\n pageBreakType: string | null;\n forceNonfitting: boolean;\n leftFloatEdge: number;\n /**\n * bottom of the bottommost left float\n */\n rightFloatEdge: number;\n /**\n * bottom of the bottommost right float\n */\n bottommostFloatTop: number;\n /**\n * Top of the bottommost float\n */\n stopAtOverflow: boolean;\n lastAfterPosition: Vtree.NodePosition | null;\n fragmentLayoutConstraints: FragmentLayoutConstraint[];\n pseudoParent: Column;\n nodeContextOverflowingDueToRepetitiveElements: Vtree.NodeContext | null;\n blockDistanceToBlockEndFloats: number;\n computedBlockSize: number;\n\n layoutContext: Vtree.LayoutContext;\n clientLayout: Vtree.ClientLayout;\n readonly layoutConstraint: LayoutConstraint;\n readonly pageFloatLayoutContext: PageFloats.PageFloatLayoutContext;\n\n getTopEdge(): number;\n getBottomEdge(): number;\n getLeftEdge(): number;\n getRightEdge(): number;\n isFloatNodeContext(nodeContext: Vtree.NodeContext): boolean;\n stopByOverflow(nodeContext: Vtree.NodeContext): boolean;\n isOverflown(edge: number): boolean;\n getExclusions(): GeometryUtil.Shape[];\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext>;\n calculateOffsetInNodeForNodeContext(position: Vtree.NodePosition): number;\n /**\n * @param count first-XXX nesting identifier\n */\n maybePeelOff(\n position: Vtree.NodeContext,\n count: number,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Builds the view until a CSS box edge is reached.\n * @param position start source position.\n * @param checkPoints array to append possible breaking points.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildViewToNextBlockEdge(\n position: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext>;\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Builds the view for a single unbreakable element.\n * @param position start source position.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildDeepElementView(\n position: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * Create a single floating element (for exclusion areas).\n * @param ref container's child to insert float before (can be null).\n * @param side float side (\"left\" or \"right\").\n * @param width float inline dimension.\n * @param height float box progression dimension.\n * @return newly created float element.\n */\n createFloat(\n ref: Node,\n side: string,\n width: number,\n height: number,\n ): Element;\n /**\n * Remove all the exclusion floats.\n */\n killFloats(): void;\n /**\n * Create exclusion floats for a column.\n */\n createFloats(): void;\n /**\n * @param nodeContext position after the block\n * @param checkPoints array of possible breaking points.\n * @param index index of the breaking point\n * @param boxOffset box offset\n * @return edge position\n */\n calculateEdge(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n index: number,\n boxOffset: number,\n ): number;\n /**\n * Parse CSS computed length (in pixels)\n * @param val CSS length in \"px\" units or a number.\n * @return value in pixels or 0 if not parsable\n */\n parseComputedLength(val: string | number): number;\n /**\n * Reads element's computed CSS margin.\n */\n getComputedMargin(element: Element): GeometryUtil.Insets;\n /**\n * Reads element's computed padding + borders.\n */\n getComputedPaddingBorder(element: Element): GeometryUtil.Insets;\n /**\n * Reads element's computed CSS insets(margins + border + padding or margins :\n * depends on box-sizing)\n */\n getComputedInsets(element: Element): GeometryUtil.Insets;\n /**\n * Set element's computed CSS insets to Column Container\n */\n setComputedInsets(element: Element, container: Column): void;\n /**\n * Set element's computed width and height to Column Container\n */\n setComputedWidthAndHeight(element: Element, container: Column): void;\n /**\n * Layout a single unbreakable element.\n */\n layoutUnbreakable(\n nodeContextIn: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Layout a single float element.\n */\n layoutFloat(nodeContext: Vtree.NodeContext): Task.Result<Vtree.NodeContext>;\n\n setupFloatArea(\n area: PageFloatArea,\n floatReference: PageFloats.FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): boolean;\n createPageFloatArea(\n float: PageFloats.PageFloat | null,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): PageFloatArea | null;\n layoutSinglePageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n clearSide: string | null,\n allowFragmented: boolean,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment | null,\n ): Task.Result<SinglePageFloatLayoutResult>;\n layoutPageFloatInner(\n continuation: PageFloats.PageFloatContinuation,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment,\n ): Task.Result<boolean>;\n setFloatAnchorViewNode(nodeContext: Vtree.NodeContext): Vtree.NodeContext;\n resolveFloatReferenceFromColumnSpan(\n floatReference: PageFloats.FloatReference,\n columnSpan: Css.Val,\n nodeContext: Vtree.NodeContext,\n ): Task.Result<PageFloats.FloatReference>;\n layoutPageFloat(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n createJustificationAdjustmentElement(\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n vertical: boolean,\n ): HTMLElement;\n addAndAdjustJustificationElement(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n ): HTMLElement;\n compensateJustificationLineHeight(\n span: Element,\n br: Element,\n nodeContext: Vtree.NodeContext,\n ): void;\n /**\n * Fix justification of the last line of text broken across pages (if\n * needed).\n */\n fixJustificationIfNeeded(\n nodeContext: Vtree.NodeContext,\n endOfColumn: boolean,\n ): void;\n processLineStyling(\n nodeContext: Vtree.NodeContext,\n resNodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext>;\n isLoneImage(checkPoints: Vtree.NodeContext[]): boolean;\n getTrailingMarginEdgeAdjustment(\n trailingEdgeContexts: Vtree.NodeContext[],\n ): number;\n /**\n * Layout a single CSS box.\n */\n layoutBreakableBlock(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n postLayoutBlock(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): void;\n findEndOfLine(\n linePosition: number,\n checkPoints: Vtree.NodeContext[],\n isUpdateMaxReachedAfterEdge: boolean,\n ): {\n nodeContext: Vtree.NodeContext;\n index: number;\n checkPointIndex: number;\n };\n findAcceptableBreakInside(\n checkPoints: Vtree.NodeContext[],\n edgePosition: number,\n force: boolean,\n ): Vtree.NodeContext;\n resolveTextNodeBreaker(nodeContext: Vtree.NodeContext): TextNodeBreaker;\n /**\n * Read ranges skipping special elments\n */\n getRangeBoxes(start: Node, end: Node): Vtree.ClientRect[];\n /**\n * Give block's initial and final nodes, find positions of the line bottoms.\n * This is, of course, somewhat hacky implementation.\n * @return position of line breaks\n */\n findLinePositions(checkPoints: Vtree.NodeContext[]): number[];\n calculateClonedPaddingBorder(nodeContext: Vtree.NodeContext): number;\n findBoxBreakPosition(\n bp: BoxBreakPosition,\n force: boolean,\n ): Vtree.NodeContext;\n getAfterEdgeOfBlockContainer(nodeContext: Vtree.NodeContext): number;\n findFirstOverflowingEdgeAndCheckPoint(\n checkPoints: Vtree.NodeContext[],\n ): { edge: number; checkPoint: Vtree.NodeContext | null };\n findEdgeBreakPosition(bp: EdgeBreakPosition): Vtree.NodeContext;\n /**\n * Finalize a line break.\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean>;\n findAcceptableBreakPosition(): BreakPositionAndNodeContext;\n doFinishBreak(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n initialNodeContext: Vtree.NodeContext,\n initialComputedBlockSize: number,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Determines if a page break is acceptable at this position\n */\n isBreakable(flowPosition: Vtree.NodeContext): boolean;\n /**\n * Determines if an indent value is zero\n */\n zeroIndent(val: string | number): boolean;\n /**\n * @return true if overflows\n */\n checkOverflowAndSaveEdge(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n ): boolean;\n /**\n * Save a possible page break position on a CSS block edge. Check if it\n * overflows.\n * @return true if overflows\n */\n checkOverflowAndSaveEdgeAndBreakPosition(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n saveEvenOverflown: boolean,\n breakAtTheEdge: string | null,\n ): boolean;\n applyClearance(nodeContext: Vtree.NodeContext): boolean;\n isBFC(formattingContext: Vtree.FormattingContext): boolean;\n /**\n * Skips positions until either the start of unbreakable block or inline\n * content. Also sets breakBefore on the result combining break-before and\n * break-after properties from all elements that meet at the edge.\n */\n skipEdges(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue: string | null,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Skips non-renderable positions until it hits the end of the flow or some\n * renderable content. Returns the nodeContext that was passed in if some\n * content remains and null if all content could be skipped.\n */\n skipTailEdges(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n layoutFloatOrFootnote(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext>;\n /**\n * Layout next portion of the source.\n */\n layoutNext(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue?: string | null,\n ): Task.Result<Vtree.NodeContext>;\n clearOverflownViewNodes(\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ): void;\n initGeom(): void;\n init(): void;\n /**\n * Save the potential breaking position at the edge. Should, in general, save\n * \"after\" position but only after skipping all of the \"before\" ones and\n * getting to the non-empty content (to get breakAtEdge right).\n */\n saveEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakAtEdge: string | null,\n overflows: boolean,\n ): void;\n /**\n * @param checkPoints array of breaking points for breakable block\n */\n saveBoxBreakPosition(checkPoints: Vtree.NodeContext[]): void;\n updateMaxReachedAfterEdge(afterEdge: number): void;\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<Vtree.ChunkPosition>;\n isFullWithPageFloats(): boolean;\n getMaxBlockSizeOfPageFloats(): number;\n doFinishBreakOfFragmentLayoutConstraints(nodeContext): void;\n /**\n * @param nodeContext starting position.\n * @return holding end position.\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }>;\n /**\n * Re-layout already laid-out chunks. Return the position of the last flow if\n * there is an overflow.\n * TODO: deal with chunks that did not fit at all.\n * @return holding end position.\n */\n redoLayout(): Task.Result<Vtree.ChunkPosition>;\n saveDistanceToBlockEndFloats(): void;\n collectElementsOffset(): RepetitiveElement.ElementsOffset[];\n }\n\n export type SinglePageFloatLayoutResult = {\n floatArea: PageFloatArea | null;\n pageFloatFragment: PageFloats.PageFloatFragment | null;\n newPosition: Vtree.ChunkPosition | null;\n };\n\n /**\n * breaking point resolver for Text Node.\n */\n export interface TextNodeBreaker {\n breakTextNode(\n textNode: Text,\n nodeContext: Vtree.NodeContext,\n low: number,\n checkPoints: Vtree.NodeContext[],\n checkpointIndex: number,\n force: boolean,\n ): Vtree.NodeContext;\n breakAfterSoftHyphen(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number;\n breakAfterOtherCharacter(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number;\n updateNodeContext(\n nodeContext: Vtree.NodeContext,\n viewIndex: number,\n textNode: Text,\n ): Vtree.NodeContext;\n }\n\n export interface LayoutMode {\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext>;\n accept(nodeContext: Vtree.NodeContext, column: Layout.Column): boolean;\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n accepted: boolean,\n ): boolean;\n }\n\n export interface PageFloatArea extends Column {\n adjustContentRelativeSize: boolean;\n readonly floatSide: string;\n readonly parentContainer: Vtree.Container;\n\n convertPercentageSizesToPx(target: Element): void;\n fixFloatSizeAndPosition(nodeContext: Vtree.NodeContext): void;\n getContentInlineSize(): number;\n }\n}\n\nexport namespace LayoutProcessor {\n export interface BlockFormattingContext extends Vtree.FormattingContext {}\n\n export function isInstanceOfBlockFormattingContext(\n object: Vtree.FormattingContext,\n ): object is BlockFormattingContext {\n return object && object.formattingContextType === \"Block\";\n }\n}\n\nexport namespace Net {\n export type Response = {\n status: number;\n statusText: string | null;\n url: string;\n contentType: string | null;\n responseText: string | null;\n responseXML: Document;\n responseBlob: Blob;\n };\n\n export interface ResourceStore<Resource> {\n resources: { [key: string]: Resource };\n fetchers: { [key: string]: TaskUtil.Fetcher<Resource> };\n readonly parser: (\n p1: Response,\n p2: ResourceStore<Resource>,\n ) => Task.Result<Resource>;\n readonly type: XMLHttpRequestResponseType;\n\n /**\n * @return resource for the given URL\n */\n load(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Resource>;\n /**\n * @return fetcher for the resource for the given URL\n */\n fetch(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): TaskUtil.Fetcher<Resource>;\n get(url: string): XmlDoc.XMLDocHolder;\n delete(url: string): void;\n }\n}\n\nexport namespace PageFloats {\n /**\n * @enum {string}\n */\n export enum FloatReference {\n INLINE = \"inline\",\n COLUMN = \"column\",\n REGION = \"region\",\n PAGE = \"page\",\n }\n\n export type PageFloatID = string;\n\n export interface PageFloat {\n order: number | null;\n id: PageFloatID | null;\n readonly nodePosition: Vtree.NodePosition;\n readonly floatReference: FloatReference;\n readonly floatSide: string;\n readonly clearSide: string | null;\n readonly flowName: string;\n readonly floatMinWrapBlock: Css.Numeric | null;\n\n getOrder(): number;\n getId(): PageFloatID;\n isAllowedOnContext(pageFloatLayoutContext: PageFloatLayoutContext): boolean;\n isAllowedToPrecede(other: PageFloat): boolean;\n }\n\n export interface PageFloatFragment {\n readonly floatReference: FloatReference;\n readonly floatSide: string;\n readonly continuations: PageFloatContinuation[];\n readonly area: Vtree.Container;\n readonly continues: boolean;\n\n hasFloat(float: PageFloat): boolean;\n findNotAllowedFloat(context: PageFloatLayoutContext): PageFloat | null;\n getOuterShape(): GeometryUtil.Shape;\n getOuterRect(): GeometryUtil.Rect;\n getOrder(): number;\n shouldBeStashedBefore(float: PageFloat): boolean;\n addContinuations(continuations: PageFloatContinuation[]): void;\n getFlowName(): string;\n }\n\n export interface PageFloatContinuation {\n readonly float: PageFloat;\n readonly nodePosition: Vtree.NodePosition;\n\n equals(other: PageFloatContinuation | null): boolean;\n }\n\n export type PageFloatPlacementCondition = {\n [key: string]: boolean;\n };\n\n export interface PageFloatLayoutContext {\n writingMode: Css.Val;\n direction: Css.Val;\n floatFragments: PageFloatFragment[];\n readonly parent: PageFloatLayoutContext;\n readonly flowName: string | null;\n readonly generatingNodePosition: Vtree.NodePosition | null;\n\n getContainer(floatReference?: FloatReference): Vtree.Container;\n setContainer(container: Vtree.Container);\n addPageFloat(float: PageFloat): void;\n getPageFloatLayoutContext(\n floatReference: FloatReference,\n ): PageFloatLayoutContext;\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null;\n isForbidden(float: PageFloat): boolean;\n addPageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ): void;\n removePageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ): void;\n findPageFloatFragment(float: PageFloat): PageFloatFragment | null;\n hasFloatFragments(condition?: (p1: PageFloatFragment) => boolean): boolean;\n hasContinuingFloatFragmentsInFlow(flowName: string): boolean;\n registerPageFloatAnchor(float: PageFloat, anchorViewNode: Node): void;\n collectPageFloatAnchors(): any;\n isAnchorAlreadyAppeared(floatId: PageFloatID): boolean;\n deferPageFloat(continuation: PageFloatContinuation): void;\n hasPrecedingFloatsDeferredToNext(\n float: PageFloat,\n ignoreReference?: boolean,\n ): boolean;\n getLastFollowingFloatInFragments(float: PageFloat): PageFloat | null;\n getDeferredPageFloatContinuations(\n flowName?: string | null,\n ): PageFloatContinuation[];\n getPageFloatContinuationsDeferredToNext(\n flowName?: string | null,\n ): PageFloatContinuation[];\n getFloatsDeferredToNextInChildContexts(): PageFloat[];\n checkAndForbidNotAllowedFloat(): boolean;\n checkAndForbidFloatFollowingDeferredFloat(): boolean;\n finish(): void;\n hasSameContainerAs(other: PageFloatLayoutContext): boolean;\n invalidate(): void;\n detachChildren(): PageFloatLayoutContext[];\n attachChildren(children: PageFloatLayoutContext[]): void;\n isInvalidated(): boolean;\n validate(): void;\n removeEndFloatFragments(floatSide: string): void;\n stashEndFloatFragments(float: PageFloat): void;\n restoreStashedFragments(floatReference: FloatReference): void;\n discardStashedFragments(floatReference: FloatReference): void;\n getStashedFloatFragments(\n floatReference: FloatReference,\n ): PageFloatFragment[];\n /**\n * @param anchorEdge Null indicates that the anchor is not in the current\n * container.\n * @return Logical float side (snap-block is resolved when init=false). Null\n * indicates that the float area does not fit inside the container\n */\n setFloatAreaDimensions(\n area: Layout.PageFloatArea,\n floatReference: FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n init: boolean,\n force: boolean,\n condition: PageFloatPlacementCondition,\n ): string | null;\n getFloatFragmentExclusions(): GeometryUtil.Shape[];\n getMaxReachedAfterEdge(): number;\n getBlockStartEdgeOfBlockEndFloats(): number;\n getPageFloatClearEdge(clear: string, column: Layout.Column): number;\n getPageFloatPlacementCondition(\n float: PageFloat,\n floatSide: string,\n clearSide: string | null,\n ): PageFloatPlacementCondition;\n getLayoutConstraints(): Layout.LayoutConstraint[];\n addLayoutConstraint(\n layoutConstraint: Layout.LayoutConstraint,\n floatReference: FloatReference,\n ): void;\n getMaxBlockSizeOfPageFloats(): number;\n lock(): void;\n unlock(): void;\n isLocked(): boolean;\n }\n\n export interface PageFloatLayoutStrategy {\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean;\n appliesToFloat(float: PageFloat): boolean;\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloatLayoutContext,\n column: Layout.Column,\n ): Task.Result<PageFloat>;\n createPageFloatFragment(\n continuations: PageFloatContinuation[],\n floatSide: string,\n floatArea: Layout.PageFloatArea,\n continues: boolean,\n ): PageFloatFragment;\n findPageFloatFragment(\n float: PageFloat,\n pageFloatLayoutContext: PageFloatLayoutContext,\n ): PageFloatFragment | null;\n adjustPageFloatArea(\n floatArea: Layout.PageFloatArea,\n floatContainer: Vtree.Container,\n column: Layout.Column,\n );\n forbid(float: PageFloat, pageFloatLayoutContext: PageFloatLayoutContext);\n }\n}\n\nexport namespace Selectors {\n export interface AfterIfContinues {\n readonly sourceNode: Element;\n readonly styler: PseudoElement.PseudoelementStyler;\n\n createElement(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n ): Task.Result<Element>;\n }\n\n export interface AfterIfContinuesLayoutConstraint\n extends Layout.FragmentLayoutConstraint {\n nodeContext: Vtree.NodeContext;\n afterIfContinues: AfterIfContinues;\n pseudoElementHeight: number;\n\n getRepetitiveElements(): AfterIfContinuesElementsOffset;\n }\n\n export function isInstanceOfAfterIfContinuesLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is AfterIfContinuesLayoutConstraint {\n return object && object.flagmentLayoutConstraintType == \"AfterIfContinue\";\n }\n\n export interface AfterIfContinuesElementsOffset\n extends RepetitiveElement.ElementsOffset {\n nodeContext: Vtree.NodeContext;\n pseudoElementHeight: number;\n\n affectTo(nodeContext: Vtree.NodeContext): boolean;\n }\n}\n\nexport namespace PseudoElement {\n export interface PseudoelementStyler extends CssStyler.AbstractStyler {\n contentProcessed: { [key: string]: boolean };\n readonly element: Element;\n style: CssCascade.ElementStyle;\n styler: CssStyler.AbstractStyler;\n readonly context: Exprs.Context;\n readonly exprContentListener: Vtree.ExprContentListener;\n }\n}\n\nexport namespace RepetitiveElement {\n export interface RepetitiveElementsOwnerFormattingContext\n extends Vtree.FormattingContext {\n isRoot: boolean;\n repetitiveElements: RepetitiveElements;\n readonly parent: Vtree.FormattingContext;\n readonly rootSourceNode: Element;\n getRepetitiveElements(): RepetitiveElements;\n getRootViewNode(position: Vtree.NodeContext): Element | null;\n getRootNodeContext(\n nodeContext: Vtree.NodeContext,\n ): Vtree.NodeContext | null;\n initializeRepetitiveElements(vertical: boolean): void;\n }\n\n export function isInstanceOfRepetitiveElementsOwnerFormattingContext(\n object: Vtree.FormattingContext,\n ): object is RepetitiveElementsOwnerFormattingContext {\n if (!object) {\n return false;\n }\n const type = object.formattingContextType;\n return (\n type === \"RepetitiveElementsOwner\" ||\n Table.isInstanceOfTableFormattingContext(object)\n ); // subset\n }\n\n export interface ElementsOffset {\n calculateOffset(nodeContext: Vtree.NodeContext): number;\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number;\n }\n\n export interface RepetitiveElements extends ElementsOffset {\n isSkipHeader: boolean;\n isSkipFooter: boolean;\n enableSkippingFooter: boolean;\n enableSkippingHeader: boolean;\n doneInitialLayout: boolean;\n firstContentSourceNode: Element | null;\n lastContentSourceNode: Element | null;\n allowInsert: boolean;\n allowInsertRepeatitiveElements: boolean;\n ownerSourceNode: Element;\n\n setHeaderNodeContext(nodeContext: Vtree.NodeContext): void;\n setFooterNodeContext(nodeContext: Vtree.NodeContext): void;\n updateHeight(column: Layout.Column): void;\n prepareLayoutFragment(): void;\n appendHeaderToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n appendFooterToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n appendElementToFragment(\n nodePosition: Vtree.NodePosition,\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: Layout.Column,\n ): Task.Result<boolean>;\n moveChildren(from: Element, to: Element, firstChild: Node | null): void;\n isAfterLastContent(nodeContext: Vtree.NodeContext): boolean;\n isFirstContentNode(nodeContext: Vtree.NodeContext): boolean;\n isEnableToUpdateState(): boolean;\n updateState(): void;\n preventSkippingHeader(): void;\n preventSkippingFooter(): void;\n isHeaderRegistered(): boolean;\n isFooterRegistered(): boolean;\n isHeaderSourceNode(node: Node): boolean;\n isFooterSourceNode(node: Node): boolean;\n }\n\n export interface RepetitiveElementsOwnerLayoutConstraint\n extends Layout.FragmentLayoutConstraint {\n getRepetitiveElements(): RepetitiveElements;\n }\n\n export function isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is RepetitiveElementsOwnerLayoutConstraint {\n if (!object) {\n return false;\n }\n const type = object.flagmentLayoutConstraintType;\n return (\n type === \"RepetitiveElementsOwner\" ||\n Table.isInstanceOfTableRowLayoutConstraint(object)\n ); // subset\n }\n}\n\nexport namespace Table {\n export interface TableFormattingContext\n extends RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n // FIXME\n }\n\n export function isInstanceOfTableFormattingContext(\n object: Vtree.FormattingContext,\n ): object is TableFormattingContext {\n return object && object.formattingContextType === \"Table\";\n }\n\n export interface TableRowLayoutConstraint\n extends RepetitiveElement.RepetitiveElementsOwnerLayoutConstraint {\n cellFragmentLayoutConstraints: {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[];\n\n removeDummyRowNodes(nodeContext: Vtree.NodeContext): void;\n getElementsOffsetsForTableCell(\n column: Layout.Column,\n ): RepetitiveElement.ElementsOffset[];\n }\n\n export function isInstanceOfTableRowLayoutConstraint(\n object: Layout.FragmentLayoutConstraint,\n ): object is TableRowLayoutConstraint {\n return object && object.flagmentLayoutConstraintType === \"TableRow\";\n }\n}\n\nexport namespace Vtree {\n export type ClientRect = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n };\n\n /**\n * Interface to read the position assigned to the elements and ranges by the\n * browser.\n */\n export interface ClientLayout {\n getRangeClientRects(range: Range): ClientRect[];\n getElementClientRect(element: Element): ClientRect;\n /**\n * @return element's computed style\n */\n getElementComputedStyle(element: Element): CSSStyleDeclaration;\n }\n\n /**\n * Styling, creating a single node's view, etc.\n */\n export interface LayoutContext {\n /**\n * Creates a functionally equivalent, but uninitialized layout context,\n * suitable for building a separate column.\n */\n clone(): LayoutContext;\n /**\n * Set the current source node and create a view. Parameter firstTime\n * is true (and possibly offsetInNode > 0) if node was broken on\n * the previous page.\n * @return true if children should be processed as well\n */\n setCurrent(\n nodeContext: NodeContext,\n firstTime: boolean,\n atUnforcedBreak?: boolean,\n ): Task.Result<boolean>;\n /**\n * Set the container element that holds view elements produced from the\n * source.\n */\n setViewRoot(viewRoot: Element, isFootnote: boolean);\n /**\n * Moves to the next view node, creating it and appending it to the view tree\n * if needed.\n * @return that corresponds to the next view node\n */\n nextInTree(\n nodeContext: NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<NodeContext>;\n /**\n * Apply pseudo-element styles (if any).\n * @param target element to apply styles to\n */\n applyPseudoelementStyle(\n nodeContext: NodeContext,\n pseudoName: string,\n target: Element,\n ): void;\n /**\n * Apply styles to footnote container.\n * @param target element to apply styles to\n * @return vertical\n */\n applyFootnoteStyle(\n vertical: boolean,\n rtl: boolean,\n target: Element,\n ): boolean;\n /**\n * Peel off innermost first-XXX pseudoelement, create and create view nodes\n * after the end of that pseudoelement.\n */\n peelOff(\n nodeContext: NodeContext,\n nodeOffset: number,\n ): Task.Result<NodeContext>;\n /**\n * Process a block-end edge of a fragmented block.\n */\n processFragmentedBlockEdge(nodeContext: NodeContext);\n convertLengthToPx(\n numeric: Css.Numeric,\n viewNode: Node,\n clientLayout: ClientLayout,\n ): number | Css.Numeric;\n /**\n * Returns if two NodePositions represents the same position in the document.\n */\n isSameNodePosition(\n nodePosition1: NodePosition,\n nodePosition2: NodePosition,\n ): boolean;\n addEventListener(\n type: string,\n listener: Base.EventListener,\n capture?: boolean,\n ): void;\n removeEventListener(\n type: string,\n listener: Base.EventListener,\n capture?: boolean,\n ): void;\n dispatchEvent(evt: Base.Event): void;\n }\n\n /**\n * Formatting context.\n */\n export interface FormattingContext {\n formattingContextType: FormattingContextType;\n getName(): string;\n isFirstTime(nodeContext: NodeContext, firstTime: boolean): boolean;\n getParent(): FormattingContext;\n saveState(): any;\n restoreState(state: any);\n }\n\n export type NodePositionStep = {\n node: Node;\n shadowType: ShadowType;\n shadowContext: ShadowContext | null;\n nodeShadow: ShadowContext | null;\n shadowSibling: NodePositionStep | null;\n formattingContext: FormattingContext | null;\n fragmentIndex: number;\n };\n\n export type NodePosition = {\n steps: NodePositionStep[];\n offsetInNode: number;\n after: boolean;\n preprocessedTextContent: Diff.Change[] | null;\n };\n\n /**\n * Handling of purely whitespace sequences between blocks\n * @enum {number}\n */\n export enum Whitespace {\n /**\n * Whitespace sequence between blocks is ignored\n */\n IGNORE,\n /**\n * Whitespace sequence between blocks is ignored unless it containes newline\n */\n NEWLINE,\n /**\n * Whitespace sequence between blocks is preserved\n */\n PRESERVE,\n }\n\n export interface Container {\n left: number;\n top: number;\n marginLeft: number;\n marginRight: number;\n marginTop: number;\n marginBottom: number;\n borderLeft: number;\n borderRight: number;\n borderTop: number;\n borderBottom: number;\n paddingLeft: number;\n paddingRight: number;\n paddingTop: number;\n paddingBottom: number;\n width: number;\n height: number;\n originX: number;\n originY: number;\n exclusions: GeometryUtil.Shape[];\n innerShape: GeometryUtil.Shape;\n computedBlockSize: number;\n snapWidth: number;\n snapHeight: number;\n snapOffsetX: number;\n snapOffsetY: number;\n vertical: boolean; // vertical writing\n element: Element;\n\n getInsetTop(): number;\n getInsetBottom(): number;\n getInsetLeft(): number;\n getInsetRight(): number;\n getInsetBefore(): number;\n getInsetAfter(): number;\n getInsetStart(): number;\n getInsetEnd(): number;\n getBeforeEdge(box: ClientRect): number;\n getAfterEdge(box: ClientRect): number;\n getStartEdge(box: ClientRect): number;\n getEndEdge(box: ClientRect): number;\n getInlineSize(box: ClientRect): number;\n getBoxSize(box: ClientRect): number;\n getBoxDir(): number;\n getInlineDir(): number;\n copyFrom(other: Container): void;\n setVerticalPosition(top: number, height: number): void;\n setHorizontalPosition(left: number, width: number): void;\n setBlockPosition(start: number, extent: number): void;\n setInlinePosition(start: number, extent: number): void;\n clear(): void;\n getInnerShape(): GeometryUtil.Shape;\n getInnerRect(): GeometryUtil.Rect;\n getPaddingRect(): GeometryUtil.Rect;\n getOuterShape(\n outerShapeProp: Css.Val,\n context: Exprs.Context,\n ): GeometryUtil.Shape;\n getOuterRect(): GeometryUtil.Rect;\n }\n\n /**\n * @enum {number}\n */\n export enum ShadowType {\n NONE,\n CONTENT,\n ROOTLESS,\n ROOTED,\n }\n\n /**\n * Data about shadow tree instance.\n */\n export interface ShadowContext {\n readonly owner: Element;\n readonly root: Element;\n readonly xmldoc: XmlDoc.XMLDocHolder;\n readonly parentShadow: ShadowContext;\n subShadow: ShadowContext;\n readonly type: Vtree.ShadowType;\n readonly styler: object;\n\n equals(other: ShadowContext): boolean;\n }\n\n /**\n * Information about :first-letter or :first-line pseudoelements\n * @param count 0 - first-letter, 1 or more - first line(s)\n */\n export interface FirstPseudo {\n readonly outer: FirstPseudo;\n readonly count: number;\n }\n\n /**\n * NodeContext represents a position in the document + layout-related\n * information attached to it. When after=false and offsetInNode=0, the\n * position is inside the element (node), but just before its first child.\n * When offsetInNode>0 it represents offset in the textual content of the\n * node. When after=true it represents position right after the last child\n * of the node. boxOffset is incremented by 1 for any valid node position.\n */\n export interface NodeContext {\n // position itself\n offsetInNode: number;\n after: boolean;\n shadowType: ShadowType; // parent's shadow type\n shadowContext: Vtree.ShadowContext;\n nodeShadow: Vtree.ShadowContext;\n shadowSibling: NodeContext; // next \"sibling\" in the shadow tree\n // other stuff\n shared: boolean;\n inline: boolean;\n overflow: boolean;\n breakPenalty: number;\n display: string | null;\n floatReference: PageFloats.FloatReference;\n floatSide: string | null;\n clearSide: string | null;\n floatMinWrapBlock: Css.Numeric | null;\n columnSpan: Css.Val | null;\n verticalAlign: string;\n captionSide: string;\n inlineBorderSpacing: number;\n blockBorderSpacing: number;\n flexContainer: boolean;\n whitespace: Whitespace;\n hyphenateCharacter: string | null;\n breakWord: boolean;\n establishesBFC: boolean;\n containingBlockForAbsolute: boolean;\n breakBefore: string | null;\n breakAfter: string | null;\n viewNode: Node;\n clearSpacer: Node;\n inheritedProps: { [key: string]: number | string | Css.Val };\n vertical: boolean;\n direction: string;\n firstPseudo: FirstPseudo;\n lang: string | null;\n preprocessedTextContent: Diff.Change[] | null;\n formattingContext: FormattingContext;\n repeatOnBreak: string | null;\n pluginProps: {\n [key: string]: string | number | undefined | null | (number | null)[];\n };\n fragmentIndex: number;\n afterIfContinues: Selectors.AfterIfContinues;\n footnotePolicy: Css.Ident | null;\n\n sourceNode: Node;\n parent: NodeContext;\n boxOffset: number;\n\n resetView(): void;\n modify(): NodeContext;\n copy(): NodeContext;\n clone(): NodeContext;\n toNodePositionStep(): NodePositionStep;\n toNodePosition(): NodePosition;\n isInsideBFC(): boolean;\n getContainingBlockForAbsolute(): NodeContext;\n /**\n * Walk up NodeContext tree (starting from itself) and call the callback for\n * each block.\n */\n walkUpBlocks(callback: (p1: NodeContext) => any): void;\n belongsTo(formattingContext: FormattingContext): boolean;\n }\n\n export interface ChunkPosition {\n floats: NodePosition[];\n primary: NodePosition;\n\n clone(): ChunkPosition;\n isSamePosition(other: ChunkPosition): boolean;\n }\n\n export type ExprContentListener = (\n p1: Exprs.Val,\n p2: string,\n p3: Document,\n ) => Node | null;\n}\n\nexport namespace XmlDoc {\n export interface XMLDocHolder {\n lang: string | null;\n totalOffset: number;\n root: Element;\n body: Element;\n head: Element;\n last: Element;\n lastOffset: number;\n idMap: { [key: string]: Element };\n readonly store: XMLDocStore;\n readonly url: string;\n readonly document: Document;\n\n doc(): NodeList;\n getElementOffset(element: Element): number;\n getNodeOffset(srcNode: Node, offsetInNode: number, after: boolean): number;\n getTotalOffset(): number;\n /**\n * @return last node such that its offset is less or equal to the given\n */\n getNodeByOffset(offset: number): Node;\n /**\n * Get element by URL in the source document(s). URL must be in either '#id'\n * or 'url#id' form.\n */\n getElement(url: string): Element | null;\n }\n\n export interface Predicate {\n readonly fn: (p1: Node) => boolean;\n\n check(node: Node): boolean;\n withAttribute(name: string, value: string): Predicate;\n withChild(name: string, opt_childPredicate?: Predicate): Predicate;\n }\n\n export interface NodeList {\n readonly nodes: Node[];\n\n asArray(): Node[];\n size(): number;\n /**\n * Filter with predicate\n */\n predicate(pr: Predicate): NodeList;\n forEachNode(fn: (p1: Node, p2: (p1: Node) => void) => void): NodeList;\n forEach<T>(fn: (p1: Node) => T): T[];\n forEachNonNull<T>(fn: (p1: Node) => T): T[];\n child(tag: string): NodeList;\n childElements(): NodeList;\n attribute(name: string): (string | null)[];\n textContent(): (string | null)[];\n }\n\n export type XMLDocStore = Net.ResourceStore<XMLDocHolder>;\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Diff utility\n */\n\nimport fastdiff from \"fast-diff\";\n\nexport type Change = (number | string)[];\n\nexport function diffChars(originalText: string, newText: string): Change[] {\n return fastdiff(originalText, newText, 0);\n}\n\n/**\n * @returns string\n */\nexport function restoreOriginalText(changes: Change[]): any {\n return changes.reduce((result, item) => {\n if (item[0] === fastdiff.INSERT) {\n return result;\n }\n return result + item[1];\n }, \"\");\n}\n\n/**\n * @returns string\n */\nexport function restoreNewText(changes: Change[]): any {\n return changes.reduce((result, item) => {\n if (item[0] === fastdiff.DELETE) {\n return result;\n }\n return result + item[1];\n }, \"\");\n}\n\nexport function resolveNewIndex(changes: Change[], oldIndex: number): number {\n return resolveIndex(changes, oldIndex, 1);\n}\n\nexport function resolveOriginalIndex(\n changes: Change[],\n newIndex: number,\n): number {\n return resolveIndex(changes, newIndex, -1);\n}\n\nexport function resolveIndex(\n changes: Change[],\n index: number,\n coef: number,\n): number {\n let diff = 0;\n let current = 0;\n changes.some((change) => {\n for (let i = 0; i < (change[1] as string).length; i++) {\n switch ((change[0] as number) * coef) {\n case fastdiff.INSERT:\n diff++;\n break;\n case fastdiff.DELETE:\n diff--;\n current++;\n break;\n case fastdiff.EQUAL:\n current++;\n break;\n }\n if (current > index) {\n return true;\n }\n }\n return false;\n });\n return Math.max(Math.min(index, current - 1) + diff, 0);\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Vtree - Basic view tree data structures and support utilities.\n */\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Diff from \"./diff\";\nimport * as Exprs from \"./exprs\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as TaskUtil from \"./task-util\";\nimport { assert } from \"./asserts\";\nimport { PageFloats, Selectors, Vtree, XmlDoc } from \"./types\";\n\nexport const delayedProps = {\n transform: true,\n \"transform-origin\": true,\n};\n\nexport const delayedPropsIfRelativePositioned = {\n top: true,\n bottom: true,\n left: true,\n right: true,\n};\n\nexport class DelayedItem {\n constructor(\n public target: Element,\n public name: string,\n public value: Css.Val,\n ) {}\n}\n\nexport type PageHyperlinkEvent = {\n type: string;\n target;\n currentTarget;\n anchorElement: Element;\n href: string;\n};\n\nexport type Trigger = {\n observer: string;\n event: string;\n action: string;\n ref: string;\n};\n\nexport const actions = {\n show: function(obj) {\n obj.style.visibility = \"visible\";\n },\n hide: function(obj) {\n obj.style.visibility = \"hidden\";\n },\n play: function(obj) {\n obj.currentTime = 0;\n obj.play();\n },\n pause: function(obj) {\n obj.pause();\n },\n resume: function(obj) {\n obj.play();\n },\n mute: function(obj) {\n obj.muted = true;\n },\n unmute: function(obj) {\n obj.muted = false;\n },\n};\n\nexport function makeListener(\n refs: Element[],\n action: string,\n): EventListener | null {\n const actionFn = actions[action];\n if (actionFn) {\n return () => {\n for (let k = 0; k < refs.length; k++) {\n try {\n actionFn(refs[k]);\n } catch (err) {}\n }\n };\n }\n return null;\n}\n\nexport class Page extends Base.SimpleEventTarget {\n private static AUTO_PAGE_WIDTH_ATTRIBUTE: string =\n \"data-vivliostyle-auto-page-width\";\n private static AUTO_PAGE_HEIGHT_ATTRIBUTE: string =\n \"data-vivliostyle-auto-page-height\";\n pageAreaElement: HTMLElement | null = null;\n delayedItems: DelayedItem[] = [];\n hrefHandler: (e: Event) => void;\n elementsById: { [key: string]: Element[] } = {};\n dimensions: { width: number; height: number } = { width: 0, height: 0 };\n isFirstPage: boolean = false;\n isLastPage: boolean = false;\n isAutoPageWidth: boolean = true;\n isAutoPageHeight: boolean = true;\n spineIndex: number = 0;\n position: LayoutPosition = null;\n offset: number = -1;\n side: Constants.PageSide | null = null;\n fetchers: TaskUtil.Fetcher<{}>[] = [];\n marginBoxes: {\n top: { [key: string]: Container };\n bottom: { [key: string]: Container };\n left: { [key: string]: Container };\n right: { [key: string]: Container };\n } = { top: {}, bottom: {}, left: {}, right: {} };\n\n constructor(\n public readonly container: HTMLElement,\n public readonly bleedBox: HTMLElement,\n ) {\n super();\n const self = this;\n this.hrefHandler = (e: Event) => {\n const anchorElement = e.currentTarget as Element;\n const href =\n anchorElement.getAttribute(\"href\") ||\n anchorElement.getAttributeNS(Base.NS.XLINK, \"href\");\n if (href) {\n const evt = {\n type: \"hyperlink\",\n target: null,\n currentTarget: null,\n anchorElement,\n href,\n preventDefault() {\n e.preventDefault();\n },\n };\n self.dispatchEvent(evt);\n }\n };\n }\n\n setAutoPageWidth(isAuto: boolean) {\n this.isAutoPageWidth = isAuto;\n if (isAuto) {\n this.container.setAttribute(Page.AUTO_PAGE_WIDTH_ATTRIBUTE, \"true\");\n } else {\n this.container.removeAttribute(Page.AUTO_PAGE_WIDTH_ATTRIBUTE);\n }\n }\n\n setAutoPageHeight(isAuto: boolean) {\n this.isAutoPageHeight = isAuto;\n if (isAuto) {\n this.container.setAttribute(Page.AUTO_PAGE_HEIGHT_ATTRIBUTE, \"true\");\n } else {\n this.container.removeAttribute(Page.AUTO_PAGE_HEIGHT_ATTRIBUTE);\n }\n }\n\n registerElementWithId(element: Element, id: string) {\n const arr = this.elementsById[id];\n if (!arr) {\n this.elementsById[id] = [element];\n } else {\n arr.push(element);\n }\n }\n\n finish(triggers: Trigger[], clientLayout: ClientLayout): void {\n // Remove ID of elements which eventually did not fit in the page\n // (Some nodes may have been removed after registration if they did not fit\n // in the page)\n Object.keys(this.elementsById).forEach((id) => {\n const elems = this.elementsById[id];\n for (let i = 0; i < elems.length; ) {\n if (this.container.contains(elems[i])) {\n i++;\n } else {\n elems.splice(i, 1);\n }\n }\n if (elems.length === 0) {\n delete this.elementsById[id];\n }\n });\n const list = this.delayedItems;\n for (let i = 0; i < list.length; i++) {\n const item = list[i];\n if (\n item.target === this.container &&\n item.name === \"transform\" &&\n !this.isAutoPageWidth &&\n !this.isAutoPageHeight\n ) {\n // When fixed page size is specified, cancel the transform property\n // set at OPFView.makePage() for the specified viewport size\n // (e.g. `<meta name=\"viewport\" content=\"width=1307, height=1920\"/>`)\n // to avoid wrong page resizing.\n continue;\n }\n Base.setCSSProperty(item.target, item.name, item.value.toString());\n }\n\n // use size of the container of the PageMasterInstance\n const rect = clientLayout.getElementClientRect(this.container);\n this.dimensions.width = rect.width;\n this.dimensions.height = rect.height;\n for (let i = 0; i < triggers.length; i++) {\n const trigger = triggers[i];\n const refs = this.elementsById[trigger.ref];\n const observers = this.elementsById[trigger.observer];\n if (refs && observers) {\n const listener = makeListener(refs, trigger.action);\n if (listener) {\n for (let k = 0; k < observers.length; k++) {\n observers[k].addEventListener(trigger.event, listener, false);\n }\n }\n }\n }\n }\n\n /**\n * Zoom page.\n * @param scale Factor to which the page will be scaled.\n */\n zoom(scale: number) {\n Base.setCSSProperty(this.container, \"transform\", `scale(${scale})`);\n }\n\n /**\n * Returns the page area element.\n */\n getPageAreaElement(): HTMLElement {\n return this.pageAreaElement || this.container;\n }\n}\n\nexport type Spread = {\n left: Page;\n right: Page;\n};\n\n/**\n * Marks an element as \"special\". It should not be used in bbox calculations.\n */\nexport const SPECIAL_ATTR = \"data-adapt-spec\";\n\nexport const Whitespace = Vtree.Whitespace;\nexport type Whitespace = Vtree.Whitespace;\n\n/**\n * Resolves Whitespace value from a value of 'white-space' property\n * @param whitespace The value of 'white-space' property\n */\nexport function whitespaceFromPropertyValue(\n whitespace: string,\n): Whitespace | null {\n switch (whitespace) {\n case \"normal\":\n case \"nowrap\":\n return Whitespace.IGNORE;\n case \"pre-line\":\n return Whitespace.NEWLINE;\n case \"pre\":\n case \"pre-wrap\":\n return Whitespace.PRESERVE;\n default:\n return null;\n }\n}\n\nexport function canIgnore(node: Node, whitespace: Whitespace): boolean {\n if (node.nodeType == 1) {\n return false;\n }\n const text = node.textContent;\n switch (whitespace) {\n case Whitespace.IGNORE:\n return !!text.match(/^\\s*$/);\n case Whitespace.NEWLINE:\n return !!text.match(/^[ \\t\\f]*$/);\n case Whitespace.PRESERVE:\n return text.length == 0;\n }\n throw new Error(`Unexpected whitespace: ${whitespace}`);\n}\n\nexport class Flow {\n forcedBreakOffsets = [] as number[];\n formattingContext: FormattingContext | null = null;\n\n constructor(\n public readonly flowName: string,\n public readonly parentFlowName: string | null,\n ) {}\n}\n\nexport class FlowChunk {\n startPage: number = -1;\n\n constructor(\n public flowName: string,\n public element: Element,\n public startOffset: number,\n public priority: number,\n public linger: number,\n public exclusive: boolean,\n public repeated: boolean,\n public last: boolean,\n public breakBefore: string | null,\n ) {}\n\n isBetter(other: FlowChunk): boolean {\n if (!this.exclusive) {\n return false;\n }\n if (!other.exclusive) {\n return true;\n }\n if (this.priority > other.priority) {\n return true;\n }\n return this.last;\n }\n}\n\nexport type ClientRect = Vtree.ClientRect;\n\nexport function clientrectIncreasingTop(\n r1: ClientRect,\n r2: ClientRect,\n): number {\n return r1.top - r2.top;\n}\n\nexport function clientrectDecreasingRight(\n r1: ClientRect,\n r2: ClientRect,\n): number {\n return r2.right - r1.right;\n}\n\n/**\n * Interface to read the position assigned to the elements and ranges by the\n * browser.\n */\nexport type ClientLayout = Vtree.ClientLayout;\n\n/**\n * Styling, creating a single node's view, etc.\n */\nexport type LayoutContext = Vtree.LayoutContext;\n\n/**\n * Formatting context.\n */\nexport type FormattingContext = Vtree.FormattingContext;\n\nexport function eachAncestorFormattingContext(\n nodeContext: NodeContext,\n callback: (p1: FormattingContext) => any,\n): void {\n if (!nodeContext) {\n return;\n }\n for (let fc = nodeContext.formattingContext; fc; fc = fc.getParent()) {\n callback(fc);\n }\n}\n\nexport type NodePositionStep = Vtree.NodePositionStep;\n\nexport function isSameNodePositionStep(\n nps1: NodePositionStep,\n nps2: NodePositionStep,\n): boolean {\n if (nps1 === nps2) {\n return true;\n }\n if (!nps1 || !nps2) {\n return false;\n }\n return (\n nps1.node === nps2.node &&\n nps1.shadowType === nps2.shadowType &&\n isSameShadowContext(nps1.shadowContext, nps2.shadowContext) &&\n isSameShadowContext(nps1.nodeShadow, nps2.nodeShadow) &&\n isSameNodePositionStep(nps1.shadowSibling, nps2.shadowSibling)\n );\n}\n\nexport type NodePosition = Vtree.NodePosition;\n\nexport function isSameNodePosition(\n np1: NodePosition | null,\n np2: NodePosition | null,\n): boolean {\n if (np1 === np2) {\n return true;\n }\n if (!np1 || !np2) {\n return false;\n }\n if (\n np1.offsetInNode !== np2.offsetInNode ||\n np1.after !== np2.after ||\n np1.steps.length !== np2.steps.length\n ) {\n return false;\n }\n for (let i = 0; i < np1.steps.length; i++) {\n if (!isSameNodePositionStep(np1.steps[i], np2.steps[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport function newNodePositionFromNode(node: Node): NodePosition {\n const step: NodePositionStep = {\n node,\n shadowType: ShadowType.NONE,\n shadowContext: null,\n nodeShadow: null,\n shadowSibling: null,\n formattingContext: null,\n fragmentIndex: 0,\n };\n return {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: null,\n };\n}\n\nexport function newNodePositionFromNodeContext(\n nodeContext: Vtree.NodeContext,\n initialFragmentIndex: number | null,\n): NodePosition {\n const step: NodePositionStep = {\n node: nodeContext.sourceNode,\n shadowType: ShadowType.NONE,\n shadowContext: nodeContext.shadowContext,\n nodeShadow: null,\n shadowSibling: null,\n formattingContext: null,\n fragmentIndex:\n initialFragmentIndex != null\n ? initialFragmentIndex\n : nodeContext.fragmentIndex,\n };\n return {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: nodeContext.preprocessedTextContent,\n };\n}\n\nexport function makeNodeContextFromNodePositionStep(\n step: NodePositionStep,\n parent: Vtree.NodeContext,\n): NodeContext {\n const nodeContext = new NodeContext(step.node, parent as NodeContext, 0);\n nodeContext.shadowType = step.shadowType;\n nodeContext.shadowContext = step.shadowContext;\n nodeContext.nodeShadow = step.nodeShadow;\n nodeContext.shadowSibling = step.shadowSibling\n ? makeNodeContextFromNodePositionStep(step.shadowSibling, parent.copy())\n : null;\n nodeContext.formattingContext = step.formattingContext;\n nodeContext.fragmentIndex = step.fragmentIndex + 1;\n return nodeContext;\n}\n\nexport const ShadowType = Vtree.ShadowType;\nexport type ShadowType = Vtree.ShadowType;\n\n/**\n * Data about shadow tree instance.\n */\nexport class ShadowContext implements Vtree.ShadowContext {\n subShadow: ShadowContext = null;\n\n constructor(\n public readonly owner: Element,\n public readonly root: Element,\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n public readonly parentShadow: ShadowContext,\n superShadow: ShadowContext,\n public readonly type: ShadowType,\n public readonly styler: object,\n ) {\n if (superShadow) {\n superShadow.subShadow = this;\n }\n }\n\n equals(other: ShadowContext): boolean {\n if (!other) {\n return false;\n }\n return (\n this.owner === other.owner &&\n this.xmldoc === other.xmldoc &&\n this.type === other.type &&\n isSameShadowContext(this.parentShadow, other.parentShadow)\n );\n }\n}\n\nexport function isSameShadowContext(\n sc1: ShadowContext,\n sc2: ShadowContext,\n): boolean {\n return sc1 === sc2 || (!!sc1 && !!sc2 && sc1.equals(sc2));\n}\n\n/**\n * Information about :first-letter or :first-line pseudoelements\n * @param count 0 - first-letter, 1 or more - first line(s)\n */\nexport class FirstPseudo implements Vtree.FirstPseudo {\n constructor(\n public readonly outer: FirstPseudo,\n public readonly count: number,\n ) {}\n}\n\n/**\n * NodeContext represents a position in the document + layout-related\n * information attached to it. When after=false and offsetInNode=0, the\n * position is inside the element (node), but just before its first child.\n * When offsetInNode>0 it represents offset in the textual content of the\n * node. When after=true it represents position right after the last child\n * of the node. boxOffset is incremented by 1 for any valid node position.\n */\nexport class NodeContext implements Vtree.NodeContext {\n // position itself\n offsetInNode: number = 0;\n after: boolean = false;\n shadowType: ShadowType;\n\n // parent's shadow type\n shadowContext: ShadowContext;\n nodeShadow: ShadowContext = null;\n shadowSibling: NodeContext = null;\n\n // next \"sibling\" in the shadow tree\n // other stuff\n shared: boolean = false;\n inline: boolean = true;\n overflow: boolean = false;\n breakPenalty: number;\n display: string | null = null;\n floatReference: PageFloats.FloatReference;\n floatSide: string | null = null;\n clearSide: string | null = null;\n floatMinWrapBlock: Css.Numeric | null = null;\n columnSpan: Css.Val | null = null;\n verticalAlign: string = \"baseline\";\n captionSide: string = \"top\";\n inlineBorderSpacing: number = 0;\n blockBorderSpacing: number = 0;\n flexContainer: boolean = false;\n whitespace: Whitespace;\n hyphenateCharacter: string | null;\n breakWord: boolean;\n establishesBFC: boolean = false;\n containingBlockForAbsolute: boolean = false;\n breakBefore: string | null = null;\n breakAfter: string | null = null;\n viewNode: Node = null;\n clearSpacer: Node = null;\n inheritedProps: { [key: string]: number | string | Css.Val };\n vertical: boolean;\n direction: string;\n firstPseudo: FirstPseudo;\n lang: string | null = null;\n preprocessedTextContent: Diff.Change[] | null = null;\n formattingContext: FormattingContext;\n repeatOnBreak: string | null = null;\n pluginProps: {\n [key: string]: string | number | undefined | null | (number | null)[];\n } = {};\n fragmentIndex: number = 1;\n afterIfContinues: Selectors.AfterIfContinues = null;\n footnotePolicy: Css.Ident | null = null;\n\n constructor(\n public sourceNode: Node,\n public parent: NodeContext,\n public boxOffset: number,\n ) {\n this.shadowType = ShadowType.NONE;\n this.shadowContext = parent ? parent.shadowContext : null;\n this.breakPenalty = parent ? parent.breakPenalty : 0;\n this.floatReference = PageFloats.FloatReference.INLINE;\n this.whitespace = parent ? parent.whitespace : Whitespace.IGNORE;\n this.hyphenateCharacter = parent ? parent.hyphenateCharacter : null;\n this.breakWord = parent ? parent.breakWord : false;\n this.inheritedProps = parent ? parent.inheritedProps : {};\n this.vertical = parent ? parent.vertical : false;\n this.direction = parent ? parent.direction : \"ltr\";\n this.firstPseudo = parent ? parent.firstPseudo : null;\n this.formattingContext = parent ? parent.formattingContext : null;\n }\n\n resetView(): void {\n this.inline = true;\n this.breakPenalty = this.parent ? this.parent.breakPenalty : 0;\n this.viewNode = null;\n this.clearSpacer = null;\n this.offsetInNode = 0;\n this.after = false;\n this.display = null;\n this.floatReference = PageFloats.FloatReference.INLINE;\n this.floatSide = null;\n this.clearSide = null;\n this.floatMinWrapBlock = null;\n this.columnSpan = null;\n this.verticalAlign = \"baseline\";\n this.flexContainer = false;\n this.whitespace = this.parent ? this.parent.whitespace : Whitespace.IGNORE;\n this.hyphenateCharacter = this.parent\n ? this.parent.hyphenateCharacter\n : null;\n this.breakWord = this.parent ? this.parent.breakWord : false;\n this.breakBefore = null;\n this.breakAfter = null;\n this.nodeShadow = null;\n this.establishesBFC = false;\n this.containingBlockForAbsolute = false;\n this.vertical = this.parent ? this.parent.vertical : false;\n this.nodeShadow = null;\n this.preprocessedTextContent = null;\n this.formattingContext = this.parent ? this.parent.formattingContext : null;\n this.repeatOnBreak = null;\n this.pluginProps = {};\n this.fragmentIndex = 1;\n this.afterIfContinues = null;\n this.footnotePolicy = null;\n }\n\n private cloneItem(): NodeContext {\n const np = new NodeContext(this.sourceNode, this.parent, this.boxOffset);\n np.offsetInNode = this.offsetInNode;\n np.after = this.after;\n np.nodeShadow = this.nodeShadow;\n np.shadowType = this.shadowType;\n np.shadowContext = this.shadowContext;\n np.shadowSibling = this.shadowSibling;\n np.inline = this.inline;\n np.breakPenalty = this.breakPenalty;\n np.display = this.display;\n np.floatReference = this.floatReference;\n np.floatSide = this.floatSide;\n np.clearSide = this.clearSide;\n np.floatMinWrapBlock = this.floatMinWrapBlock;\n np.columnSpan = this.columnSpan;\n np.verticalAlign = this.verticalAlign;\n np.captionSide = this.captionSide;\n np.inlineBorderSpacing = this.inlineBorderSpacing;\n np.blockBorderSpacing = this.blockBorderSpacing;\n np.establishesBFC = this.establishesBFC;\n np.containingBlockForAbsolute = this.containingBlockForAbsolute;\n np.flexContainer = this.flexContainer;\n np.whitespace = this.whitespace;\n np.hyphenateCharacter = this.hyphenateCharacter;\n np.breakWord = this.breakWord;\n np.breakBefore = this.breakBefore;\n np.breakAfter = this.breakAfter;\n np.viewNode = this.viewNode;\n np.clearSpacer = this.clearSpacer;\n np.firstPseudo = this.firstPseudo;\n np.vertical = this.vertical;\n np.overflow = this.overflow;\n np.preprocessedTextContent = this.preprocessedTextContent;\n np.formattingContext = this.formattingContext;\n np.repeatOnBreak = this.repeatOnBreak;\n np.pluginProps = Object.create(this.pluginProps);\n np.fragmentIndex = this.fragmentIndex;\n np.afterIfContinues = this.afterIfContinues;\n np.footnotePolicy = this.footnotePolicy;\n return np;\n }\n\n modify(): NodeContext {\n if (!this.shared) {\n return this;\n }\n return this.cloneItem();\n }\n\n copy(): NodeContext {\n let np: NodeContext = this;\n do {\n if (np.shared) {\n break;\n }\n np.shared = true;\n np = np.parent;\n } while (np);\n return this;\n }\n\n clone(): NodeContext {\n const np = this.cloneItem();\n let npc = np;\n let npp: NodeContext;\n while ((npp = npc.parent) != null) {\n npp = npp.cloneItem();\n npc.parent = npp;\n npc = npp;\n }\n return np;\n }\n\n toNodePositionStep(): NodePositionStep {\n return {\n node: this.sourceNode,\n shadowType: this.shadowType,\n shadowContext: this.shadowContext,\n nodeShadow: this.nodeShadow,\n shadowSibling: this.shadowSibling\n ? this.shadowSibling.toNodePositionStep()\n : null,\n formattingContext: this.formattingContext,\n fragmentIndex: this.fragmentIndex,\n };\n }\n\n toNodePosition(): NodePosition {\n let nc: NodeContext = this;\n const steps = [];\n do {\n // We need fully \"peeled\" path, so don't record first-XXX pseudoelement\n // containers\n if (\n !nc.firstPseudo ||\n !nc.parent ||\n nc.parent.firstPseudo === nc.firstPseudo\n ) {\n steps.push(nc.toNodePositionStep());\n }\n nc = nc.parent;\n } while (nc);\n const actualOffsetInNode = this.preprocessedTextContent\n ? Diff.resolveOriginalIndex(\n this.preprocessedTextContent,\n this.offsetInNode,\n )\n : this.offsetInNode;\n return {\n steps,\n offsetInNode: actualOffsetInNode,\n after: this.after,\n preprocessedTextContent: this.preprocessedTextContent,\n };\n }\n\n isInsideBFC(): boolean {\n let parent = this.parent;\n while (parent) {\n if (parent.establishesBFC) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n\n getContainingBlockForAbsolute(): NodeContext {\n let parent = this.parent;\n while (parent) {\n if (parent.containingBlockForAbsolute) {\n return parent;\n }\n parent = parent.parent;\n }\n return null;\n }\n\n /**\n * Walk up NodeContext tree (starting from itself) and call the callback for\n * each block.\n */\n walkUpBlocks(callback: (p1: NodeContext) => any) {\n let nodeContext: NodeContext = this;\n while (nodeContext) {\n if (!nodeContext.inline) {\n callback(nodeContext);\n }\n nodeContext = nodeContext.parent;\n }\n }\n\n belongsTo(formattingContext: FormattingContext): boolean {\n return (\n this.formattingContext === formattingContext &&\n !!this.parent &&\n this.parent.formattingContext === formattingContext\n );\n }\n}\n\nexport class ChunkPosition implements Vtree.ChunkPosition {\n floats: NodePosition[] = null;\n\n constructor(public primary: NodePosition) {}\n\n clone(): ChunkPosition {\n const result = new ChunkPosition(this.primary);\n if (this.floats) {\n result.floats = [];\n for (let i = 0; i < this.floats.length; ++i) {\n result.floats[i] = this.floats[i];\n }\n }\n return result;\n }\n\n isSamePosition(other: ChunkPosition): boolean {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n if (!isSameNodePosition(this.primary, other.primary)) {\n return false;\n }\n if (this.floats) {\n if (!other.floats || this.floats.length !== other.floats.length) {\n return false;\n }\n for (let i = 0; i < this.floats.length; i++) {\n if (!isSameNodePosition(this.floats[i], other.floats[i])) {\n return false;\n }\n }\n } else if (other.floats) {\n return false;\n }\n return true;\n }\n}\n\nexport class FlowChunkPosition {\n constructor(\n public chunkPosition: ChunkPosition,\n public readonly flowChunk: FlowChunk,\n ) {}\n\n clone(): FlowChunkPosition {\n return new FlowChunkPosition(this.chunkPosition.clone(), this.flowChunk);\n }\n\n isSamePosition(other: FlowChunkPosition): boolean {\n return (\n !!other &&\n (this === other || this.chunkPosition.isSamePosition(other.chunkPosition))\n );\n }\n}\n\nexport class FlowPosition {\n positions: FlowChunkPosition[] = [];\n startSide: string = \"any\";\n breakAfter: string | null = null;\n\n clone(): FlowPosition {\n const newfp = new FlowPosition();\n const arr = this.positions;\n const newarr = newfp.positions;\n for (let i = 0; i < arr.length; i++) {\n newarr[i] = arr[i].clone();\n }\n newfp.startSide = this.startSide;\n newfp.breakAfter = this.breakAfter;\n return newfp;\n }\n\n isSamePosition(other: FlowPosition): boolean {\n if (this === other) {\n return true;\n }\n if (!other || this.positions.length !== other.positions.length) {\n return false;\n }\n for (let i = 0; i < this.positions.length; i++) {\n if (!this.positions[i].isSamePosition(other.positions[i])) {\n return false;\n }\n }\n return true;\n }\n\n hasContent(offset: number): boolean {\n return (\n this.positions.length > 0 &&\n this.positions[0].flowChunk.startOffset <= offset\n );\n }\n}\n\nexport class LayoutPosition {\n /**\n * One-based, incremented before layout.\n */\n page: number = 0;\n flows: { [key: string]: Flow } = {};\n flowPositions: { [key: string]: FlowPosition } = {};\n\n /**\n * flowPositions is built up to this offset.\n */\n highestSeenOffset: number = 0;\n\n // FIXME: This properties seem to be not used\n highestSeenNode: Node;\n lookupPositionOffset: number;\n\n clone(): LayoutPosition {\n const newcp = new LayoutPosition();\n newcp.page = this.page;\n newcp.highestSeenNode = this.highestSeenNode;\n newcp.highestSeenOffset = this.highestSeenOffset;\n newcp.lookupPositionOffset = this.lookupPositionOffset;\n newcp.flows = this.flows;\n for (const name in this.flowPositions) {\n newcp.flowPositions[name] = this.flowPositions[name].clone();\n }\n return newcp;\n }\n\n isSamePosition(other: LayoutPosition): boolean {\n if (this === other) {\n return true;\n }\n if (\n !other ||\n this.page !== other.page ||\n this.highestSeenOffset !== other.highestSeenOffset\n ) {\n return false;\n }\n const thisFlowNames = Object.keys(this.flowPositions);\n const otherFlowNames = Object.keys(other.flowPositions);\n if (thisFlowNames.length !== otherFlowNames.length) {\n return false;\n }\n for (const flowName of thisFlowNames) {\n if (\n !this.flowPositions[flowName].isSamePosition(\n other.flowPositions[flowName],\n )\n ) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * @param name flow name.\n */\n hasContent(name: string, offset: number): boolean {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return false;\n }\n return flowPos.hasContent(offset);\n }\n\n startSideOfFlow(name: string): string {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return \"any\";\n }\n return flowPos.startSide;\n }\n\n firstFlowChunkOfFlow(name: string): FlowChunk | null {\n const flowPos = this.flowPositions[name];\n if (!flowPos) {\n return null;\n }\n const flowChunkPosition = flowPos.positions[0];\n if (!flowChunkPosition) {\n return null;\n }\n return flowChunkPosition.flowChunk;\n }\n}\n\nexport class Container implements Vtree.Container {\n left: number = 0;\n top: number = 0;\n marginLeft: number = 0;\n marginRight: number = 0;\n marginTop: number = 0;\n marginBottom: number = 0;\n borderLeft: number = 0;\n borderRight: number = 0;\n borderTop: number = 0;\n borderBottom: number = 0;\n paddingLeft: number = 0;\n paddingRight: number = 0;\n paddingTop: number = 0;\n paddingBottom: number = 0;\n width: number = 0;\n height: number = 0;\n originX: number = 0;\n originY: number = 0;\n exclusions: GeometryUtil.Shape[] = null;\n innerShape: GeometryUtil.Shape = null;\n computedBlockSize: number = 0;\n snapWidth: number = 0;\n snapHeight: number = 0;\n snapOffsetX: number = 0;\n snapOffsetY: number = 0;\n vertical: boolean = false; // vertical writing\n\n constructor(public element: Element) {}\n\n getInsetTop() {\n return this.marginTop + this.borderTop + this.paddingTop;\n }\n\n getInsetBottom() {\n return this.marginBottom + this.borderBottom + this.paddingBottom;\n }\n\n getInsetLeft() {\n return this.marginLeft + this.borderLeft + this.paddingLeft;\n }\n\n getInsetRight() {\n return this.marginRight + this.borderRight + this.paddingRight;\n }\n\n getInsetBefore() {\n if (this.vertical) {\n return this.getInsetRight();\n } else {\n return this.getInsetTop();\n }\n }\n\n getInsetAfter() {\n if (this.vertical) {\n return this.getInsetLeft();\n } else {\n return this.getInsetBottom();\n }\n }\n\n getInsetStart() {\n if (this.vertical) {\n return this.getInsetTop();\n } else {\n return this.getInsetLeft();\n }\n }\n\n getInsetEnd() {\n if (this.vertical) {\n return this.getInsetBottom();\n } else {\n return this.getInsetRight();\n }\n }\n\n getBeforeEdge(box: ClientRect): number {\n return this.vertical ? box.right : box.top;\n }\n\n getAfterEdge(box: ClientRect): number {\n return this.vertical ? box.left : box.bottom;\n }\n\n getStartEdge(box: ClientRect): number {\n return this.vertical ? box.top : box.left;\n }\n\n getEndEdge(box: ClientRect): number {\n return this.vertical ? box.bottom : box.right;\n }\n\n getInlineSize(box: ClientRect): number {\n return this.vertical ? box.bottom - box.top : box.right - box.left;\n }\n\n getBoxSize(box: ClientRect): number {\n return this.vertical ? box.right - box.left : box.bottom - box.top;\n }\n\n getBoxDir(): number {\n return this.vertical ? -1 : 1;\n }\n\n getInlineDir(): number {\n return 1;\n }\n\n copyFrom(other: Container): void {\n this.element = other.element;\n this.left = other.left;\n this.top = other.top;\n this.marginLeft = other.marginLeft;\n this.marginRight = other.marginRight;\n this.marginTop = other.marginTop;\n this.marginBottom = other.marginBottom;\n this.borderLeft = other.borderLeft;\n this.borderRight = other.borderRight;\n this.borderTop = other.borderTop;\n this.borderBottom = other.borderBottom;\n this.paddingLeft = other.paddingLeft;\n this.paddingRight = other.paddingRight;\n this.paddingTop = other.paddingTop;\n this.paddingBottom = other.paddingBottom;\n this.width = other.width;\n this.height = other.height;\n this.originX = other.originX;\n this.originY = other.originY;\n this.innerShape = other.innerShape;\n this.exclusions = other.exclusions;\n this.computedBlockSize = other.computedBlockSize;\n this.snapWidth = other.snapWidth;\n this.snapHeight = other.snapHeight;\n this.vertical = other.vertical;\n }\n\n setVerticalPosition(top: number, height: number): void {\n this.top = top;\n this.height = height;\n Base.setCSSProperty(this.element, \"top\", `${top}px`);\n Base.setCSSProperty(this.element, \"height\", `${height}px`);\n }\n\n setHorizontalPosition(left: number, width: number): void {\n this.left = left;\n this.width = width;\n Base.setCSSProperty(this.element, \"left\", `${left}px`);\n Base.setCSSProperty(this.element, \"width\", `${width}px`);\n }\n\n setBlockPosition(start: number, extent: number): void {\n if (this.vertical) {\n this.setHorizontalPosition(start + extent * this.getBoxDir(), extent);\n } else {\n this.setVerticalPosition(start, extent);\n }\n }\n\n setInlinePosition(start: number, extent: number): void {\n if (this.vertical) {\n this.setVerticalPosition(start, extent);\n } else {\n this.setHorizontalPosition(start, extent);\n }\n }\n\n clear() {\n const parent = this.element;\n let c: Node;\n while ((c = parent.lastChild)) {\n parent.removeChild(c);\n }\n }\n\n getInnerShape(): GeometryUtil.Shape {\n const rect = this.getInnerRect();\n if (this.innerShape) {\n return this.innerShape.withOffset(rect.x1, rect.y1);\n }\n return GeometryUtil.shapeForRect(rect.x1, rect.y1, rect.x2, rect.y2);\n }\n\n getInnerRect(): GeometryUtil.Rect {\n const offsetX = this.originX + this.left + this.getInsetLeft();\n const offsetY = this.originY + this.top + this.getInsetTop();\n return new GeometryUtil.Rect(\n offsetX,\n offsetY,\n offsetX + this.width,\n offsetY + this.height,\n );\n }\n\n getPaddingRect(): GeometryUtil.Rect {\n const paddingX =\n this.originX + this.left + this.marginLeft + this.borderLeft;\n const paddingY = this.originY + this.top + this.marginTop + this.borderTop;\n const paddingWidth = this.paddingLeft + this.width + this.paddingRight;\n const paddingHeight = this.paddingTop + this.height + this.paddingBottom;\n return new GeometryUtil.Rect(\n paddingX,\n paddingY,\n paddingX + paddingWidth,\n paddingY + paddingHeight,\n );\n }\n\n getOuterShape(\n outerShapeProp: Css.Val,\n context: Exprs.Context,\n ): GeometryUtil.Shape {\n const rect = this.getOuterRect();\n return CssProp.toShape(\n outerShapeProp,\n rect.x1,\n rect.y1,\n rect.x2 - rect.x1,\n rect.y2 - rect.y1,\n context,\n );\n }\n\n getOuterRect(): GeometryUtil.Rect {\n const outerX = this.originX + this.left;\n const outerY = this.originY + this.top;\n const outerWidth = this.getInsetLeft() + this.width + this.getInsetRight();\n const outerHeight =\n this.getInsetTop() + this.height + this.getInsetBottom();\n return new GeometryUtil.Rect(\n outerX,\n outerY,\n outerX + outerWidth,\n outerY + outerHeight,\n );\n }\n}\n\nexport type ExprContentListener = Vtree.ExprContentListener;\n\nexport class ContentPropertyHandler extends Css.Visitor {\n constructor(\n public readonly elem: Element,\n public readonly context: Exprs.Context,\n public readonly rootContentValue: Css.Val,\n public readonly exprContentListener: ExprContentListener,\n ) {\n super();\n }\n\n private visitStrInner(str: string, node?: Node | null) {\n if (!node) {\n node = this.elem.ownerDocument.createTextNode(str);\n }\n this.elem.appendChild(node);\n }\n\n /** @override */\n visitStr(str: Css.Str): Css.Val {\n this.visitStrInner(str.str);\n return null;\n }\n\n /** @override */\n visitURL(url: Css.URL): Css.Val {\n if ((this.rootContentValue as any).url) {\n this.elem.setAttribute(\"src\", url.url);\n } else {\n const img = this.elem.ownerDocument.createElementNS(Base.NS.XHTML, \"img\");\n img.setAttribute(\"src\", url.url);\n this.elem.appendChild(img);\n }\n return null;\n }\n\n /** @override */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.visitValues(list.values);\n return null;\n }\n\n /** @override */\n visitExpr(expr: Css.Expr): Css.Val {\n const ex = expr.toExpr();\n let val = ex.evaluate(this.context);\n if (typeof val === \"string\") {\n if (ex instanceof Exprs.Named) {\n // For env(pub-title) and env(doc-title)\n // Need to unquote the result. To be consistent with cssparse.evaluateExprToCSS()\n val = CssParser.parseValue(\n ex.scope,\n new CssTokenizer.Tokenizer(val, null),\n \"\",\n ).stringValue();\n }\n assert(this.elem.ownerDocument);\n const node = this.exprContentListener(ex, val, this.elem.ownerDocument);\n this.visitStrInner(val, node);\n }\n return null;\n }\n}\n\nexport function nonTrivialContent(val: Css.Val): boolean {\n return (\n val != null &&\n val !== Css.ident.normal &&\n val !== Css.ident.none &&\n val !== Css.ident.inherit\n );\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PageFloats - CSS Page Floats\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Logging from \"./logging\";\nimport * as CssLogicalUtil from \"./css-logical-util\";\nimport * as Sizing from \"./sizing\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout as LayoutType, PageFloats, Vtree } from \"./types\";\n\nexport const FloatReference = PageFloats.FloatReference;\nexport type FloatReference = PageFloats.FloatReference;\n\ntype PageFloatID = PageFloats.PageFloatID;\n\nexport function floatReferenceOf(str: string): FloatReference {\n switch (str) {\n case \"inline\":\n return FloatReference.INLINE;\n case \"column\":\n return FloatReference.COLUMN;\n case \"region\":\n return FloatReference.REGION;\n case \"page\":\n return FloatReference.PAGE;\n default:\n throw new Error(`Unknown float-reference: ${str}`);\n }\n}\n\nexport function isPageFloat(floatReference: FloatReference): boolean {\n switch (floatReference) {\n case FloatReference.INLINE:\n return false;\n case FloatReference.COLUMN:\n case FloatReference.REGION:\n case FloatReference.PAGE:\n return true;\n default:\n throw new Error(`Unknown float-reference: ${floatReference}`);\n }\n}\n\n/**\n * Interpret a float value with the writing-mode and direction assuming the\n * float-reference is inline and returns \"left\" or \"right\".\n */\nexport function resolveInlineFloatDirection(\n floatSide: string,\n vertical: boolean,\n direction: string,\n): string {\n const writingMode = vertical ? \"vertical-rl\" : \"horizontal-tb\";\n if (floatSide === \"top\" || floatSide === \"bottom\") {\n floatSide = CssLogicalUtil.toLogical(floatSide, writingMode, direction);\n }\n if (floatSide === \"block-start\") {\n floatSide = \"inline-start\";\n }\n if (floatSide === \"block-end\") {\n floatSide = \"inline-end\";\n }\n if (floatSide === \"inline-start\" || floatSide === \"inline-end\") {\n const physicalValue = CssLogicalUtil.toPhysical(\n floatSide,\n writingMode,\n direction,\n );\n const lineRelativeValue = CssLogicalUtil.toLineRelative(\n physicalValue,\n writingMode,\n );\n if (lineRelativeValue === \"line-left\") {\n floatSide = \"left\";\n } else if (lineRelativeValue === \"line-right\") {\n floatSide = \"right\";\n }\n }\n if (floatSide !== \"left\" && floatSide !== \"right\") {\n Logging.logger.warn(`Invalid float value: ${floatSide}. Fallback to left.`);\n floatSide = \"left\";\n }\n return floatSide;\n}\n\nexport class PageFloat implements PageFloats.PageFloat {\n order: number | null = null;\n id: PageFloatID | null = null;\n\n constructor(\n public readonly nodePosition: Vtree.NodePosition,\n public readonly floatReference: FloatReference,\n public readonly floatSide: string,\n public readonly clearSide: string | null,\n public readonly flowName: string,\n public readonly floatMinWrapBlock: Css.Numeric | null,\n ) {}\n\n getOrder(): number {\n if (this.order === null) {\n throw new Error(\"The page float is not yet added\");\n }\n return this.order;\n }\n\n getId(): PageFloatID {\n if (!this.id) {\n throw new Error(\"The page float is not yet added\");\n }\n return this.id;\n }\n\n isAllowedOnContext(pageFloatLayoutContext: PageFloatLayoutContext): boolean {\n return pageFloatLayoutContext.isAnchorAlreadyAppeared(this.getId());\n }\n\n isAllowedToPrecede(other: PageFloat): boolean {\n return false;\n }\n}\n\nexport class PageFloatStore {\n private floats: PageFloat[] = [];\n private nextPageFloatIndex: number = 0;\n\n private nextOrder(): number {\n return this.nextPageFloatIndex++;\n }\n\n private createPageFloatId(order: number): PageFloatID {\n return `pf${order}`;\n }\n\n addPageFloat(float: PageFloat) {\n const index = this.floats.findIndex((f) =>\n VtreeImpl.isSameNodePosition(f.nodePosition, float.nodePosition),\n );\n if (index >= 0) {\n throw new Error(\n \"A page float with the same source node is already registered\",\n );\n } else {\n const order = (float.order = this.nextOrder());\n float.id = this.createPageFloatId(order);\n this.floats.push(float);\n }\n }\n\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null {\n const index = this.floats.findIndex((f) =>\n VtreeImpl.isSameNodePosition(f.nodePosition, nodePosition),\n );\n return index >= 0 ? this.floats[index] : null;\n }\n\n findPageFloatById(id: PageFloatID) {\n const index = this.floats.findIndex((f) => f.id === id);\n return index >= 0 ? this.floats[index] : null;\n }\n}\n\n/**\n * @param continues Represents whether the float is fragmented and continues\n * after this fragment\n */\nexport class PageFloatFragment implements PageFloats.PageFloatFragment {\n constructor(\n public readonly floatReference: FloatReference,\n public readonly floatSide: string,\n public readonly continuations: PageFloatContinuation[],\n public readonly area: Vtree.Container,\n public readonly continues: boolean,\n ) {}\n\n hasFloat(float: PageFloat): boolean {\n return this.continuations.some((c) => c.float === float);\n }\n\n findNotAllowedFloat(context: PageFloatLayoutContext): PageFloat | null {\n for (let i = this.continuations.length - 1; i >= 0; i--) {\n const f = this.continuations[i].float;\n if (!f.isAllowedOnContext(context)) {\n return f;\n }\n }\n return null;\n }\n\n getOuterShape(): GeometryUtil.Shape {\n return this.area.getOuterShape(null, null);\n }\n\n getOuterRect(): GeometryUtil.Rect {\n return this.area.getOuterRect();\n }\n\n getOrder(): number {\n const floats = this.continuations.map((c) => c.float);\n return Math.min.apply(\n null,\n floats.map((f) => f.getOrder()),\n );\n }\n\n shouldBeStashedBefore(float: PageFloat): boolean {\n return this.getOrder() < float.getOrder();\n }\n\n addContinuations(continuations: PageFloatContinuation[]) {\n continuations.forEach((c) => {\n this.continuations.push(c);\n });\n }\n\n getFlowName(): string {\n const flowName = this.continuations[0].float.flowName;\n Asserts.assert(\n this.continuations.every((c) => c.float.flowName === flowName),\n );\n return flowName;\n }\n}\n\nexport class PageFloatContinuation implements PageFloats.PageFloatContinuation {\n constructor(\n public readonly float: PageFloat,\n public readonly nodePosition: Vtree.NodePosition,\n ) {}\n\n equals(other: PageFloatContinuation | null): boolean {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n return (\n this.float === other.float &&\n VtreeImpl.isSameNodePosition(this.nodePosition, other.nodePosition)\n );\n }\n}\n\nexport type PageFloatPlacementCondition = PageFloats.PageFloatPlacementCondition;\n\n/**\n * @param generatingNodePosition Source NodePosition generating the context.\n * Specify when a column context is generated by a non-root element (for\n * example page floats)\n */\nexport class PageFloatLayoutContext\n implements PageFloats.PageFloatLayoutContext {\n private children: PageFloatLayoutContext[] = [];\n writingMode: Css.Val;\n direction: Css.Val;\n private invalidated: boolean = false;\n private floatStore: PageFloatStore;\n private forbiddenFloats: PageFloatID[] = [];\n floatFragments: PageFloatFragment[] = [];\n private stashedFloatFragments: PageFloatFragment[] = [];\n private floatAnchors: { [key in PageFloatID]: Node } = {};\n private floatsDeferredToNext: PageFloatContinuation[] = [];\n private floatsDeferredFromPrevious: PageFloatContinuation[];\n private layoutConstraints: LayoutType.LayoutConstraint[] = [];\n private locked: boolean = false;\n\n constructor(\n public readonly parent: PageFloatLayoutContext,\n private readonly floatReference: FloatReference | null,\n private container: Vtree.Container,\n public readonly flowName: string | null,\n public readonly generatingNodePosition: Vtree.NodePosition | null,\n writingMode: Css.Val | null,\n direction: Css.Val | null,\n ) {\n if (parent) {\n parent.children.push(this);\n }\n this.writingMode =\n writingMode || (parent && parent.writingMode) || Css.ident.horizontal_tb;\n this.direction = direction || (parent && parent.direction) || Css.ident.ltr;\n this.floatStore = parent ? parent.floatStore : new PageFloatStore();\n const previousSibling = this.getPreviousSibling();\n this.floatsDeferredFromPrevious = previousSibling\n ? [].concat(previousSibling.floatsDeferredToNext)\n : [];\n }\n\n private getParent(floatReference: FloatReference): PageFloatLayoutContext {\n if (!this.parent) {\n throw new Error(`No PageFloatLayoutContext for ${floatReference}`);\n }\n return this.parent;\n }\n\n private getPreviousSiblingOf(\n child: PageFloatLayoutContext | null,\n floatReference: FloatReference | null,\n flowName: string | null,\n generatingNodePosition: Vtree.NodePosition | null,\n ): PageFloatLayoutContext | null {\n let index = this.children.indexOf(child as PageFloatLayoutContext);\n if (index < 0) {\n index = this.children.length;\n }\n for (let i = index - 1; i >= 0; i--) {\n let result = this.children[i];\n if (\n result.floatReference === floatReference &&\n result.flowName === flowName &&\n VtreeImpl.isSameNodePosition(\n result.generatingNodePosition,\n generatingNodePosition,\n )\n ) {\n return result;\n } else {\n result = result.getPreviousSiblingOf(\n null,\n floatReference,\n flowName,\n generatingNodePosition,\n );\n if (result) {\n return result;\n }\n }\n }\n return null;\n }\n\n private getPreviousSibling(): PageFloatLayoutContext | null {\n let child: PageFloatLayoutContext = this;\n let parent = this.parent;\n let result: PageFloatLayoutContext;\n while (parent) {\n result = parent.getPreviousSiblingOf(\n child,\n this.floatReference,\n this.flowName,\n this.generatingNodePosition,\n );\n if (result) {\n return result;\n }\n child = parent;\n parent = parent.parent;\n }\n return null;\n }\n\n getContainer(floatReference?: FloatReference): Vtree.Container {\n if (!floatReference || floatReference === this.floatReference) {\n return this.container;\n }\n return this.getParent(floatReference).getContainer(floatReference);\n }\n\n setContainer(container: Vtree.Container) {\n this.container = container;\n this.reattachFloatFragments();\n }\n\n addPageFloat(float: PageFloat) {\n this.floatStore.addPageFloat(float);\n }\n\n getPageFloatLayoutContext(\n floatReference: FloatReference,\n ): PageFloatLayoutContext {\n if (floatReference === this.floatReference) {\n return this;\n }\n return this.getParent(floatReference).getPageFloatLayoutContext(\n floatReference,\n );\n }\n\n findPageFloatByNodePosition(\n nodePosition: Vtree.NodePosition,\n ): PageFloat | null {\n return this.floatStore.findPageFloatByNodePosition(nodePosition);\n }\n\n private forbid(float: PageFloat) {\n const id = float.getId();\n const floatReference = float.floatReference;\n if (floatReference === this.floatReference) {\n if (!this.forbiddenFloats.includes(id)) {\n this.forbiddenFloats.push(id);\n const strategy = new PageFloatLayoutStrategyResolver().findByFloat(\n float,\n );\n strategy.forbid(float, this);\n }\n } else {\n const parent = this.getParent(floatReference);\n parent.forbid(float);\n }\n }\n\n isForbidden(float: PageFloat): boolean {\n const id = float.getId();\n const floatReference = float.floatReference;\n if (floatReference === this.floatReference) {\n return this.forbiddenFloats.includes(id);\n } else {\n const parent = this.getParent(floatReference);\n return parent.isForbidden(float);\n }\n }\n\n addPageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ) {\n const floatReference = floatFragment.floatReference;\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n parent.addPageFloatFragment(floatFragment, dontInvalidate);\n } else if (!this.floatFragments.includes(floatFragment)) {\n this.floatFragments.push(floatFragment);\n this.floatFragments.sort((fr1, fr2) => fr1.getOrder() - fr2.getOrder());\n }\n if (!dontInvalidate) {\n this.invalidate();\n }\n }\n\n removePageFloatFragment(\n floatFragment: PageFloatFragment,\n dontInvalidate?: boolean,\n ) {\n const floatReference = floatFragment.floatReference;\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n parent.removePageFloatFragment(floatFragment, dontInvalidate);\n } else {\n const index = this.floatFragments.indexOf(floatFragment);\n if (index >= 0) {\n const fragment = this.floatFragments.splice(index, 1)[0];\n const element = fragment.area && fragment.area.element;\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n if (!dontInvalidate) {\n this.invalidate();\n }\n }\n }\n }\n\n findPageFloatFragment(float: PageFloat): PageFloatFragment | null {\n if (float.floatReference !== this.floatReference) {\n const parent = this.getParent(float.floatReference);\n return parent.findPageFloatFragment(float);\n }\n const index = this.floatFragments.findIndex((f) => f.hasFloat(float));\n if (index >= 0) {\n return this.floatFragments[index];\n } else {\n return null;\n }\n }\n\n hasFloatFragments(condition?: (p1: PageFloatFragment) => boolean): boolean {\n if (this.floatFragments.length > 0) {\n if (!condition || this.floatFragments.some(condition)) {\n return true;\n }\n }\n if (this.parent) {\n return this.parent.hasFloatFragments(condition);\n } else {\n return false;\n }\n }\n\n hasContinuingFloatFragmentsInFlow(flowName: string): boolean {\n return this.hasFloatFragments(\n (fragment) => fragment.continues && fragment.getFlowName() === flowName,\n );\n }\n\n registerPageFloatAnchor(float: PageFloat, anchorViewNode: Node) {\n this.floatAnchors[float.getId()] = anchorViewNode;\n }\n\n collectPageFloatAnchors() {\n const anchors = Object.assign({}, this.floatAnchors);\n return this.children.reduce(\n (prev, child) => Object.assign(prev, child.collectPageFloatAnchors()),\n anchors,\n );\n }\n\n isAnchorAlreadyAppeared(floatId: PageFloatID) {\n const deferredFloats = this.getDeferredPageFloatContinuations();\n if (deferredFloats.some((cont) => cont.float.getId() === floatId)) {\n return true;\n }\n const floatAnchors = this.collectPageFloatAnchors();\n const anchorViewNode = floatAnchors[floatId];\n if (!anchorViewNode) {\n return false;\n }\n if (this.container && this.container.element) {\n return this.container.element.contains(anchorViewNode);\n }\n return false;\n }\n\n deferPageFloat(continuation: PageFloatContinuation) {\n const float = continuation.float;\n if (float.floatReference === this.floatReference) {\n const index = this.floatsDeferredToNext.findIndex(\n (c) => c.float === float,\n );\n if (index >= 0) {\n this.floatsDeferredToNext.splice(index, 1, continuation);\n } else {\n this.floatsDeferredToNext.push(continuation);\n }\n } else {\n const parent = this.getParent(float.floatReference);\n parent.deferPageFloat(continuation);\n }\n }\n\n hasPrecedingFloatsDeferredToNext(\n float: PageFloat,\n ignoreReference?: boolean,\n ): boolean {\n if (!ignoreReference && float.floatReference !== this.floatReference) {\n return this.getParent(\n float.floatReference,\n ).hasPrecedingFloatsDeferredToNext(float, false);\n }\n const order = float.getOrder();\n const hasPrecedingFloatsDeferredToNext = this.floatsDeferredToNext.some(\n (c) => c.float.getOrder() < order && !float.isAllowedToPrecede(c.float),\n );\n if (hasPrecedingFloatsDeferredToNext) {\n return true;\n } else if (this.parent) {\n return this.parent.hasPrecedingFloatsDeferredToNext(float, true);\n } else {\n return false;\n }\n }\n\n getLastFollowingFloatInFragments(float: PageFloat): PageFloat | null {\n const order = float.getOrder();\n let lastFollowing: PageFloat = null;\n this.floatFragments.forEach((fragment) => {\n fragment.continuations.forEach((c) => {\n const f = c.float;\n const o = f.getOrder();\n if (o > order && (!lastFollowing || o > lastFollowing.getOrder())) {\n lastFollowing = f;\n }\n });\n });\n if (this.parent) {\n const lastFollowingOfParent = this.parent.getLastFollowingFloatInFragments(\n float,\n );\n if (\n lastFollowingOfParent &&\n (!lastFollowing ||\n lastFollowingOfParent.getOrder() > lastFollowing.getOrder())\n ) {\n lastFollowing = lastFollowingOfParent;\n }\n }\n return lastFollowing;\n }\n\n getDeferredPageFloatContinuations(\n flowName?: string | null,\n ): PageFloatContinuation[] {\n flowName = flowName || this.flowName;\n let result = this.floatsDeferredFromPrevious.filter(\n (cont) => !flowName || cont.float.flowName === flowName,\n );\n if (this.parent) {\n result = this.parent\n .getDeferredPageFloatContinuations(flowName)\n .concat(result);\n }\n return result.sort((c1, c2) => c1.float.getOrder() - c2.float.getOrder());\n }\n\n getPageFloatContinuationsDeferredToNext(\n flowName?: string | null,\n ): PageFloatContinuation[] {\n flowName = flowName || this.flowName;\n const result = this.floatsDeferredToNext.filter(\n (cont) => !flowName || cont.float.flowName === flowName,\n );\n if (this.parent) {\n return this.parent\n .getPageFloatContinuationsDeferredToNext(flowName)\n .concat(result);\n } else {\n return result;\n }\n }\n\n getFloatsDeferredToNextInChildContexts(): PageFloat[] {\n let result = [];\n const done = [];\n for (let i = this.children.length - 1; i >= 0; i--) {\n const child = this.children[i];\n if (done.includes(child.flowName)) {\n continue;\n }\n done.push(child.flowName);\n result = result.concat(child.floatsDeferredToNext.map((c) => c.float));\n result = result.concat(child.getFloatsDeferredToNextInChildContexts());\n }\n return result;\n }\n\n checkAndForbidNotAllowedFloat(): boolean {\n if (this.checkAndForbidFloatFollowingDeferredFloat()) {\n return true;\n }\n for (let i = this.floatFragments.length - 1; i >= 0; i--) {\n const fragment = this.floatFragments[i];\n const notAllowedFloat = fragment.findNotAllowedFloat(this);\n if (notAllowedFloat) {\n if (this.locked) {\n this.invalidate();\n } else {\n this.removePageFloatFragment(fragment);\n this.forbid(notAllowedFloat);\n\n // If the removed float is a block-end/inline-end float,\n // we should re-layout preceding floats with the same float direction.\n this.removeEndFloatFragments(fragment.floatSide);\n }\n return true;\n }\n }\n if (this.floatReference === FloatReference.REGION && this.parent.locked) {\n return this.parent.checkAndForbidNotAllowedFloat();\n }\n return false;\n }\n\n checkAndForbidFloatFollowingDeferredFloat(): boolean {\n const deferredFloats = this.getFloatsDeferredToNextInChildContexts();\n const floatsInFragments = this.floatFragments.reduce(\n (r, fr) => r.concat(fr.continuations.map((c) => c.float)),\n [],\n );\n floatsInFragments.sort((f1, f2) => f2.getOrder() - f1.getOrder());\n for (const float of floatsInFragments) {\n const order = float.getOrder();\n if (\n deferredFloats.some(\n (d) => !float.isAllowedToPrecede(d) && order > d.getOrder(),\n )\n ) {\n if (this.locked) {\n this.invalidate();\n } else {\n this.forbid(float);\n const fragment = this.findPageFloatFragment(float);\n Asserts.assert(fragment);\n this.removePageFloatFragment(fragment);\n }\n return true;\n }\n }\n return false;\n }\n\n finish() {\n if (this.checkAndForbidNotAllowedFloat()) {\n return;\n }\n for (let i = this.floatsDeferredToNext.length - 1; i >= 0; i--) {\n const continuation = this.floatsDeferredToNext[i];\n if (!continuation.float.isAllowedOnContext(this)) {\n if (this.locked) {\n this.invalidate();\n return;\n }\n this.floatsDeferredToNext.splice(i, 1);\n }\n }\n this.floatsDeferredFromPrevious.forEach((continuation) => {\n if (\n this.floatsDeferredToNext.findIndex((c) => continuation.equals(c)) >= 0\n ) {\n return;\n }\n if (this.floatFragments.some((f) => f.hasFloat(continuation.float))) {\n return;\n }\n this.floatsDeferredToNext.push(continuation);\n });\n }\n\n hasSameContainerAs(other: PageFloatLayoutContext): boolean {\n return (\n !!this.container &&\n !!other.container &&\n this.container.element === other.container.element\n );\n }\n\n invalidate() {\n this.invalidated = true;\n if (this.locked) {\n return;\n }\n if (this.container) {\n this.children.forEach((child) => {\n // Since the same container element is shared by a region page float\n // layout context and a column page float layout context in a single\n // column region, view elements of float fragments of the child (column)\n // context need to be removed here.\n if (this.hasSameContainerAs(child)) {\n child.floatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n }\n });\n this.container.clear();\n }\n this.children.forEach((child) => {\n child.layoutConstraints.splice(0);\n });\n this.children.splice(0);\n Object.keys(this.floatAnchors).forEach((k) => {\n delete this.floatAnchors[k];\n });\n }\n\n detachChildren(): PageFloatLayoutContext[] {\n const children = this.children.splice(0);\n children.forEach((child) => {\n child.floatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n });\n return children;\n }\n\n attachChildren(children: PageFloatLayoutContext[]) {\n children.forEach((child) => {\n this.children.push(child);\n child.reattachFloatFragments();\n });\n }\n\n isInvalidated() {\n return this.invalidated || (!!this.parent && this.parent.isInvalidated());\n }\n\n validate() {\n this.invalidated = false;\n }\n\n private toLogical(side: string): string {\n const writingMode = this.writingMode.toString();\n const direction = this.direction.toString();\n return CssLogicalUtil.toLogical(side, writingMode, direction);\n }\n\n private toPhysical(side: string): string {\n const writingMode = this.writingMode.toString();\n const direction = this.direction.toString();\n return CssLogicalUtil.toPhysical(side, writingMode, direction);\n }\n\n removeEndFloatFragments(floatSide: string) {\n const logicalFloatSide = this.toLogical(floatSide);\n if (logicalFloatSide === \"block-end\" || logicalFloatSide === \"inline-end\") {\n let i = 0;\n while (i < this.floatFragments.length) {\n const fragment = this.floatFragments[i];\n const logicalFloatSide2 = this.toLogical(fragment.floatSide);\n if (logicalFloatSide2 === logicalFloatSide) {\n this.removePageFloatFragment(fragment);\n } else {\n i++;\n }\n }\n }\n }\n\n stashEndFloatFragments(float: PageFloat) {\n const floatReference = float.floatReference;\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).stashEndFloatFragments(float);\n return;\n }\n const logicalFloatSide = this.toLogical(float.floatSide);\n if (\n logicalFloatSide === \"block-end\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n let i = 0;\n while (i < this.floatFragments.length) {\n const fragment = this.floatFragments[i];\n const fragmentFloatSide = this.toLogical(fragment.floatSide);\n if (\n (fragmentFloatSide === logicalFloatSide ||\n (logicalFloatSide === \"snap-block\" &&\n fragmentFloatSide === \"block-end\")) &&\n fragment.shouldBeStashedBefore(float)\n ) {\n this.stashedFloatFragments.push(fragment);\n this.floatFragments.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n }\n\n restoreStashedFragments(floatReference: FloatReference) {\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).restoreStashedFragments(floatReference);\n return;\n }\n this.stashedFloatFragments.forEach((stashed) => {\n this.addPageFloatFragment(stashed, true);\n });\n this.stashedFloatFragments.splice(0);\n }\n\n discardStashedFragments(floatReference: FloatReference) {\n if (floatReference !== this.floatReference) {\n this.getParent(floatReference).discardStashedFragments(floatReference);\n return;\n }\n this.stashedFloatFragments.splice(0);\n }\n\n getStashedFloatFragments(\n floatReference: FloatReference,\n ): PageFloatFragment[] {\n if (floatReference === this.floatReference) {\n return this.stashedFloatFragments\n .concat()\n .sort((fr1, fr2) => fr2.getOrder() - fr1.getOrder()); // return in reverse order\n } else {\n return this.getParent(floatReference).getStashedFloatFragments(\n floatReference,\n );\n }\n }\n\n private getLimitValue(\n side: string,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): number {\n Asserts.assert(this.container);\n const logicalSide = this.toLogical(side);\n const physicalSide = this.toPhysical(side);\n const limit = this.getLimitValueInner(\n logicalSide,\n layoutContext,\n clientLayout,\n condition,\n );\n if (this.parent && this.parent.container) {\n const parentLimit = this.parent.getLimitValue(\n physicalSide,\n layoutContext,\n clientLayout,\n condition,\n );\n switch (physicalSide) {\n case \"top\":\n return Math.max(limit, parentLimit);\n case \"left\":\n return Math.max(limit, parentLimit);\n case \"bottom\":\n return Math.min(limit, parentLimit);\n case \"right\":\n return Math.min(limit, parentLimit);\n default:\n Asserts.fail(\"Should be unreachable\");\n }\n }\n return limit;\n }\n\n private getLimitValueInner(\n logicalSide: string,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): number {\n Asserts.assert(this.container);\n const limits = this.getLimitValuesInner(\n layoutContext,\n clientLayout,\n condition,\n );\n switch (logicalSide) {\n case \"block-start\":\n return this.container.vertical ? limits.right : limits.top;\n case \"block-end\":\n return this.container.vertical ? limits.left : limits.bottom;\n case \"inline-start\":\n return this.container.vertical ? limits.top : limits.left;\n case \"inline-end\":\n return this.container.vertical ? limits.bottom : limits.right;\n default:\n throw new Error(`Unknown logical side: ${logicalSide}`);\n }\n }\n\n private getLimitValuesInner(\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n condition?: (p1: PageFloatFragment, p2: PageFloatLayoutContext) => boolean,\n ): {\n top: number;\n left: number;\n bottom: number;\n right: number;\n floatMinWrapBlockStart: number;\n floatMinWrapBlockEnd: number;\n } {\n Asserts.assert(this.container);\n const offsetX = this.container.originX;\n const offsetY = this.container.originY;\n const paddingRect = this.container.getPaddingRect();\n let limits = {\n top: paddingRect.y1 - offsetY,\n left: paddingRect.x1 - offsetX,\n bottom: paddingRect.y2 - offsetY,\n right: paddingRect.x2 - offsetX,\n floatMinWrapBlockStart: 0,\n floatMinWrapBlockEnd: 0,\n };\n\n function resolveLengthPercentage(numeric, viewNode, containerLength) {\n if (numeric.unit === \"%\") {\n return (containerLength * numeric.num) / 100;\n } else {\n return layoutContext.convertLengthToPx(numeric, viewNode, clientLayout);\n }\n }\n const fragments = this.floatFragments;\n if (fragments.length > 0) {\n limits = fragments.reduce((l, f) => {\n if (condition && !condition(f, this)) {\n return l;\n }\n const logicalFloatSide = this.toLogical(f.floatSide);\n const area = f.area;\n const floatMinWrapBlock = f.continuations[0].float.floatMinWrapBlock;\n let top = l.top;\n let left = l.left;\n let bottom = l.bottom;\n let right = l.right;\n let floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n let floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n switch (logicalFloatSide) {\n case \"inline-start\":\n if (area.vertical) {\n top = Math.max(top, area.top + area.height);\n } else {\n left = Math.max(left, area.left + area.width);\n }\n break;\n case \"block-start\":\n if (area.vertical) {\n if (floatMinWrapBlock && area.left < right) {\n floatMinWrapBlockStart = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.x2 - paddingRect.x1,\n ) as number;\n }\n right = Math.min(right, area.left);\n } else {\n if (floatMinWrapBlock && area.top + area.height > top) {\n floatMinWrapBlockStart = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.y2 - paddingRect.y1,\n ) as number;\n }\n top = Math.max(top, area.top + area.height);\n }\n break;\n case \"inline-end\":\n if (area.vertical) {\n bottom = Math.min(bottom, area.top);\n } else {\n right = Math.min(right, area.left);\n }\n break;\n case \"block-end\":\n if (area.vertical) {\n if (floatMinWrapBlock && area.left + area.width > left) {\n floatMinWrapBlockEnd = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.x2 - paddingRect.x1,\n ) as number;\n }\n left = Math.max(left, area.left + area.width);\n } else {\n if (floatMinWrapBlock && area.top < bottom) {\n floatMinWrapBlockEnd = resolveLengthPercentage(\n floatMinWrapBlock,\n (area as any).rootViewNodes[0],\n paddingRect.y2 - paddingRect.y1,\n ) as number;\n }\n bottom = Math.min(bottom, area.top);\n }\n break;\n default:\n throw new Error(`Unknown logical float side: ${logicalFloatSide}`);\n }\n return {\n top,\n left,\n bottom,\n right,\n floatMinWrapBlockStart,\n floatMinWrapBlockEnd,\n };\n }, limits);\n }\n limits.left += offsetX;\n limits.right += offsetX;\n limits.top += offsetY;\n limits.bottom += offsetY;\n return limits;\n }\n\n /**\n * @param anchorEdge Null indicates that the anchor is not in the current\n * container.\n * @return Logical float side (snap-block is resolved when init=false). Null\n * indicates that the float area does not fit inside the container\n */\n setFloatAreaDimensions(\n area: LayoutType.PageFloatArea,\n floatReference: FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n init: boolean,\n force: boolean,\n condition: PageFloatPlacementCondition,\n ): string | null {\n if (floatReference !== this.floatReference) {\n const parent = this.getParent(floatReference);\n return parent.setFloatAreaDimensions(\n area,\n floatReference,\n floatSide,\n anchorEdge,\n init,\n force,\n condition,\n );\n }\n let logicalFloatSide = this.toLogical(floatSide);\n if (logicalFloatSide === \"snap-block\") {\n if (!condition[\"block-start\"] && !condition[\"block-end\"]) {\n return null;\n }\n } else {\n if (!condition[logicalFloatSide]) {\n return null;\n }\n }\n Asserts.assert(area.clientLayout);\n let blockStart = this.getLimitValue(\n \"block-start\",\n area.layoutContext,\n area.clientLayout,\n );\n let blockEnd = this.getLimitValue(\n \"block-end\",\n area.layoutContext,\n area.clientLayout,\n );\n let inlineStart = this.getLimitValue(\n \"inline-start\",\n area.layoutContext,\n area.clientLayout,\n );\n let inlineEnd = this.getLimitValue(\n \"inline-end\",\n area.layoutContext,\n area.clientLayout,\n );\n const blockOffset = area.vertical ? area.originX : area.originY;\n const inlineOffset = area.vertical ? area.originY : area.originX;\n blockStart = area.vertical\n ? Math.min(\n blockStart,\n area.left +\n area.getInsetLeft() +\n area.width +\n area.getInsetRight() +\n blockOffset,\n )\n : Math.max(blockStart, area.top + blockOffset);\n blockEnd = area.vertical\n ? Math.max(blockEnd, area.left + blockOffset)\n : Math.min(\n blockEnd,\n area.top +\n area.getInsetTop() +\n area.height +\n area.getInsetBottom() +\n blockOffset,\n );\n\n function limitBlockStartEndValueWithOpenRect(getRect, rect) {\n let openRect = getRect(area.bands, rect);\n if (openRect) {\n if (area.vertical) {\n openRect = GeometryUtil.unrotateBox(openRect);\n }\n blockStart = area.vertical\n ? Math.min(blockStart, openRect.x2)\n : Math.max(blockStart, openRect.y1);\n blockEnd = area.vertical\n ? Math.max(blockEnd, openRect.x1)\n : Math.min(blockEnd, openRect.y2);\n return true;\n } else {\n return force;\n }\n }\n let blockSize: number;\n let inlineSize: number;\n let outerBlockSize: number;\n let outerInlineSize: number;\n if (init) {\n const rect = area.vertical\n ? GeometryUtil.rotateBox(\n new GeometryUtil.Rect(blockEnd, inlineStart, blockStart, inlineEnd),\n )\n : new GeometryUtil.Rect(inlineStart, blockStart, inlineEnd, blockEnd);\n if (\n logicalFloatSide === \"block-start\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-start\"\n ) {\n if (\n !limitBlockStartEndValueWithOpenRect(\n GeometryUtil.findUppermostFullyOpenRect,\n rect,\n )\n ) {\n return null;\n }\n }\n if (\n logicalFloatSide === \"block-end\" ||\n logicalFloatSide === \"snap-block\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n if (\n !limitBlockStartEndValueWithOpenRect(\n GeometryUtil.findBottommostFullyOpenRect,\n rect,\n )\n ) {\n return null;\n }\n }\n outerBlockSize = (blockEnd - blockStart) * area.getBoxDir();\n blockSize = outerBlockSize - area.getInsetBefore() - area.getInsetAfter();\n outerInlineSize = inlineEnd - inlineStart;\n inlineSize = outerInlineSize - area.getInsetStart() - area.getInsetEnd();\n if (!force && (blockSize <= 0 || inlineSize <= 0)) {\n return null;\n }\n } else {\n blockSize = area.computedBlockSize;\n outerBlockSize = blockSize + area.getInsetBefore() + area.getInsetAfter();\n const availableBlockSize = (blockEnd - blockStart) * area.getBoxDir();\n if (logicalFloatSide === \"snap-block\") {\n if (anchorEdge === null) {\n // Deferred from previous container\n logicalFloatSide = \"block-start\";\n } else {\n const containerRect = this.container.getPaddingRect();\n const fromStart =\n this.container.getBoxDir() *\n (anchorEdge -\n (this.container.vertical ? containerRect.x2 : containerRect.y1));\n const fromEnd =\n this.container.getBoxDir() *\n ((this.container.vertical ? containerRect.x1 : containerRect.y2) -\n anchorEdge -\n outerBlockSize);\n if (fromStart <= fromEnd) {\n logicalFloatSide = \"block-start\";\n } else {\n logicalFloatSide = \"block-end\";\n }\n }\n if (!condition[logicalFloatSide]) {\n if (condition[\"block-end\"]) {\n logicalFloatSide = \"block-end\";\n } else {\n return null;\n }\n }\n }\n if (!force && availableBlockSize < outerBlockSize) {\n return null;\n }\n if (\n logicalFloatSide === \"inline-start\" ||\n logicalFloatSide === \"inline-end\"\n ) {\n inlineSize = Sizing.getSize(area.clientLayout, area.element, [\n Sizing.Size.FIT_CONTENT_INLINE_SIZE,\n ])[Sizing.Size.FIT_CONTENT_INLINE_SIZE];\n } else if (area.adjustContentRelativeSize) {\n inlineSize = area.getContentInlineSize();\n } else {\n inlineSize = area.vertical ? area.height : area.width;\n }\n outerInlineSize = inlineSize + area.getInsetStart() + area.getInsetEnd();\n const availableInlineSize = inlineEnd - inlineStart;\n if (!force && availableInlineSize < outerInlineSize) {\n return null;\n }\n }\n blockStart -= blockOffset;\n blockEnd -= blockOffset;\n inlineStart -= inlineOffset;\n inlineEnd -= inlineOffset;\n switch (logicalFloatSide) {\n case \"inline-start\":\n case \"block-start\":\n case \"snap-block\":\n area.setInlinePosition(inlineStart, inlineSize);\n area.setBlockPosition(blockStart, blockSize);\n break;\n case \"inline-end\":\n case \"block-end\":\n area.setInlinePosition(inlineEnd - outerInlineSize, inlineSize);\n area.setBlockPosition(\n blockEnd - outerBlockSize * area.getBoxDir(),\n blockSize,\n );\n break;\n default:\n throw new Error(`unknown float direction: ${floatSide}`);\n }\n return logicalFloatSide;\n }\n\n getFloatFragmentExclusions(): GeometryUtil.Shape[] {\n const result = this.floatFragments.map((fragment) =>\n fragment.getOuterShape(),\n );\n if (this.parent) {\n return this.parent.getFloatFragmentExclusions().concat(result);\n } else {\n return result;\n }\n }\n\n private reattachFloatFragments() {\n const parent = this.container.element && this.container.element.parentNode;\n if (parent) {\n this.floatFragments.forEach((fragment) => {\n parent.appendChild(fragment.area.element);\n });\n }\n }\n\n getMaxReachedAfterEdge(): number {\n const isVertical = this.getContainer().vertical;\n return this.floatFragments.reduce(\n (edge, fragment) => {\n const rect = fragment.getOuterRect();\n if (isVertical) {\n return Math.min(edge, rect.x1);\n } else {\n return Math.max(edge, rect.y2);\n }\n },\n isVertical ? Infinity : 0,\n );\n }\n\n getBlockStartEdgeOfBlockEndFloats(): number {\n const isVertical = this.getContainer().vertical;\n return this.floatFragments\n .filter((fragment) => fragment.floatSide === \"block-end\")\n .reduce(\n (edge, fragment) => {\n const rect = fragment.getOuterRect();\n if (isVertical) {\n return Math.max(edge, rect.x2);\n } else {\n return Math.min(edge, rect.y1);\n }\n },\n isVertical ? 0 : Infinity,\n );\n }\n\n getPageFloatClearEdge(clear: string, column: LayoutType.Column): number {\n function isContinuationOfAlreadyAppearedFloat(context) {\n return (continuation) =>\n context.isAnchorAlreadyAppeared(continuation.float.getId());\n }\n\n function isFragmentWithAlreadyAppearedFloat(fragment, context) {\n return fragment.continuations.some(\n isContinuationOfAlreadyAppearedFloat(context),\n );\n }\n const columnRect = column.getPaddingRect();\n const columnBlockEnd = column.vertical ? columnRect.x1 : columnRect.y2;\n let context: PageFloatLayoutContext = this;\n while (context) {\n if (\n context.floatsDeferredToNext.some(\n isContinuationOfAlreadyAppearedFloat(context),\n )\n ) {\n return columnBlockEnd;\n }\n context = context.parent;\n }\n Asserts.assert(column.clientLayout);\n const blockStartLimit = this.getLimitValue(\n \"block-start\",\n column.layoutContext,\n column.clientLayout,\n isFragmentWithAlreadyAppearedFloat,\n );\n const blockEndLimit = this.getLimitValue(\n \"block-end\",\n column.layoutContext,\n column.clientLayout,\n isFragmentWithAlreadyAppearedFloat,\n );\n if (\n blockEndLimit * column.getBoxDir() <\n columnBlockEnd * column.getBoxDir()\n ) {\n return columnBlockEnd;\n } else {\n return blockStartLimit;\n }\n }\n\n getPageFloatPlacementCondition(\n float: PageFloat,\n floatSide: string,\n clearSide: string | null,\n ): PageFloatPlacementCondition {\n if (float.floatReference !== this.floatReference) {\n const parent = this.getParent(float.floatReference);\n return parent.getPageFloatPlacementCondition(float, floatSide, clearSide);\n }\n const result: PageFloatPlacementCondition = {\n \"block-start\": true,\n \"block-end\": true,\n \"inline-start\": true,\n \"inline-end\": true,\n };\n if (!clearSide) {\n return result;\n }\n const logicalFloatSide = this.toLogical(floatSide);\n const logicalClearSide = this.toLogical(clearSide);\n let logicalSides: string[];\n if (logicalClearSide === \"all\") {\n logicalSides = [\"block-start\", \"block-end\", \"inline-start\", \"inline-end\"];\n } else if (logicalClearSide === \"both\") {\n logicalSides = [\"inline-start\", \"inline-end\"];\n } else if (logicalClearSide === \"same\") {\n if (logicalFloatSide === \"snap-block\") {\n logicalSides = [\"block-start\", \"block-end\"];\n } else {\n logicalSides = [logicalFloatSide];\n }\n } else {\n logicalSides = [logicalClearSide];\n }\n const floatOrder = float.getOrder();\n\n function isPrecedingFragment(\n side: string,\n ): (p1: PageFloatFragment) => boolean {\n return (fragment) =>\n fragment.floatSide === side && fragment.getOrder() < floatOrder;\n }\n\n function hasPrecedingFragmentInChildren(\n context: PageFloatLayoutContext,\n side: string,\n ): boolean {\n return context.children.some(\n (child) =>\n child.floatFragments.some(isPrecedingFragment(side)) ||\n hasPrecedingFragmentInChildren(child, side),\n );\n }\n\n function hasPrecedingFragmentInParents(\n context: PageFloatLayoutContext,\n side: string,\n ): boolean {\n const parent = context.parent;\n return (\n !!parent &&\n (parent.floatFragments.some(isPrecedingFragment(side)) ||\n hasPrecedingFragmentInParents(parent, side))\n );\n }\n logicalSides.forEach((side) => {\n switch (side) {\n case \"block-start\":\n case \"inline-start\":\n result[side] = !hasPrecedingFragmentInChildren(this, side);\n break;\n case \"block-end\":\n case \"inline-end\":\n result[side] = !hasPrecedingFragmentInParents(this, side);\n break;\n default:\n throw new Error(`Unexpected side: ${side}`);\n }\n });\n return result;\n }\n\n getLayoutConstraints(): LayoutType.LayoutConstraint[] {\n const constraints = this.parent ? this.parent.getLayoutConstraints() : [];\n return constraints.concat(this.layoutConstraints);\n }\n\n addLayoutConstraint(\n layoutConstraint: LayoutType.LayoutConstraint,\n floatReference: FloatReference,\n ) {\n if (floatReference === this.floatReference) {\n this.layoutConstraints.push(layoutConstraint);\n } else {\n this.getParent(floatReference).addLayoutConstraint(\n layoutConstraint,\n floatReference,\n );\n }\n }\n\n isColumnFullWithPageFloats(column: LayoutType.Column): boolean {\n const layoutContext = column.layoutContext;\n const clientLayout = column.clientLayout;\n Asserts.assert(clientLayout);\n let context: PageFloatLayoutContext = this;\n let limits: {\n top: number;\n left: number;\n bottom: number;\n right: number;\n floatMinWrapBlockStart: number;\n floatMinWrapBlockEnd: number;\n } = null;\n while (context && context.container) {\n const l = context.getLimitValuesInner(layoutContext, clientLayout);\n if (limits) {\n if (column.vertical) {\n if (l.right < limits.right) {\n limits.right = l.right;\n limits.floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n }\n if (l.left > limits.left) {\n limits.left = l.left;\n limits.floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n }\n } else {\n if (l.top > limits.top) {\n limits.top = l.top;\n limits.floatMinWrapBlockStart = l.floatMinWrapBlockStart;\n }\n if (l.bottom < limits.bottom) {\n limits.bottom = l.bottom;\n limits.floatMinWrapBlockEnd = l.floatMinWrapBlockEnd;\n }\n }\n } else {\n limits = l;\n }\n context = context.parent;\n }\n const floatMinWrapBlock = Math.max(\n limits.floatMinWrapBlockStart,\n limits.floatMinWrapBlockEnd,\n );\n const blockSpace = column.vertical\n ? limits.right - limits.left\n : limits.bottom - limits.top;\n return blockSpace <= floatMinWrapBlock;\n }\n\n getMaxBlockSizeOfPageFloats(): number {\n const isVertical = this.getContainer().vertical;\n if (!this.floatFragments.length) {\n return 0;\n }\n return Math.max.apply(\n null,\n this.floatFragments.map((fragment) => {\n const area = fragment.area;\n if (isVertical) {\n return area.width;\n } else {\n return area.height;\n }\n }),\n );\n }\n\n lock() {\n this.locked = true;\n }\n\n unlock() {\n this.locked = false;\n }\n\n isLocked(): boolean {\n return this.locked;\n }\n}\n\nexport interface PageFloatLayoutStrategy\n extends PageFloats.PageFloatLayoutStrategy {}\n\nconst pageFloatLayoutStrategies: PageFloatLayoutStrategy[] = [];\n\nexport class PageFloatLayoutStrategyResolver {\n static register(strategy: PageFloatLayoutStrategy) {\n pageFloatLayoutStrategies.push(strategy);\n }\n\n findByNodeContext(nodeContext: Vtree.NodeContext): PageFloatLayoutStrategy {\n for (let i = pageFloatLayoutStrategies.length - 1; i >= 0; i--) {\n const strategy = pageFloatLayoutStrategies[i];\n if (strategy.appliesToNodeContext(nodeContext)) {\n return strategy;\n }\n }\n throw new Error(`No PageFloatLayoutStrategy found for ${nodeContext}`);\n }\n\n findByFloat(float: PageFloat): PageFloatLayoutStrategy {\n for (let i = pageFloatLayoutStrategies.length - 1; i >= 0; i--) {\n const strategy = pageFloatLayoutStrategies[i];\n if (strategy.appliesToFloat(float)) {\n return strategy;\n }\n }\n throw new Error(`No PageFloatLayoutStrategy found for ${float}`);\n }\n}\n\nexport class NormalPageFloatLayoutStrategy implements PageFloatLayoutStrategy {\n /**\n * @override\n */\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return isPageFloat(nodeContext.floatReference);\n }\n\n /**\n * @override\n */\n appliesToFloat(float: PageFloat): boolean {\n return true;\n }\n\n /**\n * @override\n */\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloatLayoutContext,\n column: LayoutType.Column,\n ): Task.Result<PageFloat> {\n let floatReference = nodeContext.floatReference;\n Asserts.assert(nodeContext.floatSide);\n const floatSide: string = nodeContext.floatSide;\n const nodePosition = nodeContext.toNodePosition();\n return column\n .resolveFloatReferenceFromColumnSpan(\n floatReference,\n nodeContext.columnSpan,\n nodeContext,\n )\n .thenAsync((ref) => {\n floatReference = ref;\n Asserts.assert(pageFloatLayoutContext.flowName);\n const float = new PageFloat(\n nodePosition,\n floatReference,\n floatSide,\n nodeContext.clearSide,\n pageFloatLayoutContext.flowName,\n nodeContext.floatMinWrapBlock,\n );\n pageFloatLayoutContext.addPageFloat(float);\n return Task.newResult(float);\n });\n }\n\n /**\n * @override\n */\n createPageFloatFragment(\n continuations: PageFloatContinuation[],\n floatSide: string,\n floatArea: LayoutType.PageFloatArea,\n continues: boolean,\n ): PageFloatFragment {\n const f = continuations[0].float;\n return new PageFloatFragment(\n f.floatReference,\n floatSide,\n continuations,\n floatArea,\n continues,\n );\n }\n\n /**\n * @override\n */\n findPageFloatFragment(\n float: PageFloat,\n pageFloatLayoutContext: PageFloatLayoutContext,\n ): PageFloatFragment | null {\n return pageFloatLayoutContext.findPageFloatFragment(float);\n }\n\n /**\n * @override\n */\n adjustPageFloatArea(\n floatArea: LayoutType.PageFloatArea,\n floatContainer: Vtree.Container,\n column: LayoutType.Column,\n ) {}\n\n /**\n * @override\n */\n forbid(float: PageFloat, pageFloatLayoutContext: PageFloatLayoutContext) {}\n}\n\nPageFloatLayoutStrategyResolver.register(new NormalPageFloatLayoutStrategy());\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Footnotes\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Task from \"./task\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\nconst PageFloatFragment = PageFloats.PageFloatFragment;\n\nexport class Footnote extends PageFloats.PageFloat {\n constructor(\n nodePosition: Vtree.NodePosition,\n floatReference: PageFloats.FloatReference,\n flowName: string,\n public readonly footnotePolicy: Css.Ident | null,\n floatMinWrapBlock: Css.Numeric | null,\n ) {\n super(\n nodePosition,\n floatReference,\n \"block-end\",\n null,\n flowName,\n floatMinWrapBlock,\n );\n }\n\n /**\n * @override\n */\n isAllowedToPrecede(other: PageFloats.PageFloat): boolean {\n return !(other instanceof Footnote);\n }\n}\n\n/**\n * @extends PageFloatFragment\n */\nexport class FootnoteFragment extends PageFloatFragment {\n constructor(\n floatReference: PageFloats.FloatReference,\n continuations: PageFloats.PageFloatContinuation[],\n area: Vtree.Container,\n continues: boolean,\n ) {\n super(floatReference, \"block-end\", continuations, area, continues);\n }\n\n /**\n * @override\n */\n getOrder(): number {\n return Infinity;\n }\n\n /**\n * @override\n */\n shouldBeStashedBefore(float: PageFloats.PageFloat): boolean {\n if (float instanceof Footnote) {\n return true;\n } else {\n return this.getOrder() < float.getOrder();\n }\n }\n}\n\nexport class LineFootnotePolicyLayoutConstraint\n implements Layout.LayoutConstraint {\n constructor(public readonly footnote: Footnote) {}\n\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n const nodePosition = nodeContext.toNodePosition();\n return !Vtree.isSameNodePosition(nodePosition, this.footnote.nodePosition);\n }\n}\n\nexport class FootnoteLayoutStrategy\n implements PageFloats.PageFloatLayoutStrategy {\n /**\n * @override\n */\n appliesToNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return nodeContext.floatSide === \"footnote\";\n }\n\n /**\n * @override\n */\n appliesToFloat(float: PageFloats.PageFloat): boolean {\n return float instanceof Footnote;\n }\n\n /**\n * @override\n */\n createPageFloat(\n nodeContext: Vtree.NodeContext,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n column: Layout.Column,\n ): Task.Result<PageFloats.PageFloat> {\n let floatReference = PageFloats.FloatReference.REGION;\n\n // If the region context has the same container as the page context,\n // use the page context as the context for the footnote.\n const regionContext = pageFloatLayoutContext.getPageFloatLayoutContext(\n floatReference,\n );\n const pageContext = pageFloatLayoutContext.getPageFloatLayoutContext(\n PageFloats.FloatReference.PAGE,\n );\n if (pageContext.hasSameContainerAs(regionContext)) {\n floatReference = PageFloats.FloatReference.PAGE;\n }\n const nodePosition = nodeContext.toNodePosition();\n Asserts.assert(pageFloatLayoutContext.flowName);\n const float: PageFloats.PageFloat = new Footnote(\n nodePosition,\n floatReference,\n pageFloatLayoutContext.flowName,\n nodeContext.footnotePolicy,\n nodeContext.floatMinWrapBlock,\n );\n pageFloatLayoutContext.addPageFloat(float);\n return Task.newResult(float);\n }\n\n /**\n * @override\n */\n createPageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n floatArea: Layout.PageFloatArea,\n continues: boolean,\n ): PageFloats.PageFloatFragment {\n const f = continuations[0].float;\n return new FootnoteFragment(\n f.floatReference,\n continuations,\n floatArea,\n continues,\n );\n }\n\n /**\n * @override\n */\n findPageFloatFragment(\n float: PageFloats.PageFloat,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): PageFloats.PageFloatFragment | null {\n const context = pageFloatLayoutContext.getPageFloatLayoutContext(\n float.floatReference,\n );\n const fragments = context.floatFragments.filter(\n (fr) => fr instanceof FootnoteFragment,\n );\n Asserts.assert(fragments.length <= 1);\n return fragments[0] || null;\n }\n\n /**\n * @override\n */\n adjustPageFloatArea(\n floatArea: Layout.PageFloatArea,\n floatContainer: Vtree.Container,\n column: Layout.Column,\n ) {\n floatArea.isFootnote = true;\n floatArea.adjustContentRelativeSize = false;\n const element = floatArea.element;\n Asserts.assert(element);\n floatArea.vertical = column.layoutContext.applyFootnoteStyle(\n floatContainer.vertical,\n (column.layoutContext as any).nodeContext &&\n (column.layoutContext as any).nodeContext.direction === \"rtl\",\n element,\n );\n floatArea.convertPercentageSizesToPx(element);\n column.setComputedInsets(element, floatArea);\n column.setComputedWidthAndHeight(element, floatArea);\n }\n\n /**\n * @override\n */\n forbid(\n float: PageFloats.PageFloat,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n const footnote = float as Footnote;\n switch (footnote.footnotePolicy) {\n case Css.ident.line: {\n const constraint = new LineFootnotePolicyLayoutConstraint(footnote);\n pageFloatLayoutContext.addLayoutConstraint(\n constraint,\n footnote.floatReference,\n );\n break;\n }\n }\n }\n}\n\nPageFloats.PageFloatLayoutStrategyResolver.register(\n new FootnoteLayoutStrategy(),\n);\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Break - Control fragmentation.\n */\nimport * as Css from \"./css\";\nimport * as Plugin from \"./plugin\";\n\n/**\n * Convert old page-break-* properties to break-* properties with appropriate\n * values as specified by CSS Fragmentation module:\n * https://drafts.csswg.org/css-break/#page-break-properties\n */\nexport function convertPageBreakAliases(original: {\n name: string;\n value: Css.Val;\n important: boolean;\n}): { name: string; value: Css.Val; important: boolean } {\n const name = original[\"name\"];\n const value = original[\"value\"];\n switch (name) {\n case \"page-break-before\":\n case \"page-break-after\":\n case \"page-break-inside\":\n return {\n name: name.replace(/^page-/, \"\"),\n value: value === Css.ident.always ? Css.ident.page : value,\n important: original[\"important\"],\n };\n default:\n return original;\n }\n}\n\nexport const forcedBreakValues: { [key: string]: boolean | null } = {\n page: true,\n left: true,\n right: true,\n recto: true,\n verso: true,\n column: true,\n region: true,\n};\n\n/**\n * Returns if the value is one of the forced break values.\n * @param value The break value to be judged. Treats null as 'auto'.\n */\nexport function isForcedBreakValue(value: string | null): boolean {\n return !!forcedBreakValues[value];\n}\n\nexport const avoidBreakValues: { [key: string]: boolean | null } = {\n avoid: true,\n \"avoid-page\": true,\n \"avoid-column\": true,\n \"avoid-region\": true,\n};\n\n/**\n * Returns if the value is one of the avoid break values.\n * @param value The break value to be judged. Treats null as 'auto'.\n */\nexport function isAvoidBreakValue(value: string | null): boolean {\n return !!avoidBreakValues[value];\n}\n\n/**\n * Resolves the effective break value given two break values at a single break\n * point. The order of the arguments are relevant, since a value specified on\n * the latter element takes precedence over one on the former. A forced break\n * value is chosen if present. Otherwise, an avoid break value is chosen if\n * present. See CSS Fragmentation Module for the rule:\n * https://drafts.csswg.org/css-break/#forced-breaks\n * https://drafts.csswg.org/css-break/#unforced-breaks\n * Note that though the spec requires to honor multiple break values at a single\n * break point, the current implementation choose one of them and discard the\n * others.\n * @param first The break value specified on the former element. null means\n * 'auto' (not specified)\n * @param second The break value specified on the latter element. null means\n * 'auto' (not specified)\n */\nexport function resolveEffectiveBreakValue(\n first: string | null,\n second: string | null,\n): string | null {\n if (!first) {\n return second;\n } else if (!second) {\n return first;\n } else {\n const firstIsForcedBreakValue = isForcedBreakValue(first);\n const secondIsForcedBreakValue = isForcedBreakValue(second);\n if (firstIsForcedBreakValue && secondIsForcedBreakValue) {\n switch (second) {\n case \"column\":\n // \"column\" is the weakest value\n return first;\n case \"region\":\n // \"region\" is stronger than \"column\" but weaker than page\n // values\n return first === \"column\" ? second : first;\n default:\n // page values are strongest\n return second;\n }\n } else if (secondIsForcedBreakValue) {\n return second;\n } else if (firstIsForcedBreakValue) {\n return first;\n } else if (isAvoidBreakValue(second)) {\n return second;\n } else if (isAvoidBreakValue(first)) {\n return first;\n } else {\n return second;\n }\n }\n}\n\nexport function breakValueToStartSideValue(breakValue: string | null): string {\n switch (breakValue) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return breakValue;\n default:\n return \"any\";\n }\n}\n\nexport function startSideValueToBreakValue(\n startSideValue: string,\n): string | null {\n switch (startSideValue) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return startSideValue;\n default:\n return null;\n }\n}\n\nPlugin.registerHook(\"SIMPLE_PROPERTY\", convertPageBreakAliases);\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutHelper - Helper functions of Layout.\n */\nimport * as Base from \"./base\";\nimport * as Logging from \"./logging\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * Though method used to be used as a workaround for Chrome bug, it seems that\n * the bug has been already fixed:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=297808\n * We now use this method as a workaround for Firefox bug:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1159309\n */\nexport function fixBoxesForNode(\n clientLayout: Vtree.ClientLayout,\n boxes: Vtree.ClientRect[],\n node: Node,\n): Vtree.ClientRect[] {\n const fullRange = node.ownerDocument.createRange();\n fullRange.setStart(node, 0);\n fullRange.setEnd(node, node.textContent.length);\n const fullBoxes = clientLayout.getRangeClientRects(fullRange);\n const result = [];\n for (const box of boxes) {\n let k: number;\n for (k = 0; k < fullBoxes.length; k++) {\n const fullBox = fullBoxes[k];\n if (\n box.top >= fullBox.top &&\n box.bottom <= fullBox.bottom &&\n Math.abs(box.left - fullBox.left) < 1\n ) {\n result.push({\n top: box.top,\n left: fullBox.left,\n bottom: box.bottom,\n right: fullBox.right,\n });\n break;\n }\n }\n if (k == fullBoxes.length) {\n Logging.logger.warn(\"Could not fix character box\");\n result.push(box);\n }\n }\n return result;\n}\n\n/**\n * Calculate the position of the \"after\" edge in the block-progression\n * dimension. Return 0 if position was determined successfully and return\n * non-zero if position could not be determined and the node should be\n * considered zero-height.\n */\nexport function calculateEdge(\n nodeContext: Vtree.NodeContext,\n clientLayout: Vtree.ClientLayout,\n extraOffset: number,\n vertical: boolean,\n): number {\n const node = nodeContext.viewNode;\n if (!node) {\n return NaN;\n }\n if (node.nodeType == 1) {\n if (nodeContext.after || !nodeContext.inline) {\n const cbox = clientLayout.getElementClientRect(node as Element);\n if (cbox.right >= cbox.left && cbox.bottom >= cbox.top) {\n if (nodeContext.after) {\n return vertical ? cbox.left : cbox.bottom;\n } else {\n return vertical ? cbox.right : cbox.top;\n }\n }\n }\n return NaN;\n } else {\n let edge = NaN;\n const range = node.ownerDocument.createRange();\n const length = node.textContent.length;\n if (!length) {\n return NaN;\n }\n if (nodeContext.after) {\n extraOffset += length;\n }\n if (extraOffset >= length) {\n extraOffset = length - 1;\n }\n range.setStart(node, extraOffset);\n range.setEnd(node, extraOffset + 1);\n let boxes = clientLayout.getRangeClientRects(range);\n if (vertical && Base.checkVerticalBBoxBug(document.body)) {\n boxes = fixBoxesForNode(clientLayout, boxes, node);\n }\n let maxSize = 0;\n\n // Get first of the widest boxes (works around Chrome results for soft\n // hyphens).\n for (const box of boxes) {\n const boxSize = vertical ? box.bottom - box.top : box.right - box.left;\n if (\n box.right > box.left &&\n box.bottom > box.top &&\n (isNaN(edge) || boxSize > maxSize)\n ) {\n edge = vertical ? box.left : box.bottom;\n maxSize = boxSize;\n }\n }\n return edge;\n }\n}\n\nexport function getElementHeight(\n element: Element,\n column: Layout.Column,\n vertical: boolean,\n): number {\n const rect = column.clientLayout.getElementClientRect(element);\n const margin = column.getComputedMargin(element);\n return vertical\n ? rect[\"width\"] + margin[\"left\"] + margin[\"right\"]\n : rect[\"height\"] + margin[\"top\"] + margin[\"bottom\"];\n}\n\nexport function isOrphan(node: Node): boolean {\n while (node) {\n if (node.parentNode === node.ownerDocument) {\n return false;\n }\n node = node.parentNode;\n }\n return true;\n}\n\nexport function removeFollowingSiblings(\n parentNode: Node,\n viewNode: Node,\n): void {\n if (!parentNode) {\n return;\n }\n let lastChild: Node;\n while ((lastChild = parentNode.lastChild) != viewNode) {\n parentNode.removeChild(lastChild);\n }\n}\n\nexport function isSpecial(e: Element): boolean {\n return !!e.getAttribute(VtreeImpl.SPECIAL_ATTR);\n}\n\nexport function isSpecialNodeContext(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext) {\n return false;\n }\n const viewNode = nodeContext.viewNode;\n if (viewNode && viewNode.nodeType === 1) {\n return isSpecial(viewNode as Element);\n } else {\n return false;\n }\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview BreakPosition - Definitions of BreakPosition.\n */\nimport * as Break from \"./break\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport { Layout, RepetitiveElement, Vtree } from \"./types\";\n\n/**\n * Potential breaking position.\n */\nexport type BreakPosition = Layout.BreakPosition;\n\nexport abstract class AbstractBreakPosition\n implements Layout.AbstractBreakPosition {\n abstract findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext;\n\n abstract getMinBreakPenalty(): number;\n\n calculateOffset(column): { current: number; minimum: number } {\n return calculateOffset(\n this.getNodeContext(),\n column.collectElementsOffset(),\n );\n }\n\n /**\n * @override\n */\n breakPositionChosen(column: Layout.Column): void {}\n\n getNodeContext(): Vtree.NodeContext {\n return null;\n }\n}\n\nexport function calculateOffset(\n nodeContext: Vtree.NodeContext,\n elementsOffsets: RepetitiveElement.ElementsOffset[],\n): { current: number; minimum: number } {\n return {\n current: elementsOffsets.reduce(\n (val, repetitiveElement) =>\n val + repetitiveElement.calculateOffset(nodeContext),\n 0,\n ),\n minimum: elementsOffsets.reduce(\n (val, repetitiveElement) =>\n val + repetitiveElement.calculateMinimumOffset(nodeContext),\n 0,\n ),\n };\n}\n\n/**\n * Potential edge breaking position.\n */\nexport class EdgeBreakPosition extends AbstractBreakPosition\n implements Layout.EdgeBreakPosition {\n overflowIfRepetitiveElementsDropped: boolean;\n protected isEdgeUpdated: boolean = false;\n private edge: number = 0;\n\n constructor(\n public readonly position: Vtree.NodeContext,\n public readonly breakOnEdge: string | null,\n public overflows: boolean,\n public readonly computedBlockSize: number,\n ) {\n super();\n this.overflowIfRepetitiveElementsDropped = overflows;\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n this.updateOverflows(column);\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n return column.findEdgeBreakPosition(this);\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n if (!this.isEdgeUpdated) {\n throw new Error(\"EdgeBreakPosition.prototype.updateEdge not called\");\n }\n const preferDropping =\n this.isFirstContentOfRepetitiveElementsOwner() &&\n !this.overflowIfRepetitiveElementsDropped;\n return (\n (Break.isAvoidBreakValue(this.breakOnEdge) ? 1 : 0) +\n (this.overflows && !preferDropping ? 3 : 0) +\n (this.position.parent ? this.position.parent.breakPenalty : 0)\n );\n }\n\n private updateEdge(column: Layout.Column) {\n const clonedPaddingBorder = column.calculateClonedPaddingBorder(\n this.position,\n );\n this.edge =\n LayoutHelper.calculateEdge(\n this.position,\n column.clientLayout,\n 0,\n column.vertical,\n ) + clonedPaddingBorder;\n this.isEdgeUpdated = true;\n }\n\n private updateOverflows(column: Layout.Column) {\n if (!this.isEdgeUpdated) {\n this.updateEdge(column);\n }\n const edge = this.edge;\n const offsets = this.calculateOffset(column);\n this.overflowIfRepetitiveElementsDropped = column.isOverflown(\n edge + (column.vertical ? -1 : 1) * offsets.minimum,\n );\n this.overflows = this.position.overflow = column.isOverflown(\n edge + (column.vertical ? -1 : 1) * offsets.current,\n );\n }\n\n /** @override */\n getNodeContext(): Vtree.NodeContext {\n return this.position;\n }\n\n private isFirstContentOfRepetitiveElementsOwner(): boolean {\n const nodeContext = this.getNodeContext();\n if (!nodeContext || !nodeContext.parent) {\n return false;\n }\n const { formattingContext } = nodeContext.parent;\n if (\n !RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n formattingContext,\n )\n ) {\n return false;\n }\n\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n return repetitiveElements.isFirstContentNode(nodeContext);\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Display - CSS Display Module\n */\nimport * as Css from \"./css\";\n\nexport const FLOW_ROOT_ATTR = \"data-vivliostyle-flow-root\";\n\nexport function isFlowRoot(element: Element): boolean {\n return element.getAttribute(FLOW_ROOT_ATTR) === \"true\";\n}\n\n/**\n * 'Blockify' a display value.\n * cf. https://drafts.csswg.org/css-display/#transformations\n * https://drafts.csswg.org/css2/visuren.html#dis-pos-flo\n */\nexport function blockify(display: Css.Ident): Css.Ident {\n const displayStr = display.toString();\n let blockifiedStr: string;\n switch (displayStr) {\n case \"inline-flex\":\n blockifiedStr = \"flex\";\n break;\n case \"inline-grid\":\n blockifiedStr = \"grid\";\n break;\n case \"inline-table\":\n blockifiedStr = \"table\";\n break;\n case \"inline\":\n case \"table-row-group\":\n case \"table-column\":\n case \"table-column-group\":\n case \"table-header-group\":\n case \"table-footer-group\":\n case \"table-row\":\n case \"table-cell\":\n case \"table-caption\":\n case \"inline-block\":\n blockifiedStr = \"block\";\n break;\n default:\n blockifiedStr = displayStr;\n }\n return Css.getName(blockifiedStr);\n}\n\n/**\n * Judge if the generated box is absolutely positioned.\n */\nexport function isAbsolutelyPositioned(position: Css.Ident): boolean {\n return position === Css.ident.absolute || position === Css.ident.fixed;\n}\n\n/**\n * Get computed values of display, position and float.\n * cf. https://drafts.csswg.org/css-display/#transformations\n * https://drafts.csswg.org/css2/visuren.html#dis-pos-flo\n */\nexport function getComputedDislayValue(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n): { display: Css.Ident; position: Css.Ident; float: Css.Ident } {\n if (display === Css.ident.none) {\n // no need to convert values when 'display' is 'none'\n } else if (isAbsolutelyPositioned(position)) {\n float = Css.ident.none;\n display = blockify(display);\n } else if ((float && float !== Css.ident.none) || isRoot) {\n display = blockify(display);\n }\n return { display, position, float };\n}\n\n/**\n * Judges if the generated box is block.\n */\nexport function isBlock(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n): boolean {\n return (\n getComputedDislayValue(display, position, float, isRoot).display ===\n Css.ident.block\n );\n}\n\nexport function isInlineLevel(display: Css.Ident): boolean {\n switch (display.toString()) {\n case \"inline\":\n case \"inline-block\":\n case \"inline-list-item\":\n case \"inline-flex\":\n case \"inline-grid\":\n case \"ruby\":\n case \"inline-table\":\n return true;\n default:\n return false;\n }\n}\n\nexport function isRubyInternalDisplay(display: Css.Ident): boolean {\n switch (display.toString()) {\n case \"ruby-base\":\n case \"ruby-text\":\n case \"ruby-base-container\":\n case \"ruby-text-container\":\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Judges if the generated box establishes a new block formatting context.\n */\nexport function establishesBFC(\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n overflow: Css.Ident,\n writingMode?: Css.Ident,\n parentWritingMode?: Css.Ident,\n isFlowRoot?: boolean,\n): boolean {\n writingMode = writingMode || parentWritingMode || Css.ident.horizontal_tb;\n return (\n !!isFlowRoot ||\n (!!float && float !== Css.ident.none) ||\n isAbsolutelyPositioned(position) ||\n display === Css.ident.inline_block ||\n display === Css.ident.table_cell ||\n display === Css.ident.table_caption ||\n display == Css.ident.flex ||\n ((display === Css.ident.block || display === Css.ident.list_item) &&\n !!overflow &&\n overflow !== Css.ident.visible) ||\n (!!parentWritingMode && writingMode !== parentWritingMode)\n );\n}\n\n/**\n * Judges if the generated box establishes a containing block for descendant\n * boxes with 'position: absolute'.\n */\nexport function establishesCBForAbsolute(position: Css.Ident): boolean {\n return (\n position === Css.ident.relative ||\n position === Css.ident.absolute ||\n position === Css.ident.fixed\n );\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutProcessor - Definitions of LayoutProcessor.\n */\nimport * as BreakPosition from \"./break-position\";\nimport * as Display from \"./display\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as Plugin from \"./plugin\";\nimport * as Task from \"./task\";\nimport { FormattingContextType, Layout, LayoutProcessor, Vtree } from \"./types\";\n\n/**\n * Processor doing some special layout (e.g. table layout)\n */\nexport interface LayoutProcessor {\n /**\n * Do actual layout in the column starting from given NodeContext.\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * Potential edge breaking position.\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): Layout.BreakPosition;\n\n /**\n * process nodecontext at the start of a non inline element.\n * @return return true if you skip the subsequent nodes\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean;\n\n /**\n * process nodecontext after a non inline element.\n * @return return true if you skip the subsequent nodes\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean;\n\n /**\n * @return holing true\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean>;\n\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n );\n}\n\n/**\n * Resolver finding an appropriate LayoutProcessor given a formatting context\n */\nexport class LayoutProcessorResolver {\n /**\n * Find LayoutProcessor corresponding to given formatting context.\n */\n find(formattingContext: Vtree.FormattingContext): LayoutProcessor {\n const hooks: Plugin.ResolveLayoutProcessorHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n );\n for (let i = 0; i < hooks.length; i++) {\n const processor = hooks[i](formattingContext);\n if (processor) {\n return processor;\n }\n }\n throw new Error(\n `No processor found for a formatting context: ${formattingContext.getName()}`,\n );\n }\n}\n\nexport class BlockLayoutProcessor implements LayoutProcessor {\n /**\n * @override\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n if (column.isFloatNodeContext(nodeContext)) {\n return column.layoutFloatOrFootnote(nodeContext);\n } else if (column.isBreakable(nodeContext)) {\n return column.layoutBreakableBlock(nodeContext);\n } else {\n return column.layoutUnbreakable(nodeContext);\n }\n }\n\n /**\n * @override\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): Layout.BreakPosition {\n return new BreakPosition.EdgeBreakPosition(\n position.copy(),\n breakOnEdge,\n overflows,\n columnBlockSize,\n );\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean {\n return false;\n }\n\n /**\n * @override\n */\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n if (!nodeContext.viewNode) {\n return;\n }\n if (!nodeContext.viewNode.parentNode) {\n return;\n }\n const parentNode = nodeContext.viewNode.parentNode;\n LayoutHelper.removeFollowingSiblings(parentNode, nodeContext.viewNode);\n if (removeSelf) {\n parentNode.removeChild(nodeContext.viewNode);\n }\n }\n\n /**\n * @return holing true\n * @override\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n const removeSelf =\n forceRemoveSelf ||\n (nodeContext.viewNode != null &&\n nodeContext.viewNode.nodeType == 1 &&\n !nodeContext.after);\n column.clearOverflownViewNodes(nodeContext, removeSelf);\n if (endOfColumn) {\n column.fixJustificationIfNeeded(nodeContext, true);\n column.layoutContext.processFragmentedBlockEdge(\n removeSelf ? nodeContext : nodeContext.parent,\n );\n }\n return Task.newResult(true);\n }\n}\n\nexport class BlockFormattingContext\n implements LayoutProcessor.BlockFormattingContext {\n formattingContextType: FormattingContextType = \"Block\";\n\n constructor(private readonly parent: Vtree.FormattingContext) {}\n\n /**\n * @override\n */\n getName(): string {\n return \"Block formatting context (BlockFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n return firstTime;\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n /** @override */\n saveState(): any {}\n\n /** @override */\n restoreState(state: any) {}\n}\n\nexport const blockLayoutProcessor = new BlockLayoutProcessor();\n\nexport const isInstanceOfBlockFormattingContext =\n LayoutProcessor.isInstanceOfBlockFormattingContext;\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n (nodeContext, firstTime, display, position, floatSide, isRoot) => {\n const parent = nodeContext.parent;\n if (!parent && nodeContext.formattingContext) {\n return null;\n } else if (\n parent &&\n nodeContext.formattingContext !== parent.formattingContext\n ) {\n return null;\n } else if (\n nodeContext.establishesBFC ||\n (!nodeContext.formattingContext &&\n Display.isBlock(display, position, floatSide, isRoot))\n ) {\n return new BlockFormattingContext(\n parent ? parent.formattingContext : null,\n );\n } else {\n return null;\n }\n },\n);\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n (formattingContext) => {\n if (formattingContext instanceof BlockFormattingContext) {\n return blockLayoutProcessor;\n }\n return null;\n },\n);\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutRetryers - Definitions of LayoutRetryer.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Task from \"./task\";\nimport { Layout, Vtree } from \"./types\";\n\n/**\n * @abstract\n */\nexport abstract class AbstractLayoutRetryer {\n initialBreakPositions: Layout.BreakPosition[] = null;\n initialStateOfFormattingContext: Vtree.NodeContext = null;\n initialPosition: Vtree.NodeContext;\n initialFragmentLayoutConstraints: Layout.FragmentLayoutConstraint[];\n\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n this.prepareLayout(nodeContext, column);\n return this.tryLayout(nodeContext, column);\n }\n\n private tryLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"AbstractLayoutRetryer.tryLayout\",\n );\n this.saveState(nodeContext, column);\n const mode = this.resolveLayoutMode(nodeContext);\n mode.doLayout(nodeContext, column).then((positionAfter) => {\n let accepted = mode.accept(positionAfter, column);\n accepted = mode.postLayout(\n positionAfter,\n this.initialPosition,\n column,\n accepted,\n );\n if (accepted) {\n frame.finish(positionAfter);\n } else {\n Asserts.assert(this.initialPosition);\n this.clearNodes(this.initialPosition);\n this.restoreState(nodeContext, column);\n this.tryLayout(this.initialPosition, column).thenFinish(frame);\n }\n });\n return frame.result();\n }\n\n /**\n * @abstract\n */\n abstract resolveLayoutMode(nodeContext: Vtree.NodeContext): Layout.LayoutMode;\n\n prepareLayout(nodeContext: Vtree.NodeContext, column: Layout.Column) {}\n\n clearNodes(initialPosition: Vtree.NodeContext) {\n const viewNode =\n initialPosition.viewNode || initialPosition.parent.viewNode;\n let child: Node;\n while ((child = viewNode.lastChild)) {\n viewNode.removeChild(child);\n }\n let sibling: Node;\n while ((sibling = viewNode.nextSibling)) {\n sibling.parentNode.removeChild(sibling);\n }\n }\n\n saveState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n this.initialPosition = nodeContext.copy();\n this.initialBreakPositions = [].concat(column.breakPositions);\n this.initialFragmentLayoutConstraints = [].concat(\n column.fragmentLayoutConstraints,\n );\n if (nodeContext.formattingContext) {\n this.initialStateOfFormattingContext = nodeContext.formattingContext.saveState();\n }\n }\n\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n column.breakPositions = this.initialBreakPositions;\n column.fragmentLayoutConstraints = this.initialFragmentLayoutConstraints;\n if (nodeContext.formattingContext) {\n nodeContext.formattingContext.restoreState(\n this.initialStateOfFormattingContext,\n );\n }\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview LayoutUtil - Utilities related to layout.\n */\nimport * as Break from \"./break\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport { Layout, Vtree } from \"./types\";\n\nexport type LayoutIteratorState = {\n nodeContext: Vtree.NodeContext;\n atUnforcedBreak: boolean;\n break: boolean;\n leadingEdge?: boolean;\n breakAtTheEdge?: string | null;\n onStartEdges?: boolean;\n leadingEdgeContexts?: Vtree.NodeContext[];\n lastAfterNodeContext?: Vtree.NodeContext | null;\n};\n\nexport class LayoutIteratorStrategy {\n initialState(initialNodeContext: Vtree.NodeContext): LayoutIteratorState {\n return {\n nodeContext: initialNodeContext,\n atUnforcedBreak: false,\n break: false,\n };\n }\n\n startNonDisplayableNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonDisplayableNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startIgnoredTextNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterIgnoredTextNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startNonElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n startNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n afterNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n finish(state: LayoutIteratorState): void | Task.Result<boolean> {}\n}\n\nexport class LayoutIterator {\n constructor(\n private readonly strategy: LayoutIteratorStrategy,\n private readonly layoutContext: Vtree.LayoutContext,\n ) {}\n\n iterate(\n initialNodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const strategy = this.strategy;\n const state = strategy.initialState(initialNodeContext);\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"LayoutIterator\",\n );\n frame\n .loopWithFrame((loopFrame) => {\n let r: void | Task.Result<boolean>;\n while (state.nodeContext) {\n if (!state.nodeContext.viewNode) {\n if (state.nodeContext.after) {\n r = strategy.afterNonDisplayableNode(state);\n } else {\n r = strategy.startNonDisplayableNode(state);\n }\n } else if (state.nodeContext.viewNode.nodeType !== 1) {\n if (\n VtreeImpl.canIgnore(\n state.nodeContext.viewNode,\n state.nodeContext.whitespace,\n )\n ) {\n if (state.nodeContext.after) {\n r = strategy.afterIgnoredTextNode(state);\n } else {\n r = strategy.startIgnoredTextNode(state);\n }\n } else {\n if (state.nodeContext.after) {\n r = strategy.afterNonElementNode(state);\n } else {\n r = strategy.startNonElementNode(state);\n }\n }\n } else {\n if (state.nodeContext.inline) {\n if (state.nodeContext.after) {\n r = strategy.afterInlineElementNode(state);\n } else {\n r = strategy.startInlineElementNode(state);\n }\n } else {\n if (state.nodeContext.after) {\n r = strategy.afterNonInlineElementNode(state);\n } else {\n r = strategy.startNonInlineElementNode(state);\n }\n }\n }\n const cont = r && r.isPending() ? r : Task.newResult(true);\n const nextResult = cont.thenAsync(() => {\n if (state.break) {\n return Task.newResult(null);\n }\n return this.layoutContext.nextInTree(\n state.nodeContext,\n state.atUnforcedBreak,\n );\n });\n if (nextResult.isPending()) {\n nextResult.then((nextNodeContext) => {\n if (state.break) {\n loopFrame.breakLoop();\n } else {\n state.nodeContext = nextNodeContext;\n loopFrame.continueLoop();\n }\n });\n return;\n } else if (state.break) {\n loopFrame.breakLoop();\n return;\n } else {\n state.nodeContext = nextResult.get();\n }\n }\n strategy.finish(state);\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(state.nodeContext);\n });\n return frame.result();\n }\n}\n\nexport class EdgeSkipper extends LayoutIteratorStrategy {\n constructor(protected readonly leadingEdge?: boolean) {\n super();\n }\n\n startNonInlineBox(state: LayoutIteratorState): void | Task.Result<boolean> {}\n\n endEmptyNonInlineBox(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {}\n\n endNonInlineBox(state: LayoutIteratorState): void | Task.Result<boolean> {}\n\n initialState(initialNodeContext: Vtree.NodeContext): LayoutIteratorState {\n return {\n nodeContext: initialNodeContext,\n atUnforcedBreak: !!this.leadingEdge && initialNodeContext.after,\n break: false,\n leadingEdge: this.leadingEdge,\n breakAtTheEdge: null,\n onStartEdges: false,\n leadingEdgeContexts: [],\n lastAfterNodeContext: null,\n };\n }\n\n /**\n * @return Returns true if a forced break occurs.\n */\n processForcedBreak(\n state: LayoutIteratorState,\n column: Layout.Column,\n ): boolean {\n const needForcedBreak =\n !state.leadingEdge && Break.isForcedBreakValue(state.breakAtTheEdge);\n if (needForcedBreak) {\n const nodeContext = (state.nodeContext =\n state.leadingEdgeContexts[0] || state.nodeContext);\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n column.pageBreakType = state.breakAtTheEdge;\n }\n return needForcedBreak;\n }\n\n /**\n * @return Returns true if the node overflows the column.\n */\n saveEdgeAndProcessOverflow(\n state: LayoutIteratorState,\n column: Layout.Column,\n ): boolean {\n const overflow = column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n true,\n state.breakAtTheEdge,\n );\n if (overflow) {\n state.nodeContext = (\n state.lastAfterNodeContext || state.nodeContext\n ).modify();\n state.nodeContext.overflow = true;\n }\n return overflow;\n }\n\n /**\n * @returns Returns true if the layout constraint is violated.\n */\n processLayoutConstraint(\n state: LayoutIteratorState,\n layoutConstraint: Layout.LayoutConstraint,\n column: Layout.Column,\n ): boolean {\n let nodeContext = state.nodeContext;\n const violateConstraint = !layoutConstraint.allowLayout(nodeContext);\n if (violateConstraint) {\n column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n false,\n state.breakAtTheEdge,\n );\n nodeContext = state.nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n }\n return violateConstraint;\n }\n\n /**\n * @override\n */\n startNonElementNode(state: LayoutIteratorState): void | Task.Result<boolean> {\n state.onStartEdges = false;\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {\n state.leadingEdgeContexts.push(state.nodeContext.copy());\n state.breakAtTheEdge = Break.resolveEffectiveBreakValue(\n state.breakAtTheEdge,\n state.nodeContext.breakBefore,\n );\n state.onStartEdges = true;\n return this.startNonInlineBox(state);\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutIteratorState,\n ): void | Task.Result<boolean> {\n let r: void | Task.Result<boolean>;\n let cont: Task.Result<boolean>;\n if (state.onStartEdges) {\n r = this.endEmptyNonInlineBox(state);\n cont = r && r.isPending() ? r : Task.newResult(true);\n cont = cont.thenAsync(() => {\n if (!state.break) {\n state.leadingEdgeContexts = [];\n state.leadingEdge = false;\n state.atUnforcedBreak = false;\n state.breakAtTheEdge = null;\n }\n return Task.newResult(true);\n });\n } else {\n r = this.endNonInlineBox(state);\n cont = r && r.isPending() ? r : Task.newResult(true);\n }\n return cont.thenAsync(() => {\n if (!state.break) {\n state.onStartEdges = false;\n state.lastAfterNodeContext = state.nodeContext.copy();\n state.breakAtTheEdge = Break.resolveEffectiveBreakValue(\n state.breakAtTheEdge,\n state.nodeContext.breakAfter,\n );\n }\n return Task.newResult(true);\n });\n }\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Shared - Global variables of Vivliostyle.js\n */\nimport { RepetitiveElement } from \"./types\";\n\nexport let repetitiveElementsCache: {\n root: Element;\n elements: RepetitiveElement.RepetitiveElements;\n}[] = [];\n\nexport function clearRepetitiveElementsCache(): void {\n repetitiveElementsCache = [];\n}\n","/**\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PseudoElement - CSS pseudo elements.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Exprs from \"./exprs\";\nimport * as Vtree from \"./vtree\";\nimport { PseudoElement } from \"./types\";\n\nexport const document = new DOMParser().parseFromString(\n `<root xmlns=\"${Base.NS.SHADOW}\"/>`,\n \"text/xml\",\n);\n\n/**\n * Pseudoelement names in the order they should be inserted in the shadow DOM,\n * empty string is the place where the element's DOM children are processed.\n */\nexport const pseudoNames = [\n \"footnote-marker\",\n \"first-5-lines\",\n \"first-4-lines\",\n \"first-3-lines\",\n \"first-2-lines\",\n \"first-line\",\n \"first-letter\",\n \"before\",\n \"\",\n /* content */\n \"after\",\n];\n\nexport const PSEUDO_ATTR = \"data-adapt-pseudo\";\n\nexport function getPseudoName(element: Element): string {\n return element.getAttribute(PSEUDO_ATTR) || \"\";\n}\n\nexport function setPseudoName(element: Element, name: string): void {\n element.setAttribute(PSEUDO_ATTR, name);\n}\n\nexport class PseudoelementStyler implements PseudoElement.PseudoelementStyler {\n contentProcessed: { [key: string]: boolean } = {};\n\n // after content: update style\n\n constructor(\n public readonly element: Element,\n public style: CssCascade.ElementStyle,\n public styler: CssStyler.AbstractStyler,\n public readonly context: Exprs.Context,\n public readonly exprContentListener: Vtree.ExprContentListener,\n ) {}\n\n /**\n * @override\n */\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle {\n const pseudoName = getPseudoName(element);\n if (this.styler && pseudoName && pseudoName.match(/after$/)) {\n this.style = this.styler.getStyle(this.element, true);\n this.styler = null;\n }\n const pseudoMap = CssCascade.getStyleMap(this.style, \"_pseudos\");\n const style = pseudoMap[pseudoName] || ({} as CssCascade.ElementStyle);\n if (pseudoName.match(/^first-/) && !style[\"x-first-pseudo\"]) {\n let nest = 1;\n let r: RegExpMatchArray;\n if (pseudoName == \"first-letter\") {\n nest = 0;\n } else if ((r = pseudoName.match(/^first-([0-9]+)-lines$/)) != null) {\n nest = (r[1] as any) - 0;\n }\n style[\"x-first-pseudo\"] = new CssCascade.CascadeValue(\n new Css.Int(nest),\n 0,\n );\n }\n return style;\n }\n\n /**\n * @override\n */\n processContent(element: Element, styles: { [key: string]: Css.Val }) {\n const pseudoName = getPseudoName(element);\n if (!this.contentProcessed[pseudoName]) {\n this.contentProcessed[pseudoName] = true;\n const contentVal = styles[\"content\"];\n if (contentVal) {\n if (Vtree.nonTrivialContent(contentVal)) {\n contentVal.visit(\n new Vtree.ContentPropertyHandler(\n element,\n this.context,\n contentVal,\n this.exprContentListener,\n ),\n );\n }\n }\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Layout - Fills a column with styled content.\n * This file does not communicate with the styling system directly.\n * Instead it goes through the layout interface that gives it one view tree\n * node at a time.\n */\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as Asserts from \"./asserts\";\nimport * as Shared from \"./shared\";\nimport * as Sizing from \"./sizing\";\nimport * as Break from \"./break\";\nimport * as Logging from \"./logging\";\nimport * as Diff from \"./diff\";\nimport * as Base from \"./base\";\nimport * as BreakPosition from \"./break-position\";\nimport * as Css from \"./css\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Plugin from \"./plugin\";\nimport * as Matchers from \"./matchers\";\nimport * as PseudoElement from \"./pseudo-element\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as VtreeImpl from \"./vtree\";\nimport {\n FragmentLayoutConstraintType,\n Layout,\n RepetitiveElement,\n Selectors,\n Table,\n Vtree,\n} from \"./types\";\n\nexport const isInstanceOfAfterIfContinuesLayoutConstraint =\n Selectors.isInstanceOfAfterIfContinuesLayoutConstraint;\nexport const registerFragmentIndex =\n Matchers.NthFragmentMatcher.registerFragmentIndex;\nexport const clearFragmentIndices =\n Matchers.NthFragmentMatcher.clearFragmentIndices;\n\nexport class AfterIfContinues implements Selectors.AfterIfContinues {\n constructor(\n public readonly sourceNode: Element,\n public readonly styler: PseudoElement.PseudoelementStyler,\n ) {}\n\n createElement(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n ): Task.Result<Element> {\n const doc = parentNodeContext.viewNode.ownerDocument;\n const viewRoot = doc.createElement(\"div\");\n const pseudoColumn = new PseudoColumn(column, viewRoot, parentNodeContext);\n const initialPageBreakType = pseudoColumn.getColumn().pageBreakType;\n pseudoColumn.getColumn().pageBreakType = null;\n return pseudoColumn\n .layout(this.createNodePositionForPseudoElement(), true)\n .thenAsync(() => {\n this.styler.contentProcessed[\"after-if-continues\"] = false;\n pseudoColumn.getColumn().pageBreakType = initialPageBreakType;\n const pseudoElement = viewRoot.firstChild as Element;\n Base.setCSSProperty(pseudoElement, \"display\", \"block\");\n return Task.newResult(pseudoElement);\n });\n }\n\n private createNodePositionForPseudoElement(): Vtree.ChunkPosition {\n const sourceNode = PseudoElement.document.createElementNS(\n Base.NS.XHTML,\n \"div\",\n );\n PseudoElement.setPseudoName(sourceNode, \"after-if-continues\");\n const shadowContext = this.createShadowContext(sourceNode);\n const step = {\n node: sourceNode,\n shadowType: shadowContext.type,\n shadowContext,\n nodeShadow: null,\n shadowSibling: null,\n };\n const nodePosition = {\n steps: [step],\n offsetInNode: 0,\n after: false,\n preprocessedTextContent: null,\n };\n return new VtreeImpl.ChunkPosition(nodePosition as any);\n }\n\n private createShadowContext(root: Element): Vtree.ShadowContext {\n return new VtreeImpl.ShadowContext(\n this.sourceNode,\n root,\n null,\n null,\n null,\n Vtree.ShadowType.ROOTED,\n this.styler,\n );\n }\n}\n\nexport class AfterIfContinuesLayoutConstraint\n implements Selectors.AfterIfContinuesLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType =\n \"AfterIfContinue\";\n\n constructor(\n public nodeContext: Vtree.NodeContext,\n public afterIfContinues: Selectors.AfterIfContinues,\n public pseudoElementHeight: number,\n ) {}\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {}\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n if (!this.getRepetitiveElements().affectTo(nodeContext)) {\n return Task.newResult(true);\n }\n return this.afterIfContinues\n .createElement(column, this.nodeContext)\n .thenAsync((element) => {\n this.nodeContext.viewNode.appendChild(element);\n return Task.newResult(true);\n });\n }\n\n getRepetitiveElements() {\n return new AfterIfContinuesElementsOffset(\n this.nodeContext,\n this.pseudoElementHeight,\n );\n }\n\n /** @override */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof AfterIfContinuesLayoutConstraint)) {\n return false;\n }\n return (\n this.afterIfContinues ==\n (constraint as AfterIfContinuesLayoutConstraint).afterIfContinues\n );\n }\n\n /** @override */\n getPriorityOfFinishBreak(): number {\n return 9;\n }\n}\n\nexport class AfterIfContinuesElementsOffset\n implements Selectors.AfterIfContinuesElementsOffset {\n constructor(public nodeContext, public pseudoElementHeight) {}\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n if (!this.affectTo(nodeContext)) {\n return 0;\n }\n return this.pseudoElementHeight;\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateOffset(nodeContext);\n }\n\n affectTo(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext) {\n return false;\n }\n const sourceNode = nodeContext.shadowContext\n ? nodeContext.shadowContext.owner\n : nodeContext.sourceNode;\n if (sourceNode === this.nodeContext.sourceNode) {\n return !!nodeContext.after;\n }\n for (let n = sourceNode.parentNode; n; n = n.parentNode) {\n if (n === this.nodeContext.sourceNode) {\n return true;\n }\n }\n return false;\n }\n}\n\nfunction processAfterIfContinuesOfNodeContext(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n): Task.Result<Vtree.NodeContext> {\n if (\n !nodeContext ||\n !nodeContext.afterIfContinues ||\n nodeContext.after ||\n column.isFloatNodeContext(nodeContext)\n ) {\n return Task.newResult(nodeContext);\n }\n const afterIfContinues = nodeContext.afterIfContinues;\n return afterIfContinues\n .createElement(column, nodeContext)\n .thenAsync((pseudoElement) => {\n Asserts.assert(nodeContext !== null);\n const pseudoElementHeight = calculatePseudoElementHeight(\n nodeContext,\n column,\n pseudoElement,\n );\n column.fragmentLayoutConstraints.push(\n new AfterIfContinuesLayoutConstraint(\n nodeContext as Vtree.NodeContext,\n afterIfContinues,\n pseudoElementHeight,\n ),\n );\n return Task.newResult(nodeContext);\n });\n}\n\nexport function processAfterIfContinues(\n result: Task.Result<Vtree.NodeContext>,\n column: Layout.Column,\n): Task.Result<Vtree.NodeContext> {\n return result.thenAsync((nodeContext) =>\n processAfterIfContinuesOfNodeContext(nodeContext, column),\n );\n}\n\nexport function processAfterIfContinuesOfAncestors(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"processAfterIfContinuesOfAncestors\",\n );\n let current: Vtree.NodeContext = nodeContext;\n frame\n .loop(() => {\n if (current !== null) {\n const result = processAfterIfContinuesOfNodeContext(current, column);\n current = current.parent;\n return result.thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n}\n\nexport function calculatePseudoElementHeight(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n pseudoElement: Element,\n): number {\n const parentNode = nodeContext.viewNode as Element;\n parentNode.appendChild(pseudoElement);\n const height = LayoutHelper.getElementHeight(\n pseudoElement,\n column,\n nodeContext.vertical,\n );\n parentNode.removeChild(pseudoElement);\n return height;\n}\n\nexport const mediaTags = {\n img: true,\n svg: true,\n audio: true,\n video: true,\n};\n\n/**\n * Represents a constraint on layout\n */\nexport type LayoutConstraint = Layout.LayoutConstraint;\n\n/**\n * Represents a constraint that allows layout if all the constraints it contains\n * allow layout.\n */\nexport class AllLayoutConstraint implements LayoutConstraint {\n constructor(public readonly constraints: LayoutConstraint[]) {}\n\n /**\n * @override\n */\n allowLayout(nodeContext: Vtree.NodeContext): boolean {\n return this.constraints.every((c) => c.allowLayout(nodeContext));\n }\n}\n\n/**\n * Represents constraints on laying out fragments\n */\nexport type FragmentLayoutConstraint = Layout.FragmentLayoutConstraint;\n\nexport type BreakPositionAndNodeContext = Layout.BreakPositionAndNodeContext;\n\n/**\n * Potential breaking position inside CSS box (between lines).\n * @param checkPoints array of breaking points for breakable block\n */\nexport class BoxBreakPosition extends BreakPosition.AbstractBreakPosition\n implements Layout.BoxBreakPosition {\n private alreadyEvaluated: boolean = false;\n breakNodeContext: Vtree.NodeContext = null;\n\n constructor(\n public readonly checkPoints: Vtree.NodeContext[],\n public readonly penalty: number,\n ) {\n super();\n }\n\n /**\n * @override\n */\n findAcceptableBreak(column: Column, penalty: number): Vtree.NodeContext {\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n if (!this.alreadyEvaluated) {\n this.breakNodeContext = column.findBoxBreakPosition(this, penalty > 0);\n this.alreadyEvaluated = true;\n }\n return this.breakNodeContext;\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n return this.penalty;\n }\n\n /** @override */\n getNodeContext(): Vtree.NodeContext {\n return this.alreadyEvaluated\n ? this.breakNodeContext\n : this.checkPoints[this.checkPoints.length - 1];\n }\n}\n\nexport function validateCheckPoints(checkPoints: Vtree.NodeContext[]): void {\n for (let i = 1; i < checkPoints.length; i++) {\n const cp0 = checkPoints[i - 1];\n const cp1 = checkPoints[i];\n if (cp0 === cp1) {\n Logging.logger.warn(\"validateCheckPoints: duplicate entry\");\n } else if (cp0.boxOffset >= cp1.boxOffset) {\n Logging.logger.warn(\"validateCheckPoints: incorrect boxOffset\");\n } else if (cp0.sourceNode == cp1.sourceNode) {\n if (cp1.after) {\n if (cp0.after) {\n Logging.logger.warn(\"validateCheckPoints: duplicate after points\");\n }\n } else {\n if (!cp0.after) {\n if (\n cp1.boxOffset - cp0.boxOffset !=\n cp1.offsetInNode - cp0.offsetInNode\n ) {\n Logging.logger.warn(\n \"validateCheckPoints: boxOffset inconsistent with offsetInNode\",\n );\n }\n }\n }\n }\n }\n}\n\nexport function isSpecialInlineDisplay(display: string): boolean {\n switch (display) {\n case \"ruby\":\n case \"inline-block\":\n case \"inline-flex\":\n case \"inline-grid\":\n case \"inline-list-item\":\n case \"inline-table\":\n return true;\n }\n return false;\n}\n\nexport class Column extends VtreeImpl.Container implements Layout.Column {\n last: Node;\n viewDocument: Document;\n flowRootFormattingContext: Vtree.FormattingContext = null;\n isFloat: boolean = false;\n isFootnote: boolean = false;\n startEdge: number = 0;\n endEdge: number = 0;\n beforeEdge: number = 0;\n afterEdge: number = 0;\n footnoteEdge: number = 0;\n box: GeometryUtil.Rect = null;\n chunkPositions: Vtree.ChunkPosition[] = null;\n bands: GeometryUtil.Band[] = null;\n overflown: boolean = false;\n breakPositions: BreakPosition.BreakPosition[] = null;\n pageBreakType: string | null = null;\n forceNonfitting: boolean = true;\n leftFloatEdge: number = 0; // bottom of the bottommost left float\n rightFloatEdge: number = 0; // bottom of the bottommost right float\n bottommostFloatTop: number = 0; // Top of the bottommost float\n stopAtOverflow: boolean = true;\n lastAfterPosition: Vtree.NodePosition | null = null;\n fragmentLayoutConstraints: FragmentLayoutConstraint[] = [];\n pseudoParent: Column = null;\n nodeContextOverflowingDueToRepetitiveElements: Vtree.NodeContext | null = null;\n blockDistanceToBlockEndFloats: number = NaN;\n computedBlockSize: number;\n\n constructor(\n element: Element,\n public layoutContext: Vtree.LayoutContext,\n public clientLayout: Vtree.ClientLayout,\n public readonly layoutConstraint: LayoutConstraint,\n public readonly pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n super(element);\n this.last = element.lastChild;\n this.viewDocument = element.ownerDocument;\n pageFloatLayoutContext.setContainer(this);\n }\n\n getTopEdge(): number {\n return this.vertical ? this.startEdge : this.beforeEdge;\n }\n\n getBottomEdge(): number {\n return this.vertical ? this.endEdge : this.afterEdge;\n }\n\n getLeftEdge(): number {\n return this.vertical ? this.afterEdge : this.startEdge;\n }\n\n getRightEdge(): number {\n return this.vertical ? this.beforeEdge : this.endEdge;\n }\n\n isFloatNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return !!nodeContext.floatSide && (!this.isFloat || !!nodeContext.parent);\n }\n\n stopByOverflow(nodeContext: Vtree.NodeContext): boolean {\n return this.stopAtOverflow && !!nodeContext && nodeContext.overflow;\n }\n\n isOverflown(edge: number): boolean {\n if (this.vertical) {\n return edge < this.footnoteEdge;\n } else {\n return edge > this.footnoteEdge;\n }\n }\n\n getExclusions(): GeometryUtil.Shape[] {\n const pageFloatExclusions = this.pageFloatLayoutContext.getFloatFragmentExclusions();\n return this.exclusions.concat(pageFloatExclusions);\n }\n\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"openAllViews\");\n const steps = position.steps;\n self.layoutContext.setViewRoot(self.element, self.isFootnote);\n let stepIndex = steps.length - 1;\n let nodeContext: Vtree.NodeContext = null;\n frame\n .loop(() => {\n while (stepIndex >= 0) {\n const prevContext = nodeContext;\n const step = steps[stepIndex];\n nodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n step,\n prevContext,\n );\n if (\n stepIndex === steps.length - 1 &&\n !nodeContext.formattingContext\n ) {\n nodeContext.formattingContext = self.flowRootFormattingContext;\n }\n if (stepIndex == 0) {\n nodeContext.offsetInNode = self.calculateOffsetInNodeForNodeContext(\n position,\n );\n nodeContext.after = position.after;\n nodeContext.preprocessedTextContent =\n position.preprocessedTextContent;\n if (nodeContext.after) {\n break;\n }\n }\n const r = self.layoutContext.setCurrent(\n nodeContext,\n stepIndex == 0 && nodeContext.offsetInNode == 0,\n );\n stepIndex--;\n if (r.isPending()) {\n return r;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n Asserts.assert(nodeContext);\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n calculateOffsetInNodeForNodeContext(position: Vtree.NodePosition): number {\n return position.preprocessedTextContent\n ? Diff.resolveNewIndex(\n position.preprocessedTextContent,\n position.offsetInNode,\n )\n : position.offsetInNode;\n }\n\n /**\n * @param count first-XXX nesting identifier\n */\n maybePeelOff(\n position: Vtree.NodeContext,\n count: number,\n ): Task.Result<Vtree.NodeContext> {\n if (\n position.firstPseudo &&\n position.inline &&\n !position.after &&\n position.firstPseudo.count == 0\n ) {\n // first char\n if (position.viewNode.nodeType != 1) {\n const text = position.viewNode.textContent;\n const r = text.match(firstCharPattern);\n return this.layoutContext.peelOff(position, r[0].length);\n }\n }\n return Task.newResult(position) as Task.Result<Vtree.NodeContext>;\n }\n\n /**\n * Builds the view until a CSS box edge is reached.\n * @param position start source position.\n * @param checkPoints array to append possible breaking points.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildViewToNextBlockEdge(\n position: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n let violateConstraint = false;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"buildViewToNextBlockEdge\",\n );\n frame\n .loopWithFrame((bodyFrame) => {\n if (position.viewNode && !LayoutHelper.isSpecialNodeContext(position)) {\n checkPoints.push(position.copy());\n }\n self.maybePeelOff(position, 0).then((position1Param) => {\n const position1 = position1Param as Vtree.NodeContext;\n if (position1 !== position) {\n position = position1;\n if (!LayoutHelper.isSpecialNodeContext(position)) {\n checkPoints.push(position.copy());\n }\n }\n self.nextInTree(position).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (!position) {\n // Exit the loop\n bodyFrame.breakLoop();\n return;\n }\n if (\n violateConstraint ||\n !self.layoutConstraint.allowLayout(position)\n ) {\n violateConstraint = true;\n position = position.modify();\n position.overflow = true;\n }\n if (self.isFloatNodeContext(position) && !self.vertical) {\n self.layoutFloatOrFootnote(position).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (self.pageFloatLayoutContext.isInvalidated()) {\n position = null;\n }\n if (!position) {\n bodyFrame.breakLoop();\n return;\n }\n bodyFrame.continueLoop();\n });\n } else if (!position.inline) {\n // Exit the loop\n bodyFrame.breakLoop();\n } else {\n // Continue the loop\n bodyFrame.continueLoop();\n }\n });\n });\n })\n .then(() => {\n frame.finish(position);\n });\n return frame.result();\n }\n\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext> {\n const cont = this.layoutContext.nextInTree(position, atUnforcedBreak);\n return processAfterIfContinues(cont, this);\n }\n\n /**\n * Builds the view for a single unbreakable element.\n * @param position start source position.\n * @return holding box edge position reached or null if the source is exhausted.\n */\n buildDeepElementView(\n position: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n if (!position.viewNode) {\n return Task.newResult(position);\n }\n let checkPoints: Vtree.NodeContext[] = [];\n const sourceNode = position.sourceNode;\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"buildDeepElementView\",\n );\n\n // TODO: end the loop based on depth, not sourceNode comparison\n frame\n .loopWithFrame((bodyFrame) => {\n if (\n position.viewNode &&\n position.inline &&\n !LayoutHelper.isSpecialNodeContext(position)\n ) {\n checkPoints.push(position.copy());\n } else {\n if (checkPoints.length > 0) {\n self.postLayoutBlock(position, checkPoints);\n }\n checkPoints = [];\n }\n self.maybePeelOff(position, 0).then((position1Param) => {\n const position1 = position1Param as Vtree.NodeContext;\n if (position1 !== position) {\n let p = position1;\n while (p && p.sourceNode != sourceNode) {\n p = p.parent;\n }\n if (p == null) {\n // outside of the subtree\n position = position1;\n bodyFrame.breakLoop();\n return;\n }\n if (!LayoutHelper.isSpecialNodeContext(position1)) {\n checkPoints.push(position1.copy());\n }\n }\n self.nextInTree(position1).then((positionParam) => {\n position = positionParam as Vtree.NodeContext;\n if (!position || position.sourceNode == sourceNode) {\n bodyFrame.breakLoop();\n } else if (!self.layoutConstraint.allowLayout(position)) {\n position = position.modify();\n position.overflow = true;\n if (self.stopAtOverflow) {\n bodyFrame.breakLoop();\n } else {\n bodyFrame.continueLoop();\n }\n } else {\n bodyFrame.continueLoop();\n }\n });\n });\n })\n .then(() => {\n if (checkPoints.length > 0) {\n self.postLayoutBlock(position, checkPoints);\n }\n frame.finish(position);\n });\n return frame.result();\n }\n\n /**\n * Create a single floating element (for exclusion areas).\n * @param ref container's child to insert float before (can be null).\n * @param side float side (\"left\" or \"right\").\n * @param width float inline dimension.\n * @param height float box progression dimension.\n * @return newly created float element.\n */\n createFloat(ref: Node, side: string, width: number, height: number): Element {\n const div = this.viewDocument.createElement(\"div\");\n if (this.vertical) {\n if (height >= this.height) {\n height -= 0.1;\n }\n Base.setCSSProperty(div, \"height\", `${width}px`);\n Base.setCSSProperty(div, \"width\", `${height}px`);\n } else {\n if (width >= this.width) {\n width -= 0.1;\n }\n Base.setCSSProperty(div, \"width\", `${width}px`);\n Base.setCSSProperty(div, \"height\", `${height}px`);\n }\n Base.setCSSProperty(div, \"float\", side);\n Base.setCSSProperty(div, \"clear\", side);\n\n // enable to visualize\n // Base.setCSSProperty(div, \"background-color\", \"#50F0FF\");\n this.element.insertBefore(div, ref);\n return div;\n }\n\n /**\n * Remove all the exclusion floats.\n */\n killFloats(): void {\n let c: Node = this.element.firstChild;\n while (c) {\n const nc = c.nextSibling;\n if (c.nodeType == 1) {\n const e = c as HTMLElement;\n const f = e.style.cssFloat;\n if (f == \"left\" || f == \"right\") {\n this.element.removeChild(e);\n } else {\n break;\n }\n }\n c = nc;\n }\n }\n\n /**\n * Create exclusion floats for a column.\n */\n createFloats(): void {\n const ref = this.element.firstChild;\n const bands = this.bands;\n const x1 = this.vertical ? this.getTopEdge() : this.getLeftEdge();\n const x2 = this.vertical ? this.getBottomEdge() : this.getRightEdge();\n for (const band of bands) {\n const height = band.y2 - band.y1;\n band.left = this.createFloat(ref, \"left\", band.x1 - x1, height);\n band.right = this.createFloat(ref, \"right\", x2 - band.x2, height);\n }\n }\n\n /**\n * @param nodeContext position after the block\n * @param checkPoints array of possible breaking points.\n * @param index index of the breaking point\n * @param boxOffset box offset\n * @return edge position\n */\n calculateEdge(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n index: number,\n boxOffset: number,\n ): number {\n let edge: number;\n if (nodeContext && LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return NaN;\n } else if (nodeContext && nodeContext.after && !nodeContext.inline) {\n edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n 0,\n this.vertical,\n );\n if (!isNaN(edge)) {\n return edge;\n }\n }\n nodeContext = checkPoints[index];\n let offset = boxOffset - nodeContext.boxOffset;\n while (true) {\n edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n offset,\n this.vertical,\n );\n if (!isNaN(edge)) {\n return edge;\n }\n if (offset > 0) {\n offset--;\n continue;\n }\n index--;\n if (index < 0) {\n return this.beforeEdge;\n }\n nodeContext = checkPoints[index];\n if (nodeContext.viewNode.nodeType != 1) {\n offset = nodeContext.viewNode.textContent.length;\n }\n }\n }\n\n /**\n * Parse CSS computed length (in pixels)\n * @param val CSS length in \"px\" units or a number.\n * @return value in pixels or 0 if not parsable\n */\n parseComputedLength(val: string | number): number {\n if (typeof val == \"number\") {\n return val;\n }\n const r = val.match(/^(-?[0-9]*(\\.[0-9]*)?)px$/);\n if (r) {\n return parseFloat(r[0]);\n }\n return 0;\n }\n\n /**\n * Reads element's computed CSS margin.\n */\n getComputedMargin(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n insets.left = this.parseComputedLength(style.marginLeft);\n insets.top = this.parseComputedLength(style.marginTop);\n insets.right = this.parseComputedLength(style.marginRight);\n insets.bottom = this.parseComputedLength(style.marginBottom);\n }\n return insets;\n }\n\n /**\n * Reads element's computed padding + borders.\n */\n getComputedPaddingBorder(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n insets.left =\n this.parseComputedLength(style.borderLeftWidth) +\n this.parseComputedLength(style.paddingLeft);\n insets.top =\n this.parseComputedLength(style.borderTopWidth) +\n this.parseComputedLength(style.paddingTop);\n insets.right =\n this.parseComputedLength(style.borderRightWidth) +\n this.parseComputedLength(style.paddingRight);\n insets.bottom =\n this.parseComputedLength(style.borderBottomWidth) +\n this.parseComputedLength(style.paddingBottom);\n }\n return insets;\n }\n\n /**\n * Reads element's computed CSS insets(margins + border + padding or margins :\n * depends on box-sizing)\n */\n getComputedInsets(element: Element): GeometryUtil.Insets {\n const style = this.clientLayout.getElementComputedStyle(element);\n const insets = new GeometryUtil.Insets(0, 0, 0, 0);\n if (style) {\n if (style.boxSizing == \"border-box\") {\n return this.getComputedMargin(element);\n }\n insets.left =\n this.parseComputedLength(style.marginLeft) +\n this.parseComputedLength(style.borderLeftWidth) +\n this.parseComputedLength(style.paddingLeft);\n insets.top =\n this.parseComputedLength(style.marginTop) +\n this.parseComputedLength(style.borderTopWidth) +\n this.parseComputedLength(style.paddingTop);\n insets.right =\n this.parseComputedLength(style.marginRight) +\n this.parseComputedLength(style.borderRightWidth) +\n this.parseComputedLength(style.paddingRight);\n insets.bottom =\n this.parseComputedLength(style.marginBottom) +\n this.parseComputedLength(style.borderBottomWidth) +\n this.parseComputedLength(style.paddingBottom);\n }\n return insets;\n }\n\n /**\n * Set element's computed CSS insets to Column Container\n */\n setComputedInsets(element: Element, container: Column) {\n const style = this.clientLayout.getElementComputedStyle(element);\n if (style) {\n container.marginLeft = this.parseComputedLength(style.marginLeft);\n container.borderLeft = this.parseComputedLength(style.borderLeftWidth);\n container.paddingLeft = this.parseComputedLength(style.paddingLeft);\n container.marginTop = this.parseComputedLength(style.marginTop);\n container.borderTop = this.parseComputedLength(style.borderTopWidth);\n container.paddingTop = this.parseComputedLength(style.paddingTop);\n container.marginRight = this.parseComputedLength(style.marginRight);\n container.borderRight = this.parseComputedLength(style.borderRightWidth);\n container.paddingRight = this.parseComputedLength(style.paddingRight);\n container.marginBottom = this.parseComputedLength(style.marginBottom);\n container.borderBottom = this.parseComputedLength(\n style.borderBottomWidth,\n );\n container.paddingBottom = this.parseComputedLength(style.paddingBottom);\n }\n }\n\n /**\n * Set element's computed width and height to Column Container\n */\n setComputedWidthAndHeight(element: Element, container: Column) {\n const style = this.clientLayout.getElementComputedStyle(element);\n if (style) {\n container.width = this.parseComputedLength(style.width);\n container.height = this.parseComputedLength(style.height);\n }\n }\n\n /**\n * Layout a single unbreakable element.\n */\n layoutUnbreakable(\n nodeContextIn: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n return this.buildDeepElementView(nodeContextIn);\n }\n\n /**\n * Layout a single float element.\n */\n layoutFloat(nodeContext: Vtree.NodeContext): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"layoutFloat\");\n const element = nodeContext.viewNode as Element;\n const floatSide = nodeContext.floatSide as string;\n Base.setCSSProperty(element, \"float\", \"none\");\n Base.setCSSProperty(element, \"display\", \"inline-block\");\n Base.setCSSProperty(element, \"vertical-align\", \"top\");\n self.buildDeepElementView(nodeContext).then((nodeContextAfter) => {\n const floatBBox = self.clientLayout.getElementClientRect(element);\n const margin = self.getComputedMargin(element);\n let floatBox = new GeometryUtil.Rect(\n floatBBox.left - margin.left,\n floatBBox.top - margin.top,\n floatBBox.right + margin.right,\n floatBBox.bottom + margin.bottom,\n );\n let x1 = self.startEdge;\n let x2 = self.endEdge;\n let parent = nodeContext.parent;\n while (parent && parent.inline) {\n parent = parent.parent;\n }\n if (parent) {\n // Position it at the parent element's edge.\n // We need to get the edge of the parent's content area, calling\n // getElementClientRect will also give us borders. Avoid it by creating\n // a temporary element and using it for measurment.\n const probe = parent.viewNode.ownerDocument.createElement(\"div\");\n probe.style.left = \"0px\";\n probe.style.top = \"0px\";\n if (self.vertical) {\n probe.style.bottom = \"0px\";\n probe.style.width = \"1px\";\n } else {\n probe.style.right = \"0px\";\n probe.style.height = \"1px\";\n }\n parent.viewNode.appendChild(probe);\n const parentBox = self.clientLayout.getElementClientRect(probe);\n x1 = Math.max(self.getStartEdge(parentBox), x1);\n x2 = Math.min(self.getEndEdge(parentBox), x2);\n parent.viewNode.removeChild(probe);\n const floatBoxMeasure = self.vertical\n ? floatBox.y2 - floatBox.y1\n : floatBox.x2 - floatBox.x1;\n if (floatSide == \"left\") {\n x2 = Math.max(x2, x1 + floatBoxMeasure);\n } else {\n x1 = Math.min(x1, x2 - floatBoxMeasure);\n }\n\n // Move the float below the block parent.\n // Otherwise, if the float is attached to an inline box with 'position:\n // relative', the absolute positioning of the float gets broken, since\n // the inline parent can be pushed horizontally by exclusion floats\n // after the layout of the float is done.\n parent.viewNode.appendChild(nodeContext.viewNode);\n }\n\n // box is rotated for vertical orientation\n let box = new GeometryUtil.Rect(\n x1,\n self.getBoxDir() * self.beforeEdge,\n x2,\n self.getBoxDir() * self.afterEdge,\n );\n let floatHorBox = floatBox;\n if (self.vertical) {\n floatHorBox = GeometryUtil.rotateBox(floatBox);\n }\n const dir = self.getBoxDir();\n if (floatHorBox.y1 < self.bottommostFloatTop * dir) {\n const boxExtent = floatHorBox.y2 - floatHorBox.y1;\n floatHorBox.y1 = self.bottommostFloatTop * dir;\n floatHorBox.y2 = floatHorBox.y1 + boxExtent;\n }\n GeometryUtil.positionFloat(box, self.bands, floatHorBox, floatSide);\n if (self.vertical) {\n floatBox = GeometryUtil.unrotateBox(floatHorBox);\n }\n const insets = self.getComputedInsets(element);\n Base.setCSSProperty(\n element,\n \"width\",\n `${floatBox.x2 - floatBox.x1 - insets.left - insets.right}px`,\n );\n Base.setCSSProperty(\n element,\n \"height\",\n `${floatBox.y2 - floatBox.y1 - insets.top - insets.bottom}px`,\n );\n Base.setCSSProperty(element, \"position\", \"absolute\");\n Asserts.assert(nodeContext.display);\n Base.setCSSProperty(element, \"display\", nodeContext.display);\n let offsets;\n let containingBlockForAbsolute: Vtree.NodeContext = null;\n if (parent) {\n if (parent.containingBlockForAbsolute) {\n containingBlockForAbsolute = parent;\n } else {\n containingBlockForAbsolute = parent.getContainingBlockForAbsolute();\n }\n }\n if (containingBlockForAbsolute) {\n const probe = containingBlockForAbsolute.viewNode.ownerDocument.createElement(\n \"div\",\n );\n probe.style.position = \"absolute\";\n if (containingBlockForAbsolute.vertical) {\n probe.style.right = \"0\";\n } else {\n probe.style.left = \"0\";\n }\n probe.style.top = \"0\";\n containingBlockForAbsolute.viewNode.appendChild(probe);\n offsets = self.clientLayout.getElementClientRect(probe);\n containingBlockForAbsolute.viewNode.removeChild(probe);\n } else {\n offsets = {\n left: self.getLeftEdge() - self.paddingLeft,\n right: self.getRightEdge() + self.paddingRight,\n top: self.getTopEdge() - self.paddingTop,\n };\n }\n if (\n containingBlockForAbsolute\n ? containingBlockForAbsolute.vertical\n : self.vertical\n ) {\n Base.setCSSProperty(\n element,\n \"right\",\n `${offsets.right - floatBox.x2}px`,\n );\n } else {\n Base.setCSSProperty(element, \"left\", `${floatBox.x1 - offsets.left}px`);\n }\n Base.setCSSProperty(element, \"top\", `${floatBox.y1 - offsets.top}px`);\n if (nodeContext.clearSpacer) {\n nodeContext.clearSpacer.parentNode.removeChild(nodeContext.clearSpacer);\n nodeContext.clearSpacer = null;\n }\n const floatBoxEdge = self.vertical ? floatBox.x1 : floatBox.y2;\n const floatBoxTop = self.vertical ? floatBox.x2 : floatBox.y1;\n\n // TODO: subtract after margin when determining overflow.\n if (!self.isOverflown(floatBoxEdge) || self.breakPositions.length == 0) {\n // no overflow\n self.killFloats();\n box = new GeometryUtil.Rect(\n self.getLeftEdge(),\n self.getTopEdge(),\n self.getRightEdge(),\n self.getBottomEdge(),\n );\n if (self.vertical) {\n box = GeometryUtil.rotateBox(box);\n }\n GeometryUtil.addFloatToBands(\n box,\n self.bands,\n floatHorBox,\n null,\n floatSide,\n );\n self.createFloats();\n if (floatSide == \"left\") {\n self.leftFloatEdge = floatBoxEdge;\n } else {\n self.rightFloatEdge = floatBoxEdge;\n }\n self.bottommostFloatTop = floatBoxTop;\n self.updateMaxReachedAfterEdge(floatBoxEdge);\n frame.finish(nodeContextAfter);\n } else {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n frame.finish(nodeContext);\n }\n });\n return frame.result();\n }\n\n setupFloatArea(\n area: PageFloatArea,\n floatReference: PageFloats.FloatReference,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): boolean {\n const floatLayoutContext = this.pageFloatLayoutContext;\n const floatContainer = floatLayoutContext.getContainer(floatReference);\n const element = area.element;\n floatContainer.element.parentNode.appendChild(element);\n area.isFloat = true;\n area.originX = floatContainer.originX;\n area.originY = floatContainer.originY;\n area.vertical = floatContainer.vertical;\n area.marginLeft = area.marginRight = area.marginTop = area.marginBottom = 0;\n area.borderLeft = area.borderRight = area.borderTop = area.borderBottom = 0;\n area.paddingLeft = area.paddingRight = area.paddingTop = area.paddingBottom = 0;\n area.exclusions = (floatContainer.exclusions || []).concat();\n area.forceNonfitting = !floatLayoutContext.hasFloatFragments();\n area.innerShape = null;\n const containingBlockRect = floatContainer.getPaddingRect();\n area.setHorizontalPosition(\n containingBlockRect.x1 - floatContainer.originX,\n containingBlockRect.x2 - containingBlockRect.x1,\n );\n area.setVerticalPosition(\n containingBlockRect.y1 - floatContainer.originY,\n containingBlockRect.y2 - containingBlockRect.y1,\n );\n strategy.adjustPageFloatArea(area, floatContainer, this);\n\n // Calculate bands from the exclusions before setting float area dimensions\n area.init();\n const fitWithinContainer = !!floatLayoutContext.setFloatAreaDimensions(\n area,\n floatReference,\n floatSide,\n anchorEdge,\n true,\n !floatLayoutContext.hasFloatFragments(),\n condition,\n );\n if (fitWithinContainer) {\n // New dimensions have been set, remove exclusion floats and re-init\n area.killFloats();\n area.init();\n } else {\n floatContainer.element.parentNode.removeChild(element);\n }\n return fitWithinContainer;\n }\n\n createPageFloatArea(\n float: PageFloats.PageFloat | null,\n floatSide: string,\n anchorEdge: number | null,\n strategy: PageFloats.PageFloatLayoutStrategy,\n condition: PageFloats.PageFloatPlacementCondition,\n ): PageFloatArea | null {\n const floatAreaElement = this.element.ownerDocument.createElement(\"div\");\n Base.setCSSProperty(floatAreaElement, \"position\", \"absolute\");\n const parentPageFloatLayoutContext = this.pageFloatLayoutContext.getPageFloatLayoutContext(\n float.floatReference,\n );\n\n // TODO: establish how to specify an appropriate generating element for the\n // new page float layout context\n const pageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n null,\n PageFloats.FloatReference.COLUMN,\n null,\n this.pageFloatLayoutContext.flowName,\n float.nodePosition,\n null,\n null,\n );\n const parentContainer = parentPageFloatLayoutContext.getContainer();\n const floatArea = new PageFloatArea(\n floatSide,\n floatAreaElement,\n this.layoutContext.clone(),\n this.clientLayout,\n this.layoutConstraint,\n pageFloatLayoutContext,\n parentContainer,\n );\n pageFloatLayoutContext.setContainer(floatArea);\n if (\n this.setupFloatArea(\n floatArea,\n float.floatReference,\n floatSide,\n anchorEdge,\n strategy,\n condition,\n )\n ) {\n return floatArea;\n } else {\n return null;\n }\n }\n\n layoutSinglePageFloatFragment(\n continuations: PageFloats.PageFloatContinuation[],\n floatSide: string,\n clearSide: string | null,\n allowFragmented: boolean,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment | null,\n ): Task.Result<SinglePageFloatLayoutResult> {\n const context = this.pageFloatLayoutContext;\n const originalContinuations = pageFloatFragment\n ? pageFloatFragment.continuations\n : [];\n continuations = originalContinuations.concat(continuations);\n const firstFloat = continuations[0].float;\n const condition = context.getPageFloatPlacementCondition(\n firstFloat,\n floatSide,\n clearSide,\n );\n const floatArea = this.createPageFloatArea(\n firstFloat,\n floatSide,\n anchorEdge,\n strategy,\n condition,\n );\n const result: SinglePageFloatLayoutResult = {\n floatArea,\n pageFloatFragment: null,\n newPosition: null,\n };\n if (!floatArea) {\n return Task.newResult(result);\n }\n const frame = Task.newFrame<SinglePageFloatLayoutResult>(\n \"layoutSinglePageFloatFragment\",\n );\n let failed = false;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i >= continuations.length) {\n loopFrame.breakLoop();\n return;\n }\n const c = continuations[i];\n const floatChunkPosition = new VtreeImpl.ChunkPosition(c.nodePosition);\n floatArea.layout(floatChunkPosition, true).then((newPosition) => {\n result.newPosition = newPosition;\n if (!newPosition || allowFragmented) {\n i++;\n loopFrame.continueLoop();\n } else {\n failed = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n if (!failed) {\n Asserts.assert(floatArea);\n const logicalFloatSide = context.setFloatAreaDimensions(\n floatArea,\n firstFloat.floatReference,\n floatSide,\n anchorEdge,\n false,\n allowFragmented,\n condition,\n );\n if (!logicalFloatSide) {\n failed = true;\n } else {\n const newFragment = strategy.createPageFloatFragment(\n continuations,\n logicalFloatSide,\n floatArea,\n !!result.newPosition,\n );\n context.addPageFloatFragment(newFragment, true);\n result.pageFloatFragment = newFragment;\n }\n }\n frame.finish(result);\n });\n return frame.result();\n }\n\n layoutPageFloatInner(\n continuation: PageFloats.PageFloatContinuation,\n strategy: PageFloats.PageFloatLayoutStrategy,\n anchorEdge: number | null,\n pageFloatFragment?: PageFloats.PageFloatFragment,\n ): Task.Result<boolean> {\n const context = this.pageFloatLayoutContext;\n const float = continuation.float;\n context.stashEndFloatFragments(float);\n\n function cancelLayout(floatArea, pageFloatFragment) {\n if (pageFloatFragment) {\n context.removePageFloatFragment(pageFloatFragment, true);\n } else if (floatArea) {\n floatArea.element.parentNode.removeChild(floatArea.element);\n }\n context.restoreStashedFragments(float.floatReference);\n context.deferPageFloat(continuation);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutPageFloatInner\");\n const self = this;\n this.layoutSinglePageFloatFragment(\n [continuation],\n float.floatSide,\n float.clearSide,\n !context.hasFloatFragments(),\n strategy,\n anchorEdge,\n pageFloatFragment,\n ).then((result) => {\n const floatArea = result.floatArea;\n const newFragment = result.pageFloatFragment;\n const newPosition = result.newPosition;\n if (newFragment) {\n self\n .layoutStashedPageFloats(float.floatReference, [pageFloatFragment])\n .then((success) => {\n if (success) {\n // Add again to invalidate the context\n Asserts.assert(newFragment);\n context.addPageFloatFragment(newFragment);\n context.discardStashedFragments(float.floatReference);\n if (newPosition) {\n const continuation = new PageFloats.PageFloatContinuation(\n float,\n newPosition.primary,\n );\n context.deferPageFloat(continuation);\n }\n frame.finish(true);\n } else {\n cancelLayout(floatArea, newFragment);\n frame.finish(false);\n }\n });\n } else {\n cancelLayout(floatArea, newFragment);\n frame.finish(false);\n }\n });\n return frame.result();\n }\n\n /**\n * @returns Represents if the layout was succeeded or not\n */\n private layoutStashedPageFloats(\n floatReference: PageFloats.FloatReference,\n excluded: PageFloats.PageFloatFragment[],\n ): Task.Result<boolean> {\n const context = this.pageFloatLayoutContext;\n const stashedFloatFragments = context.getStashedFloatFragments(\n floatReference,\n );\n const newFloatAreas = [];\n const newFragments = [];\n let failed = false;\n const frame = Task.newFrame<boolean>(\"layoutStashedPageFloats\");\n const self = this;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i >= stashedFloatFragments.length) {\n loopFrame.breakLoop();\n return;\n }\n const stashedFragment = stashedFloatFragments[i];\n if (excluded.includes(stashedFragment)) {\n i++;\n loopFrame.continueLoop();\n return;\n }\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByFloat(\n stashedFragment.continuations[0].float,\n );\n\n // Value of 'clear' is irrelevant when laying out stashed floats\n // since whether the 'clear' value allows placing the float\n // here is already resolved.\n self\n .layoutSinglePageFloatFragment(\n stashedFragment.continuations,\n stashedFragment.floatSide,\n null,\n false,\n strategy,\n null,\n )\n .then((result) => {\n const floatArea = result.floatArea;\n if (floatArea) {\n newFloatAreas.push(floatArea);\n }\n const fragment = result.pageFloatFragment;\n if (fragment) {\n newFragments.push(fragment);\n i++;\n loopFrame.continueLoop();\n } else {\n failed = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n if (failed) {\n newFragments.forEach((fragment) => {\n context.removePageFloatFragment(fragment, true);\n });\n newFloatAreas.forEach((area) => {\n const elem = area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n } else {\n stashedFloatFragments.forEach((fragment) => {\n const elem = fragment.area.element;\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n });\n }\n frame.finish(!failed);\n });\n return frame.result();\n }\n\n setFloatAnchorViewNode(nodeContext: Vtree.NodeContext): Vtree.NodeContext {\n const parent = nodeContext.viewNode.parentNode;\n const anchor = parent.ownerDocument.createElement(\"span\");\n anchor.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n if (nodeContext.floatSide === \"footnote\") {\n // Defaults for footnote-call, can be overriden by the stylesheet.\n this.layoutContext.applyPseudoelementStyle(\n nodeContext,\n \"footnote-call\",\n anchor,\n );\n }\n parent.appendChild(anchor);\n parent.removeChild(nodeContext.viewNode);\n const nodeContextAfter = nodeContext.modify();\n nodeContextAfter.after = true;\n nodeContextAfter.viewNode = anchor;\n return nodeContextAfter;\n }\n\n resolveFloatReferenceFromColumnSpan(\n floatReference: PageFloats.FloatReference,\n columnSpan: Css.Val,\n nodeContext: Vtree.NodeContext,\n ): Task.Result<PageFloats.FloatReference> {\n const self = this;\n const frame = Task.newFrame(\n \"resolveFloatReferenceFromColumnSpan\",\n ) as Task.Frame<PageFloats.FloatReference>;\n const columnContext = this.pageFloatLayoutContext;\n const regionContext = columnContext.getPageFloatLayoutContext(\n PageFloats.FloatReference.REGION,\n );\n const isRegionWider =\n columnContext.getContainer().width < regionContext.getContainer().width;\n if (isRegionWider && floatReference === PageFloats.FloatReference.COLUMN) {\n if (columnSpan === Css.ident.auto) {\n this.buildDeepElementView(nodeContext.copy()).then((position) => {\n const element = position.viewNode as Element;\n let inlineSize = Sizing.getSize(self.clientLayout, element, [\n Sizing.Size.MIN_CONTENT_INLINE_SIZE,\n ])[Sizing.Size.MIN_CONTENT_INLINE_SIZE];\n const margin = self.getComputedMargin(element);\n if (self.vertical) {\n inlineSize += margin.top + margin.bottom;\n } else {\n inlineSize += margin.left + margin.right;\n }\n if (inlineSize > self.width) {\n frame.finish(PageFloats.FloatReference.REGION);\n } else {\n frame.finish(floatReference);\n }\n });\n } else if (columnSpan === Css.ident.all) {\n frame.finish(PageFloats.FloatReference.REGION);\n } else {\n frame.finish(floatReference);\n }\n } else {\n frame.finish(floatReference);\n }\n return frame.result();\n }\n\n layoutPageFloat(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const context = this.pageFloatLayoutContext;\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByNodeContext(\n nodeContext,\n );\n let cont: Task.Result<PageFloats.PageFloat>;\n const float = context.findPageFloatByNodePosition(\n nodeContext.toNodePosition(),\n );\n if (!float) {\n cont = strategy.createPageFloat(nodeContext, context, this);\n } else {\n cont = Task.newResult(float);\n }\n return cont.thenAsync((float) => {\n const nodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n const nodeContextAfter = self.setFloatAnchorViewNode(nodeContext);\n const pageFloatFragment = strategy.findPageFloatFragment(float, context);\n const continuation = new PageFloats.PageFloatContinuation(\n float,\n nodePosition,\n );\n if (pageFloatFragment && pageFloatFragment.hasFloat(float)) {\n context.registerPageFloatAnchor(float, nodeContextAfter.viewNode);\n return Task.newResult(nodeContextAfter as Vtree.NodeContext);\n } else if (\n context.isForbidden(float) ||\n context.hasPrecedingFloatsDeferredToNext(float)\n ) {\n context.deferPageFloat(continuation);\n context.registerPageFloatAnchor(float, nodeContextAfter.viewNode);\n return Task.newResult(nodeContextAfter as Vtree.NodeContext);\n } else if (self.nodeContextOverflowingDueToRepetitiveElements) {\n return Task.newResult(null);\n } else {\n const edge = LayoutHelper.calculateEdge(\n nodeContextAfter,\n self.clientLayout,\n 0,\n self.vertical,\n );\n if (self.isOverflown(edge)) {\n return Task.newResult(nodeContextAfter);\n } else {\n return self\n .layoutPageFloatInner(\n continuation,\n strategy,\n edge,\n pageFloatFragment,\n )\n .thenAsync((success) => {\n Asserts.assert(float);\n if (!success) {\n context.registerPageFloatAnchor(\n float,\n nodeContextAfter.viewNode,\n );\n return Task.newResult(nodeContextAfter);\n } else {\n return Task.newResult(null);\n }\n });\n }\n }\n });\n }\n\n createJustificationAdjustmentElement(\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n vertical: boolean,\n ): HTMLElement {\n const span = doc.createElement(\"span\") as HTMLElement;\n span.style.visibility = \"hidden\";\n span.style.verticalAlign = \"top\";\n span.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n const inner = doc.createElement(\"span\") as HTMLElement;\n inner.style.fontSize = \"0\";\n inner.style.lineHeight = \"0\";\n inner.textContent = \" #\";\n span.appendChild(inner);\n\n // Measure inline-start and inline-end edge positions of the line box,\n // taking (exclusion) floats into consideration\n span.style.display = \"block\";\n span.style.textIndent = \"0\";\n span.style.textAlign = \"left\";\n parentNode.insertBefore(span, insertionPoint);\n const leftPos = this.clientLayout.getElementClientRect(inner);\n span.style.textAlign = \"right\";\n const rightPos = this.clientLayout.getElementClientRect(inner);\n span.style.textAlign = \"\";\n if (Base.checkInlineBlockJustificationBug(document.body)) {\n // For Chrome\n span.style.display = \"inline\";\n } else {\n // For Firefox, Edge and IE\n span.style.display = \"inline-block\";\n }\n const padding = vertical\n ? rightPos.top - leftPos.top\n : rightPos.left - leftPos.left;\n const paddingStr = padding >= 1 ? `${padding - 1}px` : \"100%\";\n if (vertical) {\n span.style.paddingTop = paddingStr;\n } else {\n span.style.paddingLeft = paddingStr;\n }\n return span;\n }\n\n addAndAdjustJustificationElement(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n doc: Document,\n parentNode: Node,\n ): HTMLElement {\n fixJustificationOnHyphen(nodeContext, insertAfter, node, insertionPoint);\n return this.createJustificationAdjustmentElement(\n insertionPoint,\n doc,\n parentNode,\n nodeContext.vertical,\n );\n }\n\n compensateJustificationLineHeight(\n span: Element,\n br: Element,\n nodeContext: Vtree.NodeContext,\n ) {\n const spanRect = this.clientLayout.getElementClientRect(span);\n const brRect = this.clientLayout.getElementClientRect(br);\n if (nodeContext.vertical) {\n (br as HTMLElement).style.marginRight = `${brRect.right -\n spanRect.right}px`;\n (br as HTMLElement).style.width = \"0px\";\n } else {\n (br as HTMLElement).style.marginTop = `${spanRect.top - brRect.top}px`;\n (br as HTMLElement).style.height = \"0px\";\n }\n br.setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n }\n\n /**\n * Fix justification of the last line of text broken across pages (if\n * needed).\n */\n fixJustificationIfNeeded(\n nodeContext: Vtree.NodeContext,\n endOfColumn: boolean,\n ): void {\n if (nodeContext.after && !nodeContext.inline) {\n return;\n }\n if (endOfColumn) {\n let textAlign = \"\";\n for (\n let parent = nodeContext.parent;\n parent && !textAlign;\n parent = parent.parent\n ) {\n if (!parent.inline && parent.viewNode) {\n textAlign = (parent.viewNode as HTMLElement).style.textAlign;\n }\n }\n if (textAlign !== \"justify\") {\n return;\n }\n }\n const node = nodeContext.viewNode;\n const doc = node.ownerDocument;\n const insertAfter =\n endOfColumn && (nodeContext.after || node.nodeType != 1);\n let insertionPoint = insertAfter ? node.nextSibling : node;\n if (insertionPoint && !insertionPoint.parentNode) {\n // Possible if removeSelf = false in finishBreak()\n insertionPoint = null;\n }\n const parentNode =\n node.parentNode || (nodeContext.parent && nodeContext.parent.viewNode);\n if (!parentNode) {\n // Possible if nothing was added to the column\n return;\n }\n const span = this.addAndAdjustJustificationElement(\n nodeContext,\n insertAfter,\n node,\n insertionPoint,\n doc,\n parentNode,\n );\n if (!endOfColumn) {\n const br = doc.createElement(\"div\") as HTMLElement;\n parentNode.insertBefore(br, insertionPoint);\n this.compensateJustificationLineHeight(span, br, nodeContext);\n }\n }\n\n processLineStyling(\n nodeContext: Vtree.NodeContext,\n resNodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"processLineStyling\",\n );\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n let lastCheckPoints = checkPoints.concat([]); // make a copy\n checkPoints.splice(0, checkPoints.length); // make empty\n let totalLineCount = 0;\n let firstPseudo = nodeContext.firstPseudo; // :first-letter is not processed here\n if (firstPseudo.count == 0) {\n firstPseudo = firstPseudo.outer; // move to line pseudoelement (if any)\n }\n frame\n .loopWithFrame((loopFrame) => {\n if (!firstPseudo) {\n loopFrame.breakLoop();\n return;\n }\n const linePositions = self.findLinePositions(lastCheckPoints);\n const count = firstPseudo.count - totalLineCount;\n if (linePositions.length <= count) {\n loopFrame.breakLoop();\n return;\n }\n const lineBreak = self.findAcceptableBreakInside(\n lastCheckPoints,\n linePositions[count - 1],\n true,\n );\n if (lineBreak == null) {\n loopFrame.breakLoop();\n return;\n }\n self.finishBreak(lineBreak, false, false).then(() => {\n totalLineCount += count;\n self.layoutContext\n .peelOff(lineBreak, 0)\n .then((resNodeContextParam) => {\n nodeContext = resNodeContextParam;\n self.fixJustificationIfNeeded(nodeContext, false);\n firstPseudo = nodeContext.firstPseudo;\n lastCheckPoints = []; // Wipe out line breaks inside pseudoelements\n self\n .buildViewToNextBlockEdge(nodeContext, lastCheckPoints)\n .then((resNodeContextParam) => {\n resNodeContext = resNodeContextParam;\n loopFrame.continueLoop();\n });\n });\n });\n })\n .then(() => {\n Array.prototype.push.apply(checkPoints, lastCheckPoints);\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n frame.finish(resNodeContext);\n });\n return frame.result();\n }\n\n isLoneImage(checkPoints: Vtree.NodeContext[]): boolean {\n if (checkPoints.length != 2 && this.breakPositions.length > 0) {\n return false;\n }\n return (\n checkPoints[0].sourceNode == checkPoints[1].sourceNode &&\n mediaTags[(checkPoints[0].sourceNode as Element).localName]\n );\n }\n\n getTrailingMarginEdgeAdjustment(\n trailingEdgeContexts: Vtree.NodeContext[],\n ): number {\n // Margins push the computed height, but are not counted as overflow. We\n // need to find the overall collapsed margin from all enclosed blocks.\n let maxPos = 0;\n let minNeg = 0;\n for (let i = trailingEdgeContexts.length - 1; i >= 0; i--) {\n const nodeContext = trailingEdgeContexts[i];\n if (\n !nodeContext.after ||\n !nodeContext.viewNode ||\n nodeContext.viewNode.nodeType != 1\n ) {\n break;\n }\n const margin = this.getComputedMargin(nodeContext.viewNode as Element);\n const m = this.vertical ? -margin.left : margin.bottom;\n if (m > 0) {\n maxPos = Math.max(maxPos, m);\n } else {\n minNeg = Math.min(minNeg, m);\n }\n }\n return maxPos - minNeg;\n }\n\n /**\n * Layout a single CSS box.\n */\n layoutBreakableBlock(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"layoutBreakableBlock\",\n );\n const checkPoints: Vtree.NodeContext[] = [];\n self\n .buildViewToNextBlockEdge(nodeContext, checkPoints)\n .then((resNodeContext) => {\n // at this point a single block was appended to the column\n // flowPosition is either null or\n // - if !after: contains view for the next block element\n // - if after: contains view for the enclosing block element\n const checkPointIndex = checkPoints.length - 1;\n if (checkPointIndex < 0) {\n frame.finish(resNodeContext);\n return;\n }\n\n // Record the height\n // TODO: should this be done after first-line calculation?\n let edge = self.calculateEdge(\n resNodeContext,\n checkPoints,\n checkPointIndex,\n checkPoints[checkPointIndex].boxOffset,\n );\n let overflown = false;\n if (\n !resNodeContext ||\n !LayoutHelper.isOrphan(resNodeContext.viewNode)\n ) {\n const offsets = BreakPosition.calculateOffset(\n resNodeContext,\n self.collectElementsOffset(),\n );\n overflown = self.isOverflown(\n edge + (self.vertical ? -1 : 1) * offsets.minimum,\n );\n if (\n self.isOverflown(\n edge + (self.vertical ? -1 : 1) * offsets.current,\n ) &&\n !self.nodeContextOverflowingDueToRepetitiveElements\n ) {\n self.nodeContextOverflowingDueToRepetitiveElements = resNodeContext;\n }\n }\n if (resNodeContext == null) {\n edge += self.getTrailingMarginEdgeAdjustment(checkPoints);\n }\n self.updateMaxReachedAfterEdge(edge);\n let lineCont: Task.Result<Vtree.NodeContext>;\n if (nodeContext.firstPseudo) {\n // possibly need to deal with :first-line and friends\n lineCont = self.processLineStyling(\n nodeContext,\n resNodeContext,\n checkPoints,\n );\n } else {\n lineCont = Task.newResult(resNodeContext);\n }\n lineCont.then((nodeContext) => {\n self.postLayoutBlock(nodeContext, checkPoints);\n if (checkPoints.length > 0) {\n self.saveBoxBreakPosition(checkPoints);\n\n // TODO: how to signal overflow in the last pagargaph???\n if (overflown && !self.isLoneImage(checkPoints) && nodeContext) {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n }\n }\n frame.finish(nodeContext);\n });\n });\n return frame.result();\n }\n\n postLayoutBlock(\n nodeContext: Vtree.NodeContext,\n checkPoints: Vtree.NodeContext[],\n ) {\n const hooks: Plugin.PostLayoutBlockHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.POST_LAYOUT_BLOCK,\n );\n hooks.forEach((hook) => {\n hook(nodeContext, checkPoints, this);\n });\n }\n\n findEndOfLine(\n linePosition: number,\n checkPoints: Vtree.NodeContext[],\n isUpdateMaxReachedAfterEdge: boolean,\n ): {\n nodeContext: Vtree.NodeContext;\n index: number;\n checkPointIndex: number;\n } {\n if (VIVLIOSTYLE_DEBUG) {\n validateCheckPoints(checkPoints);\n }\n\n // Workaround for Blink not returning correct fractional values for\n // Range.getClientRects.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=629828\n const effectiveLinePosition = this.vertical\n ? linePosition - 1\n : linePosition + 1;\n\n // find the first character which is out\n let lowCP = 0;\n let low = checkPoints[0].boxOffset;\n let low1 = lowCP;\n let highCP = checkPoints.length - 1;\n let high = checkPoints[highCP].boxOffset;\n let mid: number;\n while (low < high) {\n mid = low + Math.ceil((high - low) / 2);\n\n // find the node which contains mid index\n low1 = lowCP;\n let high1 = highCP;\n while (low1 < high1) {\n const mid1 = low1 + Math.ceil((high1 - low1) / 2);\n if (checkPoints[mid1].boxOffset > mid) {\n high1 = mid1 - 1;\n } else {\n low1 = mid1;\n }\n }\n const edge = this.calculateEdge(null, checkPoints, low1, mid);\n if (\n this.vertical\n ? edge <= effectiveLinePosition\n : edge >= effectiveLinePosition\n ) {\n high = mid - 1;\n while (checkPoints[low1].boxOffset == mid) {\n low1--;\n }\n highCP = low1;\n } else {\n if (isUpdateMaxReachedAfterEdge) {\n this.updateMaxReachedAfterEdge(edge);\n }\n low = mid;\n lowCP = low1;\n }\n }\n return {\n nodeContext: checkPoints[low1],\n index: low,\n checkPointIndex: low1,\n };\n }\n\n findAcceptableBreakInside(\n checkPoints: Vtree.NodeContext[],\n edgePosition: number,\n force: boolean,\n ): Vtree.NodeContext {\n const position = this.findEndOfLine(edgePosition, checkPoints, true);\n let nodeContext = position.nodeContext;\n const viewNode = nodeContext.viewNode;\n if (viewNode.nodeType != 1) {\n const textNode = viewNode as Text;\n const textNodeBreaker = this.resolveTextNodeBreaker(nodeContext);\n nodeContext = textNodeBreaker.breakTextNode(\n textNode,\n nodeContext,\n position.index,\n checkPoints,\n position.checkPointIndex,\n force,\n );\n }\n this.clearOverflownViewNodes(nodeContext, false);\n return nodeContext;\n }\n\n resolveTextNodeBreaker(nodeContext: Vtree.NodeContext): TextNodeBreaker {\n const hooks: Plugin.ResolveTextNodeBreakerHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_TEXT_NODE_BREAKER,\n );\n return hooks.reduce(\n (prev, hook) => hook(nodeContext) || prev,\n TextNodeBreaker.instance,\n );\n }\n\n /**\n * Read ranges skipping special elments\n */\n getRangeBoxes(start: Node, end: Node): Vtree.ClientRect[] {\n const arr = [];\n const range = start.ownerDocument.createRange();\n let wentUp = false;\n let node = start;\n let lastGood: Node = null;\n let haveStart = false;\n let endNotReached = true;\n while (endNotReached) {\n let seekRange = true;\n do {\n let next: Node = null;\n if (node == end) {\n if (end.nodeType === 1) {\n // If end is an element, continue traversing its children to find\n // the last text node inside it. Finish when end has no child or\n // when came back from its children (wentUp==true).\n endNotReached = !(!end.firstChild || wentUp);\n } else {\n endNotReached = false;\n }\n }\n if (node.nodeType != 1) {\n if (!haveStart) {\n range.setStartBefore(node);\n haveStart = true;\n }\n lastGood = node;\n } else if (wentUp) {\n wentUp = false;\n } else if (LayoutHelper.isSpecial(node as Element)) {\n // Skip special\n seekRange = !haveStart;\n } else if (\n (node as Element).localName == \"ruby\" ||\n isSpecialInlineDisplay(\n this.clientLayout.getElementComputedStyle(node as Element).display,\n )\n ) {\n // ruby, inline-block, etc.\n seekRange = !haveStart;\n if (seekRange) {\n range.setStartBefore(node);\n haveStart = true;\n lastGood = node;\n }\n if (node.contains(end)) {\n endNotReached = false;\n }\n } else {\n next = node.firstChild;\n }\n if (!next) {\n next = node.nextSibling;\n if (!next) {\n wentUp = true;\n next = node.parentNode;\n }\n }\n node = next;\n } while (seekRange && endNotReached);\n if (haveStart) {\n range.setEndAfter(lastGood);\n const boxList = this.clientLayout.getRangeClientRects(range);\n for (let i = 0; i < boxList.length; i++) {\n arr.push(boxList[i]);\n }\n haveStart = false;\n }\n }\n return arr;\n }\n\n /**\n * Give block's initial and final nodes, find positions of the line bottoms.\n * This is, of course, somewhat hacky implementation.\n * @return position of line breaks\n */\n findLinePositions(checkPoints: Vtree.NodeContext[]): number[] {\n const LOW_OVERLAP = 0.2;\n const MID_OVERLAP = 0.6;\n const positions = [];\n const boxes = this.getRangeBoxes(\n checkPoints[0].viewNode,\n checkPoints[checkPoints.length - 1].viewNode,\n );\n boxes.sort(\n this.vertical\n ? VtreeImpl.clientrectDecreasingRight\n : VtreeImpl.clientrectIncreasingTop,\n );\n let lineBefore = 0;\n let lineAfter = 0;\n let lineEnd = 0;\n let lineLength = 0;\n let i = 0;\n const dir = this.getBoxDir();\n while (true) {\n if (i < boxes.length) {\n const box = boxes[i];\n let overlap = 1;\n if (lineLength > 0) {\n const boxSize = Math.max(this.getBoxSize(box), 1);\n if (dir * this.getBeforeEdge(box) < dir * lineBefore) {\n overlap = (dir * (this.getAfterEdge(box) - lineBefore)) / boxSize;\n } else if (dir * this.getAfterEdge(box) > dir * lineAfter) {\n overlap = (dir * (lineAfter - this.getBeforeEdge(box))) / boxSize;\n } else {\n overlap = 1;\n }\n }\n if (\n lineLength == 0 ||\n overlap >= MID_OVERLAP ||\n (overlap >= LOW_OVERLAP && this.getStartEdge(box) >= lineEnd - 1)\n ) {\n lineEnd = this.getEndEdge(box);\n if (this.vertical) {\n lineBefore =\n lineLength == 0 ? box.right : Math.max(lineBefore, box.right);\n lineAfter =\n lineLength == 0 ? box.left : Math.min(lineAfter, box.left);\n } else {\n lineBefore =\n lineLength == 0 ? box.top : Math.min(lineBefore, box.top);\n lineAfter =\n lineLength == 0 ? box.bottom : Math.max(lineAfter, box.bottom);\n }\n lineLength++;\n i++;\n continue;\n }\n }\n\n // Add line\n if (lineLength > 0) {\n positions.push(lineAfter);\n lineLength = 0;\n }\n if (i >= boxes.length) {\n break;\n }\n }\n positions.sort(Base.numberCompare);\n if (this.vertical) {\n positions.reverse();\n }\n return positions;\n }\n\n calculateClonedPaddingBorder(nodeContext: Vtree.NodeContext): number {\n let clonedPaddingBorder = 0;\n nodeContext.walkUpBlocks((block) => {\n if (block.inheritedProps[\"box-decoration-break\"] === \"clone\") {\n Asserts.assert(block.viewNode instanceof Element);\n const paddingBorders = this.getComputedPaddingBorder(\n block.viewNode as Element,\n );\n clonedPaddingBorder += block.vertical\n ? -paddingBorders.left\n : paddingBorders.bottom;\n if (block.display === \"table\") {\n clonedPaddingBorder += block.blockBorderSpacing;\n }\n }\n });\n return clonedPaddingBorder;\n }\n\n private getOffsetByRepetitiveElements(\n bp?: BreakPosition.BreakPosition,\n ): number {\n let offset: { current: number; minimum: number };\n if (bp) {\n offset = bp.calculateOffset(this);\n } else {\n offset = BreakPosition.calculateOffset(\n null,\n this.collectElementsOffset(),\n );\n }\n return offset.current;\n }\n\n findBoxBreakPosition(\n bp: BoxBreakPosition,\n force: boolean,\n ): Vtree.NodeContext {\n const self = this;\n const checkPoints = bp.checkPoints;\n let block = checkPoints[0];\n while (block.parent && block.inline) {\n block = block.parent;\n }\n let widows: number;\n let orphans: number;\n if (force) {\n // Last resort, ignore widows/orphans\n widows = 1;\n orphans = 1;\n } else {\n // Get widows/orphans settings from the block element\n widows = Math.max(\n ((block.inheritedProps[\"widows\"] as number) || 2) - 0,\n 1,\n );\n orphans = Math.max(\n ((block.inheritedProps[\"orphans\"] as number) || 2) - 0,\n 1,\n );\n }\n\n // In case of box-decoration-break: clone, width (or height in vertical\n // writing mode) of cloned paddings and borders should be taken into\n // account.\n const clonedPaddingBorder = self.calculateClonedPaddingBorder(block);\n\n // Select the first overflowing line break position\n const linePositions = this.findLinePositions(checkPoints);\n let edge = this.footnoteEdge - clonedPaddingBorder;\n const dir = this.getBoxDir();\n const repetitiveElementsOffset = this.getOffsetByRepetitiveElements(bp);\n edge -= dir * repetitiveElementsOffset;\n\n // If an \"overflowing\" checkpoint (e.g. not allowed by LayoutConstraint)\n // exists before the edge, a line containing the checkpoint should be\n // deferred to the next column.\n const firstOverflowing = this.findFirstOverflowingEdgeAndCheckPoint(\n checkPoints,\n );\n if (isNaN(firstOverflowing.edge)) {\n firstOverflowing.edge = dir * Infinity;\n }\n let lineIndex = Base.binarySearch(linePositions.length, (i) => {\n const p = linePositions[i];\n return self.vertical\n ? p < edge || p <= firstOverflowing.edge\n : p > edge || p >= firstOverflowing.edge;\n });\n\n // If no break point is found due to the \"overflowing\" checkpoint,\n // give up deferring a line containing the checkpoint and try to cut the\n // line just before it.\n const forceCutBeforeOverflowing = lineIndex <= 0;\n if (forceCutBeforeOverflowing) {\n lineIndex = Base.binarySearch(linePositions.length, (i) =>\n self.vertical ? linePositions[i] < edge : linePositions[i] > edge,\n );\n }\n\n // First edge after the one that both fits and satisfies widows constraint.\n lineIndex = Math.min(linePositions.length - widows, lineIndex);\n if (lineIndex < orphans) {\n // Not enough lines to satisfy orphans constraint, cannot break here.\n return null;\n }\n edge = linePositions[lineIndex - 1];\n let nodeContext: Vtree.NodeContext;\n if (forceCutBeforeOverflowing) {\n nodeContext = firstOverflowing.checkPoint;\n } else {\n nodeContext = this.findAcceptableBreakInside(bp.checkPoints, edge, force);\n }\n if (nodeContext) {\n // When line-height is small, the edge calculated above (using Range)\n // can be larger than the edge of the block container containing the text.\n // We update the edge by measuring the block edge.\n const blockEdge = this.getAfterEdgeOfBlockContainer(nodeContext);\n if (!isNaN(blockEdge) && blockEdge < edge) {\n edge = blockEdge;\n }\n this.computedBlockSize =\n dir * (edge - this.beforeEdge) + repetitiveElementsOffset;\n }\n return nodeContext;\n }\n\n getAfterEdgeOfBlockContainer(nodeContext: Vtree.NodeContext): number {\n let blockParent = nodeContext;\n do {\n blockParent = blockParent.parent;\n } while (blockParent && blockParent.inline);\n if (blockParent) {\n blockParent = blockParent.copy().modify();\n blockParent.after = true;\n return LayoutHelper.calculateEdge(\n blockParent,\n this.clientLayout,\n 0,\n this.vertical,\n );\n } else {\n return NaN;\n }\n }\n\n findFirstOverflowingEdgeAndCheckPoint(\n checkPoints: Vtree.NodeContext[],\n ): { edge: number; checkPoint: Vtree.NodeContext | null } {\n const index = checkPoints.findIndex((cp) => cp.overflow);\n if (index < 0) {\n return { edge: NaN, checkPoint: null };\n }\n const cp = checkPoints[index];\n return {\n edge: this.calculateEdge(null, checkPoints, index, cp.boxOffset),\n checkPoint: cp,\n };\n }\n\n findEdgeBreakPosition(\n bp: BreakPosition.EdgeBreakPosition,\n ): Vtree.NodeContext {\n this.computedBlockSize =\n bp.computedBlockSize + this.getOffsetByRepetitiveElements(bp);\n return bp.position;\n }\n\n /**\n * Finalize a line break.\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n Asserts.assert(nodeContext.formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n nodeContext.formattingContext,\n );\n let result = layoutProcessor.finishBreak(\n this,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n if (!result) {\n result = LayoutProcessor.blockLayoutProcessor.finishBreak(\n this,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n return result;\n }\n\n findAcceptableBreakPosition(): BreakPositionAndNodeContext {\n let bp: Layout.BreakPosition = null;\n let nodeContext: Vtree.NodeContext = null;\n let penalty = 0;\n let nextPenalty = 0;\n do {\n penalty = nextPenalty;\n nextPenalty = Number.MAX_VALUE;\n for (\n let i = this.breakPositions.length - 1;\n i >= 0 && !nodeContext;\n --i\n ) {\n bp = this.breakPositions[i];\n nodeContext = bp.findAcceptableBreak(this, penalty);\n const minPenalty = bp.getMinBreakPenalty();\n if (minPenalty > penalty) {\n nextPenalty = Math.min(nextPenalty, minPenalty);\n }\n }\n } while (\n // Don't need to find a non-optimal break position if\n // forceNonfitting=false\n nextPenalty > penalty &&\n !nodeContext &&\n this.forceNonfitting\n );\n return { breakPosition: nodeContext ? bp : null, nodeContext };\n }\n\n doFinishBreak(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n initialNodeContext: Vtree.NodeContext,\n initialComputedBlockSize: number,\n ): Task.Result<Vtree.NodeContext> {\n if (\n this.pageFloatLayoutContext.isInvalidated() ||\n this.pageBreakType ||\n !overflownNodeContext\n ) {\n return Task.newResult(nodeContext);\n }\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"doFinishBreak\");\n let forceRemoveSelf = false;\n if (!nodeContext) {\n // Last resort\n if (this.forceNonfitting) {\n Logging.logger.warn(\"Could not find any page breaks?!!\");\n self.skipTailEdges(overflownNodeContext).then((nodeContext) => {\n if (nodeContext) {\n nodeContext = nodeContext.modify();\n nodeContext.overflow = false;\n self.finishBreak(nodeContext, forceRemoveSelf, true).then(() => {\n frame.finish(nodeContext);\n });\n } else {\n frame.finish(nodeContext);\n }\n });\n return frame.result();\n } else {\n nodeContext = initialNodeContext;\n forceRemoveSelf = true;\n self.computedBlockSize = initialComputedBlockSize;\n }\n }\n this.finishBreak(nodeContext, forceRemoveSelf, true).then(() => {\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n /**\n * Determines if a page break is acceptable at this position\n */\n isBreakable(flowPosition: Vtree.NodeContext): boolean {\n if (flowPosition.after) {\n return true; // may be an empty block\n }\n switch (flowPosition.sourceNode.namespaceURI) {\n case Base.NS.SVG:\n return false;\n }\n return !flowPosition.flexContainer;\n }\n\n /**\n * Determines if an indent value is zero\n */\n zeroIndent(val: string | number): boolean {\n const s = val.toString();\n return s == \"\" || s == \"auto\" || !!s.match(/^0+(.0*)?[^0-9]/);\n }\n\n /**\n * @return true if overflows\n */\n checkOverflowAndSaveEdge(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n ): boolean {\n if (!nodeContext) {\n return false;\n }\n if (LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return false;\n }\n let edge = LayoutHelper.calculateEdge(\n nodeContext,\n this.clientLayout,\n 0,\n this.vertical,\n );\n const offsets = BreakPosition.calculateOffset(\n nodeContext,\n this.collectElementsOffset(),\n );\n const overflown = this.isOverflown(\n edge + (this.vertical ? -1 : 1) * offsets.minimum,\n );\n if (\n this.isOverflown(edge + (this.vertical ? -1 : 1) * offsets.current) &&\n !this.nodeContextOverflowingDueToRepetitiveElements\n ) {\n this.nodeContextOverflowingDueToRepetitiveElements = nodeContext;\n } else if (trailingEdgeContexts) {\n // If the edge does not overflow add the trailing margin, which is\n // truncated to the remaining fragmentainer extent.\n const marginEdge =\n edge + this.getTrailingMarginEdgeAdjustment(trailingEdgeContexts);\n const footnoteEdge =\n this.footnoteEdge - this.getBoxDir() * offsets.current;\n edge = this.vertical\n ? Math.min(edge, Math.max(marginEdge, footnoteEdge))\n : Math.max(edge, Math.min(marginEdge, footnoteEdge));\n }\n this.updateMaxReachedAfterEdge(edge);\n return overflown;\n }\n\n /**\n * Save a possible page break position on a CSS block edge. Check if it\n * overflows.\n * @return true if overflows\n */\n checkOverflowAndSaveEdgeAndBreakPosition(\n nodeContext: Vtree.NodeContext,\n trailingEdgeContexts: Vtree.NodeContext[],\n saveEvenOverflown: boolean,\n breakAtTheEdge: string | null,\n ): boolean {\n if (!nodeContext) {\n return false;\n }\n if (LayoutHelper.isOrphan(nodeContext.viewNode)) {\n return false;\n }\n const overflown = this.checkOverflowAndSaveEdge(\n nodeContext,\n trailingEdgeContexts,\n );\n if (saveEvenOverflown || !overflown) {\n this.saveEdgeBreakPosition(nodeContext, breakAtTheEdge, overflown);\n }\n return overflown;\n }\n\n applyClearance(nodeContext: Vtree.NodeContext): boolean {\n if (!nodeContext.viewNode.parentNode) {\n // Cannot do ceralance for nodes without parents\n return false;\n }\n\n // measure where the edge of the element would be without clearance\n const margin = this.getComputedMargin(nodeContext.viewNode as Element);\n const spacer = nodeContext.viewNode.ownerDocument.createElement(\"div\");\n if (this.vertical) {\n spacer.style.bottom = \"0px\";\n spacer.style.width = \"1px\";\n spacer.style.marginRight = `${margin.right}px`;\n } else {\n spacer.style.right = \"0px\";\n spacer.style.height = \"1px\";\n spacer.style.marginTop = `${margin.top}px`;\n }\n nodeContext.viewNode.parentNode.insertBefore(spacer, nodeContext.viewNode);\n let spacerBox = this.clientLayout.getElementClientRect(spacer);\n const edge = this.getBeforeEdge(spacerBox);\n const dir = this.getBoxDir();\n const clear = nodeContext.clearSide;\n let clearEdge = -this.getBoxDir() * Infinity;\n if (clear === \"all\") {\n clearEdge = this.pageFloatLayoutContext.getPageFloatClearEdge(\n clear,\n this,\n );\n }\n switch (clear) {\n case \"left\":\n clearEdge = dir * Math.max(clearEdge * dir, this.leftFloatEdge * dir);\n break;\n case \"right\":\n clearEdge = dir * Math.max(clearEdge * dir, this.rightFloatEdge * dir);\n break;\n default:\n clearEdge =\n dir *\n Math.max(\n clearEdge * dir,\n Math.max(this.rightFloatEdge * dir, this.leftFloatEdge * dir),\n );\n }\n\n // edge holds the position where element border \"before\" edge will be\n // without clearance. clearEdge is the \"after\" edge of the float to clear.\n if (edge * dir >= clearEdge * dir) {\n // No need for clearance\n nodeContext.viewNode.parentNode.removeChild(spacer);\n return false;\n } else {\n // Need some clearance, determine how much. Add the clearance node,\n // measure its after edge and adjust after margin (required due to\n // possible margin collapse before clearance was introduced).\n const height = Math.max(1, (clearEdge - edge) * dir);\n if (this.vertical) {\n spacer.style.width = `${height}px`;\n } else {\n spacer.style.height = `${height}px`;\n }\n spacerBox = this.clientLayout.getElementClientRect(spacer);\n const afterEdge = this.getAfterEdge(spacerBox);\n if (this.vertical) {\n let wAdj = afterEdge + margin.right - clearEdge;\n if (wAdj > 0 == margin.right >= 0) {\n // In addition to collapsed portion\n wAdj += margin.right;\n }\n spacer.style.marginLeft = `${wAdj}px`;\n } else {\n let hAdj = clearEdge - (afterEdge + margin.top);\n if (hAdj > 0 == margin.top >= 0) {\n // In addition to collapsed portion\n hAdj += margin.top;\n }\n spacer.style.marginBottom = `${hAdj}px`;\n }\n nodeContext.clearSpacer = spacer;\n return true;\n }\n }\n\n isBFC(formattingContext: Vtree.FormattingContext): boolean {\n if (LayoutProcessor.isInstanceOfBlockFormattingContext(formattingContext)) {\n return true;\n }\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n formattingContext,\n )\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Skips positions until either the start of unbreakable block or inline\n * content. Also sets breakBefore on the result combining break-before and\n * break-after properties from all elements that meet at the edge.\n */\n skipEdges(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue: string | null,\n ): Task.Result<Vtree.NodeContext> {\n const fc = nodeContext.after\n ? nodeContext.parent && nodeContext.parent.formattingContext\n : nodeContext.formattingContext;\n if (fc && !this.isBFC(fc)) {\n return Task.newResult(nodeContext);\n }\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"skipEdges\");\n\n // If a forced break occurred at the end of the previous column,\n // nodeContext.after should be false.\n let atUnforcedBreak =\n !forcedBreakValue && leadingEdge && nodeContext && nodeContext.after;\n let breakAtTheEdge = forcedBreakValue;\n let lastAfterNodeContext: Vtree.NodeContext = null;\n let leadingEdgeContexts: Vtree.NodeContext[] = [];\n let trailingEdgeContexts: Vtree.NodeContext[] = [];\n let onStartEdges = false;\n\n function needForcedBreak() {\n // leadingEdge=true means that we are at the beginning of the new column\n // and hence must avoid a break (Otherwise leading to an infinite loop)\n return (\n !!forcedBreakValue ||\n (!leadingEdge && Break.isForcedBreakValue(breakAtTheEdge))\n );\n }\n\n function processForcedBreak() {\n nodeContext = leadingEdgeContexts[0] || nodeContext;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n self.pageBreakType = breakAtTheEdge;\n }\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n Asserts.assert(nodeContext.formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n nodeContext.formattingContext,\n );\n\n // A code block to be able to use break. Break moves to the next\n // node position.\n do {\n if (!nodeContext.viewNode) {\n // Non-displayable content, skip\n break;\n }\n if (nodeContext.inline && nodeContext.viewNode.nodeType != 1) {\n if (\n VtreeImpl.canIgnore(\n nodeContext.viewNode,\n nodeContext.whitespace,\n )\n ) {\n // Ignorable text content, skip\n break;\n }\n if (!nodeContext.after) {\n // Leading edge of non-empty block -> finished going through\n // all starting edges of the box\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n )\n ) {\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n } else {\n nodeContext = nodeContext.modify();\n nodeContext.breakBefore = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (!nodeContext.after) {\n if (layoutProcessor) {\n if (layoutProcessor.startNonInlineElementNode(nodeContext)) {\n break;\n }\n }\n if (nodeContext.clearSide) {\n // clear\n if (\n self.applyClearance(nodeContext) &&\n leadingEdge &&\n self.breakPositions.length === 0\n ) {\n self.saveEdgeBreakPosition(\n nodeContext.copy(),\n breakAtTheEdge,\n false,\n );\n }\n }\n if (\n !self.isBFC(nodeContext.formattingContext) ||\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n ) ||\n self.isFloatNodeContext(nodeContext) ||\n nodeContext.flexContainer\n ) {\n // new formatting context, or float or flex container\n // (unbreakable)\n leadingEdgeContexts.push(nodeContext.copy());\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n ) ||\n !self.layoutConstraint.allowLayout(nodeContext)\n ) {\n // overflow\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (nodeContext.viewNode.nodeType != 1) {\n // not an element\n break;\n }\n const style = (nodeContext.viewNode as HTMLElement).style;\n if (nodeContext.after) {\n // Skip an empty inline box at the start of a block\n // (An anonymous block consisting entirely of\n // collapsible white space is removed from the rendering tree)\n if (nodeContext.inline) {\n break;\n }\n if (layoutProcessor) {\n if (\n layoutProcessor.afterNonInlineElementNode(\n nodeContext,\n self.stopAtOverflow,\n )\n ) {\n break;\n }\n }\n\n // Trailing edge\n if (onStartEdges) {\n // finished going through all starting edges of the box.\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n loopFrame.breakLoop();\n return;\n }\n\n // since a break did not occur, move to the next edge. this\n // edge is no longer the leading edge.\n leadingEdgeContexts = [];\n leadingEdge = false;\n atUnforcedBreak = false;\n breakAtTheEdge = null;\n }\n onStartEdges = false; // we are now on end edges.\n lastAfterNodeContext = nodeContext.copy();\n trailingEdgeContexts.push(lastAfterNodeContext);\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakAfter,\n );\n if (\n style &&\n !(\n self.zeroIndent(style.paddingBottom) &&\n self.zeroIndent(style.borderBottomWidth)\n )\n ) {\n // Non-zero trailing inset.\n // Margins don't collapse across non-zero borders and\n // paddings.\n trailingEdgeContexts = [lastAfterNodeContext];\n }\n } else {\n // Leading edge\n leadingEdgeContexts.push(nodeContext.copy());\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n if (!self.layoutConstraint.allowLayout(nodeContext)) {\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n !self.stopAtOverflow,\n breakAtTheEdge,\n );\n nodeContext = nodeContext.modify();\n nodeContext.overflow = true;\n if (self.stopAtOverflow) {\n loopFrame.breakLoop();\n return;\n }\n }\n const viewTag = (nodeContext.viewNode as Element).localName;\n if (mediaTags[viewTag]) {\n // elements that have inherent content\n // check if a forced break must occur before the block.\n if (needForcedBreak()) {\n processForcedBreak();\n } else if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n null,\n true,\n breakAtTheEdge,\n )\n ) {\n // overflow\n nodeContext = (self.stopAtOverflow\n ? lastAfterNodeContext || nodeContext\n : nodeContext\n ).modify();\n nodeContext.overflow = true;\n }\n loopFrame.breakLoop();\n return;\n }\n if (\n style &&\n !(\n self.zeroIndent(style.paddingTop) &&\n self.zeroIndent(style.borderTopWidth)\n )\n ) {\n // Non-zero leading inset\n atUnforcedBreak = false;\n trailingEdgeContexts = [];\n }\n onStartEdges = true; // we are now on starting edges.\n }\n } while (false); // End of block of code to use break\n\n const nextResult = self.nextInTree(nodeContext, atUnforcedBreak);\n if (nextResult.isPending()) {\n nextResult.then((nodeContextParam) => {\n nodeContext = nodeContextParam;\n loopFrame.continueLoop();\n });\n return;\n } else {\n nodeContext = nextResult.get();\n }\n }\n\n if (\n self.checkOverflowAndSaveEdgeAndBreakPosition(\n lastAfterNodeContext,\n trailingEdgeContexts,\n !self.stopAtOverflow,\n breakAtTheEdge,\n )\n ) {\n if (lastAfterNodeContext && self.stopAtOverflow) {\n nodeContext = lastAfterNodeContext.modify();\n nodeContext.overflow = true;\n } else {\n // TODO: what to return here??\n }\n } else if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n })\n .then(() => {\n if (lastAfterNodeContext) {\n self.lastAfterPosition = lastAfterNodeContext.toNodePosition();\n }\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n /**\n * Skips non-renderable positions until it hits the end of the flow or some\n * renderable content. Returns the nodeContext that was passed in if some\n * content remains and null if all content could be skipped.\n */\n skipTailEdges(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n let resultNodeContext = nodeContext.copy();\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"skipEdges\");\n let breakAtTheEdge: string | null = null;\n let onStartEdges = false;\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n // A code block to be able to use break. Break moves to the next\n // node position.\n do {\n if (!nodeContext.viewNode) {\n // Non-displayable content, skip\n break;\n }\n if (nodeContext.inline && nodeContext.viewNode.nodeType != 1) {\n if (\n VtreeImpl.canIgnore(\n nodeContext.viewNode,\n nodeContext.whitespace,\n )\n ) {\n // Ignorable text content, skip\n break;\n }\n if (!nodeContext.after) {\n // Leading edge of non-empty block -> finished going through\n // all starting edges of the box\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (!nodeContext.after) {\n if (\n self.isFloatNodeContext(nodeContext) ||\n nodeContext.flexContainer\n ) {\n // float or flex container (unbreakable)\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n }\n if (nodeContext.viewNode.nodeType != 1) {\n // not an element\n break;\n }\n const style = (nodeContext.viewNode as HTMLElement).style;\n if (nodeContext.after) {\n // Trailing edge\n if (onStartEdges) {\n // finished going through all starting edges of the box.\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n loopFrame.breakLoop();\n return;\n }\n\n // since a break did not occur, move to the next edge.\n breakAtTheEdge = null;\n }\n onStartEdges = false; // we are now on end edges.\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakAfter,\n );\n } else {\n // Leading edge\n breakAtTheEdge = Break.resolveEffectiveBreakValue(\n breakAtTheEdge,\n nodeContext.breakBefore,\n );\n const viewTag = (nodeContext.viewNode as Element).localName;\n if (mediaTags[viewTag]) {\n // elements that have inherent content\n // check if a forced break must occur before the block.\n if (Break.isForcedBreakValue(breakAtTheEdge)) {\n self.pageBreakType = breakAtTheEdge;\n }\n loopFrame.breakLoop();\n return;\n }\n if (\n style &&\n !(\n self.zeroIndent(style.paddingTop) &&\n self.zeroIndent(style.borderTopWidth)\n )\n ) {\n // Non-zero leading inset\n loopFrame.breakLoop();\n return;\n }\n }\n onStartEdges = true; // we are now on starting edges.\n } while (false); // End of block of code to use break\n\n const nextResult = self.layoutContext.nextInTree(nodeContext);\n if (nextResult.isPending()) {\n nextResult.then((nodeContextParam) => {\n nodeContext = nodeContextParam;\n loopFrame.continueLoop();\n });\n return;\n } else {\n nodeContext = nextResult.get();\n }\n }\n resultNodeContext = null;\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(resultNodeContext);\n });\n return frame.result();\n }\n\n layoutFloatOrFootnote(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<Vtree.NodeContext> {\n if (\n PageFloats.isPageFloat(nodeContext.floatReference) ||\n nodeContext.floatSide === \"footnote\"\n ) {\n return this.layoutPageFloat(nodeContext);\n } else {\n return this.layoutFloat(nodeContext);\n }\n }\n\n /**\n * Layout next portion of the source.\n */\n layoutNext(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n forcedBreakValue?: string | null,\n ): Task.Result<Vtree.NodeContext> {\n const self = this;\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"layoutNext\");\n this.skipEdges(nodeContext, leadingEdge, forcedBreakValue || null).then(\n (nodeContextParam) => {\n nodeContext = nodeContextParam as Vtree.NodeContext;\n if (\n !nodeContext ||\n self.pageBreakType ||\n self.stopByOverflow(nodeContext)\n ) {\n // finished all content, explicit page break or overflow (automatic\n // page break)\n frame.finish(nodeContext);\n } else {\n const formattingContext = nodeContext.formattingContext;\n Asserts.assert(formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n formattingContext,\n );\n layoutProcessor\n .layout(nodeContext, self, leadingEdge)\n .thenFinish(frame);\n }\n },\n );\n return frame.result();\n }\n\n clearOverflownViewNodes(\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ): void {\n if (!nodeContext) {\n return;\n }\n for (\n let parent = nodeContext.parent;\n nodeContext;\n nodeContext = parent, parent = parent ? parent.parent : null\n ) {\n const formattingContext = (parent || nodeContext).formattingContext;\n Asserts.assert(formattingContext);\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n formattingContext,\n );\n layoutProcessor.clearOverflownViewNodes(\n this,\n parent,\n nodeContext,\n removeSelf,\n );\n removeSelf = false;\n }\n }\n\n initGeom(): void {\n // TODO: we should be able to avoid querying the layout engine at this\n // point. Create an element that fills the content area and query its size.\n // Calling getElementClientRect on the container element includes element\n // padding which is wrong for our purposes.\n const probe = this.element.ownerDocument.createElement(\n \"div\",\n ) as HTMLElement;\n probe.style.position = \"absolute\";\n probe.style.top = `${this.paddingTop}px`;\n probe.style.right = `${this.paddingRight}px`;\n probe.style.bottom = `${this.paddingBottom}px`;\n probe.style.left = `${this.paddingLeft}px`;\n this.element.appendChild(probe);\n const columnBBox = this.clientLayout.getElementClientRect(probe);\n this.element.removeChild(probe);\n const offsetX = this.originX + this.left + this.getInsetLeft();\n const offsetY = this.originY + this.top + this.getInsetTop();\n this.box = new GeometryUtil.Rect(\n offsetX,\n offsetY,\n offsetX + this.width,\n offsetY + this.height,\n );\n this.startEdge = columnBBox\n ? this.vertical\n ? columnBBox.top\n : columnBBox.left\n : 0;\n this.endEdge = columnBBox\n ? this.vertical\n ? columnBBox.bottom\n : columnBBox.right\n : 0;\n this.beforeEdge = columnBBox\n ? this.vertical\n ? columnBBox.right\n : columnBBox.top\n : 0;\n this.afterEdge = columnBBox\n ? this.vertical\n ? columnBBox.left\n : columnBBox.bottom\n : 0;\n this.leftFloatEdge = this.beforeEdge;\n this.rightFloatEdge = this.beforeEdge;\n this.bottommostFloatTop = this.beforeEdge;\n this.footnoteEdge = this.afterEdge;\n this.bands = GeometryUtil.shapesToBands(\n this.box,\n [this.getInnerShape()],\n this.getExclusions(),\n 8,\n this.snapHeight,\n this.vertical,\n );\n this.createFloats();\n }\n\n init(): void {\n this.chunkPositions = [];\n Base.setCSSProperty(this.element, \"width\", `${this.width}px`);\n Base.setCSSProperty(this.element, \"height\", `${this.height}px`);\n this.initGeom();\n this.computedBlockSize = 0;\n this.overflown = false;\n this.pageBreakType = null;\n this.lastAfterPosition = null;\n }\n\n /**\n * Save the potential breaking position at the edge. Should, in general, save\n * \"after\" position but only after skipping all of the \"before\" ones and\n * getting to the non-empty content (to get breakAtEdge right).\n */\n saveEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakAtEdge: string | null,\n overflows: boolean,\n ): void {\n Asserts.assert(position.formattingContext);\n const copy = position.copy();\n const layoutProcessor = new LayoutProcessor.LayoutProcessorResolver().find(\n position.formattingContext,\n );\n const clonedPaddingBorder = this.calculateClonedPaddingBorder(copy);\n const bp = layoutProcessor.createEdgeBreakPosition(\n copy,\n breakAtEdge,\n overflows,\n this.computedBlockSize + clonedPaddingBorder,\n );\n this.breakPositions.push(bp);\n }\n\n /**\n * @param checkPoints array of breaking points for breakable block\n */\n saveBoxBreakPosition(checkPoints: Vtree.NodeContext[]): void {\n const penalty = checkPoints[0].breakPenalty;\n const bp = new BoxBreakPosition(checkPoints, penalty);\n this.breakPositions.push(bp);\n }\n\n updateMaxReachedAfterEdge(afterEdge: number) {\n if (!isNaN(afterEdge)) {\n const size = this.getBoxDir() * (afterEdge - this.beforeEdge);\n this.computedBlockSize = Math.max(size, this.computedBlockSize);\n }\n }\n\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<Vtree.ChunkPosition> {\n this.chunkPositions.push(chunkPosition); // So we can re-layout this column later\n if (chunkPosition.primary.after) {\n this.lastAfterPosition = chunkPosition.primary;\n }\n if (this.stopAtOverflow && this.overflown) {\n return Task.newResult(chunkPosition as Vtree.ChunkPosition);\n }\n if (this.isFullWithPageFloats()) {\n if (\n chunkPosition.primary.after &&\n chunkPosition.primary.steps.length === 1\n ) {\n // End of contents\n return Task.newResult(null as Vtree.ChunkPosition);\n } else {\n return Task.newResult(chunkPosition as Vtree.ChunkPosition);\n }\n }\n const self = this;\n const frame: Task.Frame<Vtree.ChunkPosition> = Task.newFrame(\"layout\");\n\n // ------ start the column -----------\n self.openAllViews(chunkPosition.primary).then((nodeContext) => {\n let initialNodeContext: Vtree.NodeContext = null;\n if (nodeContext.viewNode) {\n initialNodeContext = nodeContext.copy();\n } else {\n const nextInTreeListener = (evt) => {\n if (evt.nodeContext.viewNode) {\n initialNodeContext = evt.nodeContext;\n self.layoutContext.removeEventListener(\n \"nextInTree\",\n nextInTreeListener,\n );\n }\n };\n self.layoutContext.addEventListener(\"nextInTree\", nextInTreeListener);\n }\n const retryer = new ColumnLayoutRetryer(leadingEdge, breakAfter);\n retryer.layout(nodeContext, self).then((nodeContextParam) => {\n self\n .doFinishBreak(\n nodeContextParam,\n retryer.context.overflownNodeContext,\n initialNodeContext,\n retryer.initialComputedBlockSize,\n )\n .then((positionAfter) => {\n let cont: Task.Result<boolean> = null;\n if (!self.pseudoParent) {\n cont = self.doFinishBreakOfFragmentLayoutConstraints(\n positionAfter,\n );\n } else {\n cont = Task.newResult(null);\n }\n cont.then(() => {\n if (self.pageFloatLayoutContext.isInvalidated()) {\n frame.finish(null);\n return;\n }\n if (!positionAfter) {\n frame.finish(null);\n } else {\n self.overflown = true;\n const result = new VtreeImpl.ChunkPosition(\n positionAfter.toNodePosition(),\n );\n frame.finish(result);\n }\n });\n });\n });\n });\n return frame.result();\n }\n\n isFullWithPageFloats(): boolean {\n return this.pageFloatLayoutContext.isColumnFullWithPageFloats(this);\n }\n\n getMaxBlockSizeOfPageFloats(): number {\n return this.pageFloatLayoutContext.getMaxBlockSizeOfPageFloats();\n }\n\n doFinishBreakOfFragmentLayoutConstraints(\n nodeContext: Vtree.NodeContext,\n ): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"doFinishBreakOfFragmentLayoutConstraints\",\n );\n const sortedFragmentLayoutConstraints = [].concat(\n this.fragmentLayoutConstraints,\n );\n sortedFragmentLayoutConstraints.sort(\n (a, b) => a.getPriorityOfFinishBreak() - b.getPriorityOfFinishBreak(),\n );\n let i = 0;\n frame\n .loop(() => {\n if (i < sortedFragmentLayoutConstraints.length) {\n const result = sortedFragmentLayoutConstraints[i++].finishBreak(\n nodeContext,\n this,\n );\n return result.thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @param nodeContext starting position.\n * @return holding end position.\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n leadingEdge: boolean,\n breakAfter?: string | null,\n ): Task.Result<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }> {\n const self = this;\n const frame: Task.Frame<{\n nodeContext: Vtree.NodeContext;\n overflownNodeContext: Vtree.NodeContext;\n }> = Task.newFrame(\"doLayout\");\n let overflownNodeContext: Vtree.NodeContext = null;\n\n // ------ init backtracking list -----\n self.breakPositions = [];\n self.nodeContextOverflowingDueToRepetitiveElements = null;\n\n // ------- fill the column -------------\n frame\n .loopWithFrame((loopFrame) => {\n while (nodeContext) {\n // fill a single block\n let pending = true;\n self\n .layoutNext(nodeContext, leadingEdge, breakAfter || null)\n .then((nodeContextParam) => {\n leadingEdge = false;\n breakAfter = null;\n if (\n self.nodeContextOverflowingDueToRepetitiveElements &&\n self.stopAtOverflow\n ) {\n self.pageBreakType = null;\n nodeContext =\n self.nodeContextOverflowingDueToRepetitiveElements;\n nodeContext.overflow = true;\n } else {\n nodeContext = nodeContextParam;\n }\n if (self.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n } else if (self.pageBreakType) {\n // explicit page break\n loopFrame.breakLoop(); // Loop end\n } else if (nodeContext && self.stopByOverflow(nodeContext)) {\n // overflow (implicit page break): back up and find a\n // page break\n overflownNodeContext = nodeContext;\n const bp = self.findAcceptableBreakPosition();\n nodeContext = bp.nodeContext;\n if (bp.breakPosition) {\n bp.breakPosition.breakPositionChosen(self);\n }\n loopFrame.breakLoop(); // Loop end\n } else {\n if (pending) {\n // Sync case\n pending = false;\n } else {\n // Async case\n loopFrame.continueLoop();\n }\n }\n });\n if (pending) {\n // Async case and loop end\n pending = false;\n return;\n }\n }\n\n // Sync case\n self.computedBlockSize += self.getOffsetByRepetitiveElements();\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish({ nodeContext, overflownNodeContext });\n });\n return frame.result();\n }\n\n /**\n * Re-layout already laid-out chunks. Return the position of the last flow if\n * there is an overflow.\n * TODO: deal with chunks that did not fit at all.\n * @return holding end position.\n */\n redoLayout(): Task.Result<Vtree.ChunkPosition> {\n const chunkPositions = this.chunkPositions;\n let last: Node = this.element.lastChild;\n while (last != this.last) {\n const prev = last.previousSibling;\n if (\n !(\n this.element === last.parentNode &&\n (this.layoutContext as Vgen.ViewFactory).isPseudoelement(last)\n )\n ) {\n this.element.removeChild(last);\n }\n last = prev;\n }\n this.killFloats();\n this.init();\n const self = this;\n const frame: Task.Frame<Vtree.ChunkPosition> = Task.newFrame(\"redoLayout\");\n let i = 0;\n let res: Vtree.ChunkPosition = null;\n let leadingEdge = true;\n frame\n .loopWithFrame((loopFrame) => {\n if (i < chunkPositions.length) {\n const chunkPosition = chunkPositions[i++];\n self.layout(chunkPosition, leadingEdge).then((pos) => {\n leadingEdge = false;\n if (pos) {\n res = pos;\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n });\n return;\n }\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(res);\n });\n return frame.result();\n }\n\n saveDistanceToBlockEndFloats() {\n const blockStartEdgeOfBlockEndFloats = this.pageFloatLayoutContext.getBlockStartEdgeOfBlockEndFloats();\n if (\n blockStartEdgeOfBlockEndFloats > 0 &&\n isFinite(blockStartEdgeOfBlockEndFloats)\n ) {\n this.blockDistanceToBlockEndFloats =\n this.getBoxDir() *\n (blockStartEdgeOfBlockEndFloats -\n this.beforeEdge -\n this.computedBlockSize);\n }\n }\n\n collectElementsOffset(): RepetitiveElement.ElementsOffset[] {\n const repetitiveElements: RepetitiveElement.ElementsOffset[] = [];\n for (let current: Column = this; current; current = current.pseudoParent) {\n current.fragmentLayoutConstraints.forEach((constraint) => {\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n constraint,\n )\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (\n Selectors.isInstanceOfAfterIfContinuesLayoutConstraint(constraint)\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (Table.isInstanceOfTableRowLayoutConstraint(constraint)) {\n constraint\n .getElementsOffsetsForTableCell(this)\n .forEach((repetitiveElement) => {\n repetitiveElements.push(repetitiveElement);\n });\n }\n });\n }\n return repetitiveElements;\n }\n}\n\n/**\n * Represents a \"pseudo\"-column nested inside a real column.\n * This class is created to handle parallel fragmented flows (e.g. table columns\n * in a single table row). A pseudo-column behaves in the same way as the\n * original column, sharing its properties. Property changes on the\n * pseudo-column are not propagated to the original column. The LayoutContext of\n * the original column is also cloned and used by the pseudo-column, not to\n * propagate state changes of the LayoutContext caused by the pseudo-column.\n * @param column The original (parent) column\n * @param viewRoot Root element for the pseudo-column, i.e., the root of the\n * fragmented flow.\n * @param parentNodeContext A NodeContext generating this PseudoColumn\n */\nexport class PseudoColumn {\n startNodeContexts: Vtree.NodeContext[] = [];\n private column: Layout.Column;\n constructor(\n column: Layout.Column,\n viewRoot: Element,\n parentNodeContext: Vtree.NodeContext,\n ) {\n this.column = Object.create(column) as Layout.Column;\n this.column.element = viewRoot;\n this.column.layoutContext = column.layoutContext.clone();\n this.column.stopAtOverflow = false;\n this.column.flowRootFormattingContext = parentNodeContext.formattingContext;\n this.column.pseudoParent = column;\n const parentClonedPaddingBorder = this.column.calculateClonedPaddingBorder(\n parentNodeContext,\n );\n this.column.footnoteEdge =\n this.column.footnoteEdge - parentClonedPaddingBorder;\n const pseudoColumn = this;\n this.column.openAllViews = function(position) {\n return Column.prototype.openAllViews\n .call(this, position)\n .thenAsync((result) => {\n pseudoColumn.startNodeContexts.push(result.copy());\n return Task.newResult(result);\n });\n };\n }\n /**\n * @param chunkPosition starting position.\n * @return holding end position.\n */\n layout(\n chunkPosition: Vtree.ChunkPosition,\n leadingEdge: boolean,\n ): Task.Result<Vtree.ChunkPosition> {\n return this.column.layout(chunkPosition, leadingEdge);\n }\n findAcceptableBreakPosition(\n allowBreakAtStartPosition: boolean,\n ): Layout.BreakPositionAndNodeContext {\n const p = this.column.findAcceptableBreakPosition();\n if (allowBreakAtStartPosition) {\n const startNodeContext = this.startNodeContexts[0].copy();\n const bp = new BreakPosition.EdgeBreakPosition(\n startNodeContext,\n null,\n startNodeContext.overflow,\n 0,\n );\n bp.findAcceptableBreak(this.column, 0);\n if (!p.nodeContext) {\n return { breakPosition: bp, nodeContext: startNodeContext };\n }\n }\n return p;\n }\n /**\n * @return holing true\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n return this.column.finishBreak(nodeContext, forceRemoveSelf, endOfColumn);\n }\n doFinishBreakOfFragmentLayoutConstraints(positionAfter: Vtree.NodeContext) {\n this.column.doFinishBreakOfFragmentLayoutConstraints(positionAfter);\n }\n isStartNodeContext(nodeContext: Vtree.NodeContext): boolean {\n const startNodeContext = this.startNodeContexts[0];\n return (\n startNodeContext.viewNode === nodeContext.viewNode &&\n startNodeContext.after === nodeContext.after &&\n startNodeContext.offsetInNode === nodeContext.offsetInNode\n );\n }\n isLastAfterNodeContext(nodeContext: Vtree.NodeContext): boolean {\n return VtreeImpl.isSameNodePosition(\n nodeContext.toNodePosition(),\n this.column.lastAfterPosition,\n );\n }\n getColumnElement(): Element {\n return this.column.element;\n }\n getColumn(): Layout.Column {\n return this.column;\n }\n}\n\nexport const firstCharPattern = /^[^A-Za-z0-9_\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]*([A-Za-z0-9_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527][^A-Za-z0-9_\\u009E\\u009F\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02AF\\u037B-\\u037D\\u0386\\u0388-\\u0482\\u048A-\\u0527]*)?/;\n\nexport type SinglePageFloatLayoutResult = Layout.SinglePageFloatLayoutResult;\n\nexport function fixJustificationOnHyphen(\n nodeContext: Vtree.NodeContext,\n insertAfter: boolean,\n node: Node,\n insertionPoint: Node,\n): void {\n if (Base.checkSoftWrapOpportunityAfterHyphenBug(document.body)) {\n const hyphenChar = resolveHyphenateCharacter(nodeContext);\n const prevSibling = insertAfter ? node : node.previousSibling;\n const prevText = prevSibling ? prevSibling.textContent : \"\";\n if (prevText.charAt(prevText.length - 1) === hyphenChar) {\n const doc = node.ownerDocument;\n const parent = node.parentNode;\n if (Base.checkSoftWrapOpportunityByWbrBug(document.body)) {\n // For IE\n parent.insertBefore(doc.createTextNode(\" \"), insertionPoint);\n } else {\n // For Edge\n parent.insertBefore(doc.createElement(\"wbr\"), insertionPoint);\n }\n }\n }\n}\n\n/**\n * breaking point resolver for Text Node.\n */\nexport class TextNodeBreaker implements Layout.TextNodeBreaker {\n breakTextNode(\n textNode: Text,\n nodeContext: Vtree.NodeContext,\n low: number,\n checkPoints: Vtree.NodeContext[],\n checkpointIndex: number,\n force: boolean,\n ): Vtree.NodeContext {\n if (nodeContext.after) {\n nodeContext.offsetInNode = textNode.length;\n } else {\n // Character with index low is the last one that fits.\n let viewIndex = low - nodeContext.boxOffset;\n const text = textNode.data;\n if (text.charCodeAt(viewIndex) == 173) {\n viewIndex = this.breakAfterSoftHyphen(\n textNode,\n text,\n viewIndex,\n nodeContext,\n );\n } else {\n viewIndex = this.breakAfterOtherCharacter(\n textNode,\n text,\n viewIndex,\n nodeContext,\n );\n }\n if (viewIndex > 0) {\n nodeContext = this.updateNodeContext(nodeContext, viewIndex, textNode);\n }\n }\n return nodeContext;\n }\n\n breakAfterSoftHyphen(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number {\n // convert trailing soft hyphen to a real hyphen\n textNode.replaceData(\n viewIndex,\n text.length - viewIndex,\n !nodeContext.breakWord ? resolveHyphenateCharacter(nodeContext) : \"\",\n );\n return viewIndex + 1;\n }\n\n breakAfterOtherCharacter(\n textNode: Text,\n text: string,\n viewIndex: number,\n nodeContext: Vtree.NodeContext,\n ): number {\n // keep the trailing character (it may be a space or not)\n const ch0 = text.charAt(viewIndex);\n viewIndex++;\n const ch1 = text.charAt(viewIndex);\n\n // If automatic hyphen was inserted here, add a real hyphen.\n textNode.replaceData(\n viewIndex,\n text.length - viewIndex,\n !nodeContext.breakWord && Base.isLetter(ch0) && Base.isLetter(ch1)\n ? resolveHyphenateCharacter(nodeContext)\n : \"\",\n );\n return viewIndex;\n }\n\n updateNodeContext(\n nodeContext: Vtree.NodeContext,\n viewIndex: number,\n textNode: Text,\n ): Vtree.NodeContext {\n nodeContext = nodeContext.modify();\n nodeContext.offsetInNode += viewIndex;\n nodeContext.breakBefore = null;\n return nodeContext;\n }\n\n static instance: TextNodeBreaker;\n}\nTextNodeBreaker.instance = new TextNodeBreaker();\n\nexport function resolveHyphenateCharacter(\n nodeContext: Vtree.NodeContext,\n): string {\n return (\n nodeContext.hyphenateCharacter ||\n (nodeContext.parent && nodeContext.parent.hyphenateCharacter) ||\n \"-\"\n );\n}\n\nexport class ColumnLayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n breakAfter: string | null;\n private initialPageBreakType: string | null = null;\n initialComputedBlockSize: number = 0;\n private initialOverflown: boolean = false;\n context: { overflownNodeContext: Vtree.NodeContext } = {\n overflownNodeContext: null,\n };\n\n constructor(\n public readonly leadingEdge: boolean,\n breakAfter?: string | null,\n ) {\n super();\n this.breakAfter = breakAfter || null;\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): Layout.LayoutMode {\n return new DefaultLayoutMode(\n this.leadingEdge,\n this.breakAfter,\n this.context,\n );\n }\n\n /**\n * @override\n */\n prepareLayout(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n column.fragmentLayoutConstraints = [];\n if (!column.pseudoParent) {\n Shared.clearRepetitiveElementsCache();\n }\n }\n\n /**\n * @override\n */\n clearNodes(initialPosition: Vtree.NodeContext) {\n super.clearNodes(initialPosition);\n let nodeContext = initialPosition;\n while (nodeContext) {\n const viewNode = nodeContext.viewNode;\n if (viewNode) {\n LayoutHelper.removeFollowingSiblings(viewNode.parentNode, viewNode);\n }\n nodeContext = nodeContext.parent;\n }\n }\n\n /**\n * @override\n */\n saveState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.saveState(nodeContext, column);\n this.initialPageBreakType = column.pageBreakType;\n this.initialComputedBlockSize = column.computedBlockSize;\n this.initialOverflown = column.overflown;\n }\n\n /**\n * @override\n */\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.restoreState(nodeContext, column);\n column.pageBreakType = this.initialPageBreakType;\n column.computedBlockSize = this.initialComputedBlockSize;\n column.overflown = this.initialOverflown;\n }\n}\n\nexport class DefaultLayoutMode implements Layout.LayoutMode {\n constructor(\n public readonly leadingEdge: boolean,\n public readonly breakAfter: string | null,\n public readonly context: { overflownNodeContext: Vtree.NodeContext },\n ) {}\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\n \"DefaultLayoutMode.doLayout\",\n );\n\n processAfterIfContinuesOfAncestors(nodeContext, column).then(() => {\n column\n .doLayout(nodeContext, this.leadingEdge, this.breakAfter)\n .then((result) => {\n this.context.overflownNodeContext = result.overflownNodeContext;\n frame.finish(result.nodeContext);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: Layout.Column): boolean {\n if (column.pageFloatLayoutContext.isInvalidated() || column.pageBreakType) {\n return true;\n }\n if (column.fragmentLayoutConstraints.length <= 0) {\n return true;\n }\n return column.fragmentLayoutConstraints.every((constraint) =>\n constraint.allowLayout(\n nodeContext,\n this.context.overflownNodeContext,\n column,\n ),\n );\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n accepted: boolean,\n ): boolean {\n if (!accepted) {\n const hasNextCandidate = column.fragmentLayoutConstraints.some(\n (constraint) => constraint.nextCandidate(positionAfter),\n );\n\n // If there is no next candidate, we accept the current layout trial.\n // Later Column#doFinishBreak decides whether the overflowing content\n // should be placed as is or be deferred to the next column,\n // depending on the value of Column#forceNonfitting.\n accepted = !hasNextCandidate;\n }\n column.fragmentLayoutConstraints.forEach((constraint) => {\n constraint.postLayout(accepted, positionAfter, initialPosition, column);\n });\n return accepted;\n }\n}\n\nexport class PageFloatArea extends Column implements Layout.PageFloatArea {\n private rootViewNodes: Element[] = [];\n private floatMargins: GeometryUtil.Insets[] = [];\n adjustContentRelativeSize: boolean = true;\n\n constructor(\n public readonly floatSide: string,\n element: Element,\n layoutContext: Vtree.LayoutContext,\n clientLayout: Vtree.ClientLayout,\n layoutConstraint: LayoutConstraint,\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n public readonly parentContainer: Vtree.Container,\n ) {\n super(\n element,\n layoutContext,\n clientLayout,\n layoutConstraint,\n pageFloatLayoutContext,\n );\n }\n\n /**\n * @override\n */\n openAllViews(position: Vtree.NodePosition): Task.Result<Vtree.NodeContext> {\n return super.openAllViews(position).thenAsync((nodeContext) => {\n if (nodeContext) {\n this.fixFloatSizeAndPosition(nodeContext);\n }\n return Task.newResult(nodeContext);\n });\n }\n\n convertPercentageSizesToPx(target: Element) {\n const containingBlockRect = this.parentContainer.getPaddingRect();\n const refWidth = containingBlockRect.x2 - containingBlockRect.x1;\n const refHeight = containingBlockRect.y2 - containingBlockRect.y1;\n\n function convertPercentageToPx(props: string[], refValue: number) {\n props.forEach((propName) => {\n const valueString = Base.getCSSProperty(target, propName);\n if (valueString && valueString.charAt(valueString.length - 1) === \"%\") {\n const percentageValue = parseFloat(valueString);\n const value = (refValue * percentageValue) / 100;\n Base.setCSSProperty(target, propName, `${value}px`);\n }\n });\n }\n convertPercentageToPx([\"width\", \"max-width\", \"min-width\"], refWidth);\n convertPercentageToPx([\"height\", \"max-height\", \"min-height\"], refHeight);\n convertPercentageToPx(\n [\n \"margin-top\",\n \"margin-right\",\n \"margin-bottom\",\n \"margin-left\",\n \"padding-top\",\n \"padding-right\",\n \"padding-bottom\",\n \"padding-left\",\n ],\n this.vertical ? refHeight : refWidth,\n );\n [\"margin-top\", \"margin-right\", \"margin-bottom\", \"margin-left\"].forEach(\n (propName) => {\n const value = Base.getCSSProperty(target, propName);\n if (value === \"auto\") {\n Base.setCSSProperty(target, propName, \"0\");\n }\n },\n );\n }\n\n fixFloatSizeAndPosition(nodeContext: Vtree.NodeContext) {\n while (nodeContext.parent) {\n nodeContext = nodeContext.parent;\n }\n Asserts.assert(nodeContext.viewNode.nodeType === 1);\n const rootViewNode = nodeContext.viewNode as Element;\n this.rootViewNodes.push(rootViewNode);\n if (this.adjustContentRelativeSize) {\n this.convertPercentageSizesToPx(rootViewNode);\n }\n this.floatMargins.push(this.getComputedMargin(rootViewNode));\n if (this.adjustContentRelativeSize) {\n const floatSide = this.floatSide;\n const isVertical = this.parentContainer.vertical;\n if (isVertical) {\n if (floatSide === \"block-end\" || floatSide === \"left\") {\n const height = Base.getCSSProperty(rootViewNode, \"height\");\n if (height !== \"\" && height !== \"auto\") {\n Base.setCSSProperty(rootViewNode, \"margin-top\", \"auto\");\n }\n }\n } else {\n if (floatSide === \"block-end\" || floatSide === \"bottom\") {\n const width = Base.getCSSProperty(rootViewNode, \"width\");\n if (width !== \"\" && width !== \"auto\") {\n Base.setCSSProperty(rootViewNode, \"margin-left\", \"auto\");\n }\n }\n }\n }\n }\n\n getContentInlineSize(): number {\n return Math.max.apply(\n null,\n this.rootViewNodes.map((r, i) => {\n const box = this.clientLayout.getElementClientRect(r);\n const margin = this.floatMargins[i];\n return this.vertical\n ? margin.top + box.height + margin.bottom\n : margin.left + box.width + margin.right;\n }),\n );\n }\n}\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview RepetitiveElement - Elements repeated in every fragment\n * by repeat-on-break property.\n */\nimport * as Asserts from \"./asserts\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as LayoutUtil from \"./layout-util\";\nimport * as Plugin from \"./plugin\";\nimport * as Shared from \"./shared\";\nimport * as Task from \"./task\";\nimport * as VtreeImpl from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport {\n FormattingContextType,\n FragmentLayoutConstraintType,\n Layout as LayoutType,\n RepetitiveElement,\n Table,\n Vtree,\n} from \"./types\";\n\nexport class RepetitiveElementsOwnerFormattingContext\n implements RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n formattingContextType: FormattingContextType = \"RepetitiveElementsOwner\";\n isRoot: boolean = false;\n repetitiveElements: RepetitiveElement.RepetitiveElements = null;\n\n constructor(\n public readonly parent: Vtree.FormattingContext,\n public readonly rootSourceNode: Element,\n ) {}\n\n /**\n * @override\n */\n getName(): string {\n return \"Repetitive elements owner formatting context (RepetitiveElementsOwnerFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n return firstTime;\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n getRepetitiveElements(): RepetitiveElement.RepetitiveElements {\n return this.repetitiveElements;\n }\n\n getRootViewNode(position: Vtree.NodeContext): Element | null {\n const root = this.getRootNodeContext(position);\n return root ? (root.viewNode as Element) : null;\n }\n\n getRootNodeContext(nodeContext: Vtree.NodeContext): Vtree.NodeContext | null {\n do {\n if (\n !nodeContext.belongsTo(this) &&\n nodeContext.sourceNode === this.rootSourceNode\n ) {\n return nodeContext;\n }\n } while ((nodeContext = nodeContext.parent));\n return null;\n }\n\n initializeRepetitiveElements(vertical: boolean) {\n if (this.repetitiveElements) {\n return;\n }\n const found = Shared.repetitiveElementsCache.some((entry) => {\n if (entry.root === this.rootSourceNode) {\n this.repetitiveElements = entry.elements;\n return true;\n }\n return false;\n });\n if (!found) {\n this.repetitiveElements = new RepetitiveElements(\n vertical,\n this.rootSourceNode,\n );\n Shared.repetitiveElementsCache.push({\n root: this.rootSourceNode,\n elements: this.repetitiveElements,\n });\n }\n }\n\n /** @override */\n saveState(): any {}\n\n /** @override */\n restoreState(state: any) {}\n}\n\nexport type ElementsOffset = RepetitiveElement.ElementsOffset;\n\nexport class RepetitiveElements\n implements RepetitiveElement.RepetitiveElements {\n private headerSourceNode: Element | null = null;\n private footerSourceNode: Element | null = null;\n private headerViewNode: Element | null = null;\n private footerViewNode: Element | null = null;\n private headerNodePosition: Vtree.NodePosition | null = null;\n private footerNodePosition: Vtree.NodePosition | null = null;\n private headerHeight: number = 0;\n private footerHeight: number = 0;\n isSkipHeader: boolean = false;\n isSkipFooter: boolean = false;\n enableSkippingFooter: boolean = true;\n enableSkippingHeader: boolean = true;\n doneInitialLayout: boolean = false;\n firstContentSourceNode: Element | null = null;\n lastContentSourceNode: Element | null = null;\n private affectedNodeCache: {\n nodeContext: Vtree.NodeContext;\n result: boolean;\n }[] = [];\n private afterLastContentNodeCache: {\n nodeContext: Vtree.NodeContext;\n result: boolean;\n }[] = [];\n allowInsert: boolean = false;\n allowInsertRepeatitiveElements: boolean;\n\n constructor(\n private readonly vertical: boolean,\n public ownerSourceNode: Element,\n ) {}\n\n setHeaderNodeContext(nodeContext: Vtree.NodeContext) {\n if (this.headerNodePosition) {\n return; // use first one.\n }\n this.headerNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n this.headerSourceNode = nodeContext.sourceNode as Element;\n this.headerViewNode = nodeContext.viewNode as Element;\n }\n\n setFooterNodeContext(nodeContext: Vtree.NodeContext) {\n if (this.footerNodePosition) {\n return; // use first one.\n }\n this.footerNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nodeContext,\n 0,\n );\n this.footerSourceNode = nodeContext.sourceNode as Element;\n this.footerViewNode = nodeContext.viewNode as Element;\n }\n\n updateHeight(column: LayoutType.Column) {\n if (this.headerViewNode) {\n this.headerHeight = LayoutHelper.getElementHeight(\n this.headerViewNode,\n column,\n this.vertical,\n );\n this.headerViewNode = null;\n }\n if (this.footerViewNode) {\n this.footerHeight = LayoutHelper.getElementHeight(\n this.footerViewNode,\n column,\n this.vertical,\n );\n this.footerViewNode = null;\n }\n }\n\n prepareLayoutFragment() {\n this.isSkipHeader = this.isSkipFooter = false;\n this.enableSkippingFooter = true;\n this.enableSkippingHeader = true;\n }\n\n appendHeaderToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n if (!this.headerNodePosition || this.isSkipHeader) {\n return Task.newResult(true);\n }\n return this.appendElementToFragment(\n this.headerNodePosition,\n rootNodeContext,\n firstChild,\n column,\n );\n }\n\n appendFooterToFragment(\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n if (!this.footerNodePosition || this.isSkipFooter) {\n return Task.newResult(true);\n }\n return this.appendElementToFragment(\n this.footerNodePosition,\n rootNodeContext,\n firstChild,\n column,\n );\n }\n\n /**\n * @return\n */\n appendElementToFragment(\n nodePosition: Vtree.NodePosition,\n rootNodeContext: Vtree.NodeContext,\n firstChild: Node | null,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n const doc = rootNodeContext.viewNode.ownerDocument;\n const rootViewNode = rootNodeContext.viewNode as Element;\n const viewRoot = doc.createElement(\"div\");\n rootViewNode.appendChild(viewRoot);\n const pseudoColumn = new Layout.PseudoColumn(\n column,\n viewRoot,\n rootNodeContext,\n );\n const initialPageBreakType = pseudoColumn.getColumn().pageBreakType;\n pseudoColumn.getColumn().pageBreakType = null;\n this.allowInsertRepeatitiveElements = true;\n return pseudoColumn\n .layout(new VtreeImpl.ChunkPosition(nodePosition), true)\n .thenAsync(() => {\n this.allowInsertRepeatitiveElements = false;\n rootViewNode.removeChild(viewRoot);\n this.moveChildren(viewRoot, rootViewNode, firstChild);\n pseudoColumn.getColumn().pageBreakType = initialPageBreakType;\n return Task.newResult(true);\n });\n }\n\n moveChildren(from: Element, to: Element, firstChild: Node | null) {\n if (!to) {\n return;\n }\n while (from.firstChild) {\n const child = from.firstChild;\n from.removeChild(child);\n (child as Element).setAttribute(VtreeImpl.SPECIAL_ATTR, \"1\");\n if (firstChild) {\n to.insertBefore(child, firstChild);\n } else {\n to.appendChild(child);\n }\n }\n }\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n let offset = 0;\n if (nodeContext && !this.affectTo(nodeContext)) {\n return offset;\n }\n if (\n !this.isSkipFooter ||\n (nodeContext && this.isAfterLastContent(nodeContext))\n ) {\n offset += this.footerHeight;\n }\n if (!this.isSkipHeader) {\n offset += this.headerHeight;\n }\n return offset;\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n let offset = 0;\n if (nodeContext && !this.affectTo(nodeContext)) {\n return offset;\n }\n if (nodeContext && this.isAfterLastContent(nodeContext)) {\n offset += this.footerHeight;\n }\n if (!this.enableSkippingHeader) {\n offset += this.headerHeight;\n }\n return offset;\n }\n\n isAfterLastContent(nodeContext: Vtree.NodeContext): boolean {\n return this.findResultFromCache(\n nodeContext,\n this.afterLastContentNodeCache,\n (nc) =>\n this.isAfterNodeContextOf(\n this.lastContentSourceNode as Element,\n nodeContext,\n false,\n ),\n );\n }\n\n private affectTo(nodeContext: Vtree.NodeContext): boolean {\n return this.findResultFromCache(nodeContext, this.affectedNodeCache, (nc) =>\n this.isAfterNodeContextOf(this.ownerSourceNode, nodeContext, true),\n );\n }\n\n private findResultFromCache(\n nodeContext: Vtree.NodeContext,\n cache: { nodeContext: Vtree.NodeContext; result: boolean }[],\n calculator: (p1: Vtree.NodeContext) => boolean,\n ): boolean {\n const cacheEntry = cache.filter(\n (cache) =>\n cache.nodeContext.sourceNode === nodeContext.sourceNode &&\n cache.nodeContext.after === nodeContext.after,\n );\n if (cacheEntry.length > 0) {\n return cacheEntry[0].result;\n } else {\n const result = calculator(nodeContext);\n cache.push({ nodeContext, result });\n return result;\n }\n }\n\n private isAfterNodeContextOf(\n node: Element,\n nodeContext: Vtree.NodeContext,\n includeChildren: boolean,\n ): boolean {\n const parentsOfNode = [];\n for (let n: Node | null = node; n; n = n.parentNode) {\n if (nodeContext.sourceNode === n) {\n return nodeContext.after;\n } else {\n parentsOfNode.push(n);\n }\n }\n for (\n let currentParent: Node | null = nodeContext.sourceNode;\n currentParent;\n currentParent = currentParent.parentNode\n ) {\n const index = parentsOfNode.indexOf(currentParent);\n if (index >= 0) {\n return includeChildren ? index === 0 : false;\n } else {\n for (\n let current: Element | null = currentParent as Element;\n current;\n current = current.previousElementSibling\n ) {\n if (parentsOfNode.includes(current)) {\n return true;\n }\n }\n }\n }\n return nodeContext.after;\n }\n\n isFirstContentNode(nodeContext: Vtree.NodeContext): boolean {\n return (\n nodeContext && this.firstContentSourceNode === nodeContext.sourceNode\n );\n }\n\n isEnableToUpdateState(): boolean {\n if (\n (!this.isSkipFooter &&\n this.enableSkippingFooter &&\n this.footerNodePosition) ||\n (!this.isSkipHeader &&\n this.enableSkippingHeader &&\n this.headerNodePosition)\n ) {\n return true;\n } else {\n return false;\n }\n }\n\n updateState() {\n if (\n !this.isSkipFooter &&\n this.enableSkippingFooter &&\n this.footerNodePosition\n ) {\n this.isSkipFooter = true;\n } else if (\n !this.isSkipHeader &&\n this.enableSkippingHeader &&\n this.headerNodePosition\n ) {\n this.isSkipHeader = true;\n }\n }\n\n preventSkippingHeader() {\n this.isSkipHeader = false;\n this.enableSkippingHeader = false;\n }\n\n preventSkippingFooter() {\n this.isSkipFooter = false;\n this.enableSkippingFooter = false;\n }\n\n isHeaderRegistered(): boolean {\n return !!this.headerNodePosition;\n }\n\n isFooterRegistered(): boolean {\n return !!this.footerNodePosition;\n }\n\n isHeaderSourceNode(node: Node): boolean {\n return this.headerSourceNode === node;\n }\n\n isFooterSourceNode(node: Node): boolean {\n return this.footerSourceNode === node;\n }\n}\n\n/**\n * @abstract\n */\nexport abstract class LayoutEntireBlock implements LayoutType.LayoutMode {\n constructor(\n public formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n ) {}\n\n /**\n * @override\n */\n abstract doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return !!nodeContext;\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n accepted: boolean,\n ): boolean {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n Asserts.assert(column.clientLayout);\n if (!repetitiveElements.doneInitialLayout) {\n repetitiveElements.updateHeight(column);\n repetitiveElements.doneInitialLayout = true;\n }\n }\n return accepted;\n }\n}\n\n/**\n * @abstract\n */\nexport abstract class LayoutFragmentedBlock implements LayoutType.LayoutMode {\n constructor(\n public formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n ) {}\n\n /**\n * @override\n */\n abstract doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext>;\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return true;\n }\n\n /**\n * @override\n */\n postLayout(\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n accepted: boolean,\n ): boolean {\n return accepted;\n }\n}\n\nexport class LayoutEntireOwnerBlock extends LayoutEntireBlock {\n constructor(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n // FIXME: LayoutEntireBlock.prototype.doLayout is undefined because it's abstract method.\n // Probably, removing this call is ok.\n // LayoutEntireBlock.prototype.doLayout.call(this, nodeContext, column);\n return this.processor.doInitialLayout(nodeContext, column);\n }\n\n /**\n * @override\n */\n accept(nodeContext: Vtree.NodeContext, column: LayoutType.Column): boolean {\n return false;\n }\n}\n\nexport class LayoutFragmentedOwnerBlock extends LayoutFragmentedBlock {\n constructor(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n if (!nodeContext.belongsTo(this.formattingContext) && !nodeContext.after) {\n column.fragmentLayoutConstraints.unshift(\n new RepetitiveElementsOwnerLayoutConstraint(nodeContext),\n );\n }\n return this.processor.doLayout(nodeContext, column);\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutConstraint\n implements RepetitiveElement.RepetitiveElementsOwnerLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType =\n \"RepetitiveElementsOwner\";\n nodeContext: Vtree.NodeContext;\n\n constructor(nodeContext: Vtree.NodeContext) {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n this.nodeContext = formattingContext.getRootNodeContext(nodeContext);\n }\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return true;\n }\n if (LayoutHelper.isOrphan(this.nodeContext.viewNode)) {\n return true;\n }\n if (!repetitiveElements.isEnableToUpdateState()) {\n return true;\n }\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n if (repetitiveElements.isEnableToUpdateState()) {\n repetitiveElements.updateState();\n return true;\n } else {\n return false;\n }\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: LayoutType.Column,\n ) {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return;\n }\n if (allowed) {\n if (column.stopAtOverflow) {\n if (\n positionAfter == null ||\n repetitiveElements.isAfterLastContent(positionAfter)\n ) {\n repetitiveElements.preventSkippingFooter();\n }\n }\n }\n }\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<boolean> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n );\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return Task.newResult(true);\n }\n const rootNodeContext = this.nodeContext;\n return appendHeader(formattingContext, rootNodeContext, column).thenAsync(\n () =>\n appendFooter(formattingContext, rootNodeContext, column).thenAsync(\n () => {\n repetitiveElements.prepareLayoutFragment();\n return Task.newResult(true);\n },\n ),\n );\n }\n\n getRepetitiveElements(): RepetitiveElement.RepetitiveElements {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n );\n return formattingContext.getRepetitiveElements();\n }\n\n /** @override */\n equalsTo(constraint: LayoutType.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof RepetitiveElementsOwnerLayoutConstraint)) {\n return false;\n }\n return (\n getRepetitiveElementsOwnerFormattingContext(\n this.nodeContext.formattingContext,\n ) ===\n getRepetitiveElementsOwnerFormattingContext(\n constraint.nodeContext.formattingContext,\n )\n );\n }\n\n /** @override */\n getPriorityOfFinishBreak(): number {\n return 10;\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n constructor(\n public readonly formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n private readonly processor: RepetitiveElementsOwnerLayoutProcessor,\n ) {\n super();\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): LayoutType.LayoutMode {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (\n !nodeContext.belongsTo(this.formattingContext) &&\n !repetitiveElements.doneInitialLayout\n ) {\n return new LayoutEntireOwnerBlock(this.formattingContext, this.processor);\n } else {\n if (\n !nodeContext.belongsTo(this.formattingContext) &&\n !nodeContext.after\n ) {\n if (repetitiveElements) {\n repetitiveElements.preventSkippingHeader();\n }\n }\n return new LayoutFragmentedOwnerBlock(\n this.formattingContext,\n this.processor,\n );\n }\n }\n}\n\nexport class EntireBlockLayoutStrategy extends LayoutUtil.EdgeSkipper {\n constructor(\n public readonly formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n public readonly column: LayoutType.Column,\n ) {\n super();\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (\n nodeContext.parent &&\n formattingContext.rootSourceNode === nodeContext.parent.sourceNode\n ) {\n switch (nodeContext.repeatOnBreak) {\n case \"header\":\n if (!repetitiveElements.isHeaderRegistered()) {\n repetitiveElements.setHeaderNodeContext(nodeContext);\n return Task.newResult(true);\n } else {\n nodeContext.repeatOnBreak = \"none\";\n }\n break;\n case \"footer\":\n if (!repetitiveElements.isFooterRegistered()) {\n repetitiveElements.setFooterNodeContext(nodeContext);\n return Task.newResult(true);\n } else {\n nodeContext.repeatOnBreak = \"none\";\n }\n break;\n }\n if (!repetitiveElements.firstContentSourceNode) {\n repetitiveElements.firstContentSourceNode = nodeContext.sourceNode as Element;\n }\n }\n return LayoutUtil.EdgeSkipper.prototype.startNonInlineElementNode.call(\n this,\n state,\n );\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n if (nodeContext.sourceNode === formattingContext.rootSourceNode) {\n formattingContext.getRepetitiveElements().lastContentSourceNode =\n state.lastAfterNodeContext &&\n (state.lastAfterNodeContext.sourceNode as Element);\n state.break = true;\n }\n if (\n nodeContext.repeatOnBreak === \"header\" ||\n nodeContext.repeatOnBreak === \"footer\"\n ) {\n return Task.newResult(true);\n } else {\n return LayoutUtil.EdgeSkipper.prototype.afterNonInlineElementNode.call(\n this,\n state,\n );\n }\n }\n}\n\nexport class FragmentedBlockLayoutStrategy extends LayoutUtil.EdgeSkipper {\n constructor(\n public readonly formattingContext: RepetitiveElementsOwnerFormattingContext,\n public readonly column: LayoutType.Column,\n ) {\n super();\n }\n}\n\nexport class RepetitiveElementsOwnerLayoutProcessor\n extends LayoutProcessor.BlockLayoutProcessor\n implements LayoutProcessor.LayoutProcessor {\n layout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n if (column.isFloatNodeContext(nodeContext)) {\n return column.layoutFloatOrFootnote(nodeContext);\n }\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(nodeContext);\n if (!rootViewNode) {\n return column.buildDeepElementView(nodeContext);\n } else {\n if (leadingEdge) {\n appendHeaderToAncestors(nodeContext.parent, column);\n }\n if (!nodeContext.belongsTo(formattingContext)) {\n return new RepetitiveElementsOwnerLayoutRetryer(\n formattingContext,\n this,\n ).layout(nodeContext, column);\n } else {\n return LayoutProcessor.BlockLayoutProcessor.prototype.layout.call(\n this,\n nodeContext,\n column,\n leadingEdge,\n );\n }\n }\n }\n\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n const formattingContext = getRepetitiveElementsOwnerFormattingContextOrNull(\n nodeContext,\n );\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return false;\n }\n if (\n !repetitiveElements.allowInsertRepeatitiveElements &&\n (repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode) ||\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode))\n ) {\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n }\n return false;\n }\n\n doInitialLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"BlockLayoutProcessor.doInitialLayout\",\n );\n this.layoutEntireBlock(nodeContext, column).thenFinish(frame);\n return frame.result();\n }\n\n private layoutEntireBlock(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const strategy = new EntireBlockLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n return iterator.iterate(nodeContext);\n }\n\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getRepetitiveElementsOwnerFormattingContext(\n nodeContext.formattingContext,\n );\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"doLayout\");\n const cont = column.layoutContext.nextInTree(nodeContext, false);\n Layout.processAfterIfContinues(cont, column).then((resNodeContext) => {\n let nextNodeContext = resNodeContext;\n frame\n .loopWithFrame((loopFrame) => {\n while (nextNodeContext) {\n let pending = true;\n column\n .layoutNext(nextNodeContext, false)\n .then((nodeContextParam) => {\n nextNodeContext = nodeContextParam;\n if (column.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n } else if (column.pageBreakType) {\n loopFrame.breakLoop(); // Loop end\n } else if (\n nextNodeContext &&\n column.stopByOverflow(nextNodeContext)\n ) {\n loopFrame.breakLoop(); // Loop end\n } else if (\n nextNodeContext &&\n nextNodeContext.after &&\n nextNodeContext.sourceNode == formattingContext.rootSourceNode\n ) {\n loopFrame.breakLoop(); // Loop end\n } else {\n if (pending) {\n // Sync case\n pending = false;\n } else {\n // Async case\n loopFrame.continueLoop();\n }\n }\n });\n if (pending) {\n // Async case and loop end\n pending = false;\n return;\n }\n }\n\n // Sync case\n loopFrame.breakLoop();\n })\n .then(() => {\n frame.finish(nextNodeContext);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n finishBreak(\n column: LayoutType.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> | null {\n return LayoutProcessor.BlockLayoutProcessor.prototype.finishBreak.call(\n this,\n column,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n\n /**\n * @override\n */\n clearOverflownViewNodes(\n column: LayoutType.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n LayoutProcessor.BlockLayoutProcessor.prototype.clearOverflownViewNodes(\n column,\n parentNodeContext,\n nodeContext,\n removeSelf,\n );\n }\n}\n\nfunction eachAncestorNodeContext(\n nodeContext: Vtree.NodeContext,\n callback: (\n p1: RepetitiveElementsOwnerFormattingContext,\n p2: Vtree.NodeContext,\n ) => any,\n): void {\n for (let nc = nodeContext; nc; nc = nc.parent) {\n const formattingContext = nc.formattingContext;\n if (\n formattingContext &&\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext &&\n !nc.belongsTo(formattingContext)\n ) {\n callback(formattingContext, nc);\n }\n }\n}\n\nexport function appendHeaderToAncestors(\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): void {\n if (!nodeContext) {\n return;\n }\n eachAncestorNodeContext(\n nodeContext.after ? nodeContext.parent : nodeContext,\n (formattingContext, nc) => {\n if (Table.isInstanceOfTableFormattingContext(formattingContext)) {\n return;\n }\n column.fragmentLayoutConstraints.push(\n new RepetitiveElementsOwnerLayoutConstraint(nc),\n );\n },\n );\n}\n\nexport function appendHeader(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): Task.Result<boolean> {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n const rootNodeContext = formattingContext.getRootNodeContext(nodeContext);\n if (rootNodeContext.viewNode) {\n const firstChild = rootNodeContext.viewNode.firstChild;\n return repetitiveElements.appendHeaderToFragment(\n rootNodeContext,\n firstChild,\n column,\n );\n }\n }\n return Task.newResult(true);\n}\n\nexport function appendFooter(\n formattingContext: RepetitiveElement.RepetitiveElementsOwnerFormattingContext,\n nodeContext: Vtree.NodeContext,\n column: LayoutType.Column,\n): Task.Result<boolean> {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (repetitiveElements) {\n if (!repetitiveElements.isSkipFooter) {\n const rootNodeContext = formattingContext.getRootNodeContext(nodeContext);\n if (rootNodeContext.viewNode) {\n return repetitiveElements.appendFooterToFragment(\n rootNodeContext,\n null,\n column,\n );\n }\n }\n }\n return Task.newResult(true);\n}\n\nfunction getRepetitiveElementsOwnerFormattingContextOrNull(\n nodeContext: Vtree.NodeContext,\n): RepetitiveElement.RepetitiveElementsOwnerFormattingContext | null {\n const formattingContext = nodeContext.formattingContext;\n if (!formattingContext) {\n return null;\n }\n if (\n !(formattingContext instanceof RepetitiveElementsOwnerFormattingContext)\n ) {\n return null;\n }\n return formattingContext;\n}\n\nfunction getRepetitiveElementsOwnerFormattingContext(\n formattingContext: Vtree.FormattingContext,\n): RepetitiveElement.RepetitiveElementsOwnerFormattingContext {\n Asserts.assert(\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext,\n );\n return formattingContext as RepetitiveElement.RepetitiveElementsOwnerFormattingContext;\n}\n\nconst repetitiveLayoutProcessor = new RepetitiveElementsOwnerLayoutProcessor();\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n (formattingContext) => {\n if (\n formattingContext instanceof RepetitiveElementsOwnerFormattingContext &&\n !Table.isInstanceOfTableFormattingContext(formattingContext)\n ) {\n return repetitiveLayoutProcessor;\n }\n return null;\n },\n);\n","/**\n * Copyright 2016 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Table - Table formatting context and layout.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as BreakPosition from \"./break-position\";\nimport * as Css from \"./css\";\nimport * as LayoutHelper from \"./layout-helper\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as LayoutRetryers from \"./layout-retryers\";\nimport * as LayoutUtil from \"./layout-util\";\nimport * as Plugin from \"./plugin\";\nimport * as RepetitiveElementImpl from \"./repetitive-element\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as VtreeImpl from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport {\n FormattingContextType,\n FragmentLayoutConstraintType,\n Layout as LayoutType,\n RepetitiveElement,\n Table,\n Vtree,\n} from \"./types\";\n\nexport class TableRow {\n cells: TableCell[] = [];\n\n constructor(\n public readonly rowIndex: number,\n public readonly sourceNode: Node,\n ) {}\n\n addCell(cell: TableCell) {\n this.cells.push(cell);\n }\n\n getMinimumHeight(): number {\n return Math.min.apply(\n null,\n this.cells.map((c) => c.height),\n );\n }\n}\n\nexport class TableCell {\n viewElement: Element | null;\n colSpan: number;\n rowSpan: number;\n height: number = 0;\n anchorSlot: TableSlot = null;\n\n constructor(\n public readonly rowIndex: number,\n public readonly columnIndex: number,\n viewElement: Element,\n ) {\n this.viewElement = viewElement;\n this.colSpan = (viewElement as HTMLTableCellElement).colSpan || 1;\n this.rowSpan = (viewElement as HTMLTableCellElement).rowSpan || 1;\n }\n\n setHeight(height: number) {\n this.height = height;\n }\n\n setAnchorSlot(slot: TableSlot) {\n this.anchorSlot = slot;\n }\n}\n\nexport class TableSlot {\n constructor(\n public readonly rowIndex: number,\n public readonly columnIndex: number,\n public readonly cell: TableCell,\n ) {}\n}\n\nexport class TableCellFragment {\n pseudoColumn: Layout.PseudoColumn;\n empty: boolean = false;\n\n constructor(\n public readonly column: Layout.Column,\n pseudoColumnContainer: Element,\n public readonly cellNodeContext: Vtree.NodeContext,\n ) {\n this.pseudoColumn = new Layout.PseudoColumn(\n column,\n pseudoColumnContainer,\n cellNodeContext,\n );\n }\n\n findAcceptableBreakPosition(): Layout.BreakPositionAndNodeContext {\n const element = this.cellNodeContext.viewNode as Element;\n const verticalAlign = this.cellNodeContext.verticalAlign;\n if (verticalAlign === \"middle\" || verticalAlign === \"bottom\") {\n Base.setCSSProperty(element, \"vertical-align\", \"top\");\n }\n const bp = this.pseudoColumn.findAcceptableBreakPosition(true);\n Base.setCSSProperty(element, \"vertical-align\", verticalAlign);\n return bp;\n }\n}\n\nexport class TableCaptionView {\n constructor(\n public readonly viewNode: Element,\n public readonly side: string,\n ) {}\n}\n\nexport class BetweenTableRowBreakPosition extends BreakPosition.EdgeBreakPosition {\n private formattingContext: TableFormattingContext;\n\n acceptableCellBreakPositions: Layout.BreakPositionAndNodeContext[] = null;\n private rowIndex: number | null = null;\n\n constructor(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ) {\n super(position, breakOnEdge, overflows, columnBlockSize);\n this.formattingContext = position.formattingContext as TableFormattingContext;\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n const breakNodeContext = super.findAcceptableBreak(column, penalty);\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n const allCellsBreakable = this.getAcceptableCellBreakPositions().every(\n (bp) => !!bp.nodeContext,\n );\n if (allCellsBreakable) {\n return breakNodeContext;\n } else {\n return null;\n }\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n let penalty = super.getMinBreakPenalty();\n this.getAcceptableCellBreakPositions().forEach((bp) => {\n penalty += bp.breakPosition.getMinBreakPenalty();\n });\n return penalty;\n }\n\n getAcceptableCellBreakPositions(): Layout.BreakPositionAndNodeContext[] {\n if (!this.acceptableCellBreakPositions) {\n const formattingContext = this.formattingContext;\n const cellFragments = this.getCellFragments();\n this.acceptableCellBreakPositions = cellFragments.map((cellFragment) =>\n cellFragment.findAcceptableBreakPosition(),\n );\n }\n return this.acceptableCellBreakPositions;\n }\n\n private getRowIndex(): number {\n if (this.rowIndex != null) {\n return this.rowIndex;\n }\n return (this.rowIndex = this.formattingContext.findRowIndexBySourceNode(\n this.position.sourceNode,\n ));\n }\n\n private getCellFragments() {\n return this.formattingContext\n .getRowSpanningCellsOverflowingTheRow(this.getRowIndex())\n .map(\n this.formattingContext.getCellFragmentOfCell,\n this.formattingContext,\n );\n }\n}\n\nexport class InsideTableRowBreakPosition extends BreakPosition.AbstractBreakPosition {\n acceptableCellBreakPositions: Layout.BreakPositionAndNodeContext[] = null;\n\n constructor(\n public readonly rowIndex: number,\n public readonly beforeNodeContext: Vtree.NodeContext,\n public readonly formattingContext: TableFormattingContext,\n ) {\n super();\n }\n\n /**\n * @override\n */\n findAcceptableBreak(\n column: Layout.Column,\n penalty: number,\n ): Vtree.NodeContext {\n if (penalty < this.getMinBreakPenalty()) {\n return null;\n }\n const cellFragments = this.getCellFragments();\n const acceptableCellBreakPositions = this.getAcceptableCellBreakPositions();\n const allCellsBreakable =\n acceptableCellBreakPositions.every((bp) => !!bp.nodeContext) &&\n acceptableCellBreakPositions.some((bp, index) => {\n const pseudoColumn = cellFragments[index].pseudoColumn;\n const nodeContext = bp.nodeContext;\n return (\n !pseudoColumn.isStartNodeContext(nodeContext) &&\n !pseudoColumn.isLastAfterNodeContext(nodeContext)\n );\n });\n this.beforeNodeContext.overflow = acceptableCellBreakPositions.some(\n (bp) => bp.nodeContext && bp.nodeContext.overflow,\n );\n if (allCellsBreakable) {\n return this.beforeNodeContext;\n } else {\n return null;\n }\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n const formattingContext = this.formattingContext;\n const row = formattingContext.getRowByIndex(this.rowIndex);\n let penalty = 0;\n if (!formattingContext.isFreelyFragmentableRow(row)) {\n penalty += 10;\n }\n this.getAcceptableCellBreakPositions().forEach((bp) => {\n penalty += bp.breakPosition.getMinBreakPenalty();\n });\n return penalty;\n }\n\n getAcceptableCellBreakPositions(): Layout.BreakPositionAndNodeContext[] {\n if (!this.acceptableCellBreakPositions) {\n const cellFragments = this.getCellFragments();\n this.acceptableCellBreakPositions = cellFragments.map((cellFragment) =>\n cellFragment.findAcceptableBreakPosition(),\n );\n }\n return this.acceptableCellBreakPositions;\n }\n\n private getCellFragments() {\n return this.formattingContext\n .getCellsFallingOnRow(this.rowIndex)\n .map(\n this.formattingContext.getCellFragmentOfCell,\n this.formattingContext,\n );\n }\n}\n\nexport type BrokenTableCellPosition = {\n cellNodePosition: Vtree.NodePosition;\n breakChunkPosition: Vtree.ChunkPosition;\n cell: TableCell;\n};\n\n/**\n * @param tableSourceNode Source node of the table\n */\nexport class TableFormattingContext\n extends RepetitiveElementImpl.RepetitiveElementsOwnerFormattingContext\n implements Table.TableFormattingContext {\n formattingContextType: FormattingContextType = \"Table\";\n vertical: boolean = false;\n columnCount: number = -1;\n tableWidth: number = 0;\n captions: TableCaptionView[] = [];\n colGroups: DocumentFragment | null = null;\n colWidths: number[] | null = null;\n inlineBorderSpacing: number = 0;\n rows: TableRow[] = [];\n slots: TableSlot[][] = [];\n cellFragments: TableCellFragment[][] = [];\n lastRowViewNode: Element | null = null;\n cellBreakPositions: BrokenTableCellPosition[] = [];\n repetitiveElements: RepetitiveElement.RepetitiveElements | null = null;\n\n constructor(\n parent: Vtree.FormattingContext,\n public readonly tableSourceNode: Element,\n ) {\n super(parent, tableSourceNode);\n }\n\n /**\n * @override\n */\n getName(): string {\n return \"Table formatting context (Table.TableFormattingContext)\";\n }\n\n /**\n * @override\n */\n isFirstTime(nodeContext: Vtree.NodeContext, firstTime: boolean): boolean {\n if (!firstTime) {\n return firstTime;\n }\n switch (nodeContext.display) {\n case \"table-row\":\n return this.cellBreakPositions.length === 0;\n case \"table-cell\":\n return !this.cellBreakPositions.some(\n (p) => p.cellNodePosition.steps[0].node === nodeContext.sourceNode,\n );\n default:\n return firstTime;\n }\n }\n\n /**\n * @override\n */\n getParent(): Vtree.FormattingContext {\n return this.parent;\n }\n\n finishFragment() {\n this.cellFragments = [];\n }\n\n addRow(rowIndex: number, row: TableRow) {\n this.rows[rowIndex] = row;\n }\n\n getRowSlots(rowIndex: number): TableSlot[] {\n let rowSlots = this.slots[rowIndex];\n if (!rowSlots) {\n rowSlots = this.slots[rowIndex] = [];\n }\n return rowSlots;\n }\n\n addCell(rowIndex: number, cell: TableCell) {\n let row = this.rows[rowIndex];\n if (!row) {\n this.addRow(rowIndex, new TableRow(rowIndex, null));\n row = this.rows[rowIndex];\n }\n Asserts.assert(row);\n row.addCell(cell);\n const rowUpper = rowIndex + cell.rowSpan;\n let rowSlots = this.getRowSlots(rowIndex);\n let startColIndex = 0;\n while (rowSlots[startColIndex]) {\n startColIndex++;\n }\n for (; rowIndex < rowUpper; rowIndex++) {\n rowSlots = this.getRowSlots(rowIndex);\n for (let i = startColIndex; i < startColIndex + cell.colSpan; i++) {\n const slot = (rowSlots[i] = new TableSlot(rowIndex, i, cell));\n if (!cell.anchorSlot) {\n cell.setAnchorSlot(slot);\n }\n }\n }\n }\n\n getRowByIndex(index: number): TableRow {\n const row = this.rows[index];\n Asserts.assert(row);\n return row;\n }\n\n findRowIndexBySourceNode(sourceNode: Node): number {\n return this.rows.findIndex((row) => sourceNode === row.sourceNode);\n }\n\n addCellFragment(\n rowIndex: number,\n columnIndex: number,\n cellFragment: TableCellFragment,\n ) {\n let list = this.cellFragments[rowIndex];\n if (!list) {\n list = this.cellFragments[rowIndex] = [];\n }\n list[columnIndex] = cellFragment;\n }\n\n getCellsFallingOnRow(rowIndex: number): TableCell[] {\n const rowSlots = this.getRowSlots(rowIndex);\n return rowSlots.reduce((uniqueCells, slot) => {\n if (slot.cell !== uniqueCells[uniqueCells.length - 1]) {\n return uniqueCells.concat(slot.cell);\n } else {\n return uniqueCells;\n }\n }, []);\n }\n\n getRowSpanningCellsOverflowingTheRow(rowIndex: number): TableCell[] {\n return this.getCellsFallingOnRow(rowIndex).filter(\n (cell) => cell.rowIndex + cell.rowSpan - 1 > rowIndex,\n );\n }\n\n getCellFragmentOfCell(cell: TableCell): TableCellFragment {\n return (\n this.cellFragments[cell.rowIndex] &&\n this.cellFragments[cell.rowIndex][cell.columnIndex]\n );\n }\n\n isFreelyFragmentableRow(row: TableRow): boolean {\n return row.getMinimumHeight() > this.tableWidth / 2;\n }\n\n getColumnCount(): number {\n if (this.columnCount < 0) {\n this.columnCount = Math.max.apply(\n null,\n this.rows.map((row) =>\n row.cells.reduce((sum, c) => sum + c.colSpan, 0),\n ),\n );\n }\n return this.columnCount;\n }\n\n updateCellSizes(clientLayout: Vtree.ClientLayout) {\n this.rows.forEach((row) => {\n row.cells.forEach((cell) => {\n const rect = clientLayout.getElementClientRect(\n cell.viewElement as Element,\n );\n cell.viewElement = null;\n cell.setHeight(this.vertical ? rect[\"width\"] : rect[\"height\"]);\n });\n });\n }\n\n /**\n * @return position\n */\n findCellFromColumn(\n column: Layout.Column,\n ): { rowIndex: number; columnIndex: number } | null {\n if (!column) {\n return null;\n }\n let tableCell: TableCell = null;\n let row = 0;\n let col = 0;\n loop: for (row = 0; row < this.cellFragments.length; row++) {\n if (!this.cellFragments[row]) {\n continue;\n }\n for (col = 0; col < this.cellFragments[row].length; col++) {\n if (!this.cellFragments[row][col]) {\n continue;\n }\n if (column === this.cellFragments[row][col].pseudoColumn.getColumn()) {\n tableCell = this.rows[row].cells[col];\n break loop;\n }\n }\n }\n if (!tableCell) {\n return null;\n }\n for (; row < this.slots.length; row++) {\n for (; col < this.slots[row].length; col++) {\n const slot = this.slots[row][col];\n if (slot.cell === tableCell) {\n return { rowIndex: slot.rowIndex, columnIndex: slot.columnIndex };\n }\n }\n }\n return null;\n }\n\n collectElementsOffsetOfUpperCells(\n position: { rowIndex: number; columnIndex: number } | null,\n ): RepetitiveElement.ElementsOffset[] {\n const collected = [];\n return this.slots.reduce((repetitiveElements, row, index) => {\n if (index >= position.rowIndex) {\n return repetitiveElements;\n }\n const cellFragment = this.getCellFragmentOfCell(\n row[position.columnIndex].cell,\n );\n if (!cellFragment || collected.includes(cellFragment)) {\n return repetitiveElements;\n }\n this.collectElementsOffsetFromColumn(\n cellFragment.pseudoColumn.getColumn(),\n repetitiveElements,\n );\n collected.push(cellFragment);\n return repetitiveElements;\n }, [] as RepetitiveElement.ElementsOffset[]);\n }\n\n collectElementsOffsetOfHighestColumn(): RepetitiveElement.ElementsOffset[] {\n const elementsInColumn = [];\n this.rows.forEach((row) => {\n row.cells.forEach((cell, index) => {\n if (!elementsInColumn[index]) {\n elementsInColumn[index] = { collected: [], elements: [] };\n }\n const state = elementsInColumn[index];\n const cellFragment = this.getCellFragmentOfCell(cell);\n if (!cellFragment || state.collected.includes(cellFragment)) {\n return;\n }\n this.collectElementsOffsetFromColumn(\n cellFragment.pseudoColumn.getColumn(),\n state.elements,\n );\n state.collected.push(cellFragment);\n });\n });\n return [\n new ElementsOffsetOfTableCell(\n elementsInColumn.map((entry) => entry.elements),\n ),\n ];\n }\n\n private collectElementsOffsetFromColumn(\n column: LayoutType.Column,\n repetitiveElements: RepetitiveElement.ElementsOffset[],\n ) {\n column.fragmentLayoutConstraints.forEach((constraint) => {\n if (\n RepetitiveElement.isInstanceOfRepetitiveElementsOwnerLayoutConstraint(\n constraint,\n )\n ) {\n const repetitiveElement = constraint.getRepetitiveElements();\n repetitiveElements.push(repetitiveElement);\n }\n if (Table.isInstanceOfTableRowLayoutConstraint(constraint)) {\n constraint\n .getElementsOffsetsForTableCell(null)\n .forEach((repetitiveElement) => {\n repetitiveElements.push(repetitiveElement);\n });\n }\n });\n }\n\n /** @override */\n saveState(): any {\n return [].concat(this.cellBreakPositions);\n }\n\n /** @override */\n restoreState(state: any) {\n this.cellBreakPositions = state as BrokenTableCellPosition[];\n }\n}\n\nexport class ElementsOffsetOfTableCell\n implements RepetitiveElement.ElementsOffset {\n constructor(\n public readonly repeatitiveElementsInColumns: RepetitiveElement.ElementsOffset[][],\n ) {}\n\n /** @override */\n calculateOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateMaxOffsetOfColumn(\n nodeContext,\n (offsets) => offsets.current,\n );\n }\n\n /** @override */\n calculateMinimumOffset(nodeContext: Vtree.NodeContext): number {\n return this.calculateMaxOffsetOfColumn(\n nodeContext,\n (offsets) => offsets.minimum,\n );\n }\n\n private calculateMaxOffsetOfColumn(nodeContext, resolver) {\n let maxOffset = 0;\n this.repeatitiveElementsInColumns.forEach((repetitiveElements) => {\n const offsets = BreakPosition.calculateOffset(\n nodeContext,\n repetitiveElements,\n );\n maxOffset = Math.max(maxOffset, resolver(offsets));\n });\n return maxOffset;\n }\n}\n\nfunction getTableFormattingContext(\n formattingContext: Vtree.FormattingContext,\n): TableFormattingContext {\n Asserts.assert(formattingContext instanceof TableFormattingContext);\n return formattingContext as TableFormattingContext;\n}\n\nfunction isTableRowGrouping(display: string | null): boolean {\n return (\n display === \"table-row-group\" ||\n display === \"table-header-group\" ||\n display === \"table-footer-group\"\n );\n}\n\nfunction isTableRoot(display: string | null): boolean {\n return display === \"table\" || display === \"inline-table\";\n}\n\nfunction isValidParentOfTableRow(display: string | null): boolean {\n return isTableRowGrouping(display) || isTableRoot(display);\n}\n\nfunction skipNestedTable(\n state: LayoutUtil.LayoutIteratorState,\n formattingContext: TableFormattingContext,\n column: Layout.Column,\n): Task.Result<boolean> | null {\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const parentDisplay = nodeContext.parent ? nodeContext.parent.display : null;\n\n // Is inline-table nested in another table?\n let isNestedInlineTable = false;\n if (\n parentDisplay === \"inline-table\" &&\n !(nodeContext.formattingContext instanceof TableFormattingContext)\n ) {\n for (let nc = nodeContext.parent; nc; nc = nc.parent) {\n if (nc.formattingContext instanceof TableFormattingContext) {\n isNestedInlineTable = nc.formattingContext === formattingContext;\n break;\n }\n }\n }\n const isNestedTable =\n isNestedInlineTable ||\n (display === \"table-row\" && !isValidParentOfTableRow(parentDisplay)) ||\n (display === \"table-cell\" &&\n parentDisplay !== \"table-row\" &&\n !isValidParentOfTableRow(parentDisplay)) ||\n (nodeContext.formattingContext instanceof TableFormattingContext &&\n nodeContext.formattingContext !== formattingContext);\n if (isNestedTable) {\n return column\n .buildDeepElementView(nodeContext)\n .thenAsync((nodeContextAfter) => {\n state.nodeContext = nodeContextAfter;\n return Task.newResult(true);\n });\n } else {\n return null;\n }\n}\n\nexport class EntireTableLayoutStrategy extends LayoutUtil.EdgeSkipper {\n rowIndex: number = -1;\n columnIndex: number = 0;\n inRow: boolean = false;\n checkPoints: Vtree.NodeContext[] = [];\n inHeaderOrFooter: boolean = false;\n\n constructor(\n public readonly formattingContext: TableFormattingContext,\n public readonly column: Layout.Column,\n ) {\n super();\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const r = skipNestedTable(state, formattingContext, this.column);\n if (r) {\n return r;\n }\n this.postLayoutBlockContents(state);\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const repetitiveElements = formattingContext.getRepetitiveElements();\n switch (display) {\n case \"table\":\n formattingContext.inlineBorderSpacing = nodeContext.inlineBorderSpacing;\n break;\n case \"table-caption\": {\n const captionView = new TableCaptionView(\n nodeContext.viewNode as Element,\n nodeContext.captionSide,\n );\n formattingContext.captions.push(captionView);\n break;\n }\n case \"table-header-group\":\n if (!repetitiveElements.isHeaderRegistered()) {\n this.inHeaderOrFooter = true;\n repetitiveElements.setHeaderNodeContext(nodeContext);\n }\n return Task.newResult(true);\n case \"table-footer-group\":\n if (!repetitiveElements.isFooterRegistered()) {\n this.inHeaderOrFooter = true;\n repetitiveElements.setFooterNodeContext(nodeContext);\n }\n return Task.newResult(true);\n case \"table-row\":\n if (!this.inHeaderOrFooter) {\n this.inRow = true;\n this.rowIndex++;\n Asserts.assert(nodeContext.sourceNode);\n this.columnIndex = 0;\n formattingContext.addRow(\n this.rowIndex,\n new TableRow(this.rowIndex, nodeContext.sourceNode),\n );\n if (!repetitiveElements.firstContentSourceNode) {\n repetitiveElements.firstContentSourceNode = nodeContext.sourceNode as Element;\n }\n }\n break;\n }\n return super.startNonInlineElementNode(state);\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n const clientLayout = this.column.clientLayout;\n this.postLayoutBlockContents(state);\n if (nodeContext.sourceNode === formattingContext.tableSourceNode) {\n const computedStyle = clientLayout.getElementComputedStyle(\n formattingContext.getRootViewNode(nodeContext) as Element,\n );\n formattingContext.tableWidth = parseFloat(\n computedStyle[formattingContext.vertical ? \"height\" : \"width\"],\n );\n formattingContext.getRepetitiveElements().lastContentSourceNode =\n state.lastAfterNodeContext &&\n (state.lastAfterNodeContext.sourceNode as Element);\n state.break = true;\n } else {\n switch (display) {\n case \"table-header-group\":\n case \"table-footer-group\":\n if (this.inHeaderOrFooter) {\n this.inHeaderOrFooter = false;\n return Task.newResult(true);\n }\n break;\n case \"table-row\":\n if (!this.inHeaderOrFooter) {\n formattingContext.lastRowViewNode = nodeContext.viewNode as Element;\n this.inRow = false;\n }\n break;\n case \"table-cell\":\n if (!this.inHeaderOrFooter) {\n if (!this.inRow) {\n this.rowIndex++;\n this.columnIndex = 0;\n this.inRow = true;\n }\n const elem = nodeContext.viewNode as Element;\n formattingContext.addCell(\n this.rowIndex,\n new TableCell(this.rowIndex, this.columnIndex, elem),\n );\n this.columnIndex++;\n }\n break;\n }\n }\n return super.afterNonInlineElementNode(state);\n }\n\n /** @override */\n startNonElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n afterNonElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n startInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n /** @override */\n afterInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n this.registerCheckPoint(state);\n }\n\n registerCheckPoint(state: LayoutUtil.LayoutIteratorState) {\n const nodeContext = state.nodeContext;\n if (\n nodeContext &&\n nodeContext.viewNode &&\n !LayoutHelper.isSpecialNodeContext(nodeContext)\n ) {\n this.checkPoints.push(nodeContext.clone());\n }\n }\n\n postLayoutBlockContents(state: LayoutUtil.LayoutIteratorState) {\n if (this.checkPoints.length > 0) {\n this.column.postLayoutBlock(state.nodeContext, this.checkPoints);\n }\n this.checkPoints = [];\n }\n}\n\nexport class TableLayoutStrategy extends LayoutUtil.EdgeSkipper {\n private static ignoreList: { [key: string]: boolean } = {\n \"table-caption\": true,\n \"table-column-group\": true,\n \"table-column\": true,\n };\n inRow: boolean = false;\n currentRowIndex: number = -1;\n currentColumnIndex: number = 0;\n originalStopAtOverflow: boolean;\n inHeader: boolean;\n inFooter: boolean;\n\n constructor(\n public readonly formattingContext: TableFormattingContext,\n public readonly column: Layout.Column,\n ) {\n super(true);\n this.originalStopAtOverflow = column.stopAtOverflow;\n column.stopAtOverflow = false;\n }\n\n resetColumn() {\n this.column.stopAtOverflow = this.originalStopAtOverflow;\n }\n\n getColSpanningCellWidth(cell: TableCell): number {\n const colWidths = this.formattingContext.colWidths;\n Asserts.assert(colWidths);\n let width = 0;\n for (let i = 0; i < cell.colSpan; i++) {\n width += colWidths[cell.anchorSlot.columnIndex + i];\n }\n width += this.formattingContext.inlineBorderSpacing * (cell.colSpan - 1);\n return width;\n }\n\n layoutCell(\n cell: TableCell,\n cellNodeContext: Vtree.NodeContext,\n startChunkPosition: Vtree.ChunkPosition,\n ): Task.Result<boolean> {\n const rowIndex = cell.rowIndex;\n const columnIndex = cell.columnIndex;\n const colSpan = cell.colSpan;\n const cellViewNode = cellNodeContext.viewNode as Element;\n const verticalAlign = cellNodeContext.verticalAlign;\n if (colSpan > 1) {\n Base.setCSSProperty(cellViewNode, \"box-sizing\", \"border-box\");\n Base.setCSSProperty(\n cellViewNode,\n this.formattingContext.vertical ? \"height\" : \"width\",\n `${this.getColSpanningCellWidth(cell)}px`,\n );\n }\n const pseudoColumnContainer = cellViewNode.ownerDocument.createElement(\n \"div\",\n );\n cellViewNode.appendChild(pseudoColumnContainer);\n const cellFragment = new TableCellFragment(\n this.column,\n pseudoColumnContainer,\n cellNodeContext,\n );\n this.formattingContext.addCellFragment(rowIndex, columnIndex, cellFragment);\n if (\n startChunkPosition.primary.steps.length === 1 &&\n startChunkPosition.primary.after\n ) {\n // Contents of the cell have ended in the previous fragment\n cellFragment.empty = true;\n }\n return cellFragment.pseudoColumn\n .layout(startChunkPosition, true)\n .thenReturn(true);\n }\n\n hasBrokenCellAtSlot(slotIndex): boolean {\n const cellBreakPosition = this.formattingContext.cellBreakPositions[0];\n if (cellBreakPosition) {\n return cellBreakPosition.cell.anchorSlot.columnIndex === slotIndex;\n }\n return false;\n }\n\n private extractRowSpanningCellBreakPositions(): BrokenTableCellPosition[][] {\n const cellBreakPositions = this.formattingContext.cellBreakPositions;\n if (cellBreakPositions.length === 0) {\n return [];\n }\n const rowSpanningCellBreakPositions = [];\n let i = 0;\n do {\n const p = cellBreakPositions[i];\n const rowIndex = p.cell.rowIndex;\n if (rowIndex < this.currentRowIndex) {\n let arr = rowSpanningCellBreakPositions[rowIndex];\n if (!arr) {\n arr = rowSpanningCellBreakPositions[rowIndex] = [];\n }\n arr.push(p);\n cellBreakPositions.splice(i, 1);\n } else {\n i++;\n }\n } while (i < cellBreakPositions.length);\n return rowSpanningCellBreakPositions;\n }\n\n layoutRowSpanningCellsFromPreviousFragment(\n state: LayoutUtil.LayoutIteratorState,\n ): Task.Result<boolean> {\n const formattingContext = this.formattingContext;\n const rowSpanningCellBreakPositions = this.extractRowSpanningCellBreakPositions();\n const rowCount = rowSpanningCellBreakPositions.reduce((s) => s + 1, 0);\n if (rowCount === 0) {\n return Task.newResult(true);\n }\n const layoutContext = this.column.layoutContext;\n const currentRow = state.nodeContext;\n currentRow.viewNode.parentNode.removeChild(currentRow.viewNode);\n const frame = Task.newFrame<boolean>(\n \"layoutRowSpanningCellsFromPreviousFragment\",\n );\n let cont = Task.newResult(true);\n let spanningCellRowIndex = 0;\n const occupiedSlotIndices = [];\n rowSpanningCellBreakPositions.forEach((rowCellBreakPositions) => {\n cont = cont.thenAsync(() => {\n // Is it always correct to assume steps[1] to be the row?\n const rowNodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n rowCellBreakPositions[0].cellNodePosition.steps[1],\n currentRow.parent,\n );\n return layoutContext.setCurrent(rowNodeContext, false).thenAsync(() => {\n let cont1 = Task.newResult(true);\n let columnIndex = 0;\n\n function addDummyCellUntil(upperColumnIndex) {\n while (columnIndex < upperColumnIndex) {\n if (!occupiedSlotIndices.includes(columnIndex)) {\n const dummy = rowNodeContext.viewNode.ownerDocument.createElement(\n \"td\",\n );\n Base.setCSSProperty(dummy, \"padding\", \"0\");\n rowNodeContext.viewNode.appendChild(dummy);\n }\n columnIndex++;\n }\n }\n rowCellBreakPositions.forEach((cellBreakPosition) => {\n cont1 = cont1.thenAsync(() => {\n const cell = cellBreakPosition.cell;\n addDummyCellUntil(cell.anchorSlot.columnIndex);\n const cellNodePosition = cellBreakPosition.cellNodePosition;\n const cellNodeContext = VtreeImpl.makeNodeContextFromNodePositionStep(\n cellNodePosition.steps[0],\n rowNodeContext,\n );\n cellNodeContext.offsetInNode = cellNodePosition.offsetInNode;\n cellNodeContext.after = cellNodePosition.after;\n cellNodeContext.fragmentIndex =\n cellNodePosition.steps[0].fragmentIndex + 1;\n return layoutContext\n .setCurrent(cellNodeContext, false)\n .thenAsync(() => {\n const breakChunkPosition =\n cellBreakPosition.breakChunkPosition;\n for (let i = 0; i < cell.colSpan; i++) {\n occupiedSlotIndices.push(columnIndex + i);\n }\n columnIndex += cell.colSpan;\n return this.layoutCell(\n cell,\n cellNodeContext,\n breakChunkPosition,\n ).thenAsync(() => {\n (cellNodeContext.viewNode as HTMLTableCellElement).rowSpan =\n cell.rowIndex +\n cell.rowSpan -\n this.currentRowIndex +\n rowCount -\n spanningCellRowIndex;\n return Task.newResult(true);\n });\n });\n });\n });\n return cont1.thenAsync(() => {\n addDummyCellUntil(formattingContext.getColumnCount());\n spanningCellRowIndex++;\n return Task.newResult(true);\n });\n });\n });\n });\n cont.then(() => {\n layoutContext\n .setCurrent(currentRow, true, state.atUnforcedBreak)\n .then(() => {\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n startTableRow(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n if (this.inHeader || this.inFooter) {\n return Task.newResult(true);\n }\n const nodeContext = state.nodeContext;\n const formattingContext = this.formattingContext;\n if (this.currentRowIndex < 0) {\n Asserts.assert(nodeContext.sourceNode);\n this.currentRowIndex = formattingContext.findRowIndexBySourceNode(\n nodeContext.sourceNode,\n );\n } else {\n this.currentRowIndex++;\n }\n this.currentColumnIndex = 0;\n this.inRow = true;\n return this.layoutRowSpanningCellsFromPreviousFragment(state).thenAsync(\n () => {\n this.registerCellFragmentIndex();\n const overflown = this.column.checkOverflowAndSaveEdgeAndBreakPosition(\n state.lastAfterNodeContext,\n null,\n true,\n state.breakAtTheEdge,\n );\n if (\n overflown &&\n formattingContext.getRowSpanningCellsOverflowingTheRow(\n this.currentRowIndex - 1,\n ).length === 0\n ) {\n this.resetColumn();\n nodeContext.overflow = true;\n state.break = true;\n }\n return Task.newResult(true);\n },\n );\n }\n\n private registerCellFragmentIndex() {\n const cells = this.formattingContext.getRowByIndex(this.currentRowIndex)\n .cells;\n cells.forEach((cell) => {\n const cellBreakPosition = this.formattingContext.cellBreakPositions[\n cell.columnIndex\n ];\n if (\n cellBreakPosition &&\n cellBreakPosition.cell.anchorSlot.columnIndex ==\n cell.anchorSlot.columnIndex\n ) {\n const tdNodeStep = cellBreakPosition.cellNodePosition.steps[0];\n const offset = (this.column\n .layoutContext as Vgen.ViewFactory).xmldoc.getElementOffset(\n tdNodeStep.node as Element,\n );\n Layout.registerFragmentIndex(offset, tdNodeStep.fragmentIndex + 1, 1);\n }\n });\n }\n\n startTableCell(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n if (this.inHeader || this.inFooter) {\n return Task.newResult(true);\n }\n const nodeContext = state.nodeContext;\n if (!this.inRow) {\n if (this.currentRowIndex < 0) {\n this.currentRowIndex = 0;\n } else {\n this.currentRowIndex++;\n }\n this.currentColumnIndex = 0;\n this.inRow = true;\n }\n const cell = this.formattingContext.getRowByIndex(this.currentRowIndex)\n .cells[this.currentColumnIndex];\n const afterNodeContext = nodeContext.copy().modify();\n afterNodeContext.after = true;\n state.nodeContext = afterNodeContext;\n const frame = Task.newFrame<boolean>(\"startTableCell\");\n let cont: Task.Result<Vtree.ChunkPosition>;\n if (this.hasBrokenCellAtSlot(cell.anchorSlot.columnIndex)) {\n const cellBreakPosition = this.formattingContext.cellBreakPositions.shift();\n nodeContext.fragmentIndex =\n cellBreakPosition.cellNodePosition.steps[0].fragmentIndex + 1;\n cont = Task.newResult(cellBreakPosition.breakChunkPosition);\n } else {\n cont = this.column\n .nextInTree(nodeContext, state.atUnforcedBreak)\n .thenAsync((nextNodeContext) => {\n if (nextNodeContext.viewNode) {\n nodeContext.viewNode.removeChild(nextNodeContext.viewNode);\n }\n const startNodePosition = VtreeImpl.newNodePositionFromNodeContext(\n nextNodeContext,\n 0,\n );\n return Task.newResult(new VtreeImpl.ChunkPosition(startNodePosition));\n });\n }\n cont.then((startChunkPosition) => {\n Asserts.assert(nodeContext);\n this.layoutCell(cell, nodeContext, startChunkPosition).then(() => {\n this.afterNonInlineElementNode(state);\n this.currentColumnIndex++;\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n startNonInlineBox(\n state: LayoutUtil.LayoutIteratorState,\n ): Task.Result<boolean> {\n const r = skipNestedTable(\n state,\n getTableFormattingContext(this.formattingContext),\n this.column,\n );\n if (r) {\n return r;\n }\n const nodeContext = state.nodeContext;\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n const display = nodeContext.display;\n if (\n display === \"table-header-group\" &&\n repetitiveElements &&\n repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode)\n ) {\n this.inHeader = true;\n return Task.newResult(true);\n } else if (\n display === \"table-footer-group\" &&\n repetitiveElements &&\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode)\n ) {\n this.inFooter = true;\n return Task.newResult(true);\n } else if (display === \"table-row\") {\n return this.startTableRow(state);\n } else if (display === \"table-cell\") {\n return this.startTableCell(state);\n } else {\n return Task.newResult(true);\n }\n }\n\n endNonInlineBox(state: LayoutUtil.LayoutIteratorState): Task.Result<boolean> {\n const nodeContext = state.nodeContext;\n const display = nodeContext.display;\n if (display === \"table-row\") {\n this.inRow = false;\n if (!this.inHeader && !this.inFooter) {\n const beforeNodeContext = nodeContext.copy().modify();\n beforeNodeContext.after = false;\n const bp = new InsideTableRowBreakPosition(\n this.currentRowIndex,\n beforeNodeContext,\n this.formattingContext,\n );\n this.column.breakPositions.push(bp);\n }\n }\n return Task.newResult(true);\n }\n\n afterNonInlineElementNode(\n state: LayoutUtil.LayoutIteratorState,\n ): void | Task.Result<boolean> {\n const nodeContext = state.nodeContext;\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n const display = nodeContext.display;\n if (display === \"table-header-group\") {\n if (\n repetitiveElements &&\n !repetitiveElements.allowInsertRepeatitiveElements &&\n repetitiveElements.isHeaderSourceNode(nodeContext.sourceNode)\n ) {\n this.inHeader = false;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else {\n Base.setCSSProperty(\n nodeContext.viewNode as Element,\n \"display\",\n \"table-row-group\",\n );\n }\n } else if (display === \"table-footer-group\") {\n if (\n repetitiveElements &&\n !repetitiveElements.allowInsertRepeatitiveElements &&\n repetitiveElements.isFooterSourceNode(nodeContext.sourceNode)\n ) {\n this.inFooter = false;\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else {\n Base.setCSSProperty(\n nodeContext.viewNode as Element,\n \"display\",\n \"table-row-group\",\n );\n }\n }\n if (display && TableLayoutStrategy.ignoreList[display]) {\n nodeContext.viewNode.parentNode.removeChild(nodeContext.viewNode);\n } else if (\n nodeContext.sourceNode === this.formattingContext.tableSourceNode\n ) {\n nodeContext.overflow = this.column.checkOverflowAndSaveEdge(\n nodeContext,\n null,\n );\n this.resetColumn();\n state.break = true;\n } else {\n return super.afterNonInlineElementNode(state);\n }\n return Task.newResult(true);\n }\n}\n\ntype TableLayoutOption = {\n calculateBreakPositionsInside: boolean;\n};\nconst tableLayoutOptionCache: {\n root: Node;\n tableLayoutOption: TableLayoutOption;\n}[] = [];\n\nfunction getTableLayoutOption(\n tableRootSourceNode: Node,\n): TableLayoutOption | null {\n const i = tableLayoutOptionCache.findIndex(\n (c) => c.root === tableRootSourceNode,\n );\n const pair = tableLayoutOptionCache[i];\n return pair ? pair.tableLayoutOption : null;\n}\n\nfunction clearTableLayoutOptionCache(tableRootSourceNode: Node): void {\n const i = tableLayoutOptionCache.findIndex(\n (c) => c.root === tableRootSourceNode,\n );\n if (i >= 0) {\n tableLayoutOptionCache.splice(i, 1);\n }\n}\n\nexport class TableLayoutProcessor implements LayoutProcessor.LayoutProcessor {\n private layoutEntireTable(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const strategy = new EntireTableLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n return iterator.iterate(nodeContext);\n }\n\n private getColumnWidths(\n lastRow: Element,\n columnCount: number,\n vertical: boolean,\n clientLayout: Vtree.ClientLayout,\n ): number[] {\n const doc = lastRow.ownerDocument;\n const dummyRow = doc.createElement(\"tr\");\n const dummyCells = [];\n for (let i = 0; i < columnCount; i++) {\n const cell = doc.createElement(\"td\");\n dummyRow.appendChild(cell);\n dummyCells.push(cell);\n }\n lastRow.parentNode.insertBefore(dummyRow, lastRow.nextSibling);\n const colWidths = dummyCells.map((cell) => {\n const rect = clientLayout.getElementClientRect(cell);\n return vertical ? rect[\"height\"] : rect[\"width\"];\n });\n lastRow.parentNode.removeChild(dummyRow);\n return colWidths;\n }\n\n private getColGroupElements(tableElement: Element): Element[] {\n const colGroups = [];\n let child = tableElement.firstElementChild;\n while (child) {\n if (child.localName === \"colgroup\") {\n colGroups.push(child);\n }\n child = child.nextElementSibling;\n }\n return colGroups;\n }\n\n private normalizeAndGetColElements(colGroups: Element[]): Element[] {\n const cols = [];\n colGroups.forEach((colGroup) => {\n // Replace colgroup[span=n] with colgroup with n col elements\n let span = (colGroup as any).span;\n colGroup.removeAttribute(\"span\");\n let col = colGroup.firstElementChild;\n while (col) {\n if (col.localName === \"col\") {\n // Replace col[span=n] with n col elements\n let s = (col as any).span;\n col.removeAttribute(\"span\");\n span -= s;\n while (s-- > 1) {\n const cloned = col.cloneNode(true);\n colGroup.insertBefore(cloned, col);\n cols.push(cloned);\n }\n cols.push(col);\n }\n col = col.nextElementSibling;\n }\n while (span-- > 0) {\n col = colGroup.ownerDocument.createElement(\"col\");\n colGroup.appendChild(col);\n cols.push(col);\n }\n });\n return cols;\n }\n\n private addMissingColElements(\n cols: Element[],\n colGroups: Element[],\n columnCount: number,\n tableElement: Element,\n ) {\n if (cols.length < columnCount) {\n const colGroup = tableElement.ownerDocument.createElement(\"colgroup\");\n colGroups.push(colGroup);\n for (let i = cols.length; i < columnCount; i++) {\n const col = tableElement.ownerDocument.createElement(\"col\");\n colGroup.appendChild(col);\n cols.push(col);\n }\n }\n }\n\n /**\n * Measure width of columns and normalize colgroup and col elements so that\n * each column has a corresponding col element with the width specified.\n */\n normalizeColGroups(\n formattingContext: TableFormattingContext,\n tableElement: Element,\n column: Layout.Column,\n ) {\n const vertical = formattingContext.vertical;\n const lastRow = formattingContext.lastRowViewNode;\n if (!lastRow) {\n return;\n }\n Asserts.assert(lastRow);\n formattingContext.lastRowViewNode = null;\n const doc = lastRow.ownerDocument;\n const fragment = doc.createDocumentFragment();\n\n // Count columns\n const columnCount = formattingContext.getColumnCount();\n if (!(columnCount > 0)) {\n formattingContext.colGroups = fragment;\n return;\n }\n\n // Measure column widths\n const colWidths = (formattingContext.colWidths = this.getColumnWidths(\n lastRow,\n columnCount,\n vertical,\n column.clientLayout,\n ));\n\n // Normalize colgroup and col elements\n const colGroups = this.getColGroupElements(tableElement);\n const cols = this.normalizeAndGetColElements(colGroups);\n\n // Add missing col elements for remaining columns\n this.addMissingColElements(cols, colGroups, columnCount, tableElement);\n\n // Assign width to col elements\n cols.forEach((col, i) => {\n Base.setCSSProperty(\n col,\n vertical ? \"height\" : \"width\",\n `${colWidths[i]}px`,\n );\n });\n colGroups.forEach((colGroup) => {\n fragment.appendChild(colGroup.cloneNode(true));\n });\n formattingContext.colGroups = fragment;\n }\n\n doInitialLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n formattingContext.vertical = nodeContext.vertical;\n formattingContext.initializeRepetitiveElements(nodeContext.vertical);\n Asserts.assert(nodeContext.sourceNode);\n const tableLayoutOption = getTableLayoutOption(nodeContext.sourceNode);\n clearTableLayoutOptionCache(nodeContext.sourceNode);\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"TableLayoutProcessor.doInitialLayout\",\n );\n const initialNodeContext = nodeContext.copy();\n this.layoutEntireTable(nodeContext, column).then((nodeContextAfter) => {\n const tableElement = nodeContextAfter.viewNode as Element;\n const tableBBox = column.clientLayout.getElementClientRect(tableElement);\n let edge = column.vertical ? tableBBox.left : tableBBox.bottom;\n edge +=\n (column.vertical ? -1 : 1) *\n BreakPosition.calculateOffset(\n nodeContext,\n column.collectElementsOffset(),\n ).current;\n if (\n !column.isOverflown(edge) &&\n (!tableLayoutOption || !tableLayoutOption.calculateBreakPositionsInside)\n ) {\n column.breakPositions.push(\n new EntireTableBreakPosition(initialNodeContext),\n );\n frame.finish(nodeContextAfter);\n return;\n }\n this.normalizeColGroups(formattingContext, tableElement, column);\n formattingContext.updateCellSizes(column.clientLayout);\n frame.finish(null);\n });\n return frame.result();\n }\n\n addCaptions(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n firstChild: Node | null,\n ) {\n const captions = formattingContext.captions;\n captions.forEach((caption, i) => {\n if (caption) {\n rootViewNode.insertBefore(caption.viewNode, firstChild);\n if (caption.side === \"top\") {\n captions[i] = null;\n }\n }\n });\n }\n\n addColGroups(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n firstChild: Node | null,\n ) {\n if (\n formattingContext.colGroups &&\n this.getColGroupElements(rootViewNode).length === 0\n ) {\n rootViewNode.insertBefore(\n formattingContext.colGroups.cloneNode(true),\n firstChild,\n );\n }\n }\n\n removeColGroups(\n formattingContext: TableFormattingContext,\n rootViewNode: Element,\n ) {\n if (formattingContext.colGroups && rootViewNode) {\n const colGroups = this.getColGroupElements(rootViewNode);\n if (colGroups) {\n colGroups.forEach((colGroup) => {\n rootViewNode.removeChild(colGroup);\n });\n }\n }\n }\n\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(\n nodeContext,\n ) as Element;\n const firstChild = rootViewNode.firstChild;\n this.addCaptions(formattingContext, rootViewNode, firstChild);\n this.addColGroups(formattingContext, rootViewNode, firstChild);\n const strategy = new TableLayoutStrategy(formattingContext, column);\n const iterator = new LayoutUtil.LayoutIterator(\n strategy,\n column.layoutContext,\n );\n const frame = Task.newFrame<Vtree.NodeContext>(\n \"TableFormattingContext.doLayout\",\n );\n iterator.iterate(nodeContext).thenFinish(frame);\n return frame.result();\n }\n\n /**\n * @override\n */\n layout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n leadingEdge: boolean,\n ): Task.Result<Vtree.NodeContext> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n const rootViewNode = formattingContext.getRootViewNode(nodeContext);\n if (!rootViewNode) {\n return column.buildDeepElementView(nodeContext);\n } else {\n if (leadingEdge) {\n RepetitiveElementImpl.appendHeaderToAncestors(\n nodeContext.parent,\n column,\n );\n }\n return new LayoutRetryer(formattingContext, this).layout(\n nodeContext,\n column,\n );\n }\n }\n\n /**\n * @override\n */\n createEdgeBreakPosition(\n position: Vtree.NodeContext,\n breakOnEdge: string | null,\n overflows: boolean,\n columnBlockSize: number,\n ): LayoutType.BreakPosition {\n return new BetweenTableRowBreakPosition(\n position,\n breakOnEdge,\n overflows,\n columnBlockSize,\n );\n }\n\n /**\n * @override\n */\n startNonInlineElementNode(nodeContext: Vtree.NodeContext): boolean {\n return false;\n }\n\n /**\n * @override\n */\n afterNonInlineElementNode(\n nodeContext: Vtree.NodeContext,\n stopAtOverflow: boolean,\n ): boolean {\n return false;\n }\n\n /**\n * @override\n */\n finishBreak(\n column: Layout.Column,\n nodeContext: Vtree.NodeContext,\n forceRemoveSelf: boolean,\n endOfColumn: boolean,\n ): Task.Result<boolean> {\n const formattingContext = getTableFormattingContext(\n nodeContext.formattingContext,\n );\n if (nodeContext.display === \"table-row\") {\n Asserts.assert(nodeContext.sourceNode);\n const rowIndex = formattingContext.findRowIndexBySourceNode(\n nodeContext.sourceNode,\n );\n formattingContext.cellBreakPositions = [];\n let cells: TableCell[];\n if (!nodeContext.after) {\n cells = formattingContext.getCellsFallingOnRow(rowIndex);\n } else {\n cells = formattingContext.getRowSpanningCellsOverflowingTheRow(\n rowIndex,\n );\n }\n if (cells.length) {\n const frame = Task.newFrame<boolean>(\n \"TableLayoutProcessor.finishBreak\",\n );\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i === cells.length) {\n loopFrame.breakLoop();\n return;\n }\n const cell = cells[i++];\n const cellFragment = formattingContext.getCellFragmentOfCell(cell);\n const breakNodeContext = cellFragment.findAcceptableBreakPosition()\n .nodeContext;\n Asserts.assert(breakNodeContext);\n const cellNodeContext = cellFragment.cellNodeContext;\n const cellNodePosition = cellNodeContext.toNodePosition();\n const breakChunkPosition = new VtreeImpl.ChunkPosition(\n breakNodeContext.toNodePosition(),\n );\n formattingContext.cellBreakPositions.push({\n cellNodePosition,\n breakChunkPosition,\n cell,\n } as BrokenTableCellPosition);\n const cellViewNode = cellNodeContext.viewNode as HTMLTableCellElement;\n cellFragment.column.layoutContext.processFragmentedBlockEdge(\n cellFragment.cellNodeContext,\n );\n if (rowIndex < cell.rowIndex + cell.rowSpan - 1) {\n cellViewNode.rowSpan = rowIndex - cell.rowIndex + 1;\n }\n if (!cellFragment.empty) {\n cellFragment.pseudoColumn\n .finishBreak(breakNodeContext, false, true)\n .then(() => {\n Asserts.assert(cellFragment);\n adjustCellHeight(\n cellFragment,\n formattingContext,\n breakNodeContext,\n );\n loopFrame.continueLoop();\n });\n } else {\n loopFrame.continueLoop();\n }\n })\n .then(() => {\n column.clearOverflownViewNodes(nodeContext, false);\n column.layoutContext.processFragmentedBlockEdge(nodeContext);\n formattingContext.finishFragment();\n frame.finish(true);\n });\n return frame.result();\n }\n }\n formattingContext.finishFragment();\n return LayoutProcessor.blockLayoutProcessor.finishBreak(\n column,\n nodeContext,\n forceRemoveSelf,\n endOfColumn,\n );\n }\n\n /** @override */\n clearOverflownViewNodes(\n column: Layout.Column,\n parentNodeContext: Vtree.NodeContext,\n nodeContext: Vtree.NodeContext,\n removeSelf: boolean,\n ) {\n LayoutProcessor.BlockLayoutProcessor.prototype.clearOverflownViewNodes(\n column,\n parentNodeContext,\n nodeContext,\n removeSelf,\n );\n }\n}\n\nfunction adjustCellHeight(\n cellFragment: TableCellFragment,\n formattingContext: TableFormattingContext,\n breakNodeContext: Vtree.NodeContext,\n): void {\n const repetitiveElements = formattingContext.getRepetitiveElements();\n if (!repetitiveElements) {\n return;\n }\n const vertical = formattingContext.vertical;\n const column = cellFragment.column;\n const cellContentElement = cellFragment.pseudoColumn.getColumnElement();\n const cellElement = cellFragment.cellNodeContext.viewNode as Element;\n const cellElementRect = column.clientLayout.getElementClientRect(cellElement);\n const padding = column.getComputedPaddingBorder(cellElement);\n if (vertical) {\n const width =\n cellElementRect.right -\n column.footnoteEdge -\n repetitiveElements.calculateOffset(breakNodeContext) -\n padding.right;\n Base.setCSSProperty(cellContentElement, \"max-width\", `${width}px`);\n } else {\n const height =\n column.footnoteEdge -\n repetitiveElements.calculateOffset(breakNodeContext) -\n cellElementRect.top -\n padding.top;\n Base.setCSSProperty(cellContentElement, \"max-height\", `${height}px`);\n }\n Base.setCSSProperty(cellContentElement, \"overflow\", \"hidden\");\n}\n\nexport class LayoutRetryer extends LayoutRetryers.AbstractLayoutRetryer {\n constructor(\n private tableFormattingContext: TableFormattingContext,\n private readonly processor: TableLayoutProcessor,\n ) {\n super();\n }\n\n /**\n * @override\n */\n resolveLayoutMode(nodeContext: Vtree.NodeContext): LayoutType.LayoutMode {\n const repetitiveElements = this.tableFormattingContext.getRepetitiveElements();\n if (!repetitiveElements || !repetitiveElements.doneInitialLayout) {\n return new LayoutEntireTable(this.tableFormattingContext, this.processor);\n } else {\n if (\n nodeContext.sourceNode ===\n this.tableFormattingContext.tableSourceNode &&\n !nodeContext.after\n ) {\n if (repetitiveElements) {\n repetitiveElements.preventSkippingHeader();\n }\n }\n return new LayoutFragmentedTable(\n this.tableFormattingContext,\n this.processor,\n );\n }\n }\n\n /**\n * @override\n */\n clearNodes(initialPosition: Vtree.NodeContext) {\n super.clearNodes(initialPosition);\n const rootViewNode = this.tableFormattingContext.getRootViewNode(\n initialPosition,\n );\n this.processor.removeColGroups(this.tableFormattingContext, rootViewNode);\n }\n\n /**\n * @override\n */\n restoreState(nodeContext: Vtree.NodeContext, column: Layout.Column) {\n super.restoreState(nodeContext, column);\n this.tableFormattingContext.finishFragment();\n }\n}\n\nexport class LayoutEntireTable extends RepetitiveElementImpl.LayoutEntireBlock {\n constructor(\n formattingContext: TableFormattingContext,\n public readonly processor: TableLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n return this.processor.doInitialLayout(nodeContext, column);\n }\n}\n\nexport class EntireTableBreakPosition extends BreakPosition.EdgeBreakPosition {\n constructor(tableNodeContext: Vtree.NodeContext) {\n super(tableNodeContext, null, tableNodeContext.overflow, 0);\n }\n\n /**\n * @override\n */\n getMinBreakPenalty(): number {\n if (!this.isEdgeUpdated) {\n throw new Error(\"EdgeBreakPosition.prototype.updateEdge not called\");\n }\n return (\n (this.overflows ? 3 : 0) +\n (this.position.parent ? this.position.parent.breakPenalty : 0)\n );\n }\n\n /**\n * @override\n */\n breakPositionChosen(column: Layout.Column): void {\n column.fragmentLayoutConstraints.push(\n new EntireTableLayoutConstraint(this.position.sourceNode),\n );\n }\n}\n\nexport class EntireTableLayoutConstraint\n implements Layout.FragmentLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType = \"EntireTable\";\n\n constructor(public tableRootNode: Node) {}\n\n /**\n * @override\n */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n // If the nodeContext overflows, any EntireTableLayoutConstraint should not\n // be registered in the first place. See\n // TableLayoutProcessor.prototype.doInitialLayout.\n Asserts.assert(!nodeContext.overflow);\n return false;\n }\n\n /**\n * @override\n */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n return true;\n }\n\n /**\n * @override\n */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {\n Asserts.assert(positionAfter.sourceNode);\n tableLayoutOptionCache.push({\n root: positionAfter.sourceNode,\n tableLayoutOption: {\n calculateBreakPositionsInside: true,\n } as TableLayoutOption,\n });\n }\n\n /**\n * @override\n */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n return Task.newResult(true);\n }\n\n /**\n * @override\n */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n return (\n constraint instanceof EntireTableLayoutConstraint &&\n constraint.tableRootNode === this.tableRootNode\n );\n }\n\n /**\n * @override\n */\n getPriorityOfFinishBreak(): number {\n return 0;\n }\n}\n\nexport class LayoutFragmentedTable extends RepetitiveElementImpl.LayoutFragmentedBlock {\n constructor(\n formattingContext: TableFormattingContext,\n public readonly processor: TableLayoutProcessor,\n ) {\n super(formattingContext);\n }\n\n /**\n * @override\n */\n doLayout(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<Vtree.NodeContext> {\n const repetitiveElements = this.formattingContext.getRepetitiveElements();\n if (\n repetitiveElements &&\n !repetitiveElements.isAfterLastContent(nodeContext)\n ) {\n const constraint = new TableRowLayoutConstraint(nodeContext);\n if (\n !column.fragmentLayoutConstraints.some((c) => constraint.equalsTo(c))\n ) {\n column.fragmentLayoutConstraints.unshift(constraint);\n }\n }\n return this.processor.doLayout(nodeContext, column);\n }\n}\n\nexport class TableRowLayoutConstraint\n extends RepetitiveElementImpl.RepetitiveElementsOwnerLayoutConstraint\n implements Table.TableRowLayoutConstraint {\n flagmentLayoutConstraintType: FragmentLayoutConstraintType = \"TableRow\";\n cellFragmentLayoutConstraints: {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[] = [];\n\n constructor(nodeContext: Vtree.NodeContext) {\n super(nodeContext);\n }\n\n /** @override */\n allowLayout(\n nodeContext: Vtree.NodeContext,\n overflownNodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): boolean {\n const repetitiveElements = this.getRepetitiveElements();\n if (!repetitiveElements) {\n return true;\n }\n if (column.pseudoParent) {\n return true;\n }\n if (LayoutHelper.isOrphan(this.nodeContext.viewNode)) {\n return true;\n }\n if (!repetitiveElements.isEnableToUpdateState()) {\n return true;\n }\n if (\n (overflownNodeContext && !nodeContext) ||\n (nodeContext && nodeContext.overflow)\n ) {\n return false;\n } else {\n return true;\n }\n }\n\n /** @override */\n nextCandidate(nodeContext: Vtree.NodeContext): boolean {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const cellFragmentConstraints = this.collectCellFragmentLayoutConstraints(\n nodeContext,\n formattingContext,\n );\n if (\n cellFragmentConstraints.some((entry) =>\n entry.constraints.some((constraint) =>\n constraint.nextCandidate(nodeContext),\n ),\n )\n ) {\n return true;\n }\n return super.nextCandidate(nodeContext);\n }\n\n /** @override */\n postLayout(\n allowed: boolean,\n positionAfter: Vtree.NodeContext,\n initialPosition: Vtree.NodeContext,\n column: Layout.Column,\n ) {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n this.cellFragmentLayoutConstraints = this.collectCellFragmentLayoutConstraints(\n positionAfter,\n formattingContext,\n );\n this.cellFragmentLayoutConstraints.forEach((entry) => {\n entry.constraints.forEach((constraint) => {\n constraint.postLayout(\n allowed,\n entry.breakPosition,\n initialPosition,\n column,\n );\n });\n });\n if (!allowed) {\n const rootViewNode = formattingContext.getRootViewNode(this.nodeContext);\n new TableLayoutProcessor().removeColGroups(\n formattingContext,\n rootViewNode as Element,\n );\n this.removeDummyRowNodes(initialPosition);\n }\n super.postLayout(allowed, positionAfter, initialPosition, column);\n }\n\n /** @override */\n finishBreak(\n nodeContext: Vtree.NodeContext,\n column: Layout.Column,\n ): Task.Result<boolean> {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const frame: Task.Frame<boolean> = Task.newFrame(\"finishBreak\");\n const constraints = this.cellFragmentLayoutConstraints.reduce(\n (array, entry) =>\n array.concat(\n entry.constraints.map((constraint) => ({\n constraint,\n breakPosition: entry.breakPosition,\n })),\n ),\n [],\n );\n let i = 0;\n frame\n .loop(() => {\n if (i < constraints.length) {\n const entry = constraints[i++];\n return entry.constraint\n .finishBreak(entry.breakPosition, column)\n .thenReturn(true);\n } else {\n return Task.newResult(false);\n }\n })\n .then(() => {\n frame.finish(true);\n });\n return frame\n .result()\n .thenAsync(() => super.finishBreak(nodeContext, column));\n }\n\n removeDummyRowNodes(nodeContext: Vtree.NodeContext) {\n if (\n !nodeContext ||\n nodeContext.display !== \"table-row\" ||\n !nodeContext.viewNode\n ) {\n return;\n }\n while ((nodeContext.viewNode as Element).previousElementSibling) {\n const dummyNode = (nodeContext.viewNode as Element)\n .previousElementSibling;\n if (dummyNode.parentNode) {\n dummyNode.parentNode.removeChild(dummyNode);\n }\n }\n }\n\n private collectCellFragmentLayoutConstraints(\n nodeContext: Vtree.NodeContext,\n formattingContext: TableFormattingContext,\n ): {\n constraints: Layout.FragmentLayoutConstraint[];\n breakPosition: Vtree.NodeContext;\n }[] {\n return this.getCellFragemnts(nodeContext, formattingContext).map(\n (entry) => ({\n constraints: entry.fragment.pseudoColumn.getColumn()\n .fragmentLayoutConstraints,\n breakPosition: entry.breakPosition,\n }),\n );\n }\n\n private getCellFragemnts(\n nodeContext: Vtree.NodeContext,\n formattingContext: TableFormattingContext,\n ): { fragment: TableCellFragment; breakPosition: Vtree.NodeContext }[] {\n let rowIndex = Number.MAX_VALUE;\n if (nodeContext && nodeContext.display === \"table-row\") {\n Asserts.assert(nodeContext.sourceNode);\n rowIndex =\n formattingContext.findRowIndexBySourceNode(nodeContext.sourceNode) + 1;\n }\n rowIndex = Math.min(formattingContext.cellFragments.length, rowIndex);\n const cellFragments = [];\n for (let i = 0; i < rowIndex; i++) {\n if (!formattingContext.cellFragments[i]) {\n continue;\n }\n formattingContext.cellFragments[i].forEach((cellFragment) => {\n if (!cellFragment) {\n return;\n }\n cellFragments.push({\n fragment: cellFragment,\n breakPosition: cellFragment.findAcceptableBreakPosition().nodeContext,\n });\n });\n }\n return cellFragments;\n }\n\n getElementsOffsetsForTableCell(\n column: Layout.Column,\n ): RepetitiveElement.ElementsOffset[] {\n const formattingContext = getTableFormattingContext(\n this.nodeContext.formattingContext,\n );\n const position = formattingContext.findCellFromColumn(column);\n if (position) {\n return formattingContext.collectElementsOffsetOfUpperCells(position);\n } else {\n return formattingContext.collectElementsOffsetOfHighestColumn();\n }\n }\n\n /** @override */\n equalsTo(constraint: Layout.FragmentLayoutConstraint): boolean {\n if (!(constraint instanceof TableRowLayoutConstraint)) {\n return false;\n }\n return (\n getTableFormattingContext(this.nodeContext.formattingContext) ===\n getTableFormattingContext(constraint.nodeContext.formattingContext)\n );\n }\n}\n\nconst tableLayoutProcessor = new TableLayoutProcessor();\n\nfunction resolveFormattingContextHook(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n display: Css.Ident,\n position: Css.Ident,\n floatSide: Css.Ident,\n isRoot: boolean,\n): TableFormattingContext | null {\n if (!firstTime) {\n return null;\n }\n if (display === Css.ident.table) {\n const parent = nodeContext.parent;\n return new TableFormattingContext(\n parent ? parent.formattingContext : null,\n nodeContext.sourceNode as Element,\n );\n }\n return null;\n}\n\nfunction resolveLayoutProcessor(\n formattingContext,\n): TableLayoutProcessor | null {\n if (formattingContext instanceof TableFormattingContext) {\n return tableLayoutProcessor;\n }\n return null;\n}\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n resolveFormattingContextHook,\n);\n\nPlugin.registerHook(\n Plugin.HOOKS.RESOLVE_LAYOUT_PROCESSOR,\n resolveLayoutProcessor,\n);\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview MathUtil - Math utilities\n */\nexport function mean(array: number[]): number {\n return array.reduce((prev, curr) => prev + curr, 0) / array.length;\n}\n\nexport function variance(array: number[]): number {\n const meanValue = mean(array);\n return mean(\n array.map((x) => {\n const d = x - meanValue;\n return d * d;\n }),\n );\n}\n","/**\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Columns - Control column layout.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Css from \"./css\";\nimport * as MathUtil from \"./math-util\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Task from \"./task\";\nimport * as Vtree from \"./vtree\";\nimport { Layout } from \"./types\";\n\nexport type ColumnLayoutResult = {\n columns: Layout.Column[];\n position: Vtree.LayoutPosition;\n columnPageFloatLayoutContexts?: PageFloats.PageFloatLayoutContext[];\n};\n\nexport type ColumnGenerator = () => Task.Result<ColumnLayoutResult | null>;\n\nexport class ColumnBalancingTrialResult {\n constructor(\n public readonly layoutResult: ColumnLayoutResult,\n public readonly penalty: number,\n ) {}\n}\n\nfunction getBlockSize(container: Vtree.Container): number {\n if (container.vertical) {\n return container.width;\n } else {\n return container.height;\n }\n}\n\nfunction setBlockSize(container: Vtree.Container, size: number) {\n if (container.vertical) {\n container.width = size;\n } else {\n container.height = size;\n }\n}\n\nexport abstract class ColumnBalancer {\n originalContainerBlockSize: number;\n\n constructor(\n public readonly layoutContainer: Vtree.Container,\n public readonly columnGenerator: ColumnGenerator,\n public readonly regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ) {\n this.originalContainerBlockSize = getBlockSize(layoutContainer);\n }\n\n balanceColumns(\n layoutResult: ColumnLayoutResult,\n ): Task.Result<ColumnLayoutResult> {\n const self = this;\n const frame: Task.Frame<ColumnLayoutResult> = Task.newFrame(\n \"ColumnBalancer#balanceColumns\",\n );\n self.preBalance(layoutResult);\n self.savePageFloatLayoutContexts(layoutResult);\n self.layoutContainer.clear();\n const candidates = [self.createTrialResult(layoutResult)];\n frame\n .loopWithFrame((loopFrame) => {\n if (!self.hasNextCandidate(candidates)) {\n loopFrame.breakLoop();\n return;\n }\n self.updateCondition(candidates);\n self.columnGenerator().then((layoutResult) => {\n self.savePageFloatLayoutContexts(layoutResult);\n self.layoutContainer.clear();\n if (!layoutResult) {\n loopFrame.breakLoop();\n return;\n }\n candidates.push(self.createTrialResult(layoutResult));\n loopFrame.continueLoop();\n });\n })\n .then(() => {\n const result = candidates.reduce(\n (prev, curr) => (curr.penalty < prev.penalty ? curr : prev),\n candidates[0],\n );\n self.restoreContents(result.layoutResult);\n self.postBalance();\n frame.finish(result.layoutResult);\n });\n return frame.result();\n }\n\n private createTrialResult(\n layoutResult: ColumnLayoutResult,\n ): ColumnBalancingTrialResult {\n const penalty = this.calculatePenalty(layoutResult);\n return new ColumnBalancingTrialResult(layoutResult, penalty);\n }\n\n protected preBalance(layoutResult: ColumnLayoutResult) {}\n\n protected abstract calculatePenalty(layoutResult: ColumnLayoutResult): number;\n\n protected abstract hasNextCandidate(\n candidates: ColumnBalancingTrialResult[],\n ): boolean;\n\n protected abstract updateCondition(\n candidates: ColumnBalancingTrialResult[],\n ): void;\n\n protected postBalance() {\n setBlockSize(this.layoutContainer, this.originalContainerBlockSize);\n }\n\n savePageFloatLayoutContexts(layoutResult: ColumnLayoutResult | null) {\n const children = this.regionPageFloatLayoutContext.detachChildren();\n if (layoutResult) {\n layoutResult.columnPageFloatLayoutContexts = children;\n }\n }\n\n private restoreContents(newLayoutResult: ColumnLayoutResult) {\n const parent = this.layoutContainer.element;\n newLayoutResult.columns.forEach((c) => {\n parent.appendChild(c.element);\n });\n Asserts.assert(newLayoutResult.columnPageFloatLayoutContexts);\n this.regionPageFloatLayoutContext.attachChildren(\n newLayoutResult.columnPageFloatLayoutContexts,\n );\n }\n}\nconst COLUMN_LENGTH_STEP = 1;\n\nexport function canReduceContainerSize(\n candidates: ColumnBalancingTrialResult[],\n): boolean {\n const lastCandidate = candidates[candidates.length - 1];\n if (lastCandidate.penalty === 0) {\n return false;\n }\n const secondLastCandidate = candidates[candidates.length - 2];\n if (\n secondLastCandidate &&\n lastCandidate.penalty >= secondLastCandidate.penalty\n ) {\n return false;\n }\n const columns = lastCandidate.layoutResult.columns;\n const maxColumnBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n const maxPageFloatBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.getMaxBlockSizeOfPageFloats()),\n );\n return maxColumnBlockSize > maxPageFloatBlockSize + COLUMN_LENGTH_STEP;\n}\n\nexport function reduceContainerSize(\n candidates: ColumnBalancingTrialResult[],\n container: Vtree.Container,\n): void {\n const columns = candidates[candidates.length - 1].layoutResult.columns;\n const maxColumnBlockSize = Math.max.apply(\n null,\n columns.map((c) => {\n if (!isNaN(c.blockDistanceToBlockEndFloats)) {\n return (\n c.computedBlockSize -\n c.blockDistanceToBlockEndFloats +\n COLUMN_LENGTH_STEP\n );\n } else {\n return c.computedBlockSize;\n }\n }),\n );\n const newEdge = maxColumnBlockSize - COLUMN_LENGTH_STEP;\n if (newEdge < getBlockSize(container)) {\n setBlockSize(container, newEdge);\n } else {\n setBlockSize(container, getBlockSize(container) - 1);\n }\n}\n\nexport class BalanceLastColumnBalancer extends ColumnBalancer {\n originalPosition: Vtree.LayoutPosition | null = null;\n foundUpperBound: boolean = false;\n\n constructor(\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n public readonly columnCount: number,\n ) {\n super(layoutContainer, columnGenerator, regionPageFloatLayoutContext);\n }\n\n /**\n * @override\n */\n preBalance(layoutResult: ColumnLayoutResult) {\n const columns = layoutResult.columns;\n const totalBlockSize = columns.reduce(\n (prev, c) => prev + c.computedBlockSize,\n 0,\n );\n setBlockSize(this.layoutContainer, totalBlockSize / this.columnCount);\n this.originalPosition = layoutResult.position;\n }\n\n private checkPosition(position: Vtree.LayoutPosition | null): boolean {\n if (this.originalPosition) {\n return this.originalPosition.isSamePosition(position);\n } else {\n return position === null;\n }\n }\n\n /**\n * @override\n */\n calculatePenalty(layoutResult: ColumnLayoutResult): number {\n if (!this.checkPosition(layoutResult.position)) {\n return Infinity;\n }\n const columns = layoutResult.columns;\n if (isLastColumnLongerThanAnyOtherColumn(columns)) {\n return Infinity;\n }\n return Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n }\n\n /**\n * @override\n */\n hasNextCandidate(candidates: ColumnBalancingTrialResult[]): boolean {\n if (candidates.length === 1) {\n return true;\n } else if (this.foundUpperBound) {\n return canReduceContainerSize(candidates);\n } else {\n const lastCandidate = candidates[candidates.length - 1];\n if (this.checkPosition(lastCandidate.layoutResult.position)) {\n if (\n !isLastColumnLongerThanAnyOtherColumn(\n lastCandidate.layoutResult.columns,\n )\n ) {\n this.foundUpperBound = true;\n return true;\n }\n }\n return (\n getBlockSize(this.layoutContainer) < this.originalContainerBlockSize\n );\n }\n }\n\n /**\n * @override\n */\n updateCondition(candidates: ColumnBalancingTrialResult[]): void {\n if (this.foundUpperBound) {\n reduceContainerSize(candidates, this.layoutContainer);\n } else {\n const newEdge = Math.min(\n this.originalContainerBlockSize,\n getBlockSize(this.layoutContainer) +\n this.originalContainerBlockSize * 0.1,\n );\n setBlockSize(this.layoutContainer, newEdge);\n }\n }\n}\n\nfunction isLastColumnLongerThanAnyOtherColumn(\n columns: Layout.Column[],\n): boolean {\n if (columns.length <= 1) {\n return false;\n }\n const lastColumnBlockSize = columns[columns.length - 1].computedBlockSize;\n const otherColumns = columns.slice(0, columns.length - 1);\n return otherColumns.every((c) => lastColumnBlockSize > c.computedBlockSize);\n}\n\nexport class BalanceNonLastColumnBalancer extends ColumnBalancer {\n constructor(\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n ) {\n super(layoutContainer, columnGenerator, regionPageFloatLayoutContext);\n }\n\n /**\n * @override\n */\n calculatePenalty(layoutResult: ColumnLayoutResult): number {\n if (layoutResult.columns.every((c) => c.computedBlockSize === 0)) {\n return Infinity;\n }\n const computedBlockSizes = layoutResult.columns\n .filter((c) => !c.pageBreakType)\n .map((c) => c.computedBlockSize);\n return MathUtil.variance(computedBlockSizes);\n }\n\n /**\n * @override\n */\n hasNextCandidate(candidates: ColumnBalancingTrialResult[]): boolean {\n return canReduceContainerSize(candidates);\n }\n\n /**\n * @override\n */\n updateCondition(candidates: ColumnBalancingTrialResult[]): void {\n reduceContainerSize(candidates, this.layoutContainer);\n }\n}\n\nexport function createColumnBalancer(\n columnCount: number,\n columnFill: Css.Ident,\n columnGenerator: ColumnGenerator,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n columns: Layout.Column[],\n flowPosition: Vtree.FlowPosition,\n): ColumnBalancer | null {\n if (columnFill === Css.ident.auto) {\n return null;\n } else {\n // TODO: how to handle a case where no more in-flow contents but some\n // page floats\n const noMoreContent = flowPosition.positions.length === 0;\n const lastColumn = columns[columns.length - 1];\n const isLastColumnForceBroken = !!(lastColumn && lastColumn.pageBreakType);\n if (noMoreContent || isLastColumnForceBroken) {\n return new BalanceLastColumnBalancer(\n columnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer,\n columnCount,\n );\n } else if (columnFill === Css.ident.balance_all) {\n return new BalanceNonLastColumnBalancer(\n columnGenerator,\n regionPageFloatLayoutContext,\n layoutContainer,\n );\n } else {\n Asserts.assert(columnFill === Css.ident.balance);\n return null;\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssStyler - Apply CSS cascade to a document incrementally and\n * cache the result.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Break from \"./break\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Display from \"./display\";\nimport * as Exprs from \"./exprs\";\nimport * as Vtree from \"./vtree\";\nimport { CssStyler, XmlDoc } from \"./types\";\n\nexport class SlipRange {\n endStuckFixed: number;\n endFixed: number;\n endSlipped: number;\n\n constructor(endStuckFixed, endFixed, endSlipped) {\n this.endStuckFixed = endStuckFixed;\n this.endFixed = endFixed;\n this.endSlipped = endSlipped;\n }\n}\n\n/**\n * Maps all ints in a range (\"fixed\") to ints with slippage (\"slipped\")\n */\nexport class SlipMap {\n map = [] as SlipRange[];\n\n getMaxFixed(): number {\n if (this.map.length == 0) {\n return 0;\n }\n const range = this.map[this.map.length - 1];\n return range.endFixed;\n }\n\n getMaxSlipped(): number {\n if (this.map.length == 0) {\n return 0;\n }\n const range = this.map[this.map.length - 1];\n return range.endSlipped;\n }\n\n addStuckRange(endFixed: number): void {\n if (this.map.length == 0) {\n this.map.push(new SlipRange(endFixed, endFixed, endFixed));\n } else {\n const range = this.map[this.map.length - 1];\n const endSlipped = range.endSlipped + endFixed - range.endFixed;\n if (range.endFixed == range.endStuckFixed) {\n range.endFixed = endFixed;\n range.endStuckFixed = endFixed;\n range.endSlipped = endSlipped;\n } else {\n this.map.push(new SlipRange(endFixed, endFixed, endSlipped));\n }\n }\n }\n\n addSlippedRange(endFixed: number): void {\n if (this.map.length == 0) {\n this.map.push(new SlipRange(endFixed, 0, 0));\n } else {\n this.map[this.map.length - 1].endFixed = endFixed;\n }\n }\n\n slippedByFixed(fixed: number): number {\n const self = this;\n const index = Base.binarySearch(\n this.map.length,\n (index) => fixed <= self.map[index].endFixed,\n );\n const range = this.map[index];\n return range.endSlipped - Math.max(0, range.endStuckFixed - fixed);\n }\n\n /**\n * Smallest fixed for a given slipped.\n */\n fixedBySlipped(slipped: number): number {\n const self = this;\n const index = Base.binarySearch(\n this.map.length,\n (index) => slipped <= self.map[index].endSlipped,\n );\n const range = this.map[index];\n return range.endStuckFixed - (range.endSlipped - slipped);\n }\n}\n\nexport interface FlowListener {\n /**\n * @return void\n */\n encounteredFlowChunk(flowChunk: Vtree.FlowChunk, flow: Vtree.Flow): any;\n}\n\nexport interface AbstractStyler extends CssStyler.AbstractStyler {}\n\n/**\n * Represent a box generated by a (pseudo)element. When constructed, a box\n * corresponding to `::before` pseudoelement is also constructed and stored in\n * `beforeBox` property, whereas one corresponding `::after` pseudoelement is\n * not constructed and `afterBox` property is `null`. `afterBox` is constructed\n * by `buildAfterPseudoElementBox` method.\n * @param style Cascaded style values for the box.\n * @param offset The start offset of the box. It coincides with the start offset\n * of the element if the box is generated by the element or the `::before`\n * pseudoelement. When the box corresponds to the `::after` pseudoelement,\n * the offset is just after the content before the `::after` pseudoelement.\n * @param isRoot True if the box is generated by the root element (not\n * pseudoelement).\n * @param flowChunk FlowChunk to which the box belongs to.\n * @param atBlockStart True if the box is right after the block start edge.\n * @param atFlowStart True if the box is right after the flow start.\n * @param isParentBoxDisplayed True if the parent box has a displayed box.\n */\nexport class Box {\n flowName: string;\n isBlockValue: boolean | null = null;\n hasBoxValue: boolean | null = null;\n styleValues = {} as { [key: string]: Css.Val };\n beforeBox: Box = null;\n afterBox: Box = null;\n breakBefore: string | null = null;\n\n constructor(\n public readonly context: Exprs.Context,\n public readonly style: CssCascade.ElementStyle,\n public readonly offset: number,\n public readonly isRoot: boolean,\n public readonly flowChunk: Vtree.FlowChunk,\n public readonly atBlockStart: boolean,\n public readonly atFlowStart: boolean,\n public readonly isParentBoxDisplayed: boolean,\n ) {\n this.flowName = flowChunk.flowName;\n if (this.hasBox()) {\n const pseudoMap = style[\"_pseudos\"];\n if (pseudoMap) {\n if (pseudoMap[\"before\"]) {\n const beforeBox = new Box(\n context,\n pseudoMap[\"before\"],\n offset,\n false,\n flowChunk,\n this.isBlock(),\n atFlowStart,\n true,\n );\n const beforeContent = beforeBox.styleValue(\"content\");\n if (Vtree.nonTrivialContent(beforeContent)) {\n this.beforeBox = beforeBox;\n this.breakBefore = beforeBox.breakBefore;\n }\n }\n }\n }\n this.breakBefore = Break.resolveEffectiveBreakValue(\n this.getBreakValue(\"before\"),\n this.breakBefore,\n );\n if (this.atFlowStart && Break.isForcedBreakValue(this.breakBefore)) {\n flowChunk.breakBefore = Break.resolveEffectiveBreakValue(\n flowChunk.breakBefore,\n this.breakBefore,\n );\n }\n }\n\n /**\n * Build a box corresponding to `::after` pseudoelement and stores it in\n * `afterBox` property.\n * @param offset The start offset of the `::after` pseudoelement box, which is\n * just after the content before the `::after` pseudoelement.\n * @param atBlockStart True if the box is right after the block start edge.\n * @param atFlowStart True if the box is right after the flow start.\n */\n buildAfterPseudoElementBox(\n offset: number,\n atBlockStart: boolean,\n atFlowStart: boolean,\n ) {\n if (this.hasBox()) {\n const pseudoMap = this.style[\"_pseudos\"];\n if (pseudoMap) {\n if (pseudoMap[\"after\"]) {\n const afterBox = new Box(\n this.context,\n pseudoMap[\"after\"],\n offset,\n false,\n this.flowChunk,\n atBlockStart,\n atFlowStart,\n true,\n );\n const afterContent = afterBox.styleValue(\"content\");\n if (Vtree.nonTrivialContent(afterContent)) {\n this.afterBox = afterBox;\n }\n }\n }\n }\n }\n\n styleValue(name: string, defaultValue?: Css.Val): Css.Val | null {\n if (!(name in this.styleValues)) {\n const cv = this.style[name];\n this.styleValues[name] = cv\n ? cv.evaluate(this.context, name)\n : defaultValue || null;\n }\n return this.styleValues[name];\n }\n\n displayValue(): Css.Val {\n return this.styleValue(\"display\", Css.ident.inline);\n }\n\n isBlock(): boolean {\n if (this.isBlockValue === null) {\n const display = this.displayValue() as Css.Ident;\n const position = this.styleValue(\"position\") as Css.Ident;\n const float = this.styleValue(\"float\") as Css.Ident;\n this.isBlockValue = Display.isBlock(\n display,\n position,\n float,\n this.isRoot,\n );\n }\n return this.isBlockValue;\n }\n\n hasBox(): boolean {\n if (this.hasBoxValue === null) {\n this.hasBoxValue =\n this.isParentBoxDisplayed && this.displayValue() !== Css.ident.none;\n }\n return this.hasBoxValue;\n }\n\n getBreakValue(edge: string): string | null {\n let breakValue: string | null = null;\n if (this.isBlock()) {\n const val = this.styleValue(`break-${edge}`);\n if (val) {\n breakValue = val.toString();\n }\n }\n return breakValue;\n }\n}\n\n/**\n * Manages boxes generated by elements as a stack.\n */\nexport class BoxStack {\n stack = [] as Box[];\n atBlockStart: boolean = true; // indicates if the next pushed box will be at the block start\n atFlowStart: boolean = true; // indicates if the next pushed box will be at the flow start\n atStartStack = [] as { atBlockStart: boolean; atFlowStart: boolean }[]; // pushed when a new flow starts\n\n constructor(public readonly context: Exprs.Context) {}\n\n /**\n * Returns if the stack is empty.\n */\n empty(): boolean {\n return this.stack.length === 0;\n }\n\n /**\n * Returns the last box in the stack.\n */\n lastBox(): Box | undefined {\n return this.stack[this.stack.length - 1];\n }\n\n /**\n * Returns the flow name of the last box in the stack.\n */\n lastFlowName(): string | null {\n const lastBox = this.lastBox();\n return lastBox ? lastBox.flowChunk.flowName : null;\n }\n\n /**\n * Returns if the last box in the stack is displayed.\n */\n isCurrentBoxDisplayed(): boolean {\n return this.stack.every((box) => box.displayValue() !== Css.ident.none);\n }\n\n /**\n * Create a new box and push it to the stack.\n * @param style Cascaded style values for the box.\n * @param offset The start offset of the box.\n * @param isRoot True if the box is generated by the root element\n * @param newFlowChunk Specify if the element is a flow element (i.e. the\n * element is specified a new `flow-into` value)\n */\n push(\n style: CssCascade.ElementStyle,\n offset: number,\n isRoot: boolean,\n newFlowChunk?: Vtree.FlowChunk,\n ): Box {\n const lastBox = this.lastBox();\n if (newFlowChunk && lastBox && newFlowChunk.flowName !== lastBox.flowName) {\n this.atStartStack.push({\n atBlockStart: this.atBlockStart,\n atFlowStart: this.atFlowStart,\n });\n }\n const flowChunk = newFlowChunk || lastBox.flowChunk;\n const isAtFlowStart = this.atFlowStart || !!newFlowChunk;\n const isParentBoxDisplayed = this.isCurrentBoxDisplayed();\n const box = new Box(\n this.context,\n style,\n offset,\n isRoot,\n flowChunk,\n isAtFlowStart || this.atBlockStart,\n isAtFlowStart,\n isParentBoxDisplayed,\n );\n this.stack.push(box);\n this.atBlockStart = box.hasBox()\n ? !box.beforeBox && box.isBlock()\n : this.atBlockStart;\n this.atFlowStart = box.hasBox()\n ? !box.beforeBox && isAtFlowStart\n : this.atFlowStart;\n return box;\n }\n\n encounteredTextNode(node: Node) {\n const box = this.lastBox();\n if ((this.atBlockStart || this.atFlowStart) && box.hasBox()) {\n const whitespaceValue = box\n .styleValue(\"white-space\", Css.ident.normal)\n .toString();\n const whitespace = Vtree.whitespaceFromPropertyValue(whitespaceValue);\n Asserts.assert(whitespace !== null);\n if (!Vtree.canIgnore(node, whitespace)) {\n this.atBlockStart = false;\n this.atFlowStart = false;\n }\n }\n }\n\n /**\n * Pop the last box.\n */\n pop(offset: number): Box {\n const box = this.stack.pop();\n box.buildAfterPseudoElementBox(offset, this.atBlockStart, this.atFlowStart);\n if (this.atFlowStart && box.afterBox) {\n const breakBefore = box.afterBox.getBreakValue(\"before\");\n box.flowChunk.breakBefore = Break.resolveEffectiveBreakValue(\n box.flowChunk.breakBefore,\n breakBefore,\n );\n }\n const parent = this.lastBox();\n if (parent) {\n if (parent.flowName === box.flowName) {\n if (box.hasBox()) {\n this.atBlockStart = this.atFlowStart = false;\n }\n } else {\n const atStart = this.atStartStack.pop();\n this.atBlockStart = atStart.atBlockStart;\n this.atFlowStart = atStart.atFlowStart;\n }\n }\n return box;\n }\n\n /**\n * Find the start offset of the nearest block start edge to which the\n * `break-before` value of the box should be propagated. This method can be\n * called when after pushing the box into the stack or after popping the box\n * out of the stack.\n */\n nearestBlockStartOffset(box: Box): number {\n if (!box.atBlockStart) {\n return box.offset;\n }\n let i = this.stack.length - 1;\n let parent = this.stack[i];\n\n // When called just after the box is popped out, the last box in the stack\n // is different from the box and it is the parent of the box. When called\n // after the box is pushed, the last box in the stack is identical to the\n // box and the parent of the box is a box right before the specified box.\n if (parent === box) {\n i--;\n parent = this.stack[i];\n }\n while (i >= 0) {\n if (parent.flowName !== box.flowName) {\n return box.offset;\n }\n if (!parent.atBlockStart) {\n return parent.offset;\n }\n if (parent.isRoot) {\n return parent.offset;\n }\n box = parent;\n parent = this.stack[--i];\n }\n throw new Error(\"No block start offset found!\");\n }\n}\n\nexport class Styler implements AbstractStyler {\n root: Element;\n cascadeHolder: CssCascade.Cascade;\n last: Node;\n rootStyle = {} as CssCascade.ElementStyle;\n styleMap: { [key: string]: CssCascade.ElementStyle } = {};\n flows = {} as { [key: string]: Vtree.Flow };\n flowChunks = [] as Vtree.FlowChunk[];\n flowListener: FlowListener = null;\n flowToReach: string | null = null;\n idToReach: string | null = null;\n cascade: CssCascade.CascadeInstance;\n offsetMap: SlipMap;\n primary: boolean = true;\n primaryStack = [] as boolean[];\n rootBackgroundAssigned: boolean = false;\n rootLayoutAssigned: boolean = false;\n lastOffset: number;\n breakBeforeValues = {} as { [key: number]: string | null };\n boxStack: BoxStack;\n bodyReached: boolean = true;\n\n constructor(\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n cascade: CssCascade.Cascade,\n public readonly scope: Exprs.LexicalScope,\n public readonly context: Exprs.Context,\n public readonly primaryFlows: { [key: string]: boolean },\n public readonly validatorSet: CssValidator.ValidatorSet,\n public readonly counterListener: CssCascade.CounterListener,\n counterResolver: CssCascade.CounterResolver,\n ) {\n this.root = xmldoc.root;\n this.cascadeHolder = cascade;\n this.last = this.root;\n this.cascade = cascade.createInstance(\n context,\n counterListener,\n counterResolver,\n xmldoc.lang,\n );\n this.offsetMap = new SlipMap();\n const rootOffset = xmldoc.getElementOffset(this.root);\n this.lastOffset = rootOffset;\n this.boxStack = new BoxStack(context);\n this.offsetMap.addStuckRange(rootOffset);\n const style = this.getAttrStyle(this.root);\n this.cascade.pushElement(this.root, style, rootOffset);\n this.postprocessTopStyle(style, false);\n switch (this.root.namespaceURI) {\n case Base.NS.XHTML:\n case Base.NS.FB2:\n this.bodyReached = false;\n break;\n }\n this.primaryStack.push(true);\n this.styleMap = {};\n this.styleMap[`e${rootOffset}`] = style;\n this.lastOffset++;\n this.replayFlowElementsFromOffset(-1);\n }\n\n hasProp(\n style: CssCascade.ElementStyle,\n map: CssValidator.ValueMap,\n name: string,\n ): boolean {\n const cascVal = style[name];\n return cascVal && cascVal.evaluate(this.context) !== map[name];\n }\n\n transferPropsToRoot(\n srcStyle: CssCascade.ElementStyle,\n map: CssValidator.ValueMap,\n ): void {\n for (const pname in map) {\n const cascval = srcStyle[pname];\n if (cascval) {\n this.rootStyle[pname] = cascval;\n delete srcStyle[pname];\n } else {\n const val = map[pname];\n if (val) {\n this.rootStyle[pname] = new CssCascade.CascadeValue(\n val,\n CssParser.SPECIFICITY_AUTHOR,\n );\n }\n }\n }\n }\n\n /**\n * Transfer properties that should be applied on the container (partition)\n * level to this.rootStyle.\n * @param elemStyle (source) element style\n */\n postprocessTopStyle(\n elemStyle: CssCascade.ElementStyle,\n isBody: boolean,\n ): void {\n [\"writing-mode\", \"direction\"].forEach((propName) => {\n if (elemStyle[propName] && !(isBody && this.rootStyle[propName])) {\n // Copy it over, but keep it at the root element as well.\n this.rootStyle[propName] = elemStyle[propName];\n }\n });\n if (!this.rootBackgroundAssigned) {\n const backgroundColor = this.hasProp(\n elemStyle,\n this.validatorSet.backgroundProps,\n \"background-color\",\n )\n ? elemStyle[\"background-color\"].evaluate(this.context)\n : (null as Css.Val);\n const backgroundImage = this.hasProp(\n elemStyle,\n this.validatorSet.backgroundProps,\n \"background-image\",\n )\n ? elemStyle[\"background-image\"].evaluate(this.context)\n : (null as Css.Val);\n if (\n (backgroundColor && backgroundColor !== Css.ident.inherit) ||\n (backgroundImage && backgroundImage !== Css.ident.inherit)\n ) {\n this.transferPropsToRoot(elemStyle, this.validatorSet.backgroundProps);\n this.rootBackgroundAssigned = true;\n }\n }\n if (!this.rootLayoutAssigned) {\n for (let i = 0; i < columnProps.length; i++) {\n if (\n this.hasProp(elemStyle, this.validatorSet.layoutProps, columnProps[i])\n ) {\n this.transferPropsToRoot(elemStyle, this.validatorSet.layoutProps);\n this.rootLayoutAssigned = true;\n break;\n }\n }\n }\n if (!isBody) {\n const fontSize = elemStyle[\"font-size\"];\n if (fontSize) {\n const val = fontSize.evaluate(this.context);\n let px = val.num;\n switch (val.unit) {\n case \"em\":\n case \"rem\":\n px *= this.context.initialFontSize;\n break;\n case \"ex\":\n px *=\n (this.context.initialFontSize * Exprs.defaultUnitSizes[\"ex\"]) /\n Exprs.defaultUnitSizes[\"em\"];\n break;\n case \"%\":\n px *= this.context.initialFontSize / 100;\n break;\n default: {\n const unitSize = Exprs.defaultUnitSizes[val.unit];\n if (unitSize) {\n px *= unitSize;\n }\n }\n }\n this.context.rootFontSize = px;\n }\n }\n }\n\n getTopContainerStyle(): CssCascade.ElementStyle {\n let offset = 0;\n while (!this.bodyReached) {\n offset += 5000;\n if (this.styleUntil(offset, 0) == Number.POSITIVE_INFINITY) {\n break;\n }\n }\n return this.rootStyle;\n }\n\n getAttrStyle(elem: Element): CssCascade.ElementStyle {\n // skip cases in which elements for XML other than HTML or SVG\n // have 'style' attribute not for CSS declaration\n if ((elem as any).style instanceof CSSStyleDeclaration) {\n const styleAttrValue = elem.getAttribute(\"style\");\n if (styleAttrValue) {\n return CssCascade.parseStyleAttribute(\n this.scope,\n this.validatorSet,\n this.xmldoc.url,\n styleAttrValue,\n );\n }\n }\n return {} as CssCascade.ElementStyle;\n }\n\n /**\n * @return currently reached offset\n */\n getReachedOffset(): number {\n return this.lastOffset;\n }\n\n /**\n * Replay flow elements that were encountered since the given offset\n */\n replayFlowElementsFromOffset(offset: number): void {\n if (offset >= this.lastOffset) {\n return;\n }\n const context = this.context;\n const rootOffset = this.xmldoc.getElementOffset(this.root);\n if (offset < rootOffset) {\n const rootStyle = this.getStyle(this.root, false);\n Asserts.assert(rootStyle);\n const flowName = CssCascade.getProp(rootStyle, \"flow-into\");\n const flowNameStr = flowName\n ? flowName.evaluate(context, \"flow-into\").toString()\n : \"body\";\n const newFlowChunk = this.encounteredFlowElement(\n flowNameStr,\n rootStyle,\n this.root,\n rootOffset,\n );\n if (this.boxStack.empty()) {\n this.boxStack.push(rootStyle, rootOffset, true, newFlowChunk);\n }\n }\n let node = this.xmldoc.getNodeByOffset(offset);\n let nodeOffset = this.xmldoc.getNodeOffset(node, 0, false);\n if (nodeOffset >= this.lastOffset) {\n return;\n }\n while (true) {\n if (node.nodeType != 1) {\n nodeOffset += node.textContent.length;\n } else {\n const elem = node as Element;\n if (VIVLIOSTYLE_DEBUG) {\n if (nodeOffset != this.xmldoc.getElementOffset(elem)) {\n throw new Error(\"Inconsistent offset\");\n }\n }\n const style = this.getStyle(elem, false);\n const flowName = style[\"flow-into\"];\n if (flowName) {\n const flowNameStr = flowName\n .evaluate(context, \"flow-into\")\n .toString();\n this.encounteredFlowElement(flowNameStr, style, elem, nodeOffset);\n }\n nodeOffset++;\n }\n if (nodeOffset >= this.lastOffset) {\n break;\n }\n let next: Node = node.firstChild;\n if (next == null) {\n while (true) {\n next = node.nextSibling;\n if (next) {\n break;\n }\n node = node.parentNode;\n if (node === this.root) {\n return;\n }\n }\n }\n node = next;\n }\n }\n\n resetFlowChunkStream(flowListener: FlowListener): void {\n this.flowListener = flowListener;\n for (let i = 0; i < this.flowChunks.length; i++) {\n this.flowListener.encounteredFlowChunk(\n this.flowChunks[i],\n this.flows[this.flowChunks[i].flowName],\n );\n }\n }\n\n styleUntilFlowIsReached(flowName: string) {\n this.flowToReach = flowName;\n let offset = 0;\n while (true) {\n if (this.flowToReach == null) {\n break;\n }\n offset += 5000;\n if (this.styleUntil(offset, 0) == Number.POSITIVE_INFINITY) {\n break;\n }\n }\n }\n\n styleUntilIdIsReached(id: string) {\n if (!id) {\n return;\n }\n this.idToReach = id;\n let offset = 0;\n while (true) {\n if (!this.idToReach) {\n break;\n }\n offset += 5000;\n if (this.styleUntil(offset, 0) === Number.POSITIVE_INFINITY) {\n break;\n }\n }\n this.idToReach = null;\n }\n\n private encounteredFlowElement(\n flowName: string,\n style: CssCascade.ElementStyle,\n elem: Element,\n startOffset: number,\n ): Vtree.FlowChunk {\n let priority = 0;\n let linger = Number.POSITIVE_INFINITY;\n let exclusive = false;\n let repeated = false;\n let last = false;\n const optionsCV = style[\"flow-options\"];\n if (optionsCV) {\n const options = CssProp.toSet(\n optionsCV.evaluate(this.context, \"flow-options\"),\n );\n exclusive = !!options[\"exclusive\"];\n repeated = !!options[\"static\"];\n last = !!options[\"last\"];\n }\n const lingerCV = style[\"flow-linger\"];\n if (lingerCV) {\n linger = CssProp.toInt(\n lingerCV.evaluate(this.context, \"flow-linger\"),\n Number.POSITIVE_INFINITY,\n );\n }\n const priorityCV = style[\"flow-priority\"];\n if (priorityCV) {\n priority = CssProp.toInt(\n priorityCV.evaluate(this.context, \"flow-priority\"),\n 0,\n );\n }\n const breakBefore = this.breakBeforeValues[startOffset] || null;\n let flow = this.flows[flowName];\n if (!flow) {\n const parentFlowName = this.boxStack.lastFlowName();\n flow = this.flows[flowName] = new Vtree.Flow(flowName, parentFlowName);\n }\n const flowChunk = new Vtree.FlowChunk(\n flowName,\n elem,\n startOffset,\n priority,\n linger,\n exclusive,\n repeated,\n last,\n breakBefore,\n );\n this.flowChunks.push(flowChunk);\n if (this.flowToReach == flowName) {\n this.flowToReach = null;\n }\n if (this.flowListener) {\n this.flowListener.encounteredFlowChunk(flowChunk, flow);\n }\n return flowChunk;\n }\n\n registerForcedBreakOffset(\n breakValue: string | null,\n offset: number,\n flowName: string,\n ) {\n if (Break.isForcedBreakValue(breakValue)) {\n const forcedBreakOffsets = this.flows[flowName].forcedBreakOffsets;\n if (\n forcedBreakOffsets.length === 0 ||\n forcedBreakOffsets[forcedBreakOffsets.length - 1] < offset\n ) {\n forcedBreakOffsets.push(offset);\n }\n }\n const previousValue = this.breakBeforeValues[offset];\n this.breakBeforeValues[offset] = Break.resolveEffectiveBreakValue(\n previousValue,\n breakValue,\n );\n }\n\n /**\n * @param startOffset current position in the document\n * @param lookup lookup window size for the next page\n * @return lookup offset in the document for the next page\n */\n styleUntil(startOffset: number, lookup: number): number {\n let targetSlippedOffset = -1;\n let slippedOffset: number;\n if (startOffset <= this.lastOffset) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n if (targetSlippedOffset < this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n if (this.last == null) {\n return Number.POSITIVE_INFINITY;\n }\n const context = this.context;\n while (true) {\n let next: Node = this.last.firstChild;\n if (next == null) {\n while (true) {\n if (this.last.nodeType == 1) {\n this.cascade.popElement(this.last as Element);\n this.primary = this.primaryStack.pop();\n const box = this.boxStack.pop(this.lastOffset);\n let breakAfter: string | null = null;\n if (box.afterBox) {\n const afterPseudoBreakBefore = box.afterBox.getBreakValue(\n \"before\",\n );\n this.registerForcedBreakOffset(\n afterPseudoBreakBefore,\n box.afterBox.atBlockStart\n ? this.boxStack.nearestBlockStartOffset(box)\n : box.afterBox.offset,\n box.flowName,\n );\n breakAfter = box.afterBox.getBreakValue(\"after\");\n }\n breakAfter = Break.resolveEffectiveBreakValue(\n breakAfter,\n box.getBreakValue(\"after\"),\n );\n this.registerForcedBreakOffset(\n breakAfter,\n this.lastOffset,\n box.flowName,\n );\n }\n next = this.last.nextSibling;\n if (next) {\n break;\n }\n this.last = this.last.parentNode;\n if (this.last === this.root) {\n this.last = null;\n if (startOffset < this.lastOffset) {\n if (targetSlippedOffset < 0) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n }\n if (targetSlippedOffset <= this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n return Number.POSITIVE_INFINITY;\n }\n }\n }\n this.last = next;\n if (this.last.nodeType != 1) {\n this.lastOffset += this.last.textContent.length;\n this.boxStack.encounteredTextNode(this.last);\n if (this.primary) {\n this.offsetMap.addStuckRange(this.lastOffset);\n } else {\n this.offsetMap.addSlippedRange(this.lastOffset);\n }\n } else {\n const elem = this.last as Element;\n const style = this.getAttrStyle(elem);\n this.primaryStack.push(this.primary);\n this.cascade.pushElement(elem, style, this.lastOffset);\n const id =\n elem.getAttribute(\"id\") || elem.getAttributeNS(Base.NS.XML, \"id\");\n if (id && id === this.idToReach) {\n this.idToReach = null;\n }\n if (\n !this.bodyReached &&\n elem.localName == \"body\" &&\n elem.parentNode == this.root\n ) {\n this.postprocessTopStyle(style, true);\n this.bodyReached = true;\n }\n let box: Box;\n const flowName = style[\"flow-into\"];\n if (flowName) {\n const flowNameStr = flowName\n .evaluate(context, \"flow-into\")\n .toString();\n const newFlowChunk = this.encounteredFlowElement(\n flowNameStr,\n style,\n elem,\n this.lastOffset,\n );\n this.primary = !!this.primaryFlows[flowNameStr];\n box = this.boxStack.push(\n style,\n this.lastOffset,\n elem === this.root,\n newFlowChunk,\n );\n } else {\n box = this.boxStack.push(style, this.lastOffset, elem === this.root);\n }\n const blockStartOffset = this.boxStack.nearestBlockStartOffset(box);\n this.registerForcedBreakOffset(\n box.breakBefore,\n blockStartOffset,\n box.flowName,\n );\n if (box.beforeBox) {\n const beforePseudoBreakAfter = box.beforeBox.getBreakValue(\"after\");\n this.registerForcedBreakOffset(\n beforePseudoBreakAfter,\n box.beforeBox.atBlockStart ? blockStartOffset : box.offset,\n box.flowName,\n );\n }\n if (this.primary) {\n if (box.displayValue() === Css.ident.none) {\n this.primary = false;\n }\n }\n if (VIVLIOSTYLE_DEBUG) {\n const offset = this.xmldoc.getElementOffset(this.last as Element);\n if (offset != this.lastOffset) {\n throw new Error(\"Inconsistent offset\");\n }\n }\n this.styleMap[`e${this.lastOffset}`] = style;\n this.lastOffset++;\n if (this.primary) {\n this.offsetMap.addStuckRange(this.lastOffset);\n } else {\n this.offsetMap.addSlippedRange(this.lastOffset);\n }\n if (startOffset < this.lastOffset) {\n if (targetSlippedOffset < 0) {\n slippedOffset = this.offsetMap.slippedByFixed(startOffset);\n targetSlippedOffset = slippedOffset + lookup;\n }\n if (targetSlippedOffset <= this.offsetMap.getMaxSlipped()) {\n // got to the desired point\n return this.offsetMap.fixedBySlipped(targetSlippedOffset);\n }\n }\n }\n }\n }\n\n /**\n * @override\n */\n getStyle(element: Element, deep: boolean): CssCascade.ElementStyle {\n let offset = this.xmldoc.getElementOffset(element);\n const key = `e${offset}`;\n if (deep) {\n offset = this.xmldoc.getNodeOffset(element, 0, true);\n }\n if (this.lastOffset <= offset) {\n this.styleUntil(offset, 0);\n }\n return this.styleMap[key];\n }\n\n /**\n * @override\n */\n processContent(element: Element, styles: { [key: string]: Css.Val }) {}\n}\n\nexport const columnProps = [\"column-count\", \"column-width\", \"column-fill\"];\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssValidator - Parse validation rules (validation.txt), validate\n * properties and shorthands.\n */\nimport * as Css from \"./css\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Logging from \"./logging\";\nimport ValidationTxt from \"./assets/validation.txt\";\n\nexport interface PropertyReceiver {\n unknownProperty(name: string, value: Css.Val): void;\n\n invalidPropertyValue(name: string, value: Css.Val): void;\n\n simpleProperty(name: string, value: Css.Val, important): void;\n}\n\nexport class Node {\n success: Node = null;\n failure: Node = null;\n code: number = 0;\n\n constructor(public validator: PropertyValidator) {}\n\n isSpecial(): boolean {\n return this.code != 0;\n }\n\n markAsStartGroup(): void {\n this.code = -1;\n }\n\n isStartGroup(): boolean {\n return this.code == -1;\n }\n\n markAsEndGroup(): void {\n this.code = -2;\n }\n\n isEndGroup(): boolean {\n return this.code == -2;\n }\n\n markAsStartAlternate(index: number): void {\n this.code = 2 * index + 1;\n }\n\n isStartAlternate(): boolean {\n return this.code > 0 && this.code % 2 != 0;\n }\n\n markAsEndAlternate(index: number): void {\n this.code = 2 * index + 2;\n }\n\n isEndAlternate(): boolean {\n return this.code > 0 && this.code % 2 == 0;\n }\n\n getAlternate(): number {\n return Math.floor((this.code - 1) / 2);\n }\n}\n\nexport class Connection {\n what: number = -1;\n\n constructor(public where: number, public success: boolean) {}\n}\n\n/**\n * @enum {number}\n */\nexport enum Add {\n FOLLOW = 1,\n OPTIONAL,\n REPEATED,\n ALTERNATE,\n}\n\n/**\n * A class to build a list validator from other validators.\n */\nexport class ValidatingGroup {\n nodes: Node[] = [];\n connections: Connection[] = [];\n match: number[] = []; // connector indicies\n nomatch: number[] = []; // connector indicies\n error: number[] = []; // connector indicies\n emptyHead: boolean = true;\n\n connect(arr: number[], nodeIndex: number): void {\n for (let i = 0; i < arr.length; i++) {\n this.connections[arr[i]].what = nodeIndex;\n }\n arr.splice(0, arr.length);\n }\n\n clone(): ValidatingGroup {\n const group = new ValidatingGroup();\n for (let i = 0; i < this.nodes.length; i++) {\n const node = this.nodes[i];\n const clonedNode = new Node(node.validator);\n clonedNode.code = node.code;\n group.nodes.push(clonedNode);\n }\n for (let i = 0; i < this.connections.length; i++) {\n const connection = this.connections[i];\n const groupConnection = new Connection(\n connection.where,\n connection.success,\n );\n groupConnection.what = connection.what;\n group.connections.push(groupConnection);\n }\n group.match.push(...this.match);\n group.nomatch.push(...this.nomatch);\n group.error.push(...this.error);\n return group;\n }\n\n /**\n * Add \"special\" validation node to a given array (match, nomatch, or error).\n * @param start if this a start or the end of a clause/group\n * @param clause 0 indicates group start/end, otherwise clause index\n */\n private addSpecialToArr(arr: number[], start: boolean, clause: number): void {\n const index = this.nodes.length;\n const node = new Node(ALWAYS_FAIL);\n if (clause >= 0) {\n if (start) {\n node.markAsStartAlternate(clause);\n } else {\n node.markAsEndAlternate(clause);\n }\n } else {\n if (start) {\n node.markAsStartGroup();\n } else {\n node.markAsEndGroup();\n }\n }\n this.nodes.push(node);\n this.connect(arr, index);\n const success = new Connection(index, true);\n const failure = new Connection(index, false);\n arr.push(this.connections.length);\n this.connections.push(failure);\n arr.push(this.connections.length);\n this.connections.push(success);\n }\n\n endSpecialGroup(): void {\n const arrs = [this.match, this.nomatch, this.error];\n for (let i = 0; i < arrs.length; i++) {\n this.addSpecialToArr(arrs[i], false, -1);\n }\n }\n\n startSpecialGroup(): void {\n if (this.nodes.length) {\n throw new Error(\"invalid call\");\n }\n this.addSpecialToArr(this.match, true, -1);\n }\n\n endClause(clause: number): void {\n this.addSpecialToArr(this.match, false, clause);\n }\n\n startClause(clause: number): void {\n if (this.nodes.length) {\n throw new Error(\"invalid call\");\n }\n const node = new Node(ALWAYS_FAIL);\n node.markAsStartAlternate(clause);\n this.nodes.push(node);\n const success = new Connection(0, true);\n const failure = new Connection(0, false);\n this.nomatch.push(this.connections.length);\n this.connections.push(failure);\n this.match.push(this.connections.length);\n this.connections.push(success);\n }\n\n addPrimitive(validator: PropertyValidator): void {\n const index = this.nodes.length;\n this.nodes.push(new Node(validator));\n const success = new Connection(index, true);\n const failure = new Connection(index, false);\n this.connect(this.match, index);\n if (this.emptyHead) {\n // if did not validate -> no match\n this.nomatch.push(this.connections.length);\n this.emptyHead = false;\n } else {\n // if did not validate -> failure\n this.error.push(this.connections.length);\n }\n this.connections.push(failure);\n this.match.push(this.connections.length);\n this.connections.push(success);\n }\n\n isSimple(): boolean {\n return this.nodes.length == 1 && !this.nodes[0].isSpecial();\n }\n\n isPrimitive(): boolean {\n return (\n this.isSimple() && this.nodes[0].validator instanceof PrimitiveValidator\n );\n }\n\n addGroup(group: ValidatingGroup, how: Add): void {\n if (group.nodes.length == 0) {\n return;\n }\n const index = this.nodes.length;\n\n // optimization for alternate primitive validators\n if (\n how == Add.ALTERNATE &&\n index == 1 &&\n group.isPrimitive() &&\n this.isPrimitive()\n ) {\n this.nodes[0].validator = (this.nodes[0]\n .validator as PrimitiveValidator).combine(\n group.nodes[0].validator as PrimitiveValidator,\n );\n return;\n }\n for (let i = 0; i < group.nodes.length; i++) {\n this.nodes.push(group.nodes[i]);\n }\n\n // nodes[index] is group start\n if (how == Add.ALTERNATE) {\n this.emptyHead = true;\n this.connect(this.nomatch, index);\n } else {\n this.connect(this.match, index);\n }\n const connectionIndex = this.connections.length;\n for (let i = 0; i < group.connections.length; i++) {\n const connection = group.connections[i];\n connection.where += index;\n if (connection.what >= 0) {\n connection.what += index;\n }\n this.connections.push(connection);\n }\n for (let i = 0; i < group.match.length; i++) {\n this.match.push(group.match[i] + connectionIndex);\n }\n if (how == Add.REPEATED) {\n this.connect(this.match, index);\n }\n if (how == Add.OPTIONAL || how == Add.REPEATED) {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.match.push(group.nomatch[i] + connectionIndex);\n }\n } else if (this.emptyHead) {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.nomatch.push(group.nomatch[i] + connectionIndex);\n }\n this.emptyHead = group.emptyHead;\n } else {\n for (let i = 0; i < group.nomatch.length; i++) {\n this.error.push(group.nomatch[i] + connectionIndex);\n }\n }\n for (let i = 0; i < group.error.length; i++) {\n this.error.push(group.error[i] + connectionIndex);\n }\n\n // invalidate group\n group.nodes = null;\n group.connections = null;\n }\n\n /**\n * @return how\n */\n finish(successTerminal: Node, failTerminal: Node): Node {\n const index = this.nodes.length;\n this.nodes.push(successTerminal);\n this.nodes.push(failTerminal);\n this.connect(this.match, index);\n this.connect(this.nomatch, index + 1);\n this.connect(this.error, index + 1);\n for (const connection of this.connections) {\n if (connection.success) {\n this.nodes[connection.where].success = this.nodes[connection.what];\n } else {\n this.nodes[connection.where].failure = this.nodes[connection.what];\n }\n }\n\n // make sure that our data structure is correct\n for (let j = 0; j < index; j++) {\n if (this.nodes[j].failure == null || this.nodes[j].success == null) {\n throw new Error(\"Invalid validator state\");\n }\n }\n return this.nodes[0];\n }\n}\n\nexport const ALLOW_EMPTY = 1;\n\nexport const ALLOW_STR = 2;\n\nexport const ALLOW_IDENT = 4;\n\nexport const ALLOW_POS_NUMERIC = 8;\n\nexport const ALLOW_POS_NUM = 16;\n\nexport const ALLOW_POS_INT = 32;\n\nexport const ALLOW_COLOR = 64;\n\nexport const ALLOW_URL = 128;\n\nexport const ALLOW_NEGATIVE = 256;\n\nexport const ALLOW_ZERO = 512;\n\nexport const ALLOW_ZERO_PERCENT = 1024;\n\nexport const ALLOW_SLASH = 2048;\n\nexport type ValueMap = {\n [key: string]: Css.Val;\n};\n\n/**\n * Abstract class to validate simple CSS property value (not a shorthand)\n */\nexport class PropertyValidator extends Css.Visitor {\n constructor() {\n super();\n }\n\n /**\n * Validate a subsequence of the given values from the given index. Return the\n * list of matched values or null if there is no match.\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n const rval = values[index].visit(this);\n if (rval) {\n return [rval];\n }\n return null;\n }\n}\n\n/**\n * Validate a primitive CSS value (not a list or function).\n * @param allowed mask of ALLOW_*** constants.\n */\nexport class PrimitiveValidator extends PropertyValidator {\n constructor(\n public readonly allowed: number,\n public readonly idents: ValueMap,\n public readonly units: ValueMap,\n ) {\n super();\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n if (this.allowed & ALLOW_EMPTY) {\n return empty;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSlash(slash: Css.Val): Css.Val {\n if (this.allowed & ALLOW_SLASH) {\n return slash;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n if (this.allowed & ALLOW_STR) {\n return str;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const val = this.idents[ident.name.toLowerCase()];\n if (val) {\n return val;\n }\n if (this.allowed & ALLOW_IDENT) {\n return ident;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n if (numeric.num == 0 && !(this.allowed & ALLOW_ZERO)) {\n if (numeric.unit == \"%\" && this.allowed & ALLOW_ZERO_PERCENT) {\n return numeric;\n }\n return null;\n }\n if (numeric.num < 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.units[numeric.unit]) {\n return numeric;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n if (num.num == 0) {\n return this.allowed & ALLOW_ZERO ? num : null;\n }\n if (num.num <= 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.allowed & ALLOW_POS_NUM) {\n return num;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n if (num.num == 0) {\n return this.allowed & ALLOW_ZERO ? num : null;\n }\n if (num.num <= 0 && !(this.allowed & ALLOW_NEGATIVE)) {\n return null;\n }\n if (this.allowed & (ALLOW_POS_INT | ALLOW_POS_NUM)) {\n return num;\n }\n const val = this.idents[`${num.num}`];\n if (val) {\n return val;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n if (this.allowed & ALLOW_COLOR) {\n return color;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n if (this.allowed & ALLOW_URL) {\n return url;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n if (this.allowed & 0x7fe) {\n // ALLOW_STR|ALLOW_IDENT|...|ALLOW_ZERO_PERCENT\n return expr;\n }\n return null;\n }\n\n combine(other: PrimitiveValidator): PrimitiveValidator {\n const idents: ValueMap = {};\n const units: ValueMap = {};\n for (const ident in this.idents) {\n idents[ident] = this.idents[ident];\n }\n for (const ident in other.idents) {\n idents[ident] = other.idents[ident];\n }\n for (const unit in this.units) {\n units[unit] = this.units[unit];\n }\n for (const unit in other.units) {\n units[unit] = other.units[unit];\n }\n return new PrimitiveValidator(this.allowed | other.allowed, idents, units);\n }\n}\n\nconst NO_IDENTS = {};\n\nexport const ALWAYS_FAIL = new PrimitiveValidator(0, NO_IDENTS, NO_IDENTS);\n\n/**\n * Base class for list validation.\n */\nexport class ListValidator extends PropertyValidator {\n successTerminal: Node;\n failureTerminal: Node;\n first: Node;\n\n constructor(group: ValidatingGroup) {\n super();\n this.successTerminal = new Node(null);\n this.failureTerminal = new Node(null);\n this.first = group.finish(this.successTerminal, this.failureTerminal);\n }\n\n validateList(arr: Css.Val[], slice: boolean, startIndex: number): Css.Val[] {\n let out: Css.Val[] = slice ? [] : arr;\n let current = this.first;\n let index = startIndex;\n let alternativeStack: string[][] = null;\n let alternatives: string[] = null;\n while (\n current !== this.successTerminal &&\n current !== this.failureTerminal\n ) {\n if (index >= arr.length) {\n current = current.failure;\n continue;\n }\n const inval = arr[index];\n let outval = inval;\n if (current.isSpecial()) {\n let success = true;\n if (current.isStartGroup()) {\n if (alternativeStack) {\n alternativeStack.push(alternatives);\n } else {\n alternativeStack = [alternatives];\n }\n alternatives = [];\n } else if (current.isEndGroup()) {\n if (alternativeStack.length > 0) {\n alternatives = alternativeStack.pop();\n } else {\n alternatives = null;\n }\n } else if (current.isEndAlternate()) {\n alternatives[current.getAlternate()] = \"taken\";\n } else {\n success = alternatives[current.getAlternate()] == null;\n }\n current = success ? current.success : current.failure;\n } else {\n if (\n index == 0 &&\n !slice &&\n current.validator instanceof SpaceListValidator &&\n this instanceof SpaceListValidator\n ) {\n // Special nesting case: validate the input space list as a whole.\n outval = new Css.SpaceList(arr).visit(current.validator);\n if (outval) {\n index = arr.length;\n current = current.success;\n continue;\n }\n } else if (\n index == 0 &&\n !slice &&\n current.validator instanceof CommaListValidator &&\n this instanceof SpaceListValidator\n ) {\n // Special nesting case: validate the input comma list as a whole.\n outval = new Css.CommaList(arr).visit(current.validator);\n if (outval) {\n index = arr.length;\n current = current.success;\n continue;\n }\n } else {\n outval = inval.visit(current.validator);\n }\n if (!outval) {\n current = current.failure;\n continue;\n }\n if (outval !== inval && arr === out) {\n // startIndex is zero here\n out = [];\n for (let k = 0; k < index; k++) {\n out[k] = arr[k];\n }\n }\n if (arr !== out) {\n out[index - startIndex] = outval;\n }\n index++;\n current = current.success;\n }\n }\n if (current === this.successTerminal) {\n if (slice ? out.length > 0 : index == arr.length) {\n return out;\n }\n }\n return null;\n }\n\n validateSingle(inval: Css.Val): Css.Val {\n // no need to worry about \"specials\"\n let outval: Css.Val = null;\n let current = this.first;\n while (\n current !== this.successTerminal &&\n current !== this.failureTerminal\n ) {\n if (!inval) {\n current = current.failure;\n continue;\n }\n if (current.isSpecial()) {\n current = current.success;\n continue;\n }\n outval = inval.visit(current.validator);\n if (!outval) {\n current = current.failure;\n continue;\n }\n inval = null;\n current = current.success;\n }\n if (current === this.successTerminal) {\n return outval;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n return this.validateSingle(empty);\n }\n\n /**\n * @override\n */\n visitSlash(slash: Css.Val): Css.Val {\n return this.validateSingle(slash);\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n return this.validateSingle(str);\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n return this.validateSingle(ident);\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n return this.validateSingle(numeric);\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n return this.validateSingle(color);\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n return this.validateSingle(url);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return this.validateSingle(func);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n return null;\n }\n}\n\nexport class SpaceListValidator extends ListValidator {\n constructor(group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.SpaceList(arr);\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n // Special Case : Issue #156\n let node = this.first;\n let hasCommaListValidator = false;\n while (node) {\n if (node.validator instanceof CommaListValidator) {\n hasCommaListValidator = true;\n break;\n }\n node = node.failure;\n }\n if (hasCommaListValidator) {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.CommaList(arr);\n }\n return null;\n }\n\n /**\n * @override\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n return this.validateList(values, true, index);\n }\n}\n\nexport class CommaListValidator extends ListValidator {\n constructor(group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n return this.validateSingle(list);\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n const arr = this.validateList(list.values, false, 0);\n if (arr === list.values) {\n return list;\n }\n if (!arr) {\n return null;\n }\n return new Css.CommaList(arr);\n }\n\n /**\n * @override\n */\n validateForShorthand(values: Css.Val[], index: number): Css.Val[] {\n let current = this.first;\n let rval: Css.Val[];\n while (current !== this.failureTerminal) {\n rval = current.validator.validateForShorthand(values, index);\n if (rval) {\n return rval;\n }\n current = current.failure;\n }\n return null;\n }\n}\n\nexport class FuncValidator extends ListValidator {\n constructor(public readonly name: string, group: ValidatingGroup) {\n super(group);\n }\n\n /**\n * @override\n */\n validateSingle(inval: Css.Val): Css.Val {\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n if (func.name.toLowerCase() != this.name) {\n return null;\n }\n const arr = this.validateList(func.values, false, 0);\n if (arr === func.values) {\n return func;\n }\n if (!arr) {\n return null;\n }\n return new Css.Func(func.name, arr);\n }\n}\n\n//----------------------- Shorthands\n//------------------------------------------------------------\nexport class ShorthandSyntaxNode {\n /**\n * @return new index.\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n return index;\n }\n\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {}\n}\n\nexport class ShorthandSyntaxProperty extends ShorthandSyntaxNode {\n validator: PropertyValidator;\n\n constructor(validatorSet: ValidatorSet, public readonly name: string) {\n super();\n this.validator = validatorSet.validators[this.name];\n }\n\n /**\n * @override\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n if (shorthandValidator.values[this.name]) {\n return index;\n }\n const rvals = this.validator.validateForShorthand(values, index);\n if (rvals) {\n const len = rvals.length;\n const rval = len > 1 ? new Css.SpaceList(rvals) : rvals[0];\n this.success(rval, shorthandValidator);\n return index + len;\n }\n return index;\n }\n\n /**\n * @override\n */\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {\n shorthandValidator.values[this.name] = rval;\n }\n}\n\nexport class ShorthandSyntaxPropertyN extends ShorthandSyntaxProperty {\n constructor(validatorSet: ValidatorSet, public readonly names: string[]) {\n super(validatorSet, names[0]);\n }\n\n /**\n * @override\n */\n success(rval: Css.Val, shorthandValidator: ShorthandValidator): void {\n for (let i = 0; i < this.names.length; i++) {\n shorthandValidator.values[this.names[i]] = rval;\n }\n }\n}\n\nexport class ShorthandSyntaxCompound extends ShorthandSyntaxNode {\n constructor(\n public readonly nodes: ShorthandSyntaxNode[],\n public readonly slash: boolean,\n ) {\n super();\n }\n\n /**\n * @override\n */\n tryParse(\n values: Css.Val[],\n index: number,\n shorthandValidator: ShorthandValidator,\n ): number {\n const index0 = index;\n if (this.slash) {\n if (values[index] == Css.slash) {\n if (++index == values.length) {\n return index0;\n }\n } else {\n return index0;\n }\n }\n let newIndex = this.nodes[0].tryParse(values, index, shorthandValidator);\n if (newIndex == index) {\n return index0;\n }\n index = newIndex;\n for (let i = 1; i < this.nodes.length && index < values.length; i++) {\n newIndex = this.nodes[i].tryParse(values, index, shorthandValidator);\n if (newIndex == index) {\n break;\n }\n index = newIndex;\n }\n return index;\n }\n}\n\nexport class ShorthandValidator extends Css.Visitor {\n syntax: ShorthandSyntaxNode[] = null;\n propList: string[] = null;\n error: boolean = false;\n values: ValueMap = {};\n validatorSet: ValidatorSet = null;\n\n setOwner(validatorSet: ValidatorSet) {\n this.validatorSet = validatorSet;\n }\n\n syntaxNodeForProperty(name: string): ShorthandSyntaxNode {\n return new ShorthandSyntaxProperty(this.validatorSet, name);\n }\n\n clone(): this {\n const other = new (this.constructor as any)();\n other.syntax = this.syntax;\n other.propList = this.propList;\n other.validatorSet = this.validatorSet;\n return other;\n }\n\n init(syntax: ShorthandSyntaxNode[], propList: string[]): void {\n this.syntax = syntax;\n this.propList = propList;\n }\n\n finish(important: boolean, receiver: PropertyReceiver): boolean {\n if (!this.error) {\n for (const name of this.propList) {\n receiver.simpleProperty(\n name,\n this.values[name] || this.validatorSet.defaultValues[name],\n important,\n );\n }\n return true;\n }\n return false;\n }\n\n propagateInherit(important: boolean, receiver: PropertyReceiver): void {\n for (const name of this.propList) {\n receiver.simpleProperty(name, Css.ident.inherit, important);\n }\n }\n\n validateList(list: Css.Val[]): number {\n this.error = true;\n return 0;\n }\n\n validateSingle(val: Css.Val): Css.Val {\n this.validateList([val]);\n return null;\n }\n\n /**\n * @override\n */\n visitEmpty(empty: Css.Val): Css.Val {\n return this.validateSingle(empty);\n }\n\n /**\n * @override\n */\n visitStr(str: Css.Str): Css.Val {\n return this.validateSingle(str);\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n return this.validateSingle(ident);\n }\n\n /**\n * @override\n */\n visitNumeric(numeric: Css.Numeric): Css.Val {\n return this.validateSingle(numeric);\n }\n\n /**\n * @override\n */\n visitNum(num: Css.Num): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitInt(num: Css.Int): Css.Val {\n return this.validateSingle(num);\n }\n\n /**\n * @override\n */\n visitColor(color: Css.Color): Css.Val {\n return this.validateSingle(color);\n }\n\n /**\n * @override\n */\n visitURL(url: Css.URL): Css.Val {\n return this.validateSingle(url);\n }\n\n /**\n * @override\n */\n visitSpaceList(list: Css.SpaceList): Css.Val {\n this.validateList(list.values);\n return null;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n this.error = true;\n return null;\n }\n\n /**\n * @override\n */\n visitFunc(func: Css.Func): Css.Val {\n return this.validateSingle(func);\n }\n\n /**\n * @override\n */\n visitExpr(expr: Css.Expr): Css.Val {\n this.error = true;\n return null;\n }\n}\n\nexport class SimpleShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let index = 0;\n let i = 0;\n while (index < list.length) {\n const newIndex = this.syntax[i].tryParse(list, index, this);\n if (newIndex > index) {\n index = newIndex;\n i = 0;\n continue;\n }\n if (++i == this.syntax.length) {\n this.error = true;\n break;\n }\n }\n return index;\n }\n}\n\nexport class InsetsShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n if (list.length > this.syntax.length || list.length == 0) {\n this.error = true;\n return 0;\n }\n for (let i = 0; i < this.syntax.length; i++) {\n let index = i;\n while (index >= list.length) {\n index = index == 1 ? 0 : index - 2;\n }\n if (this.syntax[i].tryParse(list, index, this) != index + 1) {\n this.error = true;\n return 0;\n }\n }\n return list.length;\n }\n\n createSyntaxNode(): ShorthandSyntaxPropertyN {\n return new ShorthandSyntaxPropertyN(this.validatorSet, this.propList);\n }\n}\n\nexport class InsetsSlashShorthandValidator extends ShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let slashIndex = list.length;\n for (let i = 0; i < list.length; i++) {\n if (list[i] === Css.slash) {\n slashIndex = i;\n break;\n }\n }\n if (slashIndex > this.syntax.length || list.length == 0) {\n this.error = true;\n return 0;\n }\n for (let i = 0; i < this.syntax.length; i++) {\n let index0 = i;\n while (index0 >= slashIndex) {\n index0 = index0 == 1 ? 0 : index0 - 2;\n }\n let index1: number;\n if (slashIndex + 1 < list.length) {\n index1 = slashIndex + i + 1;\n while (index1 >= list.length) {\n index1 = index1 - (index1 == slashIndex + 2 ? 1 : 2);\n }\n } else {\n index1 = index0;\n }\n const vals = [list[index0], list[index1]];\n if (this.syntax[i].tryParse(vals, 0, this) != 2) {\n this.error = true;\n return 0;\n }\n }\n return list.length;\n }\n}\n\nexport class CommaShorthandValidator extends SimpleShorthandValidator {\n constructor() {\n super();\n }\n\n mergeIn(acc: { [key: string]: Css.Val[] }, values: ValueMap) {\n for (const name of this.propList) {\n const val = values[name] || this.validatorSet.defaultValues[name];\n let arr = acc[name];\n if (!arr) {\n arr = [];\n acc[name] = arr;\n }\n arr.push(val);\n }\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n const acc: { [key: string]: Css.Val[] } = {};\n for (let i = 0; i < list.values.length; i++) {\n this.values = {};\n if (list.values[i] instanceof Css.CommaList) {\n this.error = true;\n } else {\n list.values[i].visit(this);\n this.mergeIn(acc, this.values);\n if (this.values[\"background-color\"] && i != list.values.length - 1) {\n this.error = true;\n }\n }\n if (this.error) {\n return null;\n }\n }\n this.values = {};\n for (const name in acc) {\n if (name == \"background-color\") {\n this.values[name] = acc[name].pop();\n } else {\n this.values[name] = new Css.CommaList(acc[name]);\n }\n }\n return null;\n }\n}\n\nexport class FontShorthandValidator extends SimpleShorthandValidator {\n constructor() {\n super();\n }\n\n /**\n * @override\n */\n init(syntax: ShorthandSyntaxNode[], propList: string[]): void {\n super.init(syntax, propList);\n this.propList.push(\"font-family\", \"line-height\", \"font-size\");\n }\n\n /**\n * @override\n */\n validateList(list: Css.Val[]): number {\n let index = super.validateList(list);\n\n // must at least have font-size and font-family at the end\n if (index + 2 > list.length) {\n this.error = true;\n return index;\n }\n this.error = false;\n const validators = this.validatorSet.validators;\n if (!list[index].visit(validators[\"font-size\"])) {\n this.error = true;\n return index;\n }\n this.values[\"font-size\"] = list[index++];\n if (list[index] === Css.slash) {\n index++;\n\n // must at least have line-height and font-family at the end\n if (index + 2 > list.length) {\n this.error = true;\n return index;\n }\n if (!list[index].visit(validators[\"line-height\"])) {\n this.error = true;\n return index;\n }\n this.values[\"line-height\"] = list[index++];\n }\n const fontFamily =\n index == list.length - 1\n ? list[index]\n : new Css.SpaceList(list.slice(index, list.length));\n if (!fontFamily.visit(validators[\"font-family\"])) {\n this.error = true;\n return index;\n }\n this.values[\"font-family\"] = fontFamily;\n return list.length;\n }\n\n /**\n * @override\n */\n visitCommaList(list: Css.CommaList): Css.Val {\n list.values[0].visit(this);\n if (this.error) {\n return null;\n }\n const familyList = [this.values[\"font-family\"]];\n for (let i = 1; i < list.values.length; i++) {\n familyList.push(list.values[i]);\n }\n const family = new Css.CommaList(familyList);\n if (!family.visit(this.validatorSet.validators[\"font-family\"])) {\n this.error = true;\n } else {\n this.values[\"font-family\"] = family;\n }\n return null;\n }\n\n /**\n * @override\n */\n visitIdent(ident: Css.Ident): Css.Val {\n const props = this.validatorSet.systemFonts[ident.name];\n if (props) {\n for (const name in props) {\n this.values[name] = props[name];\n }\n } else {\n this.error = true;\n }\n return null;\n }\n}\n\nexport const shorthandValidators: {\n [key: string]: typeof ShorthandValidator;\n} = {\n SIMPLE: SimpleShorthandValidator,\n INSETS: InsetsShorthandValidator,\n INSETS_SLASH: InsetsSlashShorthandValidator,\n COMMA: CommaShorthandValidator,\n FONT: FontShorthandValidator,\n};\n\n//---- validation grammar parser and public property validator\n//------------------------\n\n/**\n * Object that validates simple and shorthand properties, breaking up shorthand\n * properties into corresponding simple ones, also stripping property prefixes.\n */\nexport class ValidatorSet {\n validators: { [key: string]: PropertyValidator } = {};\n prefixes: { [key: string]: { [key: string]: boolean } } = {};\n defaultValues: ValueMap = {};\n namedValidators: { [key: string]: ValidatingGroup } = {};\n systemFonts: { [key: string]: ValueMap } = {};\n shorthands: { [key: string]: ShorthandValidator } = {};\n layoutProps: ValueMap = {};\n backgroundProps: ValueMap = {};\n\n private addReplacement(\n val: ValidatingGroup,\n token: CssTokenizer.Token,\n ): ValidatingGroup {\n let cssval: Css.Val;\n if (token.type == CssTokenizer.TokenType.NUMERIC) {\n cssval = new Css.Numeric(token.num, token.text);\n } else if (token.type == CssTokenizer.TokenType.HASH) {\n cssval = CssParser.colorFromHash(token.text);\n } else if (token.type == CssTokenizer.TokenType.IDENT) {\n cssval = Css.getName(token.text);\n } else {\n throw new Error(\"unexpected replacement\");\n }\n if (val.isPrimitive()) {\n const validator = val.nodes[0].validator as PrimitiveValidator;\n const idents = validator.idents;\n for (const ident in idents) {\n idents[ident] = cssval;\n }\n return val;\n }\n throw new Error(\"unexpected replacement\");\n }\n\n private newGroup(op: string, vals: ValidatingGroup[]): ValidatingGroup {\n const group = new ValidatingGroup();\n if (op == \"||\") {\n for (let i = 0; i < vals.length; i++) {\n const subgroup = new ValidatingGroup();\n subgroup.startClause(i);\n subgroup.addGroup(vals[i], Add.FOLLOW);\n subgroup.endClause(i);\n group.addGroup(subgroup, i == 0 ? Add.FOLLOW : Add.ALTERNATE);\n }\n const outer = new ValidatingGroup();\n outer.startSpecialGroup();\n outer.addGroup(group, Add.REPEATED);\n outer.endSpecialGroup();\n return outer;\n } else {\n let how: Add;\n switch (op) {\n case \" \":\n how = Add.FOLLOW;\n break;\n case \"|\":\n case \"||\":\n how = Add.ALTERNATE;\n break;\n default:\n throw new Error(\"unexpected op\");\n }\n for (let i = 0; i < vals.length; i++) {\n group.addGroup(vals[i], i == 0 ? Add.FOLLOW : how);\n }\n return group;\n }\n }\n\n private addCounts(\n val: ValidatingGroup,\n min: number,\n max: number,\n ): ValidatingGroup {\n const group = new ValidatingGroup();\n for (let i = 0; i < min; i++) {\n group.addGroup(val.clone(), Add.FOLLOW);\n }\n if (max == Number.POSITIVE_INFINITY) {\n group.addGroup(val, Add.REPEATED);\n } else {\n for (let i = min; i < max; i++) {\n group.addGroup(val.clone(), Add.OPTIONAL);\n }\n }\n return group;\n }\n\n private primitive(validator: PropertyValidator): ValidatingGroup {\n const group = new ValidatingGroup();\n group.addPrimitive(validator);\n return group;\n }\n\n private newFunc(fn: string, val: ValidatingGroup): ValidatingGroup {\n let validator: PropertyValidator;\n switch (fn) {\n case \"COMMA\":\n validator = new CommaListValidator(val);\n break;\n case \"SPACE\":\n validator = new SpaceListValidator(val);\n break;\n default:\n validator = new FuncValidator(fn.toLowerCase(), val);\n break;\n }\n return this.primitive(validator);\n }\n\n initBuiltInValidators(): void {\n this.namedValidators[\"HASHCOLOR\"] = this.primitive(\n new PrimitiveValidator(ALLOW_COLOR, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_INT\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_INT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_NUM\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUM, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_PERCENTAGE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, { \"%\": Css.empty }),\n );\n this.namedValidators[\"NEGATIVE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_NEGATIVE, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"ZERO\"] = this.primitive(\n new PrimitiveValidator(ALLOW_ZERO, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"ZERO_PERCENTAGE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_ZERO_PERCENT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"POS_LENGTH\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n em: Css.empty,\n ex: Css.empty,\n ch: Css.empty,\n rem: Css.empty,\n vw: Css.empty,\n vh: Css.empty,\n vi: Css.empty,\n vb: Css.empty,\n vmin: Css.empty,\n vmax: Css.empty,\n pvw: Css.empty,\n pvh: Css.empty,\n pvi: Css.empty,\n pvb: Css.empty,\n pvmin: Css.empty,\n pvmax: Css.empty,\n cm: Css.empty,\n mm: Css.empty,\n in: Css.empty,\n px: Css.empty,\n pt: Css.empty,\n pc: Css.empty,\n q: Css.empty,\n }),\n );\n this.namedValidators[\"POS_ANGLE\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n deg: Css.empty,\n grad: Css.empty,\n rad: Css.empty,\n turn: Css.empty,\n }),\n );\n this.namedValidators[\"POS_TIME\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n s: Css.empty,\n ms: Css.empty,\n }),\n );\n this.namedValidators[\"FREQUENCY\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n Hz: Css.empty,\n kHz: Css.empty,\n }),\n );\n this.namedValidators[\"RESOLUTION\"] = this.primitive(\n new PrimitiveValidator(ALLOW_POS_NUMERIC, NO_IDENTS, {\n dpi: Css.empty,\n dpcm: Css.empty,\n dppx: Css.empty,\n }),\n );\n this.namedValidators[\"URI\"] = this.primitive(\n new PrimitiveValidator(ALLOW_URL, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"IDENT\"] = this.primitive(\n new PrimitiveValidator(ALLOW_IDENT, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"STRING\"] = this.primitive(\n new PrimitiveValidator(ALLOW_STR, NO_IDENTS, NO_IDENTS),\n );\n this.namedValidators[\"SLASH\"] = this.primitive(\n new PrimitiveValidator(ALLOW_SLASH, NO_IDENTS, NO_IDENTS),\n );\n const stdfont = { \"font-family\": Css.getName(\"sans-serif\") };\n this.systemFonts[\"caption\"] = stdfont;\n this.systemFonts[\"icon\"] = stdfont;\n this.systemFonts[\"menu\"] = stdfont;\n this.systemFonts[\"message-box\"] = stdfont;\n this.systemFonts[\"small-caption\"] = stdfont;\n this.systemFonts[\"status-bar\"] = stdfont;\n }\n\n private isBuiltIn(name: string): boolean {\n return !!name.match(/^[A-Z_0-9]+$/);\n }\n\n private readNameAndPrefixes(\n tok: CssTokenizer.Tokenizer,\n section: number,\n ): string | null {\n let token = tok.token();\n if (token.type == CssTokenizer.TokenType.EOF) {\n // Finished normally\n return null;\n }\n const rulePrefixes: { [key: string]: boolean } = { \"\": true };\n if (token.type == CssTokenizer.TokenType.O_BRK) {\n do {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.IDENT) {\n throw new Error(\"Prefix name expected\");\n }\n rulePrefixes[token.text] = true;\n tok.consume();\n token = tok.token();\n } while (token.type == CssTokenizer.TokenType.COMMA);\n if (token.type != CssTokenizer.TokenType.C_BRK) {\n throw new Error(\"']' expected\");\n }\n tok.consume();\n token = tok.token();\n }\n if (token.type != CssTokenizer.TokenType.IDENT) {\n throw new Error(\"Property name expected\");\n }\n if (section == 2 ? token.text == \"SHORTHANDS\" : token.text == \"DEFAULTS\") {\n tok.consume();\n return null;\n }\n const name = token.text;\n tok.consume();\n if (section != 2) {\n if (tok.token().type != CssTokenizer.TokenType.EQ) {\n throw new Error(\"'=' expected\");\n }\n if (!this.isBuiltIn(name)) {\n this.prefixes[name] = rulePrefixes;\n }\n } else {\n if (tok.token().type != CssTokenizer.TokenType.COLON) {\n throw new Error(\"':' expected\");\n }\n }\n return name;\n }\n\n private parseValidators(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const ruleName = this.readNameAndPrefixes(tok, 1);\n if (!ruleName) {\n return;\n }\n let vals: ValidatingGroup[] = [];\n const stack = [];\n let op = \"\";\n let val: ValidatingGroup;\n let expectval = true;\n const self = this;\n const reduce = (): ValidatingGroup => {\n if (vals.length == 0) {\n throw new Error(\"No values\");\n }\n if (vals.length == 1) {\n return vals[0];\n }\n return self.newGroup(op, vals);\n };\n const setop = (currop: string): void => {\n if (expectval) {\n throw new Error(`'${currop}': unexpected`);\n }\n if (op && op != currop) {\n throw new Error(`mixed operators: '${currop}' and '${op}'`);\n }\n op = currop;\n expectval = true;\n };\n let result: ValidatingGroup = null;\n while (!result) {\n tok.consume();\n let token = tok.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n if (!expectval) {\n setop(\" \");\n }\n if (this.isBuiltIn(token.text)) {\n const builtIn = this.namedValidators[token.text];\n if (!builtIn) {\n throw new Error(`'${token.text}' unexpected`);\n }\n vals.push(builtIn.clone());\n } else {\n const idents = {};\n idents[token.text.toLowerCase()] = Css.getName(token.text);\n vals.push(\n this.primitive(new PrimitiveValidator(0, idents, NO_IDENTS)),\n );\n }\n expectval = false;\n break;\n case CssTokenizer.TokenType.INT: {\n const idents = {};\n idents[`${token.num}`] = new Css.Int(token.num);\n vals.push(\n this.primitive(new PrimitiveValidator(0, idents, NO_IDENTS)),\n );\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.BAR:\n setop(\"|\");\n break;\n case CssTokenizer.TokenType.BAR_BAR:\n setop(\"||\");\n break;\n case CssTokenizer.TokenType.O_BRK:\n if (!expectval) {\n setop(\" \");\n }\n stack.push({ vals, op, b: \"[\" });\n op = \"\";\n vals = [];\n expectval = true;\n break;\n case CssTokenizer.TokenType.FUNC:\n if (!expectval) {\n setop(\" \");\n }\n stack.push({ vals, op, b: \"(\", fn: token.text });\n op = \"\";\n vals = [];\n expectval = true;\n break;\n case CssTokenizer.TokenType.C_BRK: {\n val = reduce();\n const open = stack.pop();\n if (open.b != \"[\") {\n throw new Error(\"']' unexpected\");\n }\n vals = open.vals;\n vals.push(val);\n op = open.op;\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.C_PAR: {\n val = reduce();\n const open = stack.pop();\n if (open.b != \"(\") {\n throw new Error(\"')' unexpected\");\n }\n vals = open.vals;\n vals.push(this.newFunc(open.fn, val));\n op = open.op;\n expectval = false;\n break;\n }\n case CssTokenizer.TokenType.COLON:\n if (expectval) {\n throw new Error(\"':' unexpected\");\n }\n tok.consume();\n vals.push(this.addReplacement(vals.pop(), tok.token()));\n break;\n case CssTokenizer.TokenType.QMARK:\n if (expectval) {\n throw new Error(\"'?' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 0, 1));\n break;\n case CssTokenizer.TokenType.STAR:\n if (expectval) {\n throw new Error(\"'*' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 0, Number.POSITIVE_INFINITY));\n break;\n case CssTokenizer.TokenType.PLUS:\n if (expectval) {\n throw new Error(\"'+' unexpected\");\n }\n vals.push(this.addCounts(vals.pop(), 1, Number.POSITIVE_INFINITY));\n break;\n case CssTokenizer.TokenType.O_BRC: {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.INT) {\n throw new Error(\"<int> expected\");\n }\n const min = token.num;\n let max = min;\n tok.consume();\n token = tok.token();\n if (token.type == CssTokenizer.TokenType.COMMA) {\n tok.consume();\n token = tok.token();\n if (token.type != CssTokenizer.TokenType.INT) {\n throw new Error(\"<int> expected\");\n }\n max = token.num;\n tok.consume();\n token = tok.token();\n }\n if (token.type != CssTokenizer.TokenType.C_BRC) {\n throw new Error(\"'}' expected\");\n }\n vals.push(this.addCounts(vals.pop(), min, max));\n break;\n }\n case CssTokenizer.TokenType.SEMICOL:\n result = reduce();\n if (stack.length > 0) {\n throw new Error(`unclosed '${stack.pop().b}'`);\n }\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n tok.consume();\n if (this.isBuiltIn(ruleName)) {\n this.namedValidators[ruleName] = result;\n } else {\n if (result.isSimple()) {\n this.validators[ruleName] = result.nodes[0].validator;\n } else {\n this.validators[ruleName] = new SpaceListValidator(result);\n }\n }\n }\n }\n\n private parseDefaults(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const propName = this.readNameAndPrefixes(tok, 2);\n if (!propName) {\n return;\n }\n const vals: Css.Val[] = [];\n while (true) {\n tok.consume();\n const token = tok.token();\n if (token.type == CssTokenizer.TokenType.SEMICOL) {\n tok.consume();\n break;\n }\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n vals.push(Css.getName(token.text));\n break;\n case CssTokenizer.TokenType.NUM:\n vals.push(new Css.Num(token.num));\n break;\n case CssTokenizer.TokenType.INT:\n vals.push(new Css.Int(token.num));\n break;\n case CssTokenizer.TokenType.NUMERIC:\n vals.push(new Css.Numeric(token.num, token.text));\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n this.defaultValues[propName] =\n vals.length > 1 ? new Css.SpaceList(vals) : vals[0];\n }\n }\n\n private parseShorthands(tok: CssTokenizer.Tokenizer): void {\n while (true) {\n const ruleName = this.readNameAndPrefixes(tok, 3);\n if (!ruleName) {\n return;\n }\n let token = tok.nthToken(1);\n let shorthandValidator: ShorthandValidator;\n if (\n token.type == CssTokenizer.TokenType.IDENT &&\n shorthandValidators[token.text]\n ) {\n shorthandValidator = new shorthandValidators[token.text]();\n tok.consume();\n } else {\n shorthandValidator = new SimpleShorthandValidator();\n }\n shorthandValidator.setOwner(this);\n let result = false;\n let syntax: ShorthandSyntaxNode[] = [];\n let slash = false;\n const stack = [];\n const propList = [];\n while (!result) {\n tok.consume();\n token = tok.token();\n switch (token.type) {\n case CssTokenizer.TokenType.IDENT:\n if (this.validators[token.text]) {\n syntax.push(shorthandValidator.syntaxNodeForProperty(token.text));\n propList.push(token.text);\n } else if (\n this.shorthands[token.text] instanceof InsetsShorthandValidator\n ) {\n const insetShorthand = this.shorthands[\n token.text\n ] as InsetsShorthandValidator;\n syntax.push(insetShorthand.createSyntaxNode());\n propList.push(...insetShorthand.propList);\n } else {\n throw new Error(\n `'${token.text}' is neither a simple property nor an inset shorthand`,\n );\n }\n break;\n case CssTokenizer.TokenType.SLASH:\n if (syntax.length > 0 || slash) {\n throw new Error(\"unexpected slash\");\n }\n slash = true;\n break;\n case CssTokenizer.TokenType.O_BRK:\n stack.push({ slash, syntax });\n syntax = [];\n slash = false;\n break;\n case CssTokenizer.TokenType.C_BRK: {\n const compound = new ShorthandSyntaxCompound(syntax, slash);\n const item = stack.pop();\n syntax = item.syntax;\n slash = item.slash;\n syntax.push(compound);\n break;\n }\n case CssTokenizer.TokenType.SEMICOL:\n result = true;\n tok.consume();\n break;\n default:\n throw new Error(\"unexpected token\");\n }\n }\n shorthandValidator.init(syntax, propList);\n this.shorthands[ruleName] = shorthandValidator;\n }\n }\n\n parse(text: string): void {\n // Not as robust as CSS parser.\n const tok = new CssTokenizer.Tokenizer(text, null);\n this.parseValidators(tok);\n this.parseDefaults(tok);\n this.parseShorthands(tok);\n this.backgroundProps = this.makePropSet([\"background\"]);\n this.layoutProps = this.makePropSet([\n \"margin\",\n \"border\",\n \"padding\",\n \"columns\",\n \"column-gap\",\n \"column-rule\",\n \"column-fill\",\n ]);\n }\n\n makePropSet(propList: string[]): ValueMap {\n const map: ValueMap = {};\n for (const prop of propList) {\n const shorthand = this.shorthands[prop];\n const list = shorthand ? shorthand.propList : [prop];\n for (const pname of list) {\n const pval = this.defaultValues[pname];\n if (!pval) {\n Logging.logger.warn(\"Unknown property in makePropSet:\", pname);\n } else {\n map[pname] = pval;\n }\n }\n }\n return map;\n }\n\n validatePropertyAndHandleShorthand(\n name: string,\n value: Css.Val,\n important: boolean,\n receiver: PropertyReceiver,\n ): void {\n let prefix = \"\";\n const origName = name;\n name = name.toLowerCase();\n const r = name.match(/^-([a-z]+)-([-a-z0-9]+)$/);\n if (r) {\n prefix = r[1];\n name = r[2];\n }\n const px = this.prefixes[name];\n if (!px || !px[prefix]) {\n receiver.unknownProperty(origName, value);\n return;\n }\n const validator = this.validators[name];\n if (validator) {\n const rvalue =\n value === Css.ident.inherit || value.isExpr()\n ? value\n : value.visit(validator);\n if (rvalue) {\n receiver.simpleProperty(name, rvalue, important);\n } else {\n receiver.invalidPropertyValue(origName, value);\n }\n } else {\n const shorthand = this.shorthands[name].clone();\n if (value === Css.ident.inherit) {\n shorthand.propagateInherit(important, receiver);\n } else {\n value.visit(shorthand);\n if (!shorthand.finish(important, receiver)) {\n receiver.invalidPropertyValue(origName, value);\n }\n }\n }\n }\n}\n\nexport function baseValidatorSet(): ValidatorSet {\n const validatorSet = new ValidatorSet();\n validatorSet.initBuiltInValidators();\n validatorSet.parse(ValidationTxt);\n return validatorSet;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Font - Deal with embedded fonts.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as Exprs from \"./exprs\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\n\nexport const traitProps: { [key: string]: Css.Val } = {\n \"font-style\": Css.ident.normal,\n \"font-variant\": Css.ident.normal,\n \"font-weight\": Css.ident.normal,\n};\n\nexport const bogusFontData = `OTTO${new Date().valueOf()}`;\n\nexport let bogusFontCounter: number = 1;\n\nexport function makeFontTraitKey(properties: {\n [key: string]: Css.Val;\n}): string {\n const sb = new Base.StringBuffer();\n for (const prop in traitProps) {\n sb.append(\" \");\n sb.append(properties[prop].toString());\n }\n return sb.toString();\n}\n\nexport function fillDefaults(properties: { [key: string]: Css.Val }): void {\n for (const prop in traitProps) {\n if (!properties[prop]) {\n properties[prop] = traitProps[prop];\n }\n }\n}\n\nexport function prepareProperties(\n properties: CssCascade.ElementStyle,\n context: Exprs.Context,\n): { [key: string]: Css.Val } {\n const result = {} as { [key: string]: Css.Val };\n for (const prop in properties) {\n result[prop] = CssCascade.getProp(properties, prop).evaluate(context, prop);\n }\n fillDefaults(result);\n return result;\n}\n\n/**\n * A font declared in a font-face rule.\n */\nexport class Face {\n fontTraitKey: string;\n src: string | null;\n blobURLs: string[] = [];\n blobs: Blob[] = [];\n family: string | null;\n\n constructor(public readonly properties: { [key: string]: Css.Val }) {\n this.fontTraitKey = makeFontTraitKey(this.properties);\n this.src = this.properties[\"src\"]\n ? this.properties[\"src\"].toString()\n : null;\n const family = this.properties[\"font-family\"];\n this.family = family ? family.stringValue() : null;\n }\n\n /**\n * Check if font traits are the same for two font faces\n */\n traitsEqual(other: Face): boolean {\n return this.fontTraitKey == other.fontTraitKey;\n }\n\n /**\n * Create \"at\" font-face rule.\n */\n makeAtRule(src: string, fontBytes: Blob): string {\n const sb = new Base.StringBuffer();\n sb.append(\"@font-face {\\n font-family: \");\n sb.append(this.family as string);\n sb.append(\";\\n \");\n for (const prop in traitProps) {\n sb.append(prop);\n sb.append(\": \");\n this.properties[prop].appendTo(sb, true);\n sb.append(\";\\n \");\n }\n if (fontBytes) {\n sb.append('src: url(\"');\n const blobURL = Net.createObjectURL(fontBytes);\n sb.append(blobURL);\n this.blobURLs.push(blobURL);\n this.blobs.push(fontBytes);\n sb.append('\")');\n } else {\n sb.append(\"src: \");\n sb.append(src);\n }\n sb.append(\";\\n}\\n\");\n return sb.toString();\n }\n}\n\n/**\n * Set of the fonts declared in all stylesheets of a document.\n * @param deobfuscator function\n * that takes url and returns data deobfuscator\n */\nexport class DocumentFaces {\n /**\n * Maps source font family names to the family names used in the HTML view.\n */\n familyMap = {} as { [key: string]: string };\n\n constructor(\n public readonly deobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null,\n ) {}\n\n registerFamily(srcFace: Face, viewFace: Face): void {\n const srcFamily = srcFace.family as string;\n const viewFamilyFromSrc = this.familyMap[srcFamily];\n const viewFamilyFromView = viewFace.family;\n if (viewFamilyFromSrc) {\n if (viewFamilyFromSrc != viewFamilyFromView) {\n throw new Error(`E_FONT_FAMILY_INCONSISTENT ${srcFace.family}`);\n }\n } else {\n this.familyMap[srcFamily] = viewFamilyFromView as string;\n }\n }\n\n filterFontFamily(val: Css.Val): Css.Val {\n if (val instanceof Css.CommaList) {\n const list = (val as Css.CommaList).values;\n const newValues = [] as Css.Val[];\n for (const v of list) {\n const r = this.familyMap[v.stringValue()];\n if (r) {\n newValues.push(Css.getName(r));\n }\n newValues.push(v);\n }\n return new Css.CommaList(newValues);\n } else {\n const rf = this.familyMap[val.stringValue()];\n if (rf) {\n return new Css.CommaList([Css.getName(rf), val]);\n }\n return val;\n }\n }\n}\n\n/**\n * Object that loads fonts in a document and allocates font families for them\n * in the view document\n * @param head where to add styles in the view document (normally head element)\n * @param body where to probe text in the view document (normally body element)\n */\nexport class Mapper {\n /**\n * Maps Face.src to an entry for an already-loaded font.\n */\n srcURLMap: { [key: string]: TaskUtil.Fetcher<Face> } = {};\n familyPrefix: string;\n familyCounter: number = 0;\n\n constructor(\n public readonly head: Element,\n public readonly body: Element,\n opt_familyPrefix?: string,\n ) {\n this.familyPrefix = opt_familyPrefix || \"Fnt_\";\n }\n\n getViewFontFamily(srcFace: Face, documentFaces: DocumentFaces): string {\n const srcFamily = srcFace.family as string;\n let viewFamily = documentFaces.familyMap[srcFamily];\n if (viewFamily) {\n return viewFamily;\n }\n viewFamily = this.familyPrefix + ++this.familyCounter;\n documentFaces.familyMap[srcFamily] = viewFamily;\n return viewFamily;\n }\n\n /**\n * @param fontBytes deobfuscated font bytes (if deobfuscation is needed)\n */\n private initFont(\n srcFace: Face,\n fontBytes: Blob,\n documentFaces: DocumentFaces,\n ): Task.Result<Face> {\n const frame: Task.Frame<Face> = Task.newFrame(\"initFont\");\n const self = this;\n const src = srcFace.src as string;\n const props = {} as { [key: string]: Css.Val };\n for (const prop in traitProps) {\n props[prop] = srcFace.properties[prop];\n }\n const fontFamily = self.getViewFontFamily(srcFace, documentFaces);\n props[\"font-family\"] = Css.getName(fontFamily);\n const viewFontFace = new Face(props);\n const probe = self.body.ownerDocument.createElement(\"span\") as HTMLElement;\n probe.textContent = \"M\";\n const killTime = new Date().valueOf() + 1000;\n const style = self.head.ownerDocument.createElement(\"style\");\n const bogusData = bogusFontData + bogusFontCounter++;\n style.textContent = viewFontFace.makeAtRule(\"\", Net.makeBlob([bogusData]));\n self.head.appendChild(style);\n self.body.appendChild(probe);\n probe.style.visibility = \"hidden\";\n probe.style.fontFamily = fontFamily;\n for (const pname in traitProps) {\n Base.setCSSProperty(probe, pname, props[pname].toString());\n }\n const rect = probe.getBoundingClientRect();\n const initWidth = rect.right - rect.left;\n const initHeight = rect.bottom - rect.top;\n style.textContent = viewFontFace.makeAtRule(src, fontBytes);\n Logging.logger.info(\"Starting to load font:\", src);\n let loaded = false;\n frame\n .loop(() => {\n const rect = probe.getBoundingClientRect();\n const currWidth = rect.right - rect.left;\n const currHeight = rect.bottom - rect.top;\n if (initWidth != currWidth || initHeight != currHeight) {\n loaded = true;\n return Task.newResult(false);\n }\n const currTime = new Date().valueOf();\n if (currTime > killTime) {\n return Task.newResult(false);\n }\n return frame.sleep(10);\n })\n .then(() => {\n if (loaded) {\n Logging.logger.info(\"Loaded font:\", src);\n } else {\n Logging.logger.warn(\"Failed to load font:\", src);\n }\n self.body.removeChild(probe);\n frame.finish(viewFontFace);\n });\n return frame.result();\n }\n\n loadFont(\n srcFace: Face,\n documentFaces: DocumentFaces,\n ): TaskUtil.Fetcher<Face> {\n const src = srcFace.src as string;\n let fetcher = this.srcURLMap[src];\n const self = this;\n if (fetcher) {\n fetcher.piggyback((viewFaceParam) => {\n const viewFace = viewFaceParam as Face;\n if (!viewFace.traitsEqual(srcFace)) {\n Logging.logger.warn(\"E_FONT_FACE_INCOMPATIBLE\", srcFace.src);\n } else {\n documentFaces.registerFamily(srcFace, viewFace);\n Logging.logger.warn(\"Found already-loaded font:\", src);\n }\n });\n } else {\n fetcher = new TaskUtil.Fetcher(() => {\n const frame: Task.Frame<Face> = Task.newFrame(\"loadFont\");\n const deobfuscator = documentFaces.deobfuscator\n ? documentFaces.deobfuscator(src)\n : null;\n if (deobfuscator) {\n Net.ajax(src, Net.XMLHttpRequestResponseType.BLOB).then((xhr) => {\n if (!xhr.responseBlob) {\n frame.finish(null);\n return;\n }\n deobfuscator(xhr.responseBlob).then((fontBytes) => {\n self\n .initFont(srcFace, fontBytes, documentFaces)\n .thenFinish(frame);\n });\n });\n } else {\n self.initFont(srcFace, null, documentFaces).thenFinish(frame);\n }\n return frame.result();\n }, `loadFont ${src}`);\n this.srcURLMap[src] = fetcher;\n fetcher.start();\n }\n return fetcher;\n }\n\n findOrLoadFonts(\n srcFaces: Face[],\n documentFaces: DocumentFaces,\n ): Task.Result<boolean> {\n const fetchers = [] as TaskUtil.Fetcher<Face>[];\n for (const srcFace of srcFaces) {\n if (!srcFace.src || !srcFace.family) {\n Logging.logger.warn(\"E_FONT_FACE_INVALID\");\n continue;\n }\n fetchers.push(this.loadFont(srcFace, documentFaces));\n }\n return TaskUtil.waitForFetchers(fetchers);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview PageMaster - Deal with page masters, partition groups, and partitions.\n */\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Vtree from \"./vtree\";\n\nexport let keyCount: number = 1;\n\n/**\n * Represent an at-rule which creates a page-level CSS box (page-master,\n * partition, and partition-group).\n */\nexport abstract class PageBox<\n I extends PageBoxInstance = PageBoxInstance<any>\n> {\n // styles specified in the at-rule\n specified: CssCascade.ElementStyle = {};\n children: PageBox[] = [];\n pageMaster: PageMaster = null;\n index: number = 0;\n key: string;\n\n protected _scope: Exprs.LexicalScope;\n\n get scope(): Exprs.LexicalScope {\n return this._scope;\n }\n\n constructor(\n scope: Exprs.LexicalScope,\n public readonly name: string | null,\n public readonly pseudoName: string | null,\n public readonly classes: string[],\n public readonly parent: PageBox,\n ) {\n this._scope = scope;\n this.key = `p${keyCount++}`;\n if (parent) {\n this.index = parent.children.length;\n parent.children.push(this);\n }\n }\n\n createInstance(parentInstance: PageBoxInstance): PageBoxInstance {\n throw new Error(\"E_UNEXPECTED_CALL\");\n }\n\n /**\n * Clone the PageBox.\n * @param param parent: The parent of the cloned PageBox.\n * pseudoName: Assign this value as the pseudoName of the cloned PageBox.\n */\n clone(param: { parent?: PageBox; pseudoName?: string }): PageBox<I> {\n throw new Error(\"E_UNEXPECTED_CALL\");\n }\n\n /**\n * Copy 'specified' properties to another instance.\n * @param dest The PageBox into which 'specified' properties are copied\n */\n protected copySpecified(dest: PageBox) {\n const specified = this.specified;\n const destSpecified = dest.specified;\n for (const prop in specified) {\n if (Object.prototype.hasOwnProperty.call(specified, prop)) {\n destSpecified[prop] = specified[prop];\n }\n }\n }\n\n /**\n * Clone children with the specified PageBox as their parent.\n */\n protected cloneChildren(parent: PageBox) {\n for (let i = 0; i < this.children.length; i++) {\n // the cloned child is added to parent.children in the child constructor.\n this.children[i].clone({ parent });\n }\n }\n}\n\n/**\n * Parent of all page masters\n */\nexport class RootPageBox extends PageBox<RootPageBoxInstance> {\n constructor(scope: Exprs.LexicalScope) {\n super(scope, null, null, [], null);\n this.specified[\"width\"] = new CssCascade.CascadeValue(Css.fullWidth, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(Css.fullHeight, 0);\n }\n}\n\nexport class PageMasterScope extends Exprs.LexicalScope {\n constructor(scope: Exprs.LexicalScope, public pageMaster: PageMaster) {\n super(scope, resolver);\n const self = this;\n function resolver(qualifiedName, isFunc) {\n const r = qualifiedName.match(/^([^.]+)\\.([^.]+)$/);\n if (r) {\n const key = self.pageMaster.keyMap[r[1]];\n if (key) {\n const holder = this as InstanceHolder;\n const boxInstance = holder.lookupInstance(key);\n if (boxInstance) {\n if (isFunc) {\n return boxInstance.resolveFunc(r[2]);\n } else {\n return boxInstance.resolveName(r[2]);\n }\n }\n }\n }\n return null;\n }\n }\n}\n\n/**\n * Represent a page-master rule\n */\nexport class PageMaster<\n I extends PageMasterInstance = PageMasterInstance<any>\n> extends PageBox<I> {\n pageMaster: PageMaster;\n keyMap: { [key: string]: string } = {};\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: RootPageBox,\n public readonly condition: Exprs.Val,\n public readonly specificity: number,\n ) {\n super(scope, name, pseudoName, classes, parent);\n // if PageMasterScope object is passed, use (share) it.\n if (!(scope instanceof PageMasterScope)) {\n this._scope = new PageMasterScope(scope, this);\n }\n this.pageMaster = this;\n this.specified[\"width\"] = new CssCascade.CascadeValue(Css.fullWidth, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(Css.fullHeight, 0);\n this.specified[\"wrap-flow\"] = new CssCascade.CascadeValue(\n Css.ident.auto,\n 0,\n );\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.relative,\n 0,\n );\n this.specified[\"overflow\"] = new CssCascade.CascadeValue(\n Css.ident.visible,\n 0,\n );\n\n // Shift 1px to workaround Chrome printing bug\n // this.specified[\"top\"] = new CssCascade.CascadeValue(new Css.Numeric(-1, \"px\"), 0);\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageBoxInstance {\n return new PageMasterInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): PageMaster {\n // The cloned page master shares the same scope object with the original\n // one.\n const cloned = new PageMaster(\n this.scope,\n this.name,\n param.pseudoName || this.pseudoName,\n this.classes,\n this.parent as RootPageBox,\n this.condition,\n this.specificity,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n\n /**\n * Point the pageMaster reference in the PageMasterScope to the current page\n * master. This is needed when a page master is cloned and shares a common\n * scope with the original page master. Since every Exprs.Val which the\n * page master holds has a reference to the scope and uses it for variable\n * resolution, this reference must be updated properly before the page master\n * instance is used.\n */\n resetScope() {\n (this.scope as any).pageMaster = this;\n }\n}\n\n/**\n * Represent a partition-group rule\n */\nexport class PartitionGroup extends PageBox<PartitionGroupInstance> {\n pageMaster: PageMaster;\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: PageBox,\n ) {\n super(scope, name, pseudoName, classes, parent);\n this.pageMaster = parent.pageMaster;\n if (name) {\n this.pageMaster.keyMap[name] = this.key;\n }\n this.specified[\"wrap-flow\"] = new CssCascade.CascadeValue(\n Css.ident.auto,\n 0,\n );\n }\n\n /**\n * @override\n */\n createInstance(parentInstance: PageBoxInstance): PageBoxInstance {\n return new PartitionGroupInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): PartitionGroup {\n const cloned = new PartitionGroup(\n param.parent.scope,\n this.name,\n this.pseudoName,\n this.classes,\n param.parent,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n}\n\n/**\n * Represent a partition rule\n */\nexport class Partition<\n I extends PartitionInstance = PartitionInstance\n> extends PageBox<I> {\n pageMaster: PageMaster;\n\n constructor(\n scope: Exprs.LexicalScope,\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n parent: PageBox,\n ) {\n super(scope, name, pseudoName, classes, parent);\n this.pageMaster = parent.pageMaster;\n if (name) {\n this.pageMaster.keyMap[name] = this.key;\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageBoxInstance {\n return new PartitionInstance(parentInstance, this);\n }\n\n /**\n * @override\n */\n clone(param): Partition {\n const cloned = new Partition(\n param.parent.scope,\n this.name,\n this.pseudoName,\n this.classes,\n param.parent,\n );\n this.copySpecified(cloned);\n this.cloneChildren(cloned);\n return cloned;\n }\n}\n\n//---------------------------- Instance --------------------------------\n\n/**\n * @param def default value\n */\nexport function toExprIdent(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n def: string,\n): Exprs.Val {\n if (!val) {\n return new Exprs.Const(scope, def);\n }\n return val.toExpr(scope, scope.zero);\n}\n\nexport function toExprAuto(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.auto) {\n return null;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprNormal(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.normal) {\n return null;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprZero(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || val === Css.ident.auto) {\n return scope.zero;\n }\n return val.toExpr(scope, ref);\n}\n\n/**\n * If the value is not specified (null), returns zero.\n * If the value is 'auto', returns null.\n * Otherwise, return the value itself.\n */\nexport function toExprZeroAuto(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val) {\n return scope.zero;\n } else if (val === Css.ident.auto) {\n return null;\n } else {\n return val.toExpr(scope, ref);\n }\n}\n\nexport function toExprZeroBorder(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n styleVal: Css.Val,\n ref: Exprs.Val,\n): Exprs.Val {\n if (!val || styleVal === Css.ident.none) {\n return scope.zero;\n }\n return val.toExpr(scope, ref);\n}\n\nexport function toExprBool(\n scope: Exprs.LexicalScope,\n val: Css.Val,\n def: Exprs.Val,\n): Exprs.Val {\n if (!val) {\n return def;\n }\n if (val === Css.ident._true) {\n return scope._true;\n }\n if (val === Css.ident._false) {\n return scope._false;\n }\n return val.toExpr(scope, scope.zero);\n}\n\nexport interface InstanceHolder extends Exprs.Context {\n registerInstance(key: string, instance: PageBoxInstance): void;\n\n /**\n * @return instance\n */\n lookupInstance(key: string): PageBoxInstance;\n}\n\nexport class PageBoxInstance<P extends PageBox = PageBox<any>> {\n /**\n * cascaded styles, geometric ones converted to Css.Expr\n */\n protected cascaded: CssCascade.ElementStyle = {};\n style: { [key: string]: Css.Val } = {};\n private autoWidth: Exprs.Native = null;\n private autoHeight: Exprs.Native = null;\n children: PageBoxInstance[] = [];\n isAutoWidth: boolean = false;\n isAutoHeight: boolean = false;\n isTopDependentOnAutoHeight: boolean = false;\n isRightDependentOnAutoWidth: boolean = false;\n private calculatedWidth: number = 0;\n private calculatedHeight: number = 0;\n pageMasterInstance: PageMasterInstance = null;\n namedValues: { [key: string]: Exprs.Val } = {};\n namedFuncs: { [key: string]: Exprs.Val } = {};\n vertical: boolean = false;\n rtl: boolean = false;\n suppressEmptyBoxGeneration: boolean = false;\n\n constructor(\n public readonly parentInstance: PageBoxInstance,\n public readonly pageBox: P,\n ) {\n if (parentInstance) {\n parentInstance.children.push(this);\n }\n }\n\n /**\n * Reset information related to layout.\n */\n reset() {\n this.calculatedWidth = 0;\n this.calculatedHeight = 0;\n }\n\n private addNamedValues(name1: string, name2: string): Exprs.Val {\n const v1 = this.resolveName(name1);\n const v2 = this.resolveName(name2);\n if (!v1 || !v2) {\n throw new Error(\"E_INTERNAL\");\n }\n return Exprs.add(this.pageBox.scope, v1, v2);\n }\n\n resolveName(name: string): Exprs.Val {\n let expr = this.namedValues[name];\n if (expr) {\n return expr;\n }\n const val = this.style[name];\n if (val) {\n expr = val.toExpr(this.pageBox.scope, this.pageBox.scope.zero);\n }\n switch (name) {\n case \"margin-left-edge\":\n expr = this.resolveName(\"left\");\n break;\n case \"margin-top-edge\":\n expr = this.resolveName(\"top\");\n break;\n case \"margin-right-edge\":\n expr = this.addNamedValues(\"border-right-edge\", \"margin-right\");\n break;\n case \"margin-bottom-edge\":\n expr = this.addNamedValues(\"border-bottom-edge\", \"margin-bottom\");\n break;\n case \"border-left-edge\":\n expr = this.addNamedValues(\"margin-left-edge\", \"margin-left\");\n break;\n case \"border-top-edge\":\n expr = this.addNamedValues(\"margin-top-edge\", \"margin-top\");\n break;\n case \"border-right-edge\":\n expr = this.addNamedValues(\"padding-right-edge\", \"border-right-width\");\n break;\n case \"border-bottom-edge\":\n expr = this.addNamedValues(\n \"padding-bottom-edge\",\n \"border-bottom-width\",\n );\n break;\n case \"padding-left-edge\":\n expr = this.addNamedValues(\"border-left-edge\", \"border-left-width\");\n break;\n case \"padding-top-edge\":\n expr = this.addNamedValues(\"border-top-edge\", \"border-top-width\");\n break;\n case \"padding-right-edge\":\n expr = this.addNamedValues(\"right-edge\", \"padding-right\");\n break;\n case \"padding-bottom-edge\":\n expr = this.addNamedValues(\"bottom-edge\", \"padding-bottom\");\n break;\n case \"left-edge\":\n expr = this.addNamedValues(\"padding-left-edge\", \"padding-left\");\n break;\n case \"top-edge\":\n expr = this.addNamedValues(\"padding-top-edge\", \"padding-top\");\n break;\n case \"right-edge\":\n expr = this.addNamedValues(\"left-edge\", \"width\");\n break;\n case \"bottom-edge\":\n expr = this.addNamedValues(\"top-edge\", \"height\");\n break;\n }\n if (!expr) {\n let altName: string;\n if (name == \"extent\") {\n altName = this.vertical ? \"width\" : \"height\";\n } else if (name == \"measure\") {\n altName = this.vertical ? \"height\" : \"width\";\n } else {\n const map = this.vertical\n ? CssCascade.couplingMapVert\n : CssCascade.couplingMapHor;\n altName = name;\n for (const key in map) {\n altName = altName.replace(key, map[key]);\n }\n }\n if (altName != name) {\n expr = this.resolveName(altName);\n }\n }\n if (expr) {\n this.namedValues[name] = expr;\n }\n return expr;\n }\n\n resolveFunc(name) {\n let expr = this.namedFuncs[name];\n if (expr) {\n return expr;\n }\n switch (name) {\n case \"columns\": {\n // min(count,column-count) * (column-width + column-gap) - column-gap\n const scope = this.pageBox.scope;\n const count = new Exprs.Param(scope, 0);\n const columnCount = this.resolveName(\"column-count\");\n const columnWidth = this.resolveName(\"column-width\");\n const columnGap = this.resolveName(\"column-gap\");\n expr = Exprs.sub(\n scope,\n Exprs.mul(\n scope,\n new Exprs.Call(scope, \"min\", [count, columnCount]),\n Exprs.add(scope, columnWidth, columnGap),\n ),\n columnGap,\n );\n break;\n }\n }\n if (expr) {\n this.namedFuncs[name] = expr;\n }\n return expr;\n }\n\n private initEnabled(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n let enabled = toExprBool(scope, style[\"enabled\"], scope._true);\n const page = toExprAuto(scope, style[\"page\"], scope.zero);\n if (page) {\n const currentPage = new Exprs.Named(scope, \"page-number\");\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Eq(scope, page, currentPage),\n );\n }\n const minPageWidth = toExprAuto(scope, style[\"min-page-width\"], scope.zero);\n if (minPageWidth) {\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Ge(scope, new Exprs.Named(scope, \"page-width\"), minPageWidth),\n );\n }\n const minPageHeight = toExprAuto(\n scope,\n style[\"min-page-height\"],\n scope.zero,\n );\n if (minPageHeight) {\n enabled = Exprs.and(\n scope,\n enabled,\n new Exprs.Ge(\n scope,\n new Exprs.Named(scope, \"page-height\"),\n minPageHeight,\n ),\n );\n }\n enabled = this.boxSpecificEnabled(enabled);\n style[\"enabled\"] = new Css.Expr(enabled);\n }\n\n protected boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n return enabled;\n }\n\n protected initHorizontal(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const parentWidth = this.parentInstance\n ? this.parentInstance.style[\"width\"].toExpr(scope, null)\n : null;\n let left = toExprAuto(scope, style[\"left\"], parentWidth);\n let marginLeft = toExprAuto(scope, style[\"margin-left\"], parentWidth);\n const borderLeftWidth = toExprZeroBorder(\n scope,\n style[\"border-left-width\"],\n style[\"border-left-style\"],\n parentWidth,\n );\n const paddingLeft = toExprZero(scope, style[\"padding-left\"], parentWidth);\n let width = toExprAuto(scope, style[\"width\"], parentWidth);\n let maxWidth = toExprAuto(scope, style[\"max-width\"], parentWidth);\n const paddingRight = toExprZero(scope, style[\"padding-right\"], parentWidth);\n const borderRightWidth = toExprZeroBorder(\n scope,\n style[\"border-right-width\"],\n style[\"border-right-style\"],\n parentWidth,\n );\n let marginRight = toExprAuto(scope, style[\"margin-right\"], parentWidth);\n let right = toExprAuto(scope, style[\"right\"], parentWidth);\n const leftBP = Exprs.add(scope, borderLeftWidth, paddingLeft);\n const rightBP = Exprs.add(scope, borderLeftWidth, paddingRight);\n if (left && right && width) {\n let extra = Exprs.sub(\n scope,\n parentWidth,\n Exprs.add(\n scope,\n width,\n Exprs.add(scope, Exprs.add(scope, left, leftBP), rightBP),\n ),\n );\n if (!marginLeft) {\n extra = Exprs.sub(scope, extra, right);\n if (!marginRight) {\n marginLeft = Exprs.mul(scope, extra, new Exprs.Const(scope, 0.5));\n marginRight = marginLeft;\n } else {\n marginLeft = Exprs.sub(scope, extra, marginRight);\n }\n } else {\n if (!marginRight) {\n marginRight = Exprs.sub(\n scope,\n extra,\n Exprs.add(scope, right, marginLeft),\n );\n } else {\n // overconstraint\n right = Exprs.sub(scope, extra, marginRight);\n }\n }\n } else {\n if (!marginLeft) {\n marginLeft = scope.zero;\n }\n if (!marginRight) {\n marginRight = scope.zero;\n }\n if (!left && !right && !width) {\n left = scope.zero;\n }\n if (!left && !width) {\n width = this.autoWidth;\n this.isAutoWidth = true;\n } else if (!left && !right) {\n left = scope.zero;\n } else if (!width && !right) {\n width = this.autoWidth;\n this.isAutoWidth = true;\n }\n const remains = Exprs.sub(\n scope,\n parentWidth,\n Exprs.add(\n scope,\n Exprs.add(scope, marginLeft, leftBP),\n Exprs.add(scope, marginRight, rightBP),\n ),\n );\n if (this.isAutoWidth) {\n if (!maxWidth) {\n // TODO: handle the case when right/left depends on width\n maxWidth = Exprs.sub(scope, remains, left ? left : right);\n }\n\n // For multi-column layout, width is max-width.\n if (\n !this.vertical &&\n (toExprAuto(scope, style[\"column-width\"], null) ||\n toExprAuto(scope, style[\"column-count\"], null))\n ) {\n width = maxWidth;\n this.isAutoWidth = false;\n }\n }\n if (!left) {\n left = Exprs.sub(scope, remains, Exprs.add(scope, right, width));\n } else if (!width) {\n width = Exprs.sub(scope, remains, Exprs.add(scope, left, right));\n } else if (!right) {\n right = Exprs.sub(scope, remains, Exprs.add(scope, left, width));\n }\n }\n\n // snap-width is inherited\n const snapWidthVal =\n style[\"snap-width\"] ||\n (this.parentInstance ? this.parentInstance.style[\"snap-width\"] : null);\n const snapWidth = toExprZero(scope, snapWidthVal, parentWidth);\n style[\"left\"] = new Css.Expr(left);\n style[\"margin-left\"] = new Css.Expr(marginLeft);\n style[\"border-left-width\"] = new Css.Expr(borderLeftWidth);\n style[\"padding-left\"] = new Css.Expr(paddingLeft);\n style[\"width\"] = new Css.Expr(width);\n style[\"max-width\"] = new Css.Expr(maxWidth ? maxWidth : width);\n style[\"padding-right\"] = new Css.Expr(paddingRight);\n style[\"border-right-width\"] = new Css.Expr(borderRightWidth);\n style[\"margin-right\"] = new Css.Expr(marginRight);\n style[\"right\"] = new Css.Expr(right);\n style[\"snap-width\"] = new Css.Expr(snapWidth);\n }\n\n protected initVertical(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const parentWidth = this.parentInstance\n ? this.parentInstance.style[\"width\"].toExpr(scope, null)\n : null;\n const parentHeight = this.parentInstance\n ? this.parentInstance.style[\"height\"].toExpr(scope, null)\n : null;\n let top = toExprAuto(scope, style[\"top\"], parentHeight);\n let marginTop = toExprAuto(scope, style[\"margin-top\"], parentWidth);\n const borderTopWidth = toExprZeroBorder(\n scope,\n style[\"border-top-width\"],\n style[\"border-top-style\"],\n parentWidth,\n );\n const paddingTop = toExprZero(scope, style[\"padding-top\"], parentWidth);\n let height = toExprAuto(scope, style[\"height\"], parentHeight);\n let maxHeight = toExprAuto(scope, style[\"max-height\"], parentHeight);\n const paddingBottom = toExprZero(\n scope,\n style[\"padding-bottom\"],\n parentWidth,\n );\n const borderBottomWidth = toExprZeroBorder(\n scope,\n style[\"border-bottom-width\"],\n style[\"border-bottom-style\"],\n parentWidth,\n );\n let marginBottom = toExprAuto(scope, style[\"margin-bottom\"], parentWidth);\n let bottom = toExprAuto(scope, style[\"bottom\"], parentHeight);\n const topBP = Exprs.add(scope, borderTopWidth, paddingTop);\n const bottomBP = Exprs.add(scope, borderBottomWidth, paddingBottom);\n if (top && bottom && height) {\n let extra = Exprs.sub(\n scope,\n parentHeight,\n Exprs.add(\n scope,\n height,\n Exprs.add(scope, Exprs.add(scope, top, topBP), bottomBP),\n ),\n );\n if (!marginTop) {\n extra = Exprs.sub(scope, extra, bottom);\n if (!marginBottom) {\n marginTop = Exprs.mul(scope, extra, new Exprs.Const(scope, 0.5));\n marginBottom = marginTop;\n } else {\n marginTop = Exprs.sub(scope, extra, marginBottom);\n }\n } else {\n if (!marginBottom) {\n marginBottom = Exprs.sub(\n scope,\n extra,\n Exprs.add(scope, bottom, marginTop),\n );\n } else {\n // overconstraint\n bottom = Exprs.sub(scope, extra, marginTop);\n }\n }\n } else {\n if (!marginTop) {\n marginTop = scope.zero;\n }\n if (!marginBottom) {\n marginBottom = scope.zero;\n }\n if (!top && !bottom && !height) {\n top = scope.zero;\n }\n if (!top && !height) {\n height = this.autoHeight;\n this.isAutoHeight = true;\n } else if (!top && !bottom) {\n top = scope.zero;\n } else if (!height && !bottom) {\n height = this.autoHeight;\n this.isAutoHeight = true;\n }\n const remains = Exprs.sub(\n scope,\n parentHeight,\n Exprs.add(\n scope,\n Exprs.add(scope, marginTop, topBP),\n Exprs.add(scope, marginBottom, bottomBP),\n ),\n );\n if (this.isAutoHeight) {\n if (!maxHeight) {\n // TODO: handle the case when top/bottom depends on height\n maxHeight = Exprs.sub(scope, remains, top ? top : bottom);\n }\n\n // For multi-column layout in vertical writing, height is max-height.\n if (\n this.vertical &&\n (toExprAuto(scope, style[\"column-width\"], null) ||\n toExprAuto(scope, style[\"column-count\"], null))\n ) {\n height = maxHeight;\n this.isAutoHeight = false;\n }\n }\n if (!top) {\n top = Exprs.sub(scope, remains, Exprs.add(scope, bottom, height));\n } else if (!height) {\n height = Exprs.sub(scope, remains, Exprs.add(scope, bottom, top));\n } else if (!bottom) {\n bottom = Exprs.sub(scope, remains, Exprs.add(scope, top, height));\n }\n }\n\n // snap-height is inherited\n const snapHeightVal =\n style[\"snap-height\"] ||\n (this.parentInstance ? this.parentInstance.style[\"snap-height\"] : null);\n const snapHeight = toExprZero(scope, snapHeightVal, parentWidth);\n style[\"top\"] = new Css.Expr(top);\n style[\"margin-top\"] = new Css.Expr(marginTop);\n style[\"border-top-width\"] = new Css.Expr(borderTopWidth);\n style[\"padding-top\"] = new Css.Expr(paddingTop);\n style[\"height\"] = new Css.Expr(height);\n style[\"max-height\"] = new Css.Expr(maxHeight ? maxHeight : height);\n style[\"padding-bottom\"] = new Css.Expr(paddingBottom);\n style[\"border-bottom-width\"] = new Css.Expr(borderBottomWidth);\n style[\"margin-bottom\"] = new Css.Expr(marginBottom);\n style[\"bottom\"] = new Css.Expr(bottom);\n style[\"snap-height\"] = new Css.Expr(snapHeight);\n }\n\n private initColumns(): void {\n const scope = this.pageBox.scope;\n const style = this.style;\n const width = toExprAuto(\n scope,\n style[this.vertical ? \"height\" : \"width\"],\n null,\n );\n let columnWidth = toExprAuto(scope, style[\"column-width\"], width);\n let columnCount = toExprAuto(scope, style[\"column-count\"], null);\n let columnGap = toExprNormal(scope, style[\"column-gap\"], null);\n if (!columnGap) {\n columnGap = new Exprs.Numeric(scope, 1, \"em\");\n }\n if (columnWidth && !columnCount) {\n columnCount = new Exprs.Call(scope, \"floor\", [\n Exprs.div(\n scope,\n Exprs.add(scope, width, columnGap),\n Exprs.add(scope, columnWidth, columnGap),\n ),\n ]);\n columnCount = new Exprs.Call(scope, \"max\", [scope.one, columnCount]);\n }\n if (!columnCount) {\n columnCount = scope.one;\n }\n columnWidth = Exprs.sub(\n scope,\n Exprs.div(scope, Exprs.add(scope, width, columnGap), columnCount),\n columnGap,\n );\n style[\"column-width\"] = new Css.Expr(columnWidth);\n style[\"column-count\"] = new Css.Expr(columnCount);\n style[\"column-gap\"] = new Css.Expr(columnGap);\n }\n\n private depends(\n propName: string,\n val: Exprs.Val,\n context: Exprs.Context,\n ): boolean {\n return this.style[propName]\n .toExpr(this.pageBox.scope, null)\n .depend(val, context);\n }\n\n private init(context: Exprs.Context): void {\n // If context does not implement InstanceHolder we would not be able to\n // resolve \"partition.property\" names later.\n const holder = context as InstanceHolder;\n holder.registerInstance(this.pageBox.key, this);\n const scope = this.pageBox.scope;\n const style = this.style;\n const self = this;\n const regionIds = this.parentInstance\n ? this.parentInstance.getActiveRegions(context)\n : null;\n const cascMap = CssCascade.flattenCascadedStyle(\n this.cascaded,\n context,\n regionIds,\n false,\n null,\n );\n this.vertical = CssCascade.isVertical(\n cascMap,\n context,\n this.parentInstance ? this.parentInstance.vertical : false,\n );\n this.rtl = CssCascade.isRtl(\n cascMap,\n context,\n this.parentInstance ? this.parentInstance.rtl : false,\n );\n CssCascade.convertToPhysical(\n cascMap,\n style,\n this.vertical,\n this.rtl,\n (name, cascVal) => cascVal.value,\n );\n this.autoWidth = new Exprs.Native(\n scope,\n () => self.calculatedWidth,\n \"autoWidth\",\n );\n this.autoHeight = new Exprs.Native(\n scope,\n () => self.calculatedHeight,\n \"autoHeight\",\n );\n this.initHorizontal();\n this.initVertical();\n this.initColumns();\n this.initEnabled();\n }\n\n getProp(context: Exprs.Context, name: string): Css.Val {\n let val = this.style[name];\n if (val) {\n val = CssParser.evaluateCSSToCSS(context, val, name);\n }\n return val;\n }\n\n getPropAsNumber(context: Exprs.Context, name: string): number {\n let val = this.style[name];\n if (val) {\n val = CssParser.evaluateCSSToCSS(context, val, name);\n }\n return Css.toNumber(val, context);\n }\n\n getSpecial(context: Exprs.Context, name: string): Css.Val[] {\n const arr = CssCascade.getSpecial(this.cascaded, name);\n if (arr) {\n const result = [] as Css.Val[];\n for (let i = 0; i < arr.length; i++) {\n const v = arr[i].evaluate(context, \"\");\n if (v && v !== Css.empty) {\n result.push(v);\n }\n }\n if (result.length) {\n return result;\n }\n }\n return null;\n }\n\n getActiveRegions(context: Exprs.Context): string[] {\n const arr = this.getSpecial(context, \"region-id\");\n if (arr) {\n const result = [] as string[];\n for (let i = 0; i < arr.length; i++) {\n result[i] = arr[i].toString();\n }\n return result;\n }\n return null;\n }\n\n propagateProperty(\n context: Exprs.Context,\n container: Vtree.Container,\n name: string,\n docFaces: Font.DocumentFaces,\n ): void {\n this.propagatePropertyToElement(context, container.element, name, docFaces);\n }\n\n propagatePropertyToElement(\n context: Exprs.Context,\n element: Element,\n name: string,\n docFaces: Font.DocumentFaces,\n ): void {\n let val = this.getProp(context, name);\n if (val) {\n if (\n val.isNumeric() &&\n Exprs.needUnitConversion((val as Css.Numeric).unit)\n ) {\n val = Css.convertNumericToPx(val, context);\n }\n if (name === \"font-family\") {\n val = docFaces.filterFontFamily(val);\n }\n Base.setCSSProperty(element, name, val.toString());\n }\n }\n\n propagateDelayedProperty(\n context: Exprs.Context,\n container: Vtree.Container,\n name: string,\n delayedItems: Vtree.DelayedItem[],\n ): void {\n const val = this.getProp(context, name);\n if (val) {\n delayedItems.push(new Vtree.DelayedItem(container.element, name, val));\n }\n }\n\n assignLeftPosition(context: Exprs.Context, container: Vtree.Container): void {\n const left = this.getPropAsNumber(context, \"left\");\n const marginLeft = this.getPropAsNumber(context, \"margin-left\");\n const paddingLeft = this.getPropAsNumber(context, \"padding-left\");\n const borderLeftWidth = this.getPropAsNumber(context, \"border-left-width\");\n const width = this.getPropAsNumber(context, \"width\");\n container.setHorizontalPosition(left, width);\n Base.setCSSProperty(container.element, \"margin-left\", `${marginLeft}px`);\n Base.setCSSProperty(container.element, \"padding-left\", `${paddingLeft}px`);\n Base.setCSSProperty(\n container.element,\n \"border-left-width\",\n `${borderLeftWidth}px`,\n );\n container.marginLeft = marginLeft;\n container.borderLeft = borderLeftWidth;\n container.paddingLeft = paddingLeft;\n }\n\n assignRightPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n const right = this.getPropAsNumber(context, \"right\");\n const snapWidth = this.getPropAsNumber(context, \"snap-height\");\n const marginRight = this.getPropAsNumber(context, \"margin-right\");\n let paddingRight = this.getPropAsNumber(context, \"padding-right\");\n const borderRightWidth = this.getPropAsNumber(\n context,\n \"border-right-width\",\n );\n Base.setCSSProperty(container.element, \"margin-right\", `${marginRight}px`);\n Base.setCSSProperty(\n container.element,\n \"padding-right\",\n `${paddingRight}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"border-right-width\",\n `${borderRightWidth}px`,\n );\n container.marginRight = marginRight;\n container.borderRight = borderRightWidth;\n if (this.vertical && snapWidth > 0) {\n const xpos = right + container.getInsetRight();\n const r = xpos - Math.floor(xpos / snapWidth) * snapWidth;\n if (r > 0) {\n container.snapOffsetX = snapWidth - r;\n paddingRight += container.snapOffsetX;\n }\n }\n container.paddingRight = paddingRight;\n container.snapWidth = snapWidth;\n }\n\n assignTopPosition(context: Exprs.Context, container: Vtree.Container): void {\n const snapHeight = this.getPropAsNumber(context, \"snap-height\");\n const top = this.getPropAsNumber(context, \"top\");\n const marginTop = this.getPropAsNumber(context, \"margin-top\");\n let paddingTop = this.getPropAsNumber(context, \"padding-top\");\n const borderTopWidth = this.getPropAsNumber(context, \"border-top-width\");\n container.top = top;\n container.marginTop = marginTop;\n container.borderTop = borderTopWidth;\n container.snapHeight = snapHeight;\n if (!this.vertical && snapHeight > 0) {\n const ypos = top + container.getInsetTop();\n const r = ypos - Math.floor(ypos / snapHeight) * snapHeight;\n if (r > 0) {\n container.snapOffsetY = snapHeight - r;\n paddingTop += container.snapOffsetY;\n }\n }\n container.paddingTop = paddingTop;\n Base.setCSSProperty(container.element, \"top\", `${top}px`);\n Base.setCSSProperty(container.element, \"margin-top\", `${marginTop}px`);\n Base.setCSSProperty(container.element, \"padding-top\", `${paddingTop}px`);\n Base.setCSSProperty(\n container.element,\n \"border-top-width\",\n `${borderTopWidth}px`,\n );\n }\n\n assignBottomPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n const marginBottom = this.getPropAsNumber(context, \"margin-bottom\");\n const paddingBottom = this.getPropAsNumber(context, \"padding-bottom\");\n const borderBottomWidth = this.getPropAsNumber(\n context,\n \"border-bottom-width\",\n );\n const height =\n this.getPropAsNumber(context, \"height\") - container.snapOffsetY;\n Base.setCSSProperty(container.element, \"height\", `${height}px`);\n Base.setCSSProperty(\n container.element,\n \"margin-bottom\",\n `${marginBottom}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"padding-bottom\",\n `${paddingBottom}px`,\n );\n Base.setCSSProperty(\n container.element,\n \"border-bottom-width\",\n `${borderBottomWidth}px`,\n );\n container.height = height - container.snapOffsetY;\n container.marginBottom = marginBottom;\n container.borderBottom = borderBottomWidth;\n container.paddingBottom = paddingBottom;\n }\n\n assignBeforePosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignRightPosition(context, container);\n } else {\n this.assignTopPosition(context, container);\n }\n }\n\n assignAfterPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignLeftPosition(context, container);\n } else {\n this.assignBottomPosition(context, container);\n }\n }\n\n assignStartEndPosition(\n context: Exprs.Context,\n container: Vtree.Container,\n ): void {\n if (this.vertical) {\n this.assignTopPosition(context, container);\n this.assignBottomPosition(context, container);\n } else {\n this.assignRightPosition(context, container);\n this.assignLeftPosition(context, container);\n }\n }\n\n sizeWithMaxHeight(context: Exprs.Context, container: Vtree.Container): void {\n Base.setCSSProperty(container.element, \"border-top-width\", \"0px\");\n let height = this.getPropAsNumber(context, \"max-height\");\n if (this.isTopDependentOnAutoHeight) {\n container.setVerticalPosition(0, height);\n } else {\n this.assignTopPosition(context, container);\n height -= container.snapOffsetY;\n container.height = height;\n Base.setCSSProperty(container.element, \"height\", `${height}px`);\n }\n }\n\n sizeWithMaxWidth(context: Exprs.Context, container: Vtree.Container): void {\n Base.setCSSProperty(container.element, \"border-left-width\", \"0px\");\n let width = this.getPropAsNumber(context, \"max-width\");\n if (this.isRightDependentOnAutoWidth) {\n container.setHorizontalPosition(0, width);\n } else {\n this.assignRightPosition(context, container);\n width -= container.snapOffsetX;\n container.width = width;\n const right = this.getPropAsNumber(context, \"right\");\n Base.setCSSProperty(container.element, \"right\", `${right}px`);\n Base.setCSSProperty(container.element, \"width\", `${width}px`);\n }\n }\n\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n if (!this.parentInstance || this.vertical != this.parentInstance.vertical) {\n Base.setCSSProperty(\n container.element,\n \"writing-mode\",\n this.vertical ? \"vertical-rl\" : \"horizontal-tb\",\n );\n }\n if (this.vertical ? this.isAutoWidth : this.isAutoHeight) {\n if (this.vertical) {\n this.sizeWithMaxWidth(context, container);\n } else {\n this.sizeWithMaxHeight(context, container);\n }\n } else {\n this.assignBeforePosition(context, container);\n this.assignAfterPosition(context, container);\n }\n if (this.vertical ? this.isAutoHeight : this.isAutoWidth) {\n if (this.vertical) {\n this.sizeWithMaxHeight(context, container);\n } else {\n this.sizeWithMaxWidth(context, container);\n }\n } else {\n this.assignStartEndPosition(context, container);\n }\n for (let i = 0; i < passPreProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passPreProperties[i],\n docFaces,\n );\n }\n }\n\n transferContentProps(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n ): void {\n for (let i = 0; i < passContentProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passContentProperties[i],\n docFaces,\n );\n }\n }\n\n transferSinglUriContentProps(\n context: Exprs.Context,\n element: Element,\n docFaces: Font.DocumentFaces,\n ): void {\n for (let i = 0; i < passSingleUriContentProperties.length; i++) {\n this.propagatePropertyToElement(\n context,\n element,\n passSingleUriContentProperties[i],\n docFaces,\n );\n }\n }\n\n /**\n * @param column (null when content comes from the content property)\n */\n finishContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n column: Vtree.Container,\n columnCount: number,\n clientLayout: Vtree.ClientLayout,\n docFaces: Font.DocumentFaces,\n ): void {\n if (this.vertical) {\n this.calculatedWidth =\n container.computedBlockSize + container.snapOffsetX;\n } else {\n this.calculatedHeight =\n container.computedBlockSize + container.snapOffsetY;\n }\n const readHeight = (this.vertical || !column) && this.isAutoHeight;\n const readWidth = (!this.vertical || !column) && this.isAutoWidth;\n let bbox: Vtree.ClientRect = null;\n if (readWidth || readHeight) {\n if (readWidth) {\n Base.setCSSProperty(container.element, \"width\", \"auto\");\n }\n if (readHeight) {\n Base.setCSSProperty(container.element, \"height\", \"auto\");\n }\n bbox = clientLayout.getElementClientRect(\n column ? column.element : container.element,\n );\n if (readWidth) {\n this.calculatedWidth = Math.ceil(\n bbox.right -\n bbox.left -\n container.paddingLeft -\n container.borderLeft -\n container.paddingRight -\n container.borderRight,\n );\n if (this.vertical) {\n this.calculatedWidth += container.snapOffsetX;\n }\n }\n if (readHeight) {\n this.calculatedHeight =\n bbox.bottom -\n bbox.top -\n container.paddingTop -\n container.borderTop -\n container.paddingBottom -\n container.borderBottom;\n if (!this.vertical) {\n this.calculatedHeight += container.snapOffsetY;\n }\n }\n }\n if (this.vertical ? this.isAutoHeight : this.isAutoWidth) {\n this.assignStartEndPosition(context, container);\n }\n if (this.vertical ? this.isAutoWidth : this.isAutoHeight) {\n if (\n this.vertical\n ? this.isRightDependentOnAutoWidth\n : this.isTopDependentOnAutoHeight\n ) {\n this.assignBeforePosition(context, container);\n }\n this.assignAfterPosition(context, container);\n }\n if (columnCount > 1) {\n const ruleWidth = this.getPropAsNumber(context, \"column-rule-width\");\n const ruleStyle = this.getProp(context, \"column-rule-style\");\n const ruleColor = this.getProp(context, \"column-rule-color\");\n if (\n ruleWidth > 0 &&\n ruleStyle &&\n ruleStyle != Css.ident.none &&\n ruleColor != Css.ident.transparent\n ) {\n const columnGap = this.getPropAsNumber(context, \"column-gap\");\n const containerSize = this.vertical\n ? container.height\n : container.width;\n const border = this.vertical ? \"border-top\" : \"border-left\";\n for (let i = 1; i < columnCount; i++) {\n const pos =\n ((containerSize + columnGap) * i) / columnCount -\n columnGap / 2 +\n container.paddingLeft -\n ruleWidth / 2;\n const size =\n container.height + container.paddingTop + container.paddingBottom;\n const rule = container.element.ownerDocument.createElement(\"div\");\n Base.setCSSProperty(rule, \"position\", \"absolute\");\n Base.setCSSProperty(rule, this.vertical ? \"left\" : \"top\", \"0px\");\n Base.setCSSProperty(rule, this.vertical ? \"top\" : \"left\", `${pos}px`);\n Base.setCSSProperty(rule, this.vertical ? \"height\" : \"width\", \"0px\");\n Base.setCSSProperty(\n rule,\n this.vertical ? \"width\" : \"height\",\n `${size}px`,\n );\n Base.setCSSProperty(\n rule,\n border,\n `${ruleWidth}px ${ruleStyle.toString()}${\n ruleColor ? ` ${ruleColor.toString()}` : \"\"\n }`,\n );\n container.element.insertBefore(rule, container.element.firstChild);\n }\n }\n }\n for (let i = 0; i < passPostProperties.length; i++) {\n this.propagateProperty(\n context,\n container,\n passPostProperties[i],\n docFaces,\n );\n }\n for (let i = 0; i < delayedProperties.length; i++) {\n this.propagateDelayedProperty(\n context,\n container,\n delayedProperties[i],\n page.delayedItems,\n );\n }\n }\n\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n const specified = this.pageBox.specified;\n for (const name in specified) {\n if (CssCascade.isPropName(name)) {\n CssCascade.setProp(style, name, CssCascade.getProp(specified, name));\n }\n }\n if (this.pageBox.pseudoName == userAgentPageMasterPseudo) {\n for (const name in docElementStyle) {\n if (name.match(/^background-/) || name == \"writing-mode\") {\n style[name] = docElementStyle[name];\n }\n }\n }\n if (this.pageBox.pseudoName == \"layout-host\") {\n for (const name in docElementStyle) {\n if (!name.match(/^background-/) && name != \"writing-mode\") {\n style[name] = docElementStyle[name];\n }\n }\n }\n cascade.pushRule(this.pageBox.classes, null, style);\n if (style[\"content\"]) {\n style[\"content\"] = style[\"content\"].filterValue(\n new CssCascade.ContentPropVisitor(\n cascade,\n null,\n cascade.counterResolver,\n ),\n );\n }\n this.init(cascade.context);\n for (const child of this.pageBox.children) {\n const childInstance = child.createInstance(this);\n childInstance.applyCascadeAndInit(cascade, docElementStyle);\n }\n cascade.popRule();\n }\n\n resolveAutoSizing(context: Exprs.Context): void {\n // all implicit dependencies are set up at this point\n if (this.isAutoWidth) {\n this.isRightDependentOnAutoWidth =\n this.depends(\"right\", this.autoWidth, context) ||\n this.depends(\"margin-right\", this.autoWidth, context) ||\n this.depends(\"border-right-width\", this.autoWidth, context) ||\n this.depends(\"padding-right\", this.autoWidth, context);\n }\n if (this.isAutoHeight) {\n this.isTopDependentOnAutoHeight =\n this.depends(\"top\", this.autoHeight, context) ||\n this.depends(\"margin-top\", this.autoHeight, context) ||\n this.depends(\"border-top-width\", this.autoHeight, context) ||\n this.depends(\"padding-top\", this.autoHeight, context);\n }\n for (const childInstance of this.children) {\n childInstance.resolveAutoSizing(context);\n }\n }\n}\n\n/**\n * Properties that are passed through before the layout.\n */\nexport const passPreProperties = [\n \"border-left-style\",\n \"border-right-style\",\n \"border-top-style\",\n \"border-bottom-style\",\n \"border-left-color\",\n \"border-right-color\",\n \"border-top-color\",\n \"border-bottom-color\",\n \"outline-style\",\n \"outline-color\",\n \"outline-width\",\n \"overflow\",\n \"visibility\",\n];\n\n/**\n * Properties that are passed through after the layout.\n */\nexport const passPostProperties = [\n \"border-top-left-radius\",\n \"border-top-right-radius\",\n \"border-bottom-right-radius\",\n \"border-bottom-left-radius\",\n \"border-image-source\",\n \"border-image-slice\",\n \"border-image-width\",\n \"border-image-outset\",\n \"border-image-repeat\",\n \"background-attachment\",\n \"background-color\",\n \"background-image\",\n \"background-repeat\",\n \"background-position\",\n \"background-clip\",\n \"background-origin\",\n \"background-size\",\n \"opacity\",\n \"z-index\",\n \"background-blend-mode\",\n \"isolation\",\n \"mix-blend-mode\",\n \"filter\",\n];\n\n/**\n * Only passed when there is content assigned by the content property.\n */\nexport const passContentProperties = [\n \"color\",\n \"font-family\",\n \"font-size\",\n \"font-style\",\n \"font-weight\",\n \"font-variant\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n \"text-decoration\",\n \"text-indent\",\n \"text-transform\",\n \"white-space\",\n \"word-spacing\",\n \"font-feature-settings\",\n \"font-kerning\",\n \"font-size-adjust\",\n \"font-variant-east-asian\",\n \"font-stretch\",\n \"text-decoration-color\",\n \"text-decoration-line\",\n \"text-decoration-skip\",\n \"text-decoration-style\",\n \"text-emphasis\",\n \"text-emphasis-color\",\n \"text-emphasis-position\",\n \"text-emphasis-style\",\n \"text-shadow\",\n \"text-underline-position\",\n];\n\nexport const passSingleUriContentProperties = [\n \"width\",\n \"height\",\n \"image-resolution\",\n \"object-fit\",\n \"object-position\",\n];\n\nexport const delayedProperties = [\"transform\", \"transform-origin\"];\n\nexport const userAgentPageMasterPseudo = \"background-host\";\n\nexport class RootPageBoxInstance extends PageBoxInstance<RootPageBox> {\n constructor(pageBox: RootPageBox) {\n super(null, pageBox);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n super.applyCascadeAndInit(cascade, docElementStyle);\n\n // Sort page masters using order and specificity.\n const pageMasters = this.children;\n (pageMasters as PageMasterInstance[]).sort(\n (a, b) =>\n (b.pageBox as any).specificity - (a.pageBox as any).specificity || // probably cause NaN\n a.pageBox.index - b.pageBox.index,\n );\n }\n}\n\nexport class PageMasterInstance<\n P extends PageMaster = PageMaster<PageMasterInstance<any>>\n> extends PageBoxInstance<P> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: P) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = this;\n }\n\n /**\n * @override\n */\n boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n const pageMaster = this.pageBox.pageMaster;\n if (pageMaster.condition) {\n enabled = Exprs.and(pageMaster.scope, enabled, pageMaster.condition);\n }\n return enabled;\n }\n\n /**\n * Called after layout of contents of the page has done to adjust the overall\n * page layout. Override in subclasses.\n */\n adjustPageLayout(\n context: Exprs.Context,\n page: Vtree.Page,\n clientLayout: Vtree.ClientLayout,\n ) {}\n}\n\nexport class PartitionGroupInstance extends PageBoxInstance<PartitionGroup> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: PageBox) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = parentInstance.pageMasterInstance;\n }\n}\n\nexport class PartitionInstance<\n P extends Partition = Partition<PartitionInstance<any>>\n> extends PageBoxInstance<P> {\n pageMasterInstance: PageMasterInstance;\n\n constructor(parentInstance: PageBoxInstance, pageBox: P) {\n super(parentInstance, pageBox);\n this.pageMasterInstance = parentInstance.pageMasterInstance;\n }\n\n processPartitionList(\n enabled: Exprs.Val,\n listVal: Css.Val,\n conflicting: boolean,\n ): Exprs.Val {\n let list: Css.Val[] = null;\n if (listVal instanceof Css.Ident) {\n list = [listVal];\n }\n if (listVal instanceof Css.CommaList) {\n list = (listVal as Css.CommaList).values;\n }\n if (list) {\n const scope = this.pageBox.scope;\n for (let i = 0; i < list.length; i++) {\n if (list[i] instanceof Css.Ident) {\n const qname = Exprs.makeQualifiedName(\n (list[i] as Css.Ident).name,\n \"enabled\",\n );\n let term: Exprs.Val = new Exprs.Named(scope, qname);\n if (conflicting) {\n term = new Exprs.Not(scope, term);\n }\n enabled = Exprs.and(scope, enabled, term);\n }\n }\n }\n return enabled;\n }\n\n /**\n * @override\n */\n boxSpecificEnabled(enabled: Exprs.Val): Exprs.Val {\n const scope = this.pageBox.scope;\n const style = this.style;\n const required =\n toExprBool(scope, style[\"required\"], scope._false) !== scope._false;\n if (required || this.isAutoHeight) {\n const flowName = toExprIdent(scope, style[\"flow-from\"], \"body\");\n const hasContent = new Exprs.Call(scope, \"has-content\", [flowName]);\n enabled = Exprs.and(scope, enabled, hasContent);\n }\n enabled = this.processPartitionList(\n enabled,\n style[\"required-partitions\"],\n false,\n );\n enabled = this.processPartitionList(\n enabled,\n style[\"conflicting-partitions\"],\n true,\n );\n if (required) {\n const pmEnabledVal = this.pageMasterInstance.style[\"enabled\"];\n let pmEnabled = pmEnabledVal\n ? pmEnabledVal.toExpr(scope, null)\n : scope._true;\n pmEnabled = Exprs.and(scope, pmEnabled, enabled);\n this.pageMasterInstance.style[\"enabled\"] = new Css.Expr(pmEnabled);\n }\n return enabled;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n Base.setCSSProperty(container.element, \"overflow\", \"hidden\"); // default value\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n }\n}\n\n//--------------------- parsing -----------------------\nexport class PageBoxParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly target: PageBox,\n public readonly validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n this.target.specified[name] = new CssCascade.CascadeValue(\n value,\n important\n ? CssParser.SPECIFICITY_STYLE\n : CssParser.SPECIFICITY_STYLE_IMPORTANT,\n );\n }\n}\n\nexport class PartitionParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: Partition,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n }\n}\n\nexport class PartitionGroupParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: PartitionGroup,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n target.specified[\"width\"] = new CssCascade.CascadeValue(\n Css.hundredPercent,\n 0,\n );\n target.specified[\"height\"] = new CssCascade.CascadeValue(\n Css.hundredPercent,\n 0,\n );\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partition = new Partition(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionParserHandler(\n this.scope,\n this.owner,\n partition,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partitionGroup = new PartitionGroup(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionGroupParserHandler(\n this.scope,\n this.owner,\n partitionGroup,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n}\n\nexport class PageMasterParserHandler extends PageBoxParserHandler {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n target: PageMaster,\n validatorSet: CssValidator.ValidatorSet,\n ) {\n super(scope, owner, target, validatorSet);\n }\n\n /**\n * @override\n */\n startPartitionRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partition = new Partition(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionParserHandler(\n this.scope,\n this.owner,\n partition,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n\n /**\n * @override\n */\n startPartitionGroupRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const partitionGroup = new PartitionGroup(\n this.scope,\n name,\n pseudoName,\n classes,\n this.target,\n );\n const handler = new PartitionGroupParserHandler(\n this.scope,\n this.owner,\n partitionGroup,\n this.validatorSet,\n );\n this.owner.pushHandler(handler);\n }\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CssPage - `@page` rule (CSS Paged Media) support https://drafts.csswg.org/css-page/\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as PageMaster from \"./page-master\";\nimport * as Sizing from \"./sizing\";\nimport * as Vtree from \"./vtree\";\n\n/**\n * Resolve page progression direction from writing-mode and direction.\n */\nexport function resolvePageProgression(\n style: CssCascade.ElementStyle,\n): Constants.PageProgression {\n let writingMode = style[\"writing-mode\"];\n writingMode = writingMode && writingMode.value;\n let direction = style[\"direction\"];\n direction = direction && direction.value;\n if (\n writingMode === Css.ident.vertical_lr ||\n (writingMode !== Css.ident.vertical_rl && direction !== Css.ident.rtl)\n ) {\n return Constants.PageProgression.LTR;\n } else {\n return Constants.PageProgression.RTL;\n }\n}\nexport type PageSize = {\n width: Css.Numeric;\n height: Css.Numeric;\n};\n\n/**\n * Named page sizes.\n */\nexport const pageSizes: { [key: string]: PageSize } = {\n a5: { width: new Css.Numeric(148, \"mm\"), height: new Css.Numeric(210, \"mm\") },\n a4: { width: new Css.Numeric(210, \"mm\"), height: new Css.Numeric(297, \"mm\") },\n a3: { width: new Css.Numeric(297, \"mm\"), height: new Css.Numeric(420, \"mm\") },\n b5: { width: new Css.Numeric(176, \"mm\"), height: new Css.Numeric(250, \"mm\") },\n b4: { width: new Css.Numeric(250, \"mm\"), height: new Css.Numeric(353, \"mm\") },\n \"jis-b5\": {\n width: new Css.Numeric(182, \"mm\"),\n height: new Css.Numeric(257, \"mm\"),\n },\n \"jis-b4\": {\n width: new Css.Numeric(257, \"mm\"),\n height: new Css.Numeric(364, \"mm\"),\n },\n letter: {\n width: new Css.Numeric(8.5, \"in\"),\n height: new Css.Numeric(11, \"in\"),\n },\n legal: {\n width: new Css.Numeric(8.5, \"in\"),\n height: new Css.Numeric(14, \"in\"),\n },\n ledger: {\n width: new Css.Numeric(11, \"in\"),\n height: new Css.Numeric(17, \"in\"),\n },\n};\n\n/**\n * Default value for line width of printer marks\n */\nexport const defaultPrinterMarkLineWidth: Css.Numeric = new Css.Numeric(\n 0.24,\n \"pt\",\n);\n\n/**\n * Default value for distance between an edge of the page and printer marks\n */\nexport const defaultPrinterMarkOffset: Css.Numeric = new Css.Numeric(3, \"mm\");\n\n/**\n * Default value for line length of the (shorter) line of a crop mark and the\n * shorter line of a cross mark\n */\nexport const defaultPrinterMarkLineLength: Css.Numeric = new Css.Numeric(\n 10,\n \"mm\",\n);\n\n/**\n * Default value for bleed offset (= defaultPrinterMarkOffset +\n * defaultPrinterMarkLineLength)\n */\nexport const defaultBleedOffset: Css.Numeric = new Css.Numeric(3 + 10, \"mm\");\n\nexport type PageSizeAndBleed = {\n width: Css.Numeric;\n height: Css.Numeric;\n bleed: Css.Numeric;\n bleedOffset: Css.Numeric;\n};\n\nexport function resolvePageSizeAndBleed(style: {\n [key: string]: CssCascade.CascadeValue;\n}): PageSizeAndBleed {\n // default value (fit to viewport, no bleed)\n const pageSizeAndBleed: PageSizeAndBleed = {\n width: Css.fullWidth,\n height: Css.fullHeight,\n bleed: Css.numericZero,\n bleedOffset: Css.numericZero,\n };\n const size: CssCascade.CascadeValue = style[\"size\"];\n\n if (!size || size.value === Css.ident.auto) {\n // if size is auto, fit to the viewport (use default value)\n } else {\n /** !type {!Css.Val} */\n const value = size.value;\n let val1: Css.Val;\n let val2: Css.Val;\n if (value.isSpaceList()) {\n val1 = (value as Css.SpaceList).values[0];\n val2 = (value as Css.SpaceList).values[1];\n } else {\n val1 = value;\n val2 = null;\n }\n if (val1.isNumeric()) {\n // <length>{1,2}\n pageSizeAndBleed.width = val1 as Css.Numeric;\n pageSizeAndBleed.height = (val2 || val1) as Css.Numeric;\n } else {\n // <page-size> || [ portrait | landscape ]\n const s =\n (val1 as any).name && pageSizes[(val1 as Css.Ident).name.toLowerCase()];\n if (!s) {\n // portrait or landscape is specified alone. fallback to fit to the\n // viewport (use default value)\n } else if (val2 && val2 === Css.ident.landscape) {\n // swap\n pageSizeAndBleed.width = s.height;\n pageSizeAndBleed.height = s.width;\n } else {\n // return {\n pageSizeAndBleed.width = s.width;\n pageSizeAndBleed.height = s.height;\n }\n }\n }\n const marks = style[\"marks\"];\n if (marks && marks.value !== Css.ident.none) {\n pageSizeAndBleed.bleedOffset = defaultBleedOffset;\n }\n const bleed = style[\"bleed\"];\n if (!bleed || bleed.value === Css.ident.auto) {\n // \"('auto' value) Computes to 6pt if marks has crop and to zero\n // otherwise.\" https://drafts.csswg.org/css-page/#valdef-page-bleed-auto\n if (marks) {\n let hasCrop = false;\n if (marks.value.isSpaceList()) {\n hasCrop = (marks.value as Css.SpaceList).values.some(\n (v) => v === Css.ident.crop,\n );\n } else {\n hasCrop = marks.value === Css.ident.crop;\n }\n if (hasCrop) {\n pageSizeAndBleed.bleed = new Css.Numeric(6, \"pt\");\n }\n }\n } else if (bleed.value && bleed.value.isNumeric()) {\n pageSizeAndBleed.bleed = bleed.value as Css.Numeric;\n }\n return pageSizeAndBleed;\n}\n\nexport type EvaluatedPageSizeAndBleed = {\n pageWidth: number;\n pageHeight: number;\n bleed: number;\n bleedOffset: number;\n cropOffset: number;\n};\n\n/**\n * Evaluate actual page width, height and bleed from style specified in page\n * context.\n */\nexport function evaluatePageSizeAndBleed(\n pageSizeAndBleed: PageSizeAndBleed,\n context: Exprs.Context,\n): EvaluatedPageSizeAndBleed {\n const evaluated = {} as EvaluatedPageSizeAndBleed;\n const bleed =\n pageSizeAndBleed.bleed.num *\n context.queryUnitSize(pageSizeAndBleed.bleed.unit, false);\n const bleedOffset =\n pageSizeAndBleed.bleedOffset.num *\n context.queryUnitSize(pageSizeAndBleed.bleedOffset.unit, false);\n const cropOffset = bleed + bleedOffset;\n const width = pageSizeAndBleed.width;\n if (width === Css.fullWidth) {\n if (context.pref.defaultPaperSize) {\n evaluated.pageWidth =\n context.pref.defaultPaperSize.width *\n context.queryUnitSize(\"px\", false);\n } else {\n evaluated.pageWidth =\n (context.pref.spreadView\n ? Math.floor(context.viewportWidth / 2) - context.pref.pageBorder\n : context.viewportWidth) -\n cropOffset * 2;\n }\n } else {\n evaluated.pageWidth = width.num * context.queryUnitSize(width.unit, false);\n }\n const height = pageSizeAndBleed.height;\n if (height === Css.fullHeight) {\n if (context.pref.defaultPaperSize) {\n evaluated.pageHeight =\n context.pref.defaultPaperSize.height *\n context.queryUnitSize(\"px\", false);\n } else {\n evaluated.pageHeight = context.viewportHeight - cropOffset * 2;\n }\n } else {\n evaluated.pageHeight =\n height.num * context.queryUnitSize(height.unit, false);\n }\n evaluated.bleed = bleed;\n evaluated.bleedOffset = bleedOffset;\n evaluated.cropOffset = cropOffset;\n return evaluated;\n}\n\n/**\n * Create an 'svg' element for a printer mark.\n */\nexport function createPrinterMarkSvg(\n doc: Document,\n width: number,\n height: number,\n): Element {\n const mark = doc.createElementNS(Base.NS.SVG, \"svg\");\n mark.setAttribute(\"width\", width);\n mark.setAttribute(\"height\", height);\n mark.style.position = \"absolute\";\n return mark;\n}\n\n/**\n * Create an SVG element for a printer mark line.\n * @param elementType Specifies which type of element to create. Default value\n * is \"polyline\".\n */\nexport function createPrinterMarkElement(\n doc: Document,\n lineWidth: number,\n elementType?: string,\n): Element {\n elementType = elementType || \"polyline\";\n const line = doc.createElementNS(Base.NS.SVG, elementType);\n line.setAttribute(\"stroke\", \"black\");\n line.setAttribute(\"stroke-width\", lineWidth);\n line.setAttribute(\"fill\", \"none\");\n return line;\n}\n\n/**\n * Position of a corner mark\n * @enum {string}\n */\nexport enum CornerMarkPosition {\n TOP_LEFT = \"top left\",\n TOP_RIGHT = \"top right\",\n BOTTOM_LEFT = \"bottom left\",\n BOTTOM_RIGHT = \"bottom right\",\n}\n\n/**\n * Create a corner mark.\n */\nexport function createCornerMark(\n doc: Document,\n position: CornerMarkPosition,\n lineWidth: number,\n cropMarkLineLength: number,\n bleed: number,\n offset: number,\n): Element {\n let bleedMarkLineLength = cropMarkLineLength;\n\n // bleed mark line should be longer than bleed + 2mm\n if (bleedMarkLineLength <= bleed + 2 * Exprs.defaultUnitSizes[\"mm\"]) {\n bleedMarkLineLength = bleed + cropMarkLineLength / 2;\n }\n const maxLineLength = Math.max(cropMarkLineLength, bleedMarkLineLength);\n const svgWidth = bleed + maxLineLength + lineWidth / 2;\n const mark = createPrinterMarkSvg(doc, svgWidth, svgWidth);\n let points1 = [\n [0, bleed + cropMarkLineLength],\n [cropMarkLineLength, bleed + cropMarkLineLength],\n [cropMarkLineLength, bleed + cropMarkLineLength - bleedMarkLineLength],\n ];\n\n // reflect with respect to y=x\n let points2 = points1.map((p) => [p[1], p[0]]);\n if (\n position === CornerMarkPosition.TOP_RIGHT ||\n position === CornerMarkPosition.BOTTOM_RIGHT\n ) {\n // reflect with respect to a vertical axis\n points1 = points1.map((p) => [bleed + maxLineLength - p[0], p[1]]);\n points2 = points2.map((p) => [bleed + maxLineLength - p[0], p[1]]);\n }\n if (\n position === CornerMarkPosition.BOTTOM_LEFT ||\n position === CornerMarkPosition.BOTTOM_RIGHT\n ) {\n // reflect with respect to a vertical axis\n points1 = points1.map((p) => [p[0], bleed + maxLineLength - p[1]]);\n points2 = points2.map((p) => [p[0], bleed + maxLineLength - p[1]]);\n }\n const line1 = createPrinterMarkElement(doc, lineWidth);\n line1.setAttribute(\"points\", points1.map((p) => p.join(\",\")).join(\" \"));\n mark.appendChild(line1);\n const line2 = createPrinterMarkElement(doc, lineWidth);\n line2.setAttribute(\"points\", points2.map((p) => p.join(\",\")).join(\" \"));\n mark.appendChild(line2);\n position.split(\" \").forEach((side) => {\n (mark as any).style[side] = `${offset}px`;\n });\n return mark;\n}\n\n/**\n * Position of a cross mark\n * @enum {string}\n */\nexport enum CrossMarkPosition {\n TOP = \"top\",\n BOTTOM = \"bottom\",\n LEFT = \"left\",\n RIGHT = \"right\",\n}\n\n/**\n * Create a cross mark.\n */\nexport function createCrossMark(\n doc: Document,\n position: CrossMarkPosition,\n lineWidth: number,\n lineLength: number,\n offset: number,\n): Element {\n const longLineLength = lineLength * 2;\n let width: number;\n let height: number;\n if (\n position === CrossMarkPosition.TOP ||\n position === CrossMarkPosition.BOTTOM\n ) {\n width = longLineLength;\n height = lineLength;\n } else {\n width = lineLength;\n height = longLineLength;\n }\n const mark = createPrinterMarkSvg(doc, width, height);\n const horizontalLine = createPrinterMarkElement(doc, lineWidth);\n horizontalLine.setAttribute(\n \"points\",\n `0,${height / 2} ${width},${height / 2}`,\n );\n mark.appendChild(horizontalLine);\n const verticalLine = createPrinterMarkElement(doc, lineWidth);\n verticalLine.setAttribute(\"points\", `${width / 2},0 ${width / 2},${height}`);\n mark.appendChild(verticalLine);\n const circle = createPrinterMarkElement(doc, lineWidth, \"circle\");\n circle.setAttribute(\"cx\", width / 2);\n circle.setAttribute(\"cy\", height / 2);\n circle.setAttribute(\"r\", lineLength / 4);\n mark.appendChild(circle);\n let opposite: CrossMarkPosition;\n switch (position) {\n case CrossMarkPosition.TOP:\n opposite = CrossMarkPosition.BOTTOM;\n break;\n case CrossMarkPosition.BOTTOM:\n opposite = CrossMarkPosition.TOP;\n break;\n case CrossMarkPosition.LEFT:\n opposite = CrossMarkPosition.RIGHT;\n break;\n case CrossMarkPosition.RIGHT:\n opposite = CrossMarkPosition.LEFT;\n break;\n }\n Object.keys(CrossMarkPosition).forEach((key) => {\n const side = CrossMarkPosition[key];\n if (side === position) {\n (mark as any).style[side] = `${offset}px`;\n } else if (side !== opposite) {\n (mark as any).style[side] = \"0\";\n (mark as any).style[`margin-${side}`] = \"auto\";\n }\n });\n return mark;\n}\n\n/**\n * Add printer marks to the page.\n */\nexport function addPrinterMarks(\n cascadedPageStyle: CssCascade.ElementStyle,\n evaluatedPageSizeAndBleed: EvaluatedPageSizeAndBleed,\n page: Vtree.Page,\n context: Exprs.Context,\n): void {\n let crop = false;\n let cross = false;\n const marks = cascadedPageStyle[\"marks\"];\n if (marks) {\n const value = marks.value;\n if (value.isSpaceList()) {\n value.values.forEach((v) => {\n if (v === Css.ident.crop) {\n crop = true;\n } else if (v === Css.ident.cross) {\n cross = true;\n }\n });\n } else if (value === Css.ident.crop) {\n crop = true;\n } else if (value === Css.ident.cross) {\n cross = true;\n }\n }\n if (!crop && !cross) {\n return;\n }\n const container = page.container;\n const doc = container.ownerDocument as Document;\n Asserts.assert(doc);\n const bleed = evaluatedPageSizeAndBleed.bleed;\n const lineWidth = Css.toNumber(defaultPrinterMarkLineWidth, context);\n const printerMarkOffset = Css.toNumber(defaultPrinterMarkOffset, context);\n const lineLength = Css.toNumber(defaultPrinterMarkLineLength, context);\n\n if (bleed) {\n const bgcolor = cascadedPageStyle[\"background-color\"];\n if (bgcolor && bgcolor.value) {\n page.bleedBox.style.backgroundColor = bgcolor.value.stringValue();\n }\n }\n\n // corner marks\n if (crop) {\n Object.keys(CornerMarkPosition).forEach((key) => {\n const position = CornerMarkPosition[key];\n const mark = createCornerMark(\n doc,\n position,\n lineWidth,\n lineLength,\n bleed,\n printerMarkOffset,\n );\n container.appendChild(mark);\n });\n }\n\n // cross marks\n if (cross) {\n Object.keys(CrossMarkPosition).forEach((key) => {\n const position = CrossMarkPosition[key];\n const mark = createCrossMark(\n doc,\n position,\n lineWidth,\n lineLength,\n printerMarkOffset,\n );\n container.appendChild(mark);\n });\n }\n}\n\n/**\n * Properties transfered from the PageRuleMaster to the PageRulePartition\n */\nexport const propertiesAppliedToPartition = (() => {\n const sides = [\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n \"before\",\n \"after\",\n \"start\",\n \"end\",\n \"block-start\",\n \"block-end\",\n \"inline-start\",\n \"inline-end\",\n ];\n const props = {\n width: true,\n height: true,\n \"block-size\": true,\n \"inline-size\": true,\n margin: true,\n padding: true,\n border: true,\n outline: true,\n \"outline-width\": true,\n \"outline-style\": true,\n \"outline-color\": true,\n };\n sides.forEach((side) => {\n props[`margin-${side}`] = true;\n props[`padding-${side}`] = true;\n props[`border-${side}-width`] = true;\n props[`border-${side}-style`] = true;\n props[`border-${side}-color`] = true;\n });\n return props;\n})();\n\n/**\n * Represents position of a margin box along the variable dimension of the page.\n * START and END can be interpreted as 'inline-start' and 'inline-end' in\n * horizontal and vertical writing modes. For example, for top margin boxes\n * (@top-left-corner, @top-left, @top-center, @top-right, @top-right-corner),\n * @top-left corresponds to START, @top-center to CENTER, and @top-right to END.\n * The corner boxes (@top-left-corner and @top-right-corner) have a 'null'\n * position.\n * @enum {string}\n */\nexport enum MarginBoxPositionAlongVariableDimension {\n START = \"start\",\n CENTER = \"center\",\n END = \"end\",\n}\n\nexport type PageMarginBoxInformation = {\n order: number;\n isInTopRow: boolean;\n isInBottomRow: boolean;\n isInLeftColumn: boolean;\n isInRightColumn: boolean;\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension;\n};\n\n/**\n * Page-margin boxes.\n * @dict\n */\nexport const pageMarginBoxes: { [key: string]: PageMarginBoxInformation } = {\n \"top-left-corner\": {\n order: 1,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"top-left\": {\n order: 2,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"top-center\": {\n order: 3,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"top-right\": {\n order: 4,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"top-right-corner\": {\n order: 5,\n isInTopRow: true,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"right-top\": {\n order: 6,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"right-middle\": {\n order: 7,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"right-bottom\": {\n order: 8,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"bottom-right-corner\": {\n order: 9,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: true,\n positionAlongVariableDimension: null,\n },\n \"bottom-right\": {\n order: 10,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"bottom-center\": {\n order: 11,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"bottom-left\": {\n order: 12,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: false,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n \"bottom-left-corner\": {\n order: 13,\n isInTopRow: false,\n isInBottomRow: true,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension: null,\n },\n \"left-bottom\": {\n order: 14,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension: MarginBoxPositionAlongVariableDimension.END,\n },\n \"left-middle\": {\n order: 15,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.CENTER,\n },\n \"left-top\": {\n order: 16,\n isInTopRow: false,\n isInBottomRow: false,\n isInLeftColumn: true,\n isInRightColumn: false,\n positionAlongVariableDimension:\n MarginBoxPositionAlongVariableDimension.START,\n },\n};\n\n/**\n * Names for page-margin boxes order in the default painting order.\n */\nexport const pageMarginBoxNames: string[] = (() => {\n const boxes = pageMarginBoxes;\n return Object.keys(boxes).sort((a, b) => boxes[a].order - boxes[b].order);\n})();\n\n/**\n * Indicates that the page master is generated for `@page` rules.\n */\nexport const pageRuleMasterPseudoName = \"vivliostyle-page-rule-master\";\n\n/**\n * Key for properties in margin contexts.\n * Styles in margin contexts are stored in pageStyle[\"_marginBoxes\"][(margin\n * box's name)].\n */\nexport const marginBoxesKey: string = \"_marginBoxes\";\n\n/**\n * Represent a page master generated for `@page` rules\n * @param style Cascaded style for `@page` rules\n */\nexport class PageRuleMaster extends PageMaster.PageMaster<\n PageRuleMasterInstance\n> {\n private bodyPartitionKey: string;\n private pageMarginBoxes = {} as {\n [key: string]: PageMarginBoxPartition;\n };\n\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageMaster.RootPageBox,\n style: CssCascade.ElementStyle,\n ) {\n super(scope, null, pageRuleMasterPseudoName, [], parent, null, 0);\n const pageSize = resolvePageSizeAndBleed(style as any);\n const partition = new PageRulePartition(this.scope, this, style, pageSize);\n this.bodyPartitionKey = partition.key;\n this.createPageMarginBoxes(style);\n this.applySpecified(style, pageSize);\n }\n\n /**\n * Create page-margin boxes\n */\n createPageMarginBoxes(style: CssCascade.ElementStyle) {\n const marginBoxesMap = style[marginBoxesKey];\n if (marginBoxesMap) {\n const self = this;\n pageMarginBoxNames.forEach((name) => {\n if (marginBoxesMap[name]) {\n self.pageMarginBoxes[name] = new PageMarginBoxPartition(\n self.scope,\n self,\n name,\n style,\n );\n }\n });\n }\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageBox\n */\n private applySpecified(style: CssCascade.ElementStyle, pageSize: PageSize) {\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.relative,\n 0,\n );\n this.specified[\"width\"] = new CssCascade.CascadeValue(pageSize.width, 0);\n this.specified[\"height\"] = new CssCascade.CascadeValue(pageSize.height, 0);\n for (const name in style) {\n if (!propertiesAppliedToPartition[name] && name !== \"background-clip\") {\n this.specified[name] = style[name];\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageRuleMasterInstance {\n return new PageRuleMasterInstance(parentInstance, this);\n }\n}\n\n/**\n * Represent a partition placed in a PageRuleMaster\n * @param style Cascaded style for `@page` rules\n */\nexport class PageRulePartition extends PageMaster.Partition<\n PageRulePartitionInstance\n> {\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageRuleMaster,\n style: CssCascade.ElementStyle,\n public readonly pageSize: PageSize,\n ) {\n super(scope, null, null, [], parent);\n this.specified[\"z-index\"] = new CssCascade.CascadeValue(new Css.Int(0), 0);\n this.applySpecified(style);\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageBox\n */\n private applySpecified(style: CssCascade.ElementStyle) {\n this.specified[\"flow-from\"] = new CssCascade.CascadeValue(\n Css.getName(\"body\"),\n 0,\n );\n\n // Use absolute positioning so that this partition's margins don't collapse\n // with its parent's margins\n this.specified[\"position\"] = new CssCascade.CascadeValue(\n Css.ident.absolute,\n 0,\n );\n this.specified[\"overflow\"] = new CssCascade.CascadeValue(\n Css.ident.visible,\n 0,\n );\n for (const prop in propertiesAppliedToPartition) {\n if (propertiesAppliedToPartition.hasOwnProperty(prop)) {\n this.specified[prop] = style[prop];\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageMaster.PageBoxInstance {\n return new PageRulePartitionInstance(parentInstance, this);\n }\n}\n\n/**\n * Represent a partition for a page-margin box\n */\nexport class PageMarginBoxPartition extends PageMaster.Partition<\n PageMarginBoxPartitionInstance\n> {\n constructor(\n scope: Exprs.LexicalScope,\n parent: PageRuleMaster,\n public readonly marginBoxName: string,\n style: CssCascade.ElementStyle,\n ) {\n super(scope, null, null, [], parent);\n this.applySpecified(style);\n }\n\n /**\n * Transfer cascaded style for `@page` rules to 'specified' style of this\n * PageMarginBox\n */\n applySpecified(style: CssCascade.ElementStyle) {\n const ownStyle = style[marginBoxesKey][\n this.marginBoxName\n ] as CssCascade.ElementStyle;\n\n // Inherit properties in the page context to the page-margin context\n for (const prop in style) {\n const val = style[prop] as CssCascade.CascadeValue;\n const ownVal = ownStyle[prop] as CssCascade.CascadeValue;\n if (\n CssCascade.inheritedProps[prop] ||\n (ownVal && ownVal.value === Css.ident.inherit)\n ) {\n this.specified[prop] = val;\n }\n }\n for (const prop in ownStyle) {\n if (Object.prototype.hasOwnProperty.call(ownStyle, prop)) {\n const val = ownStyle[prop] as CssCascade.CascadeValue;\n if (val && val.value !== Css.ident.inherit) {\n this.specified[prop] = val;\n }\n }\n }\n }\n\n /**\n * @override\n */\n createInstance(parentInstance): PageMaster.PageBoxInstance {\n return new PageMarginBoxPartitionInstance(parentInstance, this);\n }\n}\n\n//---------------------------- Instance --------------------------------\nexport type PageAreaDimension = {\n borderBoxWidth: Exprs.Val;\n borderBoxHeight: Exprs.Val;\n marginTop: Exprs.Val;\n marginBottom: Exprs.Val;\n marginLeft: Exprs.Val;\n marginRight: Exprs.Val;\n};\n\nexport class PageRuleMasterInstance extends PageMaster.PageMasterInstance<\n PageRuleMaster\n> {\n pageAreaDimension: PageAreaDimension | null = null;\n pageMarginBoxInstances: {\n [key: string]: PageMarginBoxPartitionInstance;\n } = {};\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageRuleMaster: PageRuleMaster,\n ) {\n super(parentInstance, pageRuleMaster);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n for (const name in docElementStyle) {\n if (Object.prototype.hasOwnProperty.call(docElementStyle, name)) {\n switch (name) {\n case \"writing-mode\":\n case \"direction\":\n style[name] = docElementStyle[name];\n }\n }\n }\n super.applyCascadeAndInit(cascade, docElementStyle);\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const style = this.style;\n style[\"left\"] = Css.numericZero;\n style[\"margin-left\"] = Css.numericZero;\n style[\"border-left-width\"] = Css.numericZero;\n style[\"padding-left\"] = Css.numericZero;\n style[\"padding-right\"] = Css.numericZero;\n style[\"border-right-width\"] = Css.numericZero;\n style[\"margin-right\"] = Css.numericZero;\n style[\"right\"] = Css.numericZero;\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const style = this.style;\n\n // Shift 1px to workaround Chrome printing bug\n // style[\"top\"] = new Css.Numeric(-1, \"px\");\n style[\"top\"] = Css.numericZero;\n style[\"margin-top\"] = Css.numericZero;\n style[\"border-top-width\"] = Css.numericZero;\n style[\"padding-top\"] = Css.numericZero;\n style[\"padding-bottom\"] = Css.numericZero;\n style[\"border-bottom-width\"] = Css.numericZero;\n style[\"margin-bottom\"] = Css.numericZero;\n style[\"bottom\"] = Css.numericZero;\n }\n\n setPageAreaDimension(dim: PageAreaDimension) {\n this.pageAreaDimension = dim;\n const style = this.style;\n style[\"width\"] = new Css.Expr(dim.borderBoxWidth);\n style[\"height\"] = new Css.Expr(dim.borderBoxHeight);\n style[\"padding-left\"] = new Css.Expr(dim.marginLeft);\n style[\"padding-right\"] = new Css.Expr(dim.marginRight);\n style[\"padding-top\"] = new Css.Expr(dim.marginTop);\n style[\"padding-bottom\"] = new Css.Expr(dim.marginBottom);\n }\n\n /**\n * @override\n */\n adjustPageLayout(\n context: Exprs.Context,\n page: Vtree.Page,\n clientLayout: Vtree.ClientLayout,\n ) {\n const marginBoxContainers = page.marginBoxes;\n const horizontalDimensions = {\n start: this.pageAreaDimension.marginLeft,\n end: this.pageAreaDimension.marginRight,\n extent: this.pageAreaDimension.borderBoxWidth,\n };\n const verticalDimensions = {\n start: this.pageAreaDimension.marginTop,\n end: this.pageAreaDimension.marginBottom,\n extent: this.pageAreaDimension.borderBoxHeight,\n };\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.top,\n true,\n horizontalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.bottom,\n true,\n horizontalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.left,\n false,\n verticalDimensions,\n context,\n clientLayout,\n );\n this.sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers.right,\n false,\n verticalDimensions,\n context,\n clientLayout,\n );\n }\n\n /**\n * Determine and set margin boxes' sizes along variable dimension using an\n * algorithm specified in CSS Paged Media spec.\n * @param marginBoxContainers Containers corresponding to the target margin\n * boxes in one page edge (top, bottom, left, right)\n * @param isHorizontal Indicates if the target margin boxes are on the\n * horizontal edge (top or bottom) or not (left or right).\n * @param dimensions Page dimensions. start: margin-left or margin-top. end:\n * margin-right or margin-bottom. extent: border-box width or height of\n * the page area (= available width or height for the target margin boxes)\n */\n private sizeMarginBoxesAlongVariableDimension(\n marginBoxContainers: { [key: string]: Vtree.Container },\n isHorizontal: boolean,\n dimensions: { start: Exprs.Val; end: Exprs.Val; extent: Exprs.Val },\n context: Exprs.Context,\n clientLayout: Vtree.ClientLayout,\n ) {\n const START = MarginBoxPositionAlongVariableDimension.START;\n const CENTER = MarginBoxPositionAlongVariableDimension.CENTER;\n const END = MarginBoxPositionAlongVariableDimension.END;\n\n // prepare parameters\n const scope = this.pageBox.scope;\n const containers: {\n [key in MarginBoxPositionAlongVariableDimension]?: Vtree.Container;\n } = {};\n const boxInstances: {\n [key in MarginBoxPositionAlongVariableDimension]?: PageMarginBoxPartitionInstance;\n } = {};\n const boxParams: {\n [key in MarginBoxPositionAlongVariableDimension]?: MarginBoxSizingParam;\n } = {};\n for (const name in marginBoxContainers) {\n const boxInfo = pageMarginBoxes[name];\n if (boxInfo) {\n const container = marginBoxContainers[name];\n const boxInstance = this.pageMarginBoxInstances[name];\n const boxParam = new SingleBoxMarginBoxSizingParam(\n container,\n (boxInstance as any).style,\n isHorizontal,\n scope,\n clientLayout,\n );\n containers[boxInfo.positionAlongVariableDimension] = container;\n boxInstances[boxInfo.positionAlongVariableDimension] = boxInstance;\n boxParams[boxInfo.positionAlongVariableDimension] = boxParam;\n }\n }\n\n // determine sizes\n const evaluatedDim = {\n start: dimensions.start.evaluate(context) as number,\n end: dimensions.end.evaluate(context) as number,\n extent: dimensions.extent.evaluate(context) as number,\n };\n let sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n let needRecalculate: boolean = false;\n\n // Check max-width/max-height\n const maxOuterSizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n Object.keys(containers).forEach((n) => {\n const name = n as MarginBoxPositionAlongVariableDimension;\n const maxSize = PageMaster.toExprAuto(\n scope,\n boxInstances[name].style[isHorizontal ? \"max-width\" : \"max-height\"],\n dimensions.extent,\n );\n if (maxSize) {\n const evaluatedMaxSize = maxSize.evaluate(context) as number;\n if (sizes[name] > evaluatedMaxSize) {\n const p = (boxParams[name] = new FixedSizeMarginBoxSizingParam(\n containers[name],\n boxInstances[name].style,\n isHorizontal,\n scope,\n clientLayout,\n evaluatedMaxSize,\n ));\n maxOuterSizes[name] = p.getOuterSize();\n needRecalculate = true;\n }\n }\n });\n if (needRecalculate) {\n sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n needRecalculate = false;\n [START, CENTER, END].forEach((name) => {\n sizes[name] = maxOuterSizes[name] || sizes[name];\n });\n }\n\n // Check min-width/min-height\n const minOuterSizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n Object.keys(containers).forEach((n) => {\n const name = n as MarginBoxPositionAlongVariableDimension;\n const minSize = PageMaster.toExprAuto(\n scope,\n boxInstances[name].style[isHorizontal ? \"min-width\" : \"min-height\"],\n dimensions.extent,\n );\n if (minSize) {\n const evaluatedMinSize = minSize.evaluate(context) as number;\n if (sizes[name] < evaluatedMinSize) {\n const p = (boxParams[name] = new FixedSizeMarginBoxSizingParam(\n containers[name],\n boxInstances[name].style,\n isHorizontal,\n scope,\n clientLayout,\n evaluatedMinSize,\n ));\n minOuterSizes[name] = p.getOuterSize();\n needRecalculate = true;\n }\n }\n });\n if (needRecalculate) {\n sizes = this.getSizesOfMarginBoxesAlongVariableDimension(\n boxParams,\n evaluatedDim.extent,\n );\n [START, CENTER, END].forEach((name) => {\n sizes[name] = minOuterSizes[name] || sizes[name];\n });\n }\n\n // set sizes\n const endEdge = evaluatedDim.start + evaluatedDim.extent;\n const startEndSum =\n evaluatedDim.start + (evaluatedDim.start + evaluatedDim.extent);\n [START, CENTER, END].forEach((name) => {\n const outerSize = sizes[name];\n if (outerSize) {\n const container = containers[name];\n let offset = 0;\n switch (name) {\n case START:\n offset = isHorizontal ? container.left : container.top;\n break;\n case CENTER:\n offset = (startEndSum - outerSize) / 2;\n break;\n case END:\n offset = endEdge - outerSize;\n break;\n }\n if (isHorizontal) {\n container.setHorizontalPosition(\n offset,\n outerSize - container.getInsetLeft() - container.getInsetRight(),\n );\n } else {\n container.setVerticalPosition(\n offset,\n outerSize - container.getInsetTop() - container.getInsetBottom(),\n );\n }\n }\n });\n }\n\n private getSizesOfMarginBoxesAlongVariableDimension(\n boxParams: {\n [key in MarginBoxPositionAlongVariableDimension]?: MarginBoxSizingParam;\n },\n availableSize: number,\n ): { [key in MarginBoxPositionAlongVariableDimension]?: number } {\n const startBoxParam =\n boxParams[MarginBoxPositionAlongVariableDimension.START];\n const centerBoxParam =\n boxParams[MarginBoxPositionAlongVariableDimension.CENTER];\n const endBoxParam = boxParams[MarginBoxPositionAlongVariableDimension.END];\n const sizes: {\n [key in MarginBoxPositionAlongVariableDimension]?: number;\n } = {};\n if (!centerBoxParam) {\n const startEndSizes = this.distributeAutoMarginBoxSizes(\n startBoxParam,\n endBoxParam,\n availableSize,\n );\n if (startEndSizes.xSize) {\n sizes[MarginBoxPositionAlongVariableDimension.START] =\n startEndSizes.xSize;\n }\n if (startEndSizes.ySize) {\n sizes[MarginBoxPositionAlongVariableDimension.END] =\n startEndSizes.ySize;\n }\n } else {\n const params = [startBoxParam, endBoxParam].filter((p) => p);\n const startEndBoxParam = params.length\n ? new MultipleBoxesMarginBoxSizingParam(params)\n : null;\n const centerSizes = this.distributeAutoMarginBoxSizes(\n centerBoxParam,\n startEndBoxParam,\n availableSize,\n );\n if (centerSizes.xSize) {\n sizes[MarginBoxPositionAlongVariableDimension.CENTER] =\n centerSizes.xSize;\n }\n const centerSize = centerSizes.xSize || centerBoxParam.getOuterSize();\n const startEndAutoSize = (availableSize - centerSize) / 2;\n if (startBoxParam && startBoxParam.hasAutoSize()) {\n sizes[MarginBoxPositionAlongVariableDimension.START] = startEndAutoSize;\n }\n if (endBoxParam && endBoxParam.hasAutoSize()) {\n sizes[MarginBoxPositionAlongVariableDimension.END] = startEndAutoSize;\n }\n }\n return sizes;\n }\n\n /**\n * Distribute auto margin sizes among two margin boxes using an algorithm\n * specified in CSS Paged Media spec.\n * @param x Parameter for the first margin box. null if the box is not\n * generated.\n * @param y Parameter for the second margin box. null if the box is not\n * generated.\n * @param availableSize Available size for the margin boxes.\n * @returns Determined sizes for the two boxes. Each value is present only\n * when the size of the corresponding box is 'auto'.\n */\n private distributeAutoMarginBoxSizes(\n x: MarginBoxSizingParam,\n y: MarginBoxSizingParam,\n availableSize: number,\n ): { xSize: number | null; ySize: number | null } {\n const result: { xSize: number | null; ySize: number | null } = {\n xSize: null,\n ySize: null,\n };\n if (x && y) {\n if (x.hasAutoSize() && y.hasAutoSize()) {\n const xOuterMaxContentSize = x.getOuterMaxContentSize();\n const yOuterMaxContentSize = y.getOuterMaxContentSize();\n if (xOuterMaxContentSize > 0 && yOuterMaxContentSize > 0) {\n const maxContentSizeSum = xOuterMaxContentSize + yOuterMaxContentSize;\n if (maxContentSizeSum < availableSize) {\n result.xSize =\n (availableSize * xOuterMaxContentSize) / maxContentSizeSum;\n } else {\n const xOuterMinContentSize = x.getOuterMinContentSize();\n const yOuterMinContentSize = y.getOuterMinContentSize();\n const minContentSizeSum =\n xOuterMinContentSize + yOuterMinContentSize;\n if (minContentSizeSum < availableSize) {\n result.xSize =\n xOuterMinContentSize +\n ((availableSize - minContentSizeSum) *\n (xOuterMaxContentSize - xOuterMinContentSize)) /\n (maxContentSizeSum - minContentSizeSum);\n } else if (minContentSizeSum > 0) {\n result.xSize =\n (availableSize * xOuterMinContentSize) / minContentSizeSum;\n }\n }\n if (result.xSize > 0) {\n result.ySize = availableSize - result.xSize;\n }\n } else if (xOuterMaxContentSize > 0) {\n result.xSize = availableSize;\n } else if (yOuterMaxContentSize > 0) {\n result.ySize = availableSize;\n }\n } else if (x.hasAutoSize()) {\n result.xSize = Math.max(availableSize - y.getOuterSize(), 0);\n } else if (y.hasAutoSize()) {\n result.ySize = Math.max(availableSize - x.getOuterSize(), 0);\n }\n } else if (x) {\n if (x.hasAutoSize()) {\n result.xSize = availableSize;\n }\n } else if (y) {\n if (y.hasAutoSize()) {\n result.ySize = availableSize;\n }\n }\n return result;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n\n // Add an attribute to the element so that it can be refered from external\n // style sheets.\n container.element.setAttribute(\"data-vivliostyle-page-box\", true);\n }\n}\n\n/**\n * Interface used for parameters passed to distributeAutoMarginBoxSizes method.\n */\ninterface MarginBoxSizingParam {\n hasAutoSize(): boolean;\n\n getOuterMaxContentSize(): number;\n\n getOuterMinContentSize(): number;\n\n getOuterSize(): number;\n}\n\n/**\n * MarginBoxSizingParam for a single page-margin box.\n * @param container A container corresponding to the target margin box.\n * @param style Styles specified to the target margin box.\n */\nclass SingleBoxMarginBoxSizingParam implements MarginBoxSizingParam {\n private hasAutoSize_: boolean;\n private size: { [key in Sizing.Size]: number } | null = null;\n\n constructor(\n protected readonly container: Vtree.Container,\n style: { [key: string]: Css.Val },\n protected readonly isHorizontal: boolean,\n scope: Exprs.LexicalScope,\n private readonly clientLayout: Vtree.ClientLayout,\n ) {\n this.hasAutoSize_ = !PageMaster.toExprAuto(\n scope,\n style[isHorizontal ? \"width\" : \"height\"],\n new Exprs.Numeric(scope, 0, \"px\"),\n );\n }\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return this.hasAutoSize_;\n }\n\n private getSize(): { [key in Sizing.Size]: number } {\n if (!this.size) {\n const sizes = this.isHorizontal\n ? [Sizing.Size.MAX_CONTENT_WIDTH, Sizing.Size.MIN_CONTENT_WIDTH]\n : [Sizing.Size.MAX_CONTENT_HEIGHT, Sizing.Size.MIN_CONTENT_HEIGHT];\n this.size = Sizing.getSize(\n this.clientLayout,\n this.container.element,\n sizes,\n );\n }\n return this.size;\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n const size = this.getSize();\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n size[Sizing.Size.MAX_CONTENT_WIDTH] +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n size[Sizing.Size.MAX_CONTENT_HEIGHT] +\n this.container.getInsetBottom()\n );\n }\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n const size = this.getSize();\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n size[Sizing.Size.MIN_CONTENT_WIDTH] +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n size[Sizing.Size.MIN_CONTENT_HEIGHT] +\n this.container.getInsetBottom()\n );\n }\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n this.container.width +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n this.container.height +\n this.container.getInsetBottom()\n );\n }\n }\n}\n\n/**\n * MarginBoxSizingParam with which multiple margin boxes are treated as one\n * margin box. Each method querying a dimension returns the maximum of the boxes\n * multiplied by the number of the boxes.\n * @param params MarginBoxSizingParam's of the target margin boxes.\n */\nclass MultipleBoxesMarginBoxSizingParam implements MarginBoxSizingParam {\n constructor(private readonly params: MarginBoxSizingParam[]) {}\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return this.params.some((p) => p.hasAutoSize());\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n const sizes = this.params.map((p) => p.getOuterMaxContentSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n const sizes = this.params.map((p) => p.getOuterMinContentSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n const sizes = this.params.map((p) => p.getOuterSize());\n return Math.max.apply(null, sizes) * sizes.length;\n }\n}\n\n/**\n * MarginBoxSizingParam for a single page-margin box with a fixed size along the\n * variable dimension.\n * @param container A container corresponding to the target margin box.\n * @param style Styles specified to the target margin box.\n * @param size The fixed size (width or height) along the variable dimension.\n */\nclass FixedSizeMarginBoxSizingParam extends SingleBoxMarginBoxSizingParam {\n private fixedSize: number;\n\n constructor(\n container: Vtree.Container,\n style: { [key: string]: Css.Val },\n isHorizontal: boolean,\n scope: Exprs.LexicalScope,\n clientLayout: Vtree.ClientLayout,\n size: number,\n ) {\n super(container, style, isHorizontal, scope, clientLayout);\n this.fixedSize = size;\n }\n\n /**\n * @override\n */\n hasAutoSize(): boolean {\n return false;\n }\n\n /**\n * @override\n */\n getOuterMaxContentSize(): number {\n return this.getOuterSize();\n }\n\n /**\n * @override\n */\n getOuterMinContentSize(): number {\n return this.getOuterSize();\n }\n\n /**\n * @override\n */\n getOuterSize(): number {\n if (this.isHorizontal) {\n return (\n this.container.getInsetLeft() +\n this.fixedSize +\n this.container.getInsetRight()\n );\n } else {\n return (\n this.container.getInsetTop() +\n this.fixedSize +\n this.container.getInsetBottom()\n );\n }\n }\n}\n\nexport class PageRulePartitionInstance extends PageMaster.PartitionInstance<\n PageRulePartition\n> {\n borderBoxWidth: Exprs.Val = null;\n borderBoxHeight: Exprs.Val = null;\n marginTop: Exprs.Val = null;\n marginRight: Exprs.Val = null;\n marginBottom: Exprs.Val = null;\n marginLeft: Exprs.Val = null;\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageRulePartition: PageRulePartition,\n ) {\n super(parentInstance, pageRulePartition);\n }\n\n /**\n * @override\n */\n applyCascadeAndInit(\n cascade: CssCascade.CascadeInstance,\n docElementStyle: CssCascade.ElementStyle,\n ): void {\n const style = this.cascaded;\n for (const name in docElementStyle) {\n if (Object.prototype.hasOwnProperty.call(docElementStyle, name)) {\n if (name.match(/^column.*$/) || name.match(/^background-/)) {\n style[name] = docElementStyle[name];\n }\n }\n }\n super.applyCascadeAndInit(cascade, docElementStyle);\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n pageRuleMasterInstance.setPageAreaDimension({\n borderBoxWidth: this.borderBoxWidth,\n borderBoxHeight: this.borderBoxHeight,\n marginTop: this.marginTop,\n marginRight: this.marginRight,\n marginBottom: this.marginBottom,\n marginLeft: this.marginLeft,\n });\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const dim = this.resolvePageBoxDimensions({\n start: \"left\",\n end: \"right\",\n extent: \"width\",\n });\n this.borderBoxWidth = dim.borderBoxExtent;\n this.marginLeft = dim.marginStart;\n this.marginRight = dim.marginEnd;\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const dim = this.resolvePageBoxDimensions({\n start: \"top\",\n end: \"bottom\",\n extent: \"height\",\n });\n this.borderBoxHeight = dim.borderBoxExtent;\n this.marginTop = dim.marginStart;\n this.marginBottom = dim.marginEnd;\n }\n\n /**\n * Calculate page dimensions as specified in CSS Paged Media\n * (http://dev.w3.org/csswg/css-page/#page-model) Page border box extent and\n * margins. Since the containing block can be resized in the over-constrained\n * case, the sum of these values is not necessarily same to the original page\n * dimension specified in the page at-rules.\n */\n private resolvePageBoxDimensions(names: {\n start: string;\n end: string;\n extent: string;\n }): {\n borderBoxExtent: Exprs.Val;\n marginStart: Exprs.Val;\n marginEnd: Exprs.Val;\n } {\n const style = this.style;\n const pageSize = this.pageBox.pageSize;\n const scope = this.pageBox.scope;\n const startSide = names.start;\n const endSide = names.end;\n const extentName = names.extent;\n const pageExtent = pageSize[extentName].toExpr(scope, null);\n let extent = PageMaster.toExprAuto(scope, style[extentName], pageExtent);\n let marginStart = PageMaster.toExprAuto(\n scope,\n style[`margin-${startSide}`],\n pageExtent,\n );\n let marginEnd = PageMaster.toExprAuto(\n scope,\n style[`margin-${endSide}`],\n pageExtent,\n );\n const paddingStart = PageMaster.toExprZero(\n scope,\n style[`padding-${startSide}`],\n pageExtent,\n );\n const paddingEnd = PageMaster.toExprZero(\n scope,\n style[`padding-${endSide}`],\n pageExtent,\n );\n const borderStartWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${startSide}-width`],\n style[`border-${startSide}-style`],\n pageExtent,\n );\n const borderEndWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${endSide}-width`],\n style[`border-${endSide}-style`],\n pageExtent,\n );\n let remains = Exprs.sub(\n scope,\n pageExtent,\n Exprs.add(\n scope,\n Exprs.add(scope, borderStartWidth, paddingStart),\n Exprs.add(scope, borderEndWidth, paddingEnd),\n ),\n );\n\n // The dimensions are calculated as for a non-replaced block element in\n // normal flow (http://www.w3.org/TR/CSS21/visudet.html#blockwidth)\n if (!extent) {\n if (!marginStart) {\n marginStart = scope.zero;\n }\n if (!marginEnd) {\n marginEnd = scope.zero;\n }\n extent = Exprs.sub(\n scope,\n remains,\n Exprs.add(scope, marginStart, marginEnd),\n );\n } else {\n remains = Exprs.sub(scope, remains, extent);\n if (!marginStart && !marginEnd) {\n marginStart = Exprs.mul(scope, remains, new Exprs.Const(scope, 0.5));\n marginEnd = marginStart;\n } else if (marginStart) {\n marginEnd = Exprs.sub(scope, remains, marginStart);\n } else {\n marginStart = Exprs.sub(scope, remains, marginEnd);\n }\n }\n\n // TODO over-constrained case\n // \"if the values are over-constrained, instead of ignoring any margins, the\n // containing block is resized to coincide with the margin edges of the page\n // box.\" (CSS Paged Media http://dev.w3.org/csswg/css-page/#page-model)\n style[startSide] = new Css.Expr(marginStart);\n style[endSide] = new Css.Expr(marginEnd);\n style[`margin-${startSide}`] = Css.numericZero;\n style[`margin-${endSide}`] = Css.numericZero;\n style[`padding-${startSide}`] = new Css.Expr(paddingStart);\n style[`padding-${endSide}`] = new Css.Expr(paddingEnd);\n style[`border-${startSide}-width`] = new Css.Expr(borderStartWidth);\n style[`border-${endSide}-width`] = new Css.Expr(borderEndWidth);\n style[extentName] = new Css.Expr(extent);\n style[`max-${extentName}`] = new Css.Expr(extent);\n return {\n borderBoxExtent: Exprs.sub(\n scope,\n pageExtent,\n Exprs.add(scope, marginStart, marginEnd),\n ),\n marginStart,\n marginEnd,\n };\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n page.pageAreaElement = container.element as HTMLElement;\n\n // Set page area size for vw/vh unit calculation\n context.pageAreaWidth = parseFloat(page.pageAreaElement.style.width);\n context.pageAreaHeight = parseFloat(page.pageAreaElement.style.height);\n }\n}\n\nexport class PageMarginBoxPartitionInstance extends PageMaster.PartitionInstance<\n PageMarginBoxPartition\n> {\n boxInfo: PageMarginBoxInformation;\n suppressEmptyBoxGeneration: boolean = true;\n\n constructor(\n parentInstance: PageMaster.PageBoxInstance,\n pageMarginBoxPartition: PageMarginBoxPartition,\n ) {\n super(parentInstance, pageMarginBoxPartition);\n const name = pageMarginBoxPartition.marginBoxName;\n this.boxInfo = pageMarginBoxes[name];\n const pageRuleMasterInstance = parentInstance as PageRuleMasterInstance;\n pageRuleMasterInstance.pageMarginBoxInstances[name] = this;\n }\n\n /**\n * @override\n */\n prepareContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n docFaces: Font.DocumentFaces,\n clientLayout: Vtree.ClientLayout,\n ): void {\n this.applyVerticalAlign(context, container.element);\n super.prepareContainer(context, container, page, docFaces, clientLayout);\n }\n\n private applyVerticalAlign(context: Exprs.Context, element: Element) {\n Base.setCSSProperty(element, \"display\", \"flex\");\n const verticalAlign: Css.Val = this.getProp(context, \"vertical-align\");\n let flexAlign: string | null = null;\n if (verticalAlign === Css.getName(\"middle\")) {\n flexAlign = \"center\";\n } else if (verticalAlign === Css.getName(\"top\")) {\n flexAlign = \"flex-start\";\n } else if (verticalAlign === Css.getName(\"bottom\")) {\n flexAlign = \"flex-end\";\n }\n if (flexAlign) {\n Base.setCSSProperty(\n element,\n \"flex-flow\",\n this.vertical ? \"row\" : \"column\",\n );\n Base.setCSSProperty(element, \"justify-content\", flexAlign);\n }\n }\n\n /**\n * Calculate page-margin boxes positions along the variable dimension of the\n * page. For CENTER and END margin boxes, the position is calculated only if\n * the dimension (width or height) is non-auto, so that it can be resolved at\n * this point. If the dimension is auto, the calculation is deffered.\n */\n private positionAlongVariableDimension(\n names: { start: string; end: string; extent: string },\n dim: PageAreaDimension | null,\n ): void {\n const style = this.style;\n const scope = this.pageBox.scope;\n const startSide = names.start;\n const endSide = names.end;\n const extentName = names.extent;\n const isHorizontal = startSide === \"left\";\n const availableExtent = isHorizontal\n ? dim.borderBoxWidth\n : dim.borderBoxHeight;\n const extent = PageMaster.toExprAuto(\n scope,\n style[extentName],\n availableExtent,\n );\n const startOffset = isHorizontal ? dim.marginLeft : dim.marginTop;\n if (\n this.boxInfo.positionAlongVariableDimension ===\n MarginBoxPositionAlongVariableDimension.START\n ) {\n style[startSide] = new Css.Expr(startOffset);\n } else if (extent) {\n const marginStart = PageMaster.toExprZero(\n scope,\n style[`margin-${startSide}`],\n availableExtent,\n );\n const marginEnd = PageMaster.toExprZero(\n scope,\n style[`margin-${endSide}`],\n availableExtent,\n );\n const paddingStart = PageMaster.toExprZero(\n scope,\n style[`padding-${startSide}`],\n availableExtent,\n );\n const paddingEnd = PageMaster.toExprZero(\n scope,\n style[`padding-${endSide}`],\n availableExtent,\n );\n const borderStartWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${startSide}-width`],\n style[`border-${startSide}-style`],\n availableExtent,\n );\n const borderEndWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${endSide}-width`],\n style[`border-${endSide}-style`],\n availableExtent,\n );\n const outerExtent = Exprs.add(\n scope,\n extent,\n Exprs.add(\n scope,\n Exprs.add(scope, paddingStart, paddingEnd),\n Exprs.add(\n scope,\n Exprs.add(scope, borderStartWidth, borderEndWidth),\n Exprs.add(scope, marginStart, marginEnd),\n ),\n ),\n );\n switch (this.boxInfo.positionAlongVariableDimension) {\n case MarginBoxPositionAlongVariableDimension.CENTER:\n style[startSide] = new Css.Expr(\n Exprs.add(\n scope,\n startOffset,\n Exprs.div(\n scope,\n Exprs.sub(scope, availableExtent, outerExtent),\n new Exprs.Const(scope, 2),\n ),\n ),\n );\n break;\n case MarginBoxPositionAlongVariableDimension.END:\n style[startSide] = new Css.Expr(\n Exprs.sub(\n scope,\n Exprs.add(scope, startOffset, availableExtent),\n outerExtent,\n ),\n );\n break;\n }\n }\n }\n\n /**\n * Calculate page-margin boxes positions along the fixed dimension of the\n * page.\n */\n private positionAndSizeAlongFixedDimension(\n names: { inside: string; outside: string; extent: string },\n dim: PageAreaDimension | null,\n ): void {\n const style = this.style;\n const scope = this.pageBox.scope;\n const insideName = names.inside;\n const outsideName = names.outside;\n const extentName = names.extent;\n const pageMargin =\n dim[\n `margin${outsideName.charAt(0).toUpperCase()}${outsideName.substring(\n 1,\n )}`\n ];\n const marginInside = PageMaster.toExprZeroAuto(\n scope,\n style[`margin-${insideName}`],\n pageMargin,\n );\n const marginOutside = PageMaster.toExprZeroAuto(\n scope,\n style[`margin-${outsideName}`],\n pageMargin,\n );\n const paddingInside = PageMaster.toExprZero(\n scope,\n style[`padding-${insideName}`],\n pageMargin,\n );\n const paddingOutside = PageMaster.toExprZero(\n scope,\n style[`padding-${outsideName}`],\n pageMargin,\n );\n const borderInsideWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${insideName}-width`],\n style[`border-${insideName}-style`],\n pageMargin,\n );\n const borderOutsideWidth = PageMaster.toExprZeroBorder(\n scope,\n style[`border-${outsideName}-width`],\n style[`border-${outsideName}-style`],\n pageMargin,\n );\n const extent = PageMaster.toExprAuto(scope, style[extentName], pageMargin);\n let result: {\n extent: Exprs.Result;\n marginInside: Exprs.Result;\n marginOutside: Exprs.Result;\n } = null;\n\n function getComputedValues(\n context: Exprs.Context,\n ): {\n extent: Exprs.Result | null;\n marginInside: Exprs.Result | null;\n marginOutside: Exprs.Result | null;\n } {\n if (result) {\n return result;\n }\n result = {\n extent: extent ? extent.evaluate(context) : null,\n marginInside: marginInside ? marginInside.evaluate(context) : null,\n marginOutside: marginOutside ? marginOutside.evaluate(context) : null,\n };\n const pageMarginValue = pageMargin.evaluate(context);\n let borderAndPadding = 0;\n [\n borderInsideWidth,\n paddingInside,\n paddingOutside,\n borderOutsideWidth,\n ].forEach((x) => {\n if (x) {\n borderAndPadding += x.evaluate(context) as number;\n }\n });\n if (result.marginInside === null || result.marginOutside === null) {\n const total =\n borderAndPadding +\n (result.extent as number) +\n (result.marginInside as number) +\n (result.marginOutside as number);\n if (total > pageMarginValue) {\n if (result.marginInside === null) {\n result.marginInside = 0;\n }\n if (result.marginOutside === null) {\n result.marginOutside = 0;\n }\n }\n }\n if (\n result.extent !== null &&\n result.marginInside !== null &&\n result.marginOutside !== null\n ) {\n // over-constrained\n result.marginOutside = null;\n }\n if (\n result.extent === null &&\n result.marginInside !== null &&\n result.marginOutside !== null\n ) {\n result.extent =\n pageMarginValue -\n borderAndPadding -\n (result.marginInside as number) -\n (result.marginOutside as number);\n } else if (\n result.extent !== null &&\n (result.marginInside as number) === null &&\n (result.marginOutside as number) !== null\n ) {\n result.marginInside =\n pageMarginValue -\n borderAndPadding -\n (result.extent as number) -\n (result.marginOutside as number);\n } else if (\n result.extent !== null &&\n result.marginInside !== null &&\n result.marginOutside === null\n ) {\n result.marginOutside =\n pageMarginValue -\n borderAndPadding -\n (result.extent as number) -\n (result.marginInside as number);\n } else if (result.extent === null) {\n result.marginInside = result.marginOutside = 0;\n result.extent = pageMarginValue - borderAndPadding;\n } else {\n result.marginInside = result.marginOutside =\n (pageMarginValue - borderAndPadding - (result.extent as number)) / 2;\n }\n return result;\n }\n style[extentName] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).extent;\n return value === null ? 0 : value;\n },\n extentName,\n ),\n );\n style[`margin-${insideName}`] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).marginInside;\n return value === null ? 0 : value;\n },\n `margin-${insideName}`,\n ),\n );\n style[`margin-${outsideName}`] = new Css.Expr(\n new Exprs.Native(\n scope,\n function() {\n const value = getComputedValues(this).marginOutside;\n return value === null ? 0 : value;\n },\n `margin-${outsideName}`,\n ),\n );\n if (insideName === \"left\") {\n style[\"left\"] = new Css.Expr(\n Exprs.add(scope, dim.marginLeft, dim.borderBoxWidth),\n );\n } else if (insideName === \"top\") {\n style[\"top\"] = new Css.Expr(\n Exprs.add(scope, dim.marginTop, dim.borderBoxHeight),\n );\n }\n }\n\n /**\n * @override\n */\n initHorizontal(): void {\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n const dim = pageRuleMasterInstance.pageAreaDimension;\n if (this.boxInfo.isInLeftColumn) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"right\", outside: \"left\", extent: \"width\" },\n dim,\n );\n } else if (this.boxInfo.isInRightColumn) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"left\", outside: \"right\", extent: \"width\" },\n dim,\n );\n } else {\n this.positionAlongVariableDimension(\n { start: \"left\", end: \"right\", extent: \"width\" },\n dim,\n );\n }\n }\n\n /**\n * @override\n */\n initVertical(): void {\n const pageRuleMasterInstance = this\n .parentInstance as PageRuleMasterInstance;\n const dim = pageRuleMasterInstance.pageAreaDimension;\n if (this.boxInfo.isInTopRow) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"bottom\", outside: \"top\", extent: \"height\" },\n dim,\n );\n } else if (this.boxInfo.isInBottomRow) {\n this.positionAndSizeAlongFixedDimension(\n { inside: \"top\", outside: \"bottom\", extent: \"height\" },\n dim,\n );\n } else {\n this.positionAlongVariableDimension(\n { start: \"top\", end: \"bottom\", extent: \"height\" },\n dim,\n );\n }\n }\n\n /**\n * @override\n */\n finishContainer(\n context: Exprs.Context,\n container: Vtree.Container,\n page: Vtree.Page,\n column: Vtree.Container,\n columnCount: number,\n clientLayout: Vtree.ClientLayout,\n docFaces: Font.DocumentFaces,\n ): void {\n super.finishContainer(\n context,\n container,\n page,\n column,\n columnCount,\n clientLayout,\n docFaces,\n );\n\n // finishContainer is called only when the margin box is generated.\n // In this case, store the generated container for the margin box in the\n // page object. (except when it is a corner margin box, because size of a\n // corner margin box does not need to be adjusted after the layout)\n const marginBoxes = page.marginBoxes;\n const name = (this.pageBox as any).marginBoxName;\n const boxInfo = this.boxInfo;\n if (!boxInfo.isInLeftColumn && !boxInfo.isInRightColumn) {\n if (boxInfo.isInTopRow) {\n marginBoxes.top[name] = container;\n } else if (boxInfo.isInBottomRow) {\n marginBoxes.bottom[name] = container;\n }\n } else if (!boxInfo.isInTopRow && !boxInfo.isInBottomRow) {\n if (boxInfo.isInLeftColumn) {\n marginBoxes.left[name] = container;\n } else if (boxInfo.isInRightColumn) {\n marginBoxes.right[name] = container;\n }\n }\n }\n}\n\n/**\n * Dynamically generate and manage page masters corresponding to page at-rules.\n */\nexport class PageManager {\n private pageMasterCache: any = {} as {\n [key: string]: PageMaster.PageMasterInstance;\n };\n\n constructor(\n private readonly cascadeInstance: CssCascade.CascadeInstance,\n private readonly pageScope: Exprs.LexicalScope,\n private readonly rootPageBoxInstance: PageMaster.RootPageBoxInstance,\n private readonly context: Exprs.Context,\n private readonly docElementStyle: CssCascade.ElementStyle,\n ) {\n this.definePageProgression();\n }\n\n /**\n * Determine the page progression and define left/right/recto/verso pages.\n */\n private definePageProgression() {\n // TODO If a page break is forced before the root element, recto/verso pages\n // are no longer odd/even pages. left/right are reversed too.\n const scope = this.pageScope;\n const pageNumber = new Exprs.Named(scope, \"page-number\");\n const isEvenPage = new Exprs.Eq(\n scope,\n new Exprs.Modulo(scope, pageNumber, new Exprs.Const(scope, 2)),\n scope.zero,\n );\n scope.defineName(\"recto-page\", new Exprs.Not(scope, isEvenPage));\n scope.defineName(\"verso-page\", isEvenPage);\n const styleInstance: any /* Ops.StyleInstance */ = this.context;\n const pageProgression =\n styleInstance.pageProgression ||\n resolvePageProgression(this.docElementStyle);\n if (pageProgression === Constants.PageProgression.LTR) {\n scope.defineName(\"left-page\", isEvenPage);\n scope.defineName(\"right-page\", new Exprs.Not(scope, isEvenPage));\n } else {\n scope.defineName(\"left-page\", new Exprs.Not(scope, isEvenPage));\n scope.defineName(\"right-page\", isEvenPage);\n }\n }\n\n /**\n * Get cascaded page style specified in page context for the current page.\n */\n getCascadedPageStyle(): CssCascade.ElementStyle {\n const style = {} as CssCascade.ElementStyle;\n this.cascadeInstance.pushRule([], \"\", style);\n this.cascadeInstance.popRule();\n return style;\n }\n\n /**\n * Return a PageMasterInstance with page rules applied. Return a cached\n * instance if there already exists one with the same styles.\n * @param pageMasterInstance The original page master instance.\n * @param cascadedPageStyle Cascaded page style specified in page context.\n */\n getPageRulePageMaster(\n pageMasterInstance: PageMaster.PageMasterInstance,\n cascadedPageStyle: CssCascade.ElementStyle,\n ): PageMaster.PageMasterInstance {\n const pageMaster = pageMasterInstance.pageBox as PageMaster.PageMaster;\n\n // If no properies are specified in @page rules, use the original page\n // master.\n if (Object.keys(cascadedPageStyle).length === 0) {\n pageMaster.resetScope();\n return pageMasterInstance;\n }\n const key = this.makeCacheKey(cascadedPageStyle, pageMaster);\n let applied = this.pageMasterCache[key];\n if (!applied) {\n if (pageMaster.pseudoName === PageMaster.userAgentPageMasterPseudo) {\n // If the passed page master is a UA page master,\n // ignore it and generate a new page master from @page rules.\n applied = this.generatePageRuleMaster(cascadedPageStyle);\n } else {\n // Otherwise cascade some properties from @page rules to the page\n // master.\n applied = this.generateCascadedPageMaster(\n cascadedPageStyle,\n pageMaster,\n );\n }\n this.pageMasterCache[key] = applied;\n }\n applied.pageBox.resetScope();\n return applied;\n }\n\n /**\n * Generate a cache key from the specified styles and the original page master\n * key.\n */\n private makeCacheKey(\n style: CssCascade.ElementStyle,\n pageMaster: PageMaster.PageMaster,\n ): string {\n const propsStr = this.makeCascadeValueObjectKey(style);\n return `${pageMaster.key}^${propsStr}`;\n }\n\n private makeCascadeValueObjectKey(object: CssCascade.ElementStyle): string {\n const props = [] as string[];\n for (const prop in object) {\n if (Object.prototype.hasOwnProperty.call(object, prop)) {\n const val = object[prop];\n let str: string;\n if (val instanceof CssCascade.CascadeValue) {\n str = `${val.value}`;\n } else {\n str = this.makeCascadeValueObjectKey(val);\n }\n props.push(prop + str + (val.priority || \"\"));\n }\n }\n return props.sort().join(\"^\");\n }\n\n private generatePageRuleMaster(\n style: CssCascade.ElementStyle,\n ): PageRuleMasterInstance {\n const pageMaster = new PageRuleMaster(\n this.pageScope,\n this.rootPageBoxInstance.pageBox as PageMaster.RootPageBox,\n style,\n );\n const pageMasterInstance = pageMaster.createInstance(\n this.rootPageBoxInstance,\n );\n\n // Do the same initialization as in Ops.StyleInstance.prototype.init\n pageMasterInstance.applyCascadeAndInit(\n this.cascadeInstance,\n this.docElementStyle,\n );\n pageMasterInstance.resolveAutoSizing(this.context);\n return pageMasterInstance;\n }\n\n /**\n * Cascade some properties from `@page` rules to a page master.\n * For now, only 'width' and 'height' resolved from 'size' value are cascaded.\n * @param style Cascaded style in the page context\n * @param pageMaster The original page master\n */\n private generateCascadedPageMaster(\n style: CssCascade.ElementStyle,\n pageMaster: PageMaster.PageMaster,\n ): PageMaster.PageMasterInstance {\n const newPageMaster = pageMaster.clone({\n pseudoName: pageRuleMasterPseudoName,\n });\n const pageMasterStyle = newPageMaster.specified;\n const size = style[\"size\"];\n if (size) {\n const pageSize = resolvePageSizeAndBleed(style as any);\n const priority = size.priority;\n pageMasterStyle[\"width\"] = CssCascade.cascadeValues(\n this.context,\n pageMasterStyle[\"width\"],\n new CssCascade.CascadeValue(pageSize.width, priority),\n );\n pageMasterStyle[\"height\"] = CssCascade.cascadeValues(\n this.context,\n pageMasterStyle[\"height\"],\n new CssCascade.CascadeValue(pageSize.height, priority),\n );\n }\n\n // Transfer counter properties to the page style so that these specified in\n // the page master are also effective. Note that these values (if specified)\n // always override values in page contexts.\n [\"counter-reset\", \"counter-increment\"].forEach((name) => {\n if (pageMasterStyle[name]) {\n style[name] = pageMasterStyle[name];\n }\n });\n const pageMasterInstance = newPageMaster.createInstance(\n this.rootPageBoxInstance,\n ) as PageMaster.PageMasterInstance;\n\n // Do the same initialization as in Ops.StyleInstance.prototype.init\n pageMasterInstance.applyCascadeAndInit(\n this.cascadeInstance,\n this.docElementStyle,\n );\n pageMasterInstance.resolveAutoSizing(this.context);\n return pageMasterInstance;\n }\n}\n\nexport class CheckPageTypeAction extends CssCascade.ChainedAction {\n constructor(public readonly pageType: string) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n if (cascadeInstance.currentPageType === this.pageType) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 3;\n }\n\n /**\n * @override\n */\n makePrimary(cascade: CssCascade.Cascade): boolean {\n if (this.chained) {\n cascade.insertInTable(cascade.pagetypes, this.pageType, this.chained);\n }\n return true;\n }\n}\n\nexport class IsFirstPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const pageNumber = new Exprs.Named(this.scope, \"page-number\");\n if (pageNumber.evaluate(cascadeInstance.context) === 1) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 2;\n }\n}\n\nexport class IsLeftPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const leftPage = new Exprs.Named(this.scope, \"left-page\");\n if (leftPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsRightPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const rightPage = new Exprs.Named(this.scope, \"right-page\");\n if (rightPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsRectoPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const rectoPage = new Exprs.Named(this.scope, \"recto-page\");\n if (rectoPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\nexport class IsVersoPageAction extends CssCascade.ChainedAction {\n constructor(public readonly scope: Exprs.LexicalScope) {\n super();\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n const versoPage = new Exprs.Named(this.scope, \"verso-page\");\n if (versoPage.evaluate(cascadeInstance.context)) {\n this.chained.apply(cascadeInstance);\n }\n }\n\n /**\n * @override\n */\n getPriority(): number {\n return 1;\n }\n}\n\n/**\n * Action applying an at-page rule\n */\nexport class ApplyPageRuleAction extends CssCascade.ApplyRuleAction {\n constructor(style: CssCascade.ElementStyle, specificity: number) {\n super(style, specificity, null, null, null);\n }\n\n /**\n * @override\n */\n apply(cascadeInstance: CssCascade.CascadeInstance): void {\n mergeInPageRule(\n cascadeInstance.context,\n cascadeInstance.currentStyle,\n this.style,\n this.specificity,\n cascadeInstance,\n );\n }\n}\n\n/**\n * Merge page styles, including styles specified on page-margin boxes,\n * considering specificity. Intended to be used in place of\n * CssCascade.mergeIn, which is for element styles.\n */\nexport function mergeInPageRule(\n context: Exprs.Context,\n target: CssCascade.ElementStyle,\n style: CssCascade.ElementStyle,\n specificity: number,\n cascadeInstance: CssCascade.CascadeInstance,\n): void {\n CssCascade.mergeIn(context, target, style, specificity, null, null, null);\n const marginBoxes = style[marginBoxesKey];\n if (marginBoxes) {\n const targetMap = CssCascade.getMutableStyleMap(target, marginBoxesKey);\n for (const boxName in marginBoxes) {\n if (marginBoxes.hasOwnProperty(boxName)) {\n let targetBox = targetMap[boxName];\n if (!targetBox) {\n targetBox = {} as CssCascade.ElementStyle;\n targetMap[boxName] = targetBox;\n }\n CssCascade.mergeIn(\n context,\n targetBox,\n marginBoxes[boxName],\n specificity,\n null,\n null,\n null,\n );\n }\n }\n }\n}\n\n/**\n * ParserHandler for `@page` rules. It handles properties specified with page\n * contexts. It also does basic cascading (which can be done without information\n * other than the page rules themselves) and stores the result in `pageProps`\n * object as a map from page selectors to sets of properties. This result is\n * later used for adding `@page` rules to the real DOM, which are then used by\n * the PDF renderer (Chromium) to determine page sizes.\n */\nexport class PageParserHandler extends CssCascade.CascadeParserHandler\n implements CssValidator.PropertyReceiver {\n private currentPageSelectors: {\n selectors: string[] | null;\n specificity: number;\n }[] = [];\n private currentNamedPageSelector: string = \"\";\n private currentPseudoPageClassSelectors: string[] = [];\n\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n parent: CssCascade.CascadeParserHandler,\n validatorSet: CssValidator.ValidatorSet,\n private readonly pageProps: { [key: string]: CssCascade.ElementStyle },\n ) {\n super(scope, owner, null, parent, null, validatorSet, false);\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n this.startSelectorRule();\n }\n\n /**\n * @override\n */\n tagSelector(ns: string | null, name: string | null): void {\n Asserts.assert(name);\n this.currentNamedPageSelector = name;\n if (name) {\n this.chain.push(new CheckPageTypeAction(name));\n this.specificity += 65536;\n }\n }\n\n /**\n * @override\n */\n pseudoclassSelector(name: string, params: (number | string)[]): void {\n if (params) {\n this.reportAndSkip(\n `E_INVALID_PAGE_SELECTOR :${name}(${params.join(\"\")})`,\n );\n }\n this.currentPseudoPageClassSelectors.push(`:${name}`);\n switch (name.toLowerCase()) {\n case \"first\":\n this.chain.push(new IsFirstPageAction(this.scope));\n this.specificity += 256;\n break;\n case \"left\":\n this.chain.push(new IsLeftPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"right\":\n this.chain.push(new IsRightPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"recto\":\n this.chain.push(new IsRectoPageAction(this.scope));\n this.specificity += 1;\n break;\n case \"verso\":\n this.chain.push(new IsVersoPageAction(this.scope));\n this.specificity += 1;\n break;\n default:\n this.reportAndSkip(`E_INVALID_PAGE_SELECTOR :${name}`);\n break;\n }\n }\n\n /**\n * Save currently processed selector and reset variables.\n */\n private finishSelector() {\n let selectors: string[];\n if (\n !this.currentNamedPageSelector &&\n !this.currentPseudoPageClassSelectors.length\n ) {\n selectors = null;\n } else {\n selectors = [this.currentNamedPageSelector].concat(\n this.currentPseudoPageClassSelectors.sort(),\n );\n }\n this.currentPageSelectors.push({\n selectors,\n specificity: this.specificity,\n });\n this.currentNamedPageSelector = \"\";\n this.currentPseudoPageClassSelectors = [];\n }\n\n /**\n * @override\n */\n nextSelector(): void {\n this.finishSelector();\n super.nextSelector();\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n this.finishSelector();\n super.startRuleBody();\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n // we limit 'bleed' and 'marks' to be effective only when specified without\n // page selectors\n if (\n (name === \"bleed\" || name === \"marks\") &&\n !this.currentPageSelectors.some((s) => s.selectors === null)\n ) {\n return;\n }\n super.simpleProperty(name, value, important);\n const cascVal = CssCascade.getProp(this.elementStyle, name);\n const pageProps = this.pageProps;\n if (name === \"bleed\" || name === \"marks\") {\n if (!pageProps[\"\"]) {\n pageProps[\"\"] = {} as CssCascade.ElementStyle;\n }\n\n // we can simply overwrite without considering specificity\n // since 'bleed' and 'marks' always come from a page rule without page\n // selectors.\n Object.keys(pageProps).forEach((selector) => {\n CssCascade.setProp(pageProps[selector], name, cascVal);\n });\n } else if (name === \"size\") {\n const noPageSelectorProps = pageProps[\"\"];\n this.currentPageSelectors.forEach((s) => {\n // update specificity to reflect the specificity of the selector\n let result = new CssCascade.CascadeValue(\n cascVal.value,\n cascVal.priority + s.specificity,\n );\n const selector = s.selectors ? s.selectors.join(\"\") : \"\";\n let props = pageProps[selector];\n if (!props) {\n // since no properties for this selector have been stored before,\n // we can simply set the 'size', 'bleed' and 'marks' properties.\n props = pageProps[selector] = {} as CssCascade.ElementStyle;\n CssCascade.setProp(props, name, result);\n if (noPageSelectorProps) {\n [\"bleed\", \"marks\"].forEach((n) => {\n if (noPageSelectorProps[n]) {\n CssCascade.setProp(props, n, noPageSelectorProps[n]);\n }\n }, this);\n }\n } else {\n // consider specificity when setting 'size' property.\n // we don't have to set 'bleed' and 'marks' since they should have\n // been already updated.\n const prevCascVal = CssCascade.getProp(props, name);\n result = prevCascVal\n ? CssCascade.cascadeValues(null, result, prevCascVal)\n : result;\n CssCascade.setProp(props, name, result);\n }\n });\n }\n }\n\n /**\n * @override\n */\n insertNonPrimary(action: CssCascade.CascadeAction): void {\n // We represent page rules without selectors by *, though it is illegal in\n // CSS\n this.cascade.insertInTable(this.cascade.pagetypes, \"*\", action);\n }\n\n /**\n * @override\n */\n makeApplyRuleAction(specificity: number): CssCascade.ApplyRuleAction {\n return new ApplyPageRuleAction(this.elementStyle, specificity);\n }\n\n /**\n * @override\n */\n startPageMarginBoxRule(name: string): void {\n const marginBoxMap = CssCascade.getMutableStyleMap(\n this.elementStyle,\n marginBoxesKey,\n );\n let boxStyle = marginBoxMap[name];\n if (!boxStyle) {\n boxStyle = {} as CssCascade.ElementStyle;\n marginBoxMap[name] = boxStyle;\n }\n const handler = new PageMarginBoxParserHandler(\n this.scope,\n this.owner,\n this.validatorSet,\n boxStyle,\n );\n this.owner.pushHandler(handler);\n }\n}\n\n/**\n * Parser handler for a page-margin box rule.\n */\nexport class PageMarginBoxParserHandler extends CssParser.SlaveParserHandler\n implements CssValidator.PropertyReceiver {\n constructor(\n scope: Exprs.LexicalScope,\n owner: CssParser.DispatchParserHandler,\n public readonly validatorSet: CssValidator.ValidatorSet,\n public readonly boxStyle: CssCascade.ElementStyle,\n ) {\n super(scope, owner, false);\n }\n\n /**\n * @override\n */\n property(name: string, value: Css.Val, important: boolean): void {\n this.validatorSet.validatePropertyAndHandleShorthand(\n name,\n value,\n important,\n this,\n );\n }\n\n /**\n * @override\n */\n invalidPropertyValue(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY_VALUE ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n unknownProperty(name: string, value: Css.Val): void {\n this.report(`E_INVALID_PROPERTY ${name}: ${value.toString()}`);\n }\n\n /**\n * @override\n */\n simpleProperty(name: string, value: Css.Val, important): void {\n const specificity = important\n ? this.getImportantSpecificity()\n : this.getBaseSpecificity();\n const cascval = new CssCascade.CascadeValue(value, specificity);\n CssCascade.setProp(this.boxStyle, name, cascval);\n }\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Urls - URL Utilities\n */\n\n/**\n * transform all urls in attributeValue using documentURLTransformer.\n *\n * @returns transformed attributeValue\n */\n\nexport const transformURIs = (\n attributeValue,\n baseUrl,\n documentURLTransformer,\n) =>\n attributeValue\n .replace(\n /[uU][rR][lL]\\(\\s*\"((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^\"\\r\\n])+)\"/gm,\n (match, m1) =>\n `url(\"${documentURLTransformer.transformURL(m1, baseUrl)}\"`,\n )\n .replace(\n /[uU][rR][lL]\\(\\s*'((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^'\\r\\n])+)'/gm,\n (match, m1) =>\n `url('${documentURLTransformer.transformURL(m1, baseUrl)}'`,\n )\n .replace(\n /[uU][rR][lL]\\(\\s*((\\\\([^0-9a-fA-F]+|[0-9a-fA-F]+\\s*)|[^\"'\\r\\n\\)\\s])+)/gm,\n (match, m1) => `url(${documentURLTransformer.transformURL(m1, baseUrl)}`,\n );\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Vgen - View tree generator.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as Diff from \"./diff\";\nimport * as Display from \"./display\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Matchers from \"./matchers\";\nimport * as PageFloats from \"./page-floats\";\nimport * as Plugin from \"./plugin\";\nimport * as PseudoElement from \"./pseudo-element\";\nimport * as RepetitiveElement from \"./repetitive-element\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Urls from \"./urls\";\nimport * as Vtree from \"./vtree\";\nimport * as Layout from \"./layout\";\nimport { XmlDoc } from \"./types\";\n\nconst namespacePrefixMap = {};\n\nexport const frontEdgeBlackListHor: { [key: string]: string } = {\n \"text-indent\": \"0px\",\n \"margin-top\": \"0px\",\n \"padding-top\": \"0px\",\n \"border-top-width\": \"0px\",\n \"border-top-style\": \"none\",\n \"border-top-color\": \"transparent\",\n \"border-top-left-radius\": \"0px\",\n \"border-top-right-radius\": \"0px\",\n};\n\nexport const frontEdgeBlackListVert: { [key: string]: string } = {\n \"text-indent\": \"0px\",\n \"margin-right\": \"0px\",\n \"padding-right\": \"0px\",\n \"border-right-width\": \"0px\",\n \"border-right-style\": \"none\",\n \"border-right-color\": \"transparent\",\n \"border-top-right-radius\": \"0px\",\n \"border-bottom-right-radius\": \"0px\",\n};\n\nexport const frontEdgeUnforcedBreakBlackListHor: { [key: string]: string } = {\n \"margin-top\": \"0px\",\n};\n\nexport const frontEdgeUnforcedBreakBlackListVert: { [key: string]: string } = {\n \"margin-right\": \"0px\",\n};\n\nexport type CustomRenderer = (\n p1: Element,\n p2: Element,\n p3: { [key: string]: Css.Val },\n) => Task.Result<Element>;\n\nexport interface CustomRendererFactory {\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): CustomRenderer;\n}\n\n/**\n * Creates an epubReadingSystem object in the iframe.contentWindow.navigator\n * when load event fires.\n */\nexport function initIFrame(iframe: HTMLIFrameElement): void {\n iframe.addEventListener(\n \"load\",\n () => {\n iframe.contentWindow.navigator[\"epubReadingSystem\"] = {\n name: \"adapt\",\n version: \"0.1\",\n layoutStyle: \"paginated\",\n hasFeature: function(name, version) {\n switch (name) {\n case \"mouse-events\":\n return true;\n }\n return false;\n },\n };\n },\n false,\n );\n}\n\nexport interface StylerProducer {\n getStylerForDoc(xmldoc: XmlDoc.XMLDocHolder): CssStyler.AbstractStyler;\n}\n\nexport class ViewFactory extends Base.SimpleEventTarget\n implements Vtree.LayoutContext {\n private static SVG_URL_ATTRIBUTES: string[] = [\n \"color-profile\",\n \"clip-path\",\n \"cursor\",\n \"filter\",\n \"marker\",\n \"marker-start\",\n \"marker-end\",\n \"marker-mid\",\n \"fill\",\n \"stroke\",\n \"mask\",\n ];\n document: Document;\n exprContentListener: Vtree.ExprContentListener;\n\n // provided by layout\n nodeContext: Vtree.NodeContext | null = null;\n viewRoot: Element | null = null;\n isFootnote: boolean = false;\n sourceNode: Node | null = null;\n offsetInNode: number = 0;\n\n // computed\n // TODO: only set it on NodeContext\n viewNode: Node | null = null;\n\n constructor(\n public readonly flowName: string,\n public readonly context: Exprs.Context,\n public readonly viewport: Viewport,\n public readonly styler: CssStyler.Styler,\n public readonly regionIds: string[],\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n public readonly docFaces: Font.DocumentFaces,\n public readonly footnoteStyle: CssCascade.ElementStyle,\n public readonly stylerProducer: StylerProducer,\n public readonly page: Vtree.Page,\n public readonly customRenderer: CustomRenderer,\n public readonly fallbackMap: { [key: string]: string },\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n ) {\n super();\n this.document = viewport.document;\n this.exprContentListener = styler.counterListener.getExprContentListener();\n }\n\n /**\n * @override\n */\n clone(): Vtree.LayoutContext {\n return new ViewFactory(\n this.flowName,\n this.context,\n this.viewport,\n this.styler,\n this.regionIds,\n this.xmldoc,\n this.docFaces,\n this.footnoteStyle,\n this.stylerProducer,\n this.page,\n this.customRenderer,\n this.fallbackMap,\n this.documentURLTransformer,\n );\n }\n\n createPseudoelementShadow(\n element: Element,\n isRoot: boolean,\n cascStyle: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n parentShadow: Vtree.ShadowContext,\n subShadow: Vtree.ShadowContext,\n ): Vtree.ShadowContext {\n const pseudoMap = this.getPseudoMap(\n cascStyle,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n context,\n );\n if (!pseudoMap) {\n return subShadow;\n }\n const addedNames = [];\n const root = PseudoElement.document.createElementNS(Base.NS.SHADOW, \"root\");\n let att = root;\n for (const name of PseudoElement.pseudoNames) {\n let elem: Element;\n if (name) {\n if (!pseudoMap[name]) {\n continue;\n }\n if (name == \"footnote-marker\" && !(isRoot && this.isFootnote)) {\n continue;\n }\n if (name.match(/^first-/)) {\n const display = computedStyle[\"display\"];\n if (!display || display === Css.ident.inline) {\n continue;\n }\n }\n if (name === \"before\" || name === \"after\") {\n const content = pseudoMap[name][\"content\"];\n if (\n !content ||\n content === Css.ident.normal ||\n content === Css.ident.none\n ) {\n continue;\n }\n }\n addedNames.push(name);\n elem = PseudoElement.document.createElementNS(Base.NS.XHTML, \"span\");\n PseudoElement.setPseudoName(elem, name);\n } else {\n elem = PseudoElement.document.createElementNS(\n Base.NS.SHADOW,\n \"content\",\n );\n }\n att.appendChild(elem);\n if (name.match(/^first-/)) {\n att = elem;\n }\n }\n if (!addedNames.length) {\n return subShadow;\n }\n const shadowStyler = new PseudoElement.PseudoelementStyler(\n element,\n cascStyle,\n styler,\n context,\n this.exprContentListener,\n );\n return new Vtree.ShadowContext(\n element,\n root,\n null,\n parentShadow,\n subShadow,\n Vtree.ShadowType.ROOTLESS,\n shadowStyler,\n );\n }\n\n getPseudoMap(\n cascStyle: CssCascade.ElementStyle,\n regionIds: string[],\n isFootnote: boolean,\n nodeContext: Vtree.NodeContext,\n context: Exprs.Context,\n ) {\n const pseudoMap = CssCascade.getStyleMap(cascStyle, \"_pseudos\");\n if (!pseudoMap) {\n return null;\n }\n const computedPseudoStyleMap = {};\n for (const key in pseudoMap) {\n const computedPseudoStyle = (computedPseudoStyleMap[key] = {});\n CssCascade.mergeStyle(computedPseudoStyle, pseudoMap[key], context);\n CssCascade.mergeViewConditionalStyles(\n computedPseudoStyle,\n context,\n pseudoMap[key],\n );\n CssCascade.forEachStylesInRegion(\n pseudoMap[key],\n regionIds,\n isFootnote,\n (regionId, regionStyle) => {\n CssCascade.mergeStyle(computedPseudoStyle, regionStyle, context);\n CssCascade.forEachViewConditionalStyles(\n regionStyle,\n (viewConditionalStyles) => {\n CssCascade.mergeStyle(\n computedPseudoStyle,\n viewConditionalStyles,\n context,\n );\n },\n );\n },\n );\n }\n return computedPseudoStyleMap;\n }\n\n createRefShadow(\n href: string,\n type: Vtree.ShadowType,\n element: Element,\n parentShadow: Vtree.ShadowContext,\n subShadow: Vtree.ShadowContext,\n ): Task.Result<Vtree.ShadowContext> {\n const self = this;\n const frame: Task.Frame<Vtree.ShadowContext> = Task.newFrame(\n \"createRefShadow\",\n );\n self.xmldoc.store.load(href).then((refDocParam) => {\n const refDoc = refDocParam;\n if (refDoc) {\n const refElement = refDoc.getElement(href);\n if (refElement) {\n const refStyler = self.stylerProducer.getStylerForDoc(refDoc);\n subShadow = new Vtree.ShadowContext(\n element,\n refElement,\n refDoc,\n parentShadow,\n subShadow,\n type,\n refStyler,\n );\n }\n }\n frame.finish(subShadow);\n });\n return frame.result();\n }\n\n createShadows(\n element: Element,\n isRoot,\n cascStyle: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n shadowContext: Vtree.ShadowContext,\n ): Task.Result<Vtree.ShadowContext> {\n const self = this;\n const frame: Task.Frame<Vtree.ShadowContext> = Task.newFrame(\n \"createShadows\",\n );\n const shadow: Vtree.ShadowContext = null;\n const templateURLVal = computedStyle[\"template\"];\n let cont: Task.Result<Vtree.ShadowContext>;\n if (templateURLVal instanceof Css.URL) {\n const url = (templateURLVal as Css.URL).url;\n cont = self.createRefShadow(\n url,\n Vtree.ShadowType.ROOTLESS,\n element,\n shadowContext,\n shadow,\n );\n } else {\n cont = Task.newResult(shadow);\n }\n cont.then((shadow) => {\n let cont1: Task.Result<Vtree.ShadowContext> = null;\n if (element.namespaceURI == Base.NS.SHADOW) {\n if (element.localName == \"include\") {\n let href = element.getAttribute(\"href\");\n let xmldoc: XmlDoc.XMLDocHolder = null;\n if (href) {\n xmldoc = shadowContext ? shadowContext.xmldoc : self.xmldoc;\n } else if (shadowContext) {\n if (shadowContext.owner.namespaceURI == Base.NS.XHTML) {\n href = shadowContext.owner.getAttribute(\"href\");\n } else {\n href = shadowContext.owner.getAttributeNS(Base.NS.XLINK, \"href\");\n }\n xmldoc = shadowContext.parentShadow\n ? shadowContext.parentShadow.xmldoc\n : self.xmldoc;\n }\n if (href) {\n href = Base.resolveURL(href, xmldoc.url);\n cont1 = self.createRefShadow(\n href,\n Vtree.ShadowType.ROOTED,\n element,\n shadowContext,\n shadow,\n );\n }\n }\n }\n if (cont1 == null) {\n cont1 = Task.newResult(shadow);\n }\n let cont2: Task.Result<Vtree.ShadowContext> = null;\n cont1.then((shadow) => {\n if (computedStyle[\"display\"] === Css.ident.table_cell) {\n const url = Base.resolveURL(\n \"user-agent.xml#table-cell\",\n Base.resourceBaseURL,\n );\n cont2 = self.createRefShadow(\n url,\n Vtree.ShadowType.ROOTLESS,\n element,\n shadowContext,\n shadow,\n );\n } else {\n cont2 = Task.newResult(shadow);\n }\n });\n cont2.then((shadow) => {\n shadow = self.createPseudoelementShadow(\n element,\n isRoot,\n cascStyle,\n computedStyle,\n styler,\n context,\n shadowContext,\n shadow,\n );\n frame.finish(shadow);\n });\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n setViewRoot(viewRoot: Element, isFootnote: boolean) {\n this.viewRoot = viewRoot;\n this.isFootnote = isFootnote;\n }\n\n /**\n * @return vertical\n */\n computeStyle(\n vertical: boolean,\n rtl: boolean,\n style: CssCascade.ElementStyle,\n computedStyle: { [key: string]: Css.Val },\n ): boolean {\n const context = this.context;\n const cascMap = CssCascade.flattenCascadedStyle(\n style,\n context,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n );\n vertical = CssCascade.isVertical(cascMap, context, vertical);\n rtl = CssCascade.isRtl(cascMap, context, rtl);\n const self = this;\n CssCascade.convertToPhysical(\n cascMap,\n computedStyle,\n vertical,\n rtl,\n (name, cascVal) => {\n let value = cascVal.evaluate(context, name);\n if (name == \"font-family\") {\n value = self.docFaces.filterFontFamily(value);\n }\n return value;\n },\n );\n\n // Compute values of display, position and float\n const position = computedStyle[\"position\"] as Css.Ident;\n const float = computedStyle[\"float\"] as Css.Ident;\n const displayValues = Display.getComputedDislayValue(\n (computedStyle[\"display\"] as Css.Ident) || Css.ident.inline,\n position,\n float,\n this.sourceNode === this.xmldoc.root,\n );\n [\"display\", \"position\", \"float\"].forEach((name) => {\n if (displayValues[name]) {\n computedStyle[name] = displayValues[name];\n }\n });\n return vertical;\n }\n\n private inheritFromSourceParent(\n elementStyle: CssCascade.ElementStyle,\n ): { lang: string | null; elementStyle: CssCascade.ElementStyle } {\n let node = this.nodeContext.sourceNode;\n const styles = [];\n let lang: string | null = null;\n\n // TODO: this is hacky. We need to recover the path through the shadow\n // trees, but we do not have the full shadow tree structure at this point.\n // This code handles coming out of the shadow trees, but does not go back in\n // (through shadow:content element).\n let shadowContext = this.nodeContext.shadowContext;\n let steps = -1;\n while (node && node.nodeType == 1) {\n const shadowRoot = shadowContext && shadowContext.root == node;\n if (!shadowRoot || shadowContext.type == Vtree.ShadowType.ROOTLESS) {\n const styler = shadowContext\n ? (shadowContext.styler as CssStyler.AbstractStyler)\n : this.styler;\n const nodeStyle = styler.getStyle(node as Element, false);\n styles.push(nodeStyle);\n lang = lang || Base.getLangAttribute(node as Element);\n }\n if (shadowRoot) {\n node = shadowContext.owner;\n shadowContext = shadowContext.parentShadow;\n } else {\n node = node.parentNode;\n steps++;\n }\n }\n const isRoot = steps === 0;\n const fontSize = this.context.queryUnitSize(\"em\", isRoot);\n const props = {\n \"font-size\": new CssCascade.CascadeValue(\n new Css.Numeric(fontSize, \"px\"),\n 0,\n ),\n } as CssCascade.ElementStyle;\n const inheritanceVisitor = new CssCascade.InheritanceVisitor(\n props,\n this.context,\n );\n for (let i = styles.length - 1; i >= 0; --i) {\n const style = styles[i];\n const propList = [];\n for (const propName in style) {\n if (CssCascade.isInherited(propName)) {\n propList.push(propName);\n }\n }\n propList.sort(Css.processingOrderFn);\n for (const name of propList) {\n inheritanceVisitor.setPropName(name);\n const value = CssCascade.getProp(style, name);\n if (value.value !== Css.ident.inherit) {\n props[name] = value.filterValue(inheritanceVisitor);\n }\n }\n }\n for (const sname in elementStyle) {\n if (!CssCascade.isInherited(sname)) {\n props[sname] = elementStyle[sname];\n }\n }\n return { lang, elementStyle: props };\n }\n\n resolveURL(url: string): string {\n url = Base.resolveURL(url, this.xmldoc.url);\n return this.fallbackMap[url] || url;\n }\n\n inheritLangAttribute() {\n this.nodeContext.lang =\n Base.getLangAttribute(this.nodeContext.sourceNode as Element) ||\n (this.nodeContext.parent && this.nodeContext.parent.lang) ||\n this.nodeContext.lang;\n }\n\n transferPolyfilledInheritedProps(computedStyle: { [key: string]: Css.Val }) {\n const polyfilledInheritedProps = CssCascade.getPolyfilledInheritedProps().filter(\n (name) => computedStyle[name],\n );\n if (polyfilledInheritedProps.length) {\n let props = this.nodeContext.inheritedProps;\n if (this.nodeContext.parent) {\n props = this.nodeContext.inheritedProps = {};\n for (const n in this.nodeContext.parent.inheritedProps) {\n props[n] = this.nodeContext.parent.inheritedProps[n];\n }\n }\n polyfilledInheritedProps.forEach((name) => {\n const value = computedStyle[name];\n if (value) {\n if (value instanceof Css.Int) {\n props[name] = (value as Css.Int).num;\n } else if (value instanceof Css.Ident) {\n props[name] = (value as Css.Ident).name;\n } else if (value instanceof Css.Numeric) {\n const numericVal = value as Css.Numeric;\n switch (numericVal.unit) {\n case \"dpi\":\n case \"dpcm\":\n case \"dppx\":\n props[name] =\n numericVal.num * Exprs.defaultUnitSizes[numericVal.unit];\n break;\n }\n } else {\n props[name] = value;\n }\n delete computedStyle[name];\n }\n });\n }\n }\n\n resolveFormattingContext(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n display: Css.Ident,\n position: Css.Ident,\n float: Css.Ident,\n isRoot: boolean,\n ) {\n const hooks: Plugin.ResolveFormattingContextHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.RESOLVE_FORMATTING_CONTEXT,\n );\n for (let i = 0; i < hooks.length; i++) {\n const formattingContext = hooks[i](\n nodeContext,\n firstTime,\n display,\n position,\n float,\n isRoot,\n );\n if (formattingContext) {\n nodeContext.formattingContext = formattingContext;\n return;\n }\n }\n }\n\n /**\n * @return holding true if children should be processed\n */\n private createElementView(\n firstTime: boolean,\n atUnforcedBreak: boolean,\n ): Task.Result<boolean> {\n const self = this;\n let needToProcessChildren = true;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createElementView\");\n\n // Figure out element's styles\n let element = self.sourceNode as Element;\n const styler = self.nodeContext.shadowContext\n ? (self.nodeContext.shadowContext.styler as CssStyler.AbstractStyler)\n : self.styler;\n let elementStyle = styler.getStyle(element, false);\n if (!self.nodeContext.shadowContext) {\n const offset = this.xmldoc.getElementOffset(element);\n Matchers.NthFragmentMatcher.registerFragmentIndex(\n offset,\n self.nodeContext.fragmentIndex,\n 0,\n );\n }\n const computedStyle = {};\n if (!self.nodeContext.parent) {\n const inheritedValues = self.inheritFromSourceParent(elementStyle);\n elementStyle = inheritedValues.elementStyle;\n self.nodeContext.lang = inheritedValues.lang;\n }\n const floatReference =\n elementStyle[\"float-reference\"] &&\n PageFloats.floatReferenceOf(\n elementStyle[\"float-reference\"].value.toString(),\n );\n if (\n self.nodeContext.parent &&\n floatReference &&\n PageFloats.isPageFloat(floatReference)\n ) {\n // Since a page float will be detached from a view node of its parent,\n // inherited properties need to be inherited from its source parent.\n const inheritedValues = self.inheritFromSourceParent(elementStyle);\n elementStyle = inheritedValues.elementStyle;\n self.nodeContext.lang = inheritedValues.lang;\n }\n self.nodeContext.vertical = self.computeStyle(\n self.nodeContext.vertical,\n self.nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n styler.processContent(element, computedStyle);\n this.transferPolyfilledInheritedProps(computedStyle);\n this.inheritLangAttribute();\n if (computedStyle[\"direction\"]) {\n self.nodeContext.direction = computedStyle[\"direction\"].toString();\n }\n\n // Sort out the properties\n const flow = computedStyle[\"flow-into\"];\n if (flow && flow.toString() != self.flowName) {\n // foreign flow, don't create a view\n frame.finish(false);\n return frame.result();\n }\n let display = computedStyle[\"display\"];\n if (display === Css.ident.none) {\n // no content\n frame.finish(false);\n return frame.result();\n }\n const isRoot = self.nodeContext.parent == null;\n self.nodeContext.flexContainer = display === Css.ident.flex;\n self\n .createShadows(\n element,\n isRoot,\n elementStyle,\n computedStyle,\n styler,\n self.context,\n self.nodeContext.shadowContext,\n )\n .then((shadowParam) => {\n self.nodeContext.nodeShadow = shadowParam;\n const position = computedStyle[\"position\"];\n let floatSide = computedStyle[\"float\"];\n let clearSide = computedStyle[\"clear\"];\n const writingMode = self.nodeContext.vertical\n ? Css.ident.vertical_rl\n : Css.ident.horizontal_tb;\n const parentWritingMode = self.nodeContext.parent\n ? self.nodeContext.parent.vertical\n ? Css.ident.vertical_rl\n : Css.ident.horizontal_tb\n : writingMode;\n const isFlowRoot = Display.isFlowRoot(element);\n self.nodeContext.establishesBFC = Display.establishesBFC(\n display,\n position,\n floatSide,\n computedStyle[\"overflow\"],\n writingMode,\n parentWritingMode,\n isFlowRoot,\n );\n self.nodeContext.containingBlockForAbsolute = Display.establishesCBForAbsolute(\n position,\n );\n if (\n self.nodeContext.isInsideBFC() &&\n floatSide !== Css.ident.footnote &&\n !(floatReference && PageFloats.isPageFloat(floatReference))\n ) {\n // When the element is already inside a block formatting context\n // (except one from the root), float and clear can be controlled by\n // the browser and we don't need to care.\n floatSide = null;\n clearSide = null;\n }\n let floating =\n floatSide === Css.ident.left ||\n floatSide === Css.ident.right ||\n floatSide === Css.ident.top ||\n floatSide === Css.ident.bottom ||\n floatSide === Css.ident.inline_start ||\n floatSide === Css.ident.inline_end ||\n floatSide === Css.ident.block_start ||\n floatSide === Css.ident.block_end ||\n floatSide === Css.ident.snap_block ||\n floatSide === Css.ident.footnote;\n if (floatSide) {\n // Don't want to set it in view DOM CSS.\n delete computedStyle[\"float\"];\n if (floatSide === Css.ident.footnote) {\n if (self.isFootnote) {\n // No footnotes inside footnotes. self is most likely the root\n // of the footnote body being rendered in footnote area. Treat\n // as block.\n floating = false;\n computedStyle[\"display\"] = Css.ident.block;\n } else {\n computedStyle[\"display\"] = Css.ident.inline;\n }\n }\n }\n if (clearSide) {\n if (clearSide === Css.ident.inherit) {\n if (self.nodeContext.parent && self.nodeContext.parent.clearSide) {\n clearSide = Css.getName(self.nodeContext.parent.clearSide);\n }\n }\n if (\n clearSide === Css.ident.left ||\n clearSide === Css.ident.right ||\n clearSide === Css.ident.top ||\n clearSide === Css.ident.bottom ||\n clearSide === Css.ident.both ||\n clearSide === Css.ident.all ||\n clearSide === Css.ident.same\n ) {\n delete computedStyle[\"clear\"];\n if (\n computedStyle[\"display\"] &&\n computedStyle[\"display\"] != Css.ident.inline\n ) {\n self.nodeContext.clearSide = clearSide.toString();\n }\n }\n }\n const listItem =\n display === Css.ident.list_item &&\n computedStyle[\"ua-list-item-count\"];\n if (\n floating ||\n (computedStyle[\"break-inside\"] &&\n computedStyle[\"break-inside\"] !== Css.ident.auto)\n ) {\n self.nodeContext.breakPenalty++;\n }\n if (\n display &&\n display !== Css.ident.inline &&\n Display.isInlineLevel(display)\n ) {\n // Don't break inside ruby, inline-block, etc.\n self.nodeContext.breakPenalty++;\n }\n self.nodeContext.inline =\n (!floating && !display) ||\n Display.isInlineLevel(display) ||\n Display.isRubyInternalDisplay(display);\n self.nodeContext.display = display ? display.toString() : \"inline\";\n self.nodeContext.floatSide = floating ? floatSide.toString() : null;\n self.nodeContext.floatReference =\n floatReference || PageFloats.FloatReference.INLINE;\n self.nodeContext.floatMinWrapBlock =\n computedStyle[\"float-min-wrap-block\"] || null;\n self.nodeContext.columnSpan = computedStyle[\"column-span\"];\n if (!self.nodeContext.inline) {\n const breakAfter = computedStyle[\"break-after\"];\n if (breakAfter) {\n self.nodeContext.breakAfter = breakAfter.toString();\n }\n const breakBefore = computedStyle[\"break-before\"];\n if (breakBefore) {\n self.nodeContext.breakBefore = breakBefore.toString();\n }\n }\n self.nodeContext.verticalAlign =\n (computedStyle[\"vertical-align\"] &&\n computedStyle[\"vertical-align\"].toString()) ||\n \"baseline\";\n self.nodeContext.captionSide =\n (computedStyle[\"caption-side\"] &&\n computedStyle[\"caption-side\"].toString()) ||\n \"top\";\n const borderCollapse = computedStyle[\"border-collapse\"];\n if (!borderCollapse || borderCollapse === Css.getName(\"separate\")) {\n const borderSpacing = computedStyle[\"border-spacing\"];\n let inlineBorderSpacing;\n let blockBorderSpacing;\n if (borderSpacing) {\n if (borderSpacing.isSpaceList()) {\n inlineBorderSpacing = borderSpacing.values[0];\n blockBorderSpacing = borderSpacing.values[1];\n } else {\n inlineBorderSpacing = blockBorderSpacing = borderSpacing;\n }\n if (inlineBorderSpacing.isNumeric()) {\n self.nodeContext.inlineBorderSpacing = Css.toNumber(\n inlineBorderSpacing,\n self.context,\n );\n }\n if (blockBorderSpacing.isNumeric()) {\n self.nodeContext.blockBorderSpacing = Css.toNumber(\n blockBorderSpacing,\n self.context,\n );\n }\n }\n }\n self.nodeContext.footnotePolicy = computedStyle[\"footnote-policy\"];\n const firstPseudo = computedStyle[\"x-first-pseudo\"];\n if (firstPseudo) {\n const outerPseudo = self.nodeContext.parent\n ? self.nodeContext.parent.firstPseudo\n : null;\n self.nodeContext.firstPseudo = new Vtree.FirstPseudo(\n outerPseudo,\n /** Css.Int */\n firstPseudo.num,\n );\n }\n if (!self.nodeContext.inline) {\n self.processAfterIfcontinues(\n element,\n elementStyle,\n styler,\n self.context,\n );\n }\n const whitespace = computedStyle[\"white-space\"];\n if (whitespace) {\n const whitespaceValue = Vtree.whitespaceFromPropertyValue(\n whitespace.toString(),\n );\n if (whitespaceValue !== null) {\n self.nodeContext.whitespace = whitespaceValue;\n }\n }\n const hyphenateCharacter = computedStyle[\"hyphenate-character\"];\n if (hyphenateCharacter && hyphenateCharacter !== Css.ident.auto) {\n self.nodeContext.hyphenateCharacter = hyphenateCharacter.str;\n }\n const wordBreak = computedStyle[\"word-break\"];\n const overflowWrap = computedStyle[\"overflow-wrap\"] || [\"word-wrap\"];\n self.nodeContext.breakWord =\n wordBreak === Css.ident.break_all ||\n overflowWrap === Css.ident.break_word;\n\n // Resolve formatting context\n self.resolveFormattingContext(\n self.nodeContext,\n firstTime,\n display,\n position,\n floatSide,\n isRoot,\n );\n if (\n self.nodeContext.parent &&\n self.nodeContext.parent.formattingContext\n ) {\n firstTime = self.nodeContext.parent.formattingContext.isFirstTime(\n self.nodeContext,\n firstTime,\n );\n }\n if (!self.nodeContext.inline) {\n self.nodeContext.repeatOnBreak = self.processRepeatOnBreak(\n computedStyle,\n );\n self.findAndProcessRepeatingElements(element, styler);\n }\n\n // Create the view element\n let custom = false;\n let inner: Element = null;\n const fetchers = [];\n let ns = element.namespaceURI;\n let tag = element.localName;\n if (ns == Base.NS.XHTML) {\n if (\n tag == \"html\" ||\n tag == \"body\" ||\n tag == \"script\" ||\n tag == \"link\" ||\n tag == \"meta\"\n ) {\n tag = \"div\";\n } else if (tag == \"vide_\") {\n tag = \"video\";\n } else if (tag == \"audi_\") {\n tag = \"audio\";\n } else if (tag == \"object\") {\n custom = !!self.customRenderer;\n }\n if (element.getAttribute(PseudoElement.PSEUDO_ATTR)) {\n if (\n elementStyle[\"content\"] &&\n elementStyle[\"content\"].value &&\n elementStyle[\"content\"].value.url\n ) {\n tag = \"img\";\n }\n }\n } else if (ns == Base.NS.epub) {\n tag = \"span\";\n ns = Base.NS.XHTML;\n } else if (ns == Base.NS.FB2) {\n ns = Base.NS.XHTML;\n if (tag == \"image\") {\n tag = \"div\";\n const imageRef = element.getAttributeNS(Base.NS.XLINK, \"href\");\n if (imageRef && imageRef.charAt(0) == \"#\") {\n const imageBinary = self.xmldoc.getElement(imageRef);\n if (imageBinary) {\n inner = self.createElement(ns, \"img\");\n const mediaType =\n imageBinary.getAttribute(\"content-type\") || \"image/jpeg\";\n const innerSrc = `data:${mediaType};base64,${imageBinary.textContent.replace(\n /[ \\t\\n\\t]/g,\n \"\",\n )}`;\n fetchers.push(TaskUtil.loadElement(inner, innerSrc));\n }\n }\n } else {\n tag = fb2Remap[tag];\n }\n if (!tag) {\n tag = self.nodeContext.inline ? \"span\" : \"div\";\n }\n } else if (ns == Base.NS.NCX) {\n ns = Base.NS.XHTML;\n if (tag == \"ncx\" || tag == \"navPoint\") {\n tag = \"div\";\n } else if (tag == \"navLabel\") {\n // Cheat here. Translate source to HTML, so it will plug\n // in into the rest of the pipeline.\n tag = \"span\";\n const navParent = element.parentNode;\n if (navParent) {\n // find the content element\n let href: string | null = null;\n for (let c: Node = navParent.firstChild; c; c = c.nextSibling) {\n if (c.nodeType != 1) {\n continue;\n }\n const childElement = c as Element;\n if (\n childElement.namespaceURI == Base.NS.NCX &&\n childElement.localName == \"content\"\n ) {\n href = childElement.getAttribute(\"src\");\n break;\n }\n }\n if (href) {\n tag = \"a\";\n element = element.ownerDocument.createElementNS(ns, \"a\");\n element.setAttribute(\"href\", href);\n }\n }\n } else {\n tag = \"span\";\n }\n } else if (ns == Base.NS.SHADOW) {\n ns = Base.NS.XHTML;\n tag = self.nodeContext.inline ? \"span\" : \"div\";\n } else {\n custom = !!self.customRenderer;\n }\n if (listItem) {\n if (firstTime) {\n tag = \"li\";\n } else {\n tag = \"div\";\n display = Css.ident.block;\n computedStyle[\"display\"] = display;\n }\n } else if (tag == \"body\" || tag == \"li\") {\n tag = \"div\";\n } else if (tag == \"q\") {\n tag = \"span\";\n } else if (tag == \"a\") {\n const hp = computedStyle[\"hyperlink-processing\"];\n if (hp && hp.toString() != \"normal\") {\n tag = \"span\";\n }\n }\n if (computedStyle[\"behavior\"]) {\n const behavior = computedStyle[\"behavior\"].toString();\n if (behavior != \"none\" && self.customRenderer) {\n custom = true;\n }\n }\n if (\n (element as HTMLElement).dataset &&\n element.getAttribute(\"data-math-typeset\") === \"true\"\n ) {\n custom = true;\n }\n let elemResult: Task.Result<Element>;\n if (custom) {\n const parentNode = self.nodeContext.parent\n ? self.nodeContext.parent.viewNode\n : null;\n elemResult = self.customRenderer(\n element,\n parentNode as Element,\n computedStyle,\n );\n } else {\n elemResult = Task.newResult(null);\n }\n elemResult.then((result) => {\n if (result) {\n if (custom) {\n needToProcessChildren =\n result.getAttribute(\"data-adapt-process-children\") == \"true\";\n }\n } else {\n result = self.createElement(ns, tag);\n }\n if (tag == \"a\") {\n result.addEventListener(\"click\", self.page.hrefHandler, false);\n }\n if (inner) {\n self.applyPseudoelementStyle(self.nodeContext, \"inner\", inner);\n result.appendChild(inner);\n }\n if (\n result.localName == \"iframe\" &&\n result.namespaceURI == Base.NS.XHTML\n ) {\n initIFrame(result as HTMLIFrameElement);\n }\n const imageResolution = self.nodeContext.inheritedProps[\n \"image-resolution\"\n ] as number | undefined;\n const images: {\n image: HTMLElement;\n element: HTMLElement;\n fetcher: TaskUtil.Fetcher<string>;\n }[] = [];\n const cssWidth = computedStyle[\"width\"];\n const cssHeight = computedStyle[\"height\"];\n const attrWidth = element.getAttribute(\"width\");\n const attrHeight = element.getAttribute(\"height\");\n const hasAutoWidth =\n cssWidth === Css.ident.auto || (!cssWidth && !attrWidth);\n const hasAutoHeight =\n cssHeight === Css.ident.auto || (!cssHeight && !attrHeight);\n if (element.namespaceURI != Base.NS.FB2 || tag == \"td\") {\n const attributes = element.attributes;\n const attributeCount = attributes.length;\n let delayedSrc: string | null = null;\n for (let i = 0; i < attributeCount; i++) {\n const attribute = attributes[i];\n const attributeNS = attribute.namespaceURI;\n let attributeName = attribute.localName;\n let attributeValue = attribute.nodeValue;\n if (!attributeNS) {\n if (attributeName.match(/^on/)) {\n continue; // don't propagate JavaScript code\n }\n if (attributeName == \"style\") {\n continue; // we do styling ourselves\n }\n if (attributeName == \"id\" || attributeName == \"name\") {\n // Propagate transformed ids and collect them on the page\n // (only first time).\n if (firstTime) {\n attributeValue = self.documentURLTransformer.transformFragment(\n attributeValue,\n self.xmldoc.url,\n );\n result.setAttribute(attributeName, attributeValue);\n self.page.registerElementWithId(result, attributeValue);\n continue;\n }\n }\n\n // TODO: understand the element we are working with.\n if (\n attributeName == \"src\" ||\n attributeName == \"href\" ||\n attributeName == \"poster\"\n ) {\n attributeValue = self.resolveURL(attributeValue);\n if (attributeName === \"href\") {\n attributeValue = self.documentURLTransformer.transformURL(\n attributeValue,\n self.xmldoc.url,\n );\n }\n } else if (attributeName == \"srcset\") {\n attributeValue = attributeValue\n .split(\",\")\n .map((value) => self.resolveURL(value.trim()))\n .join(\",\");\n }\n if (\n attributeName === \"poster\" &&\n tag === \"video\" &&\n ns === Base.NS.XHTML &&\n hasAutoWidth &&\n hasAutoHeight\n ) {\n const image = new Image();\n const fetcher = TaskUtil.loadElement(image, attributeValue);\n fetchers.push(fetcher);\n images.push({\n image,\n element: result as HTMLElement,\n fetcher,\n });\n }\n } else if (attributeNS == \"http://www.w3.org/2000/xmlns/\") {\n continue; // namespace declaration (in Firefox)\n } else if (attributeNS == Base.NS.XLINK) {\n if (attributeName == \"href\") {\n attributeValue = self.resolveURL(attributeValue);\n }\n }\n if (ns == Base.NS.SVG && /^[A-Z\\-]+$/.test(attributeName)) {\n // Workaround for Edge bug\n // See\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/5579311/\n attributeName = attributeName.toLowerCase();\n }\n if (self.isSVGUrlAttribute(attributeName)) {\n attributeValue = Urls.transformURIs(\n attributeValue,\n self.xmldoc.url,\n self.documentURLTransformer,\n );\n }\n if (attributeNS) {\n const attributePrefix = namespacePrefixMap[attributeNS];\n if (attributePrefix) {\n attributeName = `${attributePrefix}:${attributeName}`;\n }\n }\n if (\n attributeName == \"src\" &&\n !attributeNS &&\n (tag == \"img\" || tag == \"input\") &&\n ns == Base.NS.XHTML\n ) {\n // HTML img element should start loading only once all\n // attributes are assigned.\n delayedSrc = attributeValue;\n } else if (\n attributeName == \"href\" &&\n tag == \"image\" &&\n ns == Base.NS.SVG &&\n attributeNS == Base.NS.XLINK\n ) {\n self.page.fetchers.push(\n TaskUtil.loadElement(result, attributeValue),\n );\n } else {\n // When the document is not XML document (e.g. non-XML HTML)\n // attributeNS can be null\n if (attributeNS) {\n result.setAttributeNS(\n attributeNS,\n attributeName,\n attributeValue,\n );\n } else {\n result.setAttribute(attributeName, attributeValue);\n }\n }\n }\n if (delayedSrc) {\n const image = tag === \"input\" ? new Image() : result;\n const imageFetcher = TaskUtil.loadElement(image, delayedSrc);\n if (image !== result) {\n (result as HTMLImageElement).src = delayedSrc;\n }\n if (!hasAutoWidth && !hasAutoHeight) {\n // No need to wait for the image, does not affect layout\n self.page.fetchers.push(imageFetcher);\n } else {\n if (\n hasAutoWidth &&\n hasAutoHeight &&\n imageResolution &&\n imageResolution !== 1\n ) {\n images.push({\n image: image as HTMLElement,\n element: result as HTMLElement,\n fetcher: imageFetcher,\n });\n }\n fetchers.push(imageFetcher);\n }\n }\n }\n delete computedStyle[\"content\"];\n const listStyleImage = computedStyle[\"list-style-image\"];\n if (listStyleImage && listStyleImage instanceof Css.URL) {\n const listStyleURL = (listStyleImage as Css.URL).url;\n fetchers.push(TaskUtil.loadElement(new Image(), listStyleURL));\n }\n self.preprocessElementStyle(computedStyle);\n self.applyComputedStyles(result, computedStyle);\n if (!self.nodeContext.inline) {\n let blackList: { [key: string]: string } = null;\n if (!firstTime) {\n if (\n self.nodeContext.inheritedProps[\"box-decoration-break\"] !==\n \"clone\"\n ) {\n blackList = self.nodeContext.vertical\n ? frontEdgeBlackListVert\n : frontEdgeBlackListHor;\n } else {\n // When box-decoration-break: clone, cloned margins are always\n // truncated to zero.\n blackList = self.nodeContext.vertical\n ? frontEdgeUnforcedBreakBlackListVert\n : frontEdgeUnforcedBreakBlackListHor;\n }\n } else if (atUnforcedBreak) {\n blackList = self.nodeContext.vertical\n ? frontEdgeUnforcedBreakBlackListVert\n : frontEdgeUnforcedBreakBlackListHor;\n }\n if (blackList) {\n for (const propName in blackList) {\n Base.setCSSProperty(result, propName, blackList[propName]);\n }\n }\n }\n if (listItem) {\n result.setAttribute(\n \"value\",\n computedStyle[\"ua-list-item-count\"].stringValue(),\n );\n }\n self.viewNode = result;\n if (fetchers.length) {\n TaskUtil.waitForFetchers(fetchers).then(() => {\n if (imageResolution > 0) {\n self.modifyElemDimensionWithImageResolution(\n images,\n imageResolution,\n computedStyle,\n self.nodeContext.vertical,\n );\n }\n frame.finish(needToProcessChildren);\n });\n } else {\n frame.timeSlice().then(() => {\n frame.finish(needToProcessChildren);\n });\n }\n });\n });\n return frame.result();\n }\n\n private processAfterIfcontinues(\n element: Element,\n cascStyle: CssCascade.ElementStyle,\n styler: CssStyler.AbstractStyler,\n context: Exprs.Context,\n ) {\n const pseudoMap = this.getPseudoMap(\n cascStyle,\n this.regionIds,\n this.isFootnote,\n this.nodeContext,\n context,\n );\n if (!pseudoMap) {\n return;\n }\n if (\n pseudoMap[\"after-if-continues\"] &&\n pseudoMap[\"after-if-continues\"][\"content\"]\n ) {\n const shadowStyler = new PseudoElement.PseudoelementStyler(\n element,\n cascStyle,\n styler,\n context,\n this.exprContentListener,\n );\n this.nodeContext.afterIfContinues = new Layout.AfterIfContinues(\n element,\n shadowStyler,\n );\n }\n }\n\n /**\n * @return isSVGUrlAttribute\n */\n isSVGUrlAttribute(attributeName: string): boolean {\n return ViewFactory.SVG_URL_ATTRIBUTES.includes(attributeName.toLowerCase());\n }\n\n modifyElemDimensionWithImageResolution(\n images: {\n image: HTMLElement;\n element: HTMLElement;\n fetcher: TaskUtil.Fetcher<string>;\n }[],\n imageResolution: number,\n computedStyle: { [key: string]: Css.Val },\n isVertical: boolean,\n ) {\n const self = this;\n images.forEach((param) => {\n if (param.fetcher.get().get() === \"load\") {\n const img = param.image;\n let scaledWidth = (img as HTMLImageElement).width / imageResolution;\n let scaledHeight = (img as HTMLImageElement).height / imageResolution;\n const elem = param.element;\n if (scaledWidth > 0 && scaledHeight > 0) {\n if (computedStyle[\"box-sizing\"] === Css.ident.border_box) {\n if (computedStyle[\"border-left-style\"] !== Css.ident.none) {\n scaledWidth += Css.toNumber(\n computedStyle[\"border-left-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-right-style\"] !== Css.ident.none) {\n scaledWidth += Css.toNumber(\n computedStyle[\"border-right-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-top-style\"] !== Css.ident.none) {\n scaledHeight += Css.toNumber(\n computedStyle[\"border-top-width\"],\n self.context,\n );\n }\n if (computedStyle[\"border-bottom-style\"] !== Css.ident.none) {\n scaledHeight += Css.toNumber(\n computedStyle[\"border-bottom-width\"],\n self.context,\n );\n }\n }\n if (imageResolution > 1) {\n const maxWidth = computedStyle[\"max-width\"] || Css.ident.none;\n const maxHeight = computedStyle[\"max-height\"] || Css.ident.none;\n if (maxWidth === Css.ident.none && maxHeight === Css.ident.none) {\n Base.setCSSProperty(elem, \"max-width\", `${scaledWidth}px`);\n } else if (\n maxWidth !== Css.ident.none &&\n maxHeight === Css.ident.none\n ) {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n } else if (\n maxWidth === Css.ident.none &&\n maxHeight !== Css.ident.none\n ) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n // maxWidth != none && maxHeight != none\n Asserts.assert(maxWidth.isNumeric());\n Asserts.assert(maxHeight.isNumeric());\n const numericMaxWidth = maxWidth as Css.Numeric;\n const numericMaxHeight = maxHeight as Css.Numeric;\n if (numericMaxWidth.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"max-width\",\n `${Math.min(\n scaledWidth,\n Css.toNumber(numericMaxWidth, self.context),\n )}px`,\n );\n } else if (numericMaxHeight.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"max-height\",\n `${Math.min(\n scaledHeight,\n Css.toNumber(numericMaxHeight, self.context),\n )}px`,\n );\n } else {\n if (isVertical) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n }\n }\n }\n } else if (imageResolution < 1) {\n const minWidth = computedStyle[\"min-width\"] || Css.numericZero;\n const minHeight = computedStyle[\"min-height\"] || Css.numericZero;\n Asserts.assert(minWidth.isNumeric());\n Asserts.assert(minWidth.isNumeric());\n const numericMinWidth = minWidth as Css.Numeric;\n const numericMinHeight = minHeight as Css.Numeric;\n if (numericMinWidth.num === 0 && numericMinHeight.num === 0) {\n Base.setCSSProperty(elem, \"min-width\", `${scaledWidth}px`);\n } else if (\n numericMinWidth.num !== 0 &&\n numericMinHeight.num === 0\n ) {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n } else if (\n numericMinWidth.num === 0 &&\n numericMinHeight.num !== 0\n ) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n // minWidth != 0 && minHeight != 0\n if (numericMinWidth.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"min-width\",\n `${Math.max(\n scaledWidth,\n Css.toNumber(numericMinWidth, self.context),\n )}px`,\n );\n } else if (numericMinHeight.unit !== \"%\") {\n Base.setCSSProperty(\n elem,\n \"min-height\",\n `${Math.max(\n scaledHeight,\n Css.toNumber(numericMinHeight, self.context),\n )}px`,\n );\n } else {\n if (isVertical) {\n Base.setCSSProperty(elem, \"height\", `${scaledHeight}px`);\n } else {\n Base.setCSSProperty(elem, \"width\", `${scaledWidth}px`);\n }\n }\n }\n }\n }\n }\n });\n }\n\n private preprocessElementStyle(computedStyle: { [key: string]: Css.Val }) {\n const self = this;\n const hooks: Plugin.PreProcessElementStyleHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_ELEMENT_STYLE,\n );\n hooks.forEach((hook) => {\n hook(self.nodeContext, computedStyle);\n });\n }\n\n private findAndProcessRepeatingElements(\n element: Element,\n styler: CssStyler.AbstractStyler,\n ) {\n for (\n let child: Node = element.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType !== 1) {\n continue;\n }\n const computedStyle = {};\n const elementStyle = styler.getStyle(child as Element, false);\n this.computeStyle(\n this.nodeContext.vertical,\n this.nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n const processRepeatOnBreak = this.processRepeatOnBreak(computedStyle);\n if (!processRepeatOnBreak) {\n continue;\n }\n if (\n this.nodeContext.formattingContext instanceof\n RepetitiveElement.RepetitiveElementsOwnerFormattingContext &&\n !this.nodeContext.belongsTo(this.nodeContext.formattingContext)\n ) {\n return;\n }\n const parent = this.nodeContext.parent;\n const parentFormattingContext = parent && parent.formattingContext;\n this.nodeContext.formattingContext = new RepetitiveElement.RepetitiveElementsOwnerFormattingContext(\n parentFormattingContext,\n this.nodeContext.sourceNode as Element,\n );\n (this.nodeContext\n .formattingContext as RepetitiveElement.RepetitiveElementsOwnerFormattingContext).initializeRepetitiveElements(\n this.nodeContext.vertical,\n );\n return;\n }\n }\n\n private processRepeatOnBreak(computedStyle: { [key: string]: Css.Val }) {\n let repeatOnBreak = computedStyle[\"repeat-on-break\"];\n if (repeatOnBreak !== Css.ident.none) {\n if (repeatOnBreak === Css.ident.auto) {\n if (computedStyle[\"display\"] === Css.ident.table_header_group) {\n repeatOnBreak = Css.ident.header;\n } else if (computedStyle[\"display\"] === Css.ident.table_footer_group) {\n repeatOnBreak = Css.ident.footer;\n } else {\n repeatOnBreak = Css.ident.none;\n }\n }\n if (repeatOnBreak && repeatOnBreak !== Css.ident.none) {\n return repeatOnBreak.toString();\n }\n }\n return null;\n }\n\n private createTextNodeView(): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createTextNodeView\");\n this.preprocessTextContent().then(() => {\n const offsetInNode = self.offsetInNode || 0;\n const textContent = Diff.restoreNewText(\n self.nodeContext.preprocessedTextContent,\n ).substr(offsetInNode);\n self.viewNode = document.createTextNode(textContent);\n frame.finish(true);\n });\n return frame.result();\n }\n\n private preprocessTextContent(): Task.Result<boolean> {\n if (this.nodeContext.preprocessedTextContent != null) {\n return Task.newResult(true);\n }\n const self = this;\n let originl: string;\n let textContent = (originl = self.sourceNode.textContent);\n const frame: Task.Frame<boolean> = Task.newFrame(\"preprocessTextContent\");\n const hooks: Plugin.PreProcessTextContentHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_TEXT_CONTENT,\n );\n let index = 0;\n frame\n .loop(() => {\n if (index >= hooks.length) {\n return Task.newResult(false);\n }\n return hooks[index++](self.nodeContext, textContent).thenAsync(\n (processedText) => {\n textContent = processedText;\n return Task.newResult(true);\n },\n );\n })\n .then(() => {\n self.nodeContext.preprocessedTextContent = Diff.diffChars(\n originl,\n textContent,\n );\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @return holding true if children should be processed\n */\n createNodeView(\n firstTime: boolean,\n atUnforcedBreak: boolean,\n ): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"createNodeView\");\n let result: Task.Result<boolean>;\n let needToProcessChildren = true;\n if (self.sourceNode.nodeType == 1) {\n result = self.createElementView(firstTime, atUnforcedBreak);\n } else {\n if (self.sourceNode.nodeType == 8) {\n self.viewNode = null; // comment node\n result = Task.newResult(true);\n } else {\n result = self.createTextNodeView();\n }\n }\n result.then((processChildren) => {\n needToProcessChildren = processChildren;\n self.nodeContext.viewNode = self.viewNode;\n if (self.viewNode) {\n const parent = self.nodeContext.parent\n ? self.nodeContext.parent.viewNode\n : self.viewRoot;\n if (parent) {\n parent.appendChild(self.viewNode);\n }\n }\n frame.finish(needToProcessChildren);\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n setCurrent(\n nodeContext: Vtree.NodeContext,\n firstTime: boolean,\n atUnforcedBreak?: boolean,\n ): Task.Result<boolean> {\n this.nodeContext = nodeContext;\n if (nodeContext) {\n this.sourceNode = nodeContext.sourceNode;\n this.offsetInNode = nodeContext.offsetInNode;\n } else {\n this.sourceNode = null;\n this.offsetInNode = -1;\n }\n this.viewNode = null;\n if (this.nodeContext) {\n return this.createNodeView(firstTime, !!atUnforcedBreak);\n }\n return Task.newResult(true);\n }\n\n processShadowContent(pos: Vtree.NodeContext): Vtree.NodeContext {\n if (\n pos.shadowContext == null ||\n (pos.sourceNode as Element).localName != \"content\" ||\n pos.sourceNode.namespaceURI != Base.NS.SHADOW\n ) {\n return pos;\n }\n const boxOffset = pos.boxOffset;\n const shadow = pos.shadowContext;\n const parent = pos.parent;\n\n // content that will be inserted\n let contentNode: Node;\n let contentShadowType: Vtree.ShadowType;\n let contentShadow: Vtree.ShadowContext;\n if (shadow.subShadow) {\n contentShadow = shadow.subShadow;\n contentNode = shadow.root;\n contentShadowType = shadow.type;\n if (contentShadowType == Vtree.ShadowType.ROOTLESS) {\n contentNode = contentNode.firstChild;\n }\n } else {\n contentShadow = shadow.parentShadow;\n contentNode = shadow.owner.firstChild;\n contentShadowType = Vtree.ShadowType.ROOTLESS;\n }\n const nextSibling = pos.sourceNode.nextSibling;\n if (nextSibling) {\n pos.sourceNode = nextSibling;\n pos.resetView();\n } else if (pos.shadowSibling) {\n pos = pos.shadowSibling;\n } else if (contentNode) {\n pos = null;\n } else {\n pos = pos.parent.modify();\n pos.after = true;\n }\n if (contentNode) {\n const r = new Vtree.NodeContext(contentNode, parent, boxOffset);\n r.shadowContext = contentShadow;\n r.shadowType = contentShadowType;\n r.shadowSibling = pos;\n return r;\n }\n pos.boxOffset = boxOffset;\n return pos;\n }\n\n private nextPositionInTree(pos: Vtree.NodeContext): Vtree.NodeContext {\n let boxOffset = pos.boxOffset + 1; // offset for the next position\n if (pos.after) {\n // root, that was the last possible position\n if (!pos.parent) {\n return null;\n }\n\n // we are done with this sourceNode, see if there is a next sibling,\n // unless this is the root of the shadow tree\n if (pos.shadowType != Vtree.ShadowType.ROOTED) {\n const next = pos.sourceNode.nextSibling;\n if (next) {\n pos = pos.modify();\n\n // keep shadowType\n pos.boxOffset = boxOffset;\n pos.sourceNode = next;\n pos.resetView();\n return this.processShadowContent(pos);\n }\n }\n\n // if no viable siblings, check if there are shadow siblings\n if (pos.shadowSibling) {\n // our next position is the element after shadow:content in the parent\n // shadow tree\n pos = pos.shadowSibling.modify();\n pos.boxOffset = boxOffset;\n return pos;\n }\n\n // if not rootless shadow, move to the \"after\" position for the parent\n pos = pos.parent.modify();\n pos.boxOffset = boxOffset;\n pos.after = true;\n return pos;\n } else {\n // any shadow trees?\n if (pos.nodeShadow) {\n let shadowNode: Node | null = pos.nodeShadow.root;\n if (pos.nodeShadow.type == Vtree.ShadowType.ROOTLESS) {\n shadowNode = shadowNode.firstChild;\n }\n if (shadowNode) {\n const sr = new Vtree.NodeContext(shadowNode, pos, boxOffset);\n sr.shadowContext = pos.nodeShadow;\n sr.shadowType = pos.nodeShadow.type;\n return this.processShadowContent(sr);\n }\n }\n\n // any children?\n const child = pos.sourceNode.firstChild;\n if (child) {\n return this.processShadowContent(\n new Vtree.NodeContext(child, pos, boxOffset),\n );\n }\n\n // no children - was there text content?\n if (pos.sourceNode.nodeType != 1) {\n const content = Diff.restoreNewText(pos.preprocessedTextContent);\n boxOffset += content.length - 1 - pos.offsetInNode;\n }\n pos = pos.modify();\n pos.boxOffset = boxOffset;\n pos.after = true;\n return pos;\n }\n }\n\n isTransclusion(\n element: Element,\n elementStyle: CssCascade.ElementStyle,\n transclusionType: string | null,\n ) {\n const proc = CssCascade.getProp(elementStyle, \"hyperlink-processing\");\n if (!proc) {\n return false;\n }\n const prop = proc.evaluate(this.context, \"hyperlink-processing\");\n if (!prop) {\n return false;\n }\n return prop.toString() == transclusionType;\n }\n\n /**\n * @override\n */\n nextInTree(\n position: Vtree.NodeContext,\n atUnforcedBreak?: boolean,\n ): Task.Result<Vtree.NodeContext> {\n let nodeContext = this.nextPositionInTree(position);\n if (!nodeContext || nodeContext.after) {\n return Task.newResult(nodeContext);\n }\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"nextInTree\");\n this.setCurrent(nodeContext, true, atUnforcedBreak).then(\n (processChildren) => {\n if (!nodeContext.viewNode || !processChildren) {\n nodeContext = nodeContext.modify();\n nodeContext.after = true; // skip\n if (!nodeContext.viewNode) {\n nodeContext.inline = true;\n }\n }\n this.dispatchEvent({ type: \"nextInTree\", nodeContext } as any);\n frame.finish(nodeContext);\n },\n );\n return frame.result();\n }\n\n addImageFetchers(bg: Css.Val) {\n if (bg instanceof Css.CommaList) {\n const values = (bg as Css.CommaList).values;\n for (let i = 0; i < values.length; i++) {\n this.addImageFetchers(values[i]);\n }\n } else if (bg instanceof Css.URL) {\n const url = (bg as Css.URL).url;\n this.page.fetchers.push(TaskUtil.loadElement(new Image(), url));\n }\n }\n\n applyComputedStyles(\n target: Element,\n computedStyle: { [key: string]: Css.Val },\n ) {\n const bg = computedStyle[\"background-image\"];\n if (bg) {\n this.addImageFetchers(bg);\n }\n const isRelativePositioned =\n computedStyle[\"position\"] === Css.ident.relative;\n for (const propName in computedStyle) {\n if (propertiesNotPassedToDOM[propName]) {\n continue;\n }\n let value = computedStyle[propName];\n value = value.visit(\n new CssProp.UrlTransformVisitor(\n this.xmldoc.url,\n this.documentURLTransformer,\n ),\n );\n if (\n value.isNumeric() &&\n Exprs.needUnitConversion((value as Css.Numeric).unit)\n ) {\n // font-size for the root element is already converted to px\n value = Css.convertNumericToPx(value, this.context);\n }\n if (\n Vtree.delayedProps[propName] ||\n (isRelativePositioned &&\n Vtree.delayedPropsIfRelativePositioned[propName])\n ) {\n // Set it after page layout is done.\n this.page.delayedItems.push(\n new Vtree.DelayedItem(target, propName, value),\n );\n continue;\n }\n Base.setCSSProperty(target, propName, value.toString());\n }\n }\n\n /**\n * @override\n */\n applyPseudoelementStyle(\n nodeContext: Vtree.NodeContext,\n pseudoName: string,\n target: Element,\n ): void {\n if (nodeContext.after) {\n return;\n }\n const element = this.sourceNode as Element;\n const styler = nodeContext.shadowContext\n ? (nodeContext.shadowContext.styler as CssStyler.AbstractStyler)\n : this.styler;\n let elementStyle = styler.getStyle(element, false);\n const pseudoMap = CssCascade.getStyleMap(elementStyle, \"_pseudos\");\n if (!pseudoMap) {\n return;\n }\n elementStyle = pseudoMap[pseudoName];\n if (!elementStyle) {\n return;\n }\n const computedStyle = {};\n nodeContext.vertical = this.computeStyle(\n nodeContext.vertical,\n nodeContext.direction === \"rtl\",\n elementStyle,\n computedStyle,\n );\n const content = computedStyle[\"content\"];\n if (Vtree.nonTrivialContent(content)) {\n content.visit(\n new Vtree.ContentPropertyHandler(\n target,\n this.context,\n content,\n this.exprContentListener,\n ),\n );\n delete computedStyle[\"content\"];\n }\n this.applyComputedStyles(target, computedStyle);\n }\n\n /**\n * @override\n */\n peelOff(\n nodeContext: Vtree.NodeContext,\n nodeOffset: number,\n ): Task.Result<Vtree.NodeContext> {\n const frame: Task.Frame<Vtree.NodeContext> = Task.newFrame(\"peelOff\");\n const firstPseudo = nodeContext.firstPseudo;\n let offsetInNode = nodeContext.offsetInNode;\n const after = nodeContext.after;\n if (nodeOffset > 0) {\n const text = nodeContext.viewNode.textContent;\n nodeContext.viewNode.textContent = text.substr(0, nodeOffset);\n offsetInNode += nodeOffset;\n } else if (!after && nodeContext.viewNode && offsetInNode == 0) {\n const parent = nodeContext.viewNode.parentNode;\n if (parent) {\n parent.removeChild(nodeContext.viewNode);\n }\n }\n const boxOffset = nodeContext.boxOffset + nodeOffset;\n const arr = [];\n while (nodeContext.firstPseudo === firstPseudo) {\n arr.push(nodeContext);\n nodeContext = nodeContext.parent;\n }\n let pn = arr.pop(); // container for that pseudoelement\n let shadowSibling = pn.shadowSibling;\n const self = this;\n frame\n .loop(() => {\n while (arr.length > 0) {\n pn = arr.pop();\n nodeContext = new Vtree.NodeContext(\n pn.sourceNode,\n nodeContext,\n boxOffset,\n );\n if (arr.length == 0) {\n nodeContext.offsetInNode = offsetInNode;\n nodeContext.after = after;\n }\n nodeContext.shadowType = pn.shadowType;\n (nodeContext.shadowContext = pn.shadowContext),\n (nodeContext.nodeShadow = pn.nodeShadow);\n nodeContext.shadowSibling = pn.shadowSibling\n ? pn.shadowSibling\n : shadowSibling;\n shadowSibling = null;\n const result = self.setCurrent(nodeContext, false);\n if (result.isPending()) {\n return result;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(nodeContext);\n });\n return frame.result();\n }\n\n createElement(ns: string, tag: string): Element {\n if (ns == Base.NS.XHTML) {\n return this.document.createElement(tag);\n }\n return this.document.createElementNS(ns, tag);\n }\n\n /**\n * @override\n */\n applyFootnoteStyle(\n vertical: boolean,\n rtl: boolean,\n target: Element,\n ): boolean {\n const computedStyle = {};\n const pseudoMap = CssCascade.getStyleMap(this.footnoteStyle, \"_pseudos\");\n vertical = this.computeStyle(\n vertical,\n rtl,\n this.footnoteStyle,\n computedStyle,\n );\n if (pseudoMap && pseudoMap[\"before\"]) {\n const childComputedStyle = {};\n const span = this.createElement(Base.NS.XHTML, \"span\");\n PseudoElement.setPseudoName(span, \"before\");\n target.appendChild(span);\n this.computeStyle(vertical, rtl, pseudoMap[\"before\"], childComputedStyle);\n delete childComputedStyle[\"content\"];\n this.applyComputedStyles(span, childComputedStyle);\n }\n delete computedStyle[\"content\"];\n this.applyComputedStyles(target, computedStyle);\n return vertical;\n }\n\n /**\n * @override\n */\n processFragmentedBlockEdge(nodeContext: Vtree.NodeContext) {\n if (nodeContext) {\n nodeContext.walkUpBlocks((block) => {\n const boxDecorationBreak = block.inheritedProps[\"box-decoration-break\"];\n if (!boxDecorationBreak || boxDecorationBreak === \"slice\") {\n const elem = block.viewNode as Element;\n Asserts.assert(elem instanceof Element);\n if (block.vertical) {\n Base.setCSSProperty(elem, \"padding-left\", \"0\");\n Base.setCSSProperty(elem, \"border-left\", \"none\");\n Base.setCSSProperty(elem, \"border-top-left-radius\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom-left-radius\", \"0\");\n } else {\n Base.setCSSProperty(elem, \"padding-bottom\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom\", \"none\");\n Base.setCSSProperty(elem, \"border-bottom-left-radius\", \"0\");\n Base.setCSSProperty(elem, \"border-bottom-right-radius\", \"0\");\n }\n }\n });\n }\n }\n\n /**\n * @override\n */\n convertLengthToPx(\n numeric: Css.Numeric,\n viewNode: Node,\n clientLayout: Vtree.ClientLayout,\n ): number | Css.Numeric {\n const num = numeric.num;\n const unit = numeric.unit;\n if (Exprs.isFontRelativeLengthUnit(unit)) {\n let elem = viewNode;\n while (elem && elem.nodeType !== 1) {\n elem = elem.parentNode;\n }\n Asserts.assert(elem);\n const fontSize = parseFloat(\n clientLayout.getElementComputedStyle(elem as Element)[\"font-size\"],\n );\n Asserts.assert(this.context);\n return CssCascade.convertFontRelativeLengthToPx(\n numeric,\n fontSize,\n this.context,\n ).num;\n } else {\n const unitSize = this.context.queryUnitSize(unit, false);\n if (unitSize) {\n return num * unitSize;\n } else {\n return numeric;\n }\n }\n }\n\n /**\n * Returns if two NodePositionStep are equivalent.\n */\n isSameNodePositionStep(\n step1: Vtree.NodePositionStep,\n step2: Vtree.NodePositionStep,\n ): boolean {\n if (step1.shadowContext) {\n if (!step2.shadowContext) {\n return false;\n }\n const elem1 =\n step1.node.nodeType === 1\n ? (step1.node as Element)\n : (step1.node.parentElement as Element);\n const elem2 =\n step2.node.nodeType === 1\n ? (step2.node as Element)\n : (step2.node.parentElement as Element);\n return (\n step1.shadowContext.owner === step2.shadowContext.owner &&\n PseudoElement.getPseudoName(elem1) ===\n PseudoElement.getPseudoName(elem2)\n );\n } else {\n return step1.node === step2.node;\n }\n }\n\n /**\n * @override\n */\n isSameNodePosition(\n nodePosition1: Vtree.NodePosition,\n nodePosition2: Vtree.NodePosition,\n ): boolean {\n return (\n nodePosition1.offsetInNode === nodePosition2.offsetInNode &&\n nodePosition1.after == nodePosition2.after &&\n nodePosition1.steps.length === nodePosition2.steps.length &&\n nodePosition1.steps.every((step1, i) => {\n const step2 = nodePosition2.steps[i];\n return this.isSameNodePositionStep(step1, step2);\n })\n );\n }\n\n isPseudoelement(elem) {\n return !!PseudoElement.getPseudoName(elem);\n }\n}\n\nexport const fb2Remap = {\n a: \"a\",\n sub: \"sub\",\n sup: \"sup\",\n table: \"table\",\n tr: \"tr\",\n td: \"td\",\n th: \"th\",\n code: \"code\",\n body: \"div\",\n p: \"p\",\n v: \"p\",\n date: \"p\",\n emphasis: \"em\",\n strong: \"strong\",\n style: \"span\",\n strikethrough: \"del\",\n};\n\nexport const propertiesNotPassedToDOM = {\n \"box-decoration-break\": true,\n \"float-min-wrap-block\": true,\n \"float-reference\": true,\n \"flow-into\": true,\n \"flow-linger\": true,\n \"flow-options\": true,\n \"flow-priority\": true,\n \"footnote-policy\": true,\n page: true,\n};\n\nexport class DefaultClientLayout implements Vtree.ClientLayout {\n layoutBox: Element;\n window: Window;\n\n constructor(viewport: Viewport) {\n this.layoutBox = viewport.layoutBox;\n this.window = viewport.window;\n }\n\n private subtractOffsets(\n rect: Vtree.ClientRect,\n originRect: Vtree.ClientRect,\n ): Vtree.ClientRect {\n const viewportLeft = originRect.left;\n const viewportTop = originRect.top;\n return {\n left: rect.left - viewportLeft,\n top: rect.top - viewportTop,\n right: rect.right - viewportLeft,\n bottom: rect.bottom - viewportTop,\n width: rect.width,\n height: rect.height,\n } as Vtree.ClientRect;\n }\n\n /**\n * @override\n */\n getRangeClientRects(range: Range): ClientRect[] {\n const rects = range[\"getClientRects\"]();\n const layoutBoxRect = this.layoutBox.getBoundingClientRect();\n return Array.from(rects).map((rect) =>\n this.subtractOffsets(rect, layoutBoxRect),\n );\n }\n\n /**\n * @override\n */\n getElementClientRect(element: Element): ClientRect {\n const htmlElement = element as HTMLElement;\n const rect = htmlElement.getBoundingClientRect() as Vtree.ClientRect;\n const layoutBoxRect = this.layoutBox.getBoundingClientRect();\n return this.subtractOffsets(rect, layoutBoxRect);\n }\n\n /**\n * @override\n */\n getElementComputedStyle(element: Element): CSSStyleDeclaration {\n return this.window.getComputedStyle(element, null);\n }\n}\n\nexport class Viewport {\n document: Document;\n root: HTMLElement;\n private outerZoomBox: HTMLElement;\n contentContainer: HTMLElement;\n layoutBox: Element;\n width: number;\n height: number;\n\n constructor(\n public readonly window: Window,\n public readonly fontSize: number,\n opt_root?: HTMLElement,\n opt_width?: number,\n opt_height?: number,\n ) {\n this.document = window.document;\n this.root = opt_root || this.document.body;\n let outerZoomBox = this.root.firstElementChild;\n if (!outerZoomBox) {\n outerZoomBox = this.document.createElement(\"div\");\n outerZoomBox.setAttribute(\"data-vivliostyle-outer-zoom-box\", \"true\");\n this.root.appendChild(outerZoomBox);\n }\n let contentContainer = outerZoomBox.firstElementChild;\n if (!contentContainer) {\n contentContainer = this.document.createElement(\"div\");\n contentContainer.setAttribute(\n \"data-vivliostyle-spread-container\",\n \"true\",\n );\n outerZoomBox.appendChild(contentContainer);\n }\n let layoutBox = outerZoomBox.nextElementSibling;\n if (!layoutBox) {\n layoutBox = this.document.createElement(\"div\");\n layoutBox.setAttribute(\"data-vivliostyle-layout-box\", \"true\");\n this.root.appendChild(layoutBox);\n }\n this.outerZoomBox = outerZoomBox as HTMLElement;\n this.contentContainer = contentContainer as HTMLElement;\n this.layoutBox = layoutBox as HTMLElement;\n const clientLayout = new DefaultClientLayout(this);\n const computedStyle = clientLayout.getElementComputedStyle(this.root);\n this.width =\n opt_width || parseFloat(computedStyle[\"width\"]) || window.innerWidth;\n this.height =\n opt_height || parseFloat(computedStyle[\"height\"]) || window.innerHeight;\n }\n\n /**\n * Reset zoom.\n */\n resetZoom() {\n Base.setCSSProperty(this.outerZoomBox, \"width\", \"\");\n Base.setCSSProperty(this.outerZoomBox, \"height\", \"\");\n Base.setCSSProperty(this.contentContainer, \"width\", \"\");\n Base.setCSSProperty(this.contentContainer, \"height\", \"\");\n Base.setCSSProperty(this.contentContainer, \"transform\", \"\");\n }\n\n /**\n * Zoom viewport.\n * @param width Overall width of contents before scaling (px)\n * @param height Overall height of contents before scaling (px)\n * @param scale Factor to which the viewport will be scaled.\n */\n zoom(width: number, height: number, scale: number) {\n Base.setCSSProperty(this.outerZoomBox, \"width\", `${width * scale}px`);\n Base.setCSSProperty(this.outerZoomBox, \"height\", `${height * scale}px`);\n Base.setCSSProperty(this.contentContainer, \"width\", `${width}px`);\n Base.setCSSProperty(this.contentContainer, \"height\", `${height}px`);\n Base.setCSSProperty(this.contentContainer, \"transform\", `scale(${scale})`);\n }\n\n /**\n * Remove all pages inside the viewport.\n */\n clear() {\n const root = this.root;\n while (root.lastChild) {\n root.removeChild(root.lastChild);\n }\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview XmlDoc - Utility functions to work with XML (mostly XHTML)\n * documents.\n */\nimport * as Base from \"./base\";\nimport * as Net from \"./net\";\nimport * as Task from \"./task\";\nimport { XmlDoc } from \"./types\";\n\nexport type XMLDocStore = XmlDoc.XMLDocStore;\n\nexport const ELEMENT_OFFSET_ATTR = \"data-adapt-eloff\";\n\nexport class XMLDocHolder implements XmlDoc.XMLDocHolder {\n lang: string | null = null;\n totalOffset: number = -1;\n root: Element;\n body: Element;\n head: Element;\n last: Element;\n lastOffset: number = 1;\n idMap: { [key: string]: Element };\n\n constructor(\n public readonly store: XMLDocStore,\n public readonly url: string,\n public readonly document: Document,\n ) {\n this.root = document.documentElement; // html element\n let body: Element = null;\n let head: Element = null;\n if (this.root.namespaceURI == Base.NS.XHTML) {\n for (\n let child: Node = this.root.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType != 1) {\n continue;\n }\n const elem = child as Element;\n if (elem.namespaceURI == Base.NS.XHTML) {\n switch (elem.localName) {\n case \"head\":\n head = elem;\n break;\n case \"body\":\n body = elem;\n break;\n }\n }\n }\n this.lang = this.root.getAttribute(\"lang\");\n } else if (this.root.namespaceURI == Base.NS.FB2) {\n head = this.root;\n for (\n let child: Node = this.root.firstChild;\n child;\n child = child.nextSibling\n ) {\n if (child.nodeType != 1) {\n continue;\n }\n const elem = child as Element;\n if (elem.namespaceURI == Base.NS.FB2) {\n if (elem.localName == \"body\") {\n body = elem;\n }\n }\n }\n const langs = this.doc()\n .child(\"FictionBook\")\n .child(\"description\")\n .child(\"title-info\")\n .child(\"lang\")\n .textContent();\n if (langs.length > 0) {\n this.lang = langs[0];\n }\n } else if (this.root.namespaceURI == Base.NS.SSE) {\n // treat <meta> element as \"head\" of the document\n for (\n let elem = this.root.firstElementChild;\n elem;\n elem = elem.nextElementSibling\n ) {\n const localName = elem.localName;\n if (localName === \"meta\") {\n head = elem;\n } else if (localName === \"body\") {\n body = elem;\n }\n }\n }\n this.body = body as Element;\n this.head = head as Element;\n this.last = this.root;\n this.last.setAttribute(ELEMENT_OFFSET_ATTR, \"0\");\n }\n\n doc(): XmlDoc.NodeList {\n return new NodeList([this.document]);\n }\n\n getElementOffset(element: Element): number {\n const offsetStr = element.getAttribute(ELEMENT_OFFSET_ATTR);\n if (offsetStr) {\n return parseInt(offsetStr, 10);\n }\n let offset = this.lastOffset;\n let last: Node | null = this.last;\n while (last != element) {\n let next: Node | null = last.firstChild;\n if (!next) {\n while (true) {\n next = last.nextSibling;\n if (next) {\n break;\n }\n last = last.parentNode;\n if (last == null) {\n throw new Error(\"Internal error\");\n }\n }\n }\n last = next;\n if (next.nodeType == 1) {\n const nextElement = next as Element;\n nextElement.setAttribute(ELEMENT_OFFSET_ATTR, offset.toString());\n ++offset;\n } else {\n offset += (next.textContent as string).length;\n }\n }\n this.lastOffset = offset;\n this.last = element;\n return offset - 1;\n }\n\n getNodeOffset(srcNode: Node, offsetInNode: number, after: boolean) {\n let extraOffset = 0;\n let node: Node | null = srcNode;\n let prev: Node | null = null;\n if (node.nodeType == 1) {\n // after = true is only valid for elements\n if (!after) {\n return this.getElementOffset(node as Element);\n }\n } else {\n // offsetInNode is only valid for text nodes\n extraOffset = offsetInNode;\n prev = node.previousSibling;\n if (!prev) {\n node = node.parentNode;\n extraOffset += 1;\n return this.getElementOffset(node as Element) + extraOffset;\n }\n node = prev;\n }\n while (true) {\n while (node.lastChild) {\n node = node.lastChild;\n }\n if (node.nodeType == 1) {\n // empty element\n break;\n }\n extraOffset += (node.textContent as string).length;\n prev = node.previousSibling;\n if (!prev) {\n node = node.parentNode;\n break;\n }\n node = prev;\n }\n extraOffset += 1;\n return this.getElementOffset(node as Element) + extraOffset;\n }\n\n getTotalOffset(): number {\n if (this.totalOffset < 0) {\n this.totalOffset = this.getNodeOffset(this.root, 0, true);\n }\n return this.totalOffset;\n }\n\n /**\n * @return last node such that its offset is less or equal to the given\n */\n getNodeByOffset(offset: number): Node {\n let elementOffset: number;\n\n // First, find the last element in the document, such that\n // this.getElementOffset(element) <= offset; if offest matches\n // exactly, just return it.\n const self = this;\n let element = this.root;\n while (true) {\n elementOffset = this.getElementOffset(element);\n if (elementOffset >= offset) {\n return element;\n }\n const children = element.children; // Element children\n if (!children) {\n break;\n }\n const index = Base.binarySearch(children.length, (index) => {\n const child = children[index];\n const childOffset = self.getElementOffset(child);\n return childOffset > offset;\n });\n if (index == 0) {\n break;\n }\n if (VIVLIOSTYLE_DEBUG) {\n if (index < children.length) {\n const elemOffset = self.getElementOffset(children[index]);\n if (elemOffset <= offset) {\n throw new Error(\"Consistency check failed!\");\n }\n }\n }\n element = children[index - 1];\n }\n\n // Now we have element with offset less than desired. Find following\n // (non-element) node with the right offset.\n let nodeOffset = elementOffset + 1;\n let node: Node | null = element;\n let next: Node | null = node.firstChild || node.nextSibling;\n let lastGood: Node | null = null;\n while (true) {\n if (next) {\n if (next.nodeType == 1) {\n break;\n }\n node = next;\n lastGood = node;\n nodeOffset += (next.textContent as string).length;\n if (nodeOffset > offset) {\n break;\n }\n } else {\n node = node.parentNode;\n if (!node) {\n break;\n }\n }\n next = node.nextSibling;\n }\n return lastGood || element;\n }\n\n private buildIdMap(e: Element): void {\n const id = e.getAttribute(\"id\");\n if (id && !this.idMap[id]) {\n this.idMap[id] = e;\n }\n const xmlid = e.getAttributeNS(Base.NS.XML, \"id\");\n if (xmlid && !this.idMap[xmlid]) {\n this.idMap[xmlid] = e;\n }\n for (let c = e.firstElementChild; c; c = c.nextElementSibling) {\n this.buildIdMap(c);\n }\n }\n\n /**\n * Get element by URL in the source document(s). URL must be in either '#id'\n * or 'url#id' form.\n */\n getElement(url: string): Element | null {\n const m = url.match(/([^#]*)#(.+)$/);\n if (!m || (m[1] && m[1] != this.url)) {\n return null;\n }\n const id = m[2];\n let r: Element = this.document.getElementById(id);\n if (!r && this.document.getElementsByName) {\n r = this.document.getElementsByName(id)[0];\n }\n if (!r) {\n if (!this.idMap) {\n this.idMap = {};\n this.buildIdMap(this.document.documentElement);\n }\n r = this.idMap[id];\n }\n return r;\n }\n}\n\n/**\n * cf. https://w3c.github.io/DOM-Parsing/#the-domparser-interface\n * @enum {string}\n */\nexport enum DOMParserSupportedType {\n TEXT_HTML = \"text/html\",\n TEXT_XML = \"text/xml\",\n APPLICATION_XML = \"application/xml\",\n APPLICATION_XHTML_XML = \"application/xhtml_xml\",\n IMAGE_SVG_XML = \"image/svg+xml\",\n}\n\n/**\n * Parses a string with a DOMParser and returns the document.\n * If a parse error occurs, return null.\n */\nexport function parseAndReturnNullIfError(\n str: string,\n type: string,\n opt_parser?: DOMParser,\n): Document | null {\n const parser = opt_parser || new DOMParser();\n let doc: Document;\n try {\n doc = parser.parseFromString(str, type as SupportedType);\n } catch (e) {}\n if (!doc) {\n return null;\n } else {\n const docElement = doc.documentElement;\n const errorTagName = \"parsererror\";\n if (docElement.localName === errorTagName) {\n return null;\n } else {\n for (let c = docElement.firstElementChild; c; c = c.nextElementSibling) {\n if (c.localName === errorTagName) {\n return null;\n }\n }\n }\n }\n return doc;\n}\n\n/**\n * @returns null if contentType cannot be inferred from HTTP header and file\n * extension\n */\nexport function resolveContentType(response: Net.Response): string | null {\n const contentType = response.contentType;\n if (contentType) {\n const supportedKeys = Object.keys(DOMParserSupportedType);\n for (let i = 0; i < supportedKeys.length; i++) {\n if (DOMParserSupportedType[supportedKeys[i]] === contentType) {\n return contentType;\n }\n }\n if (contentType.match(/\\+xml$/)) {\n return DOMParserSupportedType.APPLICATION_XML;\n }\n }\n const match = response.url.match(/\\.([^./]+)$/);\n if (match) {\n const extension = match[1];\n switch (extension) {\n case \"html\":\n case \"htm\":\n return DOMParserSupportedType.TEXT_HTML;\n case \"xhtml\":\n case \"xht\":\n return DOMParserSupportedType.APPLICATION_XHTML_XML;\n case \"svg\":\n case \"svgz\":\n return DOMParserSupportedType.IMAGE_SVG_XML;\n case \"opf\":\n case \"xml\":\n return DOMParserSupportedType.APPLICATION_XML;\n }\n }\n return null;\n}\n\nexport function parseXMLResource(\n response: Net.Response,\n store: XMLDocStore,\n): Task.Result<XmlDoc.XMLDocHolder> {\n let doc = response.responseXML;\n if (!doc) {\n const parser = new DOMParser();\n const text = response.responseText;\n if (text) {\n const contentType = resolveContentType(response);\n doc = parseAndReturnNullIfError(\n text,\n contentType || DOMParserSupportedType.APPLICATION_XML,\n parser,\n );\n\n // When contentType cannot be inferred from HTTP header and file\n // extension, we use root element's tag name to infer the contentType. If\n // it is html or svg, we re-parse the source with an appropriate\n // contentType.\n if (doc && !contentType) {\n const root = doc.documentElement;\n if (root.localName.toLowerCase() === \"html\" && !root.namespaceURI) {\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.TEXT_HTML,\n parser,\n );\n } else if (\n root.localName.toLowerCase() === \"svg\" &&\n (doc as any).contentType !== DOMParserSupportedType.IMAGE_SVG_XML\n ) {\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.IMAGE_SVG_XML,\n parser,\n );\n }\n }\n if (!doc) {\n // Fallback to HTML parsing\n doc = parseAndReturnNullIfError(\n text,\n DOMParserSupportedType.TEXT_HTML,\n parser,\n );\n }\n }\n }\n const xmldoc = doc ? new XMLDocHolder(store, response.url, doc) : null;\n return Task.newResult(xmldoc);\n}\n\nexport function newXMLDocStore(): XMLDocStore {\n return new Net.ResourceStore(\n parseXMLResource,\n Net.XMLHttpRequestResponseType.DOCUMENT,\n );\n}\n\nexport class Predicate implements XmlDoc.Predicate {\n constructor(public readonly fn: (p1: Node) => boolean) {}\n\n check(node: Node): boolean {\n return this.fn(node);\n }\n\n withAttribute(name: string, value: string): Predicate {\n const self = this;\n return new Predicate(\n (node) =>\n self.check(node) &&\n node.nodeType == 1 &&\n (node as Element).getAttribute(name) == value,\n );\n }\n\n withChild(name: string, opt_childPredicate?: Predicate): Predicate {\n const self = this;\n return new Predicate((node) => {\n if (!self.check(node)) {\n return false;\n }\n let list = new NodeList([node]);\n list = list.child(name);\n if (opt_childPredicate) {\n list = list.predicate(opt_childPredicate);\n }\n return list.size() > 0;\n });\n }\n}\n\nexport const predicate = new Predicate((node) => true);\n\nexport class NodeList implements XmlDoc.NodeList {\n constructor(public readonly nodes: Node[]) {}\n\n asArray(): Node[] {\n return this.nodes;\n }\n\n size(): number {\n return this.nodes.length;\n }\n\n /**\n * Filter with predicate\n */\n predicate(pr: Predicate): NodeList {\n const arr = [];\n for (const n of this.nodes) {\n if (pr.check(n)) {\n arr.push(n);\n }\n }\n return new NodeList(arr);\n }\n\n forEachNode(fn: (p1: Node, p2: (p1: Node) => void) => void): NodeList {\n const arr = [];\n const add = (n) => {\n arr.push(n);\n };\n for (let i = 0; i < this.nodes.length; i++) {\n fn(this.nodes[i], add);\n }\n return new NodeList(arr);\n }\n\n /**\n * @template T\n */\n forEach<T>(fn: (p1: Node) => T): T[] {\n const arr = [];\n for (let i = 0; i < this.nodes.length; i++) {\n arr.push(fn(this.nodes[i]));\n }\n return arr;\n }\n\n /**\n * @template T\n */\n forEachNonNull<T>(fn: (p1: Node) => T): T[] {\n const arr = [];\n for (let i = 0; i < this.nodes.length; i++) {\n const t = fn(this.nodes[i]);\n if (t != null) {\n arr.push(t);\n }\n }\n return arr;\n }\n\n child(tag: string): NodeList {\n return this.forEachNode((node, add) => {\n for (let c: Node = node.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1 && (c as Element).localName == tag) {\n add(c);\n }\n }\n });\n }\n\n childElements(): NodeList {\n return this.forEachNode((node, add) => {\n for (let c: Node = node.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n add(c);\n }\n }\n });\n }\n\n attribute(name: string): (string | null)[] {\n return this.forEachNonNull((node) => {\n if (node.nodeType == 1) {\n return (node as Element).getAttribute(name);\n }\n return null;\n });\n }\n\n textContent(): (string | null)[] {\n return this.forEach((node) => node.textContent);\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Ops - Render EPUB content files by applying page masters,\n * styling and layout.\n */\nimport \"./footnotes\";\nimport \"./table\";\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Break from \"./break\";\nimport * as Columns from \"./columns\";\nimport * as Constants from \"./constants\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssProp from \"./css-prop\";\nimport * as CssStyler from \"./css-styler\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as CssValidator from \"./css-validator\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as GeometryUtil from \"./geometry-util\";\nimport * as Layout from \"./layout\";\nimport * as LayoutProcessor from \"./layout-processor\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as PageFloats from \"./page-floats\";\nimport * as CssPage from \"./css-page\";\nimport * as Plugin from \"./plugin\";\nimport * as PageMaster from \"./page-master\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\nimport { Layout as LayoutType } from \"./types\";\nimport UserAgentBaseCss from \"./assets/user-agent-base.css\";\nimport UserAgentPageCss from \"./assets/user-agent-page.css\";\n\nexport const uaStylesheetBaseFetcher: TaskUtil.Fetcher<boolean> = new TaskUtil.Fetcher(\n () => {\n const frame: Task.Frame<boolean> = Task.newFrame(\"uaStylesheetBase\");\n const validatorSet = CssValidator.baseValidatorSet();\n const url = Base.resolveURL(\"user-agent-base.css\", Base.resourceBaseURL);\n const handler = new CssCascade.CascadeParserHandler(\n null,\n null,\n null,\n null,\n null,\n validatorSet,\n true,\n );\n handler.startStylesheet(CssParser.StylesheetFlavor.USER_AGENT);\n CssCascade.setUABaseCascade(handler.cascade);\n CssParser.parseStylesheetFromText(\n UserAgentBaseCss,\n handler,\n url,\n null,\n null,\n ).thenFinish(frame);\n return frame.result();\n },\n \"uaStylesheetBaseFetcher\",\n);\n\nexport function loadUABase(): Task.Result<boolean> {\n return uaStylesheetBaseFetcher.get();\n}\n\nexport type FontFace = {\n properties: CssCascade.ElementStyle;\n condition: Exprs.Val;\n};\n\nexport class Style {\n fontDeobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null;\n validatorSet: CssValidator.ValidatorSet;\n\n constructor(\n public readonly store: OPSDocStore,\n public readonly rootScope: Exprs.LexicalScope,\n public readonly pageScope: Exprs.LexicalScope,\n public readonly cascade: CssCascade.Cascade,\n public readonly rootBox: PageMaster.RootPageBox,\n public readonly fontFaces: FontFace[],\n public readonly footnoteProps: CssCascade.ElementStyle,\n public readonly flowProps: { [key: string]: CssCascade.ElementStyle },\n public readonly viewportProps: CssCascade.ElementStyle[],\n public readonly pageProps: { [key: string]: CssCascade.ElementStyle },\n ) {\n this.fontDeobfuscator = store.fontDeobfuscator;\n this.validatorSet = store.validatorSet;\n this.pageScope.defineBuiltIn(\"has-content\", function(name) {\n name = name as string;\n const styleInstance = this as StyleInstance;\n const cp = styleInstance.currentLayoutPosition;\n const flowChunk = cp.firstFlowChunkOfFlow(name);\n return (\n styleInstance.matchPageSide(cp.startSideOfFlow(name as string)) &&\n cp.hasContent(name as string, styleInstance.lookupOffset) &&\n !!flowChunk &&\n !styleInstance.flowChunkIsAfterParentFlowForcedBreak(flowChunk)\n );\n });\n this.pageScope.defineName(\n \"page-number\",\n new Exprs.Native(\n this.pageScope,\n function() {\n const styleInstance = this as StyleInstance;\n return (\n styleInstance.pageNumberOffset +\n styleInstance.currentLayoutPosition.page\n );\n },\n \"page-number\",\n ),\n );\n }\n\n sizeViewport(\n viewportWidth: number,\n viewportHeight: number,\n fontSize: number,\n pref?: Exprs.Preferences,\n ): { width: number; height: number; fontSize: number } {\n if (this.viewportProps.length) {\n const context = new Exprs.Context(\n this.rootScope,\n viewportWidth,\n viewportHeight,\n fontSize,\n );\n const viewportProps = CssCascade.mergeAll(context, this.viewportProps);\n const width = viewportProps[\"width\"];\n const height = viewportProps[\"height\"];\n const textZoom = viewportProps[\"text-zoom\"];\n let scaleFactor = 1;\n if ((width && height) || textZoom) {\n const defaultFontSize = Exprs.defaultUnitSizes[\"em\"];\n const zoomVal = textZoom\n ? textZoom.evaluate(context, \"text-zoom\")\n : null;\n if (zoomVal === Css.ident.scale) {\n scaleFactor = defaultFontSize / fontSize;\n fontSize = defaultFontSize;\n viewportWidth *= scaleFactor;\n viewportHeight *= scaleFactor;\n }\n if (width && height) {\n const widthVal = Css.toNumber(\n width.evaluate(context, \"width\"),\n context,\n );\n const heightVal = Css.toNumber(\n height.evaluate(context, \"height\"),\n context,\n );\n if (widthVal > 0 && heightVal > 0) {\n const spreadWidth =\n pref && pref.spreadView\n ? (widthVal + pref.pageBorder) * 2\n : widthVal;\n return { width: spreadWidth, height: heightVal, fontSize };\n }\n }\n }\n }\n return { width: viewportWidth, height: viewportHeight, fontSize };\n }\n}\n\n//-------------------------------------------------------------------------------\nexport class StyleInstance extends Exprs.Context\n implements\n CssStyler.FlowListener,\n PageMaster.InstanceHolder,\n Vgen.StylerProducer {\n lang: string | null;\n primaryFlows = { body: true } as { [key: string]: boolean };\n rootPageBoxInstance: PageMaster.RootPageBoxInstance = null;\n styler: CssStyler.Styler = null;\n stylerMap: { [key: string]: CssStyler.Styler } = null;\n currentLayoutPosition: Vtree.LayoutPosition = null;\n layoutPositionAtPageStart: Vtree.LayoutPosition = null;\n lookupOffset: number = 0;\n faces: Font.DocumentFaces;\n pageBoxInstances: { [key: string]: PageMaster.PageBoxInstance } = {};\n pageManager: CssPage.PageManager = null;\n private rootPageFloatLayoutContext: PageFloats.PageFloatLayoutContext;\n pageBreaks: { [key: string]: boolean } = {};\n pageProgression: Constants.PageProgression | null = null;\n pageSheetSize: { [key: string]: { width: number; height: number } } = {};\n pageSheetHeight: number = 0;\n pageSheetWidth: number = 0;\n actualPageWidth: number;\n actualPageHeight: number;\n\n constructor(\n public readonly style: Style,\n public readonly xmldoc: XmlDoc.XMLDocHolder,\n defaultLang: string | null,\n public readonly viewport: Vgen.Viewport,\n public readonly clientLayout: Vtree.ClientLayout,\n public readonly fontMapper: Font.Mapper,\n public readonly customRenderer: Vgen.CustomRenderer,\n public readonly fallbackMap: { [key: string]: string },\n public readonly pageNumberOffset: number,\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n public readonly counterStore: Counters.CounterStore,\n pageProgression?: Constants.PageProgression,\n ) {\n super(style.rootScope, viewport.width, viewport.height, viewport.fontSize);\n this.lang = xmldoc.lang || defaultLang;\n this.faces = new Font.DocumentFaces(this.style.fontDeobfuscator);\n this.rootPageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n null,\n null,\n null,\n null,\n null,\n null,\n null,\n );\n this.pageProgression = pageProgression || null;\n for (const flowName in style.flowProps) {\n const flowStyle = style.flowProps[flowName];\n const consume = CssCascade.getProp(flowStyle, \"flow-consume\");\n if (consume) {\n const consumeVal = consume.evaluate(this, \"flow-consume\");\n if (consumeVal == Css.ident.all) {\n this.primaryFlows[flowName] = true;\n } else {\n delete this.primaryFlows[flowName];\n }\n }\n }\n }\n\n init(): Task.Result<boolean> {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"StyleInstance.init\");\n const counterListener = self.counterStore.createCounterListener(\n self.xmldoc.url,\n );\n const counterResolver = self.counterStore.createCounterResolver(\n self.xmldoc.url,\n self.style.rootScope,\n self.style.pageScope,\n );\n self.styler = new CssStyler.Styler(\n self.xmldoc,\n self.style.cascade,\n self.style.rootScope,\n self,\n this.primaryFlows,\n self.style.validatorSet,\n counterListener,\n counterResolver,\n );\n counterResolver.setStyler(self.styler);\n self.styler.resetFlowChunkStream(self);\n self.stylerMap = {};\n self.stylerMap[self.xmldoc.url] = self.styler;\n const docElementStyle = self.styler.getTopContainerStyle();\n if (!self.pageProgression) {\n self.pageProgression = CssPage.resolvePageProgression(docElementStyle);\n }\n const rootBox = this.style.rootBox;\n this.rootPageBoxInstance = new PageMaster.RootPageBoxInstance(rootBox);\n const cascadeInstance = this.style.cascade.createInstance(\n self,\n counterListener,\n counterResolver,\n this.lang,\n );\n this.rootPageBoxInstance.applyCascadeAndInit(\n cascadeInstance,\n docElementStyle,\n );\n this.rootPageBoxInstance.resolveAutoSizing(self);\n this.pageManager = new CssPage.PageManager(\n cascadeInstance,\n this.style.pageScope,\n this.rootPageBoxInstance,\n self,\n docElementStyle,\n );\n const srcFaces = [] as Font.Face[];\n for (const fontFace of self.style.fontFaces) {\n if (fontFace.condition && !fontFace.condition.evaluate(self)) {\n continue;\n }\n const properties = Font.prepareProperties(fontFace.properties, self);\n const srcFace = new Font.Face(properties);\n srcFaces.push(srcFace);\n }\n self.fontMapper.findOrLoadFonts(srcFaces, self.faces).thenFinish(frame);\n\n // Determine page sheet sizes corresponding to page selectors\n const pageProps = self.style.pageProps;\n Object.keys(pageProps).forEach((selector) => {\n const pageSizeAndBleed = CssPage.evaluatePageSizeAndBleed(\n CssPage.resolvePageSizeAndBleed(pageProps[selector] as any),\n this,\n );\n this.pageSheetSize[selector] = {\n width: pageSizeAndBleed.pageWidth + pageSizeAndBleed.cropOffset * 2,\n height: pageSizeAndBleed.pageHeight + pageSizeAndBleed.cropOffset * 2,\n };\n });\n return frame.result();\n }\n\n /**\n * @override\n */\n getStylerForDoc(xmldoc: XmlDoc.XMLDocHolder): CssStyler.AbstractStyler {\n let styler = this.stylerMap[xmldoc.url];\n if (!styler) {\n const style = this.style.store.getStyleForDoc(xmldoc);\n\n // We need a separate content, so that variables can get potentially\n // different values.\n const context = new Exprs.Context(\n style.rootScope,\n this.pageWidth(),\n this.pageHeight(),\n this.initialFontSize,\n );\n const counterListener = this.counterStore.createCounterListener(\n xmldoc.url,\n );\n const counterResolver = this.counterStore.createCounterResolver(\n xmldoc.url,\n style.rootScope,\n style.pageScope,\n );\n styler = new CssStyler.Styler(\n xmldoc,\n style.cascade,\n style.rootScope,\n context,\n this.primaryFlows,\n style.validatorSet,\n counterListener,\n counterResolver,\n );\n this.stylerMap[xmldoc.url] = styler;\n }\n return styler;\n }\n\n /**\n * @override\n */\n registerInstance(key: string, instance: PageMaster.PageBoxInstance): void {\n this.pageBoxInstances[key] = instance;\n }\n\n /**\n * @override\n */\n lookupInstance(key: string): PageMaster.PageBoxInstance {\n return this.pageBoxInstances[key];\n }\n\n /**\n * @override\n */\n encounteredFlowChunk(flowChunk: Vtree.FlowChunk, flow: Vtree.Flow): any {\n const cp = this.currentLayoutPosition;\n if (cp) {\n if (!cp.flows[flowChunk.flowName]) {\n cp.flows[flowChunk.flowName] = flow;\n } else {\n flow = cp.flows[flowChunk.flowName];\n }\n let flowPosition = cp.flowPositions[flowChunk.flowName];\n if (!flowPosition) {\n flowPosition = new Vtree.FlowPosition();\n cp.flowPositions[flowChunk.flowName] = flowPosition;\n }\n const nodePosition = Vtree.newNodePositionFromNode(flowChunk.element);\n const chunkPosition = new Vtree.ChunkPosition(nodePosition);\n const flowChunkPosition = new Vtree.FlowChunkPosition(\n chunkPosition,\n flowChunk,\n );\n flowPosition.positions.push(flowChunkPosition);\n }\n }\n\n getConsumedOffset(flowPosition: Vtree.FlowPosition): number {\n let offset = Number.POSITIVE_INFINITY;\n for (let i = 0; i < flowPosition.positions.length; i++) {\n const pos = flowPosition.positions[i].chunkPosition.primary;\n let node = pos.steps[0].node;\n let offsetInNode = pos.offsetInNode;\n let after = pos.after;\n let k = 0;\n while (node.ownerDocument != this.xmldoc.document) {\n k++;\n node = pos.steps[k].node;\n after = false;\n offsetInNode = 0;\n }\n const chunkOffset = this.xmldoc.getNodeOffset(node, offsetInNode, after);\n if (chunkOffset < offset) {\n offset = chunkOffset;\n }\n }\n return offset;\n }\n\n /**\n * @param noLookAhead Do not look ahead elements that are not styled yet\n * @return document offset of the given layoutPosition\n */\n getPosition(\n layoutPosition?: Vtree.LayoutPosition,\n noLookAhead?: boolean,\n ): number {\n if (!layoutPosition) {\n return 0;\n }\n let currentPosition = Number.POSITIVE_INFINITY;\n for (const flowName in this.primaryFlows) {\n let flowPosition = layoutPosition.flowPositions[flowName];\n if (\n !noLookAhead &&\n (!flowPosition || flowPosition.positions.length == 0) &&\n this.currentLayoutPosition\n ) {\n this.styler.styleUntilFlowIsReached(flowName);\n flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n if (layoutPosition != this.currentLayoutPosition) {\n if (flowPosition) {\n flowPosition = flowPosition.clone();\n layoutPosition.flowPositions[flowName] = flowPosition;\n }\n }\n }\n if (flowPosition) {\n const consumedOffset = this.getConsumedOffset(flowPosition);\n if (consumedOffset < currentPosition) {\n currentPosition = consumedOffset;\n }\n }\n }\n return currentPosition;\n }\n\n dumpLocation(position) {\n Logging.logger.debug(\"Location - page\", this.currentLayoutPosition.page);\n Logging.logger.debug(\" current:\", position);\n Logging.logger.debug(\" lookup:\", this.lookupOffset);\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (const p of flowPosition.positions) {\n Logging.logger.debug(\n \" Chunk\",\n `${flowName}:`,\n p.flowChunk.startOffset,\n );\n }\n }\n }\n\n matchPageSide(side: string): boolean {\n switch (side) {\n case \"left\":\n case \"right\":\n case \"recto\":\n case \"verso\":\n return new Exprs.Named(this.style.pageScope, `${side}-page`).evaluate(\n this,\n ) as boolean;\n default:\n return true;\n }\n }\n\n updateStartSide(layoutPosition: Vtree.LayoutPosition) {\n for (const name in layoutPosition.flowPositions) {\n const flowPos = layoutPosition.flowPositions[name];\n if (flowPos && flowPos.positions.length > 0) {\n const flowChunk = flowPos.positions[0].flowChunk;\n if (this.getConsumedOffset(flowPos) === flowChunk.startOffset) {\n const flowChunkBreakBefore =\n flowPos.positions[0].flowChunk.breakBefore;\n const flowBreakAfter = Break.startSideValueToBreakValue(\n flowPos.startSide,\n );\n flowPos.startSide = Break.breakValueToStartSideValue(\n Break.resolveEffectiveBreakValue(\n flowBreakAfter,\n flowChunkBreakBefore,\n ),\n );\n }\n }\n }\n }\n\n /**\n * @param cascadedPageStyle Cascaded page style specified in page context\n */\n selectPageMaster(\n cascadedPageStyle: CssCascade.ElementStyle,\n ): PageMaster.PageMasterInstance {\n const self = this;\n const cp = this.currentLayoutPosition;\n\n // 3.5. Page Layout Processing Model\n // 1. Determine current position in the document: Find the minimal\n // consumed-offset for all elements not fully-consumed in each primary flow.\n // Current position is maximum of the results among all primary flows.\n const currentPosition = this.getPosition(cp);\n if (currentPosition == Number.POSITIVE_INFINITY) {\n // end of primary content is reached\n return null;\n }\n\n // 2. Page master selection: for each page master:\n const pageMasters = this.rootPageBoxInstance\n .children as PageMaster.PageMasterInstance[];\n let pageMaster: PageMaster.PageMasterInstance;\n for (let i = 0; i < pageMasters.length; i++) {\n pageMaster = pageMasters[i];\n\n // Skip a page master generated for @page rules\n if (pageMaster.pageBox.pseudoName === CssPage.pageRuleMasterPseudoName) {\n continue;\n }\n let coeff = 1;\n\n // A. Calculate lookup position using current position and utilization\n // (see -epubx-utilization property)\n const utilization = pageMaster.getProp(self, \"utilization\");\n if (utilization && utilization.isNum()) {\n coeff = (utilization as Css.Num).num;\n }\n const em = self.queryUnitSize(\"em\", false);\n const pageArea = self.pageWidth() * self.pageHeight();\n const lookup = Math.ceil((coeff * pageArea) / (em * em));\n\n // B. Determine element eligibility. Each element in a flow is considered\n // eligible if it is is not marked as fully consumed and it comes in the\n // document before the lookup position. Feed lookupOffset and flow\n // availability into the context\n this.lookupOffset = this.styler.styleUntil(currentPosition, lookup);\n Asserts.assert(cp);\n this.updateStartSide(cp);\n\n // update layoutPositionAtPageStart since startSide of FlowChunks may be\n // updated\n this.layoutPositionAtPageStart = cp.clone();\n this.initLingering();\n self.clearScope(this.style.pageScope);\n\n // C. Determine content availability. Flow has content available if it\n // contains eligible elements. D. Determine if page master is enabled\n // using rules in Section 3.4.7\n const enabled = pageMaster.getProp(self, \"enabled\");\n\n // E. First enabled page master is used for the next page\n if (!enabled || enabled === Css.ident._true) {\n if (VIVLIOSTYLE_DEBUG) {\n this.dumpLocation(currentPosition);\n }\n\n // Apply @page rules\n return this.pageManager.getPageRulePageMaster(\n pageMaster,\n cascadedPageStyle,\n );\n }\n }\n throw new Error(\"No enabled page masters\");\n }\n\n flowChunkIsAfterParentFlowForcedBreak(flowChunk: Vtree.FlowChunk): boolean {\n const flows = this.layoutPositionAtPageStart.flows;\n const parentFlowName = flows[flowChunk.flowName].parentFlowName;\n if (parentFlowName) {\n const startOffset = flowChunk.startOffset;\n const forcedBreakOffsets = flows[parentFlowName].forcedBreakOffsets;\n if (!forcedBreakOffsets.length || startOffset < forcedBreakOffsets[0]) {\n return false;\n }\n const breakOffsetBeforeStartIndex =\n Base.binarySearch(\n forcedBreakOffsets.length,\n (i) => forcedBreakOffsets[i] > startOffset,\n ) - 1;\n const breakOffsetBeforeStart =\n forcedBreakOffsets[breakOffsetBeforeStartIndex];\n const parentFlowPosition = this.layoutPositionAtPageStart.flowPositions[\n parentFlowName\n ];\n const parentStartOffset = this.getConsumedOffset(parentFlowPosition);\n if (breakOffsetBeforeStart < parentStartOffset) {\n return false;\n }\n if (parentStartOffset < breakOffsetBeforeStart) {\n return true;\n }\n\n // Special case: parentStartOffset === breakOffsetBeforeStart\n // In this case, the flowChunk can be used if the start side of the parent\n // flow matches the current page side.\n return !this.matchPageSide(parentFlowPosition.startSide);\n }\n return false;\n }\n\n setFormattingContextToColumn(column: LayoutType.Column, flowName: string) {\n const flow = this.currentLayoutPosition.flows[flowName];\n if (!flow.formattingContext) {\n flow.formattingContext = new LayoutProcessor.BlockFormattingContext(null);\n }\n column.flowRootFormattingContext = flow.formattingContext;\n }\n\n layoutDeferredPageFloats(column: LayoutType.Column): Task.Result<boolean> {\n const pageFloatLayoutContext = column.pageFloatLayoutContext;\n const deferredFloats = pageFloatLayoutContext.getDeferredPageFloatContinuations();\n const frame = Task.newFrame<boolean>(\"layoutDeferredPageFloats\");\n let invalidated = false;\n let i = 0;\n frame\n .loopWithFrame((loopFrame) => {\n if (i === deferredFloats.length) {\n loopFrame.breakLoop();\n return;\n }\n const continuation = deferredFloats[i++];\n const float = continuation.float;\n const strategy = new PageFloats.PageFloatLayoutStrategyResolver().findByFloat(\n float,\n );\n const pageFloatFragment = strategy.findPageFloatFragment(\n float,\n pageFloatLayoutContext,\n );\n if (pageFloatFragment && pageFloatFragment.hasFloat(float)) {\n loopFrame.continueLoop();\n return;\n } else if (\n pageFloatLayoutContext.isForbidden(float) ||\n pageFloatLayoutContext.hasPrecedingFloatsDeferredToNext(float)\n ) {\n pageFloatLayoutContext.deferPageFloat(continuation);\n loopFrame.breakLoop();\n return;\n }\n column\n .layoutPageFloatInner(continuation, strategy, null, pageFloatFragment)\n .then((success) => {\n if (!success) {\n loopFrame.breakLoop();\n return;\n }\n const parentInvalidated = pageFloatLayoutContext.parent.isInvalidated();\n if (parentInvalidated) {\n loopFrame.breakLoop();\n return;\n } else if (\n pageFloatLayoutContext.isInvalidated() &&\n !parentInvalidated\n ) {\n invalidated = true;\n pageFloatLayoutContext.validate();\n }\n loopFrame.continueLoop();\n });\n })\n .then(() => {\n if (invalidated) {\n pageFloatLayoutContext.invalidate();\n }\n frame.finish(true);\n });\n return frame.result();\n }\n\n getLastAfterPositionIfDeferredFloatsExists(\n column: LayoutType.Column,\n newPosition: Vtree.ChunkPosition | null,\n ): Vtree.ChunkPosition | null {\n const pageFloatLayoutContext = column.pageFloatLayoutContext;\n const deferredFloats = pageFloatLayoutContext.getPageFloatContinuationsDeferredToNext();\n if (deferredFloats.length > 0) {\n if (column.lastAfterPosition) {\n let result: Vtree.ChunkPosition;\n if (newPosition) {\n // Need overflown footnotes owned by newPosition\n result = newPosition.clone();\n result.primary = column.lastAfterPosition;\n } else {\n result = new Vtree.ChunkPosition(column.lastAfterPosition);\n }\n return result;\n } else {\n Asserts.assert(\"column.lastAfterPosition === null\");\n return null;\n }\n } else {\n return null;\n }\n }\n\n /**\n * @return holding true\n */\n layoutColumn(\n column: LayoutType.Column,\n flowName: string,\n ): Task.Result<boolean> {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n if (!flowPosition || !this.matchPageSide(flowPosition.startSide)) {\n return Task.newResult(true);\n }\n flowPosition.startSide = \"any\";\n this.setFormattingContextToColumn(column, flowName);\n column.init();\n if (this.primaryFlows[flowName] && column.bands.length > 0) {\n // In general, we force non-fitting content. Exception is only for primary\n // flow columns that have exclusions.\n column.forceNonfitting = false;\n }\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutColumn\");\n this.layoutDeferredPageFloats(column).then(() => {\n if (column.pageFloatLayoutContext.isInvalidated()) {\n frame.finish(true);\n return;\n }\n\n // Record indices of repeated positions and removed positions\n const repeatedIndices = [] as number[];\n const removedIndices = [] as number[];\n let leadingEdge = true;\n frame\n .loopWithFrame((loopFrame) => {\n if (\n column.pageFloatLayoutContext.hasContinuingFloatFragmentsInFlow(\n flowName,\n )\n ) {\n loopFrame.breakLoop();\n return;\n }\n while (flowPosition.positions.length - removedIndices.length > 0) {\n let index = 0;\n\n // Skip all removed positions\n while (removedIndices.includes(index)) {\n index++;\n }\n let selected = flowPosition.positions[index];\n if (\n selected.flowChunk.startOffset > self.lookupOffset ||\n self.flowChunkIsAfterParentFlowForcedBreak(selected.flowChunk)\n ) {\n break;\n }\n for (let k = index + 1; k < flowPosition.positions.length; k++) {\n if (removedIndices.includes(k)) {\n continue; // Skip removed positions\n }\n const alt = flowPosition.positions[k];\n if (\n alt.flowChunk.startOffset > self.lookupOffset ||\n self.flowChunkIsAfterParentFlowForcedBreak(alt.flowChunk)\n ) {\n break;\n }\n if (alt.flowChunk.isBetter(selected.flowChunk)) {\n selected = alt;\n index = k;\n }\n }\n const flowChunk = selected.flowChunk;\n let pending = true;\n column\n .layout(\n selected.chunkPosition,\n leadingEdge,\n flowPosition.breakAfter,\n )\n .then((newPosition) => {\n if (column.pageFloatLayoutContext.isInvalidated()) {\n loopFrame.breakLoop();\n return;\n }\n leadingEdge = false;\n\n // static: keep in the flow\n if (\n selected.flowChunk.repeated &&\n (newPosition === null || flowChunk.exclusive)\n ) {\n repeatedIndices.push(index);\n }\n if (flowChunk.exclusive) {\n // exclusive, only can have one, remove from the flow even\n // if it did not fit\n removedIndices.push(index);\n loopFrame.breakLoop();\n return;\n } else {\n // not exclusive\n const endOfColumn = !!newPosition || !!column.pageBreakType;\n const lastAfterPosition = self.getLastAfterPositionIfDeferredFloatsExists(\n column,\n newPosition,\n );\n if (column.pageBreakType && lastAfterPosition) {\n selected.chunkPosition = lastAfterPosition;\n\n // TODO propagate pageBreakType\n flowPosition.breakAfter = column.pageBreakType;\n column.pageBreakType = null;\n } else {\n // go to the next element in the flow\n removedIndices.push(index);\n if (newPosition || lastAfterPosition) {\n // did not fit completely\n selected.chunkPosition = newPosition || lastAfterPosition;\n repeatedIndices.push(index);\n }\n if (column.pageBreakType) {\n // forced break\n flowPosition.startSide = Break.breakValueToStartSideValue(\n column.pageBreakType,\n );\n }\n }\n if (endOfColumn) {\n loopFrame.breakLoop();\n return;\n }\n }\n\n // Since at least one flowChunk has been placed in the\n // column, the next flowChunk of the flow can be deferred to\n // the next partition if there is not enough space in the\n // current partition.\n column.forceNonfitting = false;\n if (pending) {\n // Sync result\n pending = false;\n } else {\n // Async result\n loopFrame.continueLoop();\n }\n });\n if (pending) {\n // Async result\n pending = false;\n return;\n }\n }\n\n // Sync result\n loopFrame.breakLoop();\n })\n .then(() => {\n if (!column.pageFloatLayoutContext.isInvalidated()) {\n // Keep positions repeated or not removed\n flowPosition.positions = flowPosition.positions.filter(\n (pos, i) =>\n repeatedIndices.includes(i) || !removedIndices.includes(i),\n );\n if (flowPosition.breakAfter === \"column\") {\n flowPosition.breakAfter = null;\n }\n column.saveDistanceToBlockEndFloats();\n const edge = column.pageFloatLayoutContext.getMaxReachedAfterEdge();\n column.updateMaxReachedAfterEdge(edge);\n }\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n createLayoutConstraint(\n pageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): LayoutType.LayoutConstraint {\n const pageIndex = this.currentLayoutPosition.page - 1;\n const counterConstraint = this.counterStore.createLayoutConstraint(\n pageIndex,\n );\n return new Layout.AllLayoutConstraint(\n [counterConstraint].concat(pageFloatLayoutContext.getLayoutConstraints()),\n );\n }\n\n private createAndLayoutColumn(\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n layoutContainer: Vtree.Container,\n currentColumnIndex: number,\n flowNameStr: string,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n columnCount: number,\n columnGap: number,\n columnWidth: number,\n innerShape: GeometryUtil.Shape,\n layoutContext: Vtree.LayoutContext,\n forceNonFitting: boolean,\n ): Task.Result<LayoutType.Column> {\n const self = this;\n const dontApplyExclusions = boxInstance.vertical\n ? boxInstance.isAutoWidth && boxInstance.isRightDependentOnAutoWidth\n : boxInstance.isAutoHeight && boxInstance.isTopDependentOnAutoHeight;\n const boxContainer = layoutContainer.element;\n const columnPageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n regionPageFloatLayoutContext,\n PageFloats.FloatReference.COLUMN,\n null,\n flowNameStr,\n null,\n null,\n null,\n );\n const positionAtColumnStart = self.currentLayoutPosition.clone();\n const frame: Task.Frame<LayoutType.Column> = Task.newFrame(\n \"createAndLayoutColumn\",\n );\n let column: LayoutType.Column;\n frame\n .loopWithFrame((loopFrame) => {\n const layoutConstraint = self.createLayoutConstraint(\n columnPageFloatLayoutContext,\n );\n if (columnCount > 1) {\n const columnContainer = self.viewport.document.createElement(\"div\");\n Base.setCSSProperty(columnContainer, \"position\", \"absolute\");\n boxContainer.appendChild(columnContainer);\n column = new Layout.Column(\n columnContainer,\n layoutContext,\n self.clientLayout,\n layoutConstraint,\n columnPageFloatLayoutContext,\n );\n column.forceNonfitting = forceNonFitting;\n column.vertical = layoutContainer.vertical;\n column.snapHeight = layoutContainer.snapHeight;\n column.snapWidth = layoutContainer.snapWidth;\n if (layoutContainer.vertical) {\n const columnY =\n currentColumnIndex * (columnWidth + columnGap) +\n layoutContainer.paddingTop;\n column.setHorizontalPosition(\n layoutContainer.paddingLeft,\n layoutContainer.width,\n );\n column.setVerticalPosition(columnY, columnWidth);\n } else {\n const columnX =\n currentColumnIndex * (columnWidth + columnGap) +\n layoutContainer.paddingLeft;\n column.setVerticalPosition(\n layoutContainer.paddingTop,\n layoutContainer.height,\n );\n column.setHorizontalPosition(columnX, columnWidth);\n }\n column.originX = offsetX;\n column.originY = offsetY;\n } else {\n column = new Layout.Column(\n boxContainer,\n layoutContext,\n self.clientLayout,\n layoutConstraint,\n columnPageFloatLayoutContext,\n );\n column.copyFrom(layoutContainer);\n }\n column.exclusions = dontApplyExclusions ? [] : exclusions.concat();\n column.innerShape = innerShape;\n columnPageFloatLayoutContext.setContainer(column);\n if (column.width >= 0) {\n // column.element.style.outline = \"1px dotted green\";\n self.layoutColumn(column, flowNameStr).then(() => {\n if (!columnPageFloatLayoutContext.isInvalidated()) {\n columnPageFloatLayoutContext.finish();\n }\n if (\n column.pageFloatLayoutContext.isInvalidated() &&\n !regionPageFloatLayoutContext.isInvalidated()\n ) {\n column.pageFloatLayoutContext.validate();\n self.currentLayoutPosition = positionAtColumnStart.clone();\n if (column.element !== boxContainer) {\n boxContainer.removeChild(column.element);\n }\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n } else {\n columnPageFloatLayoutContext.finish();\n loopFrame.breakLoop();\n }\n })\n .then(() => {\n frame.finish(column);\n });\n return frame.result();\n }\n\n setPagePageFloatLayoutContextContainer(\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n boxInstance: PageMaster.PageBoxInstance,\n layoutContainer: Vtree.Container,\n ) {\n if (\n boxInstance instanceof CssPage.PageRulePartitionInstance ||\n (boxInstance instanceof PageMaster.PageMasterInstance &&\n !(boxInstance instanceof CssPage.PageRuleMasterInstance))\n ) {\n pagePageFloatLayoutContext.setContainer(layoutContainer);\n }\n }\n\n getRegionPageFloatLayoutContext(\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n boxInstance: PageMaster.PageBoxInstance,\n layoutContainer: Vtree.Container,\n flowName: string,\n ): PageFloats.PageFloatLayoutContext {\n Asserts.assert(boxInstance instanceof PageMaster.PartitionInstance);\n const writingMode = boxInstance.getProp(this, \"writing-mode\") || null;\n const direction = boxInstance.getProp(this, \"direction\") || null;\n return new PageFloats.PageFloatLayoutContext(\n pagePageFloatLayoutContext,\n PageFloats.FloatReference.REGION,\n layoutContainer,\n flowName,\n null,\n writingMode,\n direction,\n );\n }\n\n layoutFlowColumnsWithBalancing(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n flowNameStr: string,\n columnCount: number,\n ): Task.Result<LayoutType.Column[]> {\n const self = this;\n const positionAtContainerStart = self.currentLayoutPosition.clone();\n const regionPageFloatLayoutContext = self.getRegionPageFloatLayoutContext(\n pagePageFloatLayoutContext,\n boxInstance,\n layoutContainer,\n flowNameStr,\n );\n let isFirstTime = true;\n\n function layoutColumns() {\n self.currentLayoutPosition = positionAtContainerStart.clone();\n return self\n .layoutFlowColumns(\n page,\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n regionPageFloatLayoutContext,\n layoutContainer,\n flowNameStr,\n columnCount,\n isFirstTime,\n )\n .thenAsync((columns) => {\n if (columns) {\n return Task.newResult({\n columns,\n position: self.currentLayoutPosition,\n });\n } else {\n return Task.newResult(null);\n }\n });\n }\n return layoutColumns().thenAsync((generatorResult) => {\n if (!generatorResult) {\n return Task.newResult(null);\n }\n if (columnCount <= 1) {\n return Task.newResult(generatorResult.columns);\n }\n const columnFill =\n (boxInstance.getProp(self, \"column-fill\") as Css.Ident) ||\n Css.ident.balance;\n const flowPosition =\n self.currentLayoutPosition.flowPositions[flowNameStr];\n Asserts.assert(flowPosition);\n const columnBalancer = Columns.createColumnBalancer(\n columnCount,\n columnFill,\n layoutColumns,\n regionPageFloatLayoutContext,\n layoutContainer,\n generatorResult.columns,\n flowPosition,\n );\n if (!columnBalancer) {\n return Task.newResult(generatorResult.columns);\n }\n isFirstTime = false;\n pagePageFloatLayoutContext.lock();\n regionPageFloatLayoutContext.lock();\n return columnBalancer\n .balanceColumns(generatorResult)\n .thenAsync((result) => {\n pagePageFloatLayoutContext.unlock();\n pagePageFloatLayoutContext.validate();\n regionPageFloatLayoutContext.unlock();\n self.currentLayoutPosition = result.position;\n return Task.newResult(result.columns);\n });\n });\n }\n\n layoutFlowColumns(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n regionPageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n layoutContainer: Vtree.Container,\n flowNameStr: string,\n columnCount: number,\n forceNonFitting: boolean,\n ): Task.Result<LayoutType.Column[] | null> {\n const self = this;\n const frame: Task.Frame<LayoutType.Column[] | null> = Task.newFrame(\n \"layoutFlowColumns\",\n );\n const positionAtContainerStart = self.currentLayoutPosition.clone();\n const columnGap = boxInstance.getPropAsNumber(self, \"column-gap\");\n\n // Don't query columnWidth when it's not needed, so that width calculation\n // can be delayed for width: auto columns.\n const columnWidth =\n columnCount > 1\n ? boxInstance.getPropAsNumber(self, \"column-width\")\n : layoutContainer.width;\n const regionIds = boxInstance.getActiveRegions(self);\n const innerShapeVal = boxInstance.getProp(self, \"shape-inside\");\n const innerShape = CssProp.toShape(\n innerShapeVal,\n 0,\n 0,\n layoutContainer.width,\n layoutContainer.height,\n self,\n );\n const layoutContext = new Vgen.ViewFactory(\n flowNameStr,\n self,\n self.viewport,\n self.styler,\n regionIds,\n self.xmldoc,\n self.faces,\n self.style.footnoteProps,\n self,\n page,\n self.customRenderer,\n self.fallbackMap,\n this.documentURLTransformer,\n );\n let columnIndex = 0;\n let column: LayoutType.Column = null;\n let columns: LayoutType.Column[] = [];\n frame\n .loopWithFrame((loopFrame) => {\n self\n .createAndLayoutColumn(\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n layoutContainer,\n columnIndex++,\n flowNameStr,\n regionPageFloatLayoutContext,\n columnCount,\n columnGap,\n columnWidth,\n innerShape,\n layoutContext,\n forceNonFitting,\n )\n .then((c) => {\n if (pagePageFloatLayoutContext.isInvalidated()) {\n columns = null;\n loopFrame.breakLoop();\n return;\n }\n const forcedRegionBreak =\n !!c.pageBreakType && c.pageBreakType !== \"column\";\n if (\n (forcedRegionBreak || columnIndex === columnCount) &&\n !regionPageFloatLayoutContext.isInvalidated()\n ) {\n regionPageFloatLayoutContext.finish();\n }\n if (regionPageFloatLayoutContext.isInvalidated()) {\n columnIndex = 0;\n self.currentLayoutPosition = positionAtContainerStart.clone();\n regionPageFloatLayoutContext.validate();\n if (regionPageFloatLayoutContext.isLocked()) {\n columns = null;\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n return;\n }\n column = c;\n columns[columnIndex - 1] = column;\n if (column.pageBreakType) {\n if (column.pageBreakType != \"column\") {\n // skip remaining columns\n columnIndex = columnCount;\n if (column.pageBreakType != \"region\") {\n // skip remaining regions\n self.pageBreaks[flowNameStr] = true;\n }\n }\n }\n if (columnIndex < columnCount) {\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n frame.finish(columns);\n });\n return frame.result();\n }\n\n /**\n * @return holding true\n */\n layoutContainer(\n page: Vtree.Page,\n boxInstance: PageMaster.PageBoxInstance,\n parentContainer: HTMLElement,\n offsetX: number,\n offsetY: number,\n exclusions: GeometryUtil.Shape[],\n pagePageFloatLayoutContext: PageFloats.PageFloatLayoutContext,\n ): Task.Result<boolean> {\n const self = this;\n boxInstance.reset();\n const enabled = boxInstance.getProp(self, \"enabled\");\n if (enabled && enabled !== Css.ident._true) {\n return Task.newResult(true);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"layoutContainer\");\n const wrapFlow = boxInstance.getProp(self, \"wrap-flow\");\n const dontExclude = wrapFlow === Css.ident.auto;\n const flowName = boxInstance.getProp(self, \"flow-from\");\n const boxContainer = self.viewport.document.createElement(\"div\");\n const position = boxInstance.getProp(self, \"position\");\n Base.setCSSProperty(\n boxContainer,\n \"position\",\n position ? (position as any).name : \"absolute\",\n );\n parentContainer.insertBefore(boxContainer, parentContainer.firstChild);\n let layoutContainer = new Vtree.Container(boxContainer);\n layoutContainer.vertical = boxInstance.vertical;\n layoutContainer.exclusions = exclusions;\n boxInstance.prepareContainer(\n self,\n layoutContainer,\n page,\n self.faces,\n self.clientLayout,\n );\n layoutContainer.originX = offsetX;\n layoutContainer.originY = offsetY;\n offsetX +=\n layoutContainer.left +\n layoutContainer.marginLeft +\n layoutContainer.borderLeft;\n offsetY +=\n layoutContainer.top +\n layoutContainer.marginTop +\n layoutContainer.borderTop;\n this.setPagePageFloatLayoutContextContainer(\n pagePageFloatLayoutContext,\n boxInstance,\n layoutContainer,\n );\n let cont: Task.Result<boolean>;\n let removed = false;\n if (!flowName || !flowName.isIdent()) {\n const contentVal = boxInstance.getProp(self, \"content\");\n if (contentVal && Vtree.nonTrivialContent(contentVal)) {\n let innerContainerTag = \"span\";\n if ((contentVal as any).url) {\n innerContainerTag = \"img\";\n }\n const innerContainer = self.viewport.document.createElement(\n innerContainerTag,\n );\n contentVal.visit(\n new Vtree.ContentPropertyHandler(\n innerContainer,\n self,\n contentVal,\n self.counterStore.getExprContentListener(),\n ),\n );\n boxContainer.appendChild(innerContainer);\n if (innerContainerTag == \"img\") {\n boxInstance.transferSinglUriContentProps(\n self,\n innerContainer,\n self.faces,\n );\n }\n boxInstance.transferContentProps(\n self,\n layoutContainer,\n page,\n self.faces,\n );\n } else if (boxInstance.suppressEmptyBoxGeneration) {\n parentContainer.removeChild(boxContainer);\n removed = true;\n }\n if (!removed) {\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n null,\n 1,\n self.clientLayout,\n self.faces,\n );\n }\n cont = Task.newResult(true);\n } else if (!self.pageBreaks[flowName.toString()]) {\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"layoutContainer.inner\",\n );\n const flowNameStr = flowName.toString();\n\n // for now only a single column in vertical case\n const columnCount = boxInstance.getPropAsNumber(self, \"column-count\");\n self\n .layoutFlowColumnsWithBalancing(\n page,\n boxInstance,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n layoutContainer,\n flowNameStr,\n columnCount,\n )\n .then((columns) => {\n if (!pagePageFloatLayoutContext.isInvalidated()) {\n const column = columns[0];\n Asserts.assert(column);\n if (column.element === boxContainer) {\n layoutContainer = column;\n }\n layoutContainer.computedBlockSize = Math.max.apply(\n null,\n columns.map((c) => c.computedBlockSize),\n );\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n column,\n columnCount,\n self.clientLayout,\n self.faces,\n );\n const flowPosition =\n self.currentLayoutPosition.flowPositions[flowNameStr];\n if (flowPosition && flowPosition.breakAfter === \"region\") {\n flowPosition.breakAfter = null;\n }\n }\n innerFrame.finish(true);\n });\n cont = innerFrame.result();\n } else {\n if (!pagePageFloatLayoutContext.isInvalidated()) {\n boxInstance.finishContainer(\n self,\n layoutContainer,\n page,\n null,\n 1,\n self.clientLayout,\n self.faces,\n );\n }\n cont = Task.newResult(true);\n }\n cont.then(() => {\n if (pagePageFloatLayoutContext.isInvalidated()) {\n frame.finish(true);\n return;\n }\n if (\n !boxInstance.isAutoHeight ||\n Math.floor(layoutContainer.computedBlockSize) > 0\n ) {\n if (!removed && !dontExclude) {\n const outerShapeProp = boxInstance.getProp(self, \"shape-outside\");\n const outerShape = layoutContainer.getOuterShape(\n outerShapeProp,\n self,\n );\n\n // Though it seems that LShapeFloatBug still exists in Firefox, it\n // apparently does not occur on exclusion floats. See the test file:\n // test/files/column-break-bug.html\n // if (Base.checkLShapeFloatBug(self.viewport.root)) {\n // \t// Simplistic bug workaround: add a copy of the shape translated up.\n // exclusions.push(outerShape.withOffset(0, -1.25 * self.queryUnitSize(\"em\", false)));\n // }\n exclusions.push(outerShape);\n }\n } else if (boxInstance.children.length == 0) {\n parentContainer.removeChild(boxContainer);\n frame.finish(true);\n return;\n }\n let i = boxInstance.children.length - 1;\n frame\n .loop(() => {\n while (i >= 0) {\n const child = boxInstance.children[i--];\n const r = self.layoutContainer(\n page,\n child,\n boxContainer as HTMLElement,\n offsetX,\n offsetY,\n exclusions,\n pagePageFloatLayoutContext,\n );\n if (r.isPending()) {\n return r.thenAsync(() =>\n Task.newResult(!pagePageFloatLayoutContext.isInvalidated()),\n );\n } else if (pagePageFloatLayoutContext.isInvalidated()) {\n break;\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n processLinger(): void {\n const pageNumber = this.currentLayoutPosition.page;\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (let i = flowPosition.positions.length - 1; i >= 0; i--) {\n const pos = flowPosition.positions[i];\n if (\n pos.flowChunk.startPage >= 0 &&\n pos.flowChunk.startPage + pos.flowChunk.linger - 1 <= pageNumber\n ) {\n flowPosition.positions.splice(i, 1);\n }\n }\n }\n }\n\n initLingering(): void {\n const pageNumber = this.currentLayoutPosition.page;\n for (const flowName in this.currentLayoutPosition.flowPositions) {\n const flowPosition = this.currentLayoutPosition.flowPositions[flowName];\n for (let i = flowPosition.positions.length - 1; i >= 0; i--) {\n const pos = flowPosition.positions[i];\n if (\n pos.flowChunk.startPage < 0 &&\n pos.flowChunk.startOffset < this.lookupOffset\n ) {\n pos.flowChunk.startPage = pageNumber;\n }\n }\n }\n }\n\n noMorePrimaryFlows(cp: Vtree.LayoutPosition): boolean {\n for (const flowName in this.primaryFlows) {\n const flowPosition = cp.flowPositions[flowName];\n if (flowPosition && flowPosition.positions.length > 0) {\n return false;\n }\n }\n return true;\n }\n\n layoutNextPage(\n page: Vtree.Page,\n cp?: Vtree.LayoutPosition,\n ): Task.Result<Vtree.LayoutPosition> {\n const self = this;\n\n // TOC box is special page container, no pagination\n const isTocBox = page.container === page.bleedBox;\n\n self.pageBreaks = {};\n if (cp) {\n self.currentLayoutPosition = cp.clone();\n self.styler.replayFlowElementsFromOffset(cp.highestSeenOffset);\n } else {\n self.currentLayoutPosition = new Vtree.LayoutPosition();\n self.styler.replayFlowElementsFromOffset(-1);\n }\n if (this.lang) {\n page.bleedBox.setAttribute(\"lang\", this.lang);\n }\n cp = self.currentLayoutPosition;\n cp.page++;\n self.clearScope(self.style.pageScope);\n self.layoutPositionAtPageStart = cp.clone();\n\n // Resolve page size before page master selection.\n const cascadedPageStyle = isTocBox\n ? ({} as CssCascade.ElementStyle)\n : self.pageManager.getCascadedPageStyle();\n const pageMaster = self.selectPageMaster(cascadedPageStyle);\n if (!pageMaster) {\n // end of primary content\n return Task.newResult(null as Vtree.LayoutPosition);\n }\n let bleedBoxPaddingEdge = 0;\n if (!isTocBox) {\n page.setAutoPageWidth(\n pageMaster.pageBox.specified[\"width\"].value === Css.fullWidth,\n );\n page.setAutoPageHeight(\n pageMaster.pageBox.specified[\"height\"].value === Css.fullHeight,\n );\n self.counterStore.setCurrentPage(page);\n self.counterStore.updatePageCounters(cascadedPageStyle, self);\n\n // setup bleed area and crop marks\n const evaluatedPageSizeAndBleed = CssPage.evaluatePageSizeAndBleed(\n CssPage.resolvePageSizeAndBleed(cascadedPageStyle as any),\n this,\n );\n self.setPageSizeAndBleed(evaluatedPageSizeAndBleed, page);\n CssPage.addPrinterMarks(\n cascadedPageStyle,\n evaluatedPageSizeAndBleed,\n page,\n this,\n );\n bleedBoxPaddingEdge =\n evaluatedPageSizeAndBleed.bleedOffset + evaluatedPageSizeAndBleed.bleed;\n }\n\n const writingMode =\n (!isTocBox && pageMaster.getProp(self, \"writing-mode\")) ||\n Css.ident.horizontal_tb;\n\n this.pageVertical = writingMode != Css.ident.horizontal_tb;\n\n const direction = pageMaster.getProp(self, \"direction\") || Css.ident.ltr;\n const pageFloatLayoutContext = new PageFloats.PageFloatLayoutContext(\n self.rootPageFloatLayoutContext,\n PageFloats.FloatReference.PAGE,\n null,\n null,\n null,\n writingMode,\n direction,\n );\n const frame: Task.Frame<Vtree.LayoutPosition> = Task.newFrame(\n \"layoutNextPage\",\n );\n frame\n .loopWithFrame((loopFrame) => {\n // self.layoutContainer(page, pageMaster, page.bleedBox, bleedBoxPaddingEdge, bleedBoxPaddingEdge+1, // Compensate 'top: -1px' on page master\n self\n .layoutContainer(\n page,\n pageMaster,\n page.bleedBox,\n bleedBoxPaddingEdge,\n bleedBoxPaddingEdge,\n [],\n pageFloatLayoutContext,\n )\n .then(() => {\n if (!pageFloatLayoutContext.isInvalidated()) {\n pageFloatLayoutContext.finish();\n }\n if (pageFloatLayoutContext.isInvalidated()) {\n self.currentLayoutPosition = self.layoutPositionAtPageStart.clone();\n pageFloatLayoutContext.validate();\n loopFrame.continueLoop();\n } else {\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n pageMaster.adjustPageLayout(self, page, self.clientLayout);\n if (!isTocBox) {\n const isLeftPage = new Exprs.Named(\n pageMaster.pageBox.scope,\n \"left-page\",\n );\n page.side = isLeftPage.evaluate(self)\n ? Constants.PageSide.LEFT\n : Constants.PageSide.RIGHT;\n self.processLinger();\n cp = self.currentLayoutPosition;\n Object.keys(cp.flowPositions).forEach((flowName) => {\n const flowPosition = cp.flowPositions[flowName];\n const breakAfter = flowPosition.breakAfter;\n if (\n breakAfter &&\n (breakAfter === \"page\" || !self.matchPageSide(breakAfter))\n ) {\n flowPosition.breakAfter = null;\n }\n });\n }\n self.currentLayoutPosition = self.layoutPositionAtPageStart = null;\n cp.highestSeenOffset = self.styler.getReachedOffset();\n const triggers = self.style.store.getTriggersForDoc(self.xmldoc);\n page.finish(triggers, self.clientLayout);\n if (self.noMorePrimaryFlows(cp)) {\n cp = null;\n }\n frame.finish(cp);\n });\n return frame.result();\n }\n\n /**\n * Set actual page width, height and bleed from style specified in page\n * context.\n */\n private setPageSizeAndBleed(\n evaluatedPageSizeAndBleed: CssPage.EvaluatedPageSizeAndBleed,\n page: Vtree.Page,\n ) {\n this.actualPageWidth = evaluatedPageSizeAndBleed.pageWidth;\n this.actualPageHeight = evaluatedPageSizeAndBleed.pageHeight;\n this.pageSheetWidth =\n evaluatedPageSizeAndBleed.pageWidth +\n evaluatedPageSizeAndBleed.cropOffset * 2;\n this.pageSheetHeight =\n evaluatedPageSizeAndBleed.pageHeight +\n evaluatedPageSizeAndBleed.cropOffset * 2;\n page.container.style.width = `${this.pageSheetWidth}px`;\n page.container.style.height = `${this.pageSheetHeight}px`;\n page.bleedBox.style.left = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.right = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.top = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.bottom = `${evaluatedPageSizeAndBleed.bleedOffset}px`;\n page.bleedBox.style.padding = `${evaluatedPageSizeAndBleed.bleed}px`;\n\n // Shift 1px to workaround Chrome printing bug (Canceled because of another Chrome problem)\n // page.bleedBox.style.paddingTop = `${evaluatedPageSizeAndBleed.bleed+1}px`;\n\n // Shift 0.01px to workaround Firefox printing problem\n // (This small value (< 1/64 px) has no effect to Chrome)\n page.bleedBox.style.paddingTop = `${evaluatedPageSizeAndBleed.bleed +\n 0.01}px`;\n }\n}\n\nexport class BaseParserHandler extends CssCascade.CascadeParserHandler {\n insideRegion: boolean = false;\n\n constructor(\n public masterHandler: StyleParserHandler,\n condition: Exprs.Val,\n parent: BaseParserHandler,\n regionId: string | null,\n ) {\n super(\n masterHandler.rootScope,\n masterHandler,\n condition,\n parent,\n regionId,\n masterHandler.validatorSet,\n !parent,\n );\n }\n\n /**\n * @override\n */\n startPageTemplateRule(): void {}\n\n /**\n * @override\n */\n startPageMasterRule(\n name: string | null,\n pseudoName: string | null,\n classes: string[],\n ): void {\n const pageMaster = new PageMaster.PageMaster(\n this.masterHandler.pageScope,\n name,\n pseudoName,\n classes,\n this.masterHandler.rootBox,\n this.condition,\n this.owner.getBaseSpecificity(),\n );\n this.masterHandler.pushHandler(\n new PageMaster.PageMasterParserHandler(\n pageMaster.scope,\n this.masterHandler,\n pageMaster,\n this.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startWhenRule(expr: Css.Expr): void {\n let condition = expr.expr;\n if (this.condition != null) {\n condition = Exprs.and(this.scope, this.condition, condition);\n }\n this.masterHandler.pushHandler(\n new BaseParserHandler(this.masterHandler, condition, this, this.regionId),\n );\n }\n\n /**\n * @override\n */\n startDefineRule(): void {\n this.masterHandler.pushHandler(\n new CssCascade.DefineParserHandler(this.scope, this.owner),\n );\n }\n\n /**\n * @override\n */\n startFontFaceRule(): void {\n const properties = {} as CssCascade.ElementStyle;\n this.masterHandler.fontFaces.push({\n properties,\n condition: this.condition,\n });\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n properties,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startFlowRule(flowName: string): void {\n let style = this.masterHandler.flowProps[flowName];\n if (!style) {\n style = {} as CssCascade.ElementStyle;\n this.masterHandler.flowProps[flowName] = style;\n }\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n style,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startViewportRule(): void {\n const viewportProps = {} as CssCascade.ElementStyle;\n this.masterHandler.viewportProps.push(viewportProps);\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n this.condition,\n viewportProps,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startFootnoteRule(pseudoelem: string | null): void {\n let style = this.masterHandler.footnoteProps;\n if (pseudoelem) {\n const pseudos = CssCascade.getMutableStyleMap(style, \"_pseudos\");\n style = pseudos[pseudoelem];\n if (!style) {\n style = {} as CssCascade.ElementStyle;\n pseudos[pseudoelem] = style;\n }\n }\n this.masterHandler.pushHandler(\n new CssCascade.PropSetParserHandler(\n this.scope,\n this.owner,\n null,\n style,\n this.masterHandler.validatorSet,\n ),\n );\n }\n\n /**\n * @override\n */\n startRegionRule(): void {\n this.insideRegion = true;\n this.startSelectorRule();\n }\n\n /**\n * @override\n */\n startPageRule(): void {\n const pageHandler = new CssPage.PageParserHandler(\n this.masterHandler.pageScope,\n this.masterHandler,\n this,\n this.validatorSet,\n this.masterHandler.pageProps,\n );\n this.masterHandler.pushHandler(pageHandler);\n pageHandler.startPageRule();\n }\n\n /**\n * @override\n */\n startRuleBody(): void {\n CssCascade.CascadeParserHandler.prototype.startRuleBody.call(this);\n if (this.insideRegion) {\n this.insideRegion = false;\n const regionId = `R${this.masterHandler.regionCount++}`;\n this.special(\"region-id\", Css.getName(regionId));\n this.endRule();\n const regionHandler = new BaseParserHandler(\n this.masterHandler,\n this.condition,\n this,\n regionId,\n );\n this.masterHandler.pushHandler(regionHandler);\n regionHandler.startRuleBody();\n }\n }\n}\n\n// override, so we don't register an error\nexport function processViewportMeta(meta: Element): string {\n let content = meta.getAttribute(\"content\");\n if (!content) {\n return \"\";\n }\n const vals = {};\n let r: RegExpMatchArray;\n while (\n (r = content.match(\n /^,?\\s*([-A-Za-z_.][-A-Za-z_0-9.]*)\\s*=\\s*([-+A-Za-z_0-9.]*)\\s*/,\n )) != null\n ) {\n content = content.substr(r[0].length);\n vals[r[1]] = r[2];\n }\n const width = vals[\"width\"] - 0;\n const height = vals[\"height\"] - 0;\n if (width && height) {\n return `@-epubx-viewport{width:${width}px;height:${height}px;}`;\n }\n return \"\";\n}\n\nexport class StyleParserHandler extends CssParser.DispatchParserHandler {\n rootScope: Exprs.LexicalScope;\n pageScope: Exprs.LexicalScope;\n rootBox: PageMaster.RootPageBox;\n cascadeParserHandler: BaseParserHandler;\n regionCount: number = 0;\n fontFaces = [] as FontFace[];\n footnoteProps = {} as CssCascade.ElementStyle;\n flowProps = {} as { [key: string]: CssCascade.ElementStyle };\n viewportProps = [] as CssCascade.ElementStyle[];\n pageProps = {} as { [key: string]: CssCascade.ElementStyle };\n slave: BaseParserHandler;\n\n constructor(public readonly validatorSet: CssValidator.ValidatorSet) {\n super();\n this.rootScope = new Exprs.LexicalScope(null);\n this.pageScope = new Exprs.LexicalScope(this.rootScope);\n this.rootBox = new PageMaster.RootPageBox(this.rootScope);\n this.cascadeParserHandler = new BaseParserHandler(this, null, null, null);\n this.slave = this.cascadeParserHandler;\n }\n\n /**\n * @override\n */\n error(mnemonics: string, token: CssTokenizer.Token): void {\n Logging.logger.warn(\"CSS parser:\", mnemonics);\n }\n}\n\nexport type StyleSource = {\n url: string;\n text: string | null;\n flavor: CssParser.StylesheetFlavor;\n classes: string | null;\n media: string | null;\n};\n\nexport function parseOPSResource(\n response: Net.Response,\n store: XmlDoc.XMLDocStore,\n): Task.Result<XmlDoc.XMLDocHolder> {\n return (store as OPSDocStore).parseOPSResource(response);\n}\n\nexport class OPSDocStore extends Net.ResourceStore<XmlDoc.XMLDocHolder> {\n styleByKey: { [key: string]: Style } = {};\n styleFetcherByKey: { [key: string]: TaskUtil.Fetcher<Style> } = {};\n styleByDocURL: { [key: string]: Style } = {};\n triggersByDocURL: { [key: string]: Vtree.Trigger[] } = {};\n validatorSet: CssValidator.ValidatorSet = null;\n private styleSheets: StyleSource[] = [];\n private triggerSingleDocumentPreprocessing: boolean = false;\n\n constructor(\n public fontDeobfuscator:\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null,\n ) {\n super(parseOPSResource, Net.XMLHttpRequestResponseType.DOCUMENT);\n }\n\n init(\n authorStyleSheets: { url: string | null; text: string | null }[] | null,\n userStyleSheets: { url: string | null; text: string | null }[] | null,\n ): Task.Result<boolean> {\n this.setStyleSheets(authorStyleSheets as any, userStyleSheets as any);\n const userAgentXML = Base.resolveURL(\n \"user-agent.xml\",\n Base.resourceBaseURL,\n );\n const frame = Task.newFrame<boolean>(\"OPSDocStore.init\");\n this.validatorSet = CssValidator.baseValidatorSet();\n loadUABase().then(() => {\n this.load(userAgentXML).then(() => {\n this.triggerSingleDocumentPreprocessing = true;\n frame.finish(true);\n });\n });\n return frame.result();\n }\n\n getStyleForDoc(xmldoc: XmlDoc.XMLDocHolder): Style {\n return this.styleByDocURL[xmldoc.url];\n }\n\n getTriggersForDoc(xmldoc: XmlDoc.XMLDocHolder): Vtree.Trigger[] {\n return this.triggersByDocURL[xmldoc.url];\n }\n\n /**\n * Set author stylesheets and user stylesheets. Existing style sheets are\n * removed.\n */\n private setStyleSheets(\n authorStyleSheets: StyleSource[] | null,\n userStyleSheets: StyleSource[] | null,\n ) {\n this.clearStyleSheets();\n if (authorStyleSheets) {\n authorStyleSheets.forEach(this.addAuthorStyleSheet, this);\n }\n if (userStyleSheets) {\n userStyleSheets.forEach(this.addUserStyleSheet, this);\n }\n }\n\n private clearStyleSheets() {\n this.styleSheets.splice(0);\n }\n\n private addAuthorStyleSheet(stylesheet: StyleSource) {\n let url = stylesheet.url;\n if (url) {\n url = Base.resolveURL(Base.convertSpecialURL(url), Base.baseURL);\n }\n this.styleSheets.push({\n url,\n text: stylesheet.text,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n\n private addUserStyleSheet(stylesheet: StyleSource) {\n let url = stylesheet.url;\n if (url) {\n url = Base.resolveURL(Base.convertSpecialURL(url), Base.baseURL);\n }\n this.styleSheets.push({\n url,\n text: stylesheet.text,\n flavor: CssParser.StylesheetFlavor.USER,\n classes: null,\n media: null,\n });\n }\n\n parseOPSResource(response: Net.Response): Task.Result<XmlDoc.XMLDocHolder> {\n const frame: Task.Frame<XmlDoc.XMLDocHolder> = Task.newFrame(\n \"OPSDocStore.load\",\n );\n const self = this;\n const url = response.url;\n\n // Hack for TOCView.showTOC()\n const isTocBox = url.endsWith(\"?viv-toc-box\");\n\n XmlDoc.parseXMLResource(response, self).then(\n (xmldoc: XmlDoc.XMLDocHolder) => {\n if (!xmldoc) {\n frame.finish(null);\n return;\n }\n if (self.triggerSingleDocumentPreprocessing) {\n const hooks: Plugin.PreProcessSingleDocumentHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.PREPROCESS_SINGLE_DOCUMENT,\n );\n for (let i = 0; i < hooks.length; i++) {\n try {\n hooks[i](xmldoc.document);\n } catch (e) {\n Logging.logger.warn(\n \"Error during single document preprocessing:\",\n e,\n );\n }\n }\n }\n const triggers = [];\n const triggerList = xmldoc.document.getElementsByTagNameNS(\n Base.NS.epub,\n \"trigger\",\n );\n for (let i = 0; i < triggerList.length; i++) {\n const triggerElem = triggerList[i];\n const observer = triggerElem.getAttributeNS(Base.NS.EV, \"observer\");\n const event = triggerElem.getAttributeNS(Base.NS.EV, \"event\");\n const action = triggerElem.getAttribute(\"action\");\n const ref = triggerElem.getAttribute(\"ref\");\n if (observer && event && action && ref) {\n triggers.push({ observer, event, action, ref });\n }\n }\n self.triggersByDocURL[url] = triggers;\n const sources = [] as StyleSource[];\n const userAgentURL = Base.resolveURL(\n \"user-agent-page.css\",\n Base.resourceBaseURL,\n );\n sources.push({\n url: userAgentURL,\n text: UserAgentPageCss,\n flavor: CssParser.StylesheetFlavor.USER_AGENT,\n classes: null,\n media: null,\n });\n const head = xmldoc.head;\n if (!isTocBox && head) {\n for (let c: Node = head.firstChild; c; c = c.nextSibling) {\n if (c.nodeType != 1) {\n continue;\n }\n const child = c as Element;\n const ns = child.namespaceURI;\n const localName = child.localName;\n if (ns == Base.NS.XHTML) {\n if (localName == \"style\") {\n const classes = child.getAttribute(\"class\");\n const media = child.getAttribute(\"media\");\n const title = child.getAttribute(\"title\");\n sources.push({\n url,\n text: child.textContent,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: title ? classes : null,\n media,\n });\n } else if (localName == \"link\") {\n const rel = child.getAttribute(\"rel\");\n const classes = child.getAttribute(\"class\");\n const media = child.getAttribute(\"media\");\n if (\n rel == \"stylesheet\" ||\n (rel == \"alternate stylesheet\" && classes)\n ) {\n let src = child.getAttribute(\"href\");\n src = Base.resolveURL(src, url);\n const title = child.getAttribute(\"title\");\n sources.push({\n url: src,\n text: null,\n classes: title ? classes : null,\n media,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n });\n }\n } else if (\n localName == \"meta\" &&\n child.getAttribute(\"name\") == \"viewport\"\n ) {\n sources.push({\n url,\n text: processViewportMeta(child),\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n } else if (ns == Base.NS.FB2) {\n if (\n localName == \"stylesheet\" &&\n child.getAttribute(\"type\") == \"text/css\"\n ) {\n sources.push({\n url,\n text: child.textContent,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n classes: null,\n media: null,\n });\n }\n } else if (ns == Base.NS.SSE && localName === \"property\") {\n // look for stylesheet specification like:\n // <property><name>stylesheet</name><value>style.css</value></property>\n const name = child.getElementsByTagName(\"name\")[0];\n if (name && name.textContent === \"stylesheet\") {\n const value = child.getElementsByTagName(\"value\")[0];\n if (value) {\n const src = Base.resolveURL(value.textContent, url);\n sources.push({\n url: src,\n text: null,\n classes: null,\n media: null,\n flavor: CssParser.StylesheetFlavor.AUTHOR,\n });\n }\n }\n }\n }\n }\n if (!isTocBox) {\n for (let i = 0; i < self.styleSheets.length; i++) {\n sources.push(self.styleSheets[i]);\n }\n }\n let key = \"\";\n for (let i = 0; i < sources.length; i++) {\n key += sources[i].url;\n key += \"^\";\n if (sources[i].text) {\n key += sources[i].text;\n }\n key += \"^\";\n }\n let style = self.styleByKey[key];\n if (style) {\n self.styleByDocURL[url] = style;\n frame.finish(xmldoc);\n return;\n }\n let fetcher = self.styleFetcherByKey[key];\n if (!fetcher) {\n fetcher = new TaskUtil.Fetcher(() => {\n const innerFrame: Task.Frame<Style> = Task.newFrame(\n \"fetchStylesheet\",\n );\n let index = 0;\n const sph = new StyleParserHandler(self.validatorSet);\n innerFrame\n .loop(() => {\n if (index < sources.length) {\n const source = sources[index++];\n sph.startStylesheet(source.flavor);\n if (source.text !== null) {\n return CssParser.parseStylesheetFromText(\n source.text,\n sph,\n source.url,\n source.classes,\n source.media,\n ).thenReturn(true);\n } else {\n return CssParser.parseStylesheetFromURL(\n source.url,\n sph,\n source.classes,\n source.media,\n );\n }\n }\n return Task.newResult(false);\n })\n .then(() => {\n const cascade = sph.cascadeParserHandler.finish();\n style = new Style(\n self,\n sph.rootScope,\n sph.pageScope,\n cascade,\n sph.rootBox,\n sph.fontFaces,\n sph.footnoteProps,\n sph.flowProps,\n sph.viewportProps,\n sph.pageProps,\n );\n self.styleByKey[key] = style;\n delete self.styleFetcherByKey[key];\n innerFrame.finish(style);\n });\n return innerFrame.result();\n }, `FetchStylesheet ${url}`);\n self.styleFetcherByKey[key] = fetcher;\n fetcher.start();\n }\n fetcher.get().then((style) => {\n self.styleByDocURL[url] = style;\n frame.finish(xmldoc);\n });\n },\n );\n return frame.result();\n }\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2017 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Sha1 - Calculate SHA1 hash of the given content.\n */\nimport * as Base from \"./base\";\n\n/**\n * @return big-endian byte sequence\n */\nexport function encode32(n: number): string {\n return String.fromCharCode(\n (n >>> 24) & 255,\n (n >>> 16) & 255,\n (n >>> 8) & 255,\n n & 255,\n );\n}\n\n/**\n * @param bytes big-endian byte sequence\n */\nexport function decode32(bytes: string): number {\n // Important facts: \"\".charCodeAt(0) == NaN, NaN & 0xFF == 0\n const b0 = bytes.charCodeAt(0) & 255;\n const b1 = bytes.charCodeAt(1) & 255;\n const b2 = bytes.charCodeAt(2) & 255;\n const b3 = bytes.charCodeAt(3) & 255;\n return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return big-endian uint32 numbers representing sha1 hash\n */\nexport function bytesToSHA1Int32(bytes: string): number[] {\n const sb = new Base.StringBuffer();\n sb.append(bytes);\n let appendCount = (55 - bytes.length) & 63;\n sb.append(\"\\u0080\");\n while (appendCount > 0) {\n appendCount--;\n sb.append(\"\\x00\");\n }\n sb.append(\"\\x00\\x00\\x00\\x00\");\n sb.append(encode32(bytes.length * 8));\n bytes = sb.toString();\n const h = [1732584193, 4023233417, 2562383102, 271733878, 3285377520];\n const w =\n /** @type Array.<number> */\n [] as number[];\n let i: number;\n for (let bi = 0; bi < bytes.length; bi += 64) {\n for (i = 0; i < 16; i++) {\n w[i] = decode32(bytes.substr(bi + 4 * i, 4));\n }\n for (; i < 80; i++) {\n const q = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];\n w[i] = (q << 1) | (q >>> 31);\n }\n let a = h[0];\n let b = h[1];\n let c = h[2];\n let d = h[3];\n let e = h[4];\n let f: number;\n for (i = 0; i < 80; i++) {\n if (i < 20) {\n f = ((b & c) | (~b & d)) + 1518500249;\n } else if (i < 40) {\n f = (b ^ c ^ d) + 1859775393;\n } else if (i < 60) {\n f = ((b & c) | (b & d) | (c & d)) + 2400959708;\n } else {\n f = (b ^ c ^ d) + 3395469782;\n }\n f += ((a << 5) | (a >>> 27)) + e + w[i];\n e = d;\n d = c;\n c = (b << 30) | (b >>> 2);\n b = a;\n a = f;\n }\n h[0] = (h[0] + a) | 0;\n h[1] = (h[1] + b) | 0;\n h[2] = (h[2] + c) | 0;\n h[3] = (h[3] + d) | 0;\n h[4] = (h[4] + e) | 0;\n }\n return h;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return uint8 numbers representing sha1 hash\n */\nexport function bytesToSHA1Int8(bytes: string): number[] {\n const h = bytesToSHA1Int32(bytes);\n const res = [];\n for (const n of h) {\n res.push((n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255);\n }\n return res;\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return chars with codes 0 - 255 equal to SHA1 hash of the input\n */\nexport function bytesToSHA1Bytes(bytes: string): string {\n const h = bytesToSHA1Int32(bytes);\n const sb = new Base.StringBuffer();\n for (let i = 0; i < h.length; i++) {\n sb.append(encode32(h[i]));\n }\n return sb.toString();\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return hex-encoded SHA1 hash\n */\nexport function bytesToSHA1Hex(bytes: string): string {\n const sha1 = bytesToSHA1Bytes(bytes);\n const sb = new Base.StringBuffer();\n for (let i = 0; i < sha1.length; i++) {\n sb.append((sha1.charCodeAt(i) | 256).toString(16).substr(1));\n }\n return sb.toString();\n}\n\n/**\n * @param bytes chars with codes 0 - 255 that represent message byte values\n * @return base64-encoded SHA1 hash of the input\n */\nexport function bytesToSHA1Base64(bytes: string): string {\n const sha1 = bytesToSHA1Bytes(bytes);\n const sb = new Base.StringBuffer();\n Base.appendBase64(sb, sha1);\n return sb.toString();\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2019 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Toc - Table of Contents view.\n */\nimport * as Base from \"./base\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as OPS from \"./ops\";\nimport * as Task from \"./task\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\n\n// closed: 25B8\n// open: 25BE\n// empty: 25B9\nexport const bulletClosed = \"\\u25b8\";\n\nexport const bulletOpen = \"\\u25be\";\n\nexport const bulletEmpty = \"\\u25b9\";\n\nexport class TOCView implements Vgen.CustomRendererFactory {\n pref: Exprs.Preferences;\n page: Vtree.Page = null;\n instance: OPS.StyleInstance = null;\n\n constructor(\n public readonly store: OPS.OPSDocStore,\n public readonly url: string,\n public readonly lang: string | null,\n public readonly clientLayout: Vtree.ClientLayout,\n public readonly fontMapper: Font.Mapper,\n pref: Exprs.Preferences,\n public readonly rendererFactory: Vgen.CustomRendererFactory,\n public readonly fallbackMap: { [key: string]: string },\n public readonly documentURLTransformer: Base.DocumentURLTransformer,\n public readonly counterStore: Counters.CounterStore,\n ) {\n this.pref = Exprs.clonePreferences(pref);\n this.pref.spreadView = false; // No spred view for TOC box\n }\n\n setAutoHeight(elem: Element, depth: number): void {\n if (depth-- == 0) {\n return;\n }\n for (let c: Node = elem.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n const e = c as Element;\n if (Base.getCSSProperty(e, \"height\", \"auto\") != \"auto\") {\n Base.setCSSProperty(e, \"height\", \"auto\");\n this.setAutoHeight(e, depth);\n }\n if (Base.getCSSProperty(e, \"position\", \"static\") == \"absolute\") {\n Base.setCSSProperty(e, \"position\", \"relative\");\n this.setAutoHeight(e, depth);\n }\n }\n }\n }\n\n /**\n * @override\n */\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): Vgen.CustomRenderer {\n const renderer = this.rendererFactory.makeCustomRenderer(xmldoc);\n return (\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> => {\n const behavior = computedStyle[\"behavior\"];\n if (behavior) {\n switch (behavior.toString()) {\n case \"body-child\":\n if (\n srcElem.parentElement.getAttribute(\n \"data-vivliostyle-primary-entry\",\n )\n ) {\n if (\n !srcElem.querySelector(\n \"[role=doc-toc], [role=directory], nav li a, .toc, #toc\",\n )\n ) {\n // When the TOC element is a part of the primaty entry (X)HTML,\n // hide elements not containing TOC.\n computedStyle[\"display\"] = Css.ident.none;\n }\n }\n break;\n case \"toc-node-anchor\":\n computedStyle[\"color\"] = Css.ident.inherit;\n computedStyle[\"text-decoration\"] = Css.ident.none;\n break;\n case \"toc-node\":\n computedStyle[\"display\"] = Css.ident.block;\n computedStyle[\"margin\"] = Css.numericZero;\n computedStyle[\"padding\"] = Css.numericZero;\n computedStyle[\"padding-inline-start\"] = new Css.Numeric(1.25, \"em\");\n break;\n case \"toc-node-first-child\":\n computedStyle[\"display\"] = Css.ident.inline_block;\n computedStyle[\"margin\"] = new Css.Numeric(0.2, \"em\");\n computedStyle[\"vertical-align\"] = Css.ident.top;\n computedStyle[\"color\"] = Css.ident.inherit;\n computedStyle[\"text-decoration\"] = Css.ident.none;\n break;\n }\n }\n if (\n !behavior ||\n (behavior.toString() != \"toc-node\" &&\n behavior.toString() != \"toc-container\")\n ) {\n return renderer(srcElem, viewParent, computedStyle);\n }\n // Remove white-space textnode that becomes unwanted space between button and anchor element.\n const firstChild = srcElem.firstChild;\n if (\n firstChild &&\n firstChild.nodeType !== 1 &&\n firstChild.textContent.trim() === \"\"\n ) {\n // To avoid \"Inconsistent offset\" error, create a comment node with same white-space text.\n srcElem.replaceChild(\n srcElem.ownerDocument.createComment(firstChild.textContent),\n firstChild,\n );\n }\n const adaptParentClass = viewParent.getAttribute(\"data-adapt-class\");\n if (adaptParentClass == \"toc-node\") {\n const button = viewParent.firstChild as Element;\n if (button.textContent != bulletClosed) {\n button.textContent = bulletClosed;\n Base.setCSSProperty(button, \"cursor\", \"pointer\");\n button.addEventListener(\"click\", toggleNodeExpansion, false);\n\n button.setAttribute(\"role\", \"button\");\n button.setAttribute(\"aria-expanded\", \"false\");\n viewParent.setAttribute(\"aria-expanded\", \"false\");\n\n // Enable tab move to the button unless hidden.\n if ((viewParent as HTMLElement).style.height !== \"0px\") {\n (button as HTMLElement).tabIndex = 0;\n }\n }\n }\n const element = viewParent.ownerDocument.createElement(\"div\");\n element.setAttribute(\"data-adapt-process-children\", \"true\");\n if (behavior.toString() == \"toc-node\") {\n const button = viewParent.ownerDocument.createElement(\"div\");\n button.textContent = bulletEmpty;\n\n // TODO: define pseudo-element for the button?\n Base.setCSSProperty(button, \"margin\", \"0.2em 0 0 -1em\");\n Base.setCSSProperty(button, \"margin-inline-start\", \"-1em\");\n Base.setCSSProperty(button, \"margin-inline-end\", \"0\");\n Base.setCSSProperty(button, \"display\", \"inline-block\");\n Base.setCSSProperty(button, \"width\", \"1em\");\n Base.setCSSProperty(button, \"text-align\", \"center\");\n Base.setCSSProperty(button, \"vertical-align\", \"top\");\n Base.setCSSProperty(button, \"cursor\", \"default\");\n Base.setCSSProperty(button, \"font-family\", \"Menlo,sans-serif\");\n element.appendChild(button);\n Base.setCSSProperty(element, \"overflow\", \"hidden\");\n element.setAttribute(\"data-adapt-class\", \"toc-node\");\n element.setAttribute(\"role\", \"treeitem\");\n\n if (\n adaptParentClass == \"toc-node\" ||\n adaptParentClass == \"toc-container\"\n ) {\n Base.setCSSProperty(element, \"height\", \"0px\");\n\n // Prevent tab move to hidden anchor.\n const anchorElem = srcElem.firstElementChild;\n if (anchorElem && anchorElem.localName === \"a\") {\n (anchorElem as HTMLElement).tabIndex = -1;\n }\n } else {\n viewParent.setAttribute(\"role\", \"tree\");\n }\n } else {\n if (adaptParentClass == \"toc-node\") {\n element.setAttribute(\"data-adapt-class\", \"toc-container\");\n element.setAttribute(\"role\", \"group\");\n element.setAttribute(\"aria-hidden\", \"true\");\n }\n }\n return Task.newResult(element as Element);\n };\n }\n\n showTOC(\n elem: HTMLElement,\n viewport: Vgen.Viewport,\n width: number,\n height: number,\n fontSize: number,\n ): Task.Result<Vtree.Page> {\n if (this.page) {\n return Task.newResult(this.page as Vtree.Page);\n }\n const self = this;\n const frame: Task.Frame<Vtree.Page> = Task.newFrame(\"showTOC\");\n const page = new Vtree.Page(elem, elem);\n this.page = page;\n\n // The (X)HTML doc for the TOC box may be reused for the TOC page in the book,\n // but they need different styles. So, add \"?viv-toc-box\" to distinguish with TOC page URL.\n const tocBoxUrl = this.url + \"?viv-toc-box\";\n\n this.store.load(tocBoxUrl).then((xmldoc) => {\n // Mark if this doc is the primary entry page.\n const nonTocBoxDoc = this.store.resources[this.url];\n if (\n nonTocBoxDoc &&\n nonTocBoxDoc.body &&\n nonTocBoxDoc.body.getAttribute(\"data-vivliostyle-primary-entry\")\n ) {\n xmldoc.body.setAttribute(\"data-vivliostyle-primary-entry\", true);\n }\n\n const style = self.store.getStyleForDoc(xmldoc);\n const viewportSize = style.sizeViewport(width, 100000, fontSize);\n viewport = new Vgen.Viewport(\n viewport.window,\n viewportSize.fontSize,\n viewport.root,\n viewportSize.width,\n viewportSize.height,\n );\n const customRenderer = self.makeCustomRenderer(xmldoc);\n const instance = new OPS.StyleInstance(\n style,\n xmldoc,\n self.lang,\n viewport,\n self.clientLayout,\n self.fontMapper,\n customRenderer,\n self.fallbackMap,\n 0,\n self.documentURLTransformer,\n self.counterStore,\n );\n self.instance = instance;\n instance.pref = self.pref;\n instance.init().then(() => {\n instance.layoutNextPage(page, null).then(() => {\n Array.from(\n page.container.querySelectorAll(\n \"[data-vivliostyle-toc-box]>*>*>*>*>*[style*='display: none']\",\n ),\n ).forEach((bodyChildElem) => {\n bodyChildElem.setAttribute(\"aria-hidden\", \"true\");\n bodyChildElem.setAttribute(\"hidden\", \"hidden\");\n });\n self.setAutoHeight(elem, 2);\n frame.finish(page);\n });\n });\n });\n return frame.result();\n }\n\n hideTOC(): void {\n if (this.page) {\n this.page.container.style.visibility = \"hidden\";\n this.page.container.setAttribute(\"aria-hidden\", \"true\");\n }\n }\n\n isTOCVisible(): boolean {\n return !!this.page && this.page.container.style.visibility === \"visible\";\n }\n}\n\nexport function toggleNodeExpansion(evt: Event): void {\n const elem = evt.target as Element;\n const open = elem.textContent == bulletClosed;\n elem.textContent = open ? bulletOpen : bulletClosed;\n const tocNodeElem = elem.parentNode as Element;\n elem.setAttribute(\"aria-expanded\", open ? \"true\" : \"false\");\n tocNodeElem.setAttribute(\"aria-expanded\", open ? \"true\" : \"false\");\n let c: Node = tocNodeElem.firstChild;\n while (c) {\n if (c.nodeType === 1) {\n const ce = c as HTMLElement;\n const adaptClass = ce.getAttribute(\"data-adapt-class\");\n if (adaptClass === \"toc-container\") {\n ce.setAttribute(\"aria-hidden\", !open ? \"true\" : \"false\");\n if (ce.firstChild) {\n c = ce.firstChild;\n continue;\n }\n } else if (adaptClass === \"toc-node\") {\n ce.style.height = open ? \"auto\" : \"0px\";\n\n // Update enable/disable tab move to the button and anchor.\n if (ce.children.length >= 2) {\n (ce.children[1] as HTMLElement).tabIndex = open ? 0 : -1;\n }\n if (ce.children.length >= 3) {\n (ce.children[0] as HTMLElement).tabIndex = open ? 0 : -1;\n if (!open) {\n const elem1 = ce.children[0];\n if (elem1.textContent == bulletOpen) {\n elem1.textContent = bulletClosed;\n elem1.setAttribute(\"aria-expanded\", \"false\");\n ce.setAttribute(\"aria-expanded\", \"false\");\n c = ce.children[2];\n continue;\n }\n }\n }\n }\n }\n while (!c.nextSibling && c.parentNode !== tocNodeElem) {\n c = c.parentNode;\n }\n c = c.nextSibling;\n }\n evt.stopPropagation();\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview Epub - Deal with META-INF/ and .opf files in EPUB container.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as CFI from \"./cfi\";\nimport * as Constants from \"./constants\";\nimport * as Counters from \"./counters\";\nimport * as Css from \"./css\";\nimport * as CssCascade from \"./css-cascade\";\nimport * as CssParser from \"./css-parser\";\nimport * as CssTokenizer from \"./css-tokenizer\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Logging from \"./logging\";\nimport * as Net from \"./net\";\nimport * as OPS from \"./ops\";\nimport * as SHA1 from \"./sha1\";\nimport * as Task from \"./task\";\nimport * as Toc from \"./toc\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\nimport * as XmlDoc from \"./xml-doc\";\n\nexport type Position = {\n spineIndex: number;\n pageIndex: number;\n offsetInItem: number;\n};\n\nexport class EPUBDocStore extends OPS.OPSDocStore {\n plainXMLStore: XmlDoc.XMLDocStore;\n jsonStore: Net.JSONStore;\n opfByURL: { [key: string]: OPFDoc } = {};\n primaryOPFByEPubURL: { [key: string]: OPFDoc } = {};\n deobfuscators: { [key: string]: (p1: Blob) => Task.Result<Blob> } = {};\n documents: { [key: string]: Task.Result<XmlDoc.XMLDocHolder> } = {};\n\n constructor() {\n super(null);\n this.fontDeobfuscator = this.makeDeobfuscatorFactory();\n this.plainXMLStore = XmlDoc.newXMLDocStore();\n this.jsonStore = Net.newJSONStore();\n }\n\n makeDeobfuscatorFactory():\n | ((p1: string) => ((p1: Blob) => Task.Result<Blob>) | null)\n | null {\n const self = this;\n return (url: string): ((p1: Blob) => Task.Result<Blob>) | null => {\n return self.deobfuscators[url];\n };\n }\n\n loadAsPlainXML(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<XmlDoc.XMLDocHolder> {\n return this.plainXMLStore.load(\n url,\n opt_required,\n opt_message,\n ) as Task.Result<XmlDoc.XMLDocHolder>;\n }\n\n startLoadingAsPlainXML(url: string): void {\n this.plainXMLStore.fetch(url);\n }\n\n loadAsJSON(\n url: string,\n opt_required?: boolean,\n opt_message?: string,\n ): Task.Result<Base.JSON> {\n return this.jsonStore.load(url, opt_required, opt_message);\n }\n\n startLoadingAsJSON(url: string): void {\n this.jsonStore.fetch(url);\n }\n\n loadPubDoc(url: string, haveZipMetadata: boolean): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadPubDoc\");\n\n Net.ajax(url, null, \"HEAD\").then((response) => {\n if (response.status >= 400) {\n // This url can be the root of an unzipped EPUB.\n this.loadEPUBDoc(url, haveZipMetadata).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n Logging.logger.error(\n `Failed to fetch a source document from ${url} (${response.status}${\n response.statusText ? \" \" + response.statusText : \"\"\n })`,\n );\n frame.finish(null);\n });\n } else {\n if (\n !response.status &&\n !response.responseXML &&\n !response.responseText &&\n !response.responseBlob &&\n !response.contentType\n ) {\n // Empty response\n if (/\\/[^/.]+(?:[#?]|$)/.test(url)) {\n // Adding trailing \"/\" may solve the problem.\n url = url.replace(/([#?]|$)/, \"/$1\");\n } else {\n // Ignore empty response of HEAD request, it may become OK with GET request.\n }\n }\n if (\n response.contentType == \"application/oebps-package+xml\" ||\n /\\.opf(?:[#?]|$)/.test(url)\n ) {\n // EPUB OPF\n const [, pubURL, root] = url.match(/^((?:.*\\/)?)([^/]*)$/);\n this.loadOPF(pubURL, root, haveZipMetadata).thenFinish(frame);\n } else if (\n response.contentType == \"application/ld+json\" ||\n response.contentType == \"application/webpub+json\" ||\n response.contentType == \"application/audiobook+json\" ||\n response.contentType == \"application/json\" ||\n /\\.json(?:ld)?(?:[#?]|$)/.test(url)\n ) {\n // Web Publication Manifest\n this.loadAsJSON(url, true).then((manifestObj) => {\n if (!manifestObj) {\n Logging.logger.error(\n `Received an empty response for ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n frame.finish(null);\n return;\n }\n const opf = new OPFDoc(this, url);\n opf.initWithWebPubManifest(manifestObj).then(() => {\n frame.finish(opf);\n });\n });\n } else {\n // Web Publication primary entry (X)HTML\n this.loadWebPub(url).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n // This url can be the root of an unzipped EPUB.\n this.loadEPUBDoc(url, haveZipMetadata).then((opf) => {\n if (opf) {\n frame.finish(opf);\n return;\n }\n Logging.logger.error(`Failed to load ${url}.`);\n frame.finish(null);\n });\n });\n }\n }\n });\n return frame.result();\n }\n\n loadEPUBDoc(url: string, haveZipMetadata: boolean): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadEPUBDoc\");\n if (!url.endsWith(\"/\")) {\n url = url + \"/\";\n }\n if (haveZipMetadata) {\n this.startLoadingAsJSON(url + \"?r=list\");\n }\n this.startLoadingAsPlainXML(url + \"META-INF/encryption.xml\");\n const containerURL = url + \"META-INF/container.xml\";\n this.loadAsPlainXML(containerURL).then((containerXML) => {\n if (containerXML) {\n const roots = containerXML\n .doc()\n .child(\"container\")\n .child(\"rootfiles\")\n .child(\"rootfile\")\n .attribute(\"full-path\");\n for (const root of roots) {\n if (root) {\n this.loadOPF(url, root, haveZipMetadata).thenFinish(frame);\n return;\n }\n }\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n loadOPF(\n pubURL: string,\n root: string,\n haveZipMetadata: boolean,\n ): Task.Result<OPFDoc> {\n const self = this;\n const url = pubURL + root;\n let opf = self.opfByURL[url];\n if (opf) {\n return Task.newResult(opf);\n }\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadOPF\");\n self\n .loadAsPlainXML(url, true, `Failed to fetch EPUB OPF ${url}`)\n .then((opfXML) => {\n if (!opfXML) {\n Logging.logger.error(\n `Received an empty response for EPUB OPF ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n } else {\n self\n .loadAsPlainXML(`${pubURL}META-INF/encryption.xml`)\n .then((encXML) => {\n const zipMetadataResult = haveZipMetadata\n ? self.loadAsJSON(`${pubURL}?r=list`)\n : Task.newResult(null);\n zipMetadataResult.then((zipMetadata) => {\n opf = new OPFDoc(self, pubURL);\n opf\n .initWithXMLDoc(\n opfXML,\n encXML,\n zipMetadata,\n `${pubURL}?r=manifest`,\n )\n .then(() => {\n self.opfByURL[url] = opf;\n self.primaryOPFByEPubURL[pubURL] = opf;\n frame.finish(opf);\n });\n });\n });\n }\n });\n return frame.result();\n }\n\n loadWebPub(url: string): Task.Result<OPFDoc> {\n const frame: Task.Frame<OPFDoc> = Task.newFrame(\"loadWebPub\");\n\n // Load the primary entry page (X)HTML\n this.load(url).then((xmldoc) => {\n if (!xmldoc) {\n Logging.logger.error(\n `Received an empty response for ${url}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n } else if (\n xmldoc.document.querySelector(\n \"a[href='META-INF/'],a[href$='/META-INF/']\",\n )\n ) {\n // This is likely the directory listing of unzipped EPUB top directory\n frame.finish(null);\n } else {\n const doc = xmldoc.document;\n const opf = new OPFDoc(this, url);\n\n if (doc.body) {\n doc.body.setAttribute(\"data-vivliostyle-primary-entry\", true);\n }\n // Find manifest, W3C WebPublication or Readium Web Publication Manifest\n const manifestLink = doc.querySelector(\n \"link[rel='publication'],link[rel='manifest'][type='application/webpub+json']\",\n );\n if (manifestLink) {\n const href = manifestLink.getAttribute(\"href\");\n if (/^#/.test(href)) {\n const manifestObj = Base.stringToJSON(\n doc.getElementById(href.substr(1)).textContent,\n );\n opf.initWithWebPubManifest(manifestObj, doc).then(() => {\n frame.finish(opf);\n });\n } else {\n this.loadAsJSON(\n Base.resolveURL(manifestLink.getAttribute(\"href\"), url),\n ).then((manifestObj) => {\n opf.initWithWebPubManifest(manifestObj, doc).then(() => {\n frame.finish(opf);\n });\n });\n }\n } else {\n // No manifest\n opf.initWithWebPubManifest({}, doc).then(() => {\n if (opf.xhtmlToc && opf.xhtmlToc.src === xmldoc.url) {\n // xhtmlToc is the primari entry (X)HTML\n if (\n !doc.querySelector(\n \"[role=doc-toc], [role=directory], nav, .toc, #toc\",\n )\n ) {\n // TOC is not found in the primari entry (X)HTML\n opf.xhtmlToc = null;\n }\n }\n frame.finish(opf);\n });\n }\n }\n });\n return frame.result();\n }\n\n addDocument(url: string, doc: Document) {\n const frame = Task.newFrame<XmlDoc.XMLDocHolder>(\"EPUBDocStore.load\");\n const docURL = Base.stripFragment(url);\n const r = (this.documents[docURL] = this.parseOPSResource({\n status: 200,\n statusText: \"\",\n url: docURL,\n contentType: (doc as any).contentType,\n responseText: null,\n responseXML: doc,\n responseBlob: null,\n }));\n r.thenFinish(frame);\n return frame.result();\n }\n\n /**\n * @override\n */\n load(url: string): Task.Result<XmlDoc.XMLDocHolder> {\n const docURL = Base.stripFragment(url);\n let r = this.documents[docURL];\n if (r) {\n return r.isPending() ? r : Task.newResult(r.get());\n } else {\n const frame = Task.newFrame<XmlDoc.XMLDocHolder>(\"EPUBDocStore.load\");\n r = super.load(\n docURL,\n true,\n `Failed to fetch a source document from ${docURL}`,\n );\n r.then((xmldoc: XmlDoc.XMLDocHolder) => {\n if (!xmldoc) {\n if (docURL.startsWith(\"data:\")) {\n Logging.logger.error(`Failed to load ${docURL}. Invalid data.`);\n } else if (\n docURL.startsWith(\"http:\") &&\n Base.baseURL.startsWith(\"https:\")\n ) {\n Logging.logger.error(\n `Failed to load ${docURL}. Mixed Content (\"http:\" content on \"https:\" context) is not allowed.`,\n );\n } else {\n Logging.logger.error(\n `Received an empty response for ${docURL}. This may be caused by the server not allowing cross-origin resource sharing (CORS).`,\n );\n }\n } else {\n frame.finish(xmldoc);\n }\n });\n return frame.result();\n }\n }\n}\n\nexport type OPFItemParam = {\n url: string;\n index: number;\n startPage: number | null;\n skipPagesBefore: number | null;\n};\n\nexport class OPFItem {\n id: string | null = null;\n src: string = \"\";\n mediaType: string | null = null;\n title: string | null = null;\n itemRefElement: Element | null = null;\n spineIndex: number = -1;\n compressedSize: number = 0;\n compressed: boolean | null = null;\n epage: number = 0;\n epageCount: number = 0;\n startPage: number | null = null;\n skipPagesBefore: number | null = null;\n itemProperties: { [key: string]: boolean };\n\n constructor() {\n this.itemProperties = Base.emptyObj;\n }\n\n initWithElement(itemElem: Element, opfURL: string): void {\n this.id = itemElem.getAttribute(\"id\");\n this.src = Base.resolveURL(itemElem.getAttribute(\"href\"), opfURL);\n this.mediaType = itemElem.getAttribute(\"media-type\");\n const propStr = itemElem.getAttribute(\"properties\");\n if (propStr) {\n this.itemProperties = Base.arrayToSet(propStr.split(/\\s+/));\n }\n }\n\n initWithParam(param: OPFItemParam) {\n this.spineIndex = param.index;\n this.id = `item${param.index + 1}`;\n this.src = param.url;\n this.startPage = param.startPage;\n this.skipPagesBefore = param.skipPagesBefore;\n }\n}\n\nexport function getOPFItemId(item: OPFItem): string | null {\n return item.id;\n}\n\nexport function makeDeobfuscator(uid: string): (p1: Blob) => Task.Result<Blob> {\n // TODO: use UTF8 of uid\n const sha1Sum = SHA1.bytesToSHA1Int8(uid);\n return (blob) => {\n const frame = Task.newFrame(\"deobfuscator\") as Task.Frame<Blob>;\n let head: Blob;\n let tail: Blob;\n if (blob.slice) {\n head = blob.slice(0, 1040);\n tail = blob.slice(1040, blob.size);\n } else {\n head = blob[\"webkitSlice\"](0, 1040);\n tail = blob[\"webkitSlice\"](1040, blob.size - 1040);\n }\n Net.readBlob(head).then((buf) => {\n const dataView = new DataView(buf);\n for (let k = 0; k < dataView.byteLength; k++) {\n let b = dataView.getUint8(k);\n b ^= sha1Sum[k % 20];\n dataView.setUint8(k, b);\n }\n frame.finish(Net.makeBlob([dataView, tail]));\n });\n return frame.result();\n };\n}\n\nexport function makeObfuscationKey(uid: string): string {\n return `1040:${SHA1.bytesToSHA1Hex(uid)}`;\n}\n\nexport type RawMetaItem = {\n name: string;\n value: string;\n id: string | null;\n refines: string | null;\n scheme: string | null;\n lang: string | null;\n order: number;\n};\n\nexport const predefinedPrefixes = {\n dcterms: \"http://purl.org/dc/terms/\",\n marc: \"http://id.loc.gov/vocabulary/\",\n media: \"http://www.idpf.org/epub/vocab/overlays/#\",\n rendition: \"http://www.idpf.org/vocab/rendition/#\",\n onix: \"http://www.editeur.org/ONIX/book/codelists/current.html#\",\n xsd: \"http://www.w3.org/2001/XMLSchema#\",\n};\n\nexport const defaultIRI = \"http://idpf.org/epub/vocab/package/#\";\n\nexport const metaTerms = {\n language: `${predefinedPrefixes[\"dcterms\"]}language`,\n title: `${predefinedPrefixes[\"dcterms\"]}title`,\n creator: `${predefinedPrefixes[\"dcterms\"]}creator`,\n layout: `${predefinedPrefixes[\"rendition\"]}layout`,\n titleType: `${defaultIRI}title-type`,\n displaySeq: `${defaultIRI}display-seq`,\n alternateScript: `${defaultIRI}alternate-script`,\n};\n\nexport function getMetadataComparator(\n term: string,\n lang: string,\n): (p1: Base.JSON, p2: Base.JSON) => number {\n const empty = {};\n return (item1, item2) => {\n let m1: boolean;\n let m2: boolean;\n const r1 = item1[\"r\"] || empty;\n const r2 = item2[\"r\"] || empty;\n if (term == metaTerms.title) {\n m1 = r1[metaTerms.titleType] == \"main\";\n m2 = r2[metaTerms.titleType] == \"main\";\n if (m1 != m2) {\n return m1 ? -1 : 1;\n }\n }\n let i1 = parseInt(r1[metaTerms.displaySeq], 10);\n if (isNaN(i1)) {\n i1 = Number.MAX_VALUE;\n }\n let i2 = parseInt(r2[metaTerms.displaySeq], 10);\n if (isNaN(i2)) {\n i2 = Number.MAX_VALUE;\n }\n if (i1 != i2) {\n return i1 - i2;\n }\n if (term != metaTerms.language && lang) {\n m1 = (r1[metaTerms.language] || r1[metaTerms.alternateScript]) == lang;\n m2 = (r2[metaTerms.language] || r2[metaTerms.alternateScript]) == lang;\n if (m1 != m2) {\n return m1 ? -1 : 1;\n }\n }\n return item1[\"o\"] - item2[\"o\"];\n };\n}\n\nexport function readMetadata(\n mroot: XmlDoc.NodeList,\n prefixes: string | null,\n): Base.JSON {\n // Parse prefix map (if any)\n let prefixMap;\n if (!prefixes) {\n prefixMap = predefinedPrefixes;\n } else {\n prefixMap = {};\n for (const pn in predefinedPrefixes) {\n prefixMap[pn] = predefinedPrefixes[pn];\n }\n let r: RegExpMatchArray;\n\n // This code permits any non-ASCII characters in the name to avoid bloating\n // the pattern.\n while (\n (r = prefixes.match(\n /^\\s*([A-Z_a-z\\u007F-\\uFFFF][-.A-Z_a-z0-9\\u007F-\\uFFFF]*):\\s*(\\S+)/,\n )) != null\n ) {\n prefixes = prefixes.substr(r[0].length);\n prefixMap[r[1]] = r[2];\n }\n }\n const resolveProperty = (val: string | null): string | null => {\n if (val) {\n const r = val.match(/^\\s*(([^:]*):)?(\\S+)\\s*$/);\n if (r) {\n const iri = r[2] ? prefixMap[r[2]] : defaultIRI;\n if (iri) {\n return iri + r[3];\n }\n }\n }\n return null;\n };\n let order = 1;\n\n // List of metadata items.\n const rawItems = mroot.childElements().forEachNonNull((node: Element) => {\n if (node.localName == \"meta\") {\n const p = resolveProperty((node as Element).getAttribute(\"property\"));\n if (p) {\n return {\n name: p,\n value: node.textContent,\n id: (node as Element).getAttribute(\"id\"),\n order: order++,\n refines: (node as Element).getAttribute(\"refines\"),\n lang: null,\n scheme: resolveProperty((node as Element).getAttribute(\"scheme\")),\n };\n }\n } else if (node.namespaceURI == Base.NS.DC) {\n return {\n name: predefinedPrefixes[\"dcterms\"] + node.localName,\n order: order++,\n lang: (node as Element).getAttribute(\"xml:lang\"),\n value: node.textContent,\n id: (node as Element).getAttribute(\"id\"),\n refines: null,\n scheme: null,\n };\n }\n return null;\n });\n\n // Items grouped by their target id.\n const rawItemsByTarget = Base.multiIndexArray(\n rawItems,\n (rawItem) => rawItem.refines,\n );\n const makeMetadata = (map: {\n [key: string]: any[];\n }): { [key: string]: any[] } =>\n Base.mapObj(map, (rawItemArr, itemName) =>\n rawItemArr.map((rawItem) => {\n const entry = { v: rawItem.value, o: rawItem.order };\n if (rawItem.schema) {\n entry[\"s\"] = rawItem.scheme;\n }\n if (rawItem.id || rawItem.lang) {\n let refs = rawItemsByTarget[rawItem.id];\n if (refs || rawItem.lang) {\n if (rawItem.lang) {\n // Special handling for xml:lang\n const langItem = {\n name: metaTerms.language,\n value: rawItem.lang,\n lang: null,\n id: null,\n refines: rawItem.id,\n scheme: null,\n order: rawItem.order,\n };\n if (refs) {\n refs.push(langItem);\n } else {\n refs = [langItem];\n }\n }\n const entryMap = Base.multiIndexArray(\n refs,\n (rawItem) => rawItem.name,\n );\n entry[\"r\"] = makeMetadata(entryMap);\n }\n }\n return entry;\n }),\n );\n const metadata = makeMetadata(\n Base.multiIndexArray(rawItems, (rawItem) =>\n rawItem.refines ? null : rawItem.name,\n ),\n );\n let lang: string | null = null;\n if (metadata[metaTerms.language]) {\n lang = metadata[metaTerms.language][0][\"v\"];\n }\n const sortMetadata = (metadata: { [key: string]: any[] }) => {\n for (const term in metadata) {\n const arr = metadata[term];\n arr.sort(getMetadataComparator(term, lang));\n for (let i = 0; i < arr.length; i++) {\n const r = arr[i][\"r\"];\n if (r) {\n sortMetadata(r);\n }\n }\n }\n };\n sortMetadata(metadata);\n return metadata;\n}\n\nexport function getMathJaxHub(): object {\n const math = window[\"MathJax\"];\n if (math) {\n return math[\"Hub\"];\n }\n return null;\n}\n\nexport function checkMathJax(): void {\n if (getMathJaxHub()) {\n CssCascade.supportedNamespaces[Base.NS.MATHML] = true;\n }\n}\n\nexport const supportedMediaTypes = {\n \"application/xhtml+xml\": true,\n \"image/jpeg\": true,\n \"image/png\": true,\n \"image/svg+xml\": true,\n \"image/gif\": true,\n \"audio/mp3\": true,\n};\n\nexport const transformedIdPrefix = \"viv-id-\";\n\nexport class OPFDoc {\n opfXML: XmlDoc.XMLDocHolder = null;\n encXML: XmlDoc.XMLDocHolder = null;\n items: OPFItem[] = null;\n spine: OPFItem[] = null;\n itemMap: { [key: string]: OPFItem } = null;\n itemMapByPath: { [key: string]: OPFItem } = null;\n uid: string | null = null;\n bindings: { [key: string]: string } = {};\n lang: string | null = null;\n epageCount: number = 0;\n prePaginated: boolean = false;\n epageIsRenderedPage: boolean = true;\n epageCountCallback: (p1: number) => void | null = null;\n metadata: Base.JSON = {};\n ncxToc: OPFItem = null;\n xhtmlToc: OPFItem = null;\n cover: OPFItem = null;\n fallbackMap: { [key: string]: string } = {};\n pageProgression: Constants.PageProgression | null = null;\n documentURLTransformer: Base.DocumentURLTransformer;\n\n constructor(\n public readonly store: EPUBDocStore,\n public readonly pubURL: string,\n ) {\n this.documentURLTransformer = this.createDocumentURLTransformer();\n checkMathJax();\n }\n\n // FIXME: TS4055\n createDocumentURLTransformer(): Base.DocumentURLTransformer {\n const self = this;\n class OPFDocumentURLTransformer implements Base.DocumentURLTransformer {\n /**\n * @override\n */\n transformFragment(fragment: string, baseURL: string): string {\n const url = baseURL + (fragment ? `#${fragment}` : \"\");\n return transformedIdPrefix + Base.escapeNameStrToHex(url, \":\");\n }\n\n /**\n * @override\n */\n transformURL(url: string, baseURL: string): string {\n const r = url.match(/^([^#]*)#?(.*)$/);\n if (r) {\n const path = r[1] || baseURL;\n const fragment = r[2];\n if (path) {\n if (self.items.some((item) => item.src === path)) {\n return `#${this.transformFragment(fragment, path)}`;\n }\n }\n }\n return url;\n }\n\n /**\n * @override\n */\n restoreURL(encoded: string): string[] {\n if (encoded.charAt(0) === \"#\") {\n encoded = encoded.substring(1);\n }\n if (encoded.indexOf(transformedIdPrefix) === 0) {\n encoded = encoded.substring(transformedIdPrefix.length);\n }\n const decoded = Base.unescapeStrFromHex(encoded, \":\");\n const r = decoded.match(/^([^#]*)#?(.*)$/);\n return r ? [r[1], r[2]] : [];\n }\n }\n return new OPFDocumentURLTransformer();\n }\n\n /**\n * Metadata is organized in the following way: fully-expanded property names\n * (with IRI prefixes prepended) point to an array of values. Array contains\n * at least one element. First element is primary and should be used by\n * default. Element values are objects have the following keys:\n * - \"v\" - item value as string,\n * - \"s\" - scheme,\n * - \"o\" - index in the order of appearing in the source,\n * - \"r\" - refinement submetadata (organized just like the top-level\n * metadata).\n */\n getMetadata(): Base.JSON {\n return this.metadata;\n }\n\n getPathFromURL(url: string): string | null {\n if (url.startsWith(\"data:\")) {\n return url === this.pubURL ? \"\" : url;\n }\n if (this.pubURL) {\n let epubBaseURL = Base.resolveURL(\"\", this.pubURL);\n if (url === epubBaseURL || url + \"/\" === epubBaseURL) {\n return \"\";\n }\n if (epubBaseURL.charAt(epubBaseURL.length - 1) != \"/\") {\n epubBaseURL += \"/\";\n }\n return url.substr(0, epubBaseURL.length) == epubBaseURL\n ? decodeURI(url.substr(epubBaseURL.length))\n : null;\n } else {\n return url;\n }\n }\n\n initWithXMLDoc(\n opfXML: XmlDoc.XMLDocHolder,\n encXML: XmlDoc.XMLDocHolder,\n zipMetadata: Base.JSON,\n manifestURL: string,\n ): Task.Result<any> {\n const self = this;\n this.opfXML = opfXML;\n this.encXML = encXML;\n const pkg = opfXML.doc().child(\"package\");\n const uidref = pkg.attribute(\"unique-identifier\")[0];\n if (uidref) {\n const uidElem = opfXML.getElement(`${opfXML.url}#${uidref}`);\n if (uidElem) {\n this.uid = uidElem.textContent.replace(/[ \\n\\r\\t]/g, \"\");\n }\n }\n const srcToFallbackId = {};\n this.items = pkg\n .child(\"manifest\")\n .child(\"item\")\n .asArray()\n .map((node) => {\n const item = new OPFItem();\n const elem = node as Element;\n item.initWithElement(elem, opfXML.url);\n const fallback = elem.getAttribute(\"fallback\");\n if (fallback && !supportedMediaTypes[item.mediaType]) {\n srcToFallbackId[item.src] = fallback;\n }\n if (!self.xhtmlToc && item.itemProperties[\"nav\"]) {\n self.xhtmlToc = item;\n }\n if (!self.cover && item.itemProperties[\"cover-image\"]) {\n self.cover = item;\n }\n return item;\n });\n this.itemMap = Base.indexArray(\n this.items,\n getOPFItemId as (p1: OPFItem) => string | null,\n );\n this.itemMapByPath = Base.indexArray(this.items, (item) =>\n self.getPathFromURL(item.src),\n );\n for (const src in srcToFallbackId) {\n let fallbackSrc = src;\n while (true) {\n const item = this.itemMap[srcToFallbackId[fallbackSrc]];\n if (!item) {\n break;\n }\n if (supportedMediaTypes[item.mediaType]) {\n this.fallbackMap[src] = item.src;\n break;\n }\n fallbackSrc = item.src;\n }\n }\n this.spine = pkg\n .child(\"spine\")\n .child(\"itemref\")\n .asArray()\n .map((node, index) => {\n const elem = node as Element;\n const id = elem.getAttribute(\"idref\");\n const item = self.itemMap[id as string];\n if (item) {\n item.itemRefElement = elem;\n item.spineIndex = index;\n }\n return item;\n });\n const tocAttr = pkg.child(\"spine\").attribute(\"toc\")[0];\n if (tocAttr) {\n this.ncxToc = this.itemMap[tocAttr];\n }\n const pageProgressionAttr = pkg\n .child(\"spine\")\n .attribute(\"page-progression-direction\")[0];\n if (pageProgressionAttr) {\n this.pageProgression = Constants.pageProgressionOf(pageProgressionAttr);\n }\n const idpfObfURLs = !encXML\n ? []\n : encXML\n .doc()\n .child(\"encryption\")\n .child(\"EncryptedData\")\n .predicate(\n XmlDoc.predicate.withChild(\n \"EncryptionMethod\",\n XmlDoc.predicate.withAttribute(\n \"Algorithm\",\n \"http://www.idpf.org/2008/embedding\",\n ),\n ),\n )\n .child(\"CipherData\")\n .child(\"CipherReference\")\n .attribute(\"URI\");\n const mediaTypeElems = pkg\n .child(\"bindings\")\n .child(\"mediaType\")\n .asArray() as Element[];\n for (let i = 0; i < mediaTypeElems.length; i++) {\n const handlerId = mediaTypeElems[i].getAttribute(\"handler\");\n const mediaType = mediaTypeElems[i].getAttribute(\"media-type\");\n if (mediaType && handlerId && this.itemMap[handlerId]) {\n this.bindings[mediaType] = this.itemMap[handlerId].src;\n }\n }\n this.metadata = readMetadata(\n pkg.child(\"metadata\"),\n pkg.attribute(\"prefix\")[0],\n );\n if (this.metadata[metaTerms.language]) {\n this.lang = this.metadata[metaTerms.language][0][\"v\"];\n }\n if (this.metadata[metaTerms.layout]) {\n this.prePaginated =\n this.metadata[metaTerms.layout][0][\"v\"] === \"pre-paginated\";\n }\n\n if (!zipMetadata) {\n if (idpfObfURLs.length > 0 && this.uid) {\n // Have to deobfuscate in JavaScript\n const deobfuscator = makeDeobfuscator(this.uid);\n for (let i = 0; i < idpfObfURLs.length; i++) {\n this.store.deobfuscators[this.pubURL + idpfObfURLs[i]] = deobfuscator;\n }\n }\n if (this.prePaginated) {\n this.assignAutoPages();\n }\n return Task.newResult(true);\n }\n const manifestText = new Base.StringBuffer();\n const obfuscations = {};\n if (idpfObfURLs.length > 0 && this.uid) {\n // Deobfuscate in the server.\n const obfuscationKey = makeObfuscationKey(this.uid);\n for (let i = 0; i < idpfObfURLs.length; i++) {\n obfuscations[idpfObfURLs[i]] = obfuscationKey;\n }\n }\n for (let i = 0; i < zipMetadata.length; i++) {\n const entry = zipMetadata[i];\n const encodedPath = entry[\"n\"];\n if (encodedPath) {\n const path = decodeURI(encodedPath);\n const item = this.itemMapByPath[path];\n let mediaType: string | null = null;\n if (item) {\n item.compressed = entry[\"m\"] != 0;\n item.compressedSize = entry[\"c\"];\n if (item.mediaType) {\n mediaType = item.mediaType.replace(/\\s+/g, \"\");\n }\n }\n const obfuscation = obfuscations[path];\n if (mediaType || obfuscation) {\n manifestText.append(encodedPath);\n manifestText.append(\" \");\n manifestText.append(mediaType || \"application/octet-stream\");\n if (obfuscation) {\n manifestText.append(\" \");\n manifestText.append(obfuscation);\n }\n manifestText.append(\"\\n\");\n }\n }\n }\n self.assignAutoPages();\n return Net.ajax(\n manifestURL,\n Net.XMLHttpRequestResponseType.DEFAULT,\n \"POST\",\n manifestText.toString(),\n \"text/plain\",\n );\n }\n\n assignAutoPages(): void {\n let epage = 0;\n for (const item of this.spine) {\n const epageCount = this.prePaginated\n ? 1\n : Math.ceil(item.compressedSize / 1024);\n item.epage = epage;\n item.epageCount = epageCount;\n epage += epageCount;\n }\n this.epageCount = epage;\n\n if (this.epageCountCallback) {\n this.epageCountCallback(this.epageCount);\n }\n }\n\n setEPageCountMode(epageIsRenderedPage: boolean) {\n this.epageIsRenderedPage = epageIsRenderedPage || this.prePaginated;\n }\n\n countEPages(\n epageCountCallback: ((p1: number) => void) | null,\n ): Task.Result<boolean> {\n this.epageCountCallback = epageCountCallback;\n\n if (this.epageIsRenderedPage) {\n if (this.prePaginated && this.epageCount == 0) {\n this.assignAutoPages();\n }\n return Task.newResult(true);\n }\n\n let epage = 0;\n let i = 0;\n const frame: Task.Frame<boolean> = Task.newFrame(\"countEPages\");\n frame\n .loopWithFrame((loopFrame) => {\n if (i === this.spine.length) {\n loopFrame.breakLoop();\n return;\n }\n const item = this.spine[i++];\n item.epage = epage;\n this.store.load(item.src).then((xmldoc) => {\n // According to the old comment,\n // \"Estimate that offset=2700 roughly corresponds to 1024 bytes of compressed size.\"\n // However, it should depend on the language.\n // Further adjustment needed.\n\n //let offsetPerEPage = 2700;\n let offsetPerEPage = 1800;\n const lang = xmldoc.lang || this.lang;\n if (lang && lang.match(/^(ja|ko|zh)/)) {\n offsetPerEPage /= 3;\n }\n item.epageCount = Math.ceil(xmldoc.getTotalOffset() / offsetPerEPage);\n epage += item.epageCount;\n this.epageCount = epage;\n if (this.epageCountCallback) {\n this.epageCountCallback(this.epageCount);\n }\n loopFrame.continueLoop();\n });\n })\n .thenFinish(frame);\n return frame.result();\n }\n\n /**\n * Creates a fake OPF \"document\" that contains OPS chapters.\n */\n initWithChapters(params: OPFItemParam[], doc?: Document | null) {\n this.itemMap = {};\n this.itemMapByPath = {};\n this.items = [];\n this.spine = this.items;\n\n // create a minimum fake OPF XML for navigation with EPUB CFI\n const opfXML = (this.opfXML = new XmlDoc.XMLDocHolder(\n null,\n \"\",\n new DOMParser().parseFromString(\"<spine></spine>\", \"text/xml\"),\n ));\n params.forEach((param) => {\n const item = new OPFItem();\n item.initWithParam(param);\n Asserts.assert(item.id);\n const itemref = opfXML.document.createElement(\"itemref\");\n itemref.setAttribute(\"idref\", item.id);\n opfXML.root.appendChild(itemref);\n item.itemRefElement = itemref;\n this.itemMap[item.id] = item;\n let path = this.getPathFromURL(param.url);\n if (path == null) {\n path = param.url;\n }\n this.itemMapByPath[path] = item;\n this.items.push(item);\n });\n if (doc) {\n return this.store.addDocument(params[0].url, doc);\n } else {\n return Task.newResult(null);\n }\n }\n\n initWithWebPubManifest(\n manifestObj: Base.JSON,\n doc?: Document,\n ): Task.Result<boolean> {\n if (manifestObj[\"readingProgression\"]) {\n this.pageProgression = manifestObj[\"readingProgression\"];\n }\n if (this.metadata === undefined) {\n this.metadata = {};\n }\n const title =\n (doc && doc.title) ||\n manifestObj[\"name\"] ||\n (manifestObj[\"metadata\"] && manifestObj[\"metadata\"][\"title\"]);\n if (title) {\n this.metadata[metaTerms.title] = [{ v: title }];\n }\n // TODO: other metadata...\n\n const primaryEntryPath = this.getPathFromURL(this.pubURL);\n if (!manifestObj[\"readingOrder\"] && doc && primaryEntryPath !== null) {\n manifestObj[\"readingOrder\"] = [encodeURI(primaryEntryPath)];\n\n // Find TOC in the primary entry (X)HTML\n const selector =\n \"[role=doc-toc] a[href],\" +\n \"[role=directory] a[href],\" +\n \"nav li a[href],\" +\n \".toc a[href],\" +\n \"#toc a[href]\";\n Array.from(doc.querySelectorAll(selector)).forEach((anchorElem) => {\n const hrefNoFragment = Base.stripFragment(\n Base.resolveURL(anchorElem.getAttribute(\"href\"), this.pubURL),\n );\n const path = this.getPathFromURL(hrefNoFragment);\n const url = path !== null ? encodeURI(path) : hrefNoFragment;\n if (manifestObj[\"readingOrder\"].indexOf(url) == -1) {\n manifestObj[\"readingOrder\"].push(url);\n }\n });\n }\n\n const params = [];\n let itemCount = 0;\n let tocFound = -1;\n [manifestObj[\"readingOrder\"], manifestObj[\"resources\"]].forEach(\n (readingOrderOrResources) => {\n if (readingOrderOrResources instanceof Array) {\n readingOrderOrResources.forEach((itemObj) => {\n const isInReadingOrder = manifestObj[\"readingOrder\"].includes(\n itemObj,\n );\n const url =\n typeof itemObj === \"string\"\n ? itemObj\n : itemObj.url || itemObj.href;\n const encodingFormat =\n typeof itemObj === \"string\"\n ? \"\"\n : itemObj.encodingFormat ||\n (itemObj.href && itemObj.type) ||\n \"\";\n if (\n isInReadingOrder ||\n encodingFormat === \"text/html\" ||\n encodingFormat === \"application/xhtml+xml\" ||\n /(^|\\/)([^/]+\\.(x?html|htm|xht)|[^/.]*)([#?]|$)/.test(url)\n ) {\n const param = {\n url: Base.resolveURL(Base.convertSpecialURL(url), this.pubURL),\n index: itemCount++,\n startPage: null,\n skipPagesBefore: null,\n };\n if (itemObj.rel === \"contents\" && tocFound === -1) {\n tocFound = param.index;\n }\n params.push(param);\n\n //TODO: items not in readingOrder should be excluded from linear reading but available with internal link navigation.\n }\n });\n }\n },\n );\n const frame: Task.Frame<boolean> = Task.newFrame(\"initWithWebPubManifest\");\n this.initWithChapters(params).then(() => {\n if (tocFound !== -1) {\n this.xhtmlToc = this.items[tocFound];\n }\n\n if (!this.xhtmlToc) {\n this.xhtmlToc = this.itemMapByPath[primaryEntryPath];\n }\n\n frame.finish(true);\n });\n return frame.result();\n }\n\n /**\n * @return cfi\n */\n getCFI(spineIndex: number, offsetInItem: number): Task.Result<string | null> {\n const item = this.spine[spineIndex];\n const frame: Task.Frame<string | null> = Task.newFrame(\"getCFI\");\n this.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const node = xmldoc.getNodeByOffset(offsetInItem);\n let cfi: string | null = null;\n if (node) {\n const startOffset = xmldoc.getNodeOffset(node, 0, false);\n const offsetInNode = offsetInItem - startOffset;\n const fragment = new CFI.Fragment();\n fragment.prependPathFromNode(node, offsetInNode, false, null);\n if (item.itemRefElement) {\n fragment.prependPathFromNode(item.itemRefElement, 0, false, null);\n }\n cfi = fragment.toString();\n }\n frame.finish(cfi);\n });\n return frame.result();\n }\n\n resolveFragment(fragstr: string | null): Task.Result<Position | null> {\n const self = this;\n return Task.handle(\n \"resolveFragment\",\n (frame: Task.Frame<Position | null>): void => {\n if (!fragstr) {\n frame.finish(null);\n return;\n }\n let fragment = new CFI.Fragment();\n fragment.fromString(fragstr);\n let item: OPFItem;\n if (self.opfXML) {\n const opfNav = fragment.navigate(self.opfXML.document);\n if (opfNav.node.nodeType != 1 || opfNav.after || !opfNav.ref) {\n frame.finish(null);\n return;\n }\n const elem = opfNav.node as Element;\n const idref = elem.getAttribute(\"idref\");\n if (elem.localName != \"itemref\" || !idref || !self.itemMap[idref]) {\n frame.finish(null);\n return;\n }\n item = self.itemMap[idref];\n fragment = opfNav.ref;\n } else {\n item = self.spine[0];\n }\n self.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const nodeNav = fragment.navigate(xmldoc.document);\n const offset = xmldoc.getNodeOffset(\n nodeNav.node,\n nodeNav.offset,\n nodeNav.after,\n );\n frame.finish({\n spineIndex: item.spineIndex,\n offsetInItem: offset,\n pageIndex: -1,\n });\n });\n },\n (frame: Task.Frame<Position | null>, err: Error): void => {\n Logging.logger.warn(err, \"Cannot resolve fragment:\", fragstr);\n frame.finish(null);\n },\n );\n }\n\n resolveEPage(epage: number): Task.Result<Position | null> {\n const self = this;\n return Task.handle(\n \"resolveEPage\",\n (frame: Task.Frame<Position | null>): void => {\n if (epage <= 0) {\n frame.finish({ spineIndex: 0, offsetInItem: 0, pageIndex: -1 });\n return;\n }\n if (self.epageIsRenderedPage) {\n let spineIndex = self.spine.findIndex((item) => {\n return (\n (item.epage == 0 && item.epageCount == 0) ||\n (item.epage <= epage && item.epage + item.epageCount > epage)\n );\n });\n if (spineIndex == -1) {\n spineIndex = self.spine.length - 1;\n }\n let item = self.spine[spineIndex];\n if (!item || item.epageCount == 0) {\n item = self.spine[--spineIndex];\n }\n const pageIndex = Math.floor(epage - item.epage);\n frame.finish({ spineIndex, offsetInItem: -1, pageIndex: pageIndex });\n return;\n }\n let spineIndex = Base.binarySearch(self.spine.length, (index) => {\n const item = self.spine[index];\n return item.epage + item.epageCount > epage;\n });\n if (spineIndex == self.spine.length) {\n spineIndex--;\n }\n const item = self.spine[spineIndex];\n self.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n epage -= item.epage;\n if (epage > item.epageCount) {\n epage = item.epageCount;\n }\n let offset = 0;\n if (epage > 0) {\n const totalOffset = xmldoc.getTotalOffset();\n offset = Math.round((totalOffset * epage) / item.epageCount);\n if (offset == totalOffset) {\n offset--;\n }\n }\n frame.finish({ spineIndex, offsetInItem: offset, pageIndex: -1 });\n });\n },\n (frame: Task.Frame<Position | null>, err: Error): void => {\n Logging.logger.warn(err, \"Cannot resolve epage:\", epage);\n frame.finish(null);\n },\n );\n }\n\n getEPageFromPosition(position: Position): Task.Result<number> {\n const item = this.spine[position.spineIndex];\n if (this.epageIsRenderedPage) {\n const epage = item.epage + position.pageIndex;\n return Task.newResult(epage);\n }\n if (position.offsetInItem <= 0) {\n return Task.newResult(item.epage);\n }\n const frame: Task.Frame<number> = Task.newFrame(\"getEPage\");\n this.store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n const totalOffset = xmldoc.getTotalOffset();\n const offset = Math.min(totalOffset, position.offsetInItem);\n frame.finish(item.epage + (offset * item.epageCount) / totalOffset);\n });\n return frame.result();\n }\n}\n\nexport type PageAndPosition = {\n page: Vtree.Page;\n position: Position;\n};\n\nexport const makePageAndPosition = (\n page: Vtree.Page,\n pageIndex: number,\n): PageAndPosition => ({\n page,\n position: {\n spineIndex: page.spineIndex,\n pageIndex,\n offsetInItem: page.offset,\n },\n});\n\nexport type OPFViewItem = {\n item: OPFItem;\n xmldoc: XmlDoc.XMLDocHolder;\n instance: OPS.StyleInstance;\n layoutPositions: Vtree.LayoutPosition[];\n pages: Vtree.Page[];\n complete: boolean;\n};\n\nexport class OPFView implements Vgen.CustomRendererFactory {\n spineItems: OPFViewItem[] = [];\n spineItemLoadingContinuations: Task.Continuation<any>[][] = [];\n pref: Exprs.Preferences;\n clientLayout: Vgen.DefaultClientLayout;\n counterStore: Counters.CounterStore;\n tocAutohide: boolean = false;\n tocView?: Toc.TOCView;\n\n constructor(\n public readonly opf: OPFDoc,\n public readonly viewport: Vgen.Viewport,\n public readonly fontMapper: Font.Mapper,\n pref: Exprs.Preferences,\n public readonly pageSheetSizeReporter: (\n p1: { width: number; height: number },\n p2: { [key: string]: { width: number; height: number } },\n p3: number,\n p4: number,\n ) => any,\n ) {\n this.pref = Exprs.clonePreferences(pref);\n this.clientLayout = new Vgen.DefaultClientLayout(viewport);\n this.counterStore = new Counters.CounterStore(opf.documentURLTransformer);\n }\n\n private getPage(position: Position): Vtree.Page {\n const viewItem = this.spineItems[position.spineIndex];\n return viewItem ? viewItem.pages[position.pageIndex] : null;\n }\n\n getCurrentPageProgression(\n position: Position,\n ): Constants.PageProgression | null {\n if (this.opf.pageProgression) {\n return this.opf.pageProgression;\n } else {\n const viewItem = this.spineItems[position ? position.spineIndex : 0];\n return viewItem ? viewItem.instance.pageProgression : null;\n }\n }\n\n private finishPageContainer(\n viewItem: OPFViewItem,\n page: Vtree.Page,\n pageIndex: number,\n ) {\n page.container.style.display = \"none\";\n page.container.style.visibility = \"visible\";\n page.container.style.position = \"\";\n page.container.style.top = \"\";\n page.container.style.left = \"\";\n page.container.setAttribute(\n \"data-vivliostyle-page-side\",\n page.side as string,\n );\n const oldPage = viewItem.pages[pageIndex];\n page.isFirstPage = viewItem.item.spineIndex == 0 && pageIndex == 0;\n viewItem.pages[pageIndex] = page;\n\n if (this.opf.epageIsRenderedPage) {\n if (pageIndex == 0 && viewItem.item.spineIndex > 0) {\n const prevItem = this.opf.spine[viewItem.item.spineIndex - 1];\n viewItem.item.epage = prevItem.epage + prevItem.epageCount;\n }\n viewItem.item.epageCount = viewItem.pages.length;\n this.opf.epageCount = this.opf.spine.reduce(\n (count, item) => count + item.epageCount,\n 0,\n );\n\n if (this.opf.epageCountCallback) {\n this.opf.epageCountCallback(this.opf.epageCount);\n }\n }\n\n if (oldPage) {\n viewItem.instance.viewport.contentContainer.replaceChild(\n page.container,\n oldPage.container,\n );\n oldPage.dispatchEvent({\n type: \"replaced\",\n target: null,\n currentTarget: null,\n preventDefault: null,\n newPage: page,\n });\n } else {\n // Find insert position in contentContainer.\n let insertPos: Element | null = null;\n if (pageIndex > 0) {\n insertPos = viewItem.pages[pageIndex - 1].container.nextElementSibling;\n } else {\n for (\n let i = viewItem.item.spineIndex + 1;\n i < this.spineItems.length;\n i++\n ) {\n const item = this.spineItems[i];\n if (item && item.pages[0]) {\n insertPos = item.pages[0].container;\n break;\n }\n }\n }\n viewItem.instance.viewport.contentContainer.insertBefore(\n page.container,\n insertPos,\n );\n }\n this.pageSheetSizeReporter(\n {\n width: viewItem.instance.pageSheetWidth,\n height: viewItem.instance.pageSheetHeight,\n },\n viewItem.instance.pageSheetSize,\n viewItem.item.spineIndex,\n viewItem.instance.pageNumberOffset + pageIndex,\n );\n }\n\n /**\n * Render a single page. If the new page contains elements with ids that are\n * referenced from other pages by 'target-counter()', those pages are rendered\n * too (calling `renderSinglePage` recursively).\n */\n private renderSinglePage(\n viewItem: OPFViewItem,\n pos: Vtree.LayoutPosition,\n ): Task.Result<RenderSinglePageResult> {\n const frame: Task.Frame<RenderSinglePageResult> = Task.newFrame(\n \"renderSinglePage\",\n );\n let page = this.makePage(viewItem, pos);\n const self = this;\n viewItem.instance.layoutNextPage(page, pos).then((posParam) => {\n pos = posParam as Vtree.LayoutPosition;\n const pageIndex = pos\n ? pos.page - 1\n : viewItem.layoutPositions.length - 1;\n self.finishPageContainer(viewItem, page, pageIndex);\n self.counterStore.finishPage(page.spineIndex, pageIndex);\n\n // If the position of the page break change, we should re-layout the next\n // page too.\n let cont: Task.Result<any> = null;\n if (pos) {\n const prevPos = viewItem.layoutPositions[pos.page];\n viewItem.layoutPositions[pos.page] = pos;\n if (prevPos && viewItem.pages[pos.page]) {\n if (!pos.isSamePosition(prevPos)) {\n cont = self.renderSinglePage(viewItem, pos);\n }\n }\n }\n if (!cont) {\n cont = Task.newResult(true);\n }\n cont.then(() => {\n const unresolvedRefs = self.counterStore.getUnresolvedRefsToPage(page);\n let index = 0;\n frame\n .loopWithFrame((loopFrame) => {\n index++;\n if (index > unresolvedRefs.length) {\n loopFrame.breakLoop();\n return;\n }\n const refs = unresolvedRefs[index - 1];\n refs.refs = refs.refs.filter((ref) => !ref.isResolved());\n if (refs.refs.length === 0) {\n loopFrame.continueLoop();\n return;\n }\n self.getPageViewItem(refs.spineIndex).then((viewItem) => {\n if (!viewItem) {\n loopFrame.continueLoop();\n return;\n }\n self.counterStore.pushPageCounters(refs.pageCounters);\n self.counterStore.pushReferencesToSolve(refs.refs);\n const pos = viewItem.layoutPositions[refs.pageIndex];\n self.renderSinglePage(viewItem, pos).then((result) => {\n self.counterStore.popPageCounters();\n self.counterStore.popReferencesToSolve();\n const resultPosition = result.pageAndPosition.position;\n if (\n resultPosition.spineIndex === page.spineIndex &&\n resultPosition.pageIndex === pageIndex\n ) {\n page = result.pageAndPosition.page;\n }\n loopFrame.continueLoop();\n });\n });\n })\n .then(() => {\n if (!page.container.parentElement) {\n // page is replaced\n page = viewItem.pages[pageIndex];\n }\n page.isLastPage =\n !pos && viewItem.item.spineIndex === self.opf.spine.length - 1;\n if (page.isLastPage) {\n Asserts.assert(self.viewport);\n self.counterStore.finishLastPage(self.viewport);\n }\n frame.finish({\n pageAndPosition: makePageAndPosition(page, pageIndex),\n nextLayoutPosition: pos,\n });\n });\n });\n });\n return frame.result();\n }\n\n private normalizeSeekPosition(\n position: Position,\n viewItem: OPFViewItem,\n ): Position | null {\n let pageIndex = position.pageIndex;\n let seekOffset = -1;\n if (pageIndex < 0) {\n seekOffset = position.offsetInItem;\n\n // page with offset higher than seekOffset\n const seekOffsetPageIndex = Base.binarySearch(\n viewItem.layoutPositions.length,\n (pageIndex) => {\n // 'noLookAhead' argument of getPosition must be true, since\n // otherwise StyleInstance.currentLayoutPosition is modified\n // unintentionally.\n const offset = viewItem.instance.getPosition(\n viewItem.layoutPositions[pageIndex],\n true,\n );\n return offset > seekOffset;\n },\n );\n if (seekOffsetPageIndex === viewItem.layoutPositions.length) {\n if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n } else {\n // need to search through pages that are not yet produced\n pageIndex = Number.POSITIVE_INFINITY;\n }\n } else {\n // page that contains seekOffset\n pageIndex = seekOffsetPageIndex - 1;\n }\n } else if (\n pageIndex === Number.POSITIVE_INFINITY &&\n position.offsetInItem !== -1\n ) {\n seekOffset = position.offsetInItem;\n }\n return {\n spineIndex: position.spineIndex,\n pageIndex,\n offsetInItem: seekOffset,\n } as Position;\n }\n\n /**\n * Find a page corresponding to a specified position among already laid out\n * pages.\n * @param sync If true, find the page synchronously (not waiting another\n * rendering task)\n */\n private findPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\"findPage\");\n self.getPageViewItem(position.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n let resultPage: Vtree.Page = null;\n let pageIndex: number;\n frame\n .loopWithFrame((loopFrame) => {\n const normalizedPosition = self.normalizeSeekPosition(\n position,\n viewItem,\n );\n pageIndex = normalizedPosition.pageIndex;\n resultPage = viewItem.pages[pageIndex];\n if (resultPage) {\n loopFrame.breakLoop();\n } else if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n resultPage = viewItem.pages[pageIndex];\n loopFrame.breakLoop();\n } else if (sync) {\n self.renderPage(normalizedPosition).then((result) => {\n if (result) {\n resultPage = result.page;\n pageIndex = result.position.pageIndex;\n }\n loopFrame.breakLoop();\n });\n } else {\n // Wait for the layout task and retry\n frame.sleep(100).then(() => {\n loopFrame.continueLoop();\n });\n }\n })\n .then(() => {\n Asserts.assert(resultPage);\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n });\n });\n return frame.result();\n }\n\n /**\n * Renders a page at the specified position.\n */\n renderPage(position: Position): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"renderPage\",\n );\n self.getPageViewItem(position.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n const normalizedPosition = self.normalizeSeekPosition(position, viewItem);\n let pageIndex = normalizedPosition.pageIndex;\n const seekOffset = normalizedPosition.offsetInItem;\n let resultPage = viewItem.pages[pageIndex];\n if (resultPage) {\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n return;\n }\n frame\n .loopWithFrame((loopFrame) => {\n if (pageIndex < viewItem.layoutPositions.length) {\n loopFrame.breakLoop();\n return;\n }\n if (viewItem.complete) {\n pageIndex = viewItem.layoutPositions.length - 1;\n loopFrame.breakLoop();\n return;\n }\n let pos =\n viewItem.layoutPositions[viewItem.layoutPositions.length - 1];\n self.renderSinglePage(viewItem, pos).then((result) => {\n const page = result.pageAndPosition.page;\n pos = result.nextLayoutPosition;\n if (pos) {\n if (seekOffset >= 0) {\n // Searching for offset, don't know the page number.\n const offset = viewItem.instance.getPosition(pos);\n if (offset > seekOffset) {\n resultPage = page;\n pageIndex = viewItem.layoutPositions.length - 2;\n loopFrame.breakLoop();\n return;\n }\n }\n loopFrame.continueLoop();\n } else {\n resultPage = page;\n pageIndex = result.pageAndPosition.position.pageIndex;\n viewItem.complete = true;\n loopFrame.breakLoop();\n }\n });\n })\n .then(() => {\n resultPage = resultPage || viewItem.pages[pageIndex];\n const pos = viewItem.layoutPositions[pageIndex];\n if (resultPage) {\n frame.finish(makePageAndPosition(resultPage, pageIndex));\n return;\n }\n self.renderSinglePage(viewItem, pos).then((result) => {\n if (!result.nextLayoutPosition) {\n viewItem.complete = true;\n }\n frame.finish(result.pageAndPosition);\n });\n });\n });\n return frame.result();\n }\n\n renderAllPages(): Task.Result<PageAndPosition | null> {\n return this.renderPagesUpto(\n {\n spineIndex: this.opf.spine.length - 1,\n pageIndex: Number.POSITIVE_INFINITY,\n offsetInItem: -1,\n },\n false,\n );\n }\n\n /**\n * Render pages from (spineIndex=0, pageIndex=0) to the specified (spineIndex,\n * pageIndex).\n * @param notAllPages If true, render from biginning of specified spine item.\n */\n renderPagesUpto(\n position: Position,\n notAllPages: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"renderPagesUpto\",\n );\n if (!position) {\n position = { spineIndex: 0, pageIndex: 0, offsetInItem: 0 };\n }\n const spineIndex = position.spineIndex;\n const pageIndex = position.pageIndex;\n let s = 0;\n\n if (notAllPages) {\n // Render pages from biginning of specified spine item.\n s = spineIndex;\n }\n\n let lastResult: PageAndPosition;\n frame\n .loopWithFrame((loopFrame) => {\n const pos = {\n spineIndex: s,\n pageIndex: s === spineIndex ? pageIndex : Number.POSITIVE_INFINITY,\n offsetInItem: s === spineIndex ? position.offsetInItem : -1,\n };\n self.renderPage(pos).then((result) => {\n lastResult = result;\n if (++s > spineIndex) {\n loopFrame.breakLoop();\n } else {\n loopFrame.continueLoop();\n }\n });\n })\n .then(() => {\n frame.finish(lastResult);\n });\n return frame.result();\n }\n\n /**\n * Move to the first page and render it.\n */\n firstPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n return this.findPage(\n { spineIndex: 0, pageIndex: 0, offsetInItem: -1 },\n sync,\n );\n }\n\n /**\n * Move to the last page and render it.\n */\n lastPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n return this.findPage(\n {\n spineIndex: this.opf.spine.length - 1,\n pageIndex: Number.POSITIVE_INFINITY,\n offsetInItem: -1,\n },\n sync,\n );\n }\n\n /**\n * Move to the next page position and render page.\n * @param sync If true, get the page synchronously (not waiting another\n * rendering task)\n */\n nextPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const self = this;\n let spineIndex = position.spineIndex;\n let pageIndex = position.pageIndex;\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\"nextPage\");\n self.getPageViewItem(spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n if (\n viewItem.complete &&\n pageIndex == viewItem.layoutPositions.length - 1\n ) {\n if (spineIndex >= self.opf.spine.length - 1) {\n frame.finish(null);\n return;\n }\n spineIndex++;\n pageIndex = 0;\n\n // Remove next viewItem if its first page has same side as the current page\n // to avoid unpaired page.\n const nextViewItem = this.spineItems[spineIndex];\n const nextPage = nextViewItem && nextViewItem.pages[0];\n const currentPage = viewItem.pages[viewItem.pages.length - 1];\n if (nextPage && currentPage && nextPage.side == currentPage.side) {\n nextViewItem.pages.forEach((page) => {\n if (page.container) page.container.remove();\n });\n this.spineItems[spineIndex] = null;\n this.spineItemLoadingContinuations[spineIndex] = null;\n }\n } else {\n pageIndex++;\n }\n self\n .findPage({ spineIndex, pageIndex, offsetInItem: -1 }, sync)\n .thenFinish(frame);\n });\n return frame.result();\n }\n\n /**\n * Move to the previous page and render it.\n */\n previousPage(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n let spineIndex = position.spineIndex;\n let pageIndex = position.pageIndex;\n if (pageIndex == 0) {\n if (spineIndex == 0) {\n return Task.newResult(null as PageAndPosition | null);\n }\n spineIndex--;\n pageIndex = Number.POSITIVE_INFINITY;\n } else {\n pageIndex--;\n }\n return this.findPage({ spineIndex, pageIndex, offsetInItem: -1 }, sync);\n }\n\n /**\n * @param page This page should be a currently displayed page.\n */\n private isRectoPage(page: Vtree.Page, position: Position): boolean {\n const isLeft = page.side === Constants.PageSide.LEFT;\n const isLTR =\n this.getCurrentPageProgression(position) ===\n Constants.PageProgression.LTR;\n return (!isLeft && isLTR) || (isLeft && !isLTR);\n }\n\n /**\n * Get a spread containing the currently displayed page.\n * @param sync If true, get the spread synchronously (not waiting another\n * rendering task)\n */\n getSpread(position: Position, sync: boolean): Task.Result<Vtree.Spread> {\n const frame: Task.Frame<Vtree.Spread> = Task.newFrame(\"getCurrentSpread\");\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(\n /** @type Vtree.Spread */\n { left: null, right: null } as Vtree.Spread,\n );\n }\n const isLeft = page.side === Constants.PageSide.LEFT;\n let other: Task.Result<PageAndPosition>;\n if (this.isRectoPage(page, position)) {\n other = this.previousPage(position, sync);\n } else {\n other = this.nextPage(position, sync);\n }\n other.then((otherPageAndPosition) => {\n // this page may be replaced during nextPage(), so get thisPage again.\n const thisPage = this.getPage(position);\n\n let otherPage = otherPageAndPosition && otherPageAndPosition.page;\n if (otherPage && otherPage.side === thisPage.side) {\n // otherPage must not be same side\n otherPage = null;\n }\n\n if (isLeft) {\n frame.finish({ left: thisPage, right: otherPage });\n } else {\n frame.finish({ left: otherPage, right: thisPage });\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the next spread and render pages.\n * @param sync If true, get the spread synchronously (not waiting another\n * rendering task)\n * @returns The 'verso' page of the next spread.\n */\n nextSpread(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(null as PageAndPosition | null);\n }\n const isRecto = this.isRectoPage(page, position);\n const next = this.nextPage(position, sync);\n if (isRecto) {\n return next;\n } else {\n const self = this;\n return next.thenAsync((result) => {\n if (result) {\n if (result.page.side === page.side) {\n // If same side, this is the next spread.\n return next;\n }\n const next2 = self.nextPage(result.position, sync);\n return next2.thenAsync((result2) => {\n if (result2) {\n return next2;\n } else {\n // If this is tha last spread, move to next page in the same spread.\n return next;\n }\n });\n } else {\n return Task.newResult(null as PageAndPosition | null);\n }\n });\n }\n }\n\n /**\n * Move to the previous spread and render pages.\n * @returns The 'recto' page of the previous spread.\n */\n previousSpread(\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const page = this.getPage(position);\n if (!page) {\n return Task.newResult(null as PageAndPosition | null);\n }\n const isRecto = this.isRectoPage(page, position);\n const prev = this.previousPage(position, sync);\n const oldPrevPageCont = page.container.previousElementSibling;\n if (isRecto) {\n const self = this;\n return prev.thenAsync((result) => {\n if (result) {\n if (result.page.side === page.side) {\n // If same side, this is the previous spread.\n return prev;\n }\n if (result.page.container !== oldPrevPageCont) {\n // If previous page is changed, return it.\n return prev;\n }\n return self.previousPage(result.position, sync);\n } else {\n return Task.newResult(null as PageAndPosition | null);\n }\n });\n } else {\n return prev;\n }\n }\n\n /**\n * Move to the epage specified by the given number (zero-based) and render it.\n */\n navigateToEPage(\n epage: number,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateToEPage\",\n );\n const self = this;\n this.opf.resolveEPage(epage).then((position) => {\n if (position) {\n self.findPage(position, sync).thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the page specified by the given CFI and render it.\n */\n navigateToFragment(\n fragment: string,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateToCFI\",\n );\n const self = this;\n self.opf.resolveFragment(fragment).then((position) => {\n if (position) {\n self.findPage(position, sync).thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n /**\n * Move to the page specified by the given URL and render it.\n */\n navigateTo(\n href: string,\n position: Position,\n sync: boolean,\n ): Task.Result<PageAndPosition | null> {\n Logging.logger.debug(\"Navigate to\", href);\n let path = this.opf.getPathFromURL(Base.stripFragment(href));\n if (!path) {\n if (this.opf.opfXML && href.match(/^#epubcfi\\(/)) {\n // CFI fragment is \"relative\" to OPF.\n path = this.opf.getPathFromURL(this.opf.opfXML.url);\n } else if (href.charAt(0) === \"#\") {\n const restored = this.opf.documentURLTransformer.restoreURL(href);\n if (this.opf.opfXML) {\n path = this.opf.getPathFromURL(restored[0]);\n if (path == null) {\n path = restored[0];\n }\n } else {\n path = restored[0];\n }\n href = restored[0] + (restored[1] ? `#${restored[1]}` : \"\");\n }\n if (path == null) {\n return Task.newResult(null as PageAndPosition | null);\n }\n }\n const item = this.opf.itemMapByPath[path];\n if (!item) {\n if (\n this.opf.opfXML &&\n path == this.opf.getPathFromURL(this.opf.opfXML.url)\n ) {\n // CFI link?\n const fragmentIndex = href.indexOf(\"#\");\n if (fragmentIndex >= 0) {\n return this.navigateToFragment(\n href.substr(fragmentIndex + 1),\n position,\n sync,\n );\n }\n }\n return Task.newResult(null as PageAndPosition | null);\n }\n const frame: Task.Frame<PageAndPosition | null> = Task.newFrame(\n \"navigateTo\",\n );\n const self = this;\n self.getPageViewItem(item.spineIndex).then((viewItem) => {\n if (!viewItem) {\n frame.finish(null);\n return;\n }\n const target = viewItem.xmldoc.getElement(href);\n if (target) {\n self\n .findPage(\n {\n spineIndex: item.spineIndex,\n pageIndex: -1,\n offsetInItem: viewItem.xmldoc.getElementOffset(target),\n },\n sync,\n )\n .thenFinish(frame);\n } else if (position.spineIndex !== item.spineIndex) {\n // no fragment, different spine item\n self\n .findPage(\n {\n spineIndex: item.spineIndex,\n pageIndex: 0,\n offsetInItem: -1,\n },\n sync,\n )\n .thenFinish(frame);\n } else {\n frame.finish(null);\n }\n });\n return frame.result();\n }\n\n makePage(viewItem: OPFViewItem, pos: Vtree.LayoutPosition): Vtree.Page {\n const viewport = viewItem.instance.viewport;\n const pageCont = viewport.document.createElement(\"div\") as HTMLElement;\n pageCont.setAttribute(\"data-vivliostyle-page-container\", \"true\");\n pageCont.setAttribute(\"role\", \"region\");\n pageCont.style.position = \"absolute\";\n pageCont.style.top = \"0\";\n pageCont.style.left = \"0\";\n if (!Constants.isDebug) {\n pageCont.style.visibility = \"hidden\";\n pageCont.setAttribute(\"aria-hidden\", \"true\");\n }\n viewport.layoutBox.appendChild(pageCont);\n const bleedBox = viewport.document.createElement(\"div\") as HTMLElement;\n bleedBox.setAttribute(\"data-vivliostyle-bleed-box\", \"true\");\n pageCont.appendChild(bleedBox);\n const page = new Vtree.Page(pageCont, bleedBox);\n page.spineIndex = viewItem.item.spineIndex;\n page.position = pos;\n page.offset = viewItem.instance.getPosition(pos);\n if (page.offset === 0) {\n const id = this.opf.documentURLTransformer.transformFragment(\n \"\",\n viewItem.item.src,\n );\n bleedBox.setAttribute(\"id\", id);\n page.registerElementWithId(bleedBox, id);\n }\n if (viewport !== this.viewport) {\n const matrix = Exprs.letterbox(\n this.viewport.width,\n this.viewport.height,\n viewport.width,\n viewport.height,\n );\n const cssMatrix = CssParser.parseValue(\n null,\n new CssTokenizer.Tokenizer(matrix, null),\n \"\",\n );\n page.delayedItems.push(\n new Vtree.DelayedItem(pageCont, \"transform\", cssMatrix),\n );\n }\n return page;\n }\n\n makeObjectView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n let data = srcElem.getAttribute(\"data\");\n let result: Element | null = null;\n if (data) {\n data = Base.resolveURL(data, xmldoc.url);\n let mediaType = srcElem.getAttribute(\"media-type\");\n if (!mediaType) {\n const path = this.opf.getPathFromURL(data);\n if (path) {\n const item = this.opf.itemMapByPath[path];\n if (item) {\n mediaType = item.mediaType;\n }\n }\n }\n if (mediaType) {\n const handlerSrc = this.opf.bindings[mediaType];\n if (handlerSrc) {\n result = this.viewport.document.createElement(\"iframe\");\n (result as HTMLElement).style.border = \"none\";\n const srcParam = Base.lightURLEncode(data);\n const typeParam = Base.lightURLEncode(mediaType);\n const sb = new Base.StringBuffer();\n sb.append(handlerSrc);\n sb.append(\"?src=\");\n sb.append(srcParam);\n sb.append(\"&type=\");\n sb.append(typeParam);\n for (let c: Node = srcElem.firstChild; c; c = c.nextSibling) {\n if (c.nodeType == 1) {\n const ce = c as Element;\n if (ce.localName == \"param\" && ce.namespaceURI == Base.NS.XHTML) {\n const pname = ce.getAttribute(\"name\");\n const pvalue = ce.getAttribute(\"value\");\n if (pname && pvalue) {\n sb.append(\"&\");\n sb.append(encodeURIComponent(pname));\n sb.append(\"=\");\n sb.append(encodeURIComponent(pvalue));\n }\n }\n }\n }\n result.setAttribute(\"src\", sb.toString());\n const width = srcElem.getAttribute(\"width\");\n if (width) {\n result.setAttribute(\"width\", width);\n }\n const height = srcElem.getAttribute(\"height\");\n if (height) {\n result.setAttribute(\"height\", height);\n }\n }\n }\n }\n if (!result) {\n result = this.viewport.document.createElement(\"span\");\n result.setAttribute(\"data-adapt-process-children\", \"true\");\n }\n\n // Need to cast because we need {Element}, not {!Element}\n return Task.newResult(result as Element);\n }\n\n makeMathJaxView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n // See if MathJax installed, use it if it is.\n const hub = getMathJaxHub();\n if (hub) {\n const doc = viewParent.ownerDocument;\n const span = doc.createElement(\"span\");\n viewParent.appendChild(span);\n const clonedMath = doc.importNode(srcElem, true);\n this.resolveURLsInMathML(clonedMath, xmldoc);\n span.appendChild(clonedMath);\n const queue = hub[\"queue\"];\n queue[\"Push\"]([\"Typeset\", hub, span]);\n const frame: Task.Frame<Element> = Task.newFrame(\"makeMathJaxView\");\n const continuation = frame.suspend();\n queue[\"Push\"](() => {\n continuation.schedule(span);\n });\n return frame.result();\n }\n return Task.newResult(null as Element);\n }\n\n private resolveURLsInMathML(node: Node, xmldoc: XmlDoc.XMLDocHolder) {\n if (node == null) {\n return;\n }\n if (node.nodeType === 1 && (node as Element).tagName === \"mglyph\") {\n const attrs = Array.from((node as Element).attributes);\n for (const attr of attrs) {\n if (attr.name !== \"src\") {\n continue;\n }\n const newUrl = Base.resolveURL(attr.nodeValue, xmldoc.url);\n if (attr.namespaceURI) {\n (node as Element).setAttributeNS(\n attr.namespaceURI,\n attr.name,\n newUrl,\n );\n } else {\n (node as Element).setAttribute(attr.name, newUrl);\n }\n }\n }\n if (node.firstChild) {\n this.resolveURLsInMathML(node.firstChild, xmldoc);\n }\n if (node.nextSibling) {\n this.resolveURLsInMathML(node.nextSibling, xmldoc);\n }\n }\n\n // TODO move makeSSEView to a more appropriate class (SSE XML content is not\n // allowed in EPUB)\n /**\n * @param computedStyle\n */\n makeSSEView(\n xmldoc: XmlDoc.XMLDocHolder,\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> {\n const doc = viewParent ? viewParent.ownerDocument : this.viewport.document;\n const srcTagName = srcElem.localName;\n let tagName: string;\n switch (srcTagName) {\n case \"t\":\n case \"tab\":\n case \"ec\":\n case \"nt\":\n case \"fraction\":\n case \"comment\":\n case \"mark\":\n tagName = \"span\";\n break;\n case \"ruby\":\n case \"rp\":\n case \"rt\":\n tagName = srcTagName;\n break;\n default:\n tagName = \"div\";\n }\n const result = doc.createElement(tagName);\n result.setAttribute(\"data-adapt-process-children\", \"true\");\n\n // Need to cast because we need {Element}, not {!Element}\n return Task.newResult(result as Element);\n }\n\n /**\n * @override\n */\n makeCustomRenderer(xmldoc: XmlDoc.XMLDocHolder): Vgen.CustomRenderer {\n const self = this;\n return (\n srcElem: Element,\n viewParent: Element,\n computedStyle: { [key: string]: Css.Val },\n ): Task.Result<Element> => {\n if (\n srcElem.localName == \"object\" &&\n srcElem.namespaceURI == Base.NS.XHTML\n ) {\n return self.makeObjectView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (srcElem.namespaceURI == Base.NS.MATHML) {\n return self.makeMathJaxView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (srcElem.namespaceURI == Base.NS.SSE) {\n return self.makeSSEView(xmldoc, srcElem, viewParent, computedStyle);\n } else if (\n (srcElem as HTMLElement).dataset &&\n (srcElem as HTMLElement).dataset[\"mathTypeset\"] == \"true\"\n ) {\n return self.makeMathJaxView(xmldoc, srcElem, viewParent, computedStyle);\n }\n return Task.newResult(null as Element);\n };\n }\n\n getPageViewItem(spineIndex: number): Task.Result<OPFViewItem> {\n const self = this;\n if (spineIndex === -1 || spineIndex >= self.opf.spine.length) {\n return Task.newResult(null as OPFViewItem);\n }\n let viewItem = self.spineItems[spineIndex];\n if (viewItem) {\n return Task.newResult(viewItem);\n }\n const frame: Task.Frame<OPFViewItem> = Task.newFrame(\"getPageViewItem\");\n\n // If loading for the item has already been started, suspend and wait for\n // the result.\n let loadingContinuations = this.spineItemLoadingContinuations[spineIndex];\n if (loadingContinuations) {\n const cont = frame.suspend();\n loadingContinuations.push(cont);\n return frame.result();\n } else {\n loadingContinuations = this.spineItemLoadingContinuations[\n spineIndex\n ] = [];\n }\n const item = self.opf.spine[spineIndex];\n const store = self.opf.store;\n store.load(item.src).then((xmldoc: XmlDoc.XMLDocHolder) => {\n item.title = xmldoc.document.title;\n const style = store.getStyleForDoc(xmldoc);\n const customRenderer = self.makeCustomRenderer(xmldoc);\n let viewport = self.viewport;\n const viewportSize = style.sizeViewport(\n viewport.width,\n viewport.height,\n viewport.fontSize,\n self.pref,\n );\n if (\n viewportSize.width != viewport.width ||\n viewportSize.height != viewport.height ||\n viewportSize.fontSize != viewport.fontSize\n ) {\n viewport = new Vgen.Viewport(\n viewport.window,\n viewportSize.fontSize,\n viewport.root,\n viewportSize.width,\n viewportSize.height,\n );\n }\n const previousViewItem = self.spineItems[spineIndex - 1];\n let pageNumberOffset: number;\n if (item.startPage !== null) {\n pageNumberOffset = item.startPage - 1;\n } else {\n if (\n spineIndex > 0 &&\n (!previousViewItem || !previousViewItem.complete)\n ) {\n // When navigate to a new spine item skipping the previous items,\n // give up calculate pageNumberOffset and use epage (or spineIndex if epage is unset).\n pageNumberOffset = item.epage || spineIndex;\n if (!self.opf.prePaginated && pageNumberOffset % 2 == 0) {\n // Force to odd number to avoid unpaired page. (This is 0 based and even number is recto)\n pageNumberOffset++;\n }\n } else {\n pageNumberOffset = previousViewItem\n ? previousViewItem.instance.pageNumberOffset +\n previousViewItem.pages.length\n : 0;\n }\n if (item.skipPagesBefore !== null) {\n pageNumberOffset += item.skipPagesBefore;\n }\n }\n self.counterStore.forceSetPageCounter(pageNumberOffset);\n const instance = new OPS.StyleInstance(\n style,\n xmldoc,\n self.opf.lang,\n viewport,\n self.clientLayout,\n self.fontMapper,\n customRenderer,\n self.opf.fallbackMap,\n pageNumberOffset,\n self.opf.documentURLTransformer,\n self.counterStore,\n self.opf.pageProgression,\n );\n instance.pref = self.pref;\n\n // For env(pub-title) and env(doc-title)\n const pubTitles = self.opf.metadata && self.opf.metadata[metaTerms.title];\n instance.pubTitle =\n (pubTitles && pubTitles[0] && pubTitles[0][\"v\"]) || \"\";\n instance.docTitle = item.title || \"\";\n\n instance.init().then(() => {\n viewItem = {\n item,\n xmldoc,\n instance,\n layoutPositions: [null],\n pages: [],\n complete: false,\n };\n self.spineItems[spineIndex] = viewItem;\n frame.finish(viewItem);\n loadingContinuations.forEach((c) => {\n c.schedule(viewItem);\n });\n });\n });\n return frame.result();\n }\n\n removeRenderedPages() {\n const items = this.spineItems;\n for (const item of items) {\n if (item) {\n item.pages.splice(0);\n }\n }\n this.viewport.clear();\n }\n\n /**\n * Returns if at least one page has 'auto' size\n */\n hasAutoSizedPages(): boolean {\n const items = this.spineItems;\n for (const item of items) {\n if (item) {\n const pages = item.pages;\n for (const page of pages) {\n if (page.isAutoPageWidth && page.isAutoPageHeight) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n hasPages(): boolean {\n return this.spineItems.some((item) => item && item.pages.length > 0);\n }\n\n showTOC(autohide: boolean): Task.Result<Vtree.Page> {\n const opf = this.opf;\n const toc = opf.xhtmlToc || opf.ncxToc;\n this.tocAutohide = autohide;\n if (!toc) {\n return Task.newResult(null as Vtree.Page);\n }\n if (this.tocView && this.tocView.page) {\n this.tocView.page.container.style.visibility = \"visible\";\n this.tocView.page.container.setAttribute(\"aria-hidden\", \"false\");\n return Task.newResult(this.tocView.page);\n }\n const frame: Task.Frame<Vtree.Page> = Task.newFrame(\"showTOC\");\n if (!this.tocView) {\n this.tocView = new Toc.TOCView(\n opf.store,\n toc.src,\n opf.lang,\n this.clientLayout,\n this.fontMapper,\n this.pref,\n this,\n opf.fallbackMap,\n opf.documentURLTransformer,\n this.counterStore,\n );\n }\n const viewport = this.viewport;\n const tocWidth = Math.min(350, Math.round(0.67 * viewport.width) - 16);\n const tocHeight = viewport.height - 6;\n const pageCont = viewport.document.createElement(\"div\") as HTMLElement;\n viewport.root.appendChild(pageCont);\n // pageCont.style.position = \"absolute\";\n pageCont.style.visibility = \"hidden\";\n // pageCont.style.left = \"3px\";\n // pageCont.style.top = \"3px\";\n pageCont.style.width = `${tocWidth + 10}px`;\n pageCont.style.maxHeight = `${tocHeight}px`;\n // pageCont.style.overflow = \"scroll\";\n // pageCont.style.overflowX = \"hidden\";\n // pageCont.style.background = \"rgba(248,248,248,0.9)\";\n // pageCont.style[\"borderRadius\"] = \"2px\";\n // pageCont.style[\"boxShadow\"] = \"1px 1px 2px rgba(0,0,0,0.4)\";\n\n pageCont.setAttribute(\"data-vivliostyle-toc-box\", \"true\");\n pageCont.setAttribute(\"role\", \"navigation\");\n\n this.tocView\n .showTOC(pageCont, viewport, tocWidth, tocHeight, this.viewport.fontSize)\n .then((page) => {\n pageCont.style.visibility = \"visible\";\n pageCont.setAttribute(\"aria-hidden\", \"false\");\n frame.finish(page);\n });\n return frame.result();\n }\n\n hideTOC(): void {\n if (this.tocView) {\n this.tocView.hideTOC();\n }\n }\n\n isTOCVisible(): boolean {\n return !!this.tocView && this.tocView.isTOCVisible();\n }\n}\n\nexport interface RenderSinglePageResult {\n pageAndPosition: PageAndPosition;\n nextLayoutPosition: Vtree.LayoutPosition;\n}\n","/**\n * Copyright 2013 Google, Inc.\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview AdaptiveViewer - Viewer implementation.\n */\nimport * as Asserts from \"./asserts\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Epub from \"./epub\";\nimport * as Exprs from \"./exprs\";\nimport * as Font from \"./font\";\nimport * as Logging from \"./logging\";\nimport * as Plugin from \"./plugin\";\nimport * as Profile from \"./profile\";\nimport * as Task from \"./task\";\nimport * as TaskUtil from \"./task-util\";\nimport * as Vgen from \"./vgen\";\nimport * as Vtree from \"./vtree\";\n\nexport type Action = (p1: Base.JSON) => Task.Result<boolean>;\n\nexport type ViewportSize = {\n marginLeft: number;\n marginRight: number;\n marginTop: number;\n marginBottom: number;\n width: number;\n height: number;\n};\n\nexport const VIEWPORT_STATUS_ATTRIBUTE = \"data-vivliostyle-viewer-status\";\n\nexport const VIEWPORT_SPREAD_VIEW_ATTRIBUTE = \"data-vivliostyle-spread-view\";\n\n/**\n * @enum {string}\n */\nexport enum PageViewMode {\n SINGLE_PAGE = \"singlePage\",\n SPREAD = \"spread\",\n AUTO_SPREAD = \"autoSpread\",\n}\n\nexport type SingleDocumentParam = {\n url: string;\n startPage: number | null;\n skipPagesBefore: number | null;\n};\n\nexport class AdaptiveViewer {\n fontMapper: Font.Mapper;\n kick: () => void;\n sendCommand: (p1: Base.JSON | string) => void;\n resizeListener: () => void;\n hyperlinkListener: Base.EventListener;\n pageRuleStyleElement: HTMLElement;\n pageSheetSizeAlreadySet: boolean = false;\n renderTask: Task.Task | null = null;\n actions: { [key: string]: Action };\n readyState: Constants.ReadyState;\n packageURL: string[];\n opf: Epub.OPFDoc;\n haveZipMetadata: boolean;\n touchActive: boolean;\n touchX: number;\n touchY: number;\n needResize: boolean;\n needRefresh: boolean;\n viewportSize: ViewportSize | null;\n currentPage: Vtree.Page;\n currentSpread: Vtree.Spread | null;\n pagePosition: Epub.Position | null;\n fontSize: number;\n zoom: number;\n fitToScreen: boolean;\n pageViewMode: PageViewMode;\n waitForLoading: boolean;\n renderAllPages: boolean;\n pref: Exprs.Preferences;\n pageSizes: { width: number; height: number }[];\n\n // force relayout\n viewport: Vgen.Viewport | null;\n opfView: Epub.OPFView;\n\n constructor(\n public readonly window: Window,\n public readonly viewportElement: HTMLElement,\n public readonly instanceId: string,\n public readonly callbackFn: (p1: Base.JSON) => void,\n ) {\n const self = this;\n viewportElement.setAttribute(\"data-vivliostyle-viewer-viewport\", true);\n if (Constants.isDebug) {\n viewportElement.setAttribute(\"data-vivliostyle-debug\", true);\n }\n viewportElement.setAttribute(VIEWPORT_STATUS_ATTRIBUTE, \"loading\");\n const document = window.document;\n this.fontMapper = new Font.Mapper(document.head, viewportElement);\n this.init();\n this.kick = () => {};\n this.sendCommand = () => {};\n this.resizeListener = () => {\n self.needResize = true;\n self.kick();\n };\n this.pageReplacedListener = this.pageReplacedListener.bind(this);\n this.hyperlinkListener = (evt) => {};\n this.pageRuleStyleElement = document.getElementById(\n \"vivliostyle-page-rules\",\n );\n this.actions = {\n loadPublication: this.loadPublication,\n loadXML: this.loadXML,\n configure: this.configure,\n moveTo: this.moveTo,\n toc: this.showTOC,\n };\n this.addLogListeners();\n }\n\n private init(): void {\n this.readyState = Constants.ReadyState.LOADING;\n this.packageURL = [];\n this.opf = null;\n this.haveZipMetadata = false;\n this.touchActive = false;\n this.touchX = 0;\n this.touchY = 0;\n this.needResize = false;\n this.needRefresh = false;\n this.viewportSize = null;\n this.currentPage = null;\n this.currentSpread = null;\n this.pagePosition = null;\n this.fontSize = 16;\n this.zoom = 1;\n this.fitToScreen = false;\n this.pageViewMode = PageViewMode.SINGLE_PAGE;\n this.waitForLoading = false;\n this.renderAllPages = true;\n this.pref = Exprs.defaultPreferences();\n this.pageSizes = [];\n }\n\n addLogListeners() {\n const logLevel = Logging.LogLevel;\n Logging.logger.addListener(logLevel.DEBUG, (info) => {\n this.callback({ t: \"debug\", content: info });\n });\n Logging.logger.addListener(logLevel.INFO, (info) => {\n this.callback({ t: \"info\", content: info });\n });\n Logging.logger.addListener(logLevel.WARN, (info) => {\n this.callback({ t: \"warn\", content: info });\n });\n Logging.logger.addListener(logLevel.ERROR, (info) => {\n this.callback({ t: \"error\", content: info });\n });\n }\n\n private callback(message: Base.JSON): void {\n message[\"i\"] = this.instanceId;\n this.callbackFn(message);\n }\n\n /**\n * Set readyState and notify to listeners\n */\n setReadyState(readyState: Constants.ReadyState) {\n if (this.readyState !== readyState) {\n this.readyState = readyState;\n this.viewportElement.setAttribute(VIEWPORT_STATUS_ATTRIBUTE, readyState);\n this.callback({ t: \"readystatechange\" });\n }\n }\n\n loadPublication(command: Base.JSON): Task.Result<boolean> {\n Profile.profiler.registerStartTiming(\"beforeRender\");\n this.setReadyState(Constants.ReadyState.LOADING);\n const url = command[\"url\"] as string;\n const fragment = command[\"fragment\"] as string | null;\n const haveZipMetadata = !!command[\"zipmeta\"];\n const authorStyleSheet = command[\"authorStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n const userStyleSheet = command[\"userStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n this.viewport = null;\n const frame: Task.Frame<boolean> = Task.newFrame(\"loadPublication\");\n const self = this;\n self.configure(command).then(() => {\n const store = new Epub.EPUBDocStore();\n store.init(authorStyleSheet, userStyleSheet).then(() => {\n const pubURL = Base.resolveURL(\n Base.convertSpecialURL(url),\n self.window.location.href,\n );\n self.packageURL = [pubURL];\n store.loadPubDoc(pubURL, haveZipMetadata).then((opf) => {\n if (opf) {\n self.opf = opf;\n self.render(fragment).then(() => {\n frame.finish(true);\n });\n } else {\n frame.finish(false);\n }\n });\n });\n });\n return frame.result();\n }\n\n loadXML(command: Base.JSON): Task.Result<boolean> {\n Profile.profiler.registerStartTiming(\"beforeRender\");\n this.setReadyState(Constants.ReadyState.LOADING);\n const params: SingleDocumentParam[] = command[\"url\"];\n const doc = command[\"document\"] as Document;\n const fragment = command[\"fragment\"] as string | null;\n const authorStyleSheet = command[\"authorStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n const userStyleSheet = command[\"userStyleSheet\"] as {\n url: string | null;\n text: string | null;\n }[];\n\n // force relayout\n this.viewport = null;\n const frame: Task.Frame<boolean> = Task.newFrame(\"loadXML\");\n const self = this;\n self.configure(command).then(() => {\n const store = new Epub.EPUBDocStore();\n store.init(authorStyleSheet, userStyleSheet).then(() => {\n const resolvedParams: Epub.OPFItemParam[] = params.map((p, index) => ({\n url: Base.resolveURL(\n Base.convertSpecialURL(p.url),\n self.window.location.href,\n ),\n index,\n startPage: p.startPage,\n skipPagesBefore: p.skipPagesBefore,\n }));\n self.packageURL = resolvedParams.map((p) => p.url);\n self.opf = new Epub.OPFDoc(store, \"\");\n self.opf.initWithChapters(resolvedParams, doc).then(() => {\n self.render(fragment).then(() => {\n frame.finish(true);\n });\n });\n });\n });\n return frame.result();\n }\n\n private render(fragment?: string | null): Task.Result<boolean> {\n this.cancelRenderingTask();\n const self = this;\n let cont: Task.Result<boolean>;\n if (fragment) {\n cont = this.opf.resolveFragment(fragment).thenAsync((position) => {\n self.pagePosition = position;\n return Task.newResult(true);\n });\n } else {\n cont = Task.newResult(true);\n }\n return cont.thenAsync(() => {\n Profile.profiler.registerEndTiming(\"beforeRender\");\n return self.resize();\n });\n }\n\n private resolveLength(specified: string): number {\n const value = parseFloat(specified);\n const unitPattern = /[a-z]+$/;\n let matched: RegExpMatchArray;\n if (\n typeof specified === \"string\" &&\n (matched = specified.match(unitPattern))\n ) {\n const unit = matched[0];\n if (unit === \"em\" || unit === \"rem\") {\n return value * this.fontSize;\n }\n if (unit === \"ex\") {\n return (\n (value * Exprs.defaultUnitSizes[\"ex\"] * this.fontSize) /\n Exprs.defaultUnitSizes[\"em\"]\n );\n }\n const unitSize = Exprs.defaultUnitSizes[unit];\n if (unitSize) {\n return value * unitSize;\n }\n }\n return value;\n }\n\n configure(command: Base.JSON): Task.Result<boolean> {\n if (typeof command[\"autoresize\"] == \"boolean\") {\n if (command[\"autoresize\"]) {\n this.viewportSize = null;\n this.window.addEventListener(\"resize\", this.resizeListener, false);\n this.needResize = true;\n } else {\n this.window.removeEventListener(\"resize\", this.resizeListener, false);\n }\n }\n if (typeof command[\"fontSize\"] == \"number\") {\n const fontSize = command[\"fontSize\"] as number;\n if (fontSize >= 5 && fontSize <= 72 && this.fontSize != fontSize) {\n this.fontSize = fontSize;\n this.needResize = true;\n }\n }\n if (typeof command[\"viewport\"] == \"object\" && command[\"viewport\"]) {\n const vp = command[\"viewport\"];\n const viewportSize = {\n marginLeft: this.resolveLength(vp[\"margin-left\"]) || 0,\n marginRight: this.resolveLength(vp[\"margin-right\"]) || 0,\n marginTop: this.resolveLength(vp[\"margin-top\"]) || 0,\n marginBottom: this.resolveLength(vp[\"margin-bottom\"]) || 0,\n width: this.resolveLength(vp[\"width\"]) || 0,\n height: this.resolveLength(vp[\"height\"]) || 0,\n };\n if (viewportSize.width >= 200 || viewportSize.height >= 200) {\n this.window.removeEventListener(\"resize\", this.resizeListener, false);\n this.viewportSize = viewportSize;\n this.needResize = true;\n }\n }\n if (typeof command[\"hyphenate\"] == \"boolean\") {\n this.pref.hyphenate = command[\"hyphenate\"];\n this.needResize = true;\n }\n if (typeof command[\"horizontal\"] == \"boolean\") {\n this.pref.horizontal = command[\"horizontal\"];\n this.needResize = true;\n }\n if (typeof command[\"nightMode\"] == \"boolean\") {\n this.pref.nightMode = command[\"nightMode\"];\n this.needResize = true;\n }\n if (typeof command[\"lineHeight\"] == \"number\") {\n this.pref.lineHeight = command[\"lineHeight\"];\n this.needResize = true;\n }\n if (typeof command[\"columnWidth\"] == \"number\") {\n this.pref.columnWidth = command[\"columnWidth\"];\n this.needResize = true;\n }\n if (typeof command[\"fontFamily\"] == \"string\") {\n this.pref.fontFamily = command[\"fontFamily\"];\n this.needResize = true;\n }\n if (typeof command[\"load\"] == \"boolean\") {\n this.waitForLoading = command[\"load\"]; // Load images (and other resources) on the page.\n }\n if (typeof command[\"renderAllPages\"] == \"boolean\") {\n this.renderAllPages = command[\"renderAllPages\"];\n }\n // for backward compatibility\n if (typeof command[\"userAgentRootURL\"] == \"string\") {\n Base.setBaseURL(command[\"userAgentRootURL\"].replace(/resources\\/?$/, \"\"));\n Base.setResourceBaseURL(command[\"userAgentRootURL\"]);\n }\n if (typeof command[\"rootURL\"] == \"string\") {\n Base.setBaseURL(command[\"rootURL\"]);\n Base.setResourceBaseURL(`${Base.baseURL}resources/`);\n }\n if (\n typeof command[\"pageViewMode\"] == \"string\" &&\n command[\"pageViewMode\"] !== this.pageViewMode\n ) {\n this.pageViewMode = command[\"pageViewMode\"] as PageViewMode;\n this.needResize = true;\n }\n if (\n typeof command[\"pageBorder\"] == \"number\" &&\n command[\"pageBorder\"] !== this.pref.pageBorder\n ) {\n // Force relayout\n this.viewport = null;\n this.pref.pageBorder = command[\"pageBorder\"];\n this.needResize = true;\n }\n if (typeof command[\"zoom\"] == \"number\" && command[\"zoom\"] !== this.zoom) {\n this.zoom = command[\"zoom\"];\n this.needRefresh = true;\n }\n if (\n typeof command[\"fitToScreen\"] == \"boolean\" &&\n command[\"fitToScreen\"] !== this.fitToScreen\n ) {\n this.fitToScreen = command[\"fitToScreen\"];\n this.needRefresh = true;\n }\n if (\n typeof command[\"defaultPaperSize\"] == \"object\" &&\n typeof command[\"defaultPaperSize\"].width == \"number\" &&\n typeof command[\"defaultPaperSize\"].height == \"number\"\n ) {\n this.viewport = null;\n this.pref.defaultPaperSize = command[\"defaultPaperSize\"];\n this.needResize = true;\n }\n this.configurePlugins(command);\n return Task.newResult(true);\n }\n\n configurePlugins(command: Base.JSON) {\n const hooks: Plugin.ConfigurationHook[] = Plugin.getHooksForName(\n Plugin.HOOKS.CONFIGURATION,\n );\n hooks.forEach((hook) => {\n const result = hook(command);\n this.needResize = result.needResize || this.needResize;\n this.needRefresh = result.needRefresh || this.needRefresh;\n });\n }\n\n /**\n * Refresh view when a currently displayed page is replaced (by re-layout\n * caused by cross reference resolutions)\n */\n pageReplacedListener(evt: Base.Event) {\n const currentPage = this.currentPage;\n const spread = this.currentSpread;\n const target = evt.target;\n if (spread) {\n if (spread.left === target || spread.right === target) {\n this.showCurrent(evt.newPage);\n }\n } else if (currentPage === evt.target) {\n this.showCurrent(evt.newPage);\n }\n }\n\n /**\n * Iterate through currently displayed pages and do something\n */\n private forCurrentPages(fn: (p1: Vtree.Page) => any) {\n const pages = [];\n if (this.currentPage) {\n pages.push(this.currentPage);\n }\n if (this.currentSpread) {\n pages.push(this.currentSpread.left);\n pages.push(this.currentSpread.right);\n }\n pages.forEach((page) => {\n if (page) {\n fn(page);\n }\n });\n }\n\n private removePageListeners() {\n this.forCurrentPages((page) => {\n page.removeEventListener(\"hyperlink\", this.hyperlinkListener, false);\n page.removeEventListener(\"replaced\", this.pageReplacedListener, false);\n });\n }\n\n /**\n * Hide current pages (this.currentPage, this.currentSpread)\n */\n private hidePages() {\n this.removePageListeners();\n this.forCurrentPages((page) => {\n Base.setCSSProperty(page.container, \"display\", \"none\");\n page.container.setAttribute(\"aria-hidden\", \"true\");\n });\n this.currentPage = null;\n this.currentSpread = null;\n }\n\n private showSinglePage(page: Vtree.Page) {\n page.addEventListener(\"hyperlink\", this.hyperlinkListener, false);\n page.addEventListener(\"replaced\", this.pageReplacedListener, false);\n Base.setCSSProperty(page.container, \"visibility\", \"visible\");\n Base.setCSSProperty(page.container, \"display\", \"block\");\n page.container.setAttribute(\"aria-hidden\", \"false\");\n }\n\n private showPage(page: Vtree.Page): void {\n this.hidePages();\n this.currentPage = page;\n page.container.style.marginLeft = \"\";\n page.container.style.marginRight = \"\";\n this.showSinglePage(page);\n }\n\n private showSpread(spread: Vtree.Spread) {\n this.hidePages();\n this.currentSpread = spread;\n if (spread.left && spread.right) {\n // Adjust spread horizontal alignment when left/right page widths differ\n let leftWidth = parseFloat(spread.left.container.style.width);\n let rightWidth = parseFloat(spread.right.container.style.width);\n if (leftWidth && rightWidth && leftWidth !== rightWidth) {\n if (leftWidth < rightWidth) {\n spread.left.container.style.marginLeft = `${rightWidth -\n leftWidth}px`;\n } else {\n spread.right.container.style.marginRight = `${leftWidth -\n rightWidth}px`;\n }\n }\n }\n if (spread.left) {\n this.showSinglePage(spread.left);\n if (!spread.right) {\n spread.left.container.setAttribute(\n \"data-vivliostyle-unpaired-page\",\n true,\n );\n } else {\n spread.left.container.removeAttribute(\"data-vivliostyle-unpaired-page\");\n }\n }\n if (spread.right) {\n this.showSinglePage(spread.right);\n if (!spread.left) {\n spread.right.container.setAttribute(\n \"data-vivliostyle-unpaired-page\",\n true,\n );\n } else {\n spread.right.container.removeAttribute(\n \"data-vivliostyle-unpaired-page\",\n );\n }\n }\n }\n\n private reportPosition(): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\"reportPosition\");\n const self = this;\n Asserts.assert(self.pagePosition);\n self.opf\n .getCFI(this.pagePosition.spineIndex, this.pagePosition.offsetInItem)\n .then((cfi) => {\n const page = self.currentPage;\n const r =\n self.waitForLoading && page.fetchers.length > 0\n ? TaskUtil.waitForFetchers(page.fetchers)\n : Task.newResult(true);\n r.then(() => {\n self.sendLocationNotification(page, cfi).thenFinish(frame);\n });\n });\n return frame.result();\n }\n\n private createViewport(): Vgen.Viewport {\n const viewportElement = this.viewportElement;\n if (this.viewportSize) {\n const vs = this.viewportSize;\n viewportElement.style.marginLeft = `${vs.marginLeft}px`;\n viewportElement.style.marginRight = `${vs.marginRight}px`;\n viewportElement.style.marginTop = `${vs.marginTop}px`;\n viewportElement.style.marginBottom = `${vs.marginBottom}px`;\n return new Vgen.Viewport(\n this.window,\n this.fontSize,\n viewportElement,\n vs.width,\n vs.height,\n );\n } else {\n return new Vgen.Viewport(this.window, this.fontSize, viewportElement);\n }\n }\n\n private resolveSpreadView(viewport: Vgen.Viewport): boolean {\n switch (this.pageViewMode) {\n case PageViewMode.SINGLE_PAGE:\n return false;\n case PageViewMode.SPREAD:\n return true;\n case PageViewMode.AUTO_SPREAD:\n default:\n // wide enough for a pair of pages of A/B paper sizes, but not too\n // narrow\n return viewport.width / viewport.height >= 1.45 && viewport.width > 800;\n }\n }\n\n private updateSpreadView(spreadView: boolean) {\n this.pref.spreadView = spreadView;\n this.viewportElement.setAttribute(\n VIEWPORT_SPREAD_VIEW_ATTRIBUTE,\n spreadView.toString(),\n );\n }\n\n private sizeIsGood(): boolean {\n const viewport = this.createViewport();\n const spreadView = this.resolveSpreadView(viewport);\n const spreadViewChanged = this.pref.spreadView !== spreadView;\n this.updateSpreadView(spreadView);\n if (\n this.viewportSize ||\n !this.viewport ||\n this.viewport.fontSize != this.fontSize\n ) {\n return false;\n }\n if (\n !spreadViewChanged &&\n viewport.width == this.viewport.width &&\n viewport.height == this.viewport.height\n ) {\n return true;\n }\n\n if (\n !spreadViewChanged &&\n viewport.width == this.viewport.width &&\n viewport.height != this.viewport.height &&\n /Android|iPhone|iPad|iPod/.test(navigator.userAgent)\n ) {\n // On mobile browsers, the viewport height may change unexpectedly\n // when soft keyboard appears or tab/address bar auto-hide occurs,\n // so ignore resizing in this condition.\n return true;\n }\n\n if (\n this.opfView &&\n this.opfView.hasPages() &&\n !this.opfView.hasAutoSizedPages()\n ) {\n this.viewport.width = viewport.width;\n this.viewport.height = viewport.height;\n this.needRefresh = true;\n return true;\n }\n return false;\n }\n\n private setPageSize(\n pageSize: { width: number; height: number },\n pageSheetSize: { [key: string]: { width: number; height: number } },\n spineIndex: number,\n pageIndex: number,\n ) {\n this.pageSizes[pageIndex] = pageSize;\n this.setPageSizePageRules(pageSheetSize, spineIndex, pageIndex);\n }\n\n private setPageSizePageRules(\n pageSheetSize: { [key: string]: { width: number; height: number } },\n spineIndex: number,\n pageIndex: number,\n ) {\n if (!this.pageSheetSizeAlreadySet && this.pageRuleStyleElement) {\n let styleText = \"\";\n Object.keys(pageSheetSize).forEach((selector) => {\n styleText += `@page ${selector}{margin:0;size:`;\n const size = pageSheetSize[selector];\n styleText += `${size.width}px ${size.height}px;}`;\n });\n this.pageRuleStyleElement.textContent = styleText;\n this.pageSheetSizeAlreadySet = true;\n }\n }\n\n removePageSizePageRules() {\n if (this.pageRuleStyleElement) {\n this.pageRuleStyleElement.textContent = \"\";\n this.pageSheetSizeAlreadySet = false;\n }\n }\n\n private reset(): void {\n let tocVisible = false;\n let tocAutohide = false;\n if (this.opfView) {\n tocVisible = this.opfView.isTOCVisible();\n tocAutohide = this.opfView.tocAutohide;\n this.opfView.hideTOC();\n this.opfView.removeRenderedPages();\n }\n this.removePageSizePageRules();\n this.viewport = this.createViewport();\n this.viewport.resetZoom();\n this.opfView = new Epub.OPFView(\n this.opf,\n this.viewport,\n this.fontMapper,\n this.pref,\n this.setPageSize.bind(this),\n );\n if (tocVisible) {\n this.sendCommand({ a: \"toc\", v: \"show\", autohide: tocAutohide });\n }\n }\n\n /**\n * Show current page or spread depending on the setting\n * (this.pref.spreadView).\n * @param sync If true, get the necessary page synchronously (not waiting\n * another rendering task)\n */\n private showCurrent(page: Vtree.Page, sync?: boolean): Task.Result<null> {\n this.needRefresh = false;\n this.removePageListeners();\n const self = this;\n if (this.pref.spreadView) {\n return this.opfView\n .getSpread(this.pagePosition, sync)\n .thenAsync((spread) => {\n self.showSpread(spread);\n self.setSpreadZoom(spread);\n self.currentPage = page;\n return Task.newResult(null);\n });\n } else {\n this.showPage(page);\n this.setPageZoom(page);\n this.currentPage = page;\n return Task.newResult(null);\n }\n }\n\n setPageZoom(page: Vtree.Page) {\n const zoom = this.getAdjustedZoomFactor(page.dimensions);\n this.viewport.zoom(page.dimensions.width, page.dimensions.height, zoom);\n }\n\n setSpreadZoom(spread: Vtree.Spread) {\n const dim = this.getSpreadDimensions(spread);\n this.viewport.zoom(dim.width, dim.height, this.getAdjustedZoomFactor(dim));\n }\n\n /**\n * @returns adjusted zoom factor\n */\n getAdjustedZoomFactor(pageDimension: {\n width: number;\n height: number;\n }): number {\n return this.fitToScreen\n ? this.calculateZoomFactorToFitInsideViewPort(pageDimension)\n : this.zoom;\n }\n\n /**\n * Returns width and height of the spread, including the margin between pages.\n */\n getSpreadDimensions(spread: Vtree.Spread): { width: number; height: number } {\n let width = 0;\n let height = 0;\n if (spread.left) {\n width += spread.left.dimensions.width;\n height = spread.left.dimensions.height;\n }\n if (spread.right) {\n width += spread.right.dimensions.width;\n height = Math.max(height, spread.right.dimensions.height);\n }\n if (spread.left && spread.right) {\n width += this.pref.pageBorder * 2;\n // Adjust spread horizontal alignment when left/right page widths differ\n width += Math.abs(\n spread.left.dimensions.width - spread.right.dimensions.width,\n );\n }\n return { width, height };\n }\n\n /**\n * Returns zoom factor corresponding to the specified zoom type.\n */\n queryZoomFactor(type: ZoomType): number {\n if (!this.currentPage) {\n throw new Error(\"no page exists.\");\n }\n switch (type) {\n case ZoomType.FIT_INSIDE_VIEWPORT: {\n let pageDim: { width: number; height: number };\n if (this.pref.spreadView) {\n Asserts.assert(this.currentSpread);\n pageDim = this.getSpreadDimensions(this.currentSpread);\n } else {\n pageDim = this.currentPage.dimensions;\n }\n return this.calculateZoomFactorToFitInsideViewPort(pageDim);\n }\n default:\n throw new Error(`unknown zoom type: ${type}`);\n }\n }\n\n /**\n * @returns zoom factor to fit inside viewport\n */\n calculateZoomFactorToFitInsideViewPort(pageDimension: {\n width: number;\n height: number;\n }): number {\n const widthZoom = this.viewport.width / pageDimension.width;\n const heightZoom = this.viewport.height / pageDimension.height;\n return Math.min(widthZoom, heightZoom);\n }\n\n private cancelRenderingTask() {\n if (this.renderTask) {\n this.renderTask.interrupt(new RenderingCanceledError());\n }\n this.renderTask = null;\n }\n\n resize(): Task.Result<boolean> {\n this.needResize = false;\n this.needRefresh = false;\n if (this.sizeIsGood()) {\n return Task.newResult(true);\n }\n const self = this;\n this.setReadyState(Constants.ReadyState.LOADING);\n this.cancelRenderingTask();\n const resizeTask = Task.currentTask()\n .getScheduler()\n .run(() =>\n Task.handle(\n \"resize\",\n (frame) => {\n if (!self.opf) {\n frame.finish(false);\n return;\n }\n self.renderTask = resizeTask;\n Profile.profiler.registerStartTiming(\"render (resize)\");\n self.reset();\n if (self.pagePosition) {\n // When resizing, do not use the current page index, for a page\n // index corresponding to the current position in the document\n // (offsetInItem) can change due to different layout caused by\n // different viewport size.\n\n // Update(2019-03): to avoid unexpected page move (first page to next),\n // keep pageIndex == 0 when offsetInItem == 0\n if (\n !(\n self.pagePosition.pageIndex == 0 &&\n self.pagePosition.offsetInItem == 0\n )\n ) {\n self.pagePosition.pageIndex = -1;\n }\n }\n\n // epageCount counting depends renderAllPages mode\n self.opf.setEPageCountMode(self.renderAllPages);\n\n // With renderAllPages option specified, the rendering is\n // performed after the initial page display, otherwise users are\n // forced to wait the rendering finish in front of a blank page.\n self.opfView\n .renderPagesUpto(self.pagePosition, !self.renderAllPages)\n .then((result) => {\n if (!result) {\n frame.finish(false);\n return;\n }\n self.pagePosition = result.position;\n self.showCurrent(result.page, true).then(() => {\n self.setReadyState(Constants.ReadyState.INTERACTIVE);\n\n self.opf\n .countEPages((epageCount) => {\n const notification = {\n t: \"nav\",\n epageCount: epageCount,\n first: self.currentPage.isFirstPage,\n last: self.currentPage.isLastPage,\n metadata: self.opf.metadata,\n docTitle:\n self.opf.spine[self.pagePosition.spineIndex].title,\n };\n if (\n self.currentPage.isFirstPage ||\n (self.pagePosition.pageIndex == 0 &&\n self.opf.spine[self.pagePosition.spineIndex].epage)\n ) {\n notification[\"epage\"] =\n self.opf.spine[self.pagePosition.spineIndex].epage;\n }\n self.callback(notification);\n })\n .then(() => {\n self.reportPosition().then((p) => {\n const r = self.renderAllPages\n ? self.opfView.renderAllPages()\n : Task.newResult(null);\n r.then(() => {\n if (self.renderTask === resizeTask) {\n self.renderTask = null;\n }\n Profile.profiler.registerEndTiming(\"render (resize)\");\n if (self.renderAllPages) {\n self.setReadyState(Constants.ReadyState.COMPLETE);\n }\n self.callback({ t: \"loaded\" });\n frame.finish(p);\n });\n });\n });\n });\n });\n },\n (frame, err) => {\n if (err instanceof RenderingCanceledError) {\n Profile.profiler.registerEndTiming(\"render (resize)\");\n Logging.logger.debug(err.message);\n } else {\n throw err;\n }\n },\n ),\n );\n return Task.newResult(true);\n }\n\n private sendLocationNotification(\n page: Vtree.Page,\n cfi: string | null,\n ): Task.Result<boolean> {\n const frame: Task.Frame<boolean> = Task.newFrame(\n \"sendLocationNotification\",\n );\n const notification = {\n t: \"nav\",\n first: page.isFirstPage,\n last: page.isLastPage,\n metadata: this.opf.metadata,\n docTitle: this.opf.spine[page.spineIndex].title,\n };\n const self = this;\n this.opf\n .getEPageFromPosition(self.pagePosition as Epub.Position)\n .then((epage) => {\n notification[\"epage\"] = epage;\n notification[\"epageCount\"] = self.opf.epageCount;\n if (cfi) {\n notification[\"cfi\"] = cfi;\n }\n self.callback(notification);\n frame.finish(true);\n });\n return frame.result();\n }\n\n getCurrentPageProgression(): Constants.PageProgression | null {\n return this.opfView\n ? this.opfView.getCurrentPageProgression(this.pagePosition)\n : null;\n }\n\n moveTo(command: Base.JSON): Task.Result<boolean> {\n let method: () => Task.Result<Epub.PageAndPosition>;\n const self = this;\n if (\n this.readyState !== Constants.ReadyState.COMPLETE &&\n command[\"where\"] !== \"next\"\n ) {\n this.setReadyState(Constants.ReadyState.LOADING);\n }\n if (typeof command[\"where\"] == \"string\") {\n let m: (\n position: Epub.Position,\n sync: boolean,\n ) => Task.Result<Epub.PageAndPosition>;\n switch (command[\"where\"]) {\n case \"next\":\n m = this.pref.spreadView\n ? this.opfView.nextSpread\n : this.opfView.nextPage;\n break;\n case \"previous\":\n m = this.pref.spreadView\n ? this.opfView.previousSpread\n : this.opfView.previousPage;\n break;\n case \"last\":\n m = this.opfView.lastPage;\n break;\n case \"first\":\n m = this.opfView.firstPage;\n break;\n default:\n return Task.newResult(true);\n }\n if (m) {\n method = () =>\n m.call(self.opfView, self.pagePosition, !self.renderAllPages);\n }\n } else if (typeof command[\"epage\"] == \"number\") {\n const epage = command[\"epage\"] as number;\n method = () =>\n self.opfView.navigateToEPage(\n epage,\n self.pagePosition,\n !self.renderAllPages,\n );\n } else if (typeof command[\"url\"] == \"string\") {\n const url = command[\"url\"] as string;\n method = () =>\n self.opfView.navigateTo(url, self.pagePosition, !self.renderAllPages);\n } else {\n return Task.newResult(true);\n }\n const frame: Task.Frame<boolean> = Task.newFrame(\"moveTo\");\n method.call(self.opfView).then((result) => {\n let cont: Task.Result<boolean>;\n if (result) {\n self.pagePosition = result.position;\n const innerFrame: Task.Frame<boolean> = Task.newFrame(\n \"moveTo.showCurrent\",\n );\n cont = innerFrame.result();\n self.showCurrent(result.page, !self.renderAllPages).then(() => {\n self.reportPosition().thenFinish(innerFrame);\n });\n } else {\n cont = Task.newResult(true);\n }\n cont.then((res) => {\n if (self.readyState === Constants.ReadyState.LOADING) {\n self.setReadyState(Constants.ReadyState.INTERACTIVE);\n }\n frame.finish(res);\n });\n });\n return frame.result();\n }\n\n showTOC(command: Base.JSON): Task.Result<boolean> {\n const autohide = !!command[\"autohide\"];\n const visibility = command[\"v\"];\n const currentVisibility = this.opfView.isTOCVisible();\n const changeAutohide =\n autohide != this.opfView.tocAutohide && visibility != \"hide\";\n if (currentVisibility) {\n if (visibility == \"show\" && !changeAutohide) {\n return Task.newResult(true);\n }\n } else {\n if (visibility == \"hide\") {\n return Task.newResult(true);\n }\n }\n if (currentVisibility && visibility != \"show\") {\n this.opfView.hideTOC();\n return Task.newResult(true);\n } else {\n const self = this;\n const frame: Task.Frame<boolean> = Task.newFrame(\"showTOC\");\n this.opfView.showTOC(autohide).then((page) => {\n if (page) {\n if (changeAutohide) {\n page.listeners = {};\n }\n if (autohide) {\n const hideTOC = () => {\n self.opfView.hideTOC();\n };\n page.addEventListener(\"hyperlink\", hideTOC, false);\n // page.container.addEventListener(\"click\", hideTOC, false);\n }\n page.addEventListener(\"hyperlink\", self.hyperlinkListener, false);\n }\n frame.finish(true);\n });\n return frame.result();\n }\n }\n\n runCommand(command: Base.JSON): Task.Result<boolean> {\n const self = this;\n const actionName = command[\"a\"] || \"\";\n return Task.handle(\n \"runCommand\",\n (frame) => {\n const action = self.actions[actionName];\n if (action) {\n action.call(self, command).then(() => {\n self.callback({ t: \"done\", a: actionName });\n frame.finish(true);\n });\n } else {\n Logging.logger.error(\"No such action:\", actionName);\n frame.finish(true);\n }\n },\n (frame, err) => {\n Logging.logger.error(err, \"Error during action:\", actionName);\n frame.finish(true);\n },\n );\n }\n\n initEmbed(cmd: Base.JSON | string): void {\n let command = maybeParse(cmd);\n let continuation: Task.Continuation<boolean> | null = null;\n const viewer = this;\n Task.start(() => {\n const frame: Task.Frame<boolean> = Task.newFrame(\"commandLoop\");\n const scheduler = Task.currentTask().getScheduler();\n viewer.hyperlinkListener = (evt) => {\n const hrefEvent = evt as Vtree.PageHyperlinkEvent;\n const internal =\n hrefEvent.href.charAt(0) === \"#\" ||\n viewer.packageURL.some(\n (url) => hrefEvent.href.substr(0, url.length) == url,\n );\n if (internal) {\n evt.preventDefault();\n const msg = {\n t: \"hyperlink\",\n href: hrefEvent.href,\n internal: internal,\n };\n scheduler.run(() => {\n viewer.callback(msg);\n return Task.newResult(true);\n });\n }\n };\n frame\n .loopWithFrame((loopFrame) => {\n if (viewer.needResize) {\n viewer.resize().then(() => {\n loopFrame.continueLoop();\n });\n } else if (viewer.needRefresh) {\n if (viewer.currentPage) {\n viewer.showCurrent(viewer.currentPage).then(() => {\n loopFrame.continueLoop();\n });\n }\n } else if (command) {\n const cmd = command;\n command = null;\n viewer.runCommand(cmd).then(() => {\n loopFrame.continueLoop();\n });\n } else {\n const frameInternal: Task.Frame<boolean> = Task.newFrame(\n \"waitForCommand\",\n );\n continuation = frameInternal.suspend(self);\n frameInternal.result().then(() => {\n loopFrame.continueLoop();\n });\n }\n })\n .thenFinish(frame);\n return frame.result();\n });\n viewer.kick = () => {\n const cont = continuation;\n if (cont) {\n continuation = null;\n cont.schedule(true);\n }\n };\n viewer.sendCommand = (cmd) => {\n if (command) {\n return false;\n }\n command = maybeParse(cmd);\n viewer.kick();\n return true;\n };\n this.window[\"adapt_command\"] = viewer.sendCommand;\n }\n}\n\n/**\n * @enum {string}\n */\nexport enum ZoomType {\n FIT_INSIDE_VIEWPORT = \"fit inside viewport\",\n}\n\n/**\n * Error representing that the rendering has been canceled.\n */\nclass RenderingCanceledError extends Error {\n name: string = \"RenderingCanceledError\";\n message: string = \"Page rendering has been canceled\";\n stack: string;\n\n constructor() {\n super();\n // Set the prototype explicitly.\n // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, RenderingCanceledError.prototype);\n this.stack = new Error().stack;\n }\n}\n\nexport function maybeParse(cmd: any): Base.JSON {\n if (typeof cmd == \"string\") {\n return Base.stringToJSON(cmd);\n }\n return cmd;\n}\n","/**\n * Copyright 2015 Trim-marks Inc.\n * Copyright 2018 Vivliostyle Foundation\n *\n * Vivliostyle.js is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Vivliostyle.js is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Vivliostyle.js. If not, see <http://www.gnu.org/licenses/>.\n *\n * @fileoverview CoreViewer - Vivliostyle CoreViewer class\n */\nimport * as AdaptiveViewer from \"./adaptive-viewer\";\nimport * as Base from \"./base\";\nimport * as Constants from \"./constants\";\nimport * as Profile from \"./profile\";\n\nexport interface Payload {\n type: string;\n internal: boolean;\n href: string;\n content: string;\n cfi: string;\n first: boolean;\n last: boolean;\n epage: unknown;\n epageCount: number;\n metadata: unknown;\n docTitle: string;\n}\n\nconst PageProgression = Constants.PageProgression;\n\n/**\n * Viewer settings that must be passed to Viewer's constructor.\n * - userAgentRootURL: URL of a directory from which viewer resource files\n * (under resources/ directory in the source repository) are served.\n * - viewportElement: An element used as the viewport of the displayed contents.\n * - window: Window object. If omitted, current `window` is used.\n * - debug: Debug flag.\n */\nexport type CoreViewerSettings = {\n userAgentRootURL?: string;\n viewportElement: HTMLElement;\n window?: Window;\n debug?: boolean;\n};\n\n/**\n * Viewer options that can be set after the Viewer object is constructed.\n * - autoResize: Run layout again when the window is resized. default: true\n * - fontSize: Default font size (px). default: 16\n * - pageBorderWidth: Width of a border between two pages in a single\n * spread (px). Effective only in spread view mode. default: 1\n * - renderAllPages: Render all pages at the document load time. default: true\n * - pageViewMode: Page view mode (singlePage / spread / autoSpread).\n * default: singlePage\n * - zoom: Zoom factor with which pages are displayed. default: 1\n * - fitToScreen: Auto adjust zoom factor to fit the screen. default: false\n * - defaultPaperSize: Default paper size in px. Effective when `@page` size\n * is set to auto. default: undefined (means the windows size is used as\n * paper size).\n */\nexport type CoreViewerOptions = {\n autoResize?: boolean;\n fontSize?: number;\n pageBorderWidth?: number;\n renderAllPages?: boolean;\n pageViewMode?: AdaptiveViewer.PageViewMode;\n zoom?: number;\n fitToScreen?: boolean;\n defaultPaperSize?: { width: number; height: number };\n};\n\nfunction getDefaultViewerOptions(): CoreViewerOptions {\n return {\n autoResize: true,\n fontSize: 16,\n pageBorderWidth: 1,\n renderAllPages: true,\n pageViewMode: AdaptiveViewer.PageViewMode.AUTO_SPREAD,\n zoom: 1,\n fitToScreen: false,\n defaultPaperSize: undefined,\n };\n}\n\nfunction convertViewerOptions(options: CoreViewerOptions): object {\n const converted = {};\n Object.keys(options).forEach((key) => {\n const v = options[key];\n switch (key) {\n case \"autoResize\":\n converted[\"autoresize\"] = v;\n break;\n case \"pageBorderWidth\":\n converted[\"pageBorder\"] = v;\n break;\n default:\n converted[key] = v;\n }\n });\n return converted;\n}\n\n/**\n * Options for the displayed document.\n * - documentObject: Document object for the document. If provided, it is used\n * directly without parsing the source again.\n * - fragment: Fragmentation identifier (EPUB CFI) of the location in the\n * document which is to be displayed.\n * - authorStyleSheet: An array of author style sheets to be injected after all\n * author style sheets referenced from the document. A single stylesheet may\n * be a URL of the style sheet or a text content of the style sheet.\n * - userStyleSheet: An array of user style sheets to be injected.\n * A single stylesheet may be a URL of the style sheet or a text content of\n * the style sheet.\n */\nexport type DocumentOptions = {\n documentObject?: Document;\n fragment?: string;\n authorStyleSheet?: { url?: string; text?: string }[];\n userStyleSheet?: { url?: string; text?: string }[];\n};\n\n/**\n * Options for a single source document.\n * - url: URL of the document.\n * - startPage: If specified, the `page` page-based counter is set to the\n * specified value on the first page of the document. It is equivalent to\n * specifying `counter-reset: page [specified value - 1]` on that page.\n * - skipPagesBefore: If specified, the `page` page-based counter is\n * incremented by the specified value *before* updating page-based counters\n * on the first page of the document.\n * This option is ignored if `startPageNumber` option is also specified.\n */\nexport type SingleDocumentOptions =\n | string\n | {\n url: string;\n startPage?: number;\n skipPagesBefore?: number;\n };\n\n/**\n * Vivliostyle Viewer class.\n */\nexport class CoreViewer {\n private initialized: boolean = false;\n private adaptViewer_: AdaptiveViewer.AdaptiveViewer;\n private options: CoreViewerOptions;\n private eventTarget: Base.SimpleEventTarget;\n readyState: Constants.ReadyState;\n\n constructor(\n private readonly settings: CoreViewerSettings,\n opt_options?: CoreViewerOptions,\n ) {\n Constants.setDebug(settings.debug);\n this.adaptViewer_ = new AdaptiveViewer.AdaptiveViewer(\n settings[\"window\"] || window,\n settings[\"viewportElement\"],\n \"main\",\n this.dispatcher.bind(this),\n );\n this.options = getDefaultViewerOptions();\n if (opt_options) {\n this.setOptions(opt_options);\n }\n this.eventTarget = new Base.SimpleEventTarget();\n Object.defineProperty(this, \"readyState\", {\n get() {\n return this.adaptViewer_.readyState;\n },\n });\n }\n\n /**\n * Set ViewerOptions to the viewer.\n */\n setOptions(options: CoreViewerOptions) {\n const command = Object.assign(\n { a: \"configure\" },\n convertViewerOptions(options),\n );\n this.adaptViewer_.sendCommand(command);\n Object.assign(this.options, options);\n }\n\n private dispatcher(msg: Base.JSON) {\n /** @dict */\n const event = { type: msg[\"t\"] };\n const o = msg as object;\n Object.keys(o).forEach((key) => {\n if (key !== \"t\") {\n event[key] = o[key];\n }\n });\n this.eventTarget.dispatchEvent(event);\n }\n\n /**\n * Add a listener function, which is invoked when the specified type of event\n * is dispatched.\n * @param type Event type.\n * @param listener Listener function.\n */\n addListener(type: string, listener: (payload: Payload) => void) {\n this.eventTarget.addEventListener(\n type,\n listener as Base.EventListener,\n false,\n );\n }\n\n /**\n * Remove an event listener.\n * @param type Event type.\n * @param listener Listener function.\n */\n removeListener(type: string, listener: (payload: Payload) => void) {\n this.eventTarget.removeEventListener(\n type,\n listener as Base.EventListener,\n false,\n );\n }\n\n /**\n * Load an HTML or XML document(s).\n */\n loadDocument(\n singleDocumentOptions: SingleDocumentOptions | SingleDocumentOptions[],\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n if (!singleDocumentOptions) {\n this.eventTarget.dispatchEvent({\n type: \"error\",\n content: \"No URL specified\",\n });\n }\n this.loadDocumentOrPublication(\n singleDocumentOptions,\n null,\n opt_documentOptions,\n opt_viewerOptions,\n );\n }\n\n /**\n * Load an EPUB/WebPub publication.\n */\n loadPublication(\n pubUrl: string,\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n if (!pubUrl) {\n this.eventTarget.dispatchEvent({\n type: \"error\",\n content: \"No URL specified\",\n });\n }\n this.loadDocumentOrPublication(\n null,\n pubUrl,\n opt_documentOptions,\n opt_viewerOptions,\n );\n }\n\n /**\n * Load an HTML or XML document, or an EPUB/WebPub publication.\n */\n private loadDocumentOrPublication(\n singleDocumentOptions:\n | SingleDocumentOptions\n | SingleDocumentOptions[]\n | null,\n pubUrl: string | null,\n opt_documentOptions?: DocumentOptions,\n opt_viewerOptions?: CoreViewerOptions,\n ) {\n const documentOptions = opt_documentOptions || {};\n\n function convertStyleSheetArray(arr) {\n if (arr) {\n return arr.map((s) => ({ url: s.url || null, text: s.text || null }));\n } else {\n return undefined;\n }\n }\n const authorStyleSheet = convertStyleSheetArray(\n documentOptions[\"authorStyleSheet\"],\n );\n const userStyleSheet = convertStyleSheetArray(\n documentOptions[\"userStyleSheet\"],\n );\n if (opt_viewerOptions) {\n Object.assign(this.options, opt_viewerOptions);\n }\n const command = Object.assign(\n {\n a: singleDocumentOptions ? \"loadXML\" : \"loadPublication\",\n userAgentRootURL: this.settings[\"userAgentRootURL\"],\n url: convertSingleDocumentOptions(singleDocumentOptions) || pubUrl,\n document: documentOptions[\"documentObject\"],\n fragment: documentOptions[\"fragment\"],\n authorStyleSheet: authorStyleSheet,\n userStyleSheet: userStyleSheet,\n },\n convertViewerOptions(this.options),\n );\n if (this.initialized) {\n this.adaptViewer_.sendCommand(command);\n } else {\n this.initialized = true;\n this.adaptViewer_.initEmbed(command);\n }\n }\n\n /**\n * Returns the current page progression of the viewer. If no document is\n * loaded, returns null.\n */\n getCurrentPageProgression(): Constants.PageProgression | null {\n return this.adaptViewer_.getCurrentPageProgression();\n }\n\n private resolveNavigation(nav: Navigation): Navigation {\n switch (nav) {\n case Navigation.LEFT:\n return this.getCurrentPageProgression() === PageProgression.LTR\n ? Navigation.PREVIOUS\n : Navigation.NEXT;\n case Navigation.RIGHT:\n return this.getCurrentPageProgression() === PageProgression.LTR\n ? Navigation.NEXT\n : Navigation.PREVIOUS;\n default:\n return nav;\n }\n }\n\n /**\n * Navigate to the specified page.\n */\n navigateToPage(nav: Navigation, opt_epage?: number) {\n if (nav === Navigation.EPAGE) {\n this.adaptViewer_.sendCommand({\n a: \"moveTo\",\n epage: opt_epage,\n });\n } else {\n this.adaptViewer_.sendCommand({\n a: \"moveTo\",\n where: this.resolveNavigation(nav),\n });\n }\n }\n\n /**\n * Navigate to the specified internal URL.\n */\n navigateToInternalUrl(url: string) {\n this.adaptViewer_.sendCommand({ a: \"moveTo\", url: url });\n }\n\n /**\n * @returns True if TOC is visible, false if hidden, null if TOC is unavailable\n */\n isTOCVisible(): boolean | null {\n if (\n this.adaptViewer_.opfView &&\n this.adaptViewer_.opfView.opf &&\n (this.adaptViewer_.opfView.opf.xhtmlToc ||\n this.adaptViewer_.opfView.opf.ncxToc)\n ) {\n return !!this.adaptViewer_.opfView.isTOCVisible();\n } else {\n return null;\n }\n }\n\n /**\n * Show or hide TOC box\n * @param opt_autohide If true, automatically hide when click TOC item\n * @param opt_show If true show TOC, false hide TOC. If null or undefined toggle TOC.\n */\n showTOC(opt_show?: boolean | null, opt_autohide?: boolean) {\n const visibility = opt_show == null ? \"toggle\" : opt_show ? \"show\" : \"hide\";\n this.adaptViewer_.sendCommand({\n a: \"toc\",\n v: visibility,\n autohide: opt_autohide,\n });\n }\n\n /**\n * Returns zoom factor corresponding to the specified zoom type.\n */\n queryZoomFactor(type: AdaptiveViewer.ZoomType): number {\n return this.adaptViewer_.queryZoomFactor(type);\n }\n\n getPageSizes(): { width: number; height: number }[] {\n return this.adaptViewer_.pageSizes;\n }\n}\n\nfunction convertSingleDocumentOptions(\n singleDocumentOptions: SingleDocumentOptions | SingleDocumentOptions[],\n): AdaptiveViewer.SingleDocumentParam[] | null {\n function toNumberOrNull(num: any): number | null {\n return typeof num === \"number\" ? num : null;\n }\n\n function convert(opt) {\n if (typeof opt === \"string\") {\n return {\n url: opt,\n startPage: null,\n skipPagesBefore: null,\n } as AdaptiveViewer.SingleDocumentParam;\n } else {\n return {\n url: opt[\"url\"],\n startPage: toNumberOrNull(opt[\"startPage\"]),\n skipPagesBefore: toNumberOrNull(opt[\"skipPagesBefore\"]),\n } as AdaptiveViewer.SingleDocumentParam;\n }\n }\n if (Array.isArray(singleDocumentOptions)) {\n return singleDocumentOptions.map(convert);\n } else if (singleDocumentOptions) {\n return [convert(singleDocumentOptions)];\n } else {\n return null;\n }\n}\n\n/**\n * @enum {string}\n */\nexport enum Navigation {\n PREVIOUS = \"previous\",\n NEXT = \"next\",\n LEFT = \"left\",\n RIGHT = \"right\",\n FIRST = \"first\",\n LAST = \"last\",\n EPAGE = \"epage\",\n}\n\nexport type ZoomType = AdaptiveViewer.ZoomType;\nexport const ZoomType = AdaptiveViewer.ZoomType;\n\nexport type PageViewMode = AdaptiveViewer.PageViewMode;\nexport const PageViewMode = AdaptiveViewer.PageViewMode;\n\nexport const viewer = {\n CoreViewer,\n PageViewMode,\n ZoomType,\n};\n\nProfile.profiler.forceRegisterEndTiming(\"load_vivliostyle\");\n","// Johannes Wilm\n// Vivliostyle Foundation\n\nimport * as CoreViewer from \"./core-viewer\";\nimport viewportCss from \"../../resources/vivliostyle-viewport.css\";\nimport viewportScreenCss from \"../../resources/vivliostyle-viewport-screen.css\";\n\ninterface IFrameWindowForPrint {\n printInstance?: VivliostylePrint;\n}\n\ninterface PrintConfig {\n title: string;\n printCallback: (iframeWin: Window) => void;\n hideIframe: boolean;\n removeIframe: boolean;\n}\n\nclass VivliostylePrint {\n htmlDoc: string;\n title: string;\n printCallback: (iframeWin: Window) => void;\n hideIframe: boolean;\n removeIframe: boolean;\n iframe: HTMLIFrameElement;\n iframeWin: Window;\n window: Window & typeof globalThis & IFrameWindowForPrint;\n\n constructor(\n htmlDoc: string,\n {\n title = \"\",\n printCallback = (iframeWin: Window) => iframeWin.print(),\n hideIframe = true,\n removeIframe = true,\n }: PrintConfig,\n ) {\n this.htmlDoc = htmlDoc;\n this.title = title;\n this.printCallback = printCallback;\n this.hideIframe = hideIframe;\n this.removeIframe = removeIframe;\n }\n\n init() {\n this.iframe = document.createElement(\"iframe\");\n\n if (this.hideIframe) {\n this.iframe.style.width = \"0\"; // We don't want the iframe to be seen, so we make it zero size with zero border.\n this.iframe.style.height = \"0\";\n this.iframe.style.borderWidth = \"0\";\n }\n\n this.window = window;\n this.window.printInstance = this;\n this.iframe.srcdoc = `\n <!DOCTYPE html>\n <html data-vivliostyle-paginated=\"true\">\n <head>\n <meta charset='utf-8'/>\n <meta name='viewport' content='width=device-width, initial-scale=1.0'/>\n <title>${this.title}</title>\n <style>${viewportCss}</style>\n <style>${viewportScreenCss}</style>\n <style>\n html[data-vivliostyle-paginated] {\n width: 100%;\n height: 100%;\n }\n html[data-vivliostyle-paginated] body,\n html[data-vivliostyle-paginated] [data-vivliostyle-viewer-viewport] {\n width: 100% !important;\n height: 100% !important;\n }\n html[data-vivliostyle-paginated],\n html[data-vivliostyle-paginated] body {\n margin: 0;\n padding: 0;\n }\n </style>\n <style id='vivliostyle-page-rules'></style>\n </head>\n <body onload='parent.printInstance.runInIframe(window)'>\n <div id=\"vivliostyle-viewer-viewport\"></div>\n </body>\n </html>`;\n\n document.body.appendChild(this.iframe);\n }\n\n runInIframe(iframeWin: Window) {\n this.iframeWin = iframeWin;\n return this.preparePrint()\n .then(() => this.browserPrint())\n .then(() => this.cleanUp());\n }\n\n preparePrint() {\n this.iframeWin.document.title = this.title;\n const docBlob = new Blob([this.htmlDoc], {\n type: \"text/html\",\n }),\n docURL = URL.createObjectURL(docBlob),\n Viewer = new CoreViewer.CoreViewer(\n {\n viewportElement: this.iframeWin.document.body\n .firstElementChild as HTMLElement,\n window: this.iframeWin,\n debug: true,\n },\n {\n defaultPaperSize: {\n width: 794, // These numbers give weird output, but not setting them crashes the browser when there is no CSS.\n height: 1122,\n },\n },\n );\n return new Promise((resolve) => {\n Viewer.addListener(\"readystatechange\", () => {\n if (Viewer.readyState === \"complete\") {\n resolve();\n }\n });\n\n Viewer.loadDocument({\n url: docURL,\n });\n });\n }\n\n browserPrint() {\n this.printCallback(this.iframeWin);\n }\n\n cleanUp() {\n delete this.window.printInstance;\n if (this.removeIframe) {\n this.iframe.parentElement.removeChild(this.iframe);\n }\n }\n}\n\nexport function printHTML(htmlDoc: string, config: PrintConfig) {\n const instance = new VivliostylePrint(htmlDoc, config);\n instance.init();\n}\n"],"names":["setDebug","value","isDebug","pageProgressionOf","str","PageProgression","LTR","RTL","Error","PageSide","ReadyState","constants","LogLevel","argumentsToErrorInfo","args","a","Array","from","e","shift","error","messages","buildMessageAndStackTrace","stack","concat","length","logger","[object Object]","opt_console","this","msg","debug","log","console","info","warn","level","listeners","forEach","listener","push","var_args","arguments","consoleDebug","triggerListeners","DEBUG","consoleInfo","INFO","consoleWarn","WARN","consoleError","ERROR","HOOKS","hooks","registerHook","name","fn","hooksForName","Logging.logger","removeHook","index","indexOf","splice","getHooksForName","plugin","Profiler","performanceInstance","registerTiming","noop","registerStartTiming","registerEndTiming","timestamp","call","timestamps","st","Object","keys","stamps","l","i","t","startEnd","now","fallbackPerformanceInstance","Date","profiler","window","performance","forceRegisterStartTiming","profile","printTimings","disable","enable","emptyObj","stringToJSON","JSON","parse","stripFragment","url","r","match","baseURL","location","href","setBaseURL","resourceBaseURL","setResourceBaseURL","resolveURL","relURL","startsWith","toLowerCase","substr","stripFragmentAndQuery","lastIndexOf","urlOption","j","replace","convertSpecialURL","exec","NS","asString","v","toString","PriorityQueue","queue","item","parentIndex","Math","floor","parent","compare","result","curr","pop","size","childIndex","knownPrefixes","propNameMap","checkIfPropertySupported","prefix","prop","probe","document","createElement","style","setProperty","documentElement","cssPropName","txt","toUpperCase","cssToJSProp","getPrefixedPropertyNames","prefixed","setCSSProperty","elem","prefixedPropertyNames","err","getCSSProperty","opt_value","propertyNames","getPropertyValue","getLangAttribute","element","lang","getAttributeNS","XML","namespaceURI","XHTML","getAttribute","StringBuffer","list","join","escapeChar","charCodeAt","escapeCSSIdent","escapeCSSStr","lightURLEncode","encodeURIComponent","isLetter","ch","escapeNameStrToHex","s","escapeCharToHex","escapeRegExp","unescapeStrFromHex","regexp","RegExp","String","fromCharCode","parseInt","substring","unescapeCharFromHex","binarySearch","high","good","h","m","numberCompare","b","indexArray","arr","key","map","k","multiIndexArray","SimpleEventTarget","evt","type","target","currentTarget","capture","hasVerticalBBoxBug","hasInlineBlockJustificationBug","hasSoftWrapOpportunityAfterHyphenBug","hasSoftWrapOpportunityByWbrBug","getId","node","nodeType","idtxt","escape","unescapeChar","unescape","parseExtVal","extstr","p","parseExt","ext","RefStep","sb","append","pos","ChildStep","id","sideBias","childElements","children","childElementCount","child","firstChild","min","next","nextSibling","after","OffsetStep","offset","textBefore","textAfter","textLength","textContent","Fragment","fragstr","steps","charAt","Base.asString","doc","ref","applyTo","slice","text","parentNode","previousSibling","trim","reverse","Base.StringBuffer","appendTo","clonePreferences","pref","fontFamily","lineHeight","margin","hyphenate","columnWidth","horizontal","nightMode","spreadView","pageBorder","enabledMediaTypes","assign","defaultPaperSize","undefined","defaultPreferencesInstance","vivliostyle","print","Special","PENDING","letterbox","viewW","viewH","objW","objH","scale","cssString","Base.escapeCSSStr","cssIdent","Base.escapeCSSIdent","makeQualifiedName","objName","memberName","nextKeyIndex","LexicalScope","resolver","scopeKey","zero","Const","one","_true","_false","builtIns","ceil","round","sqrt","max","x","defineBuiltInName","pageWidth","pageHeight","fontSize","pubTitle","docTitle","values","Native","qualifiedName","val","funcs","isViewportRelativeLengthUnit","unit","defaultUnitSizes","px","in","pt","pc","cm","mm","q","em","rem","ex","dppx","dpi","dpcm","needUnitConversion","Context","rootScope","viewportWidth","viewportHeight","actualPageWidth","actualPageHeight","initialFontSize","rootFontSize","scope","scopes","clearScope","isRoot","pvw","pvh","vw","pageAreaWidth","vh","pageAreaHeight","pageVertical","params","noBuiltInEval","body","evaluate","apply","not","enabled","feature","req","actual","screen","availWidth","availHeight","pixelDepth","getScopeContext","Val","buf","priority","context","other","dependencyCache","cached","dependCore","dependOuter","queryVal","evaluateCore","storeVal","Prefix","super","evalPrefix","getOp","expand","constructor","Infix","lhs","rhs","evalInfix","thisPriority","getPriority","Logical","Comparison","Additive","Multiplicative","Not","Negate","And","AndMedia","Or","OrMedia","Lt","Le","Gt","Ge","Eq","Ne","Add","Subtract","Multiply","Divide","Modulo","Numeric","num","queryUnitSize","Named","evalName","MediaName","evalMediaName","Call","appendValArray","evalCall","expandedParams","expanded","expandValArray","Cond","cond","ifTrue","ifFalse","MediaTest","evalMediaTest","Param","and","v1","v2","add","sub","mul","div","Visitor","visit","empty","slash","ident","numeric","visitNum","color","func","expr","FilterVisitor","before","visitValues","SpaceList","CommaList","Func","visitor","Empty","instance","Exprs.Const","visitEmpty","Slash","visitSlash","Str","visitStr","nameTable","Ident","visitIdent","getName","Exprs.Multiply","Exprs.Numeric","visitNumeric","Num","Int","visitInt","Color","rgb","visitColor","URL","visitURL","appendList","separator","visitSpaceList","visitCommaList","visitFunc","Expr","visitExpr","toNumber","isNumeric","isNum","convertNumericToPx","absolute","all","always","auto","avoid","balance","balance_all","block","block_end","block_start","both","bottom","border_box","break_all","break_word","crop","cross","column","exclusive","fixed","flex","footnote","footer","header","hidden","horizontal_tb","inherit","inline","inline_block","inline_end","inline_start","landscape","left","line","list_item","ltr","manual","none","normal","oeb_page_foot","oeb_page_head","page","relative","right","same","snap_block","spread","_static","rtl","table","table_caption","table_cell","table_footer_group","table_header_group","table_row","top","transparent","vertical_lr","vertical_rl","visible","hundredPercent","fullWidth","fullHeight","numericZero","processingOrder","font-size","processingOrderFn","name1","name2","Number","MAX_VALUE","Rect","x1","y1","x2","y2","Point","y","Insets","Segment","low","winding","shapeId","Band","segmentCompare","s1","s2","Shape","points","prev","offsetX","offsetY","shapeForEllipse","cx","cy","rx","ry","PI","sin","cos","shapeForRect","BandIntersection","lowOrHigh","intersectY","isNaN","addBandIntersections","intersections","w1","w2","mergeIntersections","includeCount","excludeCount","shapeCount","windings1","windings2","xranges","inside","intersectionCount","intersection","stillInside","rotateBox","box","unrotateBox","rotateShape","shape","point","rotatePoint","normalize","bands","currBand","prevBand","findBand","mid","findUppermostFullyOpenRect","rect","band","topEdge","bottomEdge","findBottommostFullyOpenRect","SetVisitor","Css.Visitor","propSet","IntVisitor","toInt","def","ShapeVisitor","collect","coords","Css.Numeric","width","height","numbers","coord","GeometryUtil.Point","GeometryUtil.Shape","GeometryUtil.shapeForRect","GeometryUtil.shapeForEllipse","toShape","getShape","CountersVisitor","reset","counters","toCounters","UrlTransformVisitor","Css.FilterVisitor","baseUrl","transformer","Css.URL","transformURL","cloneCounterValues","TargetCounterReference","targetId","resolved","spineIndex","pageIndex","CounterListener","counterStore","documentURLTransformer","transformFragment","countersById","getExprContentListener","CounterResolver","pageScope","styler","transformedId","Base.resolveURL","format","self","Exprs.Native","currentPageCounters","getCounterNumber","registerPageCounterExpr","lookForElement","targetCounters","styleUntilIdIsReached","currentPage","elementsById","pageCountersById","getFragment","getTransformedId","getTargetCounters","countersOfName","pageCounters","getTargetPageCounters","resolveReference","pageCountersOfName","saveReferenceOfCurrentPage","elementCountersOfName","CounterStore","counterName","pageNumber","cascadedPageStyle","resetMap","previousPageCounters","resetVal","CssProp.toCounters","resetCounterName","definePageCounter","incrementMap","increment","incrementVal","incrementCounterName","counterValues","currentPageCountersStack","unresolvedRefs","unresolvedReferences","resolvedRefs","resolvedReferences","pushed","referencesToSolve","resolve","newReferencesOfCurrentPage","some","ids","oldPageIndex","pageIndicesById","unresolve","prevPageCounters","isResolved","every","equals","refs","idRefs","sort","r1","r2","o","referencesToSolveStack","pagesCounterExprs","exprContentListener","bind","findIndex","setAttribute","PAGES_COUNTER_ATTR","viewport","nodes","root","querySelectorAll","pages","LayoutConstraint","nodeContext","viewNode","escapeParseSingle","code","escapeParse","TokenType","Action","Token","EOF","makeActions","spec","END","INVALID","actionsNormal","SPACE","BANG","STR2","HASH","DOLLAR","PERCENT","AMP","STR1","O_PAR","C_PAR","STAR","PLUS","COMMA","MINUS","DOT","SLASH","INT","COLON","SEMICOL","LT","EQ","GT","QMARK","AT","IDENT","O_BRK","BSLASH","C_BRK","HAT","O_BRC","BAR","C_BRC","TILDE","actionsIdent","ENDIDNT","FUNC","CONT","IDNTESC","actionsNumOrClass","TOCLASS","TONUM","TOIDES","actionsMinus","MINMIN","TOINT","TOIDENT","actionsIdentEsc","ENDIDES","CHKPOSS","FUNCES","actionsInt","ENDINT","PCUNIT","NUMBER","UNIT","actionsNumber","ENDNUM","actionsCheckEq","EQTAIL","actionsColon","COL_COL","actionsBar","BAR_BAR","actionsAmp","AMP_AMP","actionsSlash","COMMENT","actionsComment","COMMST","actionsCommentStar","ENDNOTK","actionsMinusMinus","KILL1","actionsLt","LT_BG","actionsLtBang","LT_BG_M","actionsLtBangMinus","KILL2","actionsIdentEscChr","IDESCH","actionsStr1","ENDSTR","STR1ESC","actionsStr2","STR2ESC","actionsStr1Esc","ENDESTR","CHKPOSN","actionsStr2Esc","actionsURL","URL2","URL1","actionsURLInside","ENDURL","CHKSP","URLESC","NaN","actionsURLInside1","TERMURL","actionsURLInside2","actionsURLTail","FINURL","INITIAL_INDEX_MASK","Tokenizer","input","handler","indexMask","buffer","tail","fillBuffer","n","head","newIndexMask","newBuffer","oldIndex","newIndex","position","token","mnemonics","reallocate","actions","tokenType","tokenPosition","tokenText","tokenNum","seenSpace","backslashPos","charCode","STR","CLASS","BANG_EQ","NUM","parseFloat","NUMERIC","precededBySpace","privateCurrentTask","primaryScheduler","currentTask","newFrame","task","frame","Frame","state","FrameState","ACTIVE","newResult","SyncResultImpl","handle","onErr","raise","start","opt_name","opt_timer","getScheduler","Scheduler","TimerImpl","run","valueOf","delay","setTimeout","clearTimeout","timer","Base.PriorityQueue","timeout","currentTime","sliceOverTime","inTimeSlice","newTime","peek","scheduledTime","timeoutToken","wakeupTime","doTimeSlice","continuation","opt_delay","c","order","arm","remove","canceled","resumeInternal","Task","then","done","running","callback","callbacks","savedTask","schedule","suspend","Continuation","otherComp","scheduler","finish","cancel","waitTarget","whenDone","exception","opt_frame","fillStack","f","unwind","out","ResultImpl","isPending","res1","res2","res","thenAsync","INIT","checkEnvironment","FINISHED","DEAD","isTimeSliceOver","step","more","loop","LoopBodyFrame","get","opt_waitTarget","Fetcher","fetch","Task.currentTask","Task.newFrame","resource","piggibacks","piggybacks","arrived","Task.newResult","waitForFetchers","fetchers","thenReturn","fetcher","hasArrived","loadElement","src","localName","removeAttribute","addEventListener","Base.NS","SVG","setAttributeNS","XLINK","XMLHttpRequestResponseType","ajax","opt_type","opt_method","opt_data","opt_contentType","request","XMLHttpRequest","response","status","statusText","contentType","responseText","responseXML","responseBlob","open","responseType","onreadystatechange","readyState","DOCUMENT","HTMLDocument","TEXT","makeBlob","contentTypeHeader","getResponseHeader","setRequestHeader","send","test","overrideMimeType","parts","builderCtr","builder","getBlob","Blob","ResourceStore","parser","opt_required","opt_message","Base.stripFragment","resources","isTocBox","endsWith","userAgentXmlUrl","Base.resourceBaseURL","isUserAgentXml","UserAgentXml","TaskUtil.Fetcher","fetchInner","parseJSONResource","store","Base.stringToJSON","SPECIFICITY_USER_AGENT","SPECIFICITY_USER","SPECIFICITY_AUTHOR","SPECIFICITY_STYLE","SPECIFICITY_STYLE_IMPORTANT","SPECIFICITY_AUTHOR_IMPORTANT","SPECIFICITY_USER_IMPORTANT","StylesheetFlavor","colorFromHash","Css.Color","ParserHandler","flavor","AUTHOR","ns","op","pseudoelem","startWhenRule","flowName","pseudoName","classes","important","funcName","USER_AGENT","USER","DispatchParserHandler","slave","tokenizer","getScope","startStylesheet","tagSelector","classSelector","pseudoclassSelector","pseudoelementSelector","idSelector","attributeSelector","descendantSelector","childSelector","adjacentSiblingSelector","followingSiblingSelector","nextSelector","startSelectorRule","startFontFaceRule","startFootnoteRule","startViewportRule","startDefineRule","startRegionRule","startPageRule","startPageMarginBoxRule","startFlowRule","startPageTemplateRule","startPageMasterRule","startPartitionRule","startPartitionGroupRule","startRuleBody","property","endRule","startFuncWithSelector","endFuncWithSelector","SkippingParserHandler","owner","topLevel","getCurrentToken","errorMsg","depth","popHandler","SlaveParserHandler","message","report","pushHandler","reportAndSkip","actionsBase","actionsStyleAttribute","actionsSelector","actionsSelectorInFunc","actionsSelectorCont","actionsSelectorStart","actionsPropVal","actionsExprVal","actionsExprOp","actionsError","actionsErrorDecl","actionsErrorSelector","OP_MEDIA_AND","CssTokenizer.TokenType","LAST","ExprContext","SELECTOR_START","RULE_END","DONE","PROP","SELECTOR_NAME","SELECTOR_ANY","SELECTOR_ID","SELECTOR_CLASS","SELECTOR_ATTR","SELECTOR_PSEUDOCLASS","SELECTOR_CHILD","SELECTOR_SIBLING","SELECTOR_FOLLOWING_SIBLING","SELECTOR_NAME_1","SELECTOR_ANY_1","SELECTOR_ID_1","SELECTOR_CLASS_1","SELECTOR_ATTR_1","SELECTOR_BODY","SELECTOR_PSEUDOCLASS_1","SELECTOR_PSEUDOELEM","SELECTOR_NEXT","VAL_IDENT","VAL_HASH","VAL_NUM","VAL_INT","VAL_NUMERIC","VAL_STR","VAL_URL","VAL_COMMA","VAL_SLASH","VAL_FUNC","VAL_C_PAR","VAL_END","VAL_BRC","VAL_BANG","VAL_PLUS","VAL_FINISH","EXPR_IDENT","EXPR_NUM","EXPR_NUMERIC","EXPR_STR","EXPR_O_PAR","EXPR_FUNC","EXPR_PREFIX","EXPR_PARAM","EXPR_INFIX_NAME","EXPR_INFIX","GT_EQ","LT_EQ","EQ_EQ","EXPR_C_PAR","EXPR_O_BRC","EXPR_SEMICOL","ERROR_PUSH","ERROR_POP","ERROR_SEMICOL","ERROR_POP_DECL","Parser","exprContext","MEDIA","sep","valStack","count","Css.SpaceList","Css.Func","extractVals","Css.CommaList","propName","val2","tok","unshift","e1","e2","er","Exprs.OrMedia","Css.Expr","Exprs.Call","Exprs.makeQualifiedName","isMediaName","Exprs.MediaTest","Exprs.Not","exprError","Exprs.Negate","Exprs.And","Exprs.AndMedia","Exprs.Or","Exprs.Lt","Exprs.Gt","Exprs.Le","Exprs.Ge","Exprs.Eq","Exprs.Ne","Exprs.Add","Exprs.Subtract","Exprs.Divide","Exprs.Modulo","Exprs.Cond","consume","hasLeadingPlus","hasMinusSign","hasSign","condition","classList","split","className","Exprs.and","Exprs.Named","ruleStack","parsingValue","parsingStyleAttr","parsingMediaQuery","parsingFunctionParam","token1","parserLoop","nthToken","isInsidePropertyOnlyRule","mark","propImportant","namespacePrefixToURI","defaultNamespaceURI","pseudoclassType","runParser","POSITIVE_INFINITY","readNthPseudoParams","readPseudoParams","TILDE_EQ","BAR_EQ","HAT_EQ","DOLLAR_EQ","STAR_EQ","regionRule","pageRule","Css.getName","Css.Num","Css.Int","Exprs.isViewportRelativeLengthUnit","Css.Str","valStackReduce","Css.slash","hasMark","unmark","IMPORT","Exprs.MediaName","Exprs.Param","exprStackReduce","WHEN","startMediaRule","importCondition","importReady","importURL","ruleName","rulePseudoName","errorBrackets","ErrorHandler","parseStylesheet","media","parseMediaQuery","CssTokenizer.Tokenizer","makeCondition","toExpr","resolvedURL","innerFrame","parseStylesheetFromURL","timeSlice","parseStylesheetFromText","Task.handle","thenFinish","Net.ajax","xhr","parseValue","numProp","z-index","column-count","flow-linger","opacity","flow-priority","utilization","evaluateExprToCSS","takesOnlyNum","Css.empty","Css.ident","evaluateCSSToCSS","isExpr","matchANPlusB","AnyMatcher","matchers","matcher","matches","AllMatcher","NthFragmentMatcher","elementOffset","fragmentIndex","indices","fragmentIndices","entry","MatcherBuilder","viewCondition","strs","inheritedProps","azimuth","border-collapse","border-spacing","caption-side","clip-rule","color-interpolation","color-rendering","cursor","direction","elevation","empty-cells","fill","fill-opacity","fill-rule","font-kerning","font-size-adjust","font-family","font-feature-settings","font-style","font-stretch","font-variant","font-weight","glyph-orientation-vertical","hyphens","hyphenate-character","hyphenate-limit-chars","hyphenate-limit-last","image-rendering","image-resolution","letter-spacing","line-break","line-height","list-style-image","list-style-position","list-style-type","marker","marker-end","marker-mid","marker-start","orphans","overflow-wrap","paint-order","pointer-events","pitch-range","quotes","richness","ruby-align","ruby-position","speak-header","speak-numeral","speak-punctuation","speech-rate","shape-rendering","stress","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","tab-size","text-align","text-align-last","text-anchor","text-decoration-skip","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-combine-upright","text-indent","text-justify","text-rendering","text-size-adjust","text-transform","text-underline-position","visibility","voice-family","volume","white-space","widows","word-break","word-spacing","word-wrap","writing-mode","polyfilledInheritedProps","getPolyfilledInheritedProps","Plugin.getHooksForName","Plugin.HOOKS","POLYFILLED_INHERITED_PROPS","reduce","props","supportedNamespaces","http://www.idpf.org/2007/ops","http://www.w3.org/1999/xhtml","http://www.w3.org/2000/svg","coupledPatterns","coupledExtentPatterns","geomNames","sides","names","max-width","max-height","min-width","min-height","buildCouplingMap","sideMap","extentMap","pattern","side","extentPattern","extent","couplingMapVert","block-start","block-end","inline-start","inline-end","block-size","inline-size","couplingMapHor","couplingMapVertRtl","couplingMapHorRtl","CascadeValue","specificity","CssParser.evaluateCSSToCSS","ConditionalCascadeValue","cascadeValues","tv","av","isEnabled","getBaseValue","SPECIALS","region-id","fragment-selector-id","isSpecialName","isPropName","isInherited","getProp","setProp","getStyleMap","getMutableStyleMap","getViewConditionalStyleMap","getSpecial","getMutableSpecial","mergeIn","pseudoelement","regionId","viewConditionMatcher","styleKey","styleMap","styles","as","ts","prototype","increaseSpecificity","chainActions","chain","action","chained","InheritanceVisitor","Exprs.isAbsoluteLengthUnit","Exprs.defaultUnitSizes","parentFontSize","convertFontRelativeLengthToPx","convertFontSizeToPx","getFontSize","baseFontSize","ratio","CascadeAction","cascadeInstance","CompoundAction","ConditionItemAction","conditionItem","pushConditionItem","fresh","ApplyRuleAction","viewConditionId","currentStyle","buildViewConditionMatcher","ChainedAction","cascade","CheckClassAction","currentClassNames","includes","insertInTable","CheckIdAction","currentId","currentXmlId","CheckLocalNameAction","currentLocalName","tags","CheckNSTagAction","currentNamespace","nsPrefix","nsCount","nsTag","nstags","CheckTargetEpubTypeAction","epubTypePatt","currentElement","ownerDocument","getElementById","epubType","epub","CheckNamespaceAction","CheckAttributePresentAction","hasAttributeNS","CheckAttributeEqAction","epubtypes","CheckNamespaceSupportedAction","CheckAttributeRegExpAction","attr","CheckLangAction","langRegExp","IsFirstAction","isFirst","IsRootAction","IsNthAction","Matchers.matchANPlusB","IsNthSiblingOfTypeAction","currentSiblingTypeCounts","IsNthLastSiblingAction","currentFollowingSiblingOrder","currentSiblingOrder","IsNthLastSiblingOfTypeAction","counts","currentFollowingSiblingTypeCounts","nsCounts","nextElementSibling","IsEmptyAction","Node","ELEMENT_NODE","TEXT_NODE","IsEnabledAction","disabled","IsDisabledAction","IsCheckedAction","selected","checked","CheckConditionAction","conditions","dependentConditions","CheckAppliedAction","applied","cloned","NegateActionsSet","checkAppliedAction","firstAction","AbstractConditionItem","decrement","DescendantConditionItem","ChildConditionItem","AdjacentSiblingConditionItem","fired","FollowingSiblingConditionItem","AfterPseudoelementItem","afterprop","processPseudoelementProps","RestoreLangItem","QuotesScopeItem","oldQuotes","AttrValueFilterVisitor","attributeName","defaultValue","stringValue","createValueFromString","hasAttribute","ContentPropVisitor","counterResolver","maxDepth","quoteDepth","upper","lower","additiveNumbering","entries","additiveFormat","alphabeticNumbering","alphabetStr","alphabet","first","last","expandAlphabet","digit","alphabeticFormat","numbering","digits","negative","formal","markers","thousands","hundreds","tens","ones","chineseCounter","chineseTradInformal","numval","getPageCounterVal","getPageCountersVal","numvals","elementCounters","targetUrl","targetUrlStr","getTargetCounterVal","getTargetCountersVal","visitFuncCounter","visitFuncCounters","visitFuncTargetCounter","visitFuncTargetCounters","roman","armenian","georgian","hebrew","latin","alpha","greek","russian","square","disc","circle","ORDER_INCREMENT","copyTable","dst","clone","Cascade","pagetypes","mergeWith","counterListener","CascadeInstance","siblingTypeCountsStack","followingSiblingOrderStack","viewConditions","filter","currentElementOffset","Matchers.MatcherBuilder","dependentConditionMatchers","conditionId","buildAnyMatcher","buildAllMatcher","pageType","baseStyle","currentNSTag","currentEpubTypes","EMPTY","currentPageType","applyActions","scoping","counterScoping","displayVal","display","setMap","set","setVal","defineCounter","setCounterName","listItemCounts","listItemCount","pseudoprops","pushCounters","filterValue","popCounters","types","FB2","Base.getLangAttribute","siblingOrderStack","currentNamespaceTypeCounts","followingSiblingTypeCountsStack","applyAttrFilter","quotesCasc","itemToPushLast","quotesVal","countersOfId","pseudos","pseudoNames","pseudoProps","elementStyle","pseudoMap","applyAttrFilterInner","applyAction","currentDoc","ParseState","uaBaseCascade","CascadeParserHandler","CssParser.SlaveParserHandler","validatorSet","TOP","makePrimary","insertNonPrimary","patt","Base.escapeRegExp","footnoteContent","langValue","ActionClass","nthSelectorActionClasses","conditionCount","processChain","finishChain","isInsideSelectorRule","SELECTOR","insideSelectorRule","nextOrder","makeApplyRuleAction","validatePropertyAndHandleShorthand","simpleProperty","hook","converted","getImportantSpecificity","getBaseSpecificity","cascval","notParserHandler","NotParameterParserHandler","nth-child","nth-of-type","nth-last-child","nth-last-of-type","parentChain","DefineParserHandler","dim","defineName","PropSetParserHandler","PropertyParserHandler","CssParser.ErrorHandler","CssParser.SPECIFICITY_STYLE_IMPORTANT","CssParser.SPECIFICITY_STYLE","forEachViewConditionalStyles","viewConditionalStyles","mergeViewConditionalStyles","cascMap","mergeStyle","parseStyleAttribute","styleAttrValue","CssParser.parseStyleAttribute","isVertical","cascaded","vertical","writingModeCasc","writingMode","isRtl","directionCasc","flattenCascadedStyle","regionIds","isFootnote","forEachStylesInRegion","regionStyle","regions","footnoteRegion","to","newVal","oldVal","convertToPhysical","dest","transform","couplingMap","hasOwnProperty","cascVal","coupledName","targetName","coupledCascVal","createRegExpMap","valueMaps","toPhysical","logical","physical","convert","maps","maps2","replaced","horizontal-tb","vertical-rl","vertical-lr","toPhysicalMaps","toLogicalMaps","Size","getSize","clientLayout","sizes","original","maxWidth","minWidth","maxHeight","minHeight","container","getComputedValue","getElementComputedStyle","Base.setCSSProperty","insertBefore","appendChild","writingModeProperty","Base.getPrefixedPropertyNames","writingModeValue","inlineSizeName","blockSizeName","getFillAvailableInline","getMaxContentInline","getMinContentInline","getFitContentInline","fillAvailableInline","minContentInline","parsedFillAvailable","maxContentInline","getIdealBlock","getFillAvailableBlock","FILL_AVAILABLE_INLINE_SIZE","MAX_CONTENT_INLINE_SIZE","MIN_CONTENT_INLINE_SIZE","FIT_CONTENT_INLINE_SIZE","FILL_AVAILABLE_BLOCK_SIZE","MAX_CONTENT_BLOCK_SIZE","MIN_CONTENT_BLOCK_SIZE","FIT_CONTENT_BLOCK_SIZE","FILL_AVAILABLE_WIDTH","FILL_AVAILABLE_HEIGHT","MAX_CONTENT_WIDTH","MAX_CONTENT_HEIGHT","MIN_CONTENT_WIDTH","MIN_CONTENT_HEIGHT","FIT_CONTENT_WIDTH","FIT_CONTENT_HEIGHT","removeChild","DIFF_DELETE","DIFF_INSERT","DIFF_EQUAL","diff_main","text1","text2","cursor_pos","_fix_unicode","editdiff","oldText","newText","oldRange","newRange","oldLength","newLength","oldCursor","oldBefore","oldAfter","maybeNewCursor","newCursor","newBefore","newAfter","prefixLength","oldPrefix","newPrefix","oldMiddle","newMiddle","make_edit_splice","suffixLength","oldSuffix","newSuffix","find_cursor_edit_diff","commonlength","diff_commonPrefix","commonprefix","diff_commonSuffix","commonsuffix","diffs","longtext","shorttext","hm","diff_halfMatchI_","best_longtext_a","best_longtext_b","best_shorttext_a","best_shorttext_b","seed","best_common","text1_a","text1_b","text2_a","text2_b","hm1","hm2","mid_common","diff_halfMatch_","diffs_a","diffs_b","text1_length","text2_length","max_d","v_offset","v_length","delta","front","k1start","k1end","k2start","k2end","d","k1","k1_offset","k2_offset","diff_bisectSplit_","k2","diff_bisect_","diff_compute_","diff_cleanupMerge","fix_unicode","pointer","count_delete","count_insert","text_delete","text_insert","previous_equality","ends_with_pair_start","stray","starts_with_pair_end","changes","text1a","text2a","text1b","text2b","diffsb","pointermin","pointermax","pointermid","pointerstart","is_surrogate_pair_start","pointerend","is_surrogate_pair_end","tuples","ret","remove_empty_tuples","diff","INSERT","DELETE","EQUAL","LayoutProcessor","PageFloats","Selectors","RepetitiveElement","Table","Vtree","restoreNewText","fastdiff","resolveIndex","coef","current","change","object","formattingContextType","FloatReference","flagmentLayoutConstraintType","isInstanceOfTableFormattingContext","isInstanceOfTableRowLayoutConstraint","Whitespace","ShadowType","delayedProps","transform-origin","delayedPropsIfRelativePositioned","DelayedItem","show","obj","hide","play","pause","resume","mute","muted","unmute","makeListener","actionFn","Page","Base.SimpleEventTarget","bleedBox","hrefHandler","anchorElement","preventDefault","dispatchEvent","isAuto","isAutoPageWidth","AUTO_PAGE_WIDTH_ATTRIBUTE","isAutoPageHeight","AUTO_PAGE_HEIGHT_ATTRIBUTE","triggers","elems","contains","delayedItems","getElementClientRect","dimensions","trigger","observers","observer","event","pageAreaElement","SPECIAL_ATTR","whitespaceFromPropertyValue","whitespace","IGNORE","NEWLINE","PRESERVE","canIgnore","Flow","parentFlowName","FlowChunk","startOffset","linger","repeated","breakBefore","clientrectIncreasingTop","clientrectDecreasingRight","isSameNodePositionStep","nps1","nps2","shadowType","isSameShadowContext","shadowContext","nodeShadow","shadowSibling","isSameNodePosition","np1","np2","offsetInNode","newNodePositionFromNodeContext","initialFragmentIndex","sourceNode","NONE","formattingContext","preprocessedTextContent","makeNodeContextFromNodePositionStep","NodeContext","copy","ShadowContext","xmldoc","parentShadow","superShadow","subShadow","sc1","sc2","FirstPseudo","outer","boxOffset","breakPenalty","floatReference","INLINE","hyphenateCharacter","breakWord","firstPseudo","clearSpacer","floatSide","clearSide","floatMinWrapBlock","columnSpan","verticalAlign","flexContainer","breakAfter","establishesBFC","containingBlockForAbsolute","repeatOnBreak","pluginProps","afterIfContinues","footnotePolicy","np","captionSide","inlineBorderSpacing","blockBorderSpacing","overflow","create","shared","cloneItem","npp","npc","toNodePositionStep","nc","ChunkPosition","primary","floats","FlowChunkPosition","chunkPosition","flowChunk","isSamePosition","FlowPosition","newfp","positions","newarr","startSide","LayoutPosition","newcp","highestSeenNode","highestSeenOffset","lookupPositionOffset","flows","flowPositions","thisFlowNames","otherFlowNames","flowPos","hasContent","flowChunkPosition","Container","marginTop","borderTop","paddingTop","marginBottom","borderBottom","paddingBottom","marginLeft","borderLeft","paddingLeft","marginRight","borderRight","paddingRight","getInsetRight","getInsetTop","getInsetLeft","getInsetBottom","originX","originY","innerShape","exclusions","computedBlockSize","snapWidth","snapHeight","setHorizontalPosition","getBoxDir","setVerticalPosition","lastChild","getInnerRect","withOffset","GeometryUtil.Rect","paddingX","paddingY","paddingWidth","paddingHeight","outerShapeProp","getOuterRect","CssProp.toShape","outerX","outerY","outerWidth","outerHeight","ContentPropertyHandler","rootContentValue","createTextNode","visitStrInner","img","createElementNS","CssParser.parseValue","nonTrivialContent","isPageFloat","COLUMN","REGION","PAGE","PageFloat","nodePosition","pageFloatLayoutContext","isAnchorAlreadyAppeared","PageFloatStore","nextPageFloatIndex","float","VtreeImpl.isSameNodePosition","createPageFloatId","PageFloatFragment","continuations","area","continues","isAllowedOnContext","getOuterShape","getOrder","PageFloatContinuation","PageFloatLayoutContext","generatingNodePosition","floatStore","getPreviousSibling","floatsDeferredFromPrevious","floatsDeferredToNext","getPreviousSiblingOf","getParent","getContainer","reattachFloatFragments","addPageFloat","getPageFloatLayoutContext","findPageFloatByNodePosition","forbiddenFloats","PageFloatLayoutStrategyResolver","findByFloat","forbid","isForbidden","floatFragment","dontInvalidate","addPageFloatFragment","floatFragments","fr1","fr2","invalidate","removePageFloatFragment","fragment","findPageFloatFragment","hasFloat","hasFloatFragments","getFlowName","anchorViewNode","floatAnchors","anchors","collectPageFloatAnchors","floatId","getDeferredPageFloatContinuations","cont","deferPageFloat","ignoreReference","hasPrecedingFloatsDeferredToNext","isAllowedToPrecede","lastFollowing","lastFollowingOfParent","getLastFollowingFloatInFragments","c1","c2","getPageFloatContinuationsDeferredToNext","getFloatsDeferredToNextInChildContexts","checkAndForbidFloatFollowingDeferredFloat","notAllowedFloat","findNotAllowedFloat","locked","removeEndFloatFragments","checkAndForbidNotAllowedFloat","deferredFloats","floatsInFragments","fr","f1","f2","invalidated","hasSameContainerAs","clear","layoutConstraints","isInvalidated","CssLogicalUtil.toLogical","CssLogicalUtil.toPhysical","logicalFloatSide","toLogical","stashEndFloatFragments","fragmentFloatSide","shouldBeStashedBefore","stashedFloatFragments","stashed","restoreStashedFragments","discardStashedFragments","getStashedFloatFragments","layoutContext","logicalSide","physicalSide","limit","getLimitValueInner","parentLimit","getLimitValue","limits","getLimitValuesInner","paddingRect","getPaddingRect","floatMinWrapBlockStart","floatMinWrapBlockEnd","resolveLengthPercentage","containerLength","convertLengthToPx","fragments","rootViewNodes","anchorEdge","init","force","setFloatAreaDimensions","blockStart","blockEnd","inlineStart","inlineEnd","blockOffset","inlineOffset","limitBlockStartEndValueWithOpenRect","getRect","openRect","GeometryUtil.unrotateBox","blockSize","inlineSize","outerBlockSize","outerInlineSize","GeometryUtil.rotateBox","GeometryUtil.findUppermostFullyOpenRect","GeometryUtil.findBottommostFullyOpenRect","getInsetBefore","getInsetAfter","getInsetStart","getInsetEnd","availableBlockSize","containerRect","Sizing.getSize","Sizing.Size","adjustContentRelativeSize","getContentInlineSize","availableInlineSize","setInlinePosition","setBlockPosition","getFloatFragmentExclusions","edge","Infinity","isContinuationOfAlreadyAppearedFloat","isFragmentWithAlreadyAppearedFloat","columnRect","columnBlockEnd","blockStartLimit","getPageFloatPlacementCondition","logicalClearSide","logicalSides","floatOrder","isPrecedingFragment","hasPrecedingFragmentInChildren","hasPrecedingFragmentInParents","getLayoutConstraints","layoutConstraint","addLayoutConstraint","pageFloatLayoutStrategies","strategy","appliesToNodeContext","appliesToFloat","register","toNodePosition","resolveFloatReferenceFromColumnSpan","floatArea","floatContainer","PageFloats.PageFloatFragment","Footnote","PageFloats.PageFloat","FootnoteFragment","LineFootnotePolicyLayoutConstraint","Vtree.isSameNodePosition","PageFloats.FloatReference","regionContext","applyFootnoteStyle","convertPercentageSizesToPx","setComputedInsets","setComputedWidthAndHeight","constraint","forcedBreakValues","recto","verso","region","isForcedBreakValue","avoidBreakValues","avoid-page","avoid-column","avoid-region","isAvoidBreakValue","resolveEffectiveBreakValue","second","firstIsForcedBreakValue","secondIsForcedBreakValue","breakValueToStartSideValue","breakValue","startSideValueToBreakValue","startSideValue","calculateEdge","extraOffset","cbox","range","createRange","setStart","setEnd","boxes","getRangeClientRects","getBoundingClientRect","Base.checkVerticalBBoxBug","fullRange","fullBoxes","fullBox","abs","fixBoxesForNode","maxSize","boxSize","getElementHeight","getComputedMargin","isOrphan","removeFollowingSiblings","isSpecial","VtreeImpl.SPECIAL_ATTR","isSpecialNodeContext","AbstractBreakPosition","calculateOffset","getNodeContext","collectElementsOffset","elementsOffsets","repetitiveElement","minimum","calculateMinimumOffset","EdgeBreakPosition","breakOnEdge","overflows","overflowIfRepetitiveElementsDropped","penalty","updateOverflows","getMinBreakPenalty","findEdgeBreakPosition","isEdgeUpdated","preferDropping","isFirstContentOfRepetitiveElementsOwner","Break.isAvoidBreakValue","clonedPaddingBorder","calculateClonedPaddingBorder","LayoutHelper.calculateEdge","updateEdge","offsets","isOverflown","isInstanceOfRepetitiveElementsOwnerFormattingContext","repetitiveElements","getRepetitiveElements","isFirstContentNode","FLOW_ROOT_ATTR","blockify","displayStr","blockifiedStr","isAbsolutelyPositioned","getComputedDislayValue","isBlock","isInlineLevel","LayoutProcessorResolver","RESOLVE_LAYOUT_PROCESSOR","processor","BlockLayoutProcessor","leadingEdge","isFloatNodeContext","layoutFloatOrFootnote","isBreakable","layoutBreakableBlock","layoutUnbreakable","columnBlockSize","BreakPosition.EdgeBreakPosition","stopAtOverflow","parentNodeContext","removeSelf","LayoutHelper.removeFollowingSiblings","forceRemoveSelf","endOfColumn","clearOverflownViewNodes","fixJustificationIfNeeded","processFragmentedBlockEdge","BlockFormattingContext","firstTime","blockLayoutProcessor","isInstanceOfBlockFormattingContext","RESOLVE_FORMATTING_CONTEXT","Display.isBlock","AbstractLayoutRetryer","prepareLayout","tryLayout","saveState","mode","resolveLayoutMode","doLayout","positionAfter","accepted","accept","postLayout","initialPosition","clearNodes","restoreState","sibling","initialBreakPositions","breakPositions","initialFragmentLayoutConstraints","fragmentLayoutConstraints","initialStateOfFormattingContext","LayoutIteratorStrategy","initialNodeContext","atUnforcedBreak","break","LayoutIterator","initialState","loopWithFrame","loopFrame","VtreeImpl.canIgnore","afterIgnoredTextNode","startIgnoredTextNode","afterNonElementNode","startNonElementNode","afterInlineElementNode","startInlineElementNode","afterNonInlineElementNode","startNonInlineElementNode","afterNonDisplayableNode","startNonDisplayableNode","nextResult","nextInTree","nextNodeContext","breakLoop","continueLoop","EdgeSkipper","breakAtTheEdge","onStartEdges","leadingEdgeContexts","lastAfterNodeContext","needForcedBreak","Break.isForcedBreakValue","pageBreakType","checkOverflowAndSaveEdgeAndBreakPosition","modify","violateConstraint","allowLayout","Break.resolveEffectiveBreakValue","startNonInlineBox","endEmptyNonInlineBox","endNonInlineBox","repetitiveElementsCache","DOMParser","parseFromString","SHADOW","PSEUDO_ATTR","getPseudoName","setPseudoName","PseudoelementStyler","deep","getStyle","CssCascade.getStyleMap","nest","CssCascade.CascadeValue","contentProcessed","contentVal","Vtree.nonTrivialContent","Vtree.ContentPropertyHandler","isInstanceOfAfterIfContinuesLayoutConstraint","registerFragmentIndex","Matchers.NthFragmentMatcher","AfterIfContinues","viewRoot","pseudoColumn","PseudoColumn","initialPageBreakType","getColumn","layout","createNodePositionForPseudoElement","pseudoElement","PseudoElement.document","PseudoElement.setPseudoName","createShadowContext","VtreeImpl.ChunkPosition","VtreeImpl.ShadowContext","ROOTED","AfterIfContinuesLayoutConstraint","pseudoElementHeight","overflownNodeContext","allowed","affectTo","AfterIfContinuesElementsOffset","processAfterIfContinuesOfNodeContext","LayoutHelper.getElementHeight","calculatePseudoElementHeight","processAfterIfContinues","mediaTags","svg","audio","video","AllLayoutConstraint","constraints","BoxBreakPosition","BreakPosition.AbstractBreakPosition","checkPoints","alreadyEvaluated","breakNodeContext","findBoxBreakPosition","isSpecialInlineDisplay","Column","VtreeImpl.Container","viewDocument","setContainer","startEdge","beforeEdge","endEdge","afterEdge","isFloat","footnoteEdge","pageFloatExclusions","setViewRoot","stepIndex","prevContext","VtreeImpl.makeNodeContextFromNodePositionStep","flowRootFormattingContext","calculateOffsetInNodeForNodeContext","setCurrent","firstCharPattern","peelOff","bodyFrame","LayoutHelper.isSpecialNodeContext","maybePeelOff","position1Param","positionParam","postLayoutBlock","position1","cssFloat","getTopEdge","getLeftEdge","getBottomEdge","getRightEdge","createFloat","LayoutHelper.isOrphan","insets","GeometryUtil.Insets","parseComputedLength","borderLeftWidth","borderTopWidth","borderRightWidth","borderBottomWidth","boxSizing","nodeContextIn","buildDeepElementView","nodeContextAfter","floatBBox","floatBox","parentBox","getStartEdge","getEndEdge","floatBoxMeasure","floatHorBox","dir","bottommostFloatTop","boxExtent","floatWidth","floatHeight","floatBottom","GeometryUtil.positionFloat","getComputedInsets","getContainingBlockForAbsolute","floatBoxEdge","floatBoxTop","killFloats","floatBands","lastY","floatBand","GeometryUtil.addFloatToBands","createFloats","leftFloatEdge","rightFloatEdge","updateMaxReachedAfterEdge","floatLayoutContext","forceNonfitting","containingBlockRect","adjustPageFloatArea","fitWithinContainer","floatAreaElement","parentPageFloatLayoutContext","PageFloats.PageFloatLayoutContext","parentContainer","PageFloatArea","setupFloatArea","allowFragmented","pageFloatFragment","originalContinuations","firstFloat","createPageFloatArea","newPosition","failed","floatChunkPosition","newFragment","createPageFloatFragment","cancelLayout","layoutSinglePageFloatFragment","layoutStashedPageFloats","success","PageFloats.PageFloatContinuation","excluded","newFloatAreas","newFragments","stashedFragment","PageFloats.PageFloatLayoutStrategyResolver","anchor","applyPseudoelementStyle","columnContext","findByNodeContext","createPageFloat","VtreeImpl.newNodePositionFromNodeContext","setFloatAnchorViewNode","registerPageFloatAnchor","nodeContextOverflowingDueToRepetitiveElements","layoutPageFloatInner","insertionPoint","span","inner","textIndent","textAlign","leftPos","rightPos","inlineBlock","Base.checkInlineBlockJustificationBug","padding","paddingStr","insertAfter","Base.checkSoftWrapOpportunityAfterHyphenBug","hyphenChar","resolveHyphenateCharacter","prevSibling","prevText","Base.checkSoftWrapOpportunityByWbrBug","fixJustificationOnHyphen","createJustificationAdjustmentElement","br","spanRect","brRect","addAndAdjustJustificationElement","compensateJustificationLineHeight","resNodeContext","lastCheckPoints","totalLineCount","linePositions","findLinePositions","lineBreak","findAcceptableBreakInside","finishBreak","resNodeContextParam","buildViewToNextBlockEdge","trailingEdgeContexts","maxPos","minNeg","checkPointIndex","lineCont","overflown","BreakPosition.calculateOffset","getTrailingMarginEdgeAdjustment","processLineStyling","saveBoxBreakPosition","isLoneImage","POST_LAYOUT_BLOCK","linePosition","isUpdateMaxReachedAfterEdge","effectiveLinePosition","lowCP","low1","highCP","high1","mid1","edgePosition","findEndOfLine","textNode","resolveTextNodeBreaker","breakTextNode","RESOLVE_TEXT_NODE_BREAKER","TextNodeBreaker","end","wentUp","lastGood","haveStart","endNotReached","seekRange","setStartBefore","LayoutHelper.isSpecial","setEndAfter","boxList","getRangeBoxes","VtreeImpl.clientrectDecreasingRight","VtreeImpl.clientrectIncreasingTop","lineBefore","lineAfter","lineEnd","lineLength","overlap","getBoxSize","getBeforeEdge","getAfterEdge","Base.numberCompare","walkUpBlocks","Element","paddingBorders","getComputedPaddingBorder","bp","repetitiveElementsOffset","getOffsetByRepetitiveElements","firstOverflowing","findFirstOverflowingEdgeAndCheckPoint","lineIndex","Base.binarySearch","forceCutBeforeOverflowing","checkPoint","blockEdge","getAfterEdgeOfBlockContainer","blockParent","cp","LayoutProcessor.LayoutProcessorResolver","find","LayoutProcessor.blockLayoutProcessor","nextPenalty","findAcceptableBreak","minPenalty","breakPosition","initialComputedBlockSize","skipTailEdges","flowPosition","marginEdge","saveEvenOverflown","checkOverflowAndSaveEdge","saveEdgeBreakPosition","spacer","spacerBox","clearEdge","getPageFloatClearEdge","wAdj","hAdj","LayoutProcessor.isInstanceOfBlockFormattingContext","forcedBreakValue","fc","isBFC","processForcedBreak","layoutProcessor","applyClearance","zeroIndent","viewTag","nodeContextParam","lastAfterPosition","resultNodeContext","PageFloats.isPageFloat","layoutPageFloat","layoutFloat","skipEdges","stopByOverflow","columnBBox","include","exclude","granularity","segments","segment","addSegments","segmentCount","lowestIncludeIndex","segmentIndex","activeSegments","y2min","yn","bandIntersections","bi1","bi2","rw","GeometryUtil.shapesToBands","getInnerShape","getExclusions","chunkPositions","initGeom","breakAtEdge","createEdgeBreakPosition","isFullWithPageFloats","openAllViews","nextInTreeListener","removeEventListener","retryer","ColumnLayoutRetryer","doFinishBreak","pseudoParent","doFinishBreakOfFragmentLayoutConstraints","isColumnFullWithPageFloats","getMaxBlockSizeOfPageFloats","sortedFragmentLayoutConstraints","getPriorityOfFinishBreak","pending","layoutNext","findAcceptableBreakPosition","breakPositionChosen","isPseudoelement","blockStartEdgeOfBlockEndFloats","getBlockStartEdgeOfBlockEndFloats","isFinite","blockDistanceToBlockEndFloats","isInstanceOfRepetitiveElementsOwnerLayoutConstraint","getElementsOffsetsForTableCell","parentClonedPaddingBorder","startNodeContexts","allowBreakAtStartPosition","startNodeContext","checkpointIndex","viewIndex","data","breakAfterSoftHyphen","breakAfterOtherCharacter","updateNodeContext","replaceData","ch0","ch1","Base.isLetter","LayoutRetryers.AbstractLayoutRetryer","DefaultLayoutMode","initialOverflown","processAfterIfContinuesOfAncestors","hasNextCandidate","nextCandidate","fixFloatSizeAndPosition","refWidth","refHeight","convertPercentageToPx","refValue","valueString","Base.getCSSProperty","percentageValue","rootViewNode","floatMargins","RepetitiveElementsOwnerFormattingContext","rootSourceNode","getRootNodeContext","belongsTo","Shared.repetitiveElementsCache","elements","RepetitiveElements","ownerSourceNode","headerNodePosition","headerSourceNode","headerViewNode","footerNodePosition","footerSourceNode","footerViewNode","headerHeight","footerHeight","isSkipHeader","isSkipFooter","enableSkippingFooter","enableSkippingHeader","rootNodeContext","appendElementToFragment","Layout.PseudoColumn","allowInsertRepeatitiveElements","moveChildren","isAfterLastContent","findResultFromCache","afterLastContentNodeCache","isAfterNodeContextOf","lastContentSourceNode","affectedNodeCache","cache","calculator","cacheEntry","includeChildren","parentsOfNode","currentParent","previousElementSibling","firstContentSourceNode","LayoutEntireBlock","doneInitialLayout","updateHeight","LayoutFragmentedBlock","LayoutEntireOwnerBlock","doInitialLayout","LayoutFragmentedOwnerBlock","RepetitiveElementsOwnerLayoutConstraint","isEnableToUpdateState","updateState","preventSkippingFooter","appendHeaderToFragment","appendHeader","appendFooterToFragment","appendFooter","prepareLayoutFragment","RepetitiveElementsOwnerLayoutRetryer","preventSkippingHeader","EntireBlockLayoutStrategy","LayoutUtil.EdgeSkipper","isHeaderRegistered","setHeaderNodeContext","isFooterRegistered","setFooterNodeContext","appendHeaderToAncestors","eachAncestorNodeContext","repetitiveLayoutProcessor","LayoutProcessor.BlockLayoutProcessor","getRootViewNode","getRepetitiveElementsOwnerFormattingContextOrNull","isHeaderSourceNode","isFooterSourceNode","layoutEntireBlock","LayoutUtil.LayoutIterator","iterate","Layout.processAfterIfContinues","TableRow","rowIndex","cell","cells","TableCell","columnIndex","viewElement","colSpan","rowSpan","slot","anchorSlot","TableSlot","TableCellFragment","pseudoColumnContainer","cellNodeContext","TableCaptionView","BetweenTableRowBreakPosition","getAcceptableCellBreakPositions","acceptableCellBreakPositions","cellFragments","getCellFragments","cellFragment","findRowIndexBySourceNode","getRowSpanningCellsOverflowingTheRow","getRowIndex","getCellFragmentOfCell","InsideTableRowBreakPosition","beforeNodeContext","allCellsBreakable","isStartNodeContext","isLastAfterNodeContext","row","getRowByIndex","isFreelyFragmentableRow","getCellsFallingOnRow","TableFormattingContext","RepetitiveElementImpl.RepetitiveElementsOwnerFormattingContext","tableSourceNode","cellBreakPositions","cellNodePosition","rows","rowSlots","slots","addRow","addCell","rowUpper","getRowSlots","startColIndex","setAnchorSlot","uniqueCells","getMinimumHeight","tableWidth","columnCount","sum","setHeight","tableCell","col","collected","collectElementsOffsetFromColumn","elementsInColumn","ElementsOffsetOfTableCell","repeatitiveElementsInColumns","calculateMaxOffsetOfColumn","maxOffset","isValidParentOfTableRow","isTableRowGrouping","isTableRoot","skipNestedTable","parentDisplay","isNestedInlineTable","EntireTableLayoutStrategy","postLayoutBlockContents","captionView","captions","inHeaderOrFooter","inRow","computedStyle","lastRowViewNode","registerCheckPoint","TableLayoutStrategy","originalStopAtOverflow","colWidths","startChunkPosition","cellViewNode","getColSpanningCellWidth","addCellFragment","slotIndex","cellBreakPosition","rowSpanningCellBreakPositions","currentRowIndex","extractRowSpanningCellBreakPositions","rowCount","currentRow","spanningCellRowIndex","occupiedSlotIndices","rowCellBreakPositions","rowNodeContext","cont1","addDummyCellUntil","upperColumnIndex","dummy","breakChunkPosition","layoutCell","getColumnCount","inHeader","inFooter","currentColumnIndex","layoutRowSpanningCellsFromPreviousFragment","registerCellFragmentIndex","resetColumn","tdNodeStep","getElementOffset","Layout.registerFragmentIndex","afterNodeContext","hasBrokenCellAtSlot","startNodePosition","startTableRow","startTableCell","ignoreList","table-caption","table-column-group","table-column","tableLayoutOptionCache","TableLayoutProcessor","lastRow","dummyRow","dummyCells","tableElement","colGroups","firstElementChild","cols","colGroup","cloneNode","createDocumentFragment","getColumnWidths","getColGroupElements","normalizeAndGetColElements","addMissingColElements","initializeRepetitiveElements","tableLayoutOption","tableRootSourceNode","pair","getTableLayoutOption","clearTableLayoutOptionCache","layoutEntireTable","tableBBox","calculateBreakPositionsInside","EntireTableBreakPosition","normalizeColGroups","updateCellSizes","caption","addCaptions","addColGroups","iterator","RepetitiveElementImpl.appendHeaderToAncestors","LayoutRetryer","cellContentElement","getColumnElement","cellElement","cellElementRect","adjustCellHeight","finishFragment","tableFormattingContext","LayoutFragmentedTable","LayoutEntireTable","removeColGroups","RepetitiveElementImpl.LayoutEntireBlock","tableNodeContext","EntireTableLayoutConstraint","tableRootNode","RepetitiveElementImpl.LayoutFragmentedBlock","TableRowLayoutConstraint","equalsTo","RepetitiveElementImpl.RepetitiveElementsOwnerLayoutConstraint","collectCellFragmentLayoutConstraints","cellFragmentLayoutConstraints","removeDummyRowNodes","array","dummyNode","getCellFragemnts","findCellFromColumn","collectElementsOffsetOfUpperCells","collectElementsOffsetOfHighestColumn","tableLayoutProcessor","mean","ColumnBalancingTrialResult","layoutResult","getBlockSize","setBlockSize","ColumnBalancer","layoutContainer","columnGenerator","regionPageFloatLayoutContext","originalContainerBlockSize","preBalance","savePageFloatLayoutContexts","candidates","createTrialResult","updateCondition","restoreContents","postBalance","calculatePenalty","detachChildren","columnPageFloatLayoutContexts","newLayoutResult","columns","attachChildren","COLUMN_LENGTH_STEP","canReduceContainerSize","lastCandidate","secondLastCandidate","reduceContainerSize","newEdge","BalanceLastColumnBalancer","totalBlockSize","originalPosition","checkPosition","isLastColumnLongerThanAnyOtherColumn","foundUpperBound","lastColumnBlockSize","BalanceNonLastColumnBalancer","meanValue","MathUtil.variance","SlipRange","endStuckFixed","endFixed","endSlipped","SlipMap","slipped","Box","atBlockStart","atFlowStart","isParentBoxDisplayed","hasBox","beforeBox","styleValue","getBreakValue","afterBox","styleValues","cv","isBlockValue","displayValue","hasBoxValue","BoxStack","lastBox","newFlowChunk","atStartStack","isAtFlowStart","isCurrentBoxDisplayed","Vtree.canIgnore","Vtree.whitespaceFromPropertyValue","buildAfterPseudoElementBox","atStart","Styler","primaryFlows","cascadeHolder","createInstance","offsetMap","rootOffset","lastOffset","boxStack","addStuckRange","getAttrStyle","pushElement","postprocessTopStyle","bodyReached","primaryStack","replayFlowElementsFromOffset","srcStyle","pname","rootStyle","CssParser.SPECIFICITY_AUTHOR","elemStyle","isBody","rootBackgroundAssigned","backgroundColor","hasProp","backgroundProps","backgroundImage","transferPropsToRoot","rootLayoutAssigned","columnProps","layoutProps","unitSize","styleUntil","CSSStyleDeclaration","CssCascade.parseStyleAttribute","CssCascade.getProp","flowNameStr","encounteredFlowElement","getNodeByOffset","nodeOffset","getNodeOffset","flowListener","flowChunks","encounteredFlowChunk","flowToReach","idToReach","optionsCV","options","CssProp.toSet","lingerCV","CssProp.toInt","priorityCV","breakBeforeValues","flow","lastFlowName","Vtree.Flow","Vtree.FlowChunk","forcedBreakOffsets","previousValue","lookup","slippedOffset","targetSlippedOffset","slippedByFixed","getMaxSlipped","fixedBySlipped","popElement","afterPseudoBreakBefore","registerForcedBreakOffset","nearestBlockStartOffset","encounteredTextNode","addSlippedRange","blockStartOffset","beforePseudoBreakAfter","validator","Connection","where","ValidatingGroup","nodeIndex","connections","what","group","clonedNode","connection","groupConnection","nomatch","clause","ALWAYS_FAIL","markAsStartAlternate","markAsEndAlternate","markAsStartGroup","markAsEndGroup","connect","failure","arrs","addSpecialToArr","emptyHead","isSimple","PrimitiveValidator","how","ALTERNATE","isPrimitive","combine","connectionIndex","REPEATED","OPTIONAL","successTerminal","failTerminal","ALLOW_EMPTY","ALLOW_STR","ALLOW_IDENT","ALLOW_POS_NUMERIC","ALLOW_POS_NUM","ALLOW_POS_INT","ALLOW_COLOR","ALLOW_URL","ALLOW_NEGATIVE","ALLOW_ZERO","ALLOW_ZERO_PERCENT","ALLOW_SLASH","PropertyValidator","rval","idents","units","NO_IDENTS","ListValidator","failureTerminal","startIndex","alternativeStack","alternatives","inval","outval","isStartGroup","isEndGroup","isEndAlternate","getAlternate","SpaceListValidator","CommaListValidator","validateSingle","validateList","hasCommaListValidator","validateForShorthand","FuncValidator","ShorthandSyntaxNode","shorthandValidator","ShorthandSyntaxProperty","validators","rvals","len","ShorthandSyntaxPropertyN","ShorthandSyntaxCompound","index0","tryParse","ShorthandValidator","syntax","propList","receiver","defaultValues","SimpleShorthandValidator","InsetsShorthandValidator","shorthandValidators","SIMPLE","INSETS","INSETS_SLASH","slashIndex","index1","vals","acc","FONT","familyList","family","systemFonts","ValidatorSet","cssval","CssParser.colorFromHash","subgroup","startClause","addGroup","FOLLOW","endClause","startSpecialGroup","endSpecialGroup","addPrimitive","primitive","namedValidators","%","vi","vb","vmin","vmax","pvi","pvb","pvmin","pvmax","deg","grad","rad","turn","ms","Hz","kHz","stdfont","section","rulePrefixes","isBuiltIn","prefixes","readNameAndPrefixes","expectval","newGroup","setop","currop","builtIn","newFunc","addReplacement","addCounts","setOwner","syntaxNodeForProperty","shorthands","insetShorthand","createSyntaxNode","compound","parseValidators","parseDefaults","parseShorthands","makePropSet","shorthand","pval","origName","unknownProperty","rvalue","invalidPropertyValue","propagateInherit","baseValidatorSet","initBuiltInValidators","ValidationTxt","traitProps","bogusFontData","bogusFontCounter","prepareProperties","properties","fillDefaults","Face","fontTraitKey","makeFontTraitKey","fontBytes","blobURL","blob","createObjectURL","blobURLs","blobs","DocumentFaces","deobfuscator","srcFace","viewFace","srcFamily","viewFamilyFromSrc","familyMap","viewFamilyFromView","newValues","rf","Mapper","opt_familyPrefix","familyPrefix","documentFaces","viewFamily","familyCounter","getViewFontFamily","viewFontFace","killTime","bogusData","makeAtRule","Net.makeBlob","initWidth","initHeight","loaded","currWidth","currHeight","sleep","srcURLMap","piggyback","viewFaceParam","traitsEqual","registerFamily","Net.XMLHttpRequestResponseType","BLOB","initFont","srcFaces","loadFont","TaskUtil.waitForFetchers","keyCount","PageBox","_scope","parentInstance","param","specified","destSpecified","RootPageBox","Css.fullWidth","Css.fullHeight","PageMasterScope","Exprs.LexicalScope","pageMaster","isFunc","keyMap","boxInstance","lookupInstance","resolveFunc","resolveName","PageMaster","PageMasterInstance","copySpecified","cloneChildren","PartitionGroup","PartitionGroupInstance","Partition","PartitionInstance","toExprAuto","toExprZero","toExprZeroAuto","toExprZeroBorder","styleVal","toExprBool","PageBoxInstance","pageBox","calculatedWidth","calculatedHeight","Exprs.add","namedValues","addNamedValues","altName","CssCascade.couplingMapVert","CssCascade.couplingMapHor","namedFuncs","columnGap","Exprs.sub","Exprs.mul","minPageWidth","minPageHeight","boxSpecificEnabled","parentWidth","leftBP","rightBP","extra","autoWidth","isAutoWidth","remains","parentHeight","topBP","bottomBP","autoHeight","isAutoHeight","toExprNormal","Exprs.div","depend","registerInstance","getActiveRegions","CssCascade.flattenCascadedStyle","CssCascade.isVertical","CssCascade.isRtl","CssCascade.convertToPhysical","initHorizontal","initVertical","initColumns","initEnabled","Css.toNumber","CssCascade.getSpecial","docFaces","propagatePropertyToElement","Exprs.needUnitConversion","Css.convertNumericToPx","filterFontFamily","Vtree.DelayedItem","getPropAsNumber","xpos","snapOffsetX","ypos","snapOffsetY","assignRightPosition","assignTopPosition","assignLeftPosition","assignBottomPosition","isTopDependentOnAutoHeight","isRightDependentOnAutoWidth","sizeWithMaxWidth","sizeWithMaxHeight","assignBeforePosition","assignAfterPosition","assignStartEndPosition","passPreProperties","propagateProperty","passContentProperties","passSingleUriContentProperties","readHeight","readWidth","bbox","ruleWidth","ruleStyle","ruleColor","containerSize","border","rule","passPostProperties","delayedProperties","propagateDelayedProperty","docElementStyle","CssCascade.isPropName","CssCascade.setProp","userAgentPageMasterPseudo","pushRule","CssCascade.ContentPropVisitor","applyCascadeAndInit","popRule","depends","childInstance","resolveAutoSizing","RootPageBoxInstance","pageMasterInstance","listVal","conflicting","Css.Ident","qname","term","required","toExprIdent","processPartitionList","pmEnabledVal","pmEnabled","prepareContainer","PageBoxParserHandler","PartitionParserHandler","PartitionGroupParserHandler","Css.hundredPercent","partition","partitionGroup","PageMasterParserHandler","resolvePageProgression","Constants.PageProgression","pageSizes","a5","a4","a3","b5","b4","jis-b5","jis-b4","letter","legal","ledger","defaultPrinterMarkLineWidth","defaultPrinterMarkOffset","defaultPrinterMarkLineLength","defaultBleedOffset","resolvePageSizeAndBleed","pageSizeAndBleed","bleed","Css.numericZero","bleedOffset","val1","isSpaceList","marks","hasCrop","evaluatePageSizeAndBleed","evaluated","cropOffset","createPrinterMarkSvg","createPrinterMarkElement","lineWidth","elementType","CornerMarkPosition","CrossMarkPosition","addPrinterMarks","evaluatedPageSizeAndBleed","printerMarkOffset","bgcolor","cropMarkLineLength","bleedMarkLineLength","maxLineLength","svgWidth","points1","points2","TOP_RIGHT","BOTTOM_RIGHT","BOTTOM_LEFT","line1","line2","createCornerMark","longLineLength","BOTTOM","horizontalLine","verticalLine","opposite","LEFT","RIGHT","createCrossMark","propertiesAppliedToPartition","outline","outline-width","outline-style","outline-color","MarginBoxPositionAlongVariableDimension","pageMarginBoxes","top-left-corner","isInTopRow","isInBottomRow","isInLeftColumn","isInRightColumn","positionAlongVariableDimension","top-left","START","top-center","CENTER","top-right","top-right-corner","right-top","right-middle","right-bottom","bottom-right-corner","bottom-right","bottom-center","bottom-left","bottom-left-corner","left-bottom","left-middle","left-top","pageMarginBoxNames","pageRuleMasterPseudoName","marginBoxesKey","PageRuleMaster","PageMaster.PageMaster","pageSize","PageRulePartition","bodyPartitionKey","createPageMarginBoxes","applySpecified","marginBoxesMap","PageMarginBoxPartition","PageRuleMasterInstance","PageMaster.Partition","PageRulePartitionInstance","marginBoxName","ownStyle","ownVal","CssCascade.inheritedProps","PageMarginBoxPartitionInstance","PageMaster.PageMasterInstance","pageRuleMaster","pageAreaDimension","borderBoxWidth","borderBoxHeight","marginBoxContainers","marginBoxes","horizontalDimensions","verticalDimensions","sizeMarginBoxesAlongVariableDimension","isHorizontal","containers","boxInstances","boxParams","boxInfo","pageMarginBoxInstances","boxParam","SingleBoxMarginBoxSizingParam","evaluatedDim","getSizesOfMarginBoxesAlongVariableDimension","needRecalculate","maxOuterSizes","PageMaster.toExprAuto","evaluatedMaxSize","FixedSizeMarginBoxSizingParam","getOuterSize","minOuterSizes","minSize","evaluatedMinSize","startEndSum","outerSize","availableSize","startBoxParam","centerBoxParam","endBoxParam","startEndBoxParam","MultipleBoxesMarginBoxSizingParam","centerSizes","distributeAutoMarginBoxSizes","xSize","startEndAutoSize","hasAutoSize","startEndSizes","ySize","xOuterMaxContentSize","getOuterMaxContentSize","yOuterMaxContentSize","maxContentSizeSum","xOuterMinContentSize","getOuterMinContentSize","minContentSizeSum","hasAutoSize_","fixedSize","PageMaster.PartitionInstance","pageRulePartition","setPageAreaDimension","resolvePageBoxDimensions","borderBoxExtent","marginStart","marginEnd","endSide","extentName","pageExtent","paddingStart","PageMaster.toExprZero","paddingEnd","borderStartWidth","PageMaster.toExprZeroBorder","borderEndWidth","pageMarginBoxPartition","applyVerticalAlign","flexAlign","availableExtent","outerExtent","insideName","outsideName","outside","pageMargin","marginInside","PageMaster.toExprZeroAuto","marginOutside","paddingInside","paddingOutside","borderInsideWidth","borderOutsideWidth","getComputedValues","pageMarginValue","borderAndPadding","positionAndSizeAlongFixedDimension","finishContainer","PageManager","rootPageBoxInstance","definePageProgression","isEvenPage","pageProgression","resetScope","makeCacheKey","pageMasterCache","PageMaster.userAgentPageMasterPseudo","generatePageRuleMaster","generateCascadedPageMaster","propsStr","makeCascadeValueObjectKey","newPageMaster","pageMasterStyle","CssCascade.cascadeValues","CheckPageTypeAction","CssCascade.ChainedAction","IsFirstPageAction","IsLeftPageAction","IsRightPageAction","IsRectoPageAction","IsVersoPageAction","ApplyPageRuleAction","CssCascade.ApplyRuleAction","CssCascade.mergeIn","targetMap","CssCascade.getMutableStyleMap","boxName","targetBox","mergeInPageRule","PageParserHandler","CssCascade.CascadeParserHandler","pageProps","currentNamedPageSelector","currentPseudoPageClassSelectors","selectors","currentPageSelectors","finishSelector","selector","noPageSelectorProps","prevCascVal","marginBoxMap","boxStyle","PageMarginBoxParserHandler","transformURIs","attributeValue","m1","namespacePrefixMap","frontEdgeBlackListHor","margin-top","padding-top","border-top-width","border-top-style","border-top-color","border-top-left-radius","border-top-right-radius","frontEdgeBlackListVert","margin-right","padding-right","border-right-width","border-right-style","border-right-color","border-bottom-right-radius","frontEdgeUnforcedBreakBlackListHor","frontEdgeUnforcedBreakBlackListVert","ViewFactory","footnoteStyle","stylerProducer","customRenderer","fallbackMap","cascStyle","getPseudoMap","addedNames","att","PseudoElement.pseudoNames","content","shadowStyler","PseudoElement.PseudoelementStyler","Vtree.ShadowContext","Vtree.ShadowType","ROOTLESS","computedPseudoStyleMap","computedPseudoStyle","CssCascade.mergeStyle","CssCascade.mergeViewConditionalStyles","CssCascade.forEachStylesInRegion","CssCascade.forEachViewConditionalStyles","load","refDocParam","refDoc","refElement","getElement","refStyler","getStylerForDoc","templateURLVal","createRefShadow","shadow","cont2","createPseudoelementShadow","displayValues","Display.getComputedDislayValue","shadowRoot","nodeStyle","inheritanceVisitor","CssCascade.InheritanceVisitor","CssCascade.isInherited","Css.processingOrderFn","setPropName","sname","CssCascade.getPolyfilledInheritedProps","numericVal","needToProcessChildren","inheritedValues","inheritFromSourceParent","PageFloats.floatReferenceOf","computeStyle","processContent","transferPolyfilledInheritedProps","inheritLangAttribute","createShadows","shadowParam","parentWritingMode","isFlowRoot","Display.isFlowRoot","Display.establishesBFC","Display.establishesCBForAbsolute","isInsideBFC","floating","listItem","Display.isInlineLevel","Display.isRubyInternalDisplay","borderCollapse","borderSpacing","outerPseudo","Vtree.FirstPseudo","processAfterIfcontinues","whitespaceValue","wordBreak","overflowWrap","resolveFormattingContext","isFirstTime","processRepeatOnBreak","findAndProcessRepeatingElements","custom","elemResult","tag","PseudoElement.PSEUDO_ATTR","imageRef","imageBinary","innerSrc","TaskUtil.loadElement","fb2Remap","NCX","navParent","childElement","hp","dataset","iframe","contentWindow","navigator","version","layoutStyle","hasFeature","initIFrame","imageResolution","images","cssWidth","cssHeight","attrWidth","attrHeight","hasAutoWidth","hasAutoHeight","attributes","attributeCount","delayedSrc","attribute","attributeNS","nodeValue","registerElementWithId","image","Image","isSVGUrlAttribute","Urls.transformURIs","attributePrefix","imageFetcher","listStyleImage","listStyleURL","preprocessElementStyle","applyComputedStyles","blackList","modifyElemDimensionWithImageResolution","Layout.AfterIfContinues","SVG_URL_ATTRIBUTES","scaledWidth","scaledHeight","numericMaxWidth","numericMaxHeight","numericMinWidth","numericMinHeight","PREPROCESS_ELEMENT_STYLE","RepetitiveElement.RepetitiveElementsOwnerFormattingContext","parentFormattingContext","preprocessTextContent","Diff.restoreNewText","originl","PREPROCESS_TEXT_CONTENT","processedText","originalText","Diff.diffChars","createElementView","createTextNodeView","processChildren","createNodeView","contentNode","contentShadowType","contentShadow","resetView","Vtree.NodeContext","processShadowContent","shadowNode","sr","transclusionType","proc","nextPositionInTree","bg","addImageFetchers","isRelativePositioned","propertiesNotPassedToDOM","CssProp.UrlTransformVisitor","Vtree.delayedProps","Vtree.delayedPropsIfRelativePositioned","pn","childComputedStyle","boxDecorationBreak","Exprs.isFontRelativeLengthUnit","CssCascade.convertFontRelativeLengthToPx","step1","step2","elem1","parentElement","elem2","PseudoElement.getPseudoName","nodePosition1","nodePosition2","sup","tr","td","th","date","emphasis","strong","strikethrough","box-decoration-break","float-min-wrap-block","float-reference","flow-into","flow-options","footnote-policy","DefaultClientLayout","layoutBox","originRect","viewportLeft","viewportTop","rects","layoutBoxRect","subtractOffsets","getComputedStyle","Viewport","opt_root","opt_width","opt_height","outerZoomBox","contentContainer","innerWidth","innerHeight","ELEMENT_OFFSET_ATTR","XMLDocHolder","langs","SSE","NodeList","offsetStr","srcNode","totalOffset","idMap","xmlid","buildIdMap","getElementsByName","DOMParserSupportedType","parseAndReturnNullIfError","opt_parser","docElement","errorTagName","parseXMLResource","supportedKeys","APPLICATION_XML","TEXT_HTML","APPLICATION_XHTML_XML","IMAGE_SVG_XML","resolveContentType","Predicate","check","opt_childPredicate","predicate","pr","forEachNode","forEachNonNull","uaStylesheetBaseFetcher","CssValidator.baseValidatorSet","CssParser.StylesheetFlavor","CssCascade.setUABaseCascade","CssParser.parseStylesheetFromText","Style","rootBox","fontFaces","footnoteProps","flowProps","viewportProps","fontDeobfuscator","defineBuiltIn","currentLayoutPosition","firstFlowChunkOfFlow","matchPageSide","startSideOfFlow","lookupOffset","flowChunkIsAfterParentFlowForcedBreak","pageNumberOffset","Exprs.Context","CssCascade.mergeAll","textZoom","scaleFactor","defaultFontSize","widthVal","heightVal","StyleInstance","defaultLang","fontMapper","faces","Font.DocumentFaces","rootPageFloatLayoutContext","createCounterListener","createCounterResolver","CssStyler.Styler","setStyler","resetFlowChunkStream","stylerMap","getTopContainerStyle","CssPage.resolvePageProgression","PageMaster.RootPageBoxInstance","pageManager","CssPage.PageManager","fontFace","Font.prepareProperties","Font.Face","findOrLoadFonts","CssPage.evaluatePageSizeAndBleed","CssPage.resolvePageSizeAndBleed","pageSheetSize","getStyleForDoc","pageBoxInstances","Vtree.FlowPosition","Vtree.ChunkPosition","Vtree.FlowChunkPosition","chunkOffset","layoutPosition","noLookAhead","currentPosition","styleUntilFlowIsReached","consumedOffset","getConsumedOffset","flowChunkBreakBefore","flowBreakAfter","Break.startSideValueToBreakValue","Break.breakValueToStartSideValue","getPosition","pageMasters","CssPage.pageRuleMasterPseudoName","coeff","pageArea","updateStartSide","layoutPositionAtPageStart","initLingering","getPageRulePageMaster","breakOffsetBeforeStartIndex","breakOffsetBeforeStart","parentFlowPosition","parentStartOffset","LayoutProcessor.BlockFormattingContext","parentInvalidated","validate","setFormattingContextToColumn","layoutDeferredPageFloats","repeatedIndices","removedIndices","hasContinuingFloatFragmentsInFlow","alt","isBetter","getLastAfterPositionIfDeferredFloatsExists","saveDistanceToBlockEndFloats","getMaxReachedAfterEdge","counterConstraint","createLayoutConstraint","Layout.AllLayoutConstraint","forceNonFitting","dontApplyExclusions","boxContainer","columnPageFloatLayoutContext","positionAtColumnStart","columnContainer","Layout.Column","columnY","columnX","copyFrom","layoutColumn","pagePageFloatLayoutContext","CssPage.PageRulePartitionInstance","CssPage.PageRuleMasterInstance","positionAtContainerStart","getRegionPageFloatLayoutContext","layoutColumns","layoutFlowColumns","generatorResult","columnFill","columnBalancer","noMoreContent","lastColumn","isLastColumnForceBroken","Columns.createColumnBalancer","lock","balanceColumns","unlock","Vgen.ViewFactory","createAndLayoutColumn","isLocked","pageBreaks","dontExclude","Vtree.Container","setPagePageFloatLayoutContextContainer","removed","isIdent","layoutFlowColumnsWithBalancing","innerContainerTag","innerContainer","transferSinglUriContentProps","transferContentProps","suppressEmptyBoxGeneration","outerShape","startPage","Vtree.LayoutPosition","getCascadedPageStyle","selectPageMaster","bleedBoxPaddingEdge","setAutoPageWidth","setAutoPageHeight","setCurrentPage","updatePageCounters","setPageSizeAndBleed","CssPage.addPrinterMarks","adjustPageLayout","isLeftPage","Constants.PageSide","processLinger","getReachedOffset","getTriggersForDoc","noMorePrimaryFlows","pageSheetWidth","pageSheetHeight","BaseParserHandler","masterHandler","PageMaster.PageMasterParserHandler","CssCascade.DefineParserHandler","CssCascade.PropSetParserHandler","insideRegion","pageHandler","CssPage.PageParserHandler","regionCount","special","regionHandler","processViewportMeta","meta","StyleParserHandler","CssParser.DispatchParserHandler","PageMaster.RootPageBox","cascadeParserHandler","parseOPSResource","OPSDocStore","Net.ResourceStore","authorStyleSheets","userStyleSheets","setStyleSheets","userAgentXML","triggerSingleDocumentPreprocessing","styleByDocURL","triggersByDocURL","clearStyleSheets","addAuthorStyleSheet","addUserStyleSheet","styleSheets","stylesheet","Base.convertSpecialURL","Base.baseURL","XmlDoc.parseXMLResource","PREPROCESS_SINGLE_DOCUMENT","triggerList","getElementsByTagNameNS","triggerElem","EV","sources","userAgentURL","UserAgentPageCss","title","rel","getElementsByTagName","styleByKey","styleFetcherByKey","sph","source","CssParser.parseStylesheetFromURL","encode32","decode32","bytes","bytesToSHA1Int32","appendCount","w","bi","bytesToSHA1Hex","sha1","bytesToSHA1Bytes","bulletClosed","bulletOpen","bulletEmpty","TOCView","rendererFactory","Exprs.clonePreferences","setAutoHeight","renderer","makeCustomRenderer","srcElem","viewParent","behavior","querySelector","replaceChild","createComment","adaptParentClass","button","toggleNodeExpansion","tabIndex","anchorElem","Vtree.Page","tocBoxUrl","nonTocBoxDoc","viewportSize","sizeViewport","Vgen.Viewport","OPS.StyleInstance","layoutNextPage","bodyChildElem","tocNodeElem","ce","adaptClass","stopPropagation","EPUBDocStore","OPS.OPSDocStore","makeDeobfuscatorFactory","plainXMLStore","jsonStore","deobfuscators","haveZipMetadata","loadEPUBDoc","opf","pubURL","loadOPF","loadAsJSON","manifestObj","OPFDoc","initWithWebPubManifest","loadWebPub","startLoadingAsJSON","startLoadingAsPlainXML","containerURL","loadAsPlainXML","containerXML","roots","opfByURL","opfXML","encXML","zipMetadata","initWithXMLDoc","primaryOPFByEPubURL","manifestLink","xhtmlToc","docURL","documents","OPFItem","itemProperties","Base.emptyObj","itemElem","opfURL","mediaType","propStr","Base.arrayToSet","skipPagesBefore","getOPFItemId","makeDeobfuscator","uid","sha1Sum","SHA1.bytesToSHA1Int8","fileReader","FileReader","readAsArrayBuffer","Net.readBlob","dataView","DataView","byteLength","getUint8","setUint8","predefinedPrefixes","dcterms","marc","rendition","onix","xsd","defaultIRI","metaTerms","language","creator","titleType","displaySeq","alternateScript","getMetadataComparator","item1","item2","m2","i1","i2","getMathJaxHub","math","supportedMediaTypes","application/xhtml+xml","image/jpeg","image/png","image/svg+xml","image/gif","audio/mp3","transformedIdPrefix","createDocumentURLTransformer","CssCascade.supportedNamespaces","MATHML","Base.escapeNameStrToHex","path","items","encoded","Base.unescapeStrFromHex","metadata","epubBaseURL","decodeURI","manifestURL","pkg","uidref","uidElem","srcToFallbackId","asArray","initWithElement","fallback","cover","itemMap","Base.indexArray","itemMapByPath","getPathFromURL","fallbackSrc","spine","itemRefElement","tocAttr","ncxToc","pageProgressionAttr","Constants.pageProgressionOf","idpfObfURLs","XmlDoc.predicate","withChild","withAttribute","mediaTypeElems","handlerId","bindings","mroot","prefixMap","resolveProperty","iri","rawItems","refines","scheme","DC","rawItemsByTarget","Base.multiIndexArray","rawItem","makeMetadata","Base.mapObj","rawItemArr","itemName","schema","langItem","entryMap","sortMetadata","readMetadata","prePaginated","assignAutoPages","manifestText","obfuscations","obfuscationKey","SHA1.bytesToSHA1Hex","encodedPath","compressed","compressedSize","obfuscation","DEFAULT","epage","epageCount","epageCountCallback","epageIsRenderedPage","offsetPerEPage","getTotalOffset","XmlDoc.XMLDocHolder","initWithParam","itemref","addDocument","primaryEntryPath","encodeURI","hrefNoFragment","itemCount","tocFound","readingOrderOrResources","itemObj","isInReadingOrder","encodingFormat","initWithChapters","offsetInItem","cfi","CFI.Fragment","prependPathFromNode","fromString","opfNav","navigate","idref","nodeNav","makePageAndPosition","OPFView","pageSheetSizeReporter","Vgen.DefaultClientLayout","Counters.CounterStore","viewItem","spineItems","oldPage","isFirstPage","prevItem","newPage","insertPos","makePage","posParam","layoutPositions","finishPageContainer","finishPage","prevPos","renderSinglePage","getUnresolvedRefsToPage","getPageViewItem","pushPageCounters","pushReferencesToSolve","popPageCounters","popReferencesToSolve","resultPosition","pageAndPosition","isLastPage","finishLastPage","nextLayoutPosition","seekOffset","seekOffsetPageIndex","complete","sync","resultPage","normalizedPosition","normalizeSeekPosition","renderPage","renderPagesUpto","notAllPages","lastResult","findPage","nextViewItem","nextPage","spineItemLoadingContinuations","isLeft","isLTR","getCurrentPageProgression","getPage","isRectoPage","previousPage","otherPageAndPosition","thisPage","otherPage","isRecto","next2","result2","oldPrevPageCont","resolveEPage","resolveFragment","restored","restoreURL","navigateToFragment","pageCont","Constants.isDebug","matrix","Exprs.letterbox","cssMatrix","handlerSrc","srcParam","Base.lightURLEncode","typeParam","pvalue","hub","clonedMath","importNode","resolveURLsInMathML","tagName","attrs","newUrl","srcTagName","makeObjectView","makeMathJaxView","makeSSEView","loadingContinuations","previousViewItem","forceSetPageCounter","pubTitles","autohide","toc","tocAutohide","tocView","Toc.TOCView","tocWidth","tocHeight","showTOC","hideTOC","isTOCVisible","VIEWPORT_STATUS_ATTRIBUTE","VIEWPORT_SPREAD_VIEW_ATTRIBUTE","PageViewMode","ZoomType","AdaptiveViewer","viewportElement","instanceId","callbackFn","Font.Mapper","kick","sendCommand","resizeListener","needResize","pageReplacedListener","hyperlinkListener","pageRuleStyleElement","loadPublication","loadXML","configure","moveTo","addLogListeners","Constants.ReadyState","LOADING","packageURL","touchActive","touchX","touchY","needRefresh","currentSpread","pagePosition","zoom","fitToScreen","pageViewMode","SINGLE_PAGE","waitForLoading","renderAllPages","logLevel","Logging.LogLevel","addListener","command","Profile.profiler","setReadyState","authorStyleSheet","userStyleSheet","Epub.EPUBDocStore","loadPubDoc","render","resolvedParams","Epub.OPFDoc","cancelRenderingTask","resize","matched","vp","resolveLength","Base.setBaseURL","Base.setResourceBaseURL","configurePlugins","CONFIGURATION","showCurrent","forCurrentPages","removePageListeners","hidePages","showSinglePage","leftWidth","rightWidth","getCFI","sendLocationNotification","vs","SPREAD","AUTO_SPREAD","createViewport","resolveSpreadView","spreadViewChanged","updateSpreadView","userAgent","opfView","hasPages","hasAutoSizedPages","setPageSizePageRules","pageSheetSizeAlreadySet","styleText","tocVisible","removeRenderedPages","removePageSizePageRules","resetZoom","Epub.OPFView","setPageSize","getSpread","showSpread","setSpreadZoom","showPage","setPageZoom","getAdjustedZoomFactor","getSpreadDimensions","pageDimension","calculateZoomFactorToFitInsideViewPort","FIT_INSIDE_VIEWPORT","pageDim","widthZoom","heightZoom","renderTask","interrupt","RenderingCanceledError","sizeIsGood","resizeTask","setEPageCountMode","INTERACTIVE","countEPages","notification","reportPosition","COMPLETE","getEPageFromPosition","method","nextSpread","previousSpread","lastPage","firstPage","navigateToEPage","navigateTo","currentVisibility","changeAutohide","actionName","cmd","maybeParse","viewer","Task.start","hrefEvent","internal","runCommand","frameInternal","setPrototypeOf","convertViewerOptions","CoreViewer","settings","opt_options","Constants.setDebug","adaptViewer_","AdaptiveViewer.AdaptiveViewer","dispatcher","autoResize","pageBorderWidth","AdaptiveViewer.PageViewMode","setOptions","eventTarget","defineProperty","singleDocumentOptions","opt_documentOptions","opt_viewerOptions","loadDocumentOrPublication","pubUrl","documentOptions","convertStyleSheetArray","userAgentRootURL","convertSingleDocumentOptions","initialized","initEmbed","nav","Navigation","PREVIOUS","NEXT","opt_epage","EPAGE","resolveNavigation","opt_show","opt_autohide","queryZoomFactor","toNumberOrNull","opt","isArray","AdaptiveViewer.ZoomType","forceRegisterEndTiming","VivliostylePrint","htmlDoc","printCallback","iframeWin","hideIframe","removeIframe","borderWidth","printInstance","srcdoc","viewportCss","viewportScreenCss","preparePrint","browserPrint","cleanUp","docBlob","Viewer","CoreViewer.CoreViewer","Promise","loadDocument","config"],"mappings":";;;;;;;;kNAwBgBA,EAASC,GACvBC,UAAUD,WAeIE,EAAkBC,GAChC,OAAQA,GACN,IAAK,MACH,OAAOC,kBAAgBC,IACzB,IAAK,MACH,OAAOD,kBAAgBE,IACzB,QACE,MAAM,IAAIC,MAAM,4BAA4BJ,MAQlD,IAAYK,EASAC,aAzCkB,EAS9B,SAAYL,GACVA,YACAA,YAFF,CAAYA,oBAAAA,wBAuBAI,EAAAA,aAAAA,4BAEVA,iBAOUC,EAAAA,eAAAA,oCAEVA,4BACAA,4BAMWC,EAAY,iBACvBN,2BACAI,sBACAC,cCpDF,IAAYE,GAAZ,SAAYA,GACVA,qBACAA,mBACAA,mBACAA,qBAJF,CAAYA,IAAAA,OAqHZ,SAASC,EAAqBC,GAC5B,MAAMC,EAAIC,MAAMC,KAAKH,GACrB,IAAII,EAAW,KAIf,OAHIH,EAAE,aAAcP,QAClBU,EAAIH,EAAEI,SAED,CAAEC,MAAOF,EAAGG,SAAUN,GAG/B,SAASO,EAA0BR,GACjC,MAAMI,EAAIJ,EAAKM,MACTG,EAAQL,IAAMA,EAAc,YAAKA,EAAS,OAChD,IAAIG,EAAW,GAAGG,OAAOV,EAAe,UAUxC,OATII,IACEG,EAASI,OAAS,IACpBJ,EAAWA,EAASG,OAAO,CAAC,QAE9BH,EAAWA,EAASG,OAAO,CAACN,EAAY,aACpCK,IACFF,EAAWA,EAASG,OAAO,CAAC,OAAOA,OAAOD,KAGvCF,EAGF,MAAMK,EAAS,UA5HpBC,YAAoBC,GAAAC,iBAAAD,EAFZC,eAAiE,GAIjEF,aAAaG,GACfD,KAAKD,YACHC,KAAKD,YAAYG,MACnBF,KAAKD,YAAYG,SAASD,GAE1BD,KAAKD,YAAYI,OAAOF,GAG1BG,QAAQF,SAASD,GAIbH,YAAYG,GACdD,KAAKD,YACHC,KAAKD,YAAYM,KACnBL,KAAKD,YAAYM,QAAQJ,GAEzBD,KAAKD,YAAYI,OAAOF,GAG1BG,QAAQC,QAAQJ,GAIZH,YAAYG,GACdD,KAAKD,YACHC,KAAKD,YAAYO,KACnBN,KAAKD,YAAYO,QAAQL,GAEzBD,KAAKD,YAAYI,OAAOF,GAG1BG,QAAQE,QAAQL,GAIZH,aAAaG,GACfD,KAAKD,YACHC,KAAKD,YAAYR,MACnBS,KAAKD,YAAYR,SAASU,GAE1BD,KAAKD,YAAYI,OAAOF,GAG1BG,QAAQb,SAASU,GAIbH,iBAAiBS,EAAiBtB,GACxC,MAAMuB,EAAYR,KAAKQ,UAAUD,GAC7BC,GACFA,EAAUC,QAASC,IACjBA,EAASzB,KASfa,YAAYS,EAAiBG,GAC3B,IAAIF,EAAYR,KAAKQ,UAAUD,GAC1BC,IACHA,EAAYR,KAAKQ,UAAUD,GAAS,IAEtCC,EAAUG,KAAKD,GAGjBZ,SAASc,GACP,MAAM3B,EAAOD,EAAqB6B,WAClCb,KAAKc,aAAarB,EAA0BR,IAC5Ce,KAAKe,iBAAiBhC,EAASiC,MAAO/B,GAGxCa,QAAQc,GACN,MAAM3B,EAAOD,EAAqB6B,WAClCb,KAAKiB,YAAYxB,EAA0BR,IAC3Ce,KAAKe,iBAAiBhC,EAASmC,KAAMjC,GAGvCa,QAAQc,GACN,MAAM3B,EAAOD,EAAqB6B,WAClCb,KAAKmB,YAAY1B,EAA0BR,IAC3Ce,KAAKe,iBAAiBhC,EAASqC,KAAMnC,GAGvCa,SAASc,GACP,MAAM3B,EAAOD,EAAqB6B,WAClCb,KAAKqB,aAAa5B,EAA0BR,IAC5Ce,KAAKe,iBAAiBhC,EAASuC,MAAOrC,SCxG9BsC,GAAAA,EAAAA,UAAAA,+CAwBVA,0DAaAA,oDASAA,sDAOAA,0DAQAA,gCAYAA,wDAeAA,0DAUAA,sDAUAA,wCA+CF,MAAMC,EAAQ,YAWEC,EAAaC,EAAcC,GACzC,GAAKJ,QAAMG,GAEJ,CACL,IAAIE,EAAeJ,EAAME,GACpBE,IACHA,EAAeJ,EAAME,GAAQ,IAE/BE,EAAajB,KAAKgB,QANlBE,EAAevB,KAAK,IAAI3B,MAAM,iCAAiC+C,iBAiBnDI,EAAWJ,EAAcC,GACvC,GAAKJ,QAAMG,GAEJ,CACL,MAAME,EAAeJ,EAAME,GAC3B,GAAIE,EAAc,CAChB,MAAMG,EAAQH,EAAaI,QAAQL,GAC/BI,GAAS,GACXH,EAAaK,OAAOF,EAAO,SAN/BF,EAAevB,KAAK,IAAI3B,MAAM,iCAAiC+C,iBAgBnDQ,EAAgBR,GAE9B,OADqBF,EAAME,IACJ,SAMZS,EAAS,CACpBV,aAAAA,EACAK,WAAAA,SC3NWM,EAMXtC,YAA4BuC,GAAArC,yBAAAqC,EAL5BrC,gBAA2D,GAMzDA,KAAKsC,eAAiBC,EAGtBvC,KAA0B,oBAAIA,KAAKwC,oBAAsBD,EACzDvC,KAAwB,kBAAIA,KAAKyC,kBAAoBF,EASvDzC,yBAAyB4B,EAAcgB,GACrCJ,EAAeK,KAAK3C,KAAM0B,EAAM,QAASgB,GAS3C5C,uBAAuB4B,EAAcgB,GACnCJ,EAAeK,KAAK3C,KAAM0B,EAAM,MAAOgB,GAOzC5C,eACE,MAAM8C,EAAa5C,KAAK4C,WACxB,IAAIC,EAAK,GACTC,OAAOC,KAAKH,GAAYnC,QAASiB,IAC/B,MAAMsB,EAASJ,EAAWlB,GACpBuB,EAAID,EAAOpD,OACjB,IAAK,IAAIsD,EAAI,EAAGA,EAAID,EAAGC,IAAK,CAC1B,MAAMC,EAAIH,EAAOE,GACjBL,GAAMnB,EACFuB,EAAI,IACNJ,GAAM,IAAIK,MAEZL,GAAM,cAAcM,EAAS,eAAWA,EAAO,kBAAgBA,EACxD,IACHA,EAAS,aAGjBtB,EAAexB,KAAKwC,GAMtB/C,UACEE,KAAKsC,eAAiBC,EAGtBvC,KAA0B,oBAAIA,KAAKwC,oBAAsBD,EACzDvC,KAAwB,kBAAIA,KAAKyC,kBAAoBF,EAMvDzC,SACEE,KAAKsC,eAAiBA,EAGtBtC,KACuB,oBACnBA,KAAKwC,oBAAsBA,EAC/BxC,KAAwB,kBAAIA,KAAKyC,kBAAoBA,EAMvD3C,YACE,OAAOE,KAAKwC,sBAAwBA,GAIxC,SAASD,KAUT,SAASD,EACPZ,EACA0B,EACAV,GAEKA,IACHA,EAAY1C,KAAKqC,oBAAoBgB,OAEvC,IAIIF,EAJAP,EAAa5C,KAAK4C,WAAWlB,GAC5BkB,IACHA,EAAa5C,KAAK4C,WAAWlB,GAAQ,IAIvC,IAAK,IAAIwB,EADCN,EAAWhD,OACJ,EAAGsD,GAAK,IACvBC,EAAIP,EAAWM,IACXC,GAAMA,EAAEC,IAFcF,IAK1BC,EAAI,KAEDA,IACHA,EAAI,GACJP,EAAWjC,KAAKwC,IAElBA,EAAEC,GAAYV,EAUhB,SAASF,EAAoBd,EAAcgB,GACzC1C,KAAKsC,eAAeZ,EAAM,QAASgB,GAUrC,SAASD,EAAkBf,EAAcgB,GACvC1C,KAAKsC,eAAeZ,EAAM,MAAOgB,GAEnC,MAAMY,EAA8B,CAAED,IAAKE,KAAKF,KAEnCG,EAAW,IAAIpB,EADAqB,QAAUA,OAAOC,aAEpBJ,GAEzBE,EAASG,yBAAyB,0BAKrBC,EAAU,CACrBJ,SAAU,CACRhB,oBAAqBgB,EAAShB,oBAC9BC,kBAAmBe,EAASf,kBAC5BoB,aAAcL,EAASK,aACvBC,QAASN,EAASM,QAClBC,OAAQP,EAASO,SCtKd,IAAIC,EAAW,YAQNC,EAAa1F,GAC3B,OAAO2F,KAAKC,MAAM5F,YAGJ6F,EAAcC,GAC5B,MAAMC,EAAID,EAAIE,MAAM,YACpB,OAAID,EACKA,EAAE,GAEJD,EAcF,IAAIG,EAAUf,OAAOgB,SAASC,cACrBC,EAAWvG,GACzBoG,EAAUpG,EAOL,IAAIwG,EAAkBnB,OAAOgB,SAASC,cAC7BG,EAAmBzG,GACjCwG,EAAkBxG,WAQJ0G,EAAWC,EAAgBP,GACzC,GAAIA,EAAQQ,WAAW,SACrB,OAAOD,GAAUP,EAEnB,IAAKA,GAAWO,EAAOR,MAAM,YAC3B,OAAIQ,EAAOE,cAAcV,MAAM,gBACtB,KAELQ,EAAOR,MAAM,yBACfQ,EAAS,GAAGA,MAEPA,GAKT,IAAIT,EACJ,GAJIE,EAAQD,MAAM,yBAChBC,EAAU,GAAGA,MAGXO,EAAOR,MAAM,SAEf,OADAD,EAAIE,EAAQD,MAAM,kBACdD,EACKA,EAAE,GAAKS,EAETA,EAET,GAAIA,EAAOR,MAAM,OAEf,OADAD,EAAIE,EAAQD,MAAM,0BACdD,EACKA,EAAE,GAAKS,EAETA,EAMT,GAJIA,EAAOR,MAAM,eACfQ,EAASA,EAAOG,OAAO,IAEzBV,WAhEoCH,GACpC,MAAMC,EAAID,EAAIE,MAAM,aACpB,OAAID,EACKA,EAAE,GAEJD,EA2DGc,CAAsBX,GAC5BO,EAAOR,MAAM,MACf,OAAOC,EAAUO,EAEnB,IAAI7B,EAAIsB,EAAQY,YAAY,KAC5B,GAAIlC,EAAI,EACN,OAAO6B,EAET,GAAI7B,EAAIsB,EAAQ5E,OAAS,EAAG,CAE1B,GADU4E,EAAQY,YAAY,KACtBlC,EAAG,CAET,GAAc,IAAV6B,EACF,OAAOP,EAGTtB,GADAsB,GAAW,KACC5E,OAAS,GAGzB,IAAIyE,EAAMG,EAAQU,OAAO,EAAGhC,EAAI,GAAK6B,EACjCM,EAAY,GAOhB,IANAf,EAAID,EAAIE,MAAM,sBACVD,IACFD,EAAMC,EAAE,GACRe,EAAYf,EAAE,IAIdpB,EAAImB,EAAIrC,QAAQ,UACZkB,GAAK,IAFE,CAKX,MAAMoC,EAAIjB,EAAIe,YAAY,IAAKlC,EAAI,GACnC,GAAIoC,GAAK,EACP,MAEFjB,EAAMA,EAAIa,OAAO,EAAGI,GAAKjB,EAAIa,OAAOhC,EAAI,GAE1C,OAAOmB,EAAIkB,QAAQ,aAAc,KAAOF,WAM1BG,EAAkBnB,GAChC,IAAIC,EAgCJ,OA9BGA,EAAI,yEAAyEmB,KAC5EpB,IAIFA,EAAM,GAAGC,EAAE,iCAAiCA,EAAE,MAAMA,EAAE,GAAK,GAAK,YAC9DA,EAAE,MAGHA,EAAI,0EAA0EmB,KAC7EpB,IAIFA,EAAM,GAAGC,EAAE,gEAAgEA,EAAE,MAE5EA,EAAI,uEAAuEmB,KAC1EpB,IAIFA,EAAM,GAAGC,EAAE,kCAAkCA,EAAE,UAAUA,EAAE,MAE1DA,EAAI,+EAA+EmB,KAClFpB,MAIFA,EAAM,GAAGC,EAAE,wBAAwBA,EAAE,KAAKA,EAAE,OAEvCD,EAeT,IAAYqB,WAqDIC,EAASC,GACvB,OAAS,MAALA,EACKA,EAEFA,EAAEC,YAzDX,SAAYH,GACVA,mDACAA,sCACAA,yCACAA,8CACAA,6CACAA,uCACAA,uCACAA,2CACAA,mCACAA,wCACAA,6CACAA,+BAZF,CAAYA,IAAAA,aAsECI,EAAbhG,cACEE,WAAsB,CAAC,MAEvBF,SACE,OAAOE,KAAK+F,MAAMnG,OAAS,EAG7BE,IAAIkG,GACF,IAAIjE,EAAQ/B,KAAK+F,MAAMnG,OACvB,KAAOmC,EAAQ,GAAG,CAChB,MAAMkE,EAAcC,KAAKC,MAAMpE,EAAQ,GACjCqE,EAASpG,KAAK+F,MAAME,GAC1B,GAAIG,EAAOC,QAAQL,GAAQ,EAEzB,YADAhG,KAAK+F,MAAMhE,GAASiE,GAGtBhG,KAAK+F,MAAMhE,GAASqE,EACpBrE,EAAQkE,EAEVjG,KAAK+F,MAAM,GAAKC,EAMlBlG,OACE,OAAOE,KAAK+F,MAAM,GAOpBjG,SACE,MAAMwG,EAAStG,KAAK+F,MAAM,GACpBQ,EAAOvG,KAAK+F,MAAMS,MAClBC,EAAOzG,KAAK+F,MAAMnG,OACxB,GAAI6G,EAAO,EAAG,CACZ,IAAI1E,EAAQ,EACZ,OAAa,CACX,IAAI2E,EAAqB,EAAR3E,EACjB,GAAI2E,GAAcD,EAChB,MAEF,GAAIzG,KAAK+F,MAAMW,GAAYL,QAAQE,GAAQ,EAEvCG,EAAa,EAAID,GACjBzG,KAAK+F,MAAMW,EAAa,GAAGL,QACzBrG,KAAK+F,MAAMW,IACT,GAEJA,QAEG,CAAA,KACLA,EAAa,EAAID,GACjBzG,KAAK+F,MAAMW,EAAa,GAAGL,QAAQE,GAAQ,GAI3C,MAFAG,IAIF1G,KAAK+F,MAAMhE,GAAS/B,KAAK+F,MAAMW,GAC/B3E,EAAQ2E,EAEV1G,KAAK+F,MAAMhE,GAASwE,EAEtB,OAAOD,GAuBJ,MAAMK,EAAgB,CAAC,GAAI,WAAY,QAAS,OAAQ,MAAO,UAEzDC,EAAc,YAEXC,EACdC,EACAC,GAGA,GAAa,iBAATA,EAAyB,CAC3B,MAAMC,EAAQC,SAASC,cAAc,QACrC,MAAe,SAAXJ,GACFE,EAAMG,MAAMC,YAAYN,EAASC,EAAM,SACA,UAAhCC,EAAMG,MAAM,kBAEnBH,EAAMG,MAAMC,YAAYN,EAASC,EAAM,eACD,gBAA/BC,EAAMG,MAAML,EAASC,IAI9B,MAAmD,iBADrCE,SAASI,gBAAgBF,eAjCfL,EAAgBQ,GAQ1C,OAPIR,IACFQ,EAAc,IAAIA,IAEH,SADfR,EAASA,EAAOvB,QAAQ,KAAM,OAE5BuB,EAAS,QAIXA,EACAQ,EAAY/B,QAAQ,UAAYgC,GAAQA,EAAIrC,OAAO,GAAGsC,eAwBlCC,CAAYX,EAAQC,aAI5BW,EAAyBX,GACvC,IAAIY,EAAWf,EAAYG,GAC3B,GAAIY,GAAyB,OAAbA,EAEd,OAAOA,EAET,OAAQZ,GACN,IAAK,uBAEH,GACEF,EAAyB,WAAY,kBACpCA,EAAyB,GAAI,wBAG9B,OADAD,EAAYG,GAAQ,CAAC,wBACd,CAAC,wBAEV,MACF,IAAK,eAEH,GAAIF,EAAyB,OAAQ,gBAEnC,OADAD,EAAYG,GAAQ,CAAC,oBACd,CAAC,oBAEV,MACF,IAAK,SAEH,GAAIF,EAAyB,WAAY,UAEvC,OADAD,EAAYG,GAAQ,CAAC,kBACd,CAAC,kBAEV,MACF,IAAK,YAEH,GAAIF,EAAyB,WAAY,aACvC,OAAQD,EAAYG,GAAQ,CAAC,oBAAqB,aAEpD,MACF,IAAK,sBACH,GAAIF,EAAyB,WAAY,gBAEvC,OADAD,EAAYG,GAAQ,CAAC,wBACd,CAAC,wBAEV,MACF,IAAK,oBACH,GAAIF,EAAyB,WAAY,cAEvC,OADAD,EAAYG,GAAQ,CAAC,sBACd,CAAC,sBAEV,MACF,IAAK,uBACH,GAAIF,EAAyB,WAAY,iBAEvC,OADAD,EAAYG,GAAQ,CAAC,yBACd,CAAC,yBAEV,MACF,IAAK,qBACH,GAAIF,EAAyB,WAAY,eAEvC,OADAD,EAAYG,GAAQ,CAAC,uBACd,CAAC,uBAId,IAAK,MAAMD,KAAUH,EACnB,GAAIE,EAAyBC,EAAQC,GAGnC,OAFAY,EAAWb,EAASC,EACpBH,EAAYG,GAAQ,CAACY,GACd,CAACA,GAOZ,OAFA9F,EAAevB,KAAK,0CAA2CyG,GAC/DH,EAAYG,GAAQ,KACb,cAGOa,EACdC,EACAd,EACA3I,GAEA,IACE,MAAM0J,EAAwBJ,EAAyBX,GACvD,IAAKe,EACH,OAEFA,EAAsBrH,QAASkH,IAC7B,GAAiB,qBAAbA,EACF,OAAQvJ,GACN,IAAK,gBACHA,EAAQ,QACR,MACF,IAAK,cACHA,EAAQ,QACR,MACF,IAAK,cACHA,EAAQ,aAGP,GAAiB,yBAAbuJ,EACT,OAAQvJ,GACN,IAAK,MACHA,EAAQ,aAIVyJ,GAASA,EAAqBV,OAC/BU,EAAqBV,MAAMC,YAAYO,EAAUvJ,KAGtD,MAAO2J,GACPlG,EAAevB,KAAKyH,aAIRC,EACdH,EACAd,EACAkB,GAEA,IACE,MAAMC,EAAgBtB,EAAYG,GAClC,OAAQc,EAAqBV,MAAMgB,iBACjCD,EAAgBA,EAAc,GAAKnB,GAErC,MAAOgB,IACT,OAAOE,GAAa,YAGNG,EAAiBC,GAC/B,IAAIC,EAAOD,EAAQE,eAAe7C,EAAG8C,IAAK,QAI1C,OAHKF,GAAQD,EAAQI,cAAgB/C,EAAGgD,QACtCJ,EAAOD,EAAQM,aAAa,SAEvBL,QAGIM,EAAb9I,cACEE,UAAiB,GAEjBF,OAAOvB,GAEL,OADAyB,KAAK6I,KAAKlI,KAAKpC,GACRyB,KAGTF,QACEE,KAAK6I,KAAO,GAMd/I,WACE,MAAMvB,EAAMyB,KAAK6I,KAAKC,KAAK,IAE3B,OADA9I,KAAK6I,KAAO,CAACtK,GACNA,YAIKwK,EAAWxK,GAEzB,MAAO,KAAKA,EAAIyK,WAAW,GAAGnD,SAAS,gBAGzBoD,EAAevH,GAC7B,OAAOA,EAAK6D,QAAQ,+BAAgCwD,YAGtCG,EAAa3K,GAC3B,OAAOA,EAAIgH,QAAQ,sBAAuBwD,YAG5BI,EAAe5K,GAC7B,OAAOA,EAAIgH,QAAQ,2BAA4B6D,6BAGjCC,EAASC,GACvB,QAASA,EAAG/E,MACV,uHASYgF,EAAmBhL,EAAauI,GAI9C,OAAOvI,EAAIgH,QAAQ,mBAHnB,SAAoBiE,GAClB,gBAP4BjL,EAAauI,GAE3C,OADAA,EAA2B,iBAAXA,EAAsBA,EAAS,QAC9B,MAAQvI,EAAIyK,WAAW,IAAInD,SAAS,IAAIX,OAAO,GAKvDuE,CAAgBD,EAAG1C,eAKd4C,EAAanL,GAC3B,OAAOgL,EAAmBhL,YAYZoL,EAAmBpL,EAAauI,GAC9CA,EAA2B,iBAAXA,EAAsBA,EAAS,MAK/C,MAAM8C,EAAS,IAAIC,OAAO,GAAGH,EAAa5C,mBAAyB,KACnE,OAAOvI,EAAIgH,QAAQqE,GAJnB,SAAsBJ,GACpB,gBAbgCjL,EAAauI,GAE/C,OADAA,EAA2B,iBAAXA,EAAsBA,EAAS,MACnB,IAAxBvI,EAAIyD,QAAQ8E,GACPgD,OAAOC,aAAaC,SAASzL,EAAI0L,UAAUnD,EAAOlH,QAAS,KAE3DrB,EAQA2L,CAAoBV,EAAG1C,eAalBqD,EACdC,EACAC,GAEA,IAAIpH,EAAI,EACJqH,EAAIF,EACR,OAAa,CAIX,GAFoB,GAALnH,GAAWoH,EAAKpH,EAAI,GACpBqH,GAAKF,GAAQC,EAAKC,GAC7BrH,GAAKqH,EACP,OAAOrH,EAET,MAAMsH,EAAKtH,EAAIqH,GAAM,EACjBD,EAAKE,GACPD,EAAIC,EAEJtH,EAAIsH,EAAI,YAQEC,EAActL,EAAWuL,GACvC,OAAOvL,EAAIuL,WA0CGC,GACdC,EACAC,GAEA,MAAMC,EAA4B,GAClC,IAAK,MAAMjF,KAAK+E,EAAK,CACnB,MAAMG,EAAmBF,EAAIhF,GACzBkF,IAAMD,EAAIC,KACZD,EAAIC,GAAKlF,GAGb,OAAOiF,WAoBOE,GACdJ,EACAC,GAEA,MAAMC,EAA8B,GACpC,IAAK,MAAMjF,KAAK+E,EAAK,CACnB,MAAMG,EAAIF,EAAIhF,GACVkF,IACED,EAAIC,GACND,EAAIC,GAAGnK,KAAKiF,GAEZiF,EAAIC,GAAK,CAAClF,IAIhB,OAAOiF,QA2CIG,GAAblL,cACEE,eAAgD,GAEhDF,cAAcmL,GACZ,MAAMpC,EAAO7I,KAAKQ,UAAUyK,EAAIC,MAChC,GAAIrC,EAAM,CACRoC,EAAIE,OAASnL,KACbiL,EAAIG,cAAgBpL,KACpB,IAAK,IAAIkD,EAAI,EAAGA,EAAI2F,EAAKjJ,OAAQsD,IAC/B2F,EAAK3F,GAAG+H,IAKdnL,iBACEoL,EACAxK,EACA2K,GAEA,GAAIA,EACF,OAEF,MAAMxC,EAAO7I,KAAKQ,UAAU0K,GACxBrC,EACFA,EAAKlI,KAAKD,GAEVV,KAAKQ,UAAU0K,GAAQ,CAACxK,GAI5BZ,oBACEoL,EACAxK,EACA2K,GAEA,GAAIA,EACF,OAEF,MAAMxC,EAAO7I,KAAKQ,UAAU0K,GAC5B,GAAIrC,EAAM,CACR,MAAM9G,EAAQ8G,EAAK7G,QAAQtB,GACvBqB,GAAS,GACX8G,EAAK5G,OAAOF,EAAO,KAgDpB,IAAIuJ,GAAqC,KAoCzC,IAAIC,GAAiD,KA+BrD,IAAIC,GAAuD,KAiC3D,IAAIC,GAAiD,cC35B5CC,GAAMC,GACpB,GAAqB,GAAjBA,EAAKC,SAAe,CACtB,MAAMC,EAASF,EAAiBhD,aAAa,MAC7C,GAAIkD,GAASA,EAAMtH,MAAM,kCACvB,OAAOsH,EAGX,OAAO,cAGO9C,GAAWO,GACzB,MAAO,IAAIA,aAGGwC,GAAOvN,GACrB,OAAOA,EAAIgH,QAAQ,kBAAmBwD,aAGxBgD,GAAaxN,GAC3B,OAAOA,EAAI2G,OAAO,YAGJ8G,GAASzN,GACvB,OAAKA,EAGEA,EAAIgH,QAAQ,oBAAqBwG,IAF/BxN,WAKK0N,GAAYC,GAC1B,MAAM5F,EAAS,GACf,EAAG,CACD,MAAMhC,EAAI4H,EAAO3H,MAAM,gBACjB4H,EAAIH,GAAS1H,EAAE,IAErB,KADA4H,EAASA,EAAOhH,OAAOZ,EAAE,GAAG1E,OAAS,MACrB0G,EAAO1G,OACrB,OAAOuM,EAET7F,EAAO3F,KAAKwL,SACLD,GACT,OAAO5F,WAGO8F,GAASF,GACvB,MAAMG,EAAM,GACZ,KAAOH,GAAQ,CACb,MAAM5H,EAAI4H,EAAO3H,MAAM,4BACvB,IAAKD,EACH,OAAO+H,EAETA,EAAI/H,EAAE,IAAM2H,GAAY3H,EAAE,IAC1B4H,EAASA,EAAOhH,OAAOZ,EAAE,GAAG1E,QAE9B,OAAOyM,QASIC,GACXxM,SAASyM,GACPA,EAAGC,OAAO,KAMZ1M,QAAQ2M,GACN,OAAO,SAIEC,GACX5M,YACkBiC,EACA4K,EACAC,GAFA5M,WAAA+B,EACA/B,QAAA2M,EACA3M,cAAA4M,EAMlB9M,SAASyM,GACPA,EAAGC,OAAO,KACVD,EAAGC,OAAOxM,KAAK+B,MAAM8D,aACjB7F,KAAK2M,IAAM3M,KAAK4M,YAClBL,EAAGC,OAAO,KACNxM,KAAK2M,IACPJ,EAAGC,OAAOxM,KAAK2M,IAEb3M,KAAK4M,WACPL,EAAGC,OAAO,OACVD,EAAGC,OAAOxM,KAAK4M,WAEjBL,EAAGC,OAAO,MAOd1M,QAAQ2M,GACN,GAAyB,GAArBA,EAAId,KAAKC,SACX,MAAM,IAAIjN,MAAM,qBAElB,MAAMkJ,EAAO4E,EAAId,KACXkB,EAAgBhF,EAAKiF,SACrBC,EAAoBF,EAAcjN,OACxC,IAAIoN,EACJ,MAAMtG,EAAaR,KAAKC,MAAMnG,KAAK+B,MAAQ,GAAK,EAChD,GAAI2E,EAAa,GAA0B,GAArBqG,EACpBC,EAAQnF,EAAKoF,WACbR,EAAId,KAAOqB,GAASnF,MACf,CAEL,GADAmF,EAAQH,EAAc3G,KAAKgH,IAAIxG,EAAYqG,EAAoB,IAC9C,EAAb/M,KAAK+B,MAAW,CAClB,MAAMoL,EAAOH,EAAMI,YACdD,GAAyB,GAAjBA,EAAKvB,SAGhBoB,EAAQG,EAFRV,EAAIY,OAAQ,EAKhBZ,EAAId,KAAOqB,EAEb,GAAIhN,KAAK2M,KAAOF,EAAIY,OAASrN,KAAK2M,IAAMjB,GAAMe,EAAId,OAChD,MAAM,IAAIhN,MAAM,qBAGlB,OADA8N,EAAIG,SAAW5M,KAAK4M,UACb,SAIEU,GACXxN,YACkByN,EACAC,EACAC,EACAb,GAHA5M,YAAAuN,EACAvN,gBAAAwN,EACAxN,eAAAyN,EACAzN,cAAA4M,EAGlB9M,QAAQ2M,GACN,GAAIzM,KAAKuN,OAAS,IAAMd,EAAIY,MAAO,CACjC,IAAIE,EAASvN,KAAKuN,OACd5B,EAAOc,EAAId,KACf,OAAa,CACX,MAAMC,EAAWD,EAAKC,SACtB,GAAgB,GAAZA,EACF,MAEF,MAAMuB,EAAOxB,EAAKyB,YAClB,GAAI,GAAKxB,GAAYA,GAAY,EAAG,CAClC,MAAM8B,EAAa/B,EAAKgC,YAAY/N,OACpC,GAAI2N,GAAUG,EACZ,MAEF,IAAKP,EAAM,CACTI,EAASG,EACT,MAEFH,GAAUG,EAEZ,IAAKP,EAAM,CACTI,EAAS,EACT,MAEF5B,EAAOwB,EAETV,EAAId,KAAOA,EACXc,EAAIc,OAASA,EAGf,OADAd,EAAIG,SAAW5M,KAAK4M,UACb,EAMT9M,SAASyM,GACPA,EAAGC,OAAO,KACVD,EAAGC,OAAOxM,KAAKuN,OAAO1H,aAClB7F,KAAKwN,YAAcxN,KAAKyN,WAAazN,KAAK4M,YAC5CL,EAAGC,OAAO,MACNxM,KAAKwN,YAAcxN,KAAKyN,aACtBzN,KAAKwN,YACPjB,EAAGC,OAAOV,GAAO9L,KAAKwN,aAExBjB,EAAGC,OAAO,KACNxM,KAAKyN,WACPlB,EAAGC,OAAOV,GAAO9L,KAAKyN,aAGtBzN,KAAK4M,WACPL,EAAGC,OAAO,OACVD,EAAGC,OAAOxM,KAAK4M,WAEjBL,EAAGC,OAAO,aAKHoB,GAAb9N,cACEE,WAAgB,KAEhBF,WAAW+N,GACT,IAAIvJ,EAAIuJ,EAAQtJ,MAAM,uBACtB,IAAKD,EACH,MAAM,IAAI3F,MAAM,iBAElB,MAAMJ,EAAM+F,EAAE,GACd,IAAIpB,EAAI,EACR,MAAM4K,EAAQ,GACd,OAAa,CACX,IAAIzB,EAGJ,OAAQ9N,EAAIwP,OAAO7K,IACjB,IAAK,IAAK,CAOR,GANAA,IACAoB,EAAI/F,EACD2G,OAAOhC,GACPqB,MACC,2EAECD,EACH,MAAM,IAAI3F,MAAM,yBAElBuE,GAAKoB,EAAE,GAAG1E,OACV,MAAMmC,EAAQiI,SAAS1F,EAAE,GAAI,IACvBqI,EAAKrI,EAAE,GACb+H,EAAMD,GAAS9H,EAAE,IACjBwJ,EAAMnN,KAAK,IAAI+L,GAAU3K,EAAO4K,EAAIqB,EAAc3B,EAAO,KACzD,MAEF,IAAK,IAAK,CAOR,GANAnJ,IACAoB,EAAI/F,EACD2G,OAAOhC,GACPqB,MACC,4FAECD,EACH,MAAM,IAAI3F,MAAM,yBAElBuE,GAAKoB,EAAE,GAAG1E,OACV,MAAM2N,EAASvD,SAAS1F,EAAE,GAAI,IAC9B,IAAIkJ,EAAalJ,EAAE,GACfkJ,IACFA,EAAaxB,GAASwB,IAExB,IAAIC,EAAYnJ,EAAE,GACdmJ,IACFA,EAAYzB,GAASyB,IAEvBpB,EAAMD,GAAS9H,EAAE,KACjBwJ,EAAMnN,KACJ,IAAI2M,GACFC,EACAC,EACAC,EACAO,EAAc3B,EAAO,KAGzB,MAEF,IAAK,IACHnJ,IACA4K,EAAMnN,KAAK,IAAI2L,IACf,MACF,IAAK,IACL,IAAK,IAIL,IAAK,GAEH,YADAtM,KAAK8N,MAAQA,GAEf,QACE,MAAM,IAAInP,MAAM,uBAKxBmB,SAASmO,GACP,MAAMxB,EAAM,CACVd,KAAMsC,EAAI5G,gBACVkG,OAAQ,EACRF,OAAO,EACPT,SAAU,KACVsB,IAAK,MAEP,IAAK,IAAIhL,EAAI,EAAGA,EAAIlD,KAAK8N,MAAMlO,OAAQsD,IACrC,IAAKlD,KAAK8N,MAAM5K,GAAGiL,QAAQ1B,GAAM,CAC/BA,EAAIyB,IAAM,IAAIN,GACdnB,EAAIyB,IAAIJ,MAAQ9N,KAAK8N,MAAMM,MAAMlL,EAAI,GACrC,MAGJ,OAAOuJ,EAGT3M,KAAKuO,EAAchB,GACjB,OAAOgB,EACJ9I,QAAQ,OAAQ,KAChBhB,MACC8I,EACI,gCACA,iCACJ,GACD9H,QAAQ,MAAO,IACfA,QAAQ,MAAO,IAMpBzF,oBACE6L,EACA4B,EACAF,EACAT,GAEA,MAAMkB,EAAQ,GACd,IAAI1H,EAASuF,EAAK2C,WACdd,EAAa,GACbC,EAAY,GAChB,KAAO9B,GAAM,CACX,OAAQA,EAAKC,UACX,KAAK,EACL,KAAK,EACL,KAAK,EAAG,CACN,MAAMyC,EAAO1C,EAAKgC,YACZD,EAAaW,EAAKzO,OACpByN,GACFE,GAAUG,EACLF,IACHA,EAAaa,KAGXd,EAASG,IACXH,EAASG,GAEXL,GAAQ,EACRG,EAAaa,EAAKnJ,OAAO,EAAGqI,GAC5BE,EAAYY,EAAKnJ,OAAOqI,IAE1B5B,EAAOA,EAAK4C,gBACZ,SAEF,KAAK,EACH5C,EAAOA,EAAK4C,gBACZ,SAEJ,MAQF,KANIhB,EAAS,GAAKC,GAAcC,KAC9BD,EAAaxN,KAAKwO,KAAKhB,GAAY,GACnCC,EAAYzN,KAAKwO,KAAKf,GAAW,GACjCK,EAAMnN,KAAK,IAAI2M,GAAWC,EAAQC,EAAYC,EAAWb,IACzDA,EAAW,MAENxG,GACAA,GAA6B,GAAnBA,EAAOwF,UADT,CAIb,MAAMe,EAAKU,EAAQ,KAAO3B,GAAMC,GAChC,IAAI5J,EAAQsL,EAAQ,EAAI,EACxB,KAAO1B,GACgB,GAAjBA,EAAKC,WACP7J,GAAS,GAEX4J,EAAOA,EAAK4C,gBAEdT,EAAMnN,KAAK,IAAI+L,GAAU3K,EAAO4K,EAAIC,IACpCA,EAAW,KACXjB,EAAOvF,EACPA,EAASA,EAAOkI,WAChBjB,GAAQ,EAEVS,EAAMW,UACFzO,KAAK8N,OACPA,EAAMnN,KAAK,IAAI2L,IACftM,KAAK8N,MAAQA,EAAMnO,OAAOK,KAAK8N,QAE/B9N,KAAK8N,MAAQA,EAIjBhO,WACE,IAAKE,KAAK8N,MACR,MAAO,GAET,MAAMvB,EAAK,IAAImC,EACfnC,EAAGC,OAAO,YACV,IAAK,IAAItJ,EAAI,EAAGA,EAAIlD,KAAK8N,MAAMlO,OAAQsD,IACrClD,KAAK8N,MAAM5K,GAAGyL,SAASpC,GAGzB,OADAA,EAAGC,OAAO,KACHD,EAAG1G,qBC3XE+I,GAAiBC,GAC/B,MAAO,CACLC,WAAYD,EAAKC,WACjBC,WAAYF,EAAKE,WACjBC,OAAQH,EAAKG,OACbC,UAAWJ,EAAKI,UAChBC,YAAaL,EAAKK,YAClBC,WAAYN,EAAKM,WACjBC,UAAWP,EAAKO,UAChBC,WAAYR,EAAKQ,WACjBC,WAAYT,EAAKS,WACjBC,kBAAmBzM,OAAO0M,OAAO,GAAIX,EAAKU,mBAC1CE,iBAAkBZ,EAAKY,iBACnB3M,OAAO0M,OAAO,GAAIX,EAAKY,uBACvBC,GAID,MAAMC,GAjCJ,CACLb,WAAY,QACZC,WAAY,KACZC,OAAQ,EACRC,WAAW,EACXC,YAAa,GACbC,YAAY,EACZC,WAAW,EACXC,YAAY,EACZC,WAAY,EACZC,kBAAmB,CAAEK,aAAa,EAAMC,OAAO,GAC/CJ,sBAAkBC,GA+BTI,GAAU,CACrBC,QAAS,aAOKC,GACdC,EACAC,EACAC,EACAC,GAEA,MAAMC,EAAQnK,KAAKgH,KAAK+C,EAAQ,GAAKE,GAAOD,EAAQ,GAAKE,GACzD,MAAO,UAAUC,SAAaA,kBAMhBC,GAAU/R,GACxB,MAAO,IAAIgS,EAAkB,GAAGhS,iBAMlBiS,GAAS9O,GACvB,OAAO+O,EAAoB,GAAG/O,cAGhBgP,GACdC,EACAC,GAEA,OAAID,EACK,GAAGF,EAAoBE,MAAYF,EAAoBG,KAEzDH,EAAoBG,GAGtB,IAAIC,GAAuB,QAKrBC,GAWXhR,YACSsG,EACA2K,GAUP,GAXO/Q,YAAAoG,EACApG,cAAA+Q,EAXT/Q,cAA2B,GAK3BA,YAAiC,GACjCA,WAAgC,GAChCA,cAA2D,GAMzDA,KAAKgR,SAAW,IAAIH,OACpB7Q,KAAKiR,KAAO,IAAIC,GAAMlR,KAAM,GAC5BA,KAAKmR,IAAM,IAAID,GAAMlR,KAAM,GAC3BA,KAAKoR,MAAQ,IAAIF,GAAMlR,MAAM,GAC7BA,KAAKqR,OAAS,IAAIH,GAAMlR,MAAM,GAC1BoG,GACFA,EAAO0G,SAASnM,KAAKX,OAElBoG,EAAQ,CAEX,MAAMkL,EAAWtR,KAAKsR,SACtBA,EAAgB,MAAIpL,KAAKC,MACzBmL,EAAe,KAAIpL,KAAKqL,KACxBD,EAAgB,MAAIpL,KAAKsL,MACzBF,EAAe,KAAIpL,KAAKuL,KACxBH,EAAc,IAAIpL,KAAKgH,IACvBoE,EAAc,IAAIpL,KAAKwL,IACvBJ,EAAoB,UAAItB,GACxBsB,EAAS,cAAgBhB,GACzBgB,EAAS,YAAcd,GACvBc,EAAiB,OAAKK,UAAaA,EACnC3R,KAAK4R,kBAAkB,cAAc,WACnC,OAAO5R,KAAK6R,eAEd7R,KAAK4R,kBAAkB,eAAe,WACpC,OAAO5R,KAAK8R,gBAEd9R,KAAK4R,kBAAkB,oBAAoB,WACzC,OAAO5R,KAAK6O,KAAKC,cAEnB9O,KAAK4R,kBAAkB,mBAAmB,WACxC,OAAO5R,KAAK6O,KAAKO,aAEnBpP,KAAK4R,kBAAkB,kBAAkB,WACvC,OAAO5R,KAAK6O,KAAKI,aAEnBjP,KAAK4R,kBAAkB,eAAe,WACpC,OAAO5R,KAAK6O,KAAKG,UAEnBhP,KAAK4R,kBAAkB,oBAAoB,WACzC,OAAO5R,KAAK6O,KAAKE,cAEnB/O,KAAK4R,kBAAkB,qBAAqB,WAC1C,OAAO5R,KAAK6O,KAAKK,YAAclP,KAAK+R,YAEtC/R,KAAK4R,kBAAkB,mBAAmB,WACxC,OAAO5R,KAAK6O,KAAKM,cAEnBnP,KAAK4R,kBAAkB,oBAAoB,WACzC,OAAO5R,KAAK6O,KAAKQ,cAInBrP,KAAK4R,kBAAkB,aAAa,WAClC,OAAOtB,GAAUtQ,KAAKgS,SAAWhS,KAAKgS,SAAW,OAEnDhS,KAAK4R,kBAAkB,aAAa,WAClC,OAAOtB,GAAUtQ,KAAKiS,SAAWjS,KAAKiS,SAAW,QAKvDnS,kBAAkB4B,EAAcC,GAC9B3B,KAAKkS,OAAOxQ,GAAQ,IAAIyQ,GAAOnS,KAAM2B,EAAID,GAG3C5B,WAAWsS,EAAuBC,GAChCrS,KAAKkS,OAAOE,GAAiBC,EAG/BvS,WAAWsS,EAAuBC,GAChCrS,KAAKsS,MAAMF,GAAiBC,EAG9BvS,cAAcsS,EAAuBzQ,GACnC3B,KAAKsR,SAASc,GAAiBzQ,YAmBnB4Q,GAA6BC,GAC3C,OAAQA,EAAKvN,eACX,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,OACL,IAAK,OACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,QACL,IAAK,QACH,OAAO,EACT,QACE,OAAO,GAeN,MAAMwN,GAA8C,CACzDC,GAAI,EACJC,GAAI,GACJC,GAAI,EAAI,EACRC,GAAI,GACJC,GAAI,GAAK,KACTC,GAAI,GAAK,KACTC,EAAG,GAAK,KAAO,GACfC,GAAI,GACJC,IAAK,GACLC,GAAI,EAEJC,KAAM,EACNC,IAAK,EAAI,GACTC,KAAM,KAAO,aAMCC,GAAmBf,GACjC,OAAQA,GACN,IAAK,IACL,IAAK,MACH,OAAO,EACT,QACE,OAAO,SAWAgB,GAgBX1T,YACkB2T,EACAC,EACAC,EAChB5B,GAHgB/R,eAAAyT,EACAzT,mBAAA0T,EACA1T,oBAAA2T,EAlBR3T,qBAAiC,KAEjCA,sBAAkC,KAG5CA,kBAA8B,KAG9BA,YAA0C,GAC1CA,mBAA+B,KAC/BA,oBAAgC,KAChCA,kBAA+B,KAC/BA,cAA0B,KAC1BA,cAA0B,KAQxBA,KAAK6R,UAAY,WACf,OAAI7R,KAAK4T,gBACA5T,KAAK4T,gBAEL5T,KAAK6O,KAAKQ,WACbnJ,KAAKC,MAAMuN,EAAgB,GAAK1T,KAAK6O,KAAKS,WAC1CoE,GAGR1T,KAAK8R,WAAa,WAChB,OAAI9R,KAAK6T,iBACA7T,KAAK6T,iBAELF,GAGX3T,KAAK8T,gBAAkB/B,EACvB/R,KAAK+R,SAAW,WACd,OAAI/R,KAAK+T,aACA/T,KAAK+T,aAELhC,GAGX/R,KAAK6O,KAAOc,GAGN7P,gBAAgBkU,GACtB,IAAIxK,EAAIxJ,KAAKiU,OAAOD,EAAMhD,UAK1B,OAJKxH,IACHA,EAAI,GACJxJ,KAAKiU,OAAOD,EAAMhD,UAAYxH,GAEzBA,EAGT1J,WAAWkU,GACThU,KAAKiU,OAAOD,EAAMhD,UAAY,GAC9B,IAAK,IAAIlG,EAAI,EAAGA,EAAIkJ,EAAMlH,SAASlN,OAAQkL,IACzC9K,KAAKkU,WAAWF,EAAMlH,SAAShC,IAInChL,cAAc0S,EAAc2B,GAC1B,GAAI5B,GAA6BC,GAAO,CACtC,MAAM4B,EAAMpU,KAAK6R,YAAc,IACzBwC,EAAMrU,KAAK8R,aAAe,IAC1BwC,EAA2B,MAAtBtU,KAAKuU,cAAwBvU,KAAKuU,cAAgB,IAAMH,EAC7DI,EAA4B,MAAvBxU,KAAKyU,eAAyBzU,KAAKyU,eAAiB,IAAMJ,EAErE,OAAQ7B,GACN,IAAK,KACH,OAAO8B,EACT,IAAK,KACH,OAAOE,EACT,IAAK,KACH,OAAOxU,KAAK0U,aAAeF,EAAKF,EAClC,IAAK,KACH,OAAOtU,KAAK0U,aAAeJ,EAAKE,EAClC,IAAK,OACH,OAAOF,EAAKE,EAAKF,EAAKE,EACxB,IAAK,OACH,OAAOF,EAAKE,EAAKF,EAAKE,EACxB,IAAK,MACH,OAAOJ,EACT,IAAK,MACH,OAAOC,EACT,IAAK,MACH,OAAOrU,KAAK0U,aAAeL,EAAMD,EACnC,IAAK,MACH,OAAOpU,KAAK0U,aAAeN,EAAMC,EACnC,IAAK,QACH,OAAOD,EAAMC,EAAMD,EAAMC,EAC3B,IAAK,QACH,OAAOD,EAAMC,EAAMD,EAAMC,GAG/B,MAAY,MAAR7B,GAAwB,OAARA,EACX2B,EAASnU,KAAK8T,gBAAkB9T,KAAK+R,WAElC,MAARS,EAECC,GAAqB,IACnB0B,EAASnU,KAAK8T,gBAAkB9T,KAAK+R,YACxCU,GAAqB,GAGlBA,GAAiBD,GAG1B1S,SAASkU,EAAqB5B,GAC5B,EAAG,CACD,IAAIC,EAAM2B,EAAM9B,OAAOE,GACvB,GAAIC,EACF,OAAOA,EAET,GAAI2B,EAAMjD,WACRsB,EAAM2B,EAAMjD,SAASpO,KAAK3C,KAAMoS,GAAe,GAC3CC,GACF,OAAOA,EAGX2B,EAAQA,EAAM5N,aACP4N,GACT,MAAM,IAAIrV,MAAM,SAASyT,mBAM3BtS,SACEkU,EACA5B,EACAuC,EACAC,GAEA,EAAG,CACD,IAAIC,EAAOb,EAAM1B,MAAMF,GACvB,GAAIyC,EACF,OAAOA,EAET,GAAIb,EAAMjD,WACR8D,EAAOb,EAAMjD,SAASpO,KAAK3C,KAAMoS,GAAe,GAC5CyC,GACF,OAAOA,EAGX,MAAMlT,EAAKqS,EAAM1C,SAASc,GAC1B,GAAIzQ,EAAI,CACN,GAAIiT,EACF,OAAOZ,EAAM/C,KAEf,MAAMhS,EAAOE,MAAMwV,EAAO/U,QAC1B,IAAK,IAAIsD,EAAI,EAAGA,EAAIyR,EAAO/U,OAAQsD,IACjCjE,EAAKiE,GAAKyR,EAAOzR,GAAG4R,SAAS9U,MAE/B,OAAO,IAAIkR,GAAM8C,EAAOrS,EAAGoT,MAAM/U,KAAMf,IAEzC+U,EAAQA,EAAM5N,aACP4N,GACT,MAAM,IAAIrV,MAAM,aAAayT,mBAG/BtS,cAAc4B,EAAcsT,GAC1B,MAAMC,EAAmB,QAATvT,KAAoB1B,KAAK6O,KAAKU,kBAAkB7N,GAChE,OAAOsT,GAAOC,EAAUA,EAG1BnV,cAAcoV,EAAiB9W,GAC7B,IAAI0I,EAAS,GACb,MAAMxC,EAAI4Q,EAAQ3Q,MAAM,oBACpBD,IACFwC,EAASxC,EAAE,GACX4Q,EAAU5Q,EAAE,IAEd,IAAI6Q,EAAqB,KACrBC,EAAwB,KAC5B,OAAQF,GACN,IAAK,QACL,IAAK,SACL,IAAK,eACL,IAAK,gBACL,IAAK,QACC9W,IACF+W,EAAM/W,EAAM0W,SAAS9U,OAI3B,OAAQkV,GACN,IAAK,QACHE,EAASpV,KAAK6R,YACd,MACF,IAAK,SACHuD,EAASpV,KAAK8R,aACd,MACF,IAAK,eACHsD,EAAS3R,OAAO4R,OAAOC,WACvB,MACF,IAAK,gBACHF,EAAS3R,OAAO4R,OAAOE,YACvB,MACF,IAAK,QACHH,EAAS3R,OAAO4R,OAAOG,WAG3B,GAAc,MAAVJ,GAAyB,MAAPD,EACpB,OAAQrO,GACN,IAAK,MACH,OAAOsO,GAAUD,EACnB,IAAK,MACH,OAAOC,GAAUD,EACnB,QACE,OAAOC,GAAUD,OAEhB,GAAc,MAAVC,GAA2B,MAAThX,EAC3B,OAAkB,IAAXgX,EAET,OAAO,EAGTtV,SAASkU,EAAqBpJ,GAC5B,MAAMpB,EAAIxJ,KAAKiU,OAAOD,EAAMhD,UAC5B,OAAOxH,EAAIA,EAAEoB,QAAO8E,EAGtB5P,SAASkU,EAAqBpJ,EAAayH,GACzCrS,KAAKyV,gBAAgBzB,GAAOpJ,GAAOyH,SAS1BqD,GAGX5V,YAAmBkU,GAAAhU,WAAAgU,EACjBhU,KAAKgU,MAAQA,EACbhU,KAAK4K,IAAM,IAAIiG,OAMjB/Q,WACE,MAAM6V,EAAM,IAAIjH,EAEhB,OADA1O,KAAK2O,SAASgH,EAAK,GACZA,EAAI9P,WAGb/F,SAAS6V,EAAwBC,GAC/B,MAAM,IAAIjX,MAAM,cAGRmB,aAAa+V,GACrB,MAAM,IAAIlX,MAAM,cAGlBmB,OAAO+V,EAAkBlB,GACvB,OAAO3U,KAGTF,WACEgW,EACAD,EACAE,GAEA,OAAOD,IAAU9V,KAGnBF,YACEgW,EACAD,EACAE,GAEA,MAAMC,EAASD,EAAgB/V,KAAK4K,KACpC,GAAc,MAAVoL,EACF,OAAIA,IAAWlG,GAAQC,SAGhBiG,EACF,CACLD,EAAgB/V,KAAK4K,KAAOkF,GAAQC,QACpC,MAAMzJ,EAAStG,KAAKiW,WAAWH,EAAOD,EAASE,GAE/C,OADAA,EAAgB/V,KAAK4K,KAAOtE,EACrBA,GAIXxG,OAAOgW,EAAYD,GACjB,OAAO7V,KAAKkW,YAAYJ,EAAOD,EAAS,IAG1C/V,SAAS+V,GACP,IAAIvP,EAASuP,EAAQM,SAASnW,KAAKgU,MAAOhU,KAAK4K,KAC/C,YAAqB,IAAVtE,EACFA,GAETA,EAAStG,KAAKoW,aAAaP,GAC3BA,EAAQQ,SAASrW,KAAKgU,MAAOhU,KAAK4K,IAAKtE,GAChCA,GAGTxG,cACE,OAAO,SAIEwW,WAAeZ,GAC1B5V,YAAYkU,EAA4B3B,GACtCkE,MAAMvC,GADgChU,SAAAqS,EAI9BvS,QACR,MAAM,IAAInB,MAAM,cAGlBmB,WAAWuS,GACT,MAAM,IAAI1T,MAAM,cAMlBmB,aAAa+V,GACX,MAAMxD,EAAMrS,KAAKqS,IAAIyC,SAASe,GAC9B,OAAO7V,KAAKwW,WAAWnE,GAMzBvS,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MAAQA,KAAKqS,IAAI6D,YAAYJ,EAAOD,EAASE,GAO3DjW,SAAS6V,EAAwBC,GAC3B,GAAKA,GACPD,EAAInJ,OAAO,KAEbmJ,EAAInJ,OAAOxM,KAAKyW,SAChBzW,KAAKqS,IAAI1D,SAASgH,EAAK,IACnB,GAAKC,GACPD,EAAInJ,OAAO,KAOf1M,OAAO+V,EAAkBlB,GACvB,MAAMtC,EAAMrS,KAAKqS,IAAIqE,OAAOb,EAASlB,GACrC,OAAItC,IAAQrS,KAAKqS,IACRrS,KAEC,IAAKA,KAAK2W,YAAoB3W,KAAKgU,MAAO3B,UAK3CuE,WAAclB,GACzB5V,YAAYkU,EAA4B6C,EAAiBC,GACvDP,MAAMvC,GADgChU,SAAA6W,EAAiB7W,SAAA8W,EAIzDhX,cACE,MAAM,IAAInB,MAAM,cAGlBmB,QACE,MAAM,IAAInB,MAAM,cAGlBmB,UAAU+W,EAAaC,GACrB,MAAM,IAAInY,MAAM,cAMlBmB,aAAa+V,GACX,MAAMgB,EAAM7W,KAAK6W,IAAI/B,SAASe,GACxBiB,EAAM9W,KAAK8W,IAAIhC,SAASe,GAC9B,OAAO7V,KAAK+W,UAAUF,EAAKC,GAM7BhX,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MACVA,KAAK6W,IAAIX,YAAYJ,EAAOD,EAASE,IACrC/V,KAAK8W,IAAIZ,YAAYJ,EAAOD,EAASE,GAOzCjW,SAAS6V,EAAwBC,GAC/B,MAAMoB,EAAehX,KAAKiX,cACtBD,GAAgBpB,GAClBD,EAAInJ,OAAO,KAEbxM,KAAK6W,IAAIlI,SAASgH,EAAKqB,GACvBrB,EAAInJ,OAAOxM,KAAKyW,SAChBzW,KAAK8W,IAAInI,SAASgH,EAAKqB,GACnBA,GAAgBpB,GAClBD,EAAInJ,OAAO,KAOf1M,OAAO+V,EAAkBlB,GACvB,MAAMkC,EAAM7W,KAAK6W,IAAIH,OAAOb,EAASlB,GAC/BmC,EAAM9W,KAAK8W,IAAIJ,OAAOb,EAASlB,GACrC,OAAIkC,IAAQ7W,KAAK6W,KAAOC,IAAQ9W,KAAK8W,IAC5B9W,KAEC,IAAKA,KAAK2W,YAAoB3W,KAAKgU,MAAO6C,EAAKC,UAKhDI,WAAgBN,GAC3B9W,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,cACE,OAAO,SAIEqX,WAAmBP,GAC9B9W,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,cACE,OAAO,SAIEsX,WAAiBR,GAC5B9W,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,cACE,OAAO,SAIEuX,WAAuBT,GAClC9W,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,cACE,OAAO,SAIEwX,WAAYhB,GACvBxW,YAAYkU,EAAqB3B,GAC/BkE,MAAMvC,EAAO3B,GAMfvS,QACE,MAAO,IAMTA,WAAWuS,GACT,OAAQA,SAICkF,WAAejB,GAC1BxW,YAAYkU,EAAqB3B,GAC/BkE,MAAMvC,EAAO3B,GAMfvS,QACE,MAAO,IAMTA,WAAWuS,GACT,OAAQA,SAICmF,WAAYN,GACvBpX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,aAAa+V,GACX,OAAO7V,KAAK6W,IAAI/B,SAASe,IAAY7V,KAAK8W,IAAIhC,SAASe,UAI9C4B,WAAiBD,GAC5B1X,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,eAIE4X,WAAWR,GACtBpX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,aAAa+V,GACX,OAAO7V,KAAK6W,IAAI/B,SAASe,IAAY7V,KAAK8W,IAAIhC,SAASe,UAI9C8B,WAAgBD,GAC3B5X,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,YAIE8X,WAAWT,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAOD,EAAMC,SAIJe,WAAWV,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,UAAU+W,EAAaC,GACrB,OAAOD,GAAOC,SAILgB,WAAWX,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAOD,EAAMC,SAIJiB,WAAWZ,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,UAAU+W,EAAaC,GACrB,OAAOD,GAAOC,SAILkB,WAAWb,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,UAAU+W,EAAaC,GACrB,OAAOD,GAAOC,SAILmB,WAAWd,GACtBrX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,KAMTA,UAAU+W,EAAaC,GACrB,OAAOD,GAAOC,SAILoB,WAAYd,GACvBtX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAQD,EAAcC,SAIbqB,WAAiBf,GAC5BtX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,MAMTA,UAAU+W,EAAaC,GACrB,OAAQD,EAAeC,SAIdsB,WAAiBf,GAC5BvX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAQD,EAAeC,SAIduB,WAAehB,GAC1BvX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAQD,EAAeC,SAIdwB,WAAejB,GAC1BvX,YAAYkU,EAAqB6C,EAAUC,GACzCP,MAAMvC,EAAO6C,EAAKC,GAMpBhX,QACE,MAAO,IAMTA,UAAU+W,EAAaC,GACrB,OAAQD,EAAeC,SAOdyB,WAAgB7C,GAG3B5V,YAAYkU,EAA4BwE,EAAahG,GACnD+D,MAAMvC,GADgChU,SAAAwY,EAEtCxY,KAAKwS,KAAOA,EAAKvN,cAMnBnF,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAOxM,KAAKwY,IAAI3S,YACpB8P,EAAInJ,OAAOiE,EAAoBzQ,KAAKwS,OAMtC1S,aAAa+V,GACX,OAAO7V,KAAKwY,IAAM3C,EAAQ4C,cAAczY,KAAKwS,MAAM,UAQ1CkG,WAAchD,GACzB5V,YAAYkU,EAA4B5B,GACtCmE,MAAMvC,GADgChU,mBAAAoS,EAOxCtS,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAOxM,KAAKoS,eAMlBtS,aAAa+V,GACX,OAAOA,EAAQ8C,SAAS3Y,KAAKgU,MAAOhU,KAAKoS,eAAe0C,SAASe,GAMnE/V,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MACV6V,EACG8C,SAAS3Y,KAAKgU,MAAOhU,KAAKoS,eAC1B8D,YAAYJ,EAAOD,EAASE,UAQxB6C,WAAkBlD,GAK7B5V,YAAYkU,EAA4BgB,EAAqBtT,GAC3D6U,MAAMvC,GADgChU,SAAAgV,EAAqBhV,UAAA0B,EAO7D5B,SAAS6V,EAAwBC,GAC3B5V,KAAKgV,KACPW,EAAInJ,OAAO,QAEbmJ,EAAInJ,OAAOiE,EAAoBzQ,KAAK0B,OAMtC5B,aAAa+V,GACX,OAAOA,EAAQgD,cAAc7Y,KAAK0B,KAAM1B,KAAKgV,KAM/ClV,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MAAQA,KAAK5B,MAAM8X,YAAYJ,EAAOD,EAASE,GAO7DjW,cACE,OAAO,SAWEqS,WAAeuD,GAC1B5V,YACEkU,EACOrS,EACApD,GAEPgY,MAAMvC,GAHChU,QAAA2B,EACA3B,SAAAzB,EAQTuB,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAOxM,KAAKzB,KAMlBuB,aAAa+V,GACX,OAAO7V,KAAK2B,GAAGgB,KAAKkT,UA4CXiD,WAAapD,GACxB5V,YACEkU,EACO5B,EACAuC,GAEP4B,MAAMvC,GAHChU,mBAAAoS,EACApS,YAAA2U,EAQT7U,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAOxM,KAAKoS,wBArDWuD,EAAwBhL,GACrDgL,EAAInJ,OAAO,KACX,IAAK,IAAItJ,EAAI,EAAGA,EAAIyH,EAAI/K,OAAQsD,IAC1BA,GACFyS,EAAInJ,OAAO,KAEb7B,EAAIzH,GAAGyL,SAASgH,EAAK,GAEvBA,EAAInJ,OAAO,KA8CTuM,CAAepD,EAAK3V,KAAK2U,QAM3B7U,aAAa+V,GAOX,OANaA,EAAQmD,SACnBhZ,KAAKgU,MACLhU,KAAKoS,cACLpS,KAAK2U,QACL,GAEU+B,OAAOb,EAAS7V,KAAK2U,QAAQG,SAASe,GAMpD/V,WACEgW,EACAD,EACAE,GAEA,GAAID,IAAU9V,KACZ,OAAO,EAET,IAAK,IAAIkD,EAAI,EAAGA,EAAIlD,KAAK2U,OAAO/U,OAAQsD,IACtC,GAAIlD,KAAK2U,OAAOzR,GAAGgT,YAAYJ,EAAOD,EAASE,GAC7C,OAAO,EAWX,OARaF,EAAQmD,SACnBhZ,KAAKgU,MACLhU,KAAKoS,cACLpS,KAAK2U,QACL,GAIUuB,YAAYJ,EAAOD,EAASE,GAM1CjW,OAAO+V,EAAkBlB,GACvB,MAAMsE,WAzFRpD,EACAlL,EACAgK,GAEA,IAAIuE,EAAkBvO,EACtB,IAAK,IAAIzH,EAAI,EAAGA,EAAIyH,EAAI/K,OAAQsD,IAAK,CACnC,MAAMiJ,EAAIxB,EAAIzH,GAAGwT,OAAOb,EAASlB,GACjC,GAAIhK,IAAQuO,EACVA,EAAShW,GAAKiJ,OACT,GAAIA,IAAMxB,EAAIzH,GAAI,CACvBgW,EAAW/Z,MAAMwL,EAAI/K,QACrB,IAAK,IAAI0F,EAAI,EAAGA,EAAIpC,EAAGoC,IACrB4T,EAAS5T,GAAKqF,EAAIrF,GAEpB4T,EAAShW,GAAKiJ,GAGlB,OAAO+M,EAwEkBC,CAAetD,EAAS7V,KAAK2U,OAAQA,GAC5D,OAAIsE,IAAmBjZ,KAAK2U,OACnB3U,KAEF,IAAI8Y,GAAK9Y,KAAKgU,MAAOhU,KAAKoS,cAAe6G,UAIvCG,WAAa1D,GACxB5V,YACEkU,EACOqF,EACAC,EACAC,GAEPhD,MAAMvC,GAJChU,UAAAqZ,EACArZ,YAAAsZ,EACAtZ,aAAAuZ,EAQTzZ,SAAS6V,EAAwBC,GAC3BA,EAAW,GACbD,EAAInJ,OAAO,KAEbxM,KAAKqZ,KAAK1K,SAASgH,EAAK,GACxBA,EAAInJ,OAAO,KACXxM,KAAKsZ,OAAO3K,SAASgH,EAAK,GAC1BA,EAAInJ,OAAO,KACXxM,KAAKuZ,QAAQ5K,SAASgH,EAAK,GACvBC,EAAW,GACbD,EAAInJ,OAAO,KAOf1M,aAAa+V,GACX,OAAI7V,KAAKqZ,KAAKvE,SAASe,GACd7V,KAAKsZ,OAAOxE,SAASe,GAErB7V,KAAKuZ,QAAQzE,SAASe,GAOjC/V,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MACVA,KAAKqZ,KAAKnD,YAAYJ,EAAOD,EAASE,IACtC/V,KAAKsZ,OAAOpD,YAAYJ,EAAOD,EAASE,IACxC/V,KAAKuZ,QAAQrD,YAAYJ,EAAOD,EAASE,GAO7CjW,OAAO+V,EAAkBlB,GACvB,MAAM0E,EAAOrZ,KAAKqZ,KAAK3C,OAAOb,EAASlB,GACjC2E,EAAStZ,KAAKsZ,OAAO5C,OAAOb,EAASlB,GACrC4E,EAAUvZ,KAAKuZ,QAAQ7C,OAAOb,EAASlB,GAC7C,OACE0E,IAASrZ,KAAKqZ,MACdC,IAAWtZ,KAAKsZ,QAChBC,IAAYvZ,KAAKuZ,QAEVvZ,KAEC,IAAIoZ,GAAKpZ,KAAKgU,MAAOqF,EAAMC,EAAQC,UAKpCrI,WAAcwE,GACzB5V,YAAYkU,EAA4B3B,GACtCkE,MAAMvC,GADgChU,SAAAqS,EAOxCvS,SAAS6V,EAAwBC,GAC/B,cAAe5V,KAAKqS,KAClB,IAAK,SACL,IAAK,UACHsD,EAAInJ,OAAOxM,KAAKqS,IAAIxM,YACpB,MACF,IAAK,SACH8P,EAAInJ,OAAO,KACXmJ,EAAInJ,OAAO+D,EAAkBvQ,KAAKqS,MAClCsD,EAAInJ,OAAO,KACX,MACF,QACE,MAAM,IAAI7N,MAAM,uBAOtBmB,aAAa+V,GACX,OAAO7V,KAAKqS,WAIHmH,WAAkB9D,GAC7B5V,YAAYkU,EAA4BtS,EAAwBtD,GAC9DmY,MAAMvC,GADgChU,UAAA0B,EAAwB1B,WAAA5B,EAOhE0B,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAO,KACXmJ,EAAInJ,OAAO+D,EAAkBvQ,KAAK0B,KAAKA,OACvCiU,EAAInJ,OAAO,KACXxM,KAAK5B,MAAMuQ,SAASgH,EAAK,GACzBA,EAAInJ,OAAO,KAMb1M,aAAa+V,GACX,OAAOA,EAAQ4D,cAAczZ,KAAK0B,KAAKA,KAAM1B,KAAK5B,OAMpD0B,WACEgW,EACAD,EACAE,GAEA,OACED,IAAU9V,MAAQA,KAAK5B,MAAM8X,YAAYJ,EAAOD,EAASE,GAO7DjW,OAAO+V,EAAkBlB,GACvB,MAAMvW,EAAQ4B,KAAK5B,MAAMsY,OAAOb,EAASlB,GACzC,OAAIvW,IAAU4B,KAAK5B,MACV4B,KAEC,IAAIwZ,GAAUxZ,KAAKgU,MAAOhU,KAAK0B,KAAMtD,UAKtCsb,WAAchE,GACzB5V,YAAYkU,EAA4BjS,GACtCwU,MAAMvC,GADgChU,WAAA+B,EAOxCjC,SAAS6V,EAAwBC,GAC/BD,EAAInJ,OAAO,KACXmJ,EAAInJ,OAAOxM,KAAK+B,MAAM8D,YAMxB/F,OAAO+V,EAAkBlB,GACvB,MAAM/O,EAAI+O,EAAO3U,KAAK+B,OACtB,IAAK6D,EACH,MAAM,IAAIjH,MAAM,sBAAsBqB,KAAK+B,SAE7C,OAAO6D,YAIK+T,GAAI3F,EAAqB4F,EAASC,GAChD,OACED,IAAO5F,EAAM3C,QACbuI,IAAO5F,EAAM/C,MACb4I,GAAM7F,EAAM3C,QACZwI,GAAM7F,EAAM/C,KAEL+C,EAAM3C,OAEXuI,IAAO5F,EAAM5C,OAASwI,IAAO5F,EAAM7C,IAC9B0I,EAELA,IAAO7F,EAAM5C,OAASyI,IAAO7F,EAAM7C,IAC9ByI,EAEF,IAAIpC,GAAIxD,EAAO4F,EAAIC,YAGZC,GAAI9F,EAAqB4F,EAASC,GAChD,OAAID,IAAO5F,EAAM/C,KACR4I,EAELA,IAAO7F,EAAM/C,KACR2I,EAEF,IAAI1B,GAAIlE,EAAO4F,EAAIC,YAGZE,GAAI/F,EAAqB4F,EAASC,GAChD,OAAID,IAAO5F,EAAM/C,KACR,IAAIsG,GAAOvD,EAAO6F,GAEvBA,IAAO7F,EAAM/C,KACR2I,EAEF,IAAIzB,GAASnE,EAAO4F,EAAIC,YAGjBG,GAAIhG,EAAqB4F,EAASC,GAChD,OAAID,IAAO5F,EAAM/C,MAAQ4I,IAAO7F,EAAM/C,KAC7B+C,EAAM/C,KAEX2I,IAAO5F,EAAM7C,IACR0I,EAELA,IAAO7F,EAAM7C,IACRyI,EAEF,IAAIxB,GAASpE,EAAO4F,EAAIC,YAGjBI,GAAIjG,EAAqB4F,EAASC,GAChD,OAAID,IAAO5F,EAAM/C,KACR+C,EAAM/C,KAEX4I,IAAO7F,EAAM7C,IACRyI,EAEF,IAAIvB,GAAOrE,EAAO4F,EAAIC,SC5jDlBK,GAIXpa,YAAYoS,GACV,IAAK,IAAIhP,EAAI,EAAGA,EAAIgP,EAAOtS,OAAQsD,IACjCgP,EAAOhP,GAAGiX,MAAMna,MAIpBF,WAAWsa,GACT,MAAM,IAAIzb,MAAM,2BAGlBmB,WAAWua,GACT,MAAM,IAAI1b,MAAM,2BAGlBmB,SAASvB,GACP,MAAM,IAAII,MAAM,yBAGlBmB,WAAWwa,GACT,MAAM,IAAI3b,MAAM,2BAGlBmB,aAAaya,GACX,MAAM,IAAI5b,MAAM,6BAGlBmB,SAAS0Y,GACP,MAAM,IAAI7Z,MAAM,yBAGlBmB,SAAS0Y,GACP,OAAOxY,KAAKwa,SAAShC,GAGvB1Y,WAAW2a,GACT,MAAM,IAAI9b,MAAM,2BAGlBmB,SAASuE,GACP,MAAM,IAAI1F,MAAM,yBAGlBmB,eAAe+I,GACb,MAAM,IAAIlK,MAAM,0BAGlBmB,eAAe+I,GACb,MAAM,IAAIlK,MAAM,2BAGlBmB,UAAU4a,GACR,MAAM,IAAI/b,MAAM,0BAGlBmB,UAAU6a,GACR,MAAM,IAAIhc,MAAM,iCAIPic,WAAsBV,GACjCpa,cACEyW,QAGFzW,YAAYoS,GACV,IAAIvH,EAAa,KACjB,IAAK,IAAIzH,EAAI,EAAGA,EAAIgP,EAAOtS,OAAQsD,IAAK,CACtC,MAAM2X,EAAS3I,EAAOhP,GAChBmK,EAAQwN,EAAOV,MAAMna,MAC3B,GAAI2K,EACFA,EAAIzH,GAAKmK,OACJ,GAAIwN,IAAWxN,EAAO,CAC3B1C,EAAM,IAAIxL,MAAM+S,EAAOtS,QACvB,IAAK,IAAIkL,EAAI,EAAGA,EAAI5H,EAAG4H,IACrBH,EAAIG,GAAKoH,EAAOpH,GAElBH,EAAIzH,GAAKmK,GAGb,OAAO1C,GAAOuH,EAMhBpS,SAASvB,GACP,OAAOA,EAMTuB,WAAWwa,GACT,OAAOA,EAMTxa,WAAWua,GACT,OAAOA,EAMTva,aAAaya,GACX,OAAOA,EAMTza,SAAS0Y,GACP,OAAOA,EAMT1Y,SAAS0Y,GACP,OAAOA,EAMT1Y,WAAW2a,GACT,OAAOA,EAMT3a,SAASuE,GACP,OAAOA,EAMTvE,eAAe+I,GACb,MAAMqJ,EAASlS,KAAK8a,YAAYjS,EAAKqJ,QACrC,OAAIA,IAAWrJ,EAAKqJ,OACXrJ,EAEF,IAAIkS,GAAU7I,GAMvBpS,eAAe+I,GACb,MAAMqJ,EAASlS,KAAK8a,YAAYjS,EAAKqJ,QACrC,OAAIA,IAAWrJ,EAAKqJ,OACXrJ,EAEF,IAAImS,GAAU9I,GAMvBpS,UAAU4a,GACR,MAAMxI,EAASlS,KAAK8a,YAAYJ,EAAKxI,QACrC,OAAIA,IAAWwI,EAAKxI,OACXwI,EAEF,IAAIO,GAAKP,EAAKhZ,KAAMwQ,GAM7BpS,UAAU6a,GACR,OAAOA,SAIEjF,GAIX5V,WACE,MAAM6V,EAAM,IAAIjH,EAEhB,OADA1O,KAAK2O,SAASgH,GAAK,GACZA,EAAI9P,WAGb/F,cACE,MAAM6V,EAAM,IAAIjH,EAEhB,OADA1O,KAAK2O,SAASgH,GAAK,GACZA,EAAI9P,WAGb/F,OAAOkU,EAA2B9F,GAChC,MAAM,IAAIvP,MAAM,cAGlBmB,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAO,WAGb1M,SACE,OAAO,EAGTA,YACE,OAAO,EAGTA,QACE,OAAO,EAGTA,UACE,OAAO,EAGTA,cACE,OAAO,EAGTA,MAAMob,GACJ,MAAM,IAAIvc,MAAM,qBAIPwc,WAAczF,GAUzB5V,cACEyW,QARK6E,sBAIL,OAHKpb,KAAKoa,QACRpa,KAAKoa,MAAQ,IAAIe,IAEZnb,KAAKoa,MAUdta,OAAOkU,EAA2B9F,GAChC,OAAO,IAAImN,GAAYrH,EAAO,IAMhClU,SAAS6V,EAAwB9P,IAKjC/F,MAAMob,GACJ,OAAOA,EAAQI,WAAWtb,OAIvB,MAAMoa,GAAee,GAAMC,eAErBG,WAAc7F,GAUzB5V,cACEyW,QARK6E,sBAIL,OAHKpb,KAAKqa,QACRra,KAAKqa,MAAQ,IAAIkB,IAEZvb,KAAKqa,MAUdva,OAAOkU,EAA2B9F,GAChC,OAAO,IAAImN,GAAYrH,EAAO,KAMhClU,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAO,KAMb1M,MAAMob,GACJ,OAAOA,EAAQM,WAAWxb,OAIvB,MAAMqa,GAAekB,GAAMH,eAErBK,WAAY/F,GACvB5V,YAAmBvB,GACjBgY,QADiBvW,SAAAzB,EAOnBuB,OAAOkU,EAA2B9F,GAChC,OAAO,IAAImN,GAAYrH,EAAOhU,KAAKzB,KAMrCuB,SAAS6V,EAAwB9P,GAC3BA,GACF8P,EAAInJ,OAAO,KACXmJ,EAAInJ,OAAO+D,EAAkBvQ,KAAKzB,MAClCoX,EAAInJ,OAAO,MAEXmJ,EAAInJ,OAAOxM,KAAKzB,KAOpBuB,MAAMob,GACJ,OAAOA,EAAQQ,SAAS1b,OAI5B,MAAM2b,GAAY,SAELC,WAAclG,GACzB5V,YAAmB4B,GAEjB,GADA6U,QADiBvW,UAAA0B,EAEbia,GAAUja,GACZ,MAAM,IAAI/C,MAAM,kBAElBgd,GAAUja,GAAQ1B,KAMpBF,OAAOkU,EAA2B9F,GAChC,OAAO,IAAImN,GAAYrH,EAAOhU,KAAK0B,MAMrC5B,SAAS6V,EAAwB9P,GAC3BA,EACF8P,EAAInJ,OAAOiE,EAAoBzQ,KAAK0B,OAEpCiU,EAAInJ,OAAOxM,KAAK0B,MAOpB5B,MAAMob,GACJ,OAAOA,EAAQW,WAAW7b,MAM5BF,UACE,OAAO,YAIKgc,GAAQpa,GACtB,IAAI4C,EAAIqX,GAAUja,GAIlB,OAHK4C,IACHA,EAAI,IAAIsX,GAAMla,IAET4C,QAGIiU,WAAgB7C,GAG3B5V,YAAmB0Y,EAAahG,GAC9B+D,QADiBvW,SAAAwY,EAEjBxY,KAAKwS,KAAOA,EAAKvN,cAMnBnF,OAAOkU,EAA2B9F,GAChC,OAAgB,GAAZlO,KAAKwY,IACAxE,EAAM/C,KAEX/C,GAAoB,KAAblO,KAAKwS,KACE,KAAZxS,KAAKwY,IACAtK,EAEF,IAAI6N,GACT/H,EACA9F,EACA,IAAImN,GAAYrH,EAAOhU,KAAKwY,IAAM,MAG/B,IAAIwD,GAAchI,EAAOhU,KAAKwY,IAAKxY,KAAKwS,MAMjD1S,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAOxM,KAAKwY,IAAI3S,YACpB8P,EAAInJ,OAAOxM,KAAKwS,MAMlB1S,MAAMob,GACJ,OAAOA,EAAQe,aAAajc,MAM9BF,YACE,OAAO,SAIEoc,WAAYxG,GACvB5V,YAAmB0Y,GACjBjC,QADiBvW,SAAAwY,EAOnB1Y,OAAOkU,EAA2B9F,GAChC,OAAgB,GAAZlO,KAAKwY,IACAxE,EAAM/C,KAEC,GAAZjR,KAAKwY,IACAxE,EAAM7C,IAER,IAAIkK,GAAYrH,EAAOhU,KAAKwY,KAMrC1Y,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAOxM,KAAKwY,IAAI3S,YAMtB/F,MAAMob,GACJ,OAAOA,EAAQV,SAASxa,MAM1BF,QACE,OAAO,SAIEqc,WAAYD,GACvBpc,YAAY0Y,GACVjC,MAAMiC,GAMR1Y,MAAMob,GACJ,OAAOA,EAAQkB,SAASpc,aAIfqc,WAAc3G,GACzB5V,YAAmBwc,GACjB/F,QADiBvW,SAAAsc,EAOnBxc,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAO,KACX,MAAMjO,EAAMyB,KAAKsc,IAAIzW,SAAS,IAC9B8P,EAAInJ,OAAO,SAAStH,OAAO3G,EAAIqB,SAC/B+V,EAAInJ,OAAOjO,GAMbuB,MAAMob,GACJ,OAAOA,EAAQqB,WAAWvc,aAIjBwc,WAAY9G,GACvB5V,YAAmBuE,GACjBkS,QADiBvW,SAAAqE,EAOnBvE,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAO,SACXmJ,EAAInJ,OAAO+D,EAAkBvQ,KAAKqE,MAClCsR,EAAInJ,OAAO,MAMb1M,MAAMob,GACJ,OAAOA,EAAQuB,SAASzc,gBAIZ0c,GACd/G,EACAzD,EACAyK,EACA9W,GAEA,MAAMjG,EAASsS,EAAOtS,OACtBsS,EAAO,GAAGvD,SAASgH,EAAK9P,GACxB,IAAK,IAAI3C,EAAI,EAAGA,EAAItD,EAAQsD,IAC1ByS,EAAInJ,OAAOmQ,GACXzK,EAAOhP,GAAGyL,SAASgH,EAAK9P,SAIfkV,WAAkBrF,GAC7B5V,YAAmBoS,GACjBqE,QADiBvW,YAAAkS,EAOnBpS,SAAS6V,EAAwB9P,GAC/B6W,GAAW/G,EAAK3V,KAAKkS,OAAQ,IAAKrM,GAMpC/F,MAAMob,GACJ,OAAOA,EAAQ0B,eAAe5c,MAMhCF,cACE,OAAO,SAIEkb,WAAkBtF,GAC7B5V,YAAmBoS,GACjBqE,QADiBvW,YAAAkS,EAOnBpS,SAAS6V,EAAwB9P,GAC/B6W,GAAW/G,EAAK3V,KAAKkS,OAAQ,IAAKrM,GAMpC/F,MAAMob,GACJ,OAAOA,EAAQ2B,eAAe7c,aAIrBib,WAAavF,GACxB5V,YAAmB4B,EAAqBwQ,GACtCqE,QADiBvW,UAAA0B,EAAqB1B,YAAAkS,EAOxCpS,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAOiE,EAAoBzQ,KAAK0B,OACpCiU,EAAInJ,OAAO,KACXkQ,GAAW/G,EAAK3V,KAAKkS,OAAQ,IAAKrM,GAClC8P,EAAInJ,OAAO,KAMb1M,MAAMob,GACJ,OAAOA,EAAQ4B,UAAU9c,aAIhB+c,WAAarH,GACxB5V,YAAmB6a,GACjBpE,QADiBvW,UAAA2a,EAOnB7a,SACE,OAAOE,KAAK2a,KAMd7a,SAAS6V,EAAwB9P,GAC/B8P,EAAInJ,OAAO,gBACXxM,KAAK2a,KAAKhM,SAASgH,EAAK,GACxBA,EAAInJ,OAAO,KAMb1M,MAAMob,GACJ,OAAOA,EAAQ8B,UAAUhd,MAM3BF,SACE,OAAO,YAIKmd,GAAS5K,EAAUwD,GACjC,GAAIxD,EAAK,CACP,GAAIA,EAAI6K,YAAa,CACnB,MAAM3C,EAAUlI,EAChB,OAAOwD,EAAQ4C,cAAc8B,EAAQ/H,MAAM,GAAS+H,EAAQ/B,IAE9D,GAAInG,EAAI8K,QACN,OAAQ9K,EAAYmG,IAGxB,OAAO,WAMO4E,GAAmB/K,EAAUwD,GAC3C,OAAO,IAAI0C,GAAQ0E,GAAS5K,EAAKwD,GAAU,MAGtC,MAAMyE,GAAkC,CAC7C+C,SAAUvB,GAAQ,YAClBwB,IAAKxB,GAAQ,OACbyB,OAAQzB,GAAQ,UAChB0B,KAAM1B,GAAQ,QACd2B,MAAO3B,GAAQ,SACf4B,QAAS5B,GAAQ,WACjB6B,YAAa7B,GAAQ,eACrB8B,MAAO9B,GAAQ,SACf+B,UAAW/B,GAAQ,aACnBgC,YAAahC,GAAQ,eACrBiC,KAAMjC,GAAQ,QACdkC,OAAQlC,GAAQ,UAChBmC,WAAYnC,GAAQ,cACpBoC,UAAWpC,GAAQ,aACnBqC,WAAYrC,GAAQ,cACpBsC,KAAMtC,GAAQ,QACduC,MAAOvC,GAAQ,SACfwC,OAAQxC,GAAQ,UAChByC,UAAWzC,GAAQ,aACnBzK,OAAQyK,GAAQ,SAChB0C,MAAO1C,GAAQ,SACf2C,KAAM3C,GAAQ,QACd4C,SAAU5C,GAAQ,YAClB6C,OAAQ7C,GAAQ,UAChB8C,OAAQ9C,GAAQ,UAChB+C,OAAQ/C,GAAQ,UAChBgD,cAAehD,GAAQ,iBACvBiD,QAASjD,GAAQ,WACjBkD,OAAQlD,GAAQ,UAChBmD,aAAcnD,GAAQ,gBACtBoD,WAAYpD,GAAQ,cACpBqD,aAAcrD,GAAQ,gBACtBsD,UAAWtD,GAAQ,aACnBuD,KAAMvD,GAAQ,QACdwD,KAAMxD,GAAQ,QACdyD,UAAWzD,GAAQ,aACnB0D,IAAK1D,GAAQ,OACb2D,OAAQ3D,GAAQ,UAChB4D,KAAM5D,GAAQ,QACd6D,OAAQ7D,GAAQ,UAChB8D,cAAe9D,GAAQ,iBACvB+D,cAAe/D,GAAQ,iBACvBgE,KAAMhE,GAAQ,QACdiE,SAAUjE,GAAQ,YAClBkE,MAAOlE,GAAQ,SACfmE,KAAMnE,GAAQ,QACdzL,MAAOyL,GAAQ,SACfoE,WAAYpE,GAAQ,cACpBqE,OAAQrE,GAAQ,UAChBsE,QAAStE,GAAQ,UACjBuE,IAAKvE,GAAQ,OACbwE,MAAOxE,GAAQ,SACfyE,cAAezE,GAAQ,iBACvB0E,WAAY1E,GAAQ,cACpB2E,mBAAoB3E,GAAQ,sBAC5B4E,mBAAoB5E,GAAQ,sBAC5B6E,UAAW7E,GAAQ,aACnB8E,IAAK9E,GAAQ,OACb+E,YAAa/E,GAAQ,eACrBgF,YAAahF,GAAQ,eACrBiF,YAAajF,GAAQ,eACrBkF,QAASlF,GAAQ,WACjB1K,MAAO0K,GAAQ,SAGJmF,GAA0B,IAAI1I,GAAQ,IAAK,KAE3C2I,GAAqB,IAAI3I,GAAQ,IAAK,OAEtC4I,GAAsB,IAAI5I,GAAQ,IAAK,OAEvC6I,GAAuB,IAAI7I,GAAQ,EAAG,MAEtC8I,GAAkB,CAC7BC,YAAa,EACb7G,MAAO,YAMO8G,GAAkBC,EAAeC,GAG/C,OAFWJ,GAAgBG,IAAUE,OAAOC,YACjCN,GAAgBI,IAAUC,OAAOC,iBC7vBjCC,GACX9hB,YACS+hB,EACAC,EACAC,EACAC,GAHAhiB,QAAA6hB,EACA7hB,QAAA8hB,EACA9hB,QAAA+hB,EACA/hB,QAAAgiB,SAIEC,GACXniB,YAAmB6R,EAAkBuQ,GAAlBliB,OAAA2R,EAAkB3R,OAAAkiB,SAG1BC,GACXriB,YACSuf,EACAuB,EACAZ,EACAhC,GAHAhe,UAAAqf,EACArf,SAAA4gB,EACA5gB,WAAAggB,EACAhgB,YAAAge,SAIEoE,GACXtiB,YACSuiB,EACAjY,EACAkY,EACAC,GAHAviB,SAAAqiB,EACAriB,UAAAoK,EACApK,aAAAsiB,EACAtiB,aAAAuiB,SAQEC,GAOX1iB,YACSgiB,EACAE,EACAH,EACAE,GAHA/hB,QAAA8hB,EACA9hB,QAAAgiB,EACAhiB,QAAA6hB,EACA7hB,QAAA+hB,EATT/hB,UAAuB,KAGvBA,WAAwB,eAUVyiB,GAAeC,EAAaC,GAC1C,OAAOD,EAAGL,IAAIH,EAAIS,EAAGN,IAAIH,GAAKQ,EAAGL,IAAI1Q,EAAIgR,EAAGN,IAAI1Q,QAGrCiR,GACX9iB,YAAmB+iB,GAAA7iB,YAAA6iB,EAQnB/iB,YAAY6K,EAAgBgC,GAC1B,MAAMkW,EAAS7iB,KAAK6iB,OACdjjB,EAASijB,EAAOjjB,OACtB,IAAIkjB,EAAOD,EAAOjjB,EAAS,GAC3B,IAAK,IAAIsD,EAAI,EAAGA,EAAItD,EAAQsD,IAAK,CAC/B,MAAMqD,EAAOsc,EAAO3f,GACpB,IAAIsG,EAEFA,EADEsZ,EAAKZ,EAAI3b,EAAK2b,EACZ,IAAIE,GAAQU,EAAMvc,EAAM,EAAGoG,GAE3B,IAAIyV,GAAQ7b,EAAMuc,GAAO,EAAGnW,GAElChC,EAAIhK,KAAK6I,GACTsZ,EAAOvc,GAIXzG,WAAWijB,EAAiBC,GAC1B,MAAMH,EAAS,GACf,IAAK,MAAM1W,KAAKnM,KAAK6iB,OACnBA,EAAOliB,KAAK,IAAIshB,GAAM9V,EAAEwF,EAAIoR,EAAS5W,EAAE+V,EAAIc,IAE7C,OAAO,IAAIJ,GAAMC,aAILI,GACdC,EACAC,EACAC,EACAC,GAEA,MACMR,EAAkB,GACxB,IAAK,IAAI3f,EAAI,EAAGA,EAFF,GAEaA,IAAK,CAC9B,MAAMhE,EAAS,EAAJgE,EAAQgD,KAAKod,GAHZ,GAIZT,EAAOliB,KAAK,IAAIshB,GAAMiB,EAAKE,EAAKld,KAAKqd,IAAIrkB,GAAIikB,EAAKE,EAAKnd,KAAKsd,IAAItkB,KAElE,OAAO,IAAI0jB,GAAMC,YAGHY,GACd5B,EACAC,EACAC,EACAC,GAEA,OAAO,IAAIY,GAAM,CACf,IAAIX,GAAMJ,EAAIC,GACd,IAAIG,GAAMF,EAAID,GACd,IAAIG,GAAMF,EAAIC,GACd,IAAIC,GAAMJ,EAAIG,WAaL0B,GACX5jB,YACS6R,EACA2Q,EACAC,EACAoB,GAHA3jB,OAAA2R,EACA3R,aAAAsiB,EACAtiB,aAAAuiB,EACAviB,eAAA2jB,YAIKC,GAAWpa,EAAY0Y,GACrC,MAAMvQ,EACJnI,EAAE6Y,IAAI1Q,GAAMnI,EAAEY,KAAKuH,EAAInI,EAAE6Y,IAAI1Q,IAAMuQ,EAAI1Y,EAAE6Y,IAAIH,IAAO1Y,EAAEY,KAAK8X,EAAI1Y,EAAE6Y,IAAIH,GACvE,GAAI2B,MAAMlS,GACR,MAAM,IAAIhT,MAAM,oBAElB,OAAOgT,WAGOmS,GACdC,EACAva,EACAsY,EACAE,GAEA,IAAIH,EACAmC,EACAjC,EACAkC,EACAza,EAAEY,KAAK8X,EAAIJ,GACbjgB,EAAevB,KAAK,mCAElBkJ,EAAE6Y,IAAIH,GAAKJ,GAEbD,EAAK+B,GAAWpa,EAAGsY,GACnBkC,EAAKxa,EAAE8Y,UAEPT,EAAKrY,EAAE6Y,IAAI1Q,EACXqS,EAAK,GAEHxa,EAAEY,KAAK8X,GAAKF,GAEdD,EAAK6B,GAAWpa,EAAGwY,GACnBiC,EAAKza,EAAE8Y,UAEPP,EAAKvY,EAAEY,KAAKuH,EACZsS,EAAK,GAEHpC,EAAKE,GACPgC,EAAcpjB,KAAK,IAAI+iB,GAAiB7B,EAAImC,EAAIxa,EAAE+Y,SAAU,IAC5DwB,EAAcpjB,KAAK,IAAI+iB,GAAiB3B,EAAIkC,EAAIza,EAAE+Y,QAAS,MAE3DwB,EAAcpjB,KAAK,IAAI+iB,GAAiB3B,EAAIkC,EAAIza,EAAE+Y,SAAU,IAC5DwB,EAAcpjB,KAAK,IAAI+iB,GAAiB7B,EAAImC,EAAIxa,EAAE+Y,QAAS,cAI/C2B,GACdH,EACAI,EACAC,GAEA,MAAMC,EAAaF,EAAeC,EAC5BE,EAAsBnlB,MAAMklB,GAC5BE,EAAsBplB,MAAMklB,GAClC,IAAInhB,EACJ,IAAKA,EAAI,EAAGA,GAAKmhB,EAAYnhB,IAC3BohB,EAAUphB,GAAK,EACfqhB,EAAUrhB,GAAK,EAEjB,MAAMshB,EAAoB,GAC1B,IAAIC,GAAkB,EACtB,MAAMC,EAAoBX,EAAcnkB,OACxC,IAAK,IAAIkL,EAAI,EAAGA,EAAI4Z,EAAmB5Z,IAAK,CAC1C,MAAM6Z,EAAeZ,EAAcjZ,GACnCwZ,EAAUK,EAAapC,UAAYoC,EAAarC,QAChDiC,EAAUI,EAAapC,UAAYoC,EAAahB,UAChD,IAAIiB,GAAc,EAClB,IAAK1hB,EAAI,EAAGA,EAAIihB,EAAcjhB,IAC5B,GAAIohB,EAAUphB,KAAOqhB,EAAUrhB,GAAI,CACjC0hB,GAAc,EACd,MAGJ,GAAIA,EACF,IAAK1hB,EAAIihB,EAAcjhB,GAAKmhB,EAAYnhB,IACtC,GAAIohB,EAAUphB,IAAMqhB,EAAUrhB,GAAI,CAChC0hB,GAAc,EACd,MAIFH,GAAUG,IACZJ,EAAQ7jB,KAAKgkB,EAAahT,GAC1B8S,EAASG,GAGb,OAAOJ,WAaOre,GAAMP,EAAW4M,GAC/B,OAAOA,EAAOtM,KAAKC,MAAMP,EAAI4M,GAAQA,EAAO5M,WAU9Bif,GAAUC,GACxB,OAAO,IAAIlD,GAAKkD,EAAIhD,IAAKgD,EAAI/C,GAAI+C,EAAI9C,IAAK8C,EAAIjD,aAMhCkD,GAAYD,GAC1B,OAAO,IAAIlD,IAAMkD,EAAI9C,GAAI8C,EAAIjD,IAAKiD,EAAIhD,GAAIgD,EAAI/C,aAGhCiD,GAAYC,GAC1B,OAAO,IAAIrC,GAAMqC,EAAMpC,OAAOhY,IAAKqa,aAnBTA,GAC1B,OAAO,IAAIjD,GAAMiD,EAAMhD,GAAIgD,EAAMvT,IAkBYwT,CAAYD,cA8J3CE,GAAUN,EAAWO,GACnC,IAAIva,EAAIua,EAAMzlB,OAAS,EAInB0lB,EAAW,IAAI9C,GAAKsC,EAAI9C,GAAI8C,EAAI9C,GAAI8C,EAAIjD,GAAIiD,EAAI/C,IACpD,KAAOjX,GAAK,GAAG,CACb,MAAMya,EAAWD,EACjBA,EAAWD,EAAMva,IAEfwa,EAAStD,GAAKsD,EAASxD,GAAK,GAC3BwD,EAASzD,IAAM0D,EAAS1D,IAAMyD,EAASvD,IAAMwD,EAASxD,MAEvDwD,EAASzD,GAAKwD,EAASxD,GACvBuD,EAAMpjB,OAAO6I,EAAG,GAChBwa,EAAWC,GAEbza,cAOY0a,GAASH,EAAenD,GACtC,IAAIG,EAAM,EACNjY,EAAOib,EAAMzlB,OACjB,KAAOyiB,EAAMjY,GAAM,CACjB,MAAMqb,EAAMvf,KAAKC,OAAOkc,EAAMjY,GAAQ,GAClC8X,GAAKmD,EAAMI,GAAKzD,GAClBK,EAAMoD,EAAM,EAEZrb,EAAOqb,EAGX,OAAOpD,WASOqD,GACdL,EACAM,GAEA,IAAKN,EAAMzlB,OACT,OAAO+lB,EAET,IACIC,EACA1iB,EAFA2iB,EAAUF,EAAK7D,GAGnB,IAAK5e,EAAI,EAAGA,EAAImiB,EAAMzlB,SACpBgmB,EAAOP,EAAMniB,KAEX0iB,EAAK5D,GAAK2D,EAAK7D,IACf8D,EAAK/D,GAAK,IAAO8D,EAAK9D,IACtB+D,EAAK7D,GAAK,IAAO4D,EAAK5D,KALI7e,IAS1B2iB,EAAU3f,KAAKwL,IAAImU,EAASD,EAAK5D,IAGrC,IAAI8D,EAAaD,EACjB,KAAO3iB,EAAImiB,EAAMzlB,SACfgmB,EAAOP,EAAMniB,KAEX0iB,EAAK9D,IAAM6D,EAAK3D,IAChB4D,EAAK/D,GAAK,GAAM8D,EAAK9D,IACrB+D,EAAK7D,GAAK,GAAM4D,EAAK5D,KALA7e,IASrB4iB,EAAaF,EAAK5D,GAQtB,OAJE8D,EADE5iB,IAAMmiB,EAAMzlB,OACD+lB,EAAK3D,GAEL9b,KAAKgH,IAAI4Y,EAAYH,EAAK3D,IAErC8D,GAAcD,EACT,KAEA,IAAIjE,GAAK+D,EAAK9D,GAAIgE,EAASF,EAAK5D,GAAI+D,YAU/BC,GACdV,EACAM,GAEA,IAAKN,EAAMzlB,OACT,OAAO+lB,EAET,IACIC,EACA1iB,EAFA4iB,EAAaH,EAAK3D,GAGtB,IAAK9e,EAAImiB,EAAMzlB,OAAS,EAAGsD,GAAK,IAC9B0iB,EAAOP,EAAMniB,KACTA,IAAMmiB,EAAMzlB,OAAS,GAAKgmB,EAAK5D,GAAK2D,EAAK3D,QAG3C4D,EAAK9D,GAAK6D,EAAK3D,IACf4D,EAAK/D,GAAK,IAAO8D,EAAK9D,IACtB+D,EAAK7D,GAAK,IAAO4D,EAAK5D,IAPS7e,IAW/B4iB,EAAa5f,KAAKgH,IAAI4Y,EAAYF,EAAK9D,IAG3C,IAAI+D,EAAU3f,KAAKgH,IAAI4Y,EAAYF,EAAK5D,IACxC,KAAO9e,GAAK,IACV0iB,EAAOP,EAAMniB,KAEX0iB,EAAK5D,IAAM2D,EAAK7D,IAChB8D,EAAK/D,GAAK,GAAM8D,EAAK9D,IACrB+D,EAAK7D,GAAK,GAAM4D,EAAK5D,KALV7e,IASX2iB,EAAUD,EAAK9D,GAInB,OADA+D,EAAU3f,KAAKwL,IAAImU,EAASF,EAAK7D,IAC7BgE,GAAcD,EACT,KAEA,IAAIjE,GAAK+D,EAAK9D,GAAIgE,EAASF,EAAK5D,GAAI+D,SCriBlCE,WAAmBC,GAG9BnmB,cACEyW,QAHFvW,aAAsC,GAStCF,WAAWwa,GAET,OADAta,KAAKkmB,QAAQ5L,EAAM5Y,OAAQ,EACpB4Y,EAMTxa,eAAe+I,GAEb,OADA7I,KAAK8a,YAAYjS,EAAKqJ,QACfrJ,SAiBEsd,WAAmBF,GAC9BnmB,YAAmB1B,GACjBmY,QADiBvW,WAAA5B,EAOnB0B,SAAS0Y,GAEP,OADAxY,KAAK5B,MAAQoa,EAAIA,IACVA,YAIK4N,GAAM/T,EAAcgU,GAClC,GAAIhU,EAAK,CACP,MAAM6I,EAAU,IAAIiL,GAAWE,GAC/B,IAEE,OADAhU,EAAI8H,MAAMe,GACHA,EAAQ9c,MACf,MAAO2J,GACPlG,EAAevB,KAAKyH,EAAK,YAG7B,OAAOse,QAGIC,WAAqBL,GAKhCnmB,cACEyW,QALFvW,cAAmB,EACnBA,YAAwB,GACxBA,UAAsB,KAStBF,aAAaya,GAIX,OAHIva,KAAKumB,SACPvmB,KAAKwmB,OAAO7lB,KAAK4Z,GAEZ,KAMTza,SAAS0Y,GAIP,OAHIxY,KAAKumB,SAAsB,GAAX/N,EAAIA,KACtBxY,KAAKwmB,OAAO7lB,KAAK,IAAI8lB,GAAY,EAAG,OAE/B,KAMT3mB,eAAe+I,GAEb,OADA7I,KAAK8a,YAAYjS,EAAKqJ,QACf,KAMTpS,UAAU4a,GAOR,OANK1a,KAAKumB,UACRvmB,KAAKumB,SAAU,EACfvmB,KAAK8a,YAAYJ,EAAKxI,QACtBlS,KAAKumB,SAAU,EACfvmB,KAAK0B,KAAOgZ,EAAKhZ,KAAKuD,eAEjB,KAGTnF,SACE6R,EACAuQ,EACAwE,EACAC,EACA9Q,GAEA,GAAI7V,KAAKwmB,OAAO5mB,OAAS,EAAG,CAC1B,MAAMgnB,EAAoB,GAY1B,OAXA5mB,KAAKwmB,OAAO/lB,QAAQ,CAAComB,EAAO3jB,KAC1B,GAAkB,KAAd2jB,EAAMrU,KAAa,CACrB,IAAItE,EAAMhL,EAAI,GAAK,EAAIwjB,EAAQC,EACtB,GAALzjB,GAAuB,UAAblD,KAAK0B,OACjBwM,EAAMhI,KAAKuL,MAAMiV,EAAQA,EAAQC,EAASA,GAAU,IAEtDC,EAAQjmB,KAAMkmB,EAAMrO,IAAMtK,EAAO,UAEjC0Y,EAAQjmB,KAAKkmB,EAAMrO,IAAM3C,EAAQ4C,cAAcoO,EAAMrU,MAAM,MAGvDxS,KAAK0B,MACX,IAAK,UACH,GAAIklB,EAAQhnB,OAAS,GAAK,EAAG,CAC3B,MAAMijB,EAA+B,GACrC,IAAK,IAAI/X,EAAI,EAAGA,EAAI8b,EAAQhnB,OAAQkL,GAAK,EACvC+X,EAAOliB,KACL,IAAImmB,GAAmBnV,EAAIiV,EAAQ9b,GAAIoX,EAAI0E,EAAQ9b,EAAI,KAG3D,OAAO,IAAIic,GAAmBlE,GAEhC,MACF,IAAK,YACH,GAAsB,GAAlB+D,EAAQhnB,OACV,OAAOonB,GACLrV,EAAIiV,EAAQ,GACZ1E,EAAI0E,EAAQ,GACZjV,EAAIiV,EAAQ,GAAKA,EAAQ,GACzB1E,EAAI0E,EAAQ,GAAKA,EAAQ,IAG7B,MACF,IAAK,UACH,GAAsB,GAAlBA,EAAQhnB,OACV,OAAOqnB,GACLtV,EAAIiV,EAAQ,GACZ1E,EAAI0E,EAAQ,GACZA,EAAQ,GACRA,EAAQ,IAGZ,MACF,IAAK,SACH,GAAsB,GAAlBA,EAAQhnB,OACV,OAAOqnB,GACLtV,EAAIiV,EAAQ,GACZ1E,EAAI0E,EAAQ,GACZA,EAAQ,GACRA,EAAQ,KAMlB,OAAO,eAIKM,GACd7U,EACAV,EACAuQ,EACAwE,EACAC,EACA9Q,GAEA,GAAIxD,EAAK,CACP,MAAM6I,EAAU,IAAIoL,GACpB,IAEE,OADAjU,EAAI8H,MAAMe,GACHA,EAAQiM,SAASxV,EAAGuQ,EAAGwE,EAAOC,EAAQ9Q,GAC7C,MAAO9N,GACPlG,EAAevB,KAAKyH,EAAK,aAG7B,OAAOif,GAA0BrV,EAAGuQ,EAAGvQ,EAAI+U,EAAOxE,EAAIyE,SAG3CS,WAAwBnB,GAInCnmB,YAA4BunB,GAC1B9Q,QAD0BvW,WAAAqnB,EAH5BrnB,cAAsC,GACtCA,UAAsB,KAOtBF,WAAWwa,GAOT,OANAta,KAAK0B,KAAO4Y,EAAMzU,WACd7F,KAAKqnB,MACPrnB,KAAKsnB,SAAStnB,KAAK0B,MAAQ,EAE3B1B,KAAKsnB,SAAStnB,KAAK0B,OAAS1B,KAAKsnB,SAAStnB,KAAK0B,OAAS,GAAK,EAExD4Y,EAITxa,SAAS0Y,GAIP,OAHIxY,KAAK0B,OACP1B,KAAKsnB,SAAStnB,KAAK0B,OAAS8W,EAAIA,KAAOxY,KAAKqnB,MAAQ,EAAI,IAEnD7O,EAIT1Y,eAAe+I,GAEb,OADA7I,KAAK8a,YAAYjS,EAAKqJ,QACfrJ,YAIK0e,GACdlV,EACAgV,GAEA,MAAMnM,EAAU,IAAIkM,GAAgBC,GACpC,IACEhV,EAAI8H,MAAMe,GACV,MAAOnT,GACPlG,EAAevB,KAAKyH,EAAK,eAE3B,OAAOmT,EAAQoM,eAGJE,WAA4BC,GACvC3nB,YACS4nB,EACAC,GAEPpR,QAHOvW,aAAA0nB,EACA1nB,iBAAA2nB,EAMT7nB,SAASuE,GACP,OAAO,IAAIujB,GAAQ5nB,KAAK2nB,YAAYE,aAAaxjB,EAAIA,IAAKrE,KAAK0nB,WC/PnE,SAASI,GACPR,GAEA,MAAMhhB,EAAS,GAIf,OAHAxD,OAAOC,KAAKukB,GAAU7mB,QAASiB,IAC7B4E,EAAO5E,GAAQvC,MAAMC,KAAKkoB,EAAS5lB,MAE9B4E,QAUIyhB,GAKXjoB,YAA4BkoB,EAAyBC,GAAzBjoB,cAAAgoB,EAAyBhoB,cAAAioB,EAJrDjoB,kBAAyC,KACzCA,iBAAsB,EACtBA,gBAAqB,EAIrBF,OAAOgW,GACL,OAAI9V,OAAS8V,KAGRA,IAIH9V,KAAKgoB,WAAalS,EAAMkS,UACxBhoB,KAAKioB,WAAanS,EAAMmS,UACxBjoB,KAAKkoB,aAAepS,EAAMoS,YAC1BloB,KAAKmoB,YAAcrS,EAAMqS,WAO7BroB,aACE,OAAOE,KAAKioB,SAMdnoB,UACEE,KAAKioB,UAAW,EAMlBnoB,YACEE,KAAKioB,UAAW,GAIpB,MAAMG,GACJtoB,YACkBuoB,EACA7jB,GADAxE,kBAAAqoB,EACAroB,aAAAwE,EAMlB1E,aAAa6M,EAAY2a,GACvB3a,EAAK3M,KAAKqoB,aAAaC,uBAAuBC,kBAC5C5b,EACA3M,KAAKwE,SAEPxE,KAAKqoB,aAAaG,aAAa7b,GAAM2a,EAGvCxnB,yBACE,OAAOE,KAAKqoB,aAAaI,0BAI7B,MAAMC,GAGJ5oB,YACkBuoB,EACA7jB,EACAiP,EACAkV,GAHA3oB,kBAAAqoB,EACAroB,aAAAwE,EACAxE,eAAAyT,EACAzT,eAAA2oB,EANlB3oB,YAAkC,KASlCF,UAAU8oB,GACR5oB,KAAK4oB,OAASA,EAGR9oB,YAAYuE,GAClB,MAAMC,EAAID,EAAIE,MAAM,gBACpB,OAAOD,EAAIA,EAAE,GAAK,KAGZxE,iBAAiBuE,GACvB,IAAIwkB,EAAgB7oB,KAAKqoB,aAAaC,uBAAuBT,aAC3DiB,EAAgBzkB,EAAKrE,KAAKwE,SAC1BxE,KAAKwE,SAKP,MAHgC,MAA5BqkB,EAAc9a,OAAO,KACvB8a,EAAgBA,EAAc5e,UAAU,IAEnC4e,EAMT/oB,kBACE4B,EACAqnB,GAEA,MAAMC,EAAOhpB,KAMb,MAAM2a,EAAO,IAAIsO,GACfjpB,KAAK2oB,UACL,IAAMI,EANR,WACE,MAAM7W,EAAS8W,EAAKX,aAAaa,oBAAoBxnB,GACrD,OAAOwQ,GAAUA,EAAOtS,OAASsS,EAAOA,EAAOtS,OAAS,GAAK,KAIhDupB,IACb,gBAAgBznB,KAOlB,OADA1B,KAAKqoB,aAAae,wBAAwB1nB,GAH1C,SAAqBiJ,GACnB,OAAOoe,EAAOpe,EAAI,MAEyCgQ,GACtDA,EAMT7a,mBACE4B,EACAqnB,GAEA,MAAMC,EAAOhpB,KAKb,MAAM2a,EAAO,IAAIsO,GACfjpB,KAAK2oB,UACL,IAAMI,EAJCC,EAAKX,aAAaa,oBAAoBxnB,IAAS,IAKtD,iBAAiBA,KAGnB,OADA1B,KAAKqoB,aAAae,wBAAwB1nB,EAAMqnB,EAAQpO,GACjDA,EAiBD7a,kBACN6M,EACAkc,EACAQ,GAEA,IAAIC,EAAiBtpB,KAAKqoB,aAAaG,aAAaK,GAKpD,OAJKS,GAAkBD,GAAkB1c,IACvC3M,KAAK4oB,OAAOW,sBAAsB5c,GAClC2c,EAAiBtpB,KAAKqoB,aAAaG,aAAaK,IAE3CS,GAAkB,KASnBxpB,sBACN+oB,GAEA,OAAI7oB,KAAKqoB,aAAamB,YAAYC,aAAaZ,GACtC7oB,KAAKqoB,aAAaa,oBAElBlpB,KAAKqoB,aAAaqB,iBAAiBb,IAAkB,KAOhE/oB,oBACEuE,EACA3C,EACAqnB,GAEA,MAAMpc,EAAK3M,KAAK2pB,YAAYtlB,GACtBwkB,EAAgB7oB,KAAK4pB,iBAAiBvlB,GAI5C,IAAIijB,EAAWtnB,KAAK6pB,kBAAkBld,EAAIkc,GAAe,GACzD,GAAIvB,GAAYA,EAAS5lB,GAAO,CAG9B,MAAMooB,EAAiBxC,EAAS5lB,GAChC,OAAO,IAAI2Z,GACTrb,KAAKyT,UACLsV,EAAOe,EAAeA,EAAelqB,OAAS,IAAM,OAGxD,MAAMopB,EAAOhpB,KACb,OAAO,IAAIipB,GACTjpB,KAAK2oB,UACL,KAKE,GAFArB,EAAW0B,EAAKa,kBAAkBld,EAAIkc,GAAe,GAEjDvB,EAAU,CACZ,GAAIA,EAAS5lB,GAAO,CAGlB,MAAMooB,EAAiBxC,EAAS5lB,GAChC,OAAOqnB,EAAOe,EAAeA,EAAelqB,OAAS,IAAM,MACtD,CACL,MAAMmqB,EAAef,EAAKgB,sBAAsBnB,GAChD,GAAIkB,EAAc,CAGhB,GADAf,EAAKX,aAAa4B,iBAAiBpB,GAC/BkB,EAAaroB,GAAO,CACtB,MAAMwoB,EAAqBH,EAAaroB,GACxC,OAAOqnB,EACLmB,EAAmBA,EAAmBtqB,OAAS,IAAM,MAIvD,OAAOmpB,EAAO,GAQhB,OAJAC,EAAKX,aAAa8B,2BAChBtB,GACA,GAEK,MAQX,OADAG,EAAKX,aAAa8B,2BAA2BtB,GAAe,GACrD,MAGX,kBAAkBnnB,QAAW2C,KAOjCvE,qBACEuE,EACA3C,EACAqnB,GAEA,MAAMpc,EAAK3M,KAAK2pB,YAAYtlB,GACtBwkB,EAAgB7oB,KAAK4pB,iBAAiBvlB,GACtC2kB,EAAOhpB,KACb,OAAO,IAAIipB,GACTjpB,KAAK2oB,UACL,KACE,MAAMoB,EAAef,EAAKgB,sBAAsBnB,GAEhD,GAAKkB,EAIE,CACLf,EAAKX,aAAa4B,iBAAiBpB,GACnC,MAAMqB,EAAqBH,EAAaroB,IAAS,GAM3C0oB,EALkBpB,EAAKa,kBAC3Bld,EACAkc,GACA,GAE4CnnB,IAAS,GACvD,OAAOqnB,EAAOmB,EAAmBvqB,OAAOyqB,IAVxC,OADApB,EAAKX,aAAa8B,2BAA2BtB,GAAe,GACrD,MAaX,mBAAmBnnB,QAAW2C,YAKvBgmB,GAoBXvqB,YACkBwoB,GAAAtoB,4BAAAsoB,EApBlBtoB,kBAA4D,GAC5DA,sBAAgE,GAChEA,yBAAgD,GAChDA,0BAAiD,GACjDA,8BAAuD,GACvDA,qBAEI,GACJA,iBAA0B,KAC1BA,gCAAuD,GACvDA,uBAA8C,GAC9CA,4BAAqD,GACrDA,0BAAoE,GACpEA,wBAAkE,GAC1DA,uBAGF,GAKJA,KAAKkpB,oBAA0B,KAAI,CAAC,GAGtCppB,sBAAsB0E,GACpB,OAAO,IAAI4jB,GAAgBpoB,KAAMwE,GAGnC1E,sBACE0E,EACAiP,EACAkV,GAEA,OAAO,IAAID,GAAgB1oB,KAAMwE,EAASiP,EAAWkV,GAGvD7oB,eAAeggB,GACb9f,KAAKwpB,YAAc1J,EAGbhgB,kBAAkBwqB,EAAqBlsB,GACzC4B,KAAKkpB,oBAAoBoB,GAC3BtqB,KAAKkpB,oBAAoBoB,GAAa3pB,KAAKvC,GAE3C4B,KAAKkpB,oBAAoBoB,GAAe,CAAClsB,GAO7C0B,oBAAoByqB,GAClB,MAAMjD,EAAWtnB,KAAKkpB,oBAA0B,KAC3C5B,GAAaA,EAAS1nB,OAGzB0nB,EAASA,EAAS1nB,OAAS,GAAK2qB,EAFhCvqB,KAAKkpB,oBAA0B,KAAI,CAACqB,GAWxCzqB,mBACE0qB,EACA3U,GAIA,IAAI4U,EADJzqB,KAAK0qB,qBAAuB5C,GAAmB9nB,KAAKkpB,qBAEpD,MAAM7B,EAAQmD,EAAkB,iBAChC,GAAInD,EAAO,CACT,MAAMsD,EAAWtD,EAAMvS,SAASe,GAC5B8U,IACFF,EAAWG,GAAmBD,GAAU,IAG5C,GAAIF,EACF,IAAK,MAAMI,KAAoBJ,EAC7BzqB,KAAK8qB,kBAAkBD,EAAkBJ,EAASI,IAGtD,IAAIE,EACJ,MAAMC,EAAYR,EAAkB,qBACpC,GAAIQ,EAAW,CACb,MAAMC,EAAeD,EAAUlW,SAASe,GACpCoV,IACFF,EAAeH,GAAmBK,GAAc,IAMhDF,EACI,SAAUA,IACdA,EAAmB,KAAI,IAGzBA,EAAe,GACfA,EAAmB,KAAI,GAEzB,IAAK,MAAMG,KAAwBH,EAAc,CAC1C/qB,KAAKkpB,oBAAoBgC,IAC5BlrB,KAAK8qB,kBAAkBI,EAAsB,GAE/C,MAAMC,EAAgBnrB,KAAKkpB,oBAAoBgC,GAC/CC,EAAcA,EAAcvrB,OAAS,IACnCmrB,EAAaG,IAQnBprB,iBAAiBwnB,GACftnB,KAAKorB,yBAAyBzqB,KAAKX,KAAKkpB,qBACxClpB,KAAKkpB,oBAAsBpB,GAAmBR,GAMhDxnB,kBACEE,KAAKkpB,oBAAsBlpB,KAAKorB,yBAAyB5kB,MAM3D1G,iBAAiB6M,GACf,MAAM0e,EAAiBrrB,KAAKsrB,qBAAqB3e,GACjD,IAAI4e,EAAevrB,KAAKwrB,mBAAmB7e,GACtC4e,IACHA,EAAevrB,KAAKwrB,mBAAmB7e,GAAM,IAE/C,IAAI8e,GAAS,EACb,IAAK,IAAIvoB,EAAI,EAAGA,EAAIlD,KAAK0rB,kBAAkB9rB,QAAU,CACnD,MAAMsO,EAAMlO,KAAK0rB,kBAAkBxoB,GACnC,GAAIgL,EAAI8Z,WAAarb,EAAI,CAGvB,GAFAuB,EAAIyd,UACJ3rB,KAAK0rB,kBAAkBzpB,OAAOiB,EAAG,GAC7BmoB,EAAgB,CAClB,MAAM/lB,EAAI+lB,EAAerpB,QAAQkM,GAC7B5I,GAAK,GACP+lB,EAAeppB,OAAOqD,EAAG,GAG7BimB,EAAa5qB,KAAKuN,GAClBud,GAAS,OAETvoB,IAGCuoB,GACHzrB,KAAKmqB,2BAA2Bxd,GAAI,GAQxC7M,2BAA2B6M,EAAYsb,GACrC,IAAKjoB,KAAK4rB,2BAA2BC,KAAM3d,GAAQA,EAAI8Z,WAAarb,GAAK,CACvE,MAAMuB,EAAM,IAAI6Z,GAAuBpb,EAAIsb,GAC3CjoB,KAAK4rB,2BAA2BjrB,KAAKuN,IAUzCpO,WAAWooB,EAAoBC,GAC7B,MAAM2D,EAAMhpB,OAAOC,KAAK/C,KAAKwpB,YAAYC,cACzC,GAAIqC,EAAIlsB,OAAS,EAAG,CAClB,MAAMspB,EAAsBpB,GAAmB9nB,KAAKkpB,qBACpD4C,EAAIrrB,QAASkM,IACX3M,KAAK0pB,iBAAiB/c,GAAMuc,EAC5B,MAAM6C,EAAe/rB,KAAKgsB,gBAAgBrf,GAC1C,GAAIof,GAAgBA,EAAa5D,UAAYA,EAAW,CACtD,MAAMoD,EAAevrB,KAAKwrB,mBAAmB7e,GAC7C,GAAI4e,EAAc,CAChB,IAIIrd,EAJAmd,EAAiBrrB,KAAKsrB,qBAAqB3e,GAK/C,IAJK0e,IACHA,EAAiBrrB,KAAKsrB,qBAAqB3e,GAAM,IAG3CuB,EAAMqd,EAAajsB,SACzB4O,EAAI+d,YACJZ,EAAe1qB,KAAKuN,IAI1BlO,KAAKgsB,gBAAgBrf,GAAM,CAAEub,WAAAA,EAAYC,UAAAA,KAG7C,MAAM+D,EAAmBlsB,KAAK0qB,qBAC9B,IAAIxc,EACJ,KAAQA,EAAMlO,KAAK4rB,2BAA2BtsB,SAAU,CAItD,IAAIqL,EAHJuD,EAAI6b,aAAemC,EACnBhe,EAAIga,WAAaA,EACjBha,EAAIia,UAAYA,EAEZja,EAAIie,cACNxhB,EAAM3K,KAAKwrB,mBAAmBtd,EAAI8Z,UAC7Brd,IACHA,EAAM3K,KAAKwrB,mBAAmBtd,EAAI8Z,UAAY,MAGhDrd,EAAM3K,KAAKsrB,qBAAqBpd,EAAI8Z,UAC/Brd,IACHA,EAAM3K,KAAKsrB,qBAAqBpd,EAAI8Z,UAAY,KAGhDrd,EAAIyhB,MAAO9nB,IAAO4J,EAAIme,OAAO/nB,KAC/BqG,EAAIhK,KAAKuN,GAGblO,KAAKwpB,YAAc,KAMrB1pB,wBACEggB,GAOA,IAAIwM,EAAiC,GACzBxpB,OAAOC,KAAK+c,EAAK2J,cACzBhpB,QAASkM,IACX,MAAM4f,EAASvsB,KAAKsrB,qBAAqB3e,GACrC4f,IACFD,EAAOA,EAAK3sB,OAAO4sB,MAGvBD,EAAKE,KACH,CAACC,EAAIC,IAAOD,EAAGvE,WAAawE,EAAGxE,YAAcuE,EAAGtE,UAAYuE,EAAGvE,WAEjE,MAAM7hB,EAKA,GACN,IAAIqmB,EAKA,KAkBJ,OAjBAL,EAAK7rB,QAASyN,IAETye,GACDA,EAAEzE,aAAeha,EAAIga,YACrByE,EAAExE,YAAcja,EAAIia,UAUpBwE,EAAEL,KAAK3rB,KAAKuN,IARZye,EAAI,CACFzE,WAAYha,EAAIga,WAChBC,UAAWja,EAAIia,UACf4B,aAAc7b,EAAI6b,aAClBuC,KAAM,CAACpe,IAET5H,EAAO3F,KAAKgsB,MAKTrmB,EAOTxG,sBAAsBwsB,GACpBtsB,KAAK4sB,uBAAuBjsB,KAAKX,KAAK0rB,mBACtC1rB,KAAK0rB,kBAAoBY,EAM3BxsB,uBACEE,KAAK0rB,kBAAoB1rB,KAAK4sB,uBAAuBpmB,MAGvD1G,wBACE4B,EACAqnB,EACApO,GAEa,UAATjZ,GACF1B,KAAK6sB,kBAAkBlsB,KAAK,CAAEga,KAAAA,EAAMoO,OAAAA,IAIxCjpB,yBACE,OAAOE,KAAK8sB,oBAAoBC,KAAK/sB,MAG/BF,oBAAoB6a,EAAMtI,EAAKpL,GAErC,GADcjH,KAAK6sB,kBAAkBG,UAAWL,GAAMA,EAAEhS,OAASA,IAAS,EAC/D,CACT,MAAMhP,EAAO1E,EAASC,cAAc,QAGpC,OAFAyE,EAAKgC,YAAc0E,EACnB1G,EAAKshB,aAAaC,GAAoBvS,EAAK/P,KACpCe,EAEP,OAAO,KAIX7L,eAAeqtB,GACb,MAAMC,EAAQD,EAASE,KAAKC,iBAAiB,IAAIJ,OAC3CK,EAAQvtB,KAAKkpB,oBAA0B,KAAE,GAC/C/pB,MAAMC,KAAKguB,GAAO3sB,QAASkL,IACzB,MAAMf,EAAMe,EAAKhD,aAAaukB,IACxBhqB,EAAIlD,KAAK6sB,kBAAkBG,UAAWL,GAAMA,EAAEhS,KAAK/P,MAAQA,GAEjEe,EAAKgC,YAAc3N,KAAK6sB,kBAAkB3pB,GAAG6lB,OAAO,CAACwE,MAIzDztB,uBAAuBqoB,GACrB,OAAO,IAAIqF,GAAiBxtB,KAAMmoB,IAI/B,MAAM+E,GAAqB,iCAElC,MAAMM,GACJ1tB,YACkBuoB,EACAF,GADAnoB,kBAAAqoB,EACAroB,eAAAmoB,EAMlBroB,YAAY2tB,GACV,IAAKA,GAAeA,EAAYpgB,MAC9B,OAAO,EAET,MAAMqgB,EAAWD,EAAYC,SAC7B,IAAKA,GAAkC,IAAtBA,EAAS9hB,SACxB,OAAO,EAET,MAAMe,EACH+gB,EAAqB/kB,aAAa,OAClC+kB,EAAqB/kB,aAAa,QACrC,IAAKgE,EACH,OAAO,EAET,IACG3M,KAAKqoB,aAAamD,mBAAmB7e,KACrC3M,KAAKqoB,aAAaiD,qBAAqB3e,GAExC,OAAO,EAET,MAAMwb,EAAYnoB,KAAKqoB,aAAa2D,gBAAgBrf,GACpD,OAAKwb,GAGEnoB,KAAKmoB,WAAaA,EAAUA,oBCvrBvBwF,GAAkBpvB,GAEhC,IADAA,EAAMA,EAAI2G,OAAO,IACTX,MAAM,sBACZ,OAAOhG,EAET,MAAMqvB,EAAO5jB,SAASzL,EAAK,IAC3B,OAAIslB,MAAM+J,GACD,GAELA,GAAQ,MACH9jB,OAAOC,aAAa6jB,GAEzBA,GAAQ,QAEH9jB,OAAOC,aACZ,MAAU6jB,GAAQ,GAAM,KACxB,MAAgB,KAAPA,GAKN,aAGOC,GAAYtvB,GAC1B,OAAOA,EAAIgH,QACT,4DACAooB,IAOJ,IAAYG,GAsEAC,IAtEZ,SAAYD,GACVA,iBACAA,qBACAA,iBACAA,yBACAA,iBACAA,iBACAA,mBACAA,mBACAA,iBACAA,qBACAA,sBACAA,sBACAA,sBACAA,sBACAA,sBACAA,sBACAA,sBACAA,0BACAA,sBACAA,sBACAA,gBACAA,0BACAA,sBACAA,oBACAA,sBACAA,0BACAA,0BAGAA,oBACAA,wBACAA,kBACAA,kBACAA,sBACAA,oBACAA,gBACAA,gBACAA,gBAGAA,0BACAA,8BACAA,wBACAA,wBACAA,4BACAA,0BACAA,sBACAA,sBACAA,sBACAA,0BACAA,0BACAA,oBApDF,CAAYA,KAAAA,cAuDCE,GAOXluB,cALAE,sBAA2B,EAC3BA,SAAc,EACdA,UAAe,GACfA,cAAmB,EAGjBA,KAAKkL,KAAO4iB,GAAUG,cA6FVC,GAAY7H,EAAa8H,GACvC,MAAMjvB,EAAcC,MAAM,KAC1B,IAAI+D,EACJ,IAAKA,EAAI,EAAGA,EAAI,IAAKA,IACnBhE,EAAEgE,GAAKmjB,EAGT,IADAnnB,EAAK,IAAImnB,GAAO0H,GAAOK,IAAML,GAAOK,IAAML,GAAOM,QAC5CnrB,EAAI,EAAGA,EAAIirB,EAAKvuB,OAAQsD,GAAK,EAChChE,EAAEivB,EAAKjrB,IAAMirB,EAAKjrB,EAAI,GAExB,OAAOhE,GAhGT,SAAY6uB,GACVA,qBACAA,iBACAA,qBACAA,mBACAA,mBACAA,uBACAA,yBACAA,iBACAA,sBACAA,sBACAA,oBACAA,oBACAA,sBACAA,sBACAA,kBACAA,sBACAA,sBACAA,0BACAA,gBACAA,gBACAA,gBACAA,sBACAA,gBACAA,sBACAA,sBACAA,sBACAA,sBACAA,wBACAA,kBACAA,kBACAA,sBACAA,oBACAA,oBACAA,kBACAA,wBACAA,wBACAA,wBACAA,oBACAA,oBACAA,wBACAA,wBACAA,0BACAA,0BACAA,0BAGAA,wBACAA,0BAGAA,0BACAA,0BACAA,0BACAA,0BACAA,oBACAA,wBACAA,0BACAA,wBACAA,0BACAA,wBACAA,sBACAA,sBACAA,0BACAA,wBACAA,sBACAA,sBACAA,kBACAA,oBACAA,oBACAA,wBACAA,0BACAA,wBACAA,sBACAA,0BACAA,0BACAA,0BACAA,0BACAA,wBACAA,wBACAA,0BACAA,0BACAA,sBACAA,kBAnFF,CAAYA,KAAAA,QAsGL,MAAMO,GAA0B,CACrCP,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOQ,MACPR,GAAOQ,MACPR,GAAOM,QACPN,GAAOQ,MACPR,GAAOQ,MACPR,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOM,QACPN,GAAOQ,MACPR,GAAOS,KACPT,GAAOU,KACPV,GAAOW,KACPX,GAAOY,OACPZ,GAAOa,QACPb,GAAOc,IACPd,GAAOe,KACPf,GAAOgB,MACPhB,GAAOiB,MACPjB,GAAOkB,KACPlB,GAAOmB,KACPnB,GAAOoB,MACPpB,GAAOqB,MACPrB,GAAOsB,IACPtB,GAAOuB,MACPvB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOwB,IACPxB,GAAOyB,MACPzB,GAAO0B,QACP1B,GAAO2B,GACP3B,GAAO4B,GACP5B,GAAO6B,GACP7B,GAAO8B,MACP9B,GAAO+B,GACP/B,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOiC,MACPjC,GAAOkC,OACPlC,GAAOmC,MACPnC,GAAOoC,IACPpC,GAAOgC,MACPhC,GAAOM,QACPN,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOgC,MACPhC,GAAOqC,MACPrC,GAAOsC,IACPtC,GAAOuC,MACPvC,GAAOwC,MACPxC,GAAOM,SAGTC,GAAiB,IAAIP,GAAOE,IAKrB,MAAMuC,GAAyB,CACpCzC,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO2C,KACP3C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO4C,KACP5C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO0C,QACP1C,GAAO6C,QACP7C,GAAO0C,QACP1C,GAAO0C,QACP1C,GAAO4C,KACP5C,GAAO0C,QACP1C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KACP5C,GAAO4C,KAC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IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,KAEFC,SAAU,CACR,MACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,KAEFC,OAAQ,CACN,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,IACA,GACA,KACA,GACA,KACA,GACA,KACA,GACA,KACA,GACA,KACA,GACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,IACA,EACA,MAISnC,GAAsB,CACjCoC,MAAO,MACPC,MAAO,MACPC,MAAO,SACPC,QAAS,aAGEhoC,GAAQ,CACnBioC,OAAQ,IACRC,KAAM,IACNC,OAAQ,IACRjnC,KAAM,IAmED,MAAMylC,GAAwC,CACnDP,QAAQ,EACRF,OAAQ,aACRG,QAAS,MACTF,SAAU,KA0DL,MAAMiC,GAAkB,EAAI,iBA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"}
\No newline at end of file