[api-major] Remove the SVG back-end (PR 15173 follow-up)

This has been deprecated since version `2.15.349`, which is a year ago.
Removing this will also simplify some upcoming changes, specifically outputting of JavaScript modules in the builds.
This commit is contained in:
Jonas Jenwald 2022-01-19 11:43:41 +01:00
parent be53c7d6f5
commit 3ced0dec1b
16 changed files with 1 additions and 2302 deletions

View File

@ -1,285 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function xmlEncode(s) {
let i = 0,
ch;
s = String(s);
while (
i < s.length &&
(ch = s[i]) !== "&" &&
ch !== "<" &&
ch !== '"' &&
ch !== "\n" &&
ch !== "\r" &&
ch !== "\t"
) {
i++;
}
if (i >= s.length) {
return s;
}
let buf = s.substring(0, i);
while (i < s.length) {
ch = s[i++];
switch (ch) {
case "&":
buf += "&amp;";
break;
case "<":
buf += "&lt;";
break;
case '"':
buf += "&quot;";
break;
case "\n":
buf += "&#xA;";
break;
case "\r":
buf += "&#xD;";
break;
case "\t":
buf += "&#x9;";
break;
default:
buf += ch;
break;
}
}
return buf;
}
function DOMElement(name) {
this.nodeName = name;
this.childNodes = [];
this.attributes = {};
this.textContent = "";
if (name === "style") {
this.sheet = {
cssRules: [],
insertRule(rule) {
this.cssRules.push(rule);
},
};
}
}
DOMElement.prototype = {
getAttribute: function DOMElement_getAttribute(name) {
if (name in this.attributes) {
return this.attributes[name];
}
return null;
},
getAttributeNS: function DOMElement_getAttributeNS(NS, name) {
// Fast path
if (name in this.attributes) {
return this.attributes[name];
}
// Slow path - used by test/unit/display_svg_spec.js
// Assuming that there is only one matching attribute for a given name,
// across all namespaces.
if (NS) {
const suffix = ":" + name;
for (const fullName in this.attributes) {
if (fullName.slice(-suffix.length) === suffix) {
return this.attributes[fullName];
}
}
}
return null;
},
setAttribute: function DOMElement_setAttribute(name, value) {
this.attributes[name] = value || "";
},
setAttributeNS: function DOMElement_setAttributeNS(NS, name, value) {
this.setAttribute(name, value);
},
append: function DOMElement_append(...elements) {
const childNodes = this.childNodes;
for (const element of elements) {
if (!childNodes.includes(element)) {
childNodes.push(element);
}
}
},
appendChild: function DOMElement_appendChild(element) {
const childNodes = this.childNodes;
if (!childNodes.includes(element)) {
childNodes.push(element);
}
},
hasChildNodes: function DOMElement_hasChildNodes() {
return this.childNodes.length !== 0;
},
cloneNode: function DOMElement_cloneNode() {
const newNode = new DOMElement(this.nodeName);
newNode.childNodes = this.childNodes;
newNode.attributes = this.attributes;
newNode.textContent = this.textContent;
return newNode;
},
// This method is offered for convenience. It is recommended to directly use
// getSerializer because that allows you to process the chunks as they come
// instead of requiring the whole image to fit in memory.
toString: function DOMElement_toString() {
const buf = [];
const serializer = this.getSerializer();
let chunk;
while ((chunk = serializer.getNext()) !== null) {
buf.push(chunk);
}
return buf.join("");
},
getSerializer: function DOMElement_getSerializer() {
return new DOMElementSerializer(this);
},
};
function DOMElementSerializer(node) {
this._node = node;
this._state = 0;
this._loopIndex = 0;
this._attributeKeys = null;
this._childSerializer = null;
}
DOMElementSerializer.prototype = {
/**
* Yields the next chunk in the serialization of the element.
*
* @returns {string|null} null if the element has fully been serialized.
*/
getNext: function DOMElementSerializer_getNext() {
const node = this._node;
switch (this._state) {
case 0: // Start opening tag.
++this._state;
return "<" + node.nodeName;
case 1: // Add SVG namespace if this is the root element.
++this._state;
if (node.nodeName === "svg:svg") {
return (
' xmlns:xlink="http://www.w3.org/1999/xlink"' +
' xmlns:svg="http://www.w3.org/2000/svg"'
);
}
/* falls through */
case 2: // Initialize variables for looping over attributes.
++this._state;
this._loopIndex = 0;
this._attributeKeys = Object.keys(node.attributes);
/* falls through */
case 3: // Serialize any attributes and end opening tag.
if (this._loopIndex < this._attributeKeys.length) {
const name = this._attributeKeys[this._loopIndex++];
return " " + name + '="' + xmlEncode(node.attributes[name]) + '"';
}
++this._state;
return ">";
case 4: // Serialize textContent for tspan/style elements.
if (node.nodeName === "svg:tspan" || node.nodeName === "svg:style") {
this._state = 6;
return xmlEncode(node.textContent);
}
++this._state;
this._loopIndex = 0;
/* falls through */
case 5: // Serialize child nodes (only for non-tspan/style elements).
while (true) {
const value =
this._childSerializer && this._childSerializer.getNext();
if (value !== null) {
return value;
}
const nextChild = node.childNodes[this._loopIndex++];
if (nextChild) {
this._childSerializer = new DOMElementSerializer(nextChild);
} else {
this._childSerializer = null;
++this._state;
break;
}
}
/* falls through */
case 6: // Ending tag.
++this._state;
return "</" + node.nodeName + ">";
case 7: // Done.
return null;
default:
throw new Error("Unexpected serialization state: " + this._state);
}
},
};
const document = {
childNodes: [],
get currentScript() {
return { src: "" };
},
get documentElement() {
return this;
},
createElementNS(NS, element) {
const elObject = new DOMElement(element);
return elObject;
},
createElement(element) {
return this.createElementNS("", element);
},
getElementsByTagName(element) {
if (element === "head") {
return [this.head || (this.head = new DOMElement("head"))];
}
return [];
},
};
function Image() {
this._src = null;
this.onload = null;
}
Image.prototype = {
get src() {
return this._src;
},
set src(value) {
this._src = value;
if (this.onload) {
this.onload();
}
},
};
exports.document = document;
exports.Image = Image;
const exported_symbols = Object.keys(exports);
exports.setStubs = function (namespace) {
exported_symbols.forEach(function (key) {
console.assert(!(key in namespace), "property should not be set: " + key);
namespace[key] = exports[key];
});
};
exports.unsetStubs = function (namespace) {
exported_symbols.forEach(function (key) {
console.assert(key in namespace, "property should be set: " + key);
delete namespace[key];
});
};

View File

@ -1,128 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
//
// Node tool to dump SVG output into a file.
//
const fs = require("fs");
const util = require("util");
const path = require("path");
const stream = require("stream");
// HACK few hacks to let PDF.js be loaded not as a module in global space.
require("./domstubs.js").setStubs(global);
// Run `gulp dist-install` to generate 'pdfjs-dist' npm package files.
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
// Some PDFs need external cmaps.
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
// Loading file from file system into typed array
const pdfPath =
process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
const data = new Uint8Array(fs.readFileSync(pdfPath));
const outputDirectory = "./svgdump";
try {
// Note: This creates a directory only one level deep. If you want to create
// multiple subdirectories on the fly, use the mkdirp module from npm.
fs.mkdirSync(outputDirectory);
} catch (e) {
if (e.code !== "EEXIST") {
throw e;
}
}
// Dumps svg outputs to a folder called svgdump
function getFilePathForPage(pageNum) {
const name = path.basename(pdfPath, path.extname(pdfPath));
return path.join(outputDirectory, `${name}-${pageNum}.svg`);
}
/**
* A readable stream which offers a stream representing the serialization of a
* given DOM element (as defined by domstubs.js).
*
* @param {object} options
* @param {DOMElement} options.svgElement The element to serialize
*/
function ReadableSVGStream(options) {
if (!(this instanceof ReadableSVGStream)) {
return new ReadableSVGStream(options);
}
stream.Readable.call(this, options);
this.serializer = options.svgElement.getSerializer();
}
util.inherits(ReadableSVGStream, stream.Readable);
// Implements https://nodejs.org/api/stream.html#stream_readable_read_size_1
ReadableSVGStream.prototype._read = function () {
let chunk;
while ((chunk = this.serializer.getNext()) !== null) {
if (!this.push(chunk)) {
return;
}
}
this.push(null);
};
// Streams the SVG element to the given file path.
function writeSvgToFile(svgElement, filePath) {
let readableSvgStream = new ReadableSVGStream({
svgElement,
});
const writableStream = fs.createWriteStream(filePath);
return new Promise(function (resolve, reject) {
readableSvgStream.once("error", reject);
writableStream.once("error", reject);
writableStream.once("finish", resolve);
readableSvgStream.pipe(writableStream);
}).catch(function (err) {
readableSvgStream = null; // Explicitly null because of v8 bug 6512.
writableStream.end();
throw err;
});
}
// Will be using async/await to load document, pages and misc data.
const loadingTask = pdfjsLib.getDocument({
data,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
fontExtraProperties: true,
});
(async function () {
const doc = await loadingTask.promise;
const numPages = doc.numPages;
console.log("# Document Loaded");
console.log(`Number of Pages: ${numPages}`);
console.log();
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
try {
const page = await doc.getPage(pageNum);
console.log(`# Page ${pageNum}`);
const viewport = page.getViewport({ scale: 1.0 });
console.log(`Size: ${viewport.width}x${viewport.height}`);
console.log();
const opList = await page.getOperatorList();
const svgGfx = new pdfjsLib.SVGGraphics(
page.commonObjs,
page.objs,
/* forceDataSchema = */ true
);
svgGfx.embedFonts = true;
const svg = await svgGfx.getSVG(opList, viewport);
await writeSvgToFile(svg, getFilePathForPage(pageNum));
// Release page resources.
page.cleanup();
} catch (err) {
console.log(`Error: ${err}`);
}
}
console.log("# End of Document");
})();

View File

@ -242,7 +242,6 @@ function createWebpackConfig(
"display-network": "src/display/stubs.js", "display-network": "src/display/stubs.js",
"display-node_stream": "src/display/stubs.js", "display-node_stream": "src/display/stubs.js",
"display-node_utils": "src/display/stubs.js", "display-node_utils": "src/display/stubs.js",
"display-svg": "src/display/stubs.js",
}; };
const viewerAlias = { const viewerAlias = {
"web-alt_text_manager": "web/alt_text_manager.js", "web-alt_text_manager": "web/alt_text_manager.js",
@ -276,7 +275,6 @@ function createWebpackConfig(
libraryAlias["display-network"] = "src/display/network.js"; libraryAlias["display-network"] = "src/display/network.js";
libraryAlias["display-node_stream"] = "src/display/node_stream.js"; libraryAlias["display-node_stream"] = "src/display/node_stream.js";
libraryAlias["display-node_utils"] = "src/display/node_utils.js"; libraryAlias["display-node_utils"] = "src/display/node_utils.js";
libraryAlias["display-svg"] = "src/display/svg.js";
viewerAlias["web-com"] = "web/genericcom.js"; viewerAlias["web-com"] = "web/genericcom.js";
viewerAlias["web-print_service"] = "web/pdf_print_service.js"; viewerAlias["web-print_service"] = "web/pdf_print_service.js";
@ -1637,7 +1635,6 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) {
"display-network": "./network", "display-network": "./network",
"display-node_stream": "./node_stream", "display-node_stream": "./node_stream",
"display-node_utils": "./node_utils", "display-node_utils": "./node_utils",
"display-svg": "./svg",
}, },
}; };
const licenseHeaderLibre = fs const licenseHeaderLibre = fs
@ -1670,12 +1667,7 @@ function buildLib(defines, dir) {
{ base: "src/" } { base: "src/" }
), ),
gulp.src( gulp.src(
[ ["external/webL10n/l10n.js", "web/*.js", "!web/{pdfjs,viewer}.js"],
"examples/node/domstubs.js",
"external/webL10n/l10n.js",
"web/*.js",
"!web/{pdfjs,viewer}.js",
],
{ base: "." } { base: "." }
), ),
gulp.src("test/unit/*.js", { base: "." }), gulp.src("test/unit/*.js", { base: "." }),
@ -2217,7 +2209,6 @@ function packageJson() {
http: false, http: false,
https: false, https: false,
url: false, url: false,
zlib: false,
}, },
format: "amd", // to not allow system.js to choose 'cjs' format: "amd", // to not allow system.js to choose 'cjs'
repository: { repository: {

View File

@ -73,7 +73,6 @@ import { PDFDataTransportStream } from "./transport_stream.js";
import { PDFFetchStream } from "display-fetch_stream"; import { PDFFetchStream } from "display-fetch_stream";
import { PDFNetworkStream } from "display-network"; import { PDFNetworkStream } from "display-network";
import { PDFNodeStream } from "display-node_stream"; import { PDFNodeStream } from "display-node_stream";
import { SVGGraphics } from "display-svg";
import { XfaText } from "./xfa_text.js"; import { XfaText } from "./xfa_text.js";
const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536 const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
@ -3468,6 +3467,5 @@ export {
PDFWorker, PDFWorker,
PDFWorkerUtil, PDFWorkerUtil,
RenderTask, RenderTask,
SVGGraphics,
version, version,
}; };

View File

@ -21,7 +21,6 @@ const NullL10n = null;
const PDFFetchStream = null; const PDFFetchStream = null;
const PDFNetworkStream = null; const PDFNetworkStream = null;
const PDFNodeStream = null; const PDFNodeStream = null;
const SVGGraphics = null;
export { export {
NodeCanvasFactory, NodeCanvasFactory,
@ -32,5 +31,4 @@ export {
PDFFetchStream, PDFFetchStream,
PDFNetworkStream, PDFNetworkStream,
PDFNodeStream, PDFNodeStream,
SVGGraphics,
}; };

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,6 @@ import {
getDocument, getDocument,
PDFDataRangeTransport, PDFDataRangeTransport,
PDFWorker, PDFWorker,
SVGGraphics,
version, version,
} from "./display/api.js"; } from "./display/api.js";
import { import {
@ -119,7 +118,6 @@ export {
renderTextLayer, renderTextLayer,
setLayerDimensions, setLayerDimensions,
shadow, shadow,
SVGGraphics,
UnexpectedResponseException, UnexpectedResponseException,
updateTextLayer, updateTextLayer,
Util, Util,

View File

@ -17,7 +17,6 @@
"crypto_spec.js", "crypto_spec.js",
"custom_spec.js", "custom_spec.js",
"default_appearance_spec.js", "default_appearance_spec.js",
"display_svg_spec.js",
"display_utils_spec.js", "display_utils_spec.js",
"document_spec.js", "document_spec.js",
"editor_spec.js", "editor_spec.js",

View File

@ -1,163 +0,0 @@
/* Copyright 2017 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals __non_webpack_require__ */
import { buildGetDocumentParams } from "./test_utils.js";
import { getDocument } from "../../src/display/api.js";
import { isNodeJS } from "../../src/shared/util.js";
import { SVGGraphics } from "../../src/display/svg.js";
const XLINK_NS = "http://www.w3.org/1999/xlink";
// withZlib(true, callback); = run test with require('zlib') if possible.
// withZlib(false, callback); = run test without require('zlib').deflateSync.
// The return value of callback is returned as-is.
function withZlib(isZlibRequired, callback) {
if (isZlibRequired) {
// We could try to polyfill zlib in the browser, e.g. using pako.
// For now, only support zlib functionality on Node.js
if (!isNodeJS) {
throw new Error("zlib test can only be run in Node.js");
}
return callback();
}
if (!isNodeJS) {
// Assume that require('zlib') is unavailable in non-Node.
return callback();
}
const zlib = __non_webpack_require__("zlib");
const deflateSync = zlib.deflateSync;
zlib.deflateSync = disabledDeflateSync;
function disabledDeflateSync() {
throw new Error("zlib.deflateSync is explicitly disabled for testing.");
}
function restoreDeflateSync() {
if (zlib.deflateSync === disabledDeflateSync) {
zlib.deflateSync = deflateSync;
}
}
const promise = callback();
promise.then(restoreDeflateSync, restoreDeflateSync);
return promise;
}
describe("SVGGraphics", function () {
let loadingTask;
let page;
beforeAll(async function () {
loadingTask = getDocument(
buildGetDocumentParams("xobject-image.pdf", {
isOffscreenCanvasSupported: false,
})
);
const doc = await loadingTask.promise;
page = await doc.getPage(1);
});
afterAll(async function () {
await loadingTask.destroy();
});
describe("paintImageXObject", function () {
function getSVGImage() {
let svgGfx;
return page
.getOperatorList()
.then(function (opList) {
const forceDataSchema = true;
svgGfx = new SVGGraphics(page.commonObjs, page.objs, forceDataSchema);
return svgGfx.loadDependencies(opList);
})
.then(function () {
let svgImg;
// A mock to steal the svg:image element from paintInlineImageXObject.
const elementContainer = {
append(...elements) {
svgImg = elements.at(-1);
},
};
// This points to the XObject image in xobject-image.pdf.
const xobjectObjId = "img_p0_1";
if (isNodeJS) {
const { setStubs } = __non_webpack_require__(
"../../examples/node/domstubs.js"
);
setStubs(global);
}
try {
const imgData = svgGfx.objs.get(xobjectObjId);
svgGfx.paintInlineImageXObject(imgData, elementContainer);
} finally {
if (isNodeJS) {
const { unsetStubs } = __non_webpack_require__(
"../../examples/node/domstubs.js"
);
unsetStubs(global);
}
}
return svgImg;
});
}
it('should fail require("zlib") unless in Node.js', function () {
function testFunc() {
__non_webpack_require__("zlib");
}
if (isNodeJS) {
// Verifies that the script loader replaces __non_webpack_require__ with
// require.
expect(testFunc.toString()).toMatch(/\srequire\(["']zlib["']\)/);
expect(testFunc).not.toThrow();
} else {
// require not defined, require('zlib') not a module, etc.
expect(testFunc).toThrow();
}
});
it("should produce a reasonably small svg:image", async function () {
if (!isNodeJS) {
pending("zlib.deflateSync is not supported in non-Node environments.");
}
const svgImg = await withZlib(true, getSVGImage);
expect(svgImg.nodeName).toBe("svg:image");
expect(svgImg.getAttributeNS(null, "width")).toBe("200px");
expect(svgImg.getAttributeNS(null, "height")).toBe("100px");
const imgUrl = svgImg.getAttributeNS(XLINK_NS, "href");
// forceDataSchema = true, so the generated URL should be a data:-URL.
expect(imgUrl).toMatch(/^data:image\/png;base64,/);
// Test whether the generated image has a reasonable file size.
// I obtained a data URL of size 366 with Node 8.1.3 and zlib 1.2.11.
// Without zlib (uncompressed), the size of the data URL was excessive
// (80246).
expect(imgUrl.length).toBeLessThan(367);
});
it("should be able to produce a svg:image without zlib", async function () {
const svgImg = await withZlib(false, getSVGImage);
expect(svgImg.nodeName).toBe("svg:image");
expect(svgImg.getAttributeNS(null, "width")).toBe("200px");
expect(svgImg.getAttributeNS(null, "height")).toBe("100px");
const imgUrl = svgImg.getAttributeNS(XLINK_NS, "href");
expect(imgUrl).toMatch(/^data:image\/png;base64,/);
// The size of our naively generated PNG file is excessive :(
expect(imgUrl.length).toBe(80246);
});
});
});

View File

@ -58,7 +58,6 @@ async function initializePDFJS(callback) {
"pdfjs-test/unit/crypto_spec.js", "pdfjs-test/unit/crypto_spec.js",
"pdfjs-test/unit/custom_spec.js", "pdfjs-test/unit/custom_spec.js",
"pdfjs-test/unit/default_appearance_spec.js", "pdfjs-test/unit/default_appearance_spec.js",
"pdfjs-test/unit/display_svg_spec.js",
"pdfjs-test/unit/display_utils_spec.js", "pdfjs-test/unit/display_utils_spec.js",
"pdfjs-test/unit/document_spec.js", "pdfjs-test/unit/document_spec.js",
"pdfjs-test/unit/editor_spec.js", "pdfjs-test/unit/editor_spec.js",

View File

@ -40,7 +40,6 @@ import {
getDocument, getDocument,
PDFDataRangeTransport, PDFDataRangeTransport,
PDFWorker, PDFWorker,
SVGGraphics,
version, version,
} from "../../src/display/api.js"; } from "../../src/display/api.js";
import { import {
@ -105,7 +104,6 @@ const expectedAPI = Object.freeze({
renderTextLayer, renderTextLayer,
setLayerDimensions, setLayerDimensions,
shadow, shadow,
SVGGraphics,
UnexpectedResponseException, UnexpectedResponseException,
updateTextLayer, updateTextLayer,
Util, Util,

View File

@ -22,7 +22,6 @@
"display-network": "../../src/display/network.js", "display-network": "../../src/display/network.js",
"display-node_stream": "../../src/display/stubs.js", "display-node_stream": "../../src/display/stubs.js",
"display-node_utils": "../../src/display/stubs.js", "display-node_utils": "../../src/display/stubs.js",
"display-svg": "../../src/display/stubs.js",
"web-alt_text_manager": "../../web/alt_text_manager.js", "web-alt_text_manager": "../../web/alt_text_manager.js",
"web-annotation_editor_params": "../../web/annotation_editor_params.js", "web-annotation_editor_params": "../../web/annotation_editor_params.js",

View File

@ -14,7 +14,6 @@
"display-network": ["./src/display/network"], "display-network": ["./src/display/network"],
"display-node_stream": ["./src/display/node_stream"], "display-node_stream": ["./src/display/node_stream"],
"display-node_utils": ["./src/display/node_utils"], "display-node_utils": ["./src/display/node_utils"],
"display-svg": ["./src/display/svg"],
"pdfjs-lib": ["./src/pdf"] "pdfjs-lib": ["./src/pdf"]
} }
}, },

View File

@ -51,7 +51,6 @@ const {
renderTextLayer, renderTextLayer,
setLayerDimensions, setLayerDimensions,
shadow, shadow,
SVGGraphics,
UnexpectedResponseException, UnexpectedResponseException,
updateTextLayer, updateTextLayer,
Util, Util,
@ -98,7 +97,6 @@ export {
renderTextLayer, renderTextLayer,
setLayerDimensions, setLayerDimensions,
shadow, shadow,
SVGGraphics,
UnexpectedResponseException, UnexpectedResponseException,
updateTextLayer, updateTextLayer,
Util, Util,

View File

@ -54,7 +54,6 @@ See https://github.com/adobe-type-tools/cmap-resources
"display-network": "../src/display/network.js", "display-network": "../src/display/network.js",
"display-node_stream": "../src/display/stubs.js", "display-node_stream": "../src/display/stubs.js",
"display-node_utils": "../src/display/stubs.js", "display-node_utils": "../src/display/stubs.js",
"display-svg": "../src/display/stubs.js",
"web-alt_text_manager": "./stubs-geckoview.js", "web-alt_text_manager": "./stubs-geckoview.js",
"web-annotation_editor_params": "./stubs-geckoview.js", "web-annotation_editor_params": "./stubs-geckoview.js",

View File

@ -65,7 +65,6 @@ See https://github.com/adobe-type-tools/cmap-resources
"display-network": "../src/display/network.js", "display-network": "../src/display/network.js",
"display-node_stream": "../src/display/stubs.js", "display-node_stream": "../src/display/stubs.js",
"display-node_utils": "../src/display/stubs.js", "display-node_utils": "../src/display/stubs.js",
"display-svg": "../src/display/stubs.js",
"web-alt_text_manager": "./alt_text_manager.js", "web-alt_text_manager": "./alt_text_manager.js",
"web-annotation_editor_params": "./annotation_editor_params.js", "web-annotation_editor_params": "./annotation_editor_params.js",