{"version":3,"sources":["../src/index.ts","../src/log.ts","../src/download.ts","../src/ocr.ts","../src/metrics.ts","../src/util.ts","../src/iiif.ts","../src/convert.ts","../src/pdf/generator.ts","../src/pdf/util.ts","../src/pdf/common.ts","../src/io.ts","../src/pdf/image.ts","../src/pdf/parser.ts","../src/version.ts","../src/pdf/pkzip.ts","../src/pdf/annos.ts","../src/res/licenses.ts"],"sourcesContent":["export type { Logger } from './log.js';\nexport { setLogger, ConsoleLogger } from './log.js';\nexport { fetchManifestJson } from './download.js';\nexport * from './convert.js';\nexport { default as version } from './version.js';","type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n  setLevel(level: LogLevel): void;\n  debug(message: string, ...args: any[]): void;\n  info(message: string, ...args: any[]): void;\n  warn(message: string, ...args: any[]): void;\n  error(message: string, ...args: any[]): void;\n}\n\n/** Simple logger that simply outputs to the console */\nexport class ConsoleLogger implements Logger {\n  private level: LogLevel;\n  constructor(level: LogLevel = 'warn') {\n    this.level = level;\n  }\n\n  setLevel(level: LogLevel): void {\n    this.level = level;\n  }\n\n  debug(message: string, ...args: any[]): void {\n    if (this.level === 'debug') {\n      console.debug(message, ...args);\n    }\n  }\n\n  info(message: string, ...args: any[]): void {\n    if (this.level !== 'error' && this.level !== 'warn') {\n      console.info(message, ...args);\n    }\n  }\n\n  warn(message: string, ...args: any[]): void {\n    if (this.level !== 'error') {\n      console.warn(message, ...args);\n    }\n  }\n\n  error(message: string, ...args: any[]): void {\n    console.error(message, ...args);\n  }\n}\n\nlet logger: Logger = new ConsoleLogger();\n\nexport function setLogger(newLogger: Logger): void {\n  logger = newLogger;\n}\n\nexport { logger as default };\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport { Mutex } from 'async-mutex';\nimport {\n  CanvasNormalized,\n  ExternalWebResource,\n  FragmentSelector,\n  IIIFExternalWebResource,\n  ImageService,\n  ImageService3,\n  ManifestNormalized,\n  RangeNormalized,\n  Reference,\n  Selector,\n  Service,\n} from '@iiif/presentation-3';\n\nimport { OcrPageWithMarkup, fetchAndParseText } from './ocr.js';\nimport metrics from './metrics.js';\nimport log from './log.js';\nimport {\n  vault,\n  isPhysicalDimensionService,\n  PhysicalDimensionService,\n  supportsScaling,\n  fetchFullImageService,\n  getCanvasAnnotations,\n  Annotation,\n  ImageInfo,\n} from './iiif.js';\nimport { isDefined } from './util.js';\n\n/// In absence of more detailed information (from physical dimensions service), use this resolution\nconst FALLBACK_PPI = 300;\n\n// HTTP Accept header to make sure we get IIIFv3, if available, via content negotiation\n// Thanks to @jcoyne:\n// https://github.com/ProjectMirador/mirador/pull/3770/files#diff-166256fe28a89c78ada7b08488a3233671fc0511fd39d323c5cfc9433026e2a1R108-R112\nconst MANIFEST_ACCEPT_HEADER = 'application/ld+json;q=0.9;profile=\"http://iiif.io/api/presentation/3/context.json\", '\n  + 'application/ld+json;q=0.7;profile=\"http://iiif.io/api/presentation/2/context.json\", '\n  + 'application/ld+json;q=0.5, '\n  + 'application/json;q=0.2';\n\n/** Maps rate-limited hosts to a mutex that limits the concurrent fetching. */\nclass RateLimitingRegistry {\n  private hostMutexes = new Map<string, Mutex>();\n  private callbacks: Array<(host: string, limited: boolean) => void> = [];\n\n  getMutex(host: string): Mutex | undefined {\n    return this.hostMutexes.get(host);\n  }\n\n  limitHost(host: string): Mutex {\n    const mutex = new Mutex();\n    this.hostMutexes.set(host, mutex);\n    this.callbacks.forEach((cb) => cb(host, true));\n    return mutex;\n  }\n\n  unlimitHost(host: string): void {\n    this.hostMutexes.delete(host);\n    this.callbacks.forEach((cb) => cb(host, false));\n  }\n\n  subscribe(cb: (host: string, limited: boolean) => void): number {\n    this.callbacks.push(cb);\n    return this.callbacks.length - 1;\n  }\n\n  unsubscribe(ticket: number) {\n    this.callbacks.splice(ticket, 1);\n  }\n\n  isLimited(url: string): boolean {\n    return this.hostMutexes.has(new URL(url).host);\n  }\n}\n\nexport const rateLimitRegistry = new RateLimitingRegistry();\n\n/** A 'respectful' wrapper around `fetch` that tries to respect rate-limiting headers.\n *\n * Will also retry with exponential backoff in case of server errors.\n */\nexport async function fetchRespectfully(\n  url: string,\n  init?: RequestInit,\n  maxRetries = 3\n): Promise<Response> {\n  const { host } = new URL(url);\n  // If the host associated with the URL is rate-limited, limit concurrency to a single\n  // fetch at a time by acquiring the mutex for the host.\n  let rateLimitMutex = rateLimitRegistry.getMutex(host);\n  let numRetries = -1;\n  let resp: Response | undefined;\n  let waitMs = 5000;\n  let lastError: unknown;\n  // If we're fetching from a rate-limited host, wait until there's no other fetch for it\n  // going on\n  const release = await rateLimitMutex?.acquire();\n  try {\n    do {\n      // Don't catch network errors, let them bubble up\n      resp = await fetch(url, init);\n      if (resp.ok) {\n        break;\n      }\n      numRetries++;\n\n      const retryAfter = resp?.headers.get('retry-after');\n      if (isDefined(retryAfter)) {\n        if (Number.isInteger(retryAfter)) {\n          waitMs = Number.parseInt(retryAfter, 10) * 1000;\n        } else {\n          const waitUntil = Date.parse(retryAfter);\n          waitMs = waitUntil - Date.now();\n        }\n      } else {\n        // Exponential backoff with a random multiplier on the base wait time\n        waitMs = Math.pow(Math.random() * 2 * waitMs, numRetries);\n      }\n\n      // Check if the server response has headers corresponding to the IETF `RateLimit Header Fiels for HTTP` spec draft[1]\n      // [1] https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-05.html\n      const getHeaderValue = (ietfHeader: string): number | undefined => {\n        const headerVariants = [\n          ietfHeader,\n          `x-${ietfHeader}`,\n          `x-${ietfHeader.replace('ratelimit', 'rate-limit')}`,\n        ];\n        return headerVariants\n          .map((header) => resp?.headers.get(header))\n          .filter(isDefined<string>)\n          .map((limit) => Number.parseInt(limit, 10))\n          .find((limit) => limit != null);\n      };\n      const limit = getHeaderValue('ratelimit-limit');\n      const remaining = getHeaderValue('ratelimit-remaining');\n      const reset = getHeaderValue('ratelimit-reset');\n      if (\n        limit !== undefined &&\n        remaining !== undefined &&\n        reset !== undefined\n      ) {\n        // At this point we're pretty sure that we're being rate-limited, so let's\n        // limit concurrency from here on out.\n        rateLimitMutex = rateLimitRegistry.limitHost(host);\n\n        // We assume a sliding window implemention here\n        const secsPerQuotaUnit = reset / (limit - remaining);\n        if (remaining > 0) {\n          // If we have remaining quota units but were blocked, we wait until we have enough\n          // quota to fetch remaining*2 quota units (i.e. we assume that the units in `remaining`\n          // were not enough to fully fetch the resource)\n          waitMs = 2 * remaining * secsPerQuotaUnit * 1000;\n        } else {\n          waitMs = secsPerQuotaUnit * 1000;\n        }\n      }\n\n      // Add a 100ms buffer just to be safe and wait until the next attempt\n      await new Promise((resolve) => setTimeout(resolve, waitMs + 100));\n    } while (numRetries < maxRetries);\n  } finally {\n    if (rateLimitMutex) {\n      // We're being rate-limited, so wait some more so the next request doesn't\n      // encounter a server error on fetching\n      await new Promise((resolve) => setTimeout(resolve, waitMs + 100));\n    }\n    release?.();\n  }\n  if (!resp) {\n    throw lastError;\n  }\n  return resp;\n}\n\n/** Container for image size along with its corresponding IIIF Image API string. */\nexport type SizeInfo = {\n  iiifSize: string;\n  width: number;\n  height: number;\n};\n\n/** Calculate the image size to fetch, based on user constraints and available sizes\n *  in the Image API info.json response.\n */\nexport function getImageSize(\n  imgService: ImageService,\n  scaleFactor = 1\n): SizeInfo {\n  let sizeStr: string;\n  const isIIIFv3 = (imgService as ImageService3).id !== undefined;\n  const maxWidth = imgService.maxWidth ?? imgService.width!;\n  let requestedWidth = Math.floor(scaleFactor * maxWidth);\n  const aspectRatio = imgService.width! / imgService.height!;\n  const supportsScaleByWh = Array.isArray(imgService.profile)\n    ? imgService.profile.find(supportsScaling) !== undefined\n    : supportsScaling(imgService.profile);\n  if (scaleFactor < 1 && !supportsScaleByWh) {\n    if (imgService.sizes) {\n      // AR-compliant downscaling is not supported, find the closest available size\n      requestedWidth = Math.min(...imgService.sizes.map((dims) => Math.abs(requestedWidth - dims.width)));\n      sizeStr = `${requestedWidth},`;\n    } else {\n      // No sizes available, so we can't downscale.\n      sizeStr = `${maxWidth},`;\n    }\n  } else if (scaleFactor == 1) {\n    sizeStr =\n      isIIIFv3 || imgService.maxWidth || imgService.maxArea ? 'max' : 'full';\n    if (imgService.maxWidth) {\n      requestedWidth = imgService.maxWidth;\n    } else if (imgService.maxHeight) {\n      requestedWidth = Math.round(aspectRatio * imgService.maxHeight);\n    } else if (imgService.maxArea) {\n      const fullArea = imgService.width! * imgService.height!;\n      const scaleFactor = imgService.maxArea / fullArea;\n      requestedWidth = Math.round(scaleFactor * imgService.width!);\n    } else {\n      requestedWidth = imgService.width!;\n    }\n  } else {\n    sizeStr = `${requestedWidth},`;\n  }\n  return {\n    iiifSize: sizeStr,\n    width: requestedWidth as number,\n    height: (requestedWidth as number) / aspectRatio,\n  };\n}\n\n/** Use a IIIF Physical Dimensions service to obtain the PPI for a canvas. */\nexport function getPointsPerInch(services: Service[]): number | null {\n  const physDimService = services.find(isPhysicalDimensionService) as\n    | PhysicalDimensionService\n    | undefined;\n  if (!physDimService) {\n    return null;\n  }\n  const { physicalScale, physicalUnits } = physDimService;\n  let ppi;\n  if (physicalUnits === 'in') {\n    ppi = 1 / physicalScale;\n  } else if (physicalUnits === 'mm') {\n    ppi = 25.4 / physicalScale;\n  } else if (physicalUnits === 'cm') {\n    ppi = 2.54 / physicalScale;\n  } else {\n    ppi = FALLBACK_PPI;\n  }\n  return ppi;\n}\n\nexport function isImageFetchFailure(obj: CanvasImageData | ImageFetchFailure): obj is ImageFetchFailure {\n  return (obj as ImageFetchFailure).cause !== undefined;\n}\n\n/** All the data relevant for the canvas: images and text */\nexport type CanvasData = {\n  canvas: Reference<'Canvas'>;\n  text?: OcrPageWithMarkup;\n  images: CanvasImage[];\n  annotations: Annotation[];\n  ppi?: number;\n  imageFailures: ImageFetchFailure[];\n};\n\nexport type ImageFetchFailure = ImageInfo & {\n  cause: Error | string;\n}\n\n\n/** Data and additional information for an image on a canvas. */\nexport type CanvasImage = ImageInfo & CanvasImageData;\n\n/** Data and additional info for a canvas image, based on retrieval\n *  of external resources.\n */\nexport type CanvasImageData = {\n  data?: ArrayBuffer;\n  numBytes: number;\n  corsAvailable: boolean;\n  ppi?: number;\n  nativeWidth?: number;\n  nativeHeight?: number;\n};\n\n/** Options for fetching image */\nexport type FetchImageOptions = {\n  /// Factor to downscale the image by, number between 0.1 and 1\n  scaleFactor?: number;\n  /// PPI override, will be fetched from physical dimensions serivce by default\n  ppiOverride?: number;\n  // Optional signal to use for aborting the image fetching\n  abortSignal?: AbortSignal;\n  /// Only obtain the size of the image, don't fetch any data\n  sizeOnly?: boolean;\n};\n\n/** Download (or only determine size in bytes of) a canvas image. */\nasync function fetchCanvasImage(\n  image: IIIFExternalWebResource | ExternalWebResource,\n  { scaleFactor, abortSignal, sizeOnly = false }: FetchImageOptions\n): Promise<CanvasImageData | null> {\n  // NOTE: Here be dragons, who'd have thought downloading an image\n  //       could be so complicated?\n  if (abortSignal?.aborted) {\n    log.debug(\n      'Abort signalled, aborting before initiating image data fetching.'\n    );\n    throw new Error('Aborted due to client request', { cause: { type: 'abort' } });\n  }\n  if (image.type !== 'Image') {\n    throw new Error(`Can only fetch image resources, got ${image.type}`);\n  }\n  let imgService: ImageService | undefined;\n  if ('service' in image) {\n    imgService = image.service?.find(\n      (s: Service): s is ImageService =>\n        ((s as ImageService | undefined)?.type?.startsWith('ImageService') ??\n          false) ||\n        ((s as any)?.['@type']?.startsWith('ImageService') ?? false)\n    );\n  }\n  let ppi: number | undefined;\n  let imageUrl: string;\n  if (imgService) {\n    if (!imgService.width) {\n      imgService = await fetchFullImageService(imgService);\n    }\n    const sizeInfo = getImageSize(imgService, scaleFactor);\n    imageUrl = `${imgService.id ?? imgService['@id']}/full/${sizeInfo.iiifSize\n      }/0/default.jpg`;\n    ppi = getPointsPerInch(imgService.service ?? []) ?? undefined;\n    if (ppi) {\n      ppi = ppi * (sizeInfo.width / imgService.width!);\n    }\n  } else if (image.id && image.format === 'image/jpeg') {\n    imageUrl = image.id;\n  } else {\n    log.error(\n      `No JPEG image identifier for resource ${image.id} could be found!`\n    );\n    return null;\n  }\n\n  let data: ArrayBuffer | undefined;\n  let numBytes: number;\n  let corsAvailable = true;\n  const stopMeasuring = metrics?.imageFetchDuration.startTimer({\n    iiif_host: new URL(imageUrl).host,\n  });\n  try {\n    const imgResp = await fetchRespectfully(imageUrl, {\n      method: 'GET',\n      signal: abortSignal,\n    });\n    if (imgResp.status >= 400) {\n      throw new Error(\n        `Failed to fetch page image from ${imageUrl}, server returned status ${imgResp.status}`,\n        { cause: { type: 'http-status', status: imgResp.status } }\n      );\n    }\n    if (abortSignal?.aborted) {\n      throw new Error('Aborted due to client request', { cause: { type: 'abort' } });\n    }\n    numBytes = Number.parseInt(imgResp.headers.get('Content-Length') ?? '-1');\n    data = sizeOnly && numBytes >= 0 ? undefined : await imgResp.arrayBuffer();\n    if (numBytes < 0) {\n      numBytes = data?.byteLength ?? -1;\n    }\n    stopMeasuring?.({\n      status: 'success',\n      limited: rateLimitRegistry.isLimited(imageUrl).toString(),\n    });\n  } catch (err) {\n    // In browsers, we can't differentiate between a 'normal' network error\n    // (like an unavailable server) and a CORS error just from the response\n    // alone, so we we use a small hack involving the DOM\n    const isCorsError = typeof document !== 'undefined' && await isImageUnavailableDueToCors(imageUrl);\n    // No CORS error or CORS error, but need data? Can't continue\n    if (!isCorsError) {\n      log.error(`Failed to fetch image data from ${imageUrl}: ${err}`);\n      stopMeasuring?.({\n        status: 'error',\n        limited: rateLimitRegistry.isLimited(imageUrl).toString(),\n        cause: err instanceof Error ? (err.cause as any).type : err\n      });\n      throw err;\n    } else if (!sizeOnly) {\n      throw new Error('Data requested, but no CORS for the image endpoint', { cause: { type: 'no-cors' } });\n    }\n    corsAvailable = false;\n    log.warn(\n      `Failed to fetch image data from ${imageUrl}: CORS headers missing!`\n    );\n    // We can get the size without CORS\n    const imgResp = await fetchRespectfully(imageUrl, {\n      method: 'GET',\n      signal: abortSignal,\n      mode: 'no-cors',\n    });\n    numBytes = Number.parseInt(imgResp.headers.get('Content-Length') ?? '-1');\n  }\n\n  return {\n    data,\n    ppi,\n    numBytes,\n    corsAvailable,\n  };\n}\n\n/** Check if an image is unavailable due to missing CORS headers. */\nasync function isImageUnavailableDueToCors(imageUrl: string): Promise<boolean> {\n  const imgElem = document.createElement('img');\n  imgElem.src = imageUrl;\n  return new Promise((resolve) => {\n    // Image loads fine for element => Unavailable due to missing CORS headers\n    imgElem.onload = () => resolve(true);\n    // Image also errors when loading via element => Server can't be reached\n    imgElem.onerror = () => resolve(false);\n  });\n}\n\n/** Information about the starting canvas of a Manifet or a Range.\n * Can point to a whole canvas or to a part of it. */\nexport type StartCanvasInfo =\n  | string\n  | {\n    id: string;\n    ppi: number;  // Needed to create link in PDF\n    dimensions: { width: number; height: number };\n    position: {\n      x: number;\n      y: number;\n      width: number;\n      height: number;\n    };\n  };\n\n/** Fetch all of the information needed for a start canvas. */\nexport async function fetchStartCanvasInfo(\n  resource: ManifestNormalized | RangeNormalized\n): Promise<StartCanvasInfo | undefined> {\n  const startRef = resource.start;\n  if (!startRef) {\n    return;\n  }\n  let canvasId: string | undefined;\n  let fragment: string | undefined;\n  if (typeof startRef === 'string') {\n    const [ident, selectorStr] = (startRef as string).split('#xywh=');\n    if (!selectorStr) {\n      return ident;\n    }\n    canvasId = ident;\n    fragment = `xywh=${selectorStr}`;\n  } else if (startRef.type === 'Canvas') {\n    return startRef.id;\n  } else {\n    const selector = vault.get<Selector>(startRef);\n    if (typeof selector === 'string' || selector.type !== 'FragmentSelector') {\n      console.warn(\n        `Unsupported selector type, cannot determine start canvas for ${resource.id}`\n      );\n      return;\n    }\n    const fragSel = selector as FragmentSelector;\n    if (fragSel.conformsTo !== 'http://www.w3.org/TR/media-frags/') {\n      console.warn(\n        `Unsupported selector type, cannot determine start canvas for ${resource.id} (fragment selector type was ${fragSel.conformsTo})`\n      );\n      return;\n    }\n    canvasId = fragSel.value;\n  }\n  if (!fragment || !canvasId) {\n    console.error(\n      `Couldn't parse either canvas identifier or selector for ${resource.id} start canvas.`\n    );\n    return;\n  }\n  const [selX, selY, selWidth, selHeight] = fragment\n    .substring(5)\n    .split(',')\n    .map((v) => Number.parseInt(v, 10));\n  const canvas = vault.get<CanvasNormalized>(canvasId);\n  const ppi = getPointsPerInch(canvas.service) ?? FALLBACK_PPI;\n  return {\n    id: canvasId,\n    ppi,\n    dimensions: { width: canvas.width, height: canvas.height },\n    position: {\n      x: selX,\n      y: selY,\n      width: selWidth,\n      height: selHeight,\n    },\n  };\n}\n\n/** Fetch all of the data associated with a canvas, including external services. */\nexport async function fetchCanvasData(\n  canvas: CanvasNormalized,\n  imageInfos: ImageInfo[],\n  { scaleFactor, ppiOverride, abortSignal, sizeOnly = false }: FetchImageOptions\n): Promise<CanvasData | undefined> {\n  const imagePromises = imageInfos.map(i => i.resource).map(r => fetchCanvasImage(r, { scaleFactor, abortSignal, sizeOnly }));\n  const results = await Promise.allSettled(imagePromises);\n  const canvasImages = results\n    .reduce((acc, x, idx) => {\n      if (x.status !== 'fulfilled' || x.value === null) {\n        return acc;\n      }\n      const imgInfo = imageInfos[idx];\n      acc.push({\n        ...imgInfo,\n        ...x.value,\n        // FIXME: How can we get rid of the cast?\n      } as CanvasImage);\n      return acc;\n    }, [] as CanvasImage[])\n  const failures: ImageFetchFailure[] = results\n    .filter((x): x is PromiseRejectedResult => x.status === 'rejected')\n    .map((x, idx) => {\n      const info = imageInfos[idx];\n      return {\n        ...info,\n        cause: x.reason,\n      }\n    });\n  const ppi = ppiOverride;\n  if (!ppiOverride) {\n    let ppi = getPointsPerInch(canvas.service) ?? undefined;\n    if (ppi && scaleFactor) {\n      ppi = ppi * scaleFactor;\n    }\n  }\n  let text;\n  if (!sizeOnly) {\n    try {\n      text = await fetchAndParseText(canvas, undefined);\n    } catch (err) {\n      log.warn(`Failed to fetch text for canvas ${canvas.id}: ${err}`);\n    }\n  }\n  return {\n    canvas,\n    images: canvasImages,\n    imageFailures: failures,\n    ppi,\n    text,\n    annotations: getCanvasAnnotations(canvas),\n  };\n}\n\n/** Download the JSON data for a manifest, handling stuff like broken CORS implementations\n *  and Content-Negotiation for IIIFv3 */\nexport async function fetchManifestJson(manifestUrl: string): Promise<any> {\n  try {\n    const resp = await fetch(manifestUrl, {\n      headers: {\n        Accept: MANIFEST_ACCEPT_HEADER\n      }\n    });\n    return await resp.json();\n  } catch (err) {\n    // Check if fetching failed due to CORS by downgrading the request to a\n    // 'simple' request by removing the `Accept` header, which makes the\n    // request CORS-unsafe due to double quotes and the colon in the URL\n    const resp = await fetch(manifestUrl);\n    return await resp.json();\n  }\n}","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable complexity */\n/// Utilities for parsing OCR text from hOCR, ALTO and IIIF Annotations\nimport {\n  Annotation,\n  AnnotationNormalized,\n  CanvasNormalized,\n  ContentResource,\n} from '@iiif/presentation-3';\nimport {\n  parseAltoPages,\n  parseHocrPages,\n  type OcrPage,\n  type OcrLine,\n  Dimensions,\n} from 'ocr-parser';\n\nimport metrics from './metrics.js';\nimport { fetchRespectfully, rateLimitRegistry } from './download.js';\nimport {\n  isExternalWebResourceWithProfile,\n  ExternalWebResourceWithProfile,\n  vault,\n} from './iiif.js';\n\nexport type OcrPageWithMarkup = OcrPage & {\n  id: string;\n  markup: string;\n  mimeType: string;\n};\n\n/** Helper to calculate a rough fallback image size from the line coordinates\n *\n * @param {array} lines the parsed OCR lines\n * @returns {object} the page size estimated from the line coordinates\n */\nfunction getFallbackImageSize(lines: OcrLine[]): Dimensions {\n  return {\n    width: Math.max(...lines.map(({ x, width }) => x + (width ?? 0))) ?? 0,\n    height: Math.max(...lines.map(({ y, height }) => y + height)) ?? 0,\n  };\n}\n\n/**\n * Parse an OCR document (currently hOCR or ALTO)\n *\n * @param {string} ocrText  ALTO or hOCR markup\n * @param {object} referenceSize Reference size to scale coordinates to\n * @returns {OcrPage} the parsed OCR page\n */\nexport async function parseOcr(\n  id: string,\n  ocrText: string,\n  referenceSize: Dimensions\n): Promise<OcrPageWithMarkup | null> {\n  let pageIter: AsyncGenerator<OcrPage>;\n  const isAlto = ocrText.indexOf('<alto') >= 0;\n  if (isAlto) {\n    pageIter = parseAltoPages(ocrText, [referenceSize]);\n  } else {\n    pageIter = parseHocrPages(ocrText, [referenceSize]);\n  }\n  const page = (await pageIter.next()).value as OcrPage | undefined;\n  if (!page) {\n    return null;\n  }\n  return {\n    ...page,\n    id,\n    markup: ocrText,\n    mimeType: isAlto ? 'application/xml+alto' : 'text/vnd.hocr+html',\n  };\n}\n\n/** Parse OCR data from IIIF annotations.\n *\n * Annotations should be pre-filtered so that they all refer to a single canvas/page.\n * Annotations should only contain a single text granularity, that is either line or word.\n *\n * @param {object} annos IIIF annotations with a plaintext body and line or word granularity\n * @param {Dimensions} imgSize Reference width and height of the rendered target image\n * @returns {OcrPage} parsed OCR boxes\n */\nexport function parseIiifAnnotations(\n  annos: Array<Annotation>,\n  imgSize: Dimensions\n): OcrPage {\n  throw 'Currently not supported';\n}\n\n/** Checks if a given resource points to an ALTO OCR document */\nconst isAlto = (resource: ExternalWebResourceWithProfile) =>\n  resource.format === 'application/xml+alto' ||\n  resource.profile?.startsWith('http://www.loc.gov/standards/alto/');\n\n/** Checks if a given resource points to an hOCR document */\nconst isHocr = (resource: ExternalWebResourceWithProfile) =>\n  resource.format === 'text/vnd.hocr+html' ||\n  resource.profile ===\n    'https://github.com/kba/hocr-spec/blob/master/hocr-spec.md' ||\n  resource.profile?.startsWith('http://kba.cloud/hocr-spec/') ||\n  resource.profile?.startsWith('http://kba.github.io/hocr-spec/');\n\n/** Wrapper around fetch() that returns the content as text */\nasync function fetchOcrMarkup(url: string): Promise<string | undefined> {\n  const resp = await fetch(url);\n  if (resp.status === 404) {\n    return undefined;\n  }\n  if (resp.status != 200) {\n    throw new Error(\n      `Could not fetch OCR markup from ${url}, got status code ${resp.status}`\n    );\n  }\n  return resp.text();\n}\n\n/** Fetch external annotation resource JSON */\nexport async function fetchAnnotationResource(url: string): Promise<any> {\n  const resp = await fetchRespectfully(url);\n  return resp.json();\n}\n\n/** Retrieve a supported OCR references from a Canvas' `seeAlso` or `rendering`, if present.\n *\n * 'Supported' currently means external ALTO or hOCR markup.\n */\nexport function getOcrReferences(\n  canvas: CanvasNormalized\n): ExternalWebResourceWithProfile | undefined {\n  const refs = vault.get<ContentResource>(canvas.seeAlso);\n  refs.push(...vault.get<ContentResource>(canvas.rendering));\n  return refs\n    .filter(isExternalWebResourceWithProfile)\n    .find((r) => isAlto(r) || isHocr(r));\n}\n\nexport async function fetchAndParseText(\n  canvas: CanvasNormalized,\n  annotations?: AnnotationNormalized[]\n): Promise<OcrPageWithMarkup | undefined> {\n  // TODO: Annotations are a major PITA due to all the indirection and multiple\n  //       levels of fetching of external resources that might be neccessary,\n  //       save for later once text rendering is properly done.\n  const ocrRefs = getOcrReferences(canvas);\n  if (ocrRefs) {\n    const stopMeasuring = metrics?.ocrFetchDuration.startTimer({\n      ocr_host: new URL(ocrRefs.id!).host,\n    });\n    let markup;\n    try {\n      markup = await fetchOcrMarkup(ocrRefs.id!);\n      stopMeasuring?.({\n        status: 'success',\n        limited: rateLimitRegistry.isLimited(ocrRefs.id!).toString(),\n      });\n      if (!markup) {\n        return undefined;\n      }\n    } catch (err) {\n      stopMeasuring?.({\n        status: 'error',\n        limited: rateLimitRegistry.isLimited(ocrRefs.id!).toString(),\n      });\n      throw err;\n    }\n    return (\n      (await parseOcr(ocrRefs.id!, markup, {\n        width: canvas.width,\n        height: canvas.height,\n      })) ?? undefined\n    );\n  }\n}\n","import type { Histogram } from 'prom-client';\nimport prometheus from 'prom-client';\n\nimport { runningInNode } from './util.js';\n\ntype Metrics =\n  | {\n      pageGenerationDuration: Histogram<string>;\n      imageFetchDuration: Histogram<string>;\n      imageInfoDuration: Histogram<string>;\n      ocrFetchDuration: Histogram<string>;\n    }\n  | undefined;\n\nlet metrics: Metrics;\n\n// Prometheus metrics are only defined when running in node\nif (runningInNode()) {\n  metrics = {\n    pageGenerationDuration: new prometheus.Histogram({\n      name: 'pdiiif_page_generation_duration_seconds',\n      help: 'Latency for generating the PDF for a single page',\n      buckets: [0.001, 0.005, 0.015, 0.05, 0.1, 0.5, 1, 2],\n      labelNames: ['status'],\n    }),\n    imageFetchDuration: new prometheus.Histogram({\n      name: 'pdiiif_image_fetch_duration_seconds',\n      help: 'Latency for fetching data from IIIF Image API endpoints',\n      buckets: [0.01, 0.05, 0.15, 0.5, 1, 5, 10],\n      labelNames: ['status', 'iiif_host', 'limited'],\n    }),\n    imageInfoDuration: new prometheus.Histogram({\n      name: 'pdiiif_image_info_duration_seconds',\n      help: 'Latency for fetching info from IIIF Image API endpoints',\n      buckets: [0.01, 0.05, 0.15, 0.5, 1, 5, 10],\n      labelNames: ['status', 'iiif_host', 'limited'],\n    }),\n    ocrFetchDuration: new prometheus.Histogram({\n      name: 'pdiiif_ocr_fetch_duration_seconds',\n      help: 'Latency for fetching OCR data',\n      buckets: [0.01, 0.05, 0.15, 0.5, 1, 5, 10],\n      labelNames: ['status', 'ocr_host', 'limited'],\n    }),\n  };\n}\n\nexport default metrics;\n","export let saxParserWasm: Uint8Array | null = null;\n\n/** Get a timestamp in milliseconds, prefereably high-resolution */\nexport function now(): number {\n  if (typeof window !== 'undefined' && window.performance) {\n    return window.performance.now();\n  } else {\n    return Date.now();\n  }\n}\n\nexport function isDefined<T>(val: T | undefined | null | void): val is T {\n  return val != undefined && val !== null && val !== void 0;\n}\n\nconst CRC_TABLE = (() => {\n  const t = new Int32Array(256);\n  for (let i = 0; i < 256; ++i) {\n    let c = i, k = 9;\n    while (--k) c = ((c & 1) && -306674912) ^ (c >>> 1);\n    t[i] = c;\n  }\n  return t;\n})();\n\nexport function crc32(data: Uint8Array): number {\n  let c = -1;\n  for (let i = 0; i < data.length; ++i) {\n    c = CRC_TABLE[(c & 255) ^ data[i]] ^ (c >>> 8);\n  }\n  return ~c;\n}\n\nexport function runningInNode(): boolean {\n  return typeof process !== 'undefined' && typeof process.versions?.node !== 'undefined';\n}\n\nexport function initializeSaxParser(parserWasm: Uint8Array): void {\n  saxParserWasm = parserWasm;\n}","import {\n  InternationalString,\n  ManifestNormalized,\n  ExternalWebResource,\n  IIIFExternalWebResource,\n  ContentResource,\n  ImageProfile,\n  ImageService,\n  CanvasNormalized,\n  Reference,\n  AnnotationPageNormalized,\n  AnnotationNormalized,\n  Creator,\n  Agent,\n} from '@iiif/presentation-3';\nimport { globalVault, Vault } from '@iiif/vault';\nimport {\n  buildLocaleString,\n  createPaintingAnnotationsHelper,\n  createThumbnailHelper,\n  expandTarget,\n  SupportedTarget,\n} from '@iiif/vault-helpers';\nimport { ImageServiceLoader as ImageServiceLoader_ } from '@atlas-viewer/iiif-image-api';\n\nimport { getOcrReferences } from './ocr.js';\nimport log from './log.js';\n\nconst PURPOSE_ORDER = ['commenting', 'describing', 'tagging', 'no-purpose'];\nconst PURPOSE_LABELS: { [purpose: string]: string } = {\n  commenting: 'Comment',\n  describing: 'Description',\n  tagging: 'Tags',\n};\n\nexport const vault = globalVault() as Vault;\n\n/** Given a language preference in descending order,\n * determine the best set of strings from the\n * internationalized string.\n */\nexport function getI18nValue(\n  val: string | InternationalString,\n  languagePreference: readonly string[]\n): string[];\nexport function getI18nValue(\n  val: string | InternationalString,\n  languagePreference: readonly string[],\n  separator: string\n): string;\nexport function getI18nValue(\n  val: string | InternationalString,\n  languagePreference: readonly string[],\n  separator?: string\n): string | string[] {\n  let splitAfter = false;\n  if (!separator) {\n    separator = '<<<SNIP>>>';\n    splitAfter = true;\n  }\n  const localized = buildLocaleString(val, languagePreference[0] ?? 'none', {\n    defaultText: '',\n    fallbackLanguages: languagePreference.slice(1),\n    separator,\n  });\n  if (splitAfter) {\n    return localized.split(separator).filter((s) => s.length > 0);\n  } else {\n    return localized;\n  }\n}\n\n\n/** Custom image loader to deal with browser + node intercompatibility.\n *\n * Used for the thumbnail helper.\n */\nclass ImageServiceLoader extends ImageServiceLoader_ {\n  async fetch(input: RequestInfo, init?: RequestInit): Promise<Response> {\n    return fetch(input as any, init as any) as any;\n  }\n}\n\nconst thumbHelper = createThumbnailHelper(vault, {\n  imageServiceLoader: new ImageServiceLoader(),\n});\n\n// A few helpers to deal with painting annotations\nexport const {\n  getPaintables,\n  getAllPaintingAnnotations,\n  extractChoices\n} = createPaintingAnnotationsHelper(vault);\n\n/** Determine best thumbnail image for the manifest. */\nexport async function getThumbnail(\n  manifest: ManifestNormalized,\n  maxDimension: number\n): Promise<string | undefined> {\n  const thumb = await thumbHelper.getBestThumbnailAtSize(manifest, {\n    maxWidth: maxDimension,\n    maxHeight: maxDimension,\n  });\n  return thumb.best?.id;\n}\n\n/** Like a regular external web resource, but with an associated\n profile URI, needed for OCR discovery */\nexport interface ExternalWebResourceWithProfile extends ExternalWebResource {\n  profile: string;\n}\n\n/** Check if a resource is an external resource with an\n * associated profile. */\nexport function isExternalWebResourceWithProfile(\n  res: ContentResource\n): res is ExternalWebResourceWithProfile {\n  return (\n    res.type !== undefined &&\n    ['Dataset', 'Image', 'Video', 'Sound', 'Text', 'unknown'].indexOf(\n      res.type\n    ) >= 0 &&\n    (res as ExternalWebResourceWithProfile).profile !== undefined\n  );\n}\n\n/** See https://iiif.io/api/annex/services/#physical-dimensions */\nexport interface PhysicalDimensionService {\n  '@context': 'http://iiif.io/api/annex/services/physdim/1/context.json';\n  profile: 'http://iiif.io/api/annex/services/physdim';\n  '@id': string;\n  physicalScale: number;\n  physicalUnits: 'in' | 'cm' | 'mm';\n}\n\n/** Check if a service is a IIIF Physical Dimensions service */\nexport function isPhysicalDimensionService(\n  service: any // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n): service is PhysicalDimensionService {\n  return (\n    typeof service.profile === 'string' &&\n    service.profile === 'http://iiif.io/api/annex/services/physdim'\n  );\n}\n\n\n/** Check if a IIIF Image endpoint supports arbitrary downscaling. */\nexport function supportsScaling(profile: ImageProfile): boolean {\n  if (typeof profile === 'string') {\n    return profile.indexOf('level2') >= 0;\n  } else {\n    return (profile.supports?.indexOf('sizeByWh') ?? -1) >= 0;\n  }\n}\n\n/** Fetch the full IIIF Image service definition from\n * its info.json endpoint. */\nexport async function fetchFullImageService(\n  serviceRef: ImageService\n): Promise<ImageService> {\n  const serviceUrl = `${serviceRef['@id'] ?? serviceRef.id}/info.json`;\n  const resp = await fetch(serviceUrl);\n  const res = await resp.json();\n  return res as ImageService;\n}\n\nexport type ImageInfo = {\n  // The 'Image' content resource\n  resource: (ExternalWebResource | IIIFExternalWebResource) & { type: 'Image' };\n  // Where to draw on the corresponding canvas\n  x: number;\n  y: number\n  // At what size to draw on the canvas?\n  width: number;\n  height: number;\n  // What is the image's size, if available?\n  nativeWidth?: number;\n  nativeHeight?: number;\n  ppi?: number;\n  choiceInfo?: {\n    enabled: boolean;\n    optional: boolean;\n    visibleByDefault: boolean;\n    label?: InternationalString;\n  }\n}\n\n/** Information about a canvas that can be obtained without\n *  fetching any external resources */\nexport type CanvasInfo = {\n  canvas: Reference<'Canvas'>;\n  ocr?: {\n    id: string;\n  };\n  images: ImageInfo[];\n  numAnnotations: number;\n};\n\n/** Extract all non-painting annotations that are of interest for PDF generation\n * from a canvas */\nexport function getCanvasAnnotations(canvas: CanvasNormalized): Annotation[] {\n  return vault\n    .get<AnnotationPageNormalized>(canvas.annotations)\n    .flatMap((p) => vault.get<AnnotationNormalized>(p.items))\n    .filter((a) =>\n      Array.isArray(a.motivation)\n        ? a.motivation.find((m) => PURPOSE_LABELS[m] !== undefined) !==\n        undefined\n        : PURPOSE_LABELS[a.motivation ?? 'invalid'] !== undefined\n    )\n    .map((a) => parseAnnotation(a, []))\n    .filter((a): a is Annotation => a !== undefined);\n}\n\n/** Obtain all information about a canvas and its images\n * without hitting any external endpoints.\n */\nexport function getCanvasInfo(canvas: CanvasNormalized): CanvasInfo {\n  const imageInfos = getImageInfos(canvas);\n  const text = getOcrReferences(canvas);\n  return {\n    canvas: { id: canvas.id, type: 'Canvas' },\n    images: imageInfos,\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    ocr: text ? { id: text.id! } : undefined,\n    numAnnotations: getCanvasAnnotations(canvas).length,\n  };\n}\n\n/** A annotation prepared for rendering to PDF. */\nexport interface Annotation {\n  id: string;\n  target: SupportedTarget;\n  markup: string;\n  lastModified?: Date;\n  author?: string;\n}\n\n/** Format an annotation agent to a human readable string. */\nfunction agentToString(agent: Agent): string {\n  let name = Array.isArray(agent.name) ? agent.name.join('; ') : agent.name;\n  if (!name) {\n    name = agent.nickname ?? 'unknown';\n  }\n  if (agent.email) {\n    return `${name} <${agent.email}>`;\n  }\n  return name;\n}\n\n/** Format a annotation creator definition to a human readable\n * string. */\nfunction creatorToString(creator: Creator): string {\n  if (Array.isArray(creator)) {\n    if (typeof creator[0] === 'string') {\n      return creator.join('; ');\n    } else {\n      return creator.map((a) => agentToString(a as Agent)).join('; ');\n    }\n  }\n  if (typeof creator === 'string') {\n    return creator;\n  }\n  return agentToString(creator);\n}\n\n/** Parse a IIIF annotation into a format that is more\n *  suitable for rendering to a PDF. */\nexport function parseAnnotation(\n  anno: AnnotationNormalized,\n  langPrefs: readonly string[]\n): Annotation | undefined {\n  if (!anno.target) {\n    return;\n  }\n  // TODO: i18n?\n  const annoBody = anno.body.map((bodyRef) =>\n    vault.get<ContentResource>(bodyRef)\n  );\n  const creatorNames: Array<string> = annoBody\n    .map((body) => body.creator)\n    .filter((v: Creator | undefined): v is Creator => v !== undefined)\n    .map(creatorToString);\n  const modifiedDates: Array<number> = annoBody\n    .map((body) => body.modified)\n    .filter((v: string | undefined): v is string => v !== undefined)\n    .map((v: string) => new Date(v).getTime());\n  const target = expandTarget(anno.target);\n  const markup = buildAnnotationMarkup(annoBody);\n  if (!markup) {\n    // TODO: Log?\n    throw `No valid textual content in annotation.`;\n  }\n  return {\n    id: anno.id,\n    target,\n    markup,\n    lastModified:\n      modifiedDates.length > 0\n        ? new Date(Math.max(...modifiedDates))\n        : undefined,\n    author: creatorNames.length > 0 ? creatorNames.join('; ') : undefined,\n  };\n}\n\n/** Convert Annotation HTML to PDF Markup */\nfunction buildAnnotationMarkup(\n  bodies: Array<ContentResource>\n): string | undefined {\n  const parts: { [purpose: string]: Array<string> } = {};\n  for (const body of bodies) {\n    if (\n      body.type !== 'TextualBody' ||\n      (body.format !== 'text/plain' && body.format !== 'text/html') ||\n      body.value === undefined\n    ) {\n      continue;\n    }\n    let { purpose } = body;\n    if (Array.isArray(purpose)) {\n      purpose = purpose[0];\n    } else if (!purpose) {\n      purpose = 'no-purpose';\n    }\n    if (!parts[purpose]) {\n      parts[purpose] = [];\n    }\n    parts[purpose].push(body.value);\n  }\n  if (Object.keys(parts).length === 0) {\n    return undefined;\n  }\n  const out: Array<string> = [];\n  for (const purpose of PURPOSE_ORDER) {\n    const purposeLabel = PURPOSE_LABELS[purpose];\n    if (!parts[purpose]) {\n      continue;\n    }\n    if (parts[purpose].length > 1) {\n      if (purposeLabel) {\n        out.push(`<p><b>${purposeLabel}:</b></p>`);\n      }\n      for (const part of parts[purpose]) {\n        // TODO: Convert HTML to PDF rich text\n        out.push(`<p>${part}</p>`);\n      }\n    } else {\n      out.push('<p>');\n      if (purposeLabel) {\n        out.push(`<b>${purposeLabel}:</b> `);\n      }\n      out.push(`${parts[purpose][0]}</p>`);\n    }\n  }\n  if (out.length === 0) {\n    return undefined;\n  }\n  return out.join('\\n');\n}\n\nexport interface CompatibilityReport {\n  compatibility: 'compatible' | 'incompatible' | 'degraded';\n  incompatibleElements: {\n    [canvasId: string]: Set<\n      | 'no-jpeg' // At least one image doesn't have a JPEG representation\n      | 'no-image' // Canvas does not have a single image annotation\n      | 'annotations' // Canvas has non-painting annotations\n      | 'unsupported-painting'\n    >;\n  };\n}\n\nexport function checkCompatibility(\n  manifest: ManifestNormalized\n): CompatibilityReport | undefined {\n  const report = {\n    compatibility: 'compatible',\n    incompatibleElements: {},\n  };\n  for (const canvas of vault.get<CanvasNormalized>(manifest.items)) {\n    const paintingResources = vault\n      .get<AnnotationPageNormalized>(canvas.items)\n      .flatMap((ap) => vault.get<AnnotationNormalized>(ap.items))\n      .flatMap((a) => vault.get<ContentResource>(a.body));\n    const nonPaintingAnnos = manifest.annotations;\n    // TODO: Check if canvas has an image\n    // TODO: Check if every painting annotation is an image with a JPEG available\n    // TODO: Check for the presence of non-painting annotations\n  }\n  return undefined;\n}\n\n/** Parse a IIIF target specification */\nexport function parseTarget(targetStr: string): { x: number; y: number, width: number, height: number } {\n  const [canvasId, fragment] = targetStr.split('#xywh=');\n  if (fragment) {\n    const [x, y, width, height] = fragment\n      .split(',')\n      .map((x) => parseInt(x, 10));\n    return { x, y, width, height };\n  } else {\n    const canvas = vault.get<CanvasNormalized>(canvasId);\n    // Draw to fit canvas\n    return { x: 0, y: 0, width: canvas.width, height: canvas.height };\n  }\n}\n\n/** Get information about images on a Canvas. */\nexport function getImageInfos(canvas: CanvasNormalized): ImageInfo[] {\n  const imageInfos: ImageInfo[] = [];\n  const paintingAnnos = getAllPaintingAnnotations(canvas);\n  for (const anno of paintingAnnos) {\n    if (typeof anno.target !== 'string') {\n      log.error(`Annotation ${anno.id} has a non-string target, currently not supported.`);\n      continue;\n    }\n    const target = parseTarget(anno.target);\n\n    const body = vault.get<ContentResource>(anno.body);\n    for (const resource of body) {\n      if (resource.type !== 'Image') {\n        continue;\n      }\n      imageInfos.push({\n        resource: resource as (ExternalWebResource | IIIFExternalWebResource) & { type: 'Image' },\n        ...target,\n        nativeWidth: (resource as any).width as number | undefined,\n        nativeHeight: (resource as any).height as number | undefined,\n      });\n    }\n  }\n\n  const choice = extractChoices(paintingAnnos);\n  if (choice?.type !== 'single-choice') {\n    // Return early if there are no choices available\n    return imageInfos;\n  }\n\n  for (const choiceItem of choice.items) {\n    const resource = vault.get<ContentResource>(choiceItem.id);\n    if (resource.type !== 'Image') {\n      continue;\n    }\n    imageInfos.push({\n      resource: resource as (ExternalWebResource | IIIFExternalWebResource) & { type: 'Image' },\n      // FIXME: Can't choice images have a location and rendering dimensions?\n      x: 0,\n      y: 0,\n      width: canvas.width,\n      height: canvas.height,\n      nativeWidth: (resource as any).width as number | undefined,\n      nativeHeight: (resource as any).height as number | undefined,\n      choiceInfo: {\n        enabled: choiceItem.selected ?? false,\n        optional: true,\n        label: (resource as any).label,\n        visibleByDefault: choiceItem.selected ?? false,\n      }\n    });\n  }\n\n  return imageInfos;\n}","/// <reference types=\"wicg-file-system-access\"/>\nimport type { Writable } from 'stream';\nimport {\n  Manifest,\n  RangeItems,\n  ManifestNormalized,\n  CanvasNormalized,\n  RangeNormalized,\n  Reference,\n  IIIFExternalWebResource,\n  ContentResource,\n  Service,\n  ImageService,\n  AnnotationNormalized,\n  ResourceProviderNormalized,\n  Annotation as IIIF3Annotation,\n} from '@iiif/presentation-3';\nimport Presentation2 from '@iiif/presentation-2';\nimport { convertPresentation2 } from '@iiif/parser/presentation-2';\nimport PQueue from 'p-queue';\nimport events from 'events';\nimport * as ocrParser from 'ocr-parser';\n\nimport PDFGenerator from './pdf/generator.js';\nimport {\n  CountingWriter,\n  WebWriter,\n  NodeWriter,\n  Writer,\n  BlobWriter,\n} from './io.js';\nimport { TocItem } from './pdf/util.js';\nimport { getLicenseInfo } from './res/licenses.js';\nimport { getOcrReferences } from './ocr.js';\nimport pdiiifVersion from './version.js';\nimport {\n  fetchCanvasData,\n  fetchRespectfully,\n  CanvasData,\n  fetchStartCanvasInfo,\n  StartCanvasInfo,\n  fetchManifestJson,\n} from './download.js';\nimport metrics from './metrics.js';\nimport { initializeSaxParser, isDefined, now, saxParserWasm } from './util.js';\nimport log from './log.js';\nimport {\n  getI18nValue,\n  getThumbnail,\n  getCanvasInfo,\n  vault,\n  parseAnnotation,\n  Annotation,\n} from './iiif.js';\n\n/** Progress information for rendering a progress bar or similar UI elements. */\nexport interface ProgressStatus {\n  /** Message code that should be mapped to a human readable description in a UI. */\n  messageCode?: ProgressMessageCode;\n  /** Expected total number of pages in the PDF */\n  totalPages: number;\n  /** Number of pages that were submitted for writing */\n  pagesWritten: number;\n  /** Number of bytes that were submitted for writing to the output stream */\n  bytesPushed: number;\n  /** Number of bytes that were written to the output stream so far */\n  bytesWritten: number;\n  /** Predicted size of the final file in bytes */\n  estimatedFileSize?: number;\n  /** Write speed in bytes per second */\n  writeSpeed: number;\n  /** Estimated time in seconds until PDF has finished generating */\n  remainingDuration: number;\n}\n\n/** Parameters for rendering a cover page, parsed from IIIF manifest. */\nexport interface CoverPageParams {\n  title: string;\n  manifestUrl: string;\n  thumbnail?: {\n    url: string;\n    iiifImageService?: string;\n  };\n  provider?: {\n    label: string;\n    homepage?: string;\n    logo?: string;\n  };\n  requiredStatement?: {\n    label: string;\n    value: string;\n  };\n  rights?: {\n    text: string;\n    url?: string;\n    logo?: string;\n  };\n  metadata?: Array<[string, string | Array<string>]>;\n  pdiiifVersion: string;\n}\n\n/** Options for converting a IIIF Manifest to a PDF. */\nexport interface ConvertOptions {\n  /** Callback to provide annotations for a given canvas identifier.\n   * Should return either a `sc:AnnotationList` (IIIF2) or an `AnnotationPage` (IIIF3).\n   */\n  fetchCanvasAnnotations?: (\n    canvasId: string\n  ) => Promise<Array<IIIF3Annotation> | Array<Presentation2.Annotation>>;\n  /** Pixels per inch to assume for the full resolution version of each canvas.\n      If not set, the conversion will use an available IIIF Physical Dimensions\n      service to calculate the page dimensions instead. */\n  ppi?: number;\n  /** Set of canvas ids to include in PDF, or a predicate to filter canvas identifiers\n      by. By default, all canvases are included in the PDF. */\n  filterCanvases?: readonly string[] | ((canvasId: string) => boolean);\n  /** List of languages to use for metadata, page labels and table of contents, in\n      descending order of preference. Will use the environment's locale settings by\n      default. */\n  languagePreference?: readonly string[];\n  /** Restrict the image size to include in the PDF by downscaling by a fixed factor.\n   * The value must be a number between 0.1 and 1.\n   * Only works with Level 2 Image API services that allow arbitrary downscaling, the\n   * conversion will not perform downscaling itself.\n   * For Level 1 endpoints, the closest available lower width will be selected. */\n  scaleFactor?: number;\n  /** Number of maximum concurrent IIIF Image API requests to be performed, defaults to 1 */\n  concurrency?: number;\n  /** Callback that gets called whenever a page has finished, useful to render a\n      progress bar. */\n  onProgress?: (status: ProgressStatus) => void;\n  /** Callback that gets called with a notification when an error occurs during PDF generation\n   *  that does not cause the conversion to fail. */\n  onNotification?: (notification: ProgressNotification) => void;\n  /** Controller that allows aborting the PDF generation. All pending\n      downloads will be terminated. The caller is responsible for\n      removing underlying partial files and/or other user signaling. */\n  abortController?: AbortController;\n  /** Set PDF metadata, by default `Title` will be the manifest's label. */\n  metadata?: {\n    CreationDate?: Date;\n    Title?: string;\n    Author?: string;\n    Keywords?: string;\n  };\n  /** Endpoint to contact for retrieving PDF data with one or more cover pages\n      to insert before the canvas pages */\n  coverPageEndpoint?: string;\n  /** Callback to call for retrieving PDF data with one or more cover pages\n      to insert before the canvas pages */\n  coverPageCallback?: (params: CoverPageParams) => Promise<Uint8Array>;\n  /** Generate the PDF in a way that the resulting file is also a valid\n   *  ZIP file that contains the manifest, all of the images and, if present,\n   *  the OCR files referenced in the manifest. */\n  polyglotZipPdf?: boolean;\n  /** Base directory in the polyglot ZIP archive. If not set, all resource\n   * directories will be to-level in the archive. */\n  polyglotZipBaseDir?: string;\n  /** Custom loader callback that fetches the WASM binary for the `sax-wasm`\n   *  dependency (v2.2.4). By default, the dependency will be loaded from\n   *  `https://unpkg.com/sax-wasm/dist/sax-wasm.wasm`. Override if you want\n   *  to provide your own payload. Loader will not be called if {@link initialize}\n   *  from `ocr-parser` has been called before.\n   */\n  saxWasmLoader?: () => Promise<Uint8Array>;\n}\n\n/** Parameters for size estimation */\nexport interface EstimationParams {\n  /** The manifest to determine the PDF size for */\n  manifest: string | Manifest | Presentation2.Manifest;\n  /** Restrict the image size to include in the PDF by downscaling by a fixed factor.\n   * The value must be a number between 0.1 and 1.\n   * Only works with Level 2 Image API services that allow arbitrary downscaling, the\n   * conversion will not perform downscaling itself.\n   * For Level 1 endpoints, the closest available lower width will be selected. */\n  scaleFactor?: number;\n  /** Set of canvas ids to include in PDF, or a predicate to filter canvas identifiers\n      by. By default, all canvases are included in the PDF. */\n  filterCanvases?: readonly string[] | ((canvasId: string) => boolean);\n  /** Number of canvses to sample for estimation, defaults to 8 */\n  numSamples?: number;\n  /** Number of maximum concurrent IIIF Image API requests to be performed, defaults to 1 */\n  concurrency?: number;\n}\n\nexport type Estimation = {\n  /** Estimated size of the PDF in bytes */\n  size: number;\n  /** If CORS is enabled for all of the images referenced in the sample canvases */\n  corsSupported: boolean;\n\n}\n\nfunction getCanvasesForSampling(canvases: CanvasNormalized[], numSamples: number): CanvasNormalized[] {\n  if (canvases.length <= numSamples) {\n    return canvases;\n  }\n  const meanPixels = canvases.reduce(\n    (x, { width, height }) => x + width * height, 0) / canvases.length;\n  const candidateCanvases = canvases.filter(\n    (c) => Math.abs(meanPixels - c.width * c.height) <= 0.25 * meanPixels\n  );\n  if (candidateCanvases.length <= numSamples) {\n    return candidateCanvases;\n  }\n  const sampleCanvases: CanvasNormalized[] = []\n  while (sampleCanvases.length < numSamples) {\n    const candidate = candidateCanvases[Math.floor(Math.random() * candidateCanvases.length)]\n    if (sampleCanvases.indexOf(candidate) < 0) {\n      sampleCanvases.push(candidate)\n    }\n  }\n  return sampleCanvases;\n}\n\n/** Estimate the final size of the PDF for a given manifest.\n *\n * This will randomly sample a few representative canvases from the manifest,\n * check their size in bytes and extrapolate from that to all canvases.\n *\n * @throws {Error} if the manifest cannot be loaded\n */\nexport async function estimatePdfSize({\n  manifest: inputManifest,\n  concurrency = 1,\n  scaleFactor,\n  filterCanvases = () => true,\n  numSamples = 8,\n}: EstimationParams): Promise<Estimation> {\n  let manifestId;\n  if (typeof inputManifest === 'string') {\n    manifestId = inputManifest;\n  } else {\n    manifestId =\n      (inputManifest as Manifest).id ??\n      (inputManifest as Presentation2.Manifest)['@id'];\n  }\n  const manifestJson = await fetchManifestJson(manifestId);\n  const manifest = await vault.loadManifest(manifestId, manifestJson);\n  if (!manifest) {\n    throw new Error(`Failed to load manifest from ${manifestId}`);\n  }\n  let canvasPredicate: (canvasId: string) => boolean;\n  if (Array.isArray(filterCanvases)) {\n    canvasPredicate = (canvasId) => filterCanvases.indexOf(canvasId) >= 0;\n  } else {\n    canvasPredicate = filterCanvases as (id: string) => boolean;\n  }\n\n  const canvases = vault.get<CanvasNormalized>(\n    manifest.items.filter((c) => canvasPredicate(c.id))\n  );\n\n  // Select some representative canvases that are close to the mean in terms\n  // of their pixel area to avoid small images distorting the estimate too much\n  const totalCanvasPixels = canvases.reduce(\n    (sum, canvas) => sum + canvas.width * canvas.height,\n    0\n  );\n  const sampleCanvases = getCanvasesForSampling(canvases, numSamples);\n  const samplePixels = sampleCanvases.reduce(\n    (sum, canvas) => sum + canvas.width * canvas.height,\n    0\n  );\n  const queue = new PQueue({ concurrency });\n  const canvasData = await Promise.all(\n    sampleCanvases.map((c) =>\n      queue.add(async () => {\n        const info = getCanvasInfo(c);\n        return fetchCanvasData(c, info.images, { scaleFactor, sizeOnly: true });\n      })\n    )\n  );\n  const corsSupported = canvasData\n    .filter(isDefined<CanvasData>)\n    .flatMap((c) => c.images)\n    .every(i => i.corsAvailable);\n  const sampleBytes = canvasData\n    .filter(isDefined<CanvasData>)\n    .flatMap((c) => c.images)\n    .reduce((size: number, data) => size + (data?.numBytes ?? 0), 0);\n  const bpp = sampleBytes / samplePixels;\n  return {\n    size: bpp * totalCanvasPixels,\n    corsSupported,\n  };\n}\n\nasync function buildOutlineFromRanges(\n  manifest: ManifestNormalized,\n  canvases: CanvasNormalized[],\n  languagePreference: string[]\n): Promise<Array<TocItem>> {\n  // ToC generation: IIIF's `Range` construct is so open, doing anything useful with it is a pain :-/\n  // In our case, the pain comes from multiple directions:\n  // - PDFs can only connect an outline node to a *single* page (IIIF connects ranges of pages)\n  // - IIIF doesn't prescribe an order for the ranges or the canvases contained in them\n  // Our approach is to pre-generate the range associated with each canvas and a hierarchy\n  // of parent-child relationships for ranges.\n\n  // All canvas identifiers in the order they appear as in the sequence\n  // Note that this is a *filtered* list of canvases, i.e. if the user only selected a subset of the\n  // canvases for PDF generation, not every Range in the manifest will have all of its canvases in here\n  const canvasIds = canvases.map((canvas) => canvas.id);\n\n  // We have to recurse, this small closure handles each node in the tree\n  const isCanvas = (ri: RangeItems): ri is Reference<'Canvas'> =>\n    typeof ri !== 'string' && ri.type === 'Canvas';\n  const isRange = (ri: RangeItems): ri is Reference<'Range'> =>\n    typeof ri !== 'string' && ri.type == 'Range';\n\n  const seenRanges: Set<string> = new Set();\n  const handleTocRange = async (\n    range: RangeNormalized\n  ): Promise<TocItem | undefined> => {\n    if (seenRanges.has(range.id)) {\n      return;\n    }\n    // Double filtering with `isCanvas` is necessary because of TS limitations\n    const firstCanvas = range.items\n      .filter(isCanvas)\n      .filter(c => canvasIds.indexOf(c.id) >= 0)\n      .filter(isCanvas)\n      .sort((a, b) => canvasIds.indexOf(a.id) > canvasIds.indexOf(b.id) ? -1 : 1)[0];\n    const rangeLabel = getI18nValue(\n      range.label ?? '<untitled>',\n      languagePreference,\n      '; '\n    );\n    const childRanges = vault.get<RangeNormalized>(range.items.filter(isRange));\n    const children = (\n      await Promise.all(childRanges.map(handleTocRange))\n    ).filter(isDefined<TocItem>);\n\n    let startCanvas: StartCanvasInfo | undefined;\n    if (range.start) {\n      startCanvas = await fetchStartCanvasInfo(range);\n    }\n    seenRanges.add(range.id);\n    if (children.length === 0 && !firstCanvas) {\n      // Range with no canvases and no child ranges, ignore\n      // This usually happens when the user filtered the canvases to be included in the\n      // PDF and the range and its children only contains canvases that were filtered out\n      return;\n    } else if (!startCanvas && firstCanvas) {\n      startCanvas = firstCanvas.id;\n    } else if (!startCanvas) {\n      startCanvas = children[0].startCanvas;\n    }\n    return {\n      label: rangeLabel,\n      startCanvas,\n      children,\n    };\n  };\n\n  let tocRanges = vault.get<RangeNormalized>(manifest.structures);\n  const topRange = tocRanges.find(r => (r.behavior as string[]).indexOf(\"top\") >= 0);\n  // If there's a 'top' range, only use that as the single top-level ToC node\n  if (topRange) {\n    tocRanges = [topRange];\n  }\n\n  return (\n    (\n      await Promise.all(tocRanges.map(handleTocRange)\n      )\n    ).filter(isDefined<TocItem>) ?? []\n  );\n}\n\nexport type ProgressMessageCode =\n  'generate-cover-page' |\n  'generate-pages' |\n  'finishing';\n\nexport type ProgressNotification =\n  ImageDownloadFailureNotification |\n  OcrDownloadFailureNotification;\n\nexport type ImageDownloadFailureNotification = {\n  code: 'image-download-failure';\n  canvasIndex: number;\n  numFailed: number;\n  numTotal: number;\n  details: {\n    [imageUrl: string]: string;\n  }\n}\nexport type OcrDownloadFailureNotification = {\n  code: 'ocr-download-failure';\n  canvasIndex: number;\n  ocrUrl: string;\n}\n\n/** Tracks PDF generation progress and various statistics related to that. */\nclass ProgressTracker {\n  canvasPixels = 0;\n  pixelsWritten = 0;\n  pixelBytesFactor = 0;\n  pixelScaleFactor = 0;\n  timeStart: number | undefined;\n\n  pdfGen: PDFGenerator;\n  totalPages: number;\n  totalCanvasPixels = 0;\n  countingStream: CountingWriter;\n  onProgress?: (status: ProgressStatus) => void;\n  onNotification?: (notification: ProgressNotification) => void;\n\n  constructor(\n    canvases: CanvasNormalized[],\n    countingStream: CountingWriter,\n    pdfGen: PDFGenerator,\n    onProgress?: (status: ProgressStatus) => void,\n    onNotification?: (notification: ProgressNotification) => void\n  ) {\n    this.totalCanvasPixels = canvases.reduce(\n      (sum, canvas) => sum + canvas.width * canvas.height,\n      0\n    );\n    this.totalPages = canvases.length;\n    this.pdfGen = pdfGen;\n    this.countingStream = countingStream;\n    this.onProgress = onProgress;\n    this.onNotification = onNotification;\n  }\n\n  /** Check if there is still data that needs to be written out. */\n  get writeOutstanding(): boolean {\n    return this.pdfGen.bytesWritten > this.countingStream.bytesWritten;\n  }\n\n  /** Emit a progress update, with an optional message. */\n  emitProgress(pagesWritten: number, messageCode?: ProgressMessageCode): void {\n    if (!this.timeStart) {\n      this.timeStart = now();\n    }\n    const bytesPushed = this.pdfGen.bytesWritten;\n    let estimatedFileSize;\n    if (pagesWritten === this.totalPages) {\n      estimatedFileSize = bytesPushed;\n    } else if (pagesWritten > 0) {\n      estimatedFileSize = Math.floor(\n        this.pixelBytesFactor * this.pixelScaleFactor * this.totalCanvasPixels\n      );\n    }\n    const bytesWritten = this.countingStream.bytesWritten;\n    const writeSpeed = bytesPushed / ((now() - this.timeStart) / 1000);\n    let remainingDuration = Number.POSITIVE_INFINITY;\n    if (estimatedFileSize) {\n      remainingDuration = (estimatedFileSize - bytesWritten) / writeSpeed;\n    }\n    this.onProgress?.({\n      messageCode,\n      pagesWritten,\n      totalPages: this.totalPages,\n      bytesWritten,\n      bytesPushed,\n      estimatedFileSize,\n      writeSpeed,\n      remainingDuration,\n    });\n  }\n\n  /** Emit a notification message to inform the user about unexpected stuff that\n   * happens during PDF generation */\n  emitNotification(notification: ProgressNotification) {\n    this.onNotification?.(notification);\n  }\n\n  /** Update how many actual pixels and 'canvas pixels' have been written. */\n  updatePixels(pixelsWritten: number, canvasPixels: number) {\n    this.pixelsWritten += pixelsWritten;\n    this.canvasPixels += canvasPixels;\n    this.pixelScaleFactor = this.pixelsWritten / this.canvasPixels;\n    this.pixelBytesFactor = this.pdfGen.bytesWritten / this.pixelsWritten;\n  }\n}\n\n/** Generate a cover page PDF, either via user-provided callback, or by fetching\n * it from a remote endpoint. */\nasync function getCoverPagePdf(\n  manifest: ManifestNormalized,\n  languagePreference: Array<string>,\n  endpoint?: string,\n  callback?: (params: CoverPageParams) => Promise<Uint8Array>\n): Promise<Uint8Array> {\n  const params: CoverPageParams = {\n    // NOTE: Manifest label is mandatory, i.e. safe to assert non-null\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    title: getI18nValue(\n      manifest.label ?? '<untitled>',\n      languagePreference,\n      '; '\n    ),\n    manifestUrl: manifest.id,\n    pdiiifVersion,\n  };\n  const thumbUrl = await getThumbnail(manifest, 512);\n  if (thumbUrl) {\n    params.thumbnail = { url: thumbUrl };\n    const manifestThumb = vault.get<ContentResource>(manifest.thumbnail)[0];\n    if (manifestThumb && 'type' in manifestThumb) {\n      params.thumbnail.iiifImageService = (\n        manifestThumb as IIIFExternalWebResource\n      ).service?.find(\n        (s: Service): s is ImageService =>\n          (s as ImageService | undefined)?.type?.startsWith('ImageService') ??\n          false\n      )?.id;\n    }\n  }\n\n  const provider = vault.get<ResourceProviderNormalized>(manifest.provider)[0];\n  const required = manifest.requiredStatement;\n  if (provider) {\n    params.provider = {\n      label: getI18nValue(provider.label, languagePreference, '; '),\n      homepage: provider.homepage?.[0]?.id,\n      logo: provider.logo?.[0]?.id,\n    };\n    // FIXME: Currently this is assigned by @iiif/parser when converting from v2 to v3\n    if (params.provider.label === 'Unknown') {\n      params.provider.label = '';\n    }\n  }\n  if (required != null && required.label) {\n    params.requiredStatement = {\n      label: getI18nValue(required.label, languagePreference, '; '),\n      value: getI18nValue(required.value, languagePreference, '; '),\n    };\n  }\n  const license = manifest.rights;\n  if (license) {\n    const licenseDef = getLicenseInfo(license);\n    params.rights = {\n      text: licenseDef?.text ?? license,\n      url: license,\n      logo: licenseDef?.logo,\n    };\n  }\n  params.metadata =\n    manifest.metadata\n      ?.map((itm) => {\n        const label = getI18nValue(itm.label, languagePreference, '; ');\n        const values = getI18nValue(itm.value, languagePreference, '|||').split(\n          '|||'\n        );\n        if (!label || values.length === 0) {\n          return;\n        }\n        if (values.length === 1) {\n          return [label, values[0]];\n        } else {\n          return [label, values];\n        }\n      })\n      .filter((x): x is [string, string | string[]] => x !== undefined) ?? [];\n  if (callback) {\n    return await callback(params);\n  } else if (endpoint) {\n    const resp = await fetchRespectfully(endpoint, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(params),\n    });\n    const buf = await resp.arrayBuffer();\n    return new Uint8Array(buf);\n  } else {\n    throw 'Either `endpoint` or `callback` must be specified!';\n  }\n}\n\nexport type ConversionReport = {\n  fileSizeBytes: number;\n  numPages: number;\n  fileName?: string;\n  failedImages?: Array<{\n    canvasIndex: number;\n    numFailed: number;\n    numTotal: number;\n    details: {\n      [imageUrl: string]: string;\n    }\n  }>;\n  failedOcr?: Array<{\n    canvasIndex: number;\n    ocrUrl: string;\n  }>;\n}\n\nexport type ConversionReportWithData = ConversionReport & { data: Blob };\n\nexport async function convertManifest(\n  inputManifest: string | Manifest | Presentation2.Manifest,\n  outputStream: Writable | WritableStream,\n  options: ConvertOptions\n): Promise<ConversionReport>;\nexport async function convertManifest(\n  inputManifest: string | Manifest | Presentation2.Manifest,\n  outputStream: undefined,\n  options: ConvertOptions\n): Promise<ConversionReportWithData>;\n/** Convert a IIIF manifest to a PDF,  */\nexport async function convertManifest(\n  /* eslint-disable  @typescript-eslint/explicit-module-boundary-types */\n  inputManifest: string | Manifest | Presentation2.Manifest,\n  outputStream: Writable | WritableStream | undefined,\n  {\n    fetchCanvasAnnotations = () => Promise.resolve([]),\n    filterCanvases = () => true,\n    languagePreference = [Intl.DateTimeFormat().resolvedOptions().locale],\n    scaleFactor,\n    metadata = {},\n    onProgress,\n    onNotification,\n    ppi,\n    concurrency = 1,\n    abortController = new AbortController(),\n    coverPageCallback,\n    coverPageEndpoint,\n    polyglotZipPdf,\n    polyglotZipBaseDir,\n    saxWasmLoader = async () =>\n      fetch(`https://unpkg.com/sax-wasm@${ocrParser.SAX_WASM_VERSION}/lib/sax-wasm.wasm`)\n        .then((res) => res.arrayBuffer())\n        .then((buf) => new Uint8Array(buf)),\n  }: ConvertOptions\n): Promise<ConversionReport | ConversionReportWithData> {\n  // Prevent warning when running in Node.js\n  if (typeof process !== \"undefined\") {\n    events.setMaxListeners(100, abortController.signal);\n  }\n  let writer: Writer;\n  if (!outputStream) {\n    log.debug('Writing to Blob');\n    writer = new BlobWriter();\n    // Can't use `instanceof` since we don't have the Node class in the\n    // browser and vice versa, so examine the shape of the object\n  } else if (typeof (outputStream as Writable).destroy === 'function') {\n    log.debug('Writing to Node writable stream');\n    writer = new NodeWriter(outputStream as Writable);\n    // Cancel further processing once the underlying stream has been closed\n    // This will only have an effect if the PDF has not finished generating\n    // yet (i.e. when the client terminates the connection prematurely),\n    // otherwise all processing will long have stopped\n    (outputStream as Writable).on('close', () => abortController.abort());\n  } else {\n    log.debug('Writing to file system');\n    writer = new WebWriter(outputStream as WritableStream);\n  }\n  const countingWriter = new CountingWriter(writer);\n  const report = {\n    fileSizeBytes: 0,\n    numPages: 0,\n  } as ConversionReport;\n\n  // Build a canvas predicate function from a list of identifiers, if needed\n  let canvasPredicate: (canvasId: string) => boolean;\n  if (Array.isArray(filterCanvases)) {\n    canvasPredicate = (canvasId) => filterCanvases.indexOf(canvasId) >= 0;\n  } else {\n    canvasPredicate = filterCanvases as (id: string) => boolean;\n  }\n\n  let manifestId: string;\n  let manifestJson: Manifest | Presentation2.Manifest;\n  if (typeof inputManifest === 'string') {\n    manifestId = inputManifest;\n    manifestJson = await fetchManifestJson(manifestId) as\n      | Manifest\n      | Presentation2.Manifest;\n  } else {\n    manifestId =\n      (inputManifest as Presentation2.Manifest)['@id'] ??\n      (inputManifest as Manifest).id;\n    manifestJson = inputManifest;\n  }\n  const manifest = await vault.loadManifest(manifestId, manifestJson);\n  if (!manifest) {\n    throw new Error(`Failed to load manifest from ${manifestId}`);\n  }\n\n  const pdfMetadata = { ...metadata };\n  if (!pdfMetadata.Title && manifest.label) {\n    pdfMetadata.Title = getI18nValue(\n      manifest.label,\n      languagePreference as string[],\n      '; '\n    );\n  }\n\n  const canvases = vault.get<CanvasNormalized>(\n    manifest.items.filter((c) => canvasPredicate(c.id))\n  );\n  const hasText = !!canvases.find((c) => !!getOcrReferences(c));\n  const labels = canvases.map((canvas) =>\n    canvas.label ? getI18nValue(canvas.label, languagePreference, '; ') : ''\n  );\n\n  // Initialize XML parsers\n  if (!saxParserWasm || !ocrParser.isInitialized()) {\n    if (!saxParserWasm) {\n      const wasm = await saxWasmLoader();\n      initializeSaxParser(wasm);\n    }\n    if (!ocrParser.isInitialized()) {\n      await ocrParser.initialize(() => Promise.resolve(saxParserWasm!));\n      ocrParser.setupLogging({\n        debug: log.debug.bind(log),\n        info: log.info.bind(log),\n        warn: log.warn.bind(log),\n        error: log.error.bind(log),\n      });\n    }\n  }\n\n  // Fetch images concurrently, within limits specified by user\n  log.debug(`Setting up queue with ${concurrency} concurrent canvas fetches.`);\n  const queue = new PQueue({ concurrency });\n  abortController.signal.addEventListener('abort', () => queue.clear(), {\n    once: true,\n  });\n  const canvasInfos = canvases.map(getCanvasInfo);\n  const canvasFuts = canvases.map((c, idx) => {\n    return queue.add(() => {\n      const info = canvasInfos[idx];\n      return fetchCanvasData(c, info.images, {\n        scaleFactor,\n        ppiOverride: ppi,\n        abortSignal: abortController.signal,\n      });\n    });\n  });\n\n  const outline = await buildOutlineFromRanges(\n    manifest,\n    canvases,\n    languagePreference as string[]\n  );\n  const pdfGen = new PDFGenerator({\n    writer: countingWriter,\n    metadata: pdfMetadata,\n    canvasInfos: canvases.map((c, idx) => ({\n      canvasIdx: idx,\n      ...canvasInfos[idx]\n    })),\n    langPref: languagePreference,\n    pageLabels: labels,\n    outline,\n    hasText,\n    initialCanvas: await fetchStartCanvasInfo(manifest),\n    readingDirection:\n      manifest.viewingDirection === 'right-to-left'\n        ? 'right-to-left'\n        : 'left-to-right',\n    manifestJson,\n    zipPolyglot: polyglotZipPdf,\n    zipBaseDir: polyglotZipBaseDir,\n  });\n  log.debug(`Initialising PDF generator.`);\n  await pdfGen.setup();\n  const progress = new ProgressTracker(\n    canvases,\n    countingWriter,\n    pdfGen,\n    onProgress,\n    onNotification,\n  );\n  progress.emitProgress(0);\n\n  if (coverPageCallback || coverPageEndpoint) {\n    log.debug(`Generating cover page`);\n    progress.emitProgress(0, 'generate-cover-page');\n    try {\n      const coverPageData = await getCoverPagePdf(\n        manifest,\n        languagePreference as string[],\n        coverPageEndpoint,\n        coverPageCallback\n      );\n      log.debug('Inserting cover page into PDF');\n      await pdfGen.insertCoverPages(coverPageData);\n    } catch (err) {\n      log.error('Error while generating cover page', err);\n      abortController.abort();\n      throw err;\n    }\n  }\n\n  progress.emitProgress(0, 'generate-pages');\n  for (let canvasIdx = 0; canvasIdx < canvases.length; canvasIdx++) {\n    if (abortController.signal.aborted) {\n      log.debug('Abort signalled, aborting while waiting for image data.');\n      break;\n    }\n    try {\n      log.debug(`Waiting for data for canvas #${canvasIdx}`);\n      const canvasData = await canvasFuts[canvasIdx];\n      // This means the task was aborted, do nothing\n      // FIXME: Doesn't this also happen in case of an error?\n      if (!canvasData) {\n        throw 'Aborted';\n      }\n      const canvas = vault.get<CanvasNormalized>(canvasData.canvas);\n      const canvasInfo = canvasInfos[canvasIdx];\n      const { images, ppi, text, annotations, imageFailures } = canvasData;\n      if (imageFailures.length > 0) {\n        if (!report.failedImages) {\n          report.failedImages = [];\n        }\n        const reportData = {\n          canvasIndex: canvasIdx,\n          numFailed: imageFailures.length,\n          numTotal: images.length + imageFailures.length,\n          details: Object.fromEntries(\n            imageFailures.map((f) => [\n              f.resource.id ?? '<unknown>',\n              f.cause instanceof Error ? f.cause.toString() : f.cause\n            ]))\n        };\n        report.failedImages.push(reportData);\n        progress.emitNotification({\n          code: 'image-download-failure',\n          ...reportData\n        });\n      }\n      if (canvasInfo.ocr && !text?.markup) {\n        if (!report.failedOcr) {\n          report.failedOcr = [];\n        }\n        const reportData = {\n          canvasIndex: canvasIdx,\n          ocrUrl: canvasInfo.ocr.id,\n        }\n        report.failedOcr.push(reportData);\n        progress.emitNotification({\n          code: 'ocr-download-failure',\n          ...reportData,\n        });\n      }\n      const externalAnnotations = await fetchCanvasAnnotations(canvas.id);\n      if (externalAnnotations != null) {\n        const normalized = await Promise.all(\n          externalAnnotations.map((a) => {\n            if (!('id' in a)) {\n              a = convertPresentation2(a) as IIIF3Annotation;\n            }\n            return vault.load<AnnotationNormalized>(a.id, a);\n          })\n        );\n        if (normalized) {\n          normalized\n            .filter((a): a is AnnotationNormalized => a !== undefined)\n            .map((a) => parseAnnotation(a, languagePreference))\n            .filter((a): a is Annotation => a !== undefined)\n            .forEach((a) => annotations.push(a));\n        }\n      }\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      const stopMeasuring = metrics?.pageGenerationDuration.startTimer();\n      log.debug(`Rendering canvas #${canvasIdx} into PDF`);\n      await pdfGen.renderPage(\n        canvasData.canvas.id,\n        { width: canvas.width, height: canvas.height },\n        [...images, ...imageFailures],\n        annotations,\n        text,\n        ppi\n      );\n      stopMeasuring?.();\n      progress.updatePixels(\n        images.reduce(\n          (acc, img) => acc + img.width * img.height,\n          0\n        ),\n        canvas.width * canvas.height\n      );\n      report.numPages++;\n    } catch (err) {\n      // Clear queue, cancel all ongoing image fetching\n      if (err !== 'Aborted') {\n        log.error('Failed to render page', err);\n      }\n      queue.clear();\n      if (!abortController.signal.aborted) {\n        abortController.abort();\n      }\n      throw err;\n    } finally {\n      delete canvasFuts[canvasIdx];\n    }\n    progress.emitProgress(canvasIdx + 1);\n  }\n\n  // Finish writing PDF, resulting Promise is resolved once the writer is closed\n  log.debug('Finalizing PDF');\n  const endPromise = pdfGen.end();\n\n  // At this point the PDF data might still be incomplete, so we wait for\n  // drain events on the writer and continue updating our progress tracker\n  // until the writer is actually closed\n  if (!abortController.signal.aborted) {\n    let closed = false;\n    endPromise.then(() => (closed = true));\n    const progressOnDrain = async () => {\n      if (closed) {\n        return;\n      }\n      progress.emitProgress(canvases.length, 'finishing');\n      while (!closed && progress.writeOutstanding) {\n        await writer.waitForDrain();\n      }\n    };\n\n    // Wait for initial drainage event in case the writer isn't already closed\n    if (!closed) {\n      await writer.waitForDrain();\n      await progressOnDrain();\n    }\n  }\n\n  // Wait for the writer to be closed\n  log.debug('Waiting for writer to close.');\n  await endPromise;\n\n  report.fileSizeBytes = countingWriter.bytesWritten;\n  if (writer instanceof BlobWriter) {\n    return {...report, data: writer.blob };\n  } else {\n    return report;\n  }\n}\n","/* eslint-disable no-new-wrappers */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\n/// PDF generation code\n// FIXME: This is currently one hell of a mess, learning about PDF and coming up\n// with good abstractions at the same time was too much of a challenge for me 🙈\nimport dedent from 'dedent-js';\nimport { Manifest } from '@iiif/presentation-3';\nimport { Manifest as ManifestV2 } from '@iiif/presentation-2';\nimport { OcrPage, OcrBlock, OcrParagraph, OcrLine, OcrWord } from 'ocr-parser';\n\nimport {\n  Metadata,\n  PdfObject,\n  PdfDictionary,\n  makeRef,\n  PdfArray,\n  PdfRef,\n  serialize,\n  PdfValue,\n  toUTF16BE,\n  StructTreeEntry,\n} from './common.js';\nimport { TocItem, textEncoder, randomData, tryDeflateStream } from './util.js';\nimport { ArrayReader, Writer } from '../io.js';\nimport { OcrPageWithMarkup } from '../ocr.js';\nimport PdfImage from './image.js';\nimport { PdfParser } from './parser.js';\nimport pdiiifVersion from '../version.js';\nimport log from '../log.js';\nimport {\n  CanvasImage,\n  ImageFetchFailure,\n  StartCanvasInfo,\n  isImageFetchFailure,\n} from '../download.js';\nimport { Annotation, CanvasInfo, getI18nValue } from '../iiif.js';\nimport {\n  buildCentralFileDirectory,\n  buildLocalZipHeader,\n  CentralDirectoryFileSpec,\n} from './pkzip.js';\nimport { crc32 } from '../util.js';\nimport { exportPdfAnnotation } from './annos.js';\n\nconst PRODUCER = `pdiiif v${pdiiifVersion}`;\n\n/// If the font is 10 pts, nominal character width is 5 pts\nconst CHAR_WIDTH = 2;\n\n/// Taken from tesseract@2d6f38eebf9a14d9fbe65d785f0d7bd898ff46cb, tessdata/pdf.ttf\n/// Created by Ken Sharp\n/// (C) Copyright 2011, Google Inc.\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 http://www.apache.org/licenses/LICENSE-2.0\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.\nconst FONTDATA = new Uint8Array([\n  0, 1, 0, 0, 0, 10, 0, 128, 0, 3, 0, 32, 79, 83, 47, 50, 86, 222, 200, 148, 0,\n  0, 1, 40, 0, 0, 0, 96, 99, 109, 97, 112, 0, 10, 0, 52, 0, 0, 1, 144, 0, 0, 0,\n  30, 103, 108, 121, 102, 21, 34, 65, 36, 0, 0, 1, 184, 0, 0, 0, 24, 104, 101,\n  97, 100, 11, 120, 241, 101, 0, 0, 0, 172, 0, 0, 0, 54, 104, 104, 101, 97, 12,\n  2, 4, 2, 0, 0, 0, 228, 0, 0, 0, 36, 104, 109, 116, 120, 4, 0, 0, 0, 0, 0, 1,\n  136, 0, 0, 0, 8, 108, 111, 99, 97, 0, 12, 0, 0, 0, 0, 1, 176, 0, 0, 0, 6, 109,\n  97, 120, 112, 0, 4, 0, 5, 0, 0, 1, 8, 0, 0, 0, 32, 110, 97, 109, 101, 242,\n  235, 22, 218, 0, 0, 1, 208, 0, 0, 0, 75, 112, 111, 115, 116, 0, 1, 0, 1, 0, 0,\n  2, 28, 0, 0, 0, 32, 0, 1, 0, 0, 0, 1, 0, 0, 176, 148, 113, 16, 95, 15, 60,\n  245, 4, 7, 8, 0, 0, 0, 0, 0, 207, 154, 252, 110, 0, 0, 0, 0, 212, 195, 167,\n  242, 0, 0, 0, 0, 4, 0, 8, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n  8, 0, 255, 255, 0, 0, 4, 0, 0, 0, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 2, 0, 4, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 144, 0, 5, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 1, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 79, 79, 71, 0,\n  64, 0, 0, 0, 0, 0, 1, 255, 255, 0, 0, 0, 1, 0, 1, 128, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0,\n  0, 0, 20, 0, 3, 0, 0, 0, 0, 0, 20, 0, 6, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 8, 0, 0, 3, 0, 0, 49, 33, 17, 33,\n  4, 0, 252, 0, 8, 0, 0, 0, 0, 3, 0, 42, 0, 0, 0, 3, 0, 0, 0, 5, 0, 22, 0, 0, 0,\n  1, 0, 0, 0, 0, 0, 5, 0, 11, 0, 22, 0, 3, 0, 1, 4, 9, 0, 5, 0, 22, 0, 0, 0, 86,\n  0, 101, 0, 114, 0, 115, 0, 105, 0, 111, 0, 110, 0, 32, 0, 49, 0, 46, 0, 48,\n  86, 101, 114, 115, 105, 111, 110, 32, 49, 46, 48, 0, 0, 1, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n]);\n\ntype ZipDummyObjectSpec = {\n  filename: string;\n  data: Uint8Array;\n  deflatedData?: Uint8Array;\n  bytesUntilActualData: number;\n};\n\nexport type GeneratorParams = {\n  // Writer to output the PDF to\n  writer: Writer;\n  // Metadata to include in the PDF\n  metadata: Metadata;\n  // Information about canvases included in the PDF\n  canvasInfos: CanvasInfo[];\n  // List of languages to use for rendering labels, in descending order of preference\n  langPref: readonly string[];\n  // Labels for pages, every position corresponds to the canvas in the same position\n  pageLabels?: string[];\n  // Outline tree for the PDF\n  outline: TocItem[];\n  // Whether the PDF should include a hidden text layer\n  hasText?: boolean;\n  // Reading direction of the PDF\n  readingDirection?: 'right-to-left' | 'left-to-right';\n  // Information about the canvas (or canvas region) that should be displayed initially\n  initialCanvas?: StartCanvasInfo;\n  // The manifest to build the PDF from\n  manifestJson?: Manifest | ManifestV2;\n  // If this is enabled, the PDF will also be a valid ZIP archive of all the resources\n  // included in the PDF\n  zipPolyglot?: boolean;\n  // Base directory name for the polyglot ZIP archive, if not set the resources will be\n  // top-level in the archive\n  zipBaseDir?: string;\n};\n\nexport default class PDFGenerator {\n  // Keep track of how many bytes have been written so far\n  _offset = 0;\n  // PDF objects that are scheduled for writing, will be written on _flush()\n  _objects: Array<PdfObject> = [];\n  // Number of the next PDF object\n  _nextObjNo = 1;\n  // References to various central objects\n  _objRefs: Record<string, PdfRef> = {};\n  // Tracks offset of every XObject\n  _offsets: number[] = [];\n  // Writer used for outputting the PDF\n  _writer: Writer | undefined;\n  // Have we already started writing the IIIF pages?\n  _pagesStarted = false;\n  // Information about each canvas, needed for pre-allocating objects\n  _canvasInfos: Array<CanvasInfo> = [];\n  // Object number of the first page\n  _firstPageObjectNum: number | undefined;\n  // Labels for every page in the PDF\n  _pageLabels?: string[];\n  // Number of cover pages inserted at the beginning of the PDF\n  _numCoverPages = 0;\n  // PDF outline\n  _outline: TocItem[] = [];\n  // Is the PDF supposed to have a hidden text layer?\n  _hasText = false;\n  // List of top-level entries in the PDF's logical structure tree\n  _strucTree: StructTreeEntry[] = [];\n  // Maps a page's object number to the marked content sequence IDs its content\n  // stream has\n  _pageMCIds: Map<number, Array<number>> = new Map();\n  // Identifier of the next structure parent entry\n  _nextStructParentId = 0;\n  // For every page, its corresponding parent ID for the parent tree\n  _pageParentIds: Map<number, number> = new Map();\n  // Language preference\n  _langPref: readonly string[];\n  _initialCanvas?: StartCanvasInfo;\n  private _polyglot: boolean;\n  private _manifestJson?: Manifest | ManifestV2;\n  private _zipCatalog?: Array<CentralDirectoryFileSpec>;\n  private _zipBaseDir?: string;\n  private _readingDirection: 'right-to-left' | 'left-to-right';\n\n  constructor({\n    writer,\n    metadata,\n    canvasInfos,\n    langPref,\n    pageLabels,\n    outline = [],\n    readingDirection = 'left-to-right',\n    hasText = false,\n    initialCanvas,\n    manifestJson,\n    zipPolyglot = false,\n    zipBaseDir,\n  }: GeneratorParams) {\n    this._writer = writer;\n    this._canvasInfos = canvasInfos;\n    this._pageLabels = pageLabels;\n    this._outline = outline;\n    this._hasText = hasText;\n    this._readingDirection = readingDirection;\n    this._langPref = langPref;\n    this._initialCanvas = initialCanvas;\n    this._polyglot = zipPolyglot;\n    this._zipBaseDir = zipBaseDir;\n    this._manifestJson = manifestJson;\n\n    const pdfMetadata: PdfDictionary = {\n      ...Object.entries(metadata)\n        .filter((k, v) => v !== undefined)\n        .reduce((prev, [k, v]) => {\n          prev[k] = `(${v})`;\n          return prev;\n        }, {} as PdfDictionary),\n      Producer: `(${PRODUCER})`,\n    };\n    this._addObject(pdfMetadata, 'Info');\n  }\n\n  async setup(): Promise<void> {\n    const catalog: PdfDictionary = {\n      Type: '/Catalog',\n    };\n    this._addObject(catalog, 'Catalog');\n\n    const pagesObj = this._addObject(\n      {\n        Type: '/Pages',\n        Count: this._canvasInfos.length,\n      },\n      'Pages'\n    );\n    catalog.Pages = makeRef(pagesObj);\n\n    if (this._hasText) {\n      catalog.MarkInfo = {\n        Type: '/MarkInfo',\n        Marked: true,\n      };\n    }\n\n    if (this._outline.length > 0) {\n      catalog.PageMode = '/UseOutlines';\n      const outlines: PdfDictionary = {\n        Type: '/Outlines',\n        Count: 0,\n      };\n      const outlinesObj = this._addObject(outlines);\n      catalog.Outlines = makeRef(outlinesObj);\n      let prev: PdfObject | undefined;\n      for (const [idx, itm] of this._outline.entries()) {\n        const [childObj, numKids] = this._addOutline(itm, outlinesObj, prev);\n        (outlines.Count as number) += 1 + numKids;\n        if (idx === 0) {\n          outlines.First = makeRef(childObj);\n        } else if (idx === this._outline.length - 1) {\n          outlines.Last = makeRef(childObj);\n        }\n        prev = childObj;\n      }\n    } else {\n      catalog.PageMode = '/UseThumbs';\n    }\n    catalog.ViewerPreferences = {\n      Direction: this._readingDirection === 'right-to-left' ? '/R2L' : '/L2R',\n    };\n    if (this._hasText) {\n      await this._setupHiddenTextFont();\n    }\n  }\n\n  async _setupHiddenTextFont(): Promise<void> {\n    const typeZeroFont = this._addObject(\n      {\n        Type: '/Font',\n        Subtype: '/Type0',\n        BaseFont: '/GlyphLessFont',\n        Encoding: '/Identity-H',\n      },\n      'Type0Font'\n    );\n\n    const typeTwoFont = this._addObject({\n      type: '/Font',\n      Subtype: '/CIDFontType2',\n      BaseFont: '/GlyphLessFont',\n      DW: 1000 / CHAR_WIDTH,\n      CIDSystemInfo: {\n        Ordering: '(Identity)',\n        Registry: '(Adobe)',\n        Supplement: 0,\n      },\n    });\n    (typeZeroFont.data as PdfDictionary).DescendantFonts = [\n      makeRef(typeTwoFont),\n    ];\n\n    const cidtoGidMapData = new Uint8Array(128 * 1024);\n    for (let i = 0; i < cidtoGidMapData.length; i++) {\n      cidtoGidMapData[i] = i % 2 ? 1 : 0;\n    }\n    const comp = await tryDeflateStream(cidtoGidMapData);\n    const cidToGidMap = this._addObject(comp.dict, undefined, comp.stream);\n    (typeTwoFont.data as PdfDictionary).CIDToGIDMap = makeRef(cidToGidMap);\n\n    const cmapStream = dedent`\n      /CIDInit /ProcSet findresource begin\n        12 dict begin\n        begincmap\n            /CIDSystemInfo\n            <<\n              /Registry (Adobe)\n              /Ordering (UCS)\n              /Supplement 0\n            >> def\n            /CMapName /Adobe-Identify-UCS def\n            /CMapType 2 def\n            1 begincodespacerange\n            <0000> <FFFF>\n            endcodespacerange\n            1 beginbfrange\n            <0000> <FFFE> <0000>\n            endbfrange\n        endcmap\n        CMapName currentdict /CMap defineresource pop\n        end\n    end`;\n    const cmap = this._addObject(\n      {\n        Length: cmapStream.length,\n      },\n      undefined,\n      cmapStream\n    );\n    (typeZeroFont.data as PdfDictionary).ToUnicode = makeRef(cmap);\n\n    const fontDesc = this._addObject({\n      Type: '/FontDescriptor',\n      FontName: '/GlyphLessFont',\n      FontBBox: [0, 0, 1000 / CHAR_WIDTH, 1000],\n      Ascent: 1000,\n      CapHeight: 1000,\n      Descent: -1,\n      Flags: 5,\n      ItalicAngle: 0,\n      StemV: 80,\n    });\n    (typeTwoFont.data as PdfDictionary).FontDescriptor = makeRef(fontDesc);\n\n    const maybeCompressedFont = await tryDeflateStream(FONTDATA);\n    const fontDataObj = this._addObject(\n      {\n        Length1: FONTDATA.length,\n        ...maybeCompressedFont.dict,\n      },\n      undefined,\n      maybeCompressedFont.stream\n    );\n    (fontDesc.data as PdfDictionary).FontFile2 = makeRef(fontDataObj);\n  }\n\n  _registerEmbeddedFilesInCatalog() {\n    const catalog = this._objects[this._objRefs.Catalog.refObj]\n      .data as PdfDictionary;\n    const embeddedFiles: PdfArray = [\n      `(manifest.json)`,\n      makeRef(this._firstPageObjectNum! - (this._polyglot ? 3 : 2)),\n    ];\n    for (const [idx, canvas] of this._canvasInfos.entries()) {\n      if (!canvas.ocr) {\n        continue;\n      }\n      const pageObjNum = this.getCanvasObjectNumber(idx);\n      // The file spec for embedded OCR file is the previous to last XObject for a given canvas\n      let fileObjNum = pageObjNum + this.getObjectsPerCanvas(idx) - 2;\n      if (this._polyglot) {\n        // Except if the PDF is polyglot, then it's the second to last XObject\n        fileObjNum -= 1;\n      }\n      embeddedFiles.push(`(${canvas.ocr.id})`);\n      embeddedFiles.push(makeRef(fileObjNum));\n    }\n    if (!catalog.Names) {\n      catalog.Names = {\n        EmbeddedFiles: { Names: embeddedFiles },\n      };\n    } else {\n      const names = catalog.Names as PdfDictionary;\n      const nameTree = names.EmbeddedFiles as PdfDictionary;\n      nameTree.Names = (nameTree.Names as PdfArray).concat(embeddedFiles);\n    }\n  }\n\n  _addOutline(\n    itm: TocItem,\n    parent: PdfObject,\n    prev?: PdfObject\n  ): [PdfObject, number] {\n    let dest: PdfArray;\n    if (typeof itm.startCanvas === 'string') {\n      const destCanvasIdx = this._canvasInfos.findIndex(\n        (ci) => ci.canvas.id === itm.startCanvas\n      );\n      if (destCanvasIdx < 0) {\n        throw Error(\n          `Could not find canvas with id ${itm.startCanvas} in manifest!`\n        );\n      }\n      dest = [destCanvasIdx, '/Fit'];\n    } else {\n      const canvasId = itm.startCanvas.id;\n      const unitScale = 72 / itm.startCanvas.ppi;\n      const rect = itm.startCanvas.position;\n      const { width, height } = itm.startCanvas.dimensions;\n      const destCanvasIdx = this._canvasInfos.findIndex(\n        (ci) => ci.canvas.id === canvasId\n      );\n      if (destCanvasIdx < 0) {\n        throw Error(`Could not find canvas with id ${canvasId} in manifest!`);\n      }\n      dest = [\n        destCanvasIdx,\n        '/FitR',\n        // TODO: Thoroughly test that this is actually working!\n        unitScale * rect.x, // left\n        unitScale * rect.y, // bottom\n        unitScale * (width - (rect.x + rect.width)), // right,\n        unitScale * (height - (rect.y + rect.height)), // top,\n      ];\n    }\n    const rec: PdfDictionary = {\n      Title: `( ${itm.label} )`,\n      Parent: makeRef(parent),\n      // NOTE: The first entry is a number only during setup and will later be\n      //       replaced with a reference to the actual page object, once we know\n      //       how many objects are preceding the page objects.\n      Dest: dest,\n    };\n    const obj = this._addObject(rec);\n    if (prev) {\n      rec.Prev = makeRef(prev);\n      (prev.data as PdfDictionary).Next = makeRef(obj);\n    }\n    if (itm.children?.length) {\n      let prev: PdfObject | undefined;\n      rec.Count = 0;\n      for (const [idx, child] of itm.children.entries()) {\n        const [childObj, numChildren] = this._addOutline(child, obj, prev);\n        if (idx === 0) {\n          rec.First = makeRef(childObj);\n        } else if (idx === itm.children.length - 1) {\n          rec.Last = makeRef(childObj);\n        }\n        rec.Count = rec.Count + 1 + numChildren;\n        prev = childObj;\n      }\n    }\n    return [obj, (rec.Count as number) ?? 0];\n  }\n\n  _addObject(\n    val: PdfValue,\n    refName?: string,\n    stream?: Uint8Array | string\n  ): PdfObject {\n    const isObject = (x: unknown): x is object =>\n      typeof x === 'object' && x !== null;\n    if (stream) {\n      if (!isObject(val)) {\n        throw new Error(\n          'PDF Objects with a stream must have a dictionary as its value'\n        );\n      }\n      if (!(val as PdfDictionary).Length) {\n        (val as PdfDictionary).Length = stream.length;\n      }\n    }\n    const obj = {\n      num: this._nextObjNo,\n      data: val,\n      stream,\n    };\n    this._nextObjNo++;\n    this._objects[obj.num] = obj;\n    if (refName) {\n      this._objRefs[refName] = makeRef(obj);\n    }\n    return obj;\n  }\n\n  /** Clone an object from a foreign PDF into the current PDF, adjusting\n   *  the encountered indirect object references.\n   */\n  private async _transplantObject(\n    parser: PdfParser,\n    obj: PdfObject,\n    seenObjects: Record<number, PdfRef> = {}\n  ): Promise<PdfRef> {\n    const handleValue = async (value: PdfValue): Promise<PdfValue> => {\n      if (value instanceof PdfRef) {\n        const o = await parser.resolveRef(value);\n        if (o === undefined) {\n          throw `Could not resolve reference to object '${value.refObj}'`;\n        }\n        // Check if we've already transplanted the object\n        if (seenObjects[o.num]) {\n          return seenObjects[o.num];\n        }\n        const objDict = o.data as PdfDictionary;\n        const newObj = this._addObject(objDict, undefined, o.stream);\n        const ref = new PdfRef(newObj.num);\n        seenObjects[o.num] = ref;\n        newObj.data = await handleValue(objDict);\n        if (objDict.Type === '/Page') {\n          // Redirect to our own Pages object\n          (newObj.data as PdfDictionary).Parent = this._objRefs.Pages;\n        }\n        return ref;\n      } else if (typeof value === 'string' && value[0] != '/') {\n        return `(${value})`;\n      } else if (Array.isArray(value)) {\n        const out = [];\n        for (const val of value) {\n          out.push(await handleValue(val));\n        }\n        return out;\n      } else if (typeof value === 'object' && value !== null) {\n        const out: PdfDictionary = {};\n        for (const [key, val] of Object.entries(value)) {\n          // Ignore structure keys for now\n          if (key === 'StructParent' || key === 'StructParents') {\n            continue;\n          }\n          out[key] = await handleValue(val as PdfDictionary);\n        }\n        return out;\n      }\n      return value;\n    };\n    const ref = new PdfRef(obj.num);\n    // TODO: Special case: if the object is a page, we need to check for\n    //       a /StructParents key, check for the /StructTreeRoot key in\n    //       the catalog, and then transplant that to our _strucTree\n    //       and _pageMCIDs structures. Quite the handful!!\n    //\n    return (await handleValue(ref)) as PdfRef;\n  }\n\n  async insertCoverPages(pdfData: ArrayBuffer): Promise<void> {\n    if (this._pagesStarted) {\n      throw 'Cover pages must be inserted before writing the first regular page';\n    }\n    const reader = new ArrayReader(new Uint8Array(pdfData));\n    const parser = await PdfParser.parse(reader);\n    const pagesDict = this._objects[this._objRefs.Pages.refObj]\n      .data as PdfDictionary;\n    pagesDict.Kids = [];\n    // TODO: Parse and transplant the section and parent trees from\n    //       the catalog into our own structures.\n    for await (const page of parser.pages()) {\n      const dict = page.data as PdfDictionary;\n      // Ignore associated structured content for now\n      delete dict.StructParents;\n      delete dict.Parent;\n      const newPageRef = await this._transplantObject(parser, page);\n      (pagesDict.Kids as PdfArray).push(newPageRef);\n      (pagesDict.Count as number) += 1;\n      this._numCoverPages += 1;\n    }\n    return;\n  }\n\n  private async _embedResource(\n    id: string,\n    filename: string,\n    description: string,\n    mimeType: string,\n    data: string\n  ) {\n    // TODO: Add check that the file is actually pre-registered in\n    //       the catalog!\n    const fileSpec: PdfDictionary = {\n      Type: '/Filespec',\n      F: `(${filename})`,\n      UF: toUTF16BE(filename),\n      Desc: `(${description})`,\n      EF: {\n        F: makeRef(this._nextObjNo + (this._polyglot ? 2 : 1)),\n      },\n    };\n\n    const maybeCompressed = await tryDeflateStream(data);\n    const embeddedFile = {\n      Type: '/EmbeddedFile',\n      Subtype: `(${mimeType})`,\n      ...maybeCompressed.dict,\n    };\n\n    this._addObject(fileSpec);\n    if (this._polyglot) {\n      let zipData: Uint8Array;\n      if (typeof data === 'string') {\n        zipData = textEncoder.encode(data);\n      } else {\n        zipData = data;\n      }\n      const extraDataLength = this._getSerializedSize(\n        {\n          num: this._nextObjNo + 2,\n          data: { ...embeddedFile, ...maybeCompressed.dict },\n          stream: maybeCompressed.stream,\n        },\n        true\n      );\n      this._insertZipHeaderDummyObject({\n        filename,\n        data: zipData,\n        deflatedData: maybeCompressed.dict.Filter\n          ? (maybeCompressed.stream as Uint8Array)\n          : undefined,\n        // 2 bytes zlib header of deflated data\n        bytesUntilActualData: extraDataLength + 2,\n      });\n    }\n    this._addObject(embeddedFile, undefined, maybeCompressed.stream);\n  }\n\n  private async _embedManifest(\n    manifestJson: ManifestV2 | Manifest\n  ): Promise<void> {\n    let manifestMime = 'application/ld+json';\n    if (Array.isArray(manifestJson['@context'])) {\n      const manifestProfile = manifestJson['@context'].find((p) =>\n        p.startsWith('http://iiif.io/api/presentation')\n      );\n      if (manifestProfile) {\n        manifestMime += `;profile=\"${manifestProfile}\"`;\n      }\n    } else if (manifestJson['@context']) {\n      manifestMime += `;profile=\"${manifestJson['@context']}\"`;\n    }\n    await this._embedResource(\n      '@id' in manifestJson ? manifestJson['@id'] : manifestJson.id,\n      'manifest.json',\n      'IIIF Manifest this PDF is based on',\n      manifestMime,\n      JSON.stringify(manifestJson)\n    );\n  }\n\n  async finalizePdfHeader(): Promise<void> {\n    const catalog = this._objects[this._objRefs.Catalog.refObj]\n      .data as PdfDictionary;\n\n    // Create page tree with page labels\n    if (this._pageLabels) {\n      catalog.PageLabels = makeRef(\n        this._addObject({\n          Nums: this._pageLabels\n            .map((label, idx) =>\n              label\n                ? [idx + this._numCoverPages, { P: `( ${label} )` }]\n                : undefined\n            )\n            .filter((x) => x !== undefined)\n            .flat() as PdfArray,\n        })\n      );\n    }\n\n    const pagesObj = this._objects[this._objRefs.Pages.refObj];\n\n    // Now that we know from which object number the pages start, we can set the\n    // /Kids entry in the Pages object and update the outline destinations.\n    const pageDict = pagesObj.data as PdfDictionary;\n    if (!pageDict.Kids) {\n      pageDict.Kids = [];\n    }\n    this._firstPageObjectNum = this._nextObjNo;\n    if (this._manifestJson) {\n      this._firstPageObjectNum += 2;\n      if (this._polyglot) {\n        this._firstPageObjectNum++;\n      }\n    }\n    for (const [idx] of this._canvasInfos.entries()) {\n      (pageDict.Kids as PdfArray).push(\n        makeRef(this.getCanvasObjectNumber(idx))\n      );\n    }\n    this._objects\n      // Get ToC entry object, the first destination will be the canvas index\n      .filter((obj) => (obj.data as PdfDictionary)?.Dest !== undefined)\n      .forEach((obj: PdfObject) => {\n        const dest = (obj.data as PdfDictionary).Dest as PdfArray;\n        if (typeof dest[0] !== 'number') {\n          return;\n        }\n        dest[0] = makeRef(this.getCanvasObjectNumber(dest[0]));\n      });\n\n    // Register the structural content tree root\n    if (this._hasText) {\n      catalog.StructTreeRoot = makeRef(\n        this._nextObjNo + this.totalCanvasObjects\n      );\n    }\n\n    if (this._canvasInfos.some((ci) => ci.images.some((i) => i.choiceInfo))) {\n      // We're *very* explicit with the visibility of the various OCGs to\n      // ensure as broad a viewer support as possible (especially pdf.js\n      // needed it...)\n      const initiallyEnabledOCGs: PdfRef[] = [];\n      const initiallyDisabledOCGs: PdfRef[] = [];\n      const allOCGs: PdfRef[] = [];\n      const rbGroups: PdfRef[][] = [];\n      for (const [canvasIdx, { images }] of this._canvasInfos.entries()) {\n        const pageObjNum = this.getCanvasObjectNumber(canvasIdx);\n        let ocgStart = pageObjNum + 2 + images.length;\n        if (this._polyglot) {\n          // Take 'dummy' objects for ZIP polyglot into account\n          ocgStart += images.length;\n        }\n        let ocgIdx = 0;\n        const rbGroup = [];\n        for (const img of images) {\n          if (!img.choiceInfo) {\n            continue;\n          }\n          const ref = makeRef(ocgStart + ocgIdx);\n          if (img.choiceInfo.enabled) {\n            initiallyEnabledOCGs.push(ref);\n          } else {\n            initiallyDisabledOCGs.push(ref);\n          }\n          allOCGs.push(ref);\n          rbGroup.push(ref);\n          ocgIdx++;\n        }\n        rbGroups.push(rbGroup);\n      }\n      catalog.OCProperties = {\n        OCGs: allOCGs,\n        D: {\n          BaseState: '/OFF',\n          ON: initiallyEnabledOCGs,\n          OFF: initiallyDisabledOCGs,\n          RBGroups: rbGroups,\n        },\n      };\n    }\n\n    if (typeof this._initialCanvas === 'string') {\n      catalog.OpenAction = [\n        makeRef(\n          this.getCanvasObjectNumber(\n            this._canvasInfos.findIndex(\n              (ci) => ci.canvas.id === this._initialCanvas\n            )\n          )\n        ),\n      ];\n    } else if (this._initialCanvas) {\n      const unitScale = 72 / this._initialCanvas.ppi;\n      const rect = this._initialCanvas.position;\n      const { width, height } = this._initialCanvas.dimensions;\n      catalog.OpenAction = [\n        makeRef(\n          this.getCanvasObjectNumber(\n            this._canvasInfos.findIndex(\n              (ci) => ci.canvas.id === this._initialCanvas\n            )\n          )\n        ),\n        '/FitR',\n        // TODO: Thoroughly test that this is actually working!\n        unitScale * rect.x, // left\n        unitScale * rect.y, // bottom\n        unitScale * (width - (rect.x + rect.width)), // right,\n        unitScale * (height - (rect.y + rect.height)), // top,\n      ];\n    }\n\n    this._registerEmbeddedFilesInCatalog();\n\n    await this._flush();\n\n    if (this._manifestJson) {\n      await this._embedManifest(this._manifestJson);\n      await this._flush();\n    }\n  }\n\n  async renderPage(\n    canvasId: string,\n    {\n      width: canvasWidth,\n      height: canvasHeight,\n    }: { width: number; height: number },\n    images: (CanvasImage | ImageFetchFailure)[],\n    annotations: Annotation[],\n    ocrText?: OcrPageWithMarkup,\n    ppi = 300\n  ): Promise<void> {\n    if (!this._pagesStarted) {\n      log.debug('Initial page, finalizing PDF header structures.');\n      await this.finalizePdfHeader();\n      this._pagesStarted = true;\n    }\n    // Factor to multiply pixels by to get equivalent PDF units (72 pdf units === 1 inch)\n    const unitScale = 72 / ppi;\n    const pageDict: PdfDictionary = {\n      Type: '/Page',\n      Parent: this._objRefs.Pages,\n      MediaBox: [0, 0, unitScale * canvasWidth, unitScale * canvasHeight],\n      Resources: {\n        ProcSet: ['/PDF', '/Text', '/ImageB', '/ImageI', '/ImageC'],\n      },\n    };\n    if (this._hasText) {\n      pageDict.StructParents = this._nextStructParentId;\n      this._pageParentIds.set(this._nextObjNo, this._nextStructParentId);\n      this._nextStructParentId++;\n    }\n    if (ocrText && this._objRefs.Type0Font) {\n      (pageDict.Resources as PdfDictionary).Font = {\n        'f-0-0': this._objRefs.Type0Font,\n      };\n    }\n    const page = this._addObject(pageDict);\n\n    const contentOps: string[] = [];\n    const optionalGroupIds: { [imgId: string]: string } = {};\n    for (const [idx, image] of images.entries()) {\n      if (isImageFetchFailure(image)) {\n        continue;\n      }\n      const { x, y, width, height, choiceInfo } = image;\n      const drawWidth = unitScale * width;\n      const drawHeight = unitScale * height;\n      const drawX = unitScale * x;\n      const drawY = unitScale * (canvasHeight - height - y);\n      const imageId = `/Im${idx + 1}`;\n\n      if (choiceInfo?.optional) {\n        const ocId = `/oc${Object.keys(optionalGroupIds).length + 1}`;\n        optionalGroupIds[imageId] = ocId;\n        contentOps.push(`/OC ${ocId} BDC`);\n      }\n      contentOps.push(`q ${drawWidth} 0 0 ${drawHeight} ${drawX} ${drawY} cm`);\n      contentOps.push(`${imageId} Do`);\n      contentOps.push('Q');\n      if (choiceInfo?.optional) {\n        contentOps.push('EMC');\n      }\n    }\n    if (ocrText) {\n      contentOps.push(this._renderOcrText(ocrText, unitScale));\n    }\n    log.debug('Trying to compress content stream.');\n    const contentStreamComp = await tryDeflateStream(contentOps.join('\\n'));\n    const contentsObj = this._addObject(\n      contentStreamComp.dict,\n      undefined,\n      contentStreamComp.stream\n    );\n    (page.data as PdfDictionary).Contents = makeRef(contentsObj);\n\n    // Since we need the finalized page dictionary in order to determine\n    // the offset for the the local zip header, we pre-generate all the\n    // relevant information\n    const imageObjectNums = [...images.keys()].map((idx) => {\n      if (this._polyglot) {\n        return this._nextObjNo + idx * 2 + 1;\n      } else {\n        return this._nextObjNo + idx;\n      }\n    });\n    const optionalGroupObjectNums: { [imgId: string]: number } = {};\n    if (images.some((i) => i.choiceInfo?.optional)) {\n      for (const [idx, img] of images.entries()) {\n        if (isImageFetchFailure(img)) {\n          continue;\n        }\n        const imageId = `/Im${idx + 1}`;\n        if (!img.choiceInfo?.optional) {\n          continue;\n        }\n        // FIXME: This is broken for the layers example!\n        optionalGroupObjectNums[imageId] =\n          imageObjectNums.slice(-1)[0] + idx + 1;\n      }\n    }\n    const pageResources = (page.data as PdfDictionary)\n      .Resources as PdfDictionary;\n    const xObjects: PdfDictionary = {};\n    const properties: PdfDictionary = {};\n    for (const [idx, num] of imageObjectNums.entries()) {\n      if (isImageFetchFailure(images[idx])) {\n        continue;\n      }\n      const imageId = `/Im${idx + 1}`;\n      xObjects[imageId.substring(1)] = makeRef(num);\n      const ocgNum = optionalGroupObjectNums[imageId];\n      if (ocgNum !== undefined) {\n        const ocgId = optionalGroupIds[imageId];\n        properties[ocgId.substring(1)] = makeRef(ocgNum);\n      }\n    }\n    pageResources.XObject = xObjects;\n    if (Object.keys(properties).length > 0) {\n      pageResources.Properties = properties;\n    }\n\n    log.debug('Creating image objects.');\n    const canvasIdx = this._canvasInfos.findIndex(\n      (ci) => ci.canvas.id === canvasId\n    );\n    for (const [imgIdx, img] of images.entries()) {\n      if (isImageFetchFailure(img)) {\n        // Dummy image data object\n        this._addObject({});\n        if (this._polyglot) {\n          // Dummy dummy zip header object\n          this._addObject({});\n        }\n        continue;\n      }\n      const imageData = new Uint8Array(img.data!);\n      const image = PdfImage.open(imageData);\n      // TODO: Currently we only support JPEG, if we expand to other\n      //       file types we need to consider multiple objects pe rimage\n      const imageObj = image.toObjects(this._nextObjNo)[0];\n      if (this._polyglot) {\n        const imgPreambleSize = this._getSerializedSize(imageObj, true);\n        const filename = `img/canvas-${canvasIdx}-${imgIdx}.jpg`;\n        this._insertZipHeaderDummyObject({\n          filename,\n          data: imageData,\n          bytesUntilActualData: imgPreambleSize,\n        });\n        imageObj.num = this._nextObjNo;\n      }\n      this._nextObjNo += 1;\n      this._objects.push(imageObj);\n    }\n\n    if (images.some((i) => i?.choiceInfo?.optional)) {\n      log.debug('Creating optional content groups for page');\n      for (const [idx, img] of images.entries()) {\n        const imageId = `/Im${idx + 1}`;\n        if (!img?.choiceInfo) {\n          continue;\n        }\n        if (isImageFetchFailure(img)) {\n          // Dummy object to maintain precalculated object numbers\n          this._addObject({});\n          continue;\n        }\n        optionalGroupObjectNums[imageId] = this._nextObjNo;\n        this._addObject({\n          Type: '/OCG',\n          Name: img.choiceInfo.label\n            ? `(${getI18nValue(img.choiceInfo.label, this._langPref, '/')})`\n            : undefined,\n          Intent: '/View',\n          Usage: img.choiceInfo.visibleByDefault ? '/ON' : '/OFF',\n        } as PdfDictionary);\n      }\n    }\n\n    const canvasInfo = this._canvasInfos[canvasIdx];\n    if (ocrText?.markup) {\n      const canvasIdx = this._canvasInfos.findIndex(\n        (ci) => ci.canvas.id === canvasId\n      );\n      let filename = `ocr/canvas-${canvasIdx}`;\n      if (ocrText.mimeType.indexOf('html') >= 0) {\n        filename += '.html';\n      } else {\n        filename += '.xml';\n      }\n\n      await this._embedResource(\n        ocrText.id,\n        filename,\n        `OCR for canvas #${canvasIdx}`,\n        ocrText.mimeType,\n        ocrText.markup\n      );\n    } else if (canvasInfo.ocr) {\n      // Canvas Info says we have OCR, but none was passed, possible\n      // when he OCR doesn't have CORS or fetching failed for another reason\n      // Add two empty objects so object references are still valid\n      this._addObject({});\n      this._addObject({});\n      // Add one more if we have a polyglot PDF/ZIP\n      if (this._polyglot) {\n        this._addObject({});\n      }\n    }\n\n    // Add annotations, if present\n    if (annotations && annotations.length > 0) {\n      log.debug('Creating annotations for page');\n      pageDict.Annots = annotations\n        .flatMap((anno) => exportPdfAnnotation(anno, unitScale, canvasHeight))\n        .map((pdfAnno) => makeRef(this._addObject(pdfAnno)));\n    }\n\n    // Write out all of the objects\n    log.debug('Flushing data for page');\n    await this._flush();\n    log.debug('Finished rendering page');\n  }\n\n  /** Get PDF instructions to render a hidden text layer with the page's OCR.\n   *\n   * This owes *a lot* to Tesseract's PDF renderer[1] and the IA's `pdf-tools`[2]\n   * that ported it to Python. Accordingly, the license of this method is Apache 2.0.\n   *\n   * [1] https://github.com/tesseract-ocr/tesseract/blob/5.0.0-beta-20210916/src/api/pdfrenderer.cpp\n   * [2] https://github.com/internetarchive/archive-pdf-tools/blob/master/internetarchivepdf/pdfrenderer.py\n   *\n   *                            Apache License\n   *                     Version 2.0, January 2004\n   *                  http://www.apache.org/licenses/\n   */\n  _renderOcrText(ocr: OcrPageWithMarkup, unitScale: number): string {\n    // TODO: Handle changes in writing direction!\n    // TODO: Handle baselines, at least the simple ``cx+d` skewed-line-type, proper polyline support\n    //       requires a per-character transformation matrix, which is a bit much for the current\n    //       MVP-ish state\n    const pageHeight = ocr.height;\n    const ops: Array<string> = [];\n    ops.push('BT'); // Begin text rendering\n    ops.push('3 Tr'); // Use \"invisible ink\" (no fill, no stroke)\n    const pageObjNum = this._nextObjNo - 1;\n    let lineIdx = 0;\n    const entries: StructTreeEntry[] = [];\n    const handleChild = (\n      child: OcrPage | OcrBlock | OcrParagraph | OcrLine,\n      parent?: StructTreeEntry\n    ) => {\n      if (child.type === 'block') {\n        entries.push({\n          type: 'Sect',\n          children: [],\n          pageObjNum,\n          mcs: [],\n        });\n      } else if (child.type === 'paragraph') {\n        entries.push({\n          type: 'P',\n          children: [],\n          pageObjNum,\n          mcs: [],\n        });\n        if (parent) {\n          parent.children.push(entries.slice(-1)[0]);\n        }\n      } else if (child.type === 'line') {\n        ops.push(\n          ...this.renderOcrLine(\n            child,\n            lineIdx,\n            unitScale,\n            pageHeight,\n            pageObjNum\n          )\n        );\n        if (parent) {\n          parent.children.push({\n            type: 'Span',\n            children: [],\n            pageObjNum,\n            mcs: [lineIdx],\n          });\n        }\n        lineIdx++;\n        return;\n      }\n      for (const grandchild of child.children) {\n        handleChild(grandchild, entries.slice(-1)[0]);\n      }\n    };\n    handleChild(ocr);\n    this._strucTree.push(...entries);\n    ops.push('ET');\n    return ops.join('\\n');\n  }\n\n  renderOcrLine(\n    line: OcrLine,\n    lineIdx: number,\n    unitScale: number,\n    pageHeight: number,\n    pageObjNum: number\n  ): string[] {\n    const fontRef = '/f-0-0';\n    const scaleX = 1;\n    const scaleY = 1;\n    const shearX = 0;\n    const shearY = 0;\n    const ops: Array<string> = [];\n    // Begin of marked content sequence that wraps the line in a Span\n    ops.push(`/Span << /MCID ${lineIdx} >> BDC`);\n    // Approximated font size for western scripts, PDF font size is specified in multiples of\n    // 'user units', which default to 1/72inch. The `userScale` gives us the units per pixel.\n    const fontSize = line.height * unitScale * 0.75;\n    //const fontSize = 8; // TODO: This is what Tesseract uses, why does this work?\n    ops.push(`${fontRef} ${fontSize} Tf`);\n    // We use a text matrix for every line. Tesseract uses a per-paragraph matrix, but we don't\n    // neccesarily have block/paragraph information available, so we'll use the next-closest\n    // thing. This means that every word on the line is positioned relative to the line, not\n    // relative to the page as in the markup.\n    const xPos = line.x * unitScale;\n    const lineY = pageHeight - line.y - line.height * 0.75;\n    const yPos = lineY * unitScale;\n    ops.push(`${scaleX} ${shearX} ${shearY} ${scaleY} ${xPos} ${yPos} Tm`);\n    let xOld = 0;\n    let yOld = 0;\n    // TODO: What to do if non-word line content?\n    for (const word of line.words) {\n      if (!word.text) {\n        continue;\n      }\n      if (!word.width) {\n        continue;\n      }\n      // Position drawing with relative moveto\n      const wordX = (word.x - line.x) * unitScale;\n      // Convert beween different y-origins in OCR and PDF\n      const wordYAbsolute = pageHeight - word.y - word.height * 0.75;\n      const wordY = (wordYAbsolute - lineY) * unitScale;\n      const wordWidth = word.width * unitScale;\n      const wordHeight = word.height * unitScale;\n      const dx = wordX - xOld;\n      const dy = wordY - yOld;\n      ops.push(`${dx * scaleX + dy * shearX} ${dx * shearY + dy * scaleY} Td`);\n      xOld = wordX;\n      yOld = wordY;\n      // Calculate horizontal stretch\n      // TODO: This is ripped straight from Tesseract, I have no clue what it does\n      // FIXME: The end of the line seems to be too far to the left sometimes,\n      // while the start seems to match\n      const wordLength = Math.pow(\n        Math.pow(wordWidth, 2) + Math.pow(wordHeight, 2),\n        0.5\n      );\n      const pdfWordLen = word.text.length;\n      ops.push(\n        `${CHAR_WIDTH * ((100 * wordLength) / (fontSize * pdfWordLen))} Tz`\n      );\n      // TODO: Account for trailing space in width calculation to prevent readers\n      //       from inserting a line break\n      const textBytes = serialize(toUTF16BE(word.text + ' ', false));\n      ops.push(`[ ${textBytes} ] TJ`);\n    }\n    ops.push('EMC');\n    // Add a newline to visually group together all statements belonging to a line\n    ops.push('');\n    if (!this._pageMCIds.has(pageObjNum)) {\n      this._pageMCIds.set(pageObjNum, []);\n    }\n    this._pageMCIds.get(pageObjNum)!.push(lineIdx);\n    return ops;\n  }\n\n  get bytesWritten(): number {\n    return this._offset;\n  }\n\n  /** Number of objects needed to render all canvases */\n  get totalCanvasObjects(): number {\n    // Every canvas needs 1 object per image, 1 for the content stream and 1 for the page definition.\n    return this._canvasInfos.reduce(\n      (sum, _, idx) => sum + this.getCanvasObjectNumber(idx),\n      0\n    );\n  }\n\n  getObjectsPerCanvas(canvasIdx: number): number {\n    const { images, ocr, numAnnotations } = this._canvasInfos[canvasIdx];\n    let numObjects =\n      // 1 XObject per image\n      images.length +\n      // Page dictionary and content\n      2 +\n      // 1 Optional Content Group per optional image\n      images.filter((i) => i.choiceInfo !== undefined).length +\n      // 1 XObject per annotation\n      numAnnotations;\n    if (this._polyglot) {\n      // For a polyglot PDF, we need to precede every XObject that we'd like\n      // to expose as a file in the ZIP with a separate XObject that contains\n      // the local ZIP header for that file. Currently this concerns the\n      // images and the OCR data\n      numObjects = numObjects + images.length + (ocr ? 1 : 0);\n    }\n    if (ocr) {\n      numObjects += 2;\n    }\n    return numObjects;\n  }\n\n  getCanvasObjectNumber(canvasIdx: number): number {\n    let num = this._firstPageObjectNum!;\n    for (const [idx] of this._canvasInfos.entries()) {\n      if (idx === canvasIdx) {\n        return num;\n      }\n      num += this.getObjectsPerCanvas(idx);\n    }\n    throw new Error(`Canvas #${canvasIdx} not found.`);\n  }\n\n  async _flush(): Promise<void> {\n    if (this._offsets.length === 0) {\n      log.debug('Writing PDF header');\n      await this._write(`%PDF-1.5\\n%\\xde\\xad\\xbe\\xef\\n`);\n    }\n    for (const obj of this._objects) {\n      if (!obj) {\n        continue;\n      }\n      log.debug(`Serializing object #${obj.num}`);\n      await this._serializeObject(obj);\n    }\n    this._objects = [];\n  }\n\n  _getSerializedSize(\n    { num, data, stream }: PdfObject,\n    untilStreamStart = false\n  ): number {\n    let size = 0;\n    size += `${num} 0 obj\\n`.length;\n\n    if (data) {\n      size += serialize(data).length;\n    }\n    if (stream) {\n      size += '\\nstream\\n'.length;\n      if (untilStreamStart) {\n        return size;\n      }\n      if (typeof stream === 'string') {\n        size += textEncoder.encode(stream).byteLength;\n      } else {\n        size += stream.byteLength;\n      }\n      size += '\\nendstream'.length;\n    }\n    size += '\\nendobj\\n'.length;\n    return size;\n  }\n\n  async _serializeObject(obj: PdfObject): Promise<void> {\n    this._offsets.push(this._offset);\n    const { num, data, stream } = obj;\n    await this._write(`${num} 0 obj\\n`);\n    if (data) {\n      await this._write(serialize(data));\n    }\n    if (stream) {\n      await this._write('\\nstream\\n');\n      await this._write(stream);\n      await this._write('\\nendstream');\n    }\n    await this._write('\\nendobj\\n');\n  }\n\n  async _write(data: Uint8Array | string): Promise<void> {\n    if (this._writer === undefined) {\n      throw new Error(\n        'Cannot perform mutating operations on an already closed PDFGenerator.'\n      );\n    }\n    if (typeof data === 'string') {\n      data = textEncoder.encode(data);\n    }\n    this._offset += data.byteLength;\n    await this._writer.write(data);\n  }\n\n  async _writeStructureTree(): Promise<void> {\n    const parentRoot: PdfDictionary = {\n      Nums: [],\n    };\n    const parentRootRef = makeRef(this._addObject(parentRoot));\n    const root: PdfDictionary = {\n      Type: '/StructTreeRoot',\n      K: [],\n      ParentTree: parentRootRef,\n      ParentTreeNextKey: this._nextStructParentId,\n    };\n    const pageParents: Map<number, Array<PdfRef>> = new Map();\n    const rootRef = makeRef(this._addObject(root));\n    const visitEntry = async (\n      entry: StructTreeEntry,\n      parent: PdfDictionary,\n      parentRef: PdfRef\n    ): Promise<void> => {\n      const obj: PdfDictionary = {\n        Type: '/StructElem',\n        S: `/${entry.type}`,\n        P: parentRef,\n        Pg: makeRef(entry.pageObjNum),\n        K: [],\n      };\n      if (!pageParents.has(entry.pageObjNum)) {\n        pageParents.set(entry.pageObjNum, []);\n      }\n      const objRef = makeRef(this._addObject(obj));\n      (parent.K as PdfRef[]).push(objRef);\n      if (entry.children.length > 0) {\n        for (const i of entry.children) {\n          await visitEntry(i, obj, objRef);\n        }\n      } else if (entry.mcs.length == 1) {\n        obj.K = entry.mcs[0];\n      } else if (entry.mcs.length > 0) {\n        obj.K = entry.mcs;\n      }\n      if (entry.mcs.length > 0) {\n        const parents = pageParents.get(entry.pageObjNum)!;\n        for (const mcId of entry.mcs) {\n          parents[mcId] = objRef;\n        }\n      }\n      if (this._objects.length > 1000) {\n        await this._flush();\n      }\n    };\n    for (const i of this._strucTree) {\n      await visitEntry(i, root, rootRef);\n    }\n    for (const [pageObjNum, parents] of pageParents) {\n      const pidx = this._pageParentIds.get(pageObjNum)!;\n      (parentRoot.Nums as PdfArray).push(\n        pidx,\n        makeRef(this._addObject(parents))\n      );\n    }\n    await this._flush();\n  }\n\n  async end(): Promise<void> {\n    if (!this._writer) {\n      return;\n    }\n    /* FIXME: Disabled due to poor performance on large volumes and a strange\n     *        interaction with streamsaver, where the PDF would be prematurely\n     *        closed in the middle of writing out the structure tree.\n    console.debug(\"Writing structure tree\");\n    if (this._strucTree.length > 0) {\n      await this._writeStructureTree();\n    }\n    */\n    log.debug('Writing xref table');\n    type XrefEntry = [number, number, 'f' | 'n'];\n    const xrefEntries: Array<XrefEntry> = [\n      [0, 65535, 'f'],\n      ...this._offsets.map((offset): XrefEntry => [offset, 0, 'n']),\n    ];\n    const xRefTable = xrefEntries\n      .map(([off, gen, free]) =>\n        [\n          off.toString(10).padStart(10, '0'),\n          gen.toString(10).padStart(5, '0'),\n          free,\n          '',\n        ].join(' ')\n      )\n      .join('\\n');\n    const xrefOffset = this._offset;\n    await this._write(`xref\\n0 ${xrefEntries.length}\\n${xRefTable}\\n`);\n    const trailerDict: PdfDictionary = {\n      Size: xrefEntries.length,\n      Root: this._objRefs.Catalog,\n      Info: this._objRefs.Info,\n      ID: [randomData(32), randomData(32)],\n    };\n    await this._write(`\\ntrailer\\n${serialize(trailerDict)}`);\n    const trailer = `startxref\\n${xrefOffset}\\n%%EOF`;\n    if (this._polyglot && this._zipCatalog) {\n      log.debug('Writing zip end of central directory');\n      await this._write('9990 0 obj\\n<<>>\\nstream\\n');\n      const endObj = '\\nendstream\\nendobj\\n';\n      await this._write(\n        buildCentralFileDirectory({\n          files: this._zipCatalog,\n          trailingLength: trailer.length + endObj.length,\n          offset: this._offset,\n        })\n      );\n      await this._write(endObj);\n    }\n    await this._flush();\n    log.debug('Writing trailer');\n    await this._write(trailer);\n    log.debug('Flushing');\n    await this._flush();\n    // FIXME: Never resolves on Node.js, is it really\n    // needed in browsers?\n    //log.debug('Waiting for drainage');\n    //await this._writer.waitForDrain();\n    log.debug('PDF finished, closing writer');\n    await this._writer.close();\n    log.debug('Writer closed');\n    this._writer = undefined;\n  }\n\n  private _insertZipHeaderDummyObject({\n    filename,\n    data,\n    deflatedData,\n    bytesUntilActualData,\n  }: ZipDummyObjectSpec): void {\n    if (this._zipBaseDir) {\n      filename = `${this._zipBaseDir}/${filename}`;\n    }\n    const zipObjOffset =\n      this._offset +\n      this._objects.reduce((acc, obj) => acc + this._getSerializedSize(obj), 0);\n    const creationDate = new Date();\n    bytesUntilActualData += '\\nendstream\\nendobj\\n'.length;\n    const zipObj = this._addObject(\n      {},\n      undefined,\n      buildLocalZipHeader({\n        filename,\n        data,\n        compressedData: deflatedData,\n        extraDataLength: bytesUntilActualData,\n        creationDate,\n      })\n    );\n    const localHeaderOffset =\n      zipObjOffset + this._getSerializedSize(zipObj, true);\n    if (!this._zipCatalog) {\n      this._zipCatalog = [];\n    }\n    this._zipCatalog.push({\n      localHeaderOffset,\n      deflated: deflatedData?.length !== data.length,\n      creationDate: new Date(),\n      crc32: crc32(data),\n      dataLength: data.length,\n      // skip 2 bytes for zlib header\n      compressedDataLength: deflatedData\n        ? deflatedData.length - 2\n        : data.length,\n      filename,\n    });\n  }\n}\n","import util from 'util';\nimport zlib from 'zlib';\nimport { zlibSync } from 'fflate';\nimport nodeCrypto from 'crypto';\n\nimport { StartCanvasInfo } from '../download.js';\nimport { PdfDictionary } from './common.js';\nimport log from '../log.js';\nimport { runningInNode } from '../util.js';\n\n// Browsers have native encoders/decoders in the global namespace, use these\nexport let textEncoder: TextEncoder | util.TextEncoder;\nexport let textDecoder: TextDecoder | util.TextDecoder;\nif (typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined') {\n  textEncoder = new TextEncoder();\n  textDecoder = new TextDecoder();\n} else {\n  textEncoder = new util.TextEncoder();\n  textDecoder = new util.TextDecoder();\n}\n\n// If running in node, use the web compatible crypto implementation\nlet cryptoImpl: Crypto;\nif (runningInNode()) {\n  cryptoImpl = nodeCrypto.webcrypto as Crypto;\n} else {\n  cryptoImpl = crypto;\n}\n\nexport const IS_BIG_ENDIAN = (() => {\n  const array = new Uint8Array(4);\n  const view = new Uint32Array(array.buffer);\n  return !((view[0] = 1) & array[0]);\n})();\n\nexport interface TocItem {\n  label: string;\n  children?: Array<TocItem>;\n  startCanvas: StartCanvasInfo;\n}\n\nexport function getNumChildren(itm: TocItem): number {\n  const children = itm.children ?? [];\n  return (\n    children.length + children.map(getNumChildren).reduce((a, b) => a + b, 0)\n  );\n}\n\nexport function randomData(length: number): Uint8Array {\n  if (length > 2 ** 16) {\n    length = 2 ** 16;\n  }\n  const buf = new Uint8Array(length);\n  if (cryptoImpl !== undefined) {\n    cryptoImpl.getRandomValues(buf);\n  } else {\n    const u32View = new Uint32Array(buf.buffer);\n    for (let i = 0; i < u32View.length; i++) {\n      u32View[i] = Math.floor(Math.random() * 2 ** 32);\n    }\n  }\n  return buf;\n}\n\nexport async function tryDeflateStream(\n  pdfStream: Uint8Array | string\n): Promise<{ stream: Uint8Array | string; dict: PdfDictionary }> {\n  const data =\n    pdfStream instanceof Uint8Array ? pdfStream : textEncoder.encode(pdfStream);\n  let compressed: Uint8Array;\n  if (!runningInNode()) {\n    if (typeof CompressionStream === 'undefined') {\n      // Browser doesn't support CompressionStream API, try to use the JS implementation\n      try {\n        let bytes: Uint8Array;\n        if (pdfStream instanceof Uint8Array) {\n          bytes = pdfStream;\n        } else {\n          bytes = textEncoder.encode(pdfStream);\n        }\n        compressed = zlibSync(bytes);\n        return Promise.resolve({\n          stream: compressed,\n          dict: { Length: compressed.length, Filter: '/FlateDecode' },\n        });\n      } catch (err) {\n        log.warn(\n          `Failed to use JS deflate implementation, data will be written uncompressed: ${err}`\n        );\n        return Promise.resolve({\n          stream: pdfStream,\n          dict: { Length: pdfStream.length },\n        });\n      }\n    }\n    const compStream = new CompressionStream('deflate');\n    const c = new Blob([data]).stream().pipeThrough(compStream);\n    compressed = new Uint8Array(await new Response(c).arrayBuffer());\n  } else {\n    compressed = await new Promise((resolve, reject) =>\n      zlib.deflate(data, (err, buf) => (err ? reject(err) : resolve(buf)))\n    );\n  }\n  return {\n    dict: {\n      Length: compressed.length,\n      Filter: '/FlateDecode',\n    },\n    stream: compressed,\n  };\n}\n","import { IS_BIG_ENDIAN } from './util.js';\n\nconst PDF_INDENTATION = 2;\n\nexport interface Metadata {\n  Producer?: string;\n  Creator?: string;\n  CreationDate?: Date;\n  Title?: string;\n  Author?: string;\n  Keywords?: string;\n  ModDate?: Date;\n}\n\nexport interface PdfObject {\n  num: number;\n  data?: PdfValue;\n  stream?: Uint8Array | string;\n}\n\nexport class PdfRef {\n  refObj: number;\n\n  constructor(num: number) {\n    this.refObj = num;\n  }\n}\nexport type PdfPrimitive =\n  | string\n  | number\n  | boolean\n  | Uint8Array\n  | null\n  | Date\n  | PdfRef;\nexport interface PdfDictionary {\n  [member: string]: PdfPrimitive | PdfArray | PdfDictionary;\n}\nexport type PdfArray = Array<PdfPrimitive | PdfArray | PdfDictionary>;\nexport type PdfValue = PdfPrimitive | PdfDictionary | PdfArray | null;\n\nexport interface PdfAnnotation {\n  Type: 'Annot';\n  Subtype: string;\n  Rect: [number, number, number, number];\n  Contents: string | undefined;\n  P?: PdfRef;\n  NM?: string;\n  M?: Date;\n  F?: number;\n  AP?: PdfDictionary;\n  AS?: string;\n  Border?: [number, number, number] | [number, number, number, number];\n  C?:\n    | []\n    | [number]\n    | [number, number, number]\n    | [number, number, number, number];\n}\n\nexport interface StructTreeEntry {\n  type: 'Sect' | 'P' | 'Span';\n  children: Array<StructTreeEntry>; // Only for `Sect` and `P` entries\n  pageObjNum: number;\n  mcs: Array<number>; // Only for `Span` entries\n}\n\nexport function makeRef(target: number | PdfObject): PdfRef {\n  const num = typeof target === 'number' ? target : target.num;\n  return new PdfRef(num);\n}\n\nfunction isUnicode(str: string): boolean {\n  for (let i = 0, end = str.length; i < end; i++) {\n    if (str.charCodeAt(i) > 0x7f) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/** Convert a JS UTF8 string to a UTF16 Big Endian string */\nexport function toUTF16BE(str: string, includeBom = true): Uint8Array {\n  const buf = new Uint16Array(str.length + (includeBom ? 1 : 0));\n  for (let i = includeBom ? 1 : 0; i < buf.length; i++) {\n    buf[i] = str.charCodeAt(i - (includeBom ? 1 : 0));\n  }\n  const outBuf = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n  if (!IS_BIG_ENDIAN) {\n    // PDF needs UTF16-BE, so in little endian systems we need to swap each\n    // codepoint's byte pair\n    for (let i = includeBom ? 2 : 0, end = outBuf.length - 1; i < end; i += 2) {\n      const a = outBuf[i];\n      outBuf[i] = outBuf[i + 1];\n      outBuf[i + 1] = a;\n    }\n  }\n  // UTF16BE BOM\n  if (includeBom) {\n    outBuf[0] = 254;\n    outBuf[1] = 255;\n  }\n  return outBuf;\n}\n\nfunction safeNumber(num: number): number {\n  if (num > -1e21 && num < 1e21) {\n    return Math.round(num * 1e6) / 1e6;\n  }\n  throw new Error(`unsupported number: ${num}`);\n}\n\nexport function serialize(value: PdfValue, dictIndent = 0): string {\n  if (typeof value === 'string') {\n    if (\n      value[0] === '(' &&\n      value[value.length - 1] === ')' &&\n      isUnicode(value)\n    ) {\n      return serialize(toUTF16BE(value.substring(1, value.length - 1)));\n    }\n    return value;\n  } else if (value instanceof Uint8Array) {\n    return `<${Array.from(value)\n      .map((x) => x.toString(16).padStart(2, '0').toUpperCase())\n      .join('')}>`;\n  } else if (value instanceof Date) {\n    const dateString =\n      `D:${value.getUTCFullYear().toString(10).padStart(4, '0')}` +\n      (value.getUTCMonth() + 1).toString(10).padStart(2, '0') +\n      value.getUTCDate().toString(10).padStart(2, '0') +\n      value.getUTCHours().toString(10).padStart(2, '0') +\n      value.getUTCMinutes().toString(10).padStart(2, '0') +\n      value.getUTCSeconds().toString(10).padStart(2, '0') +\n      'Z';\n    return `(${dateString})`;\n  } else if (Array.isArray(value)) {\n    return `[${value.map((v) => serialize(v, dictIndent + 1)).join(' ')}]`;\n  } else if (value instanceof PdfRef) {\n    return `${value.refObj} 0 R`;\n  } else if ({}.toString.call(value) === '[object Object]') {\n    const outsideIndent = ' '.repeat(PDF_INDENTATION * dictIndent);\n    const insideIndent = outsideIndent + ' '.repeat(PDF_INDENTATION);\n    return `<<\\n${Object.entries(value as any)\n      .map(\n        ([k, v]) =>\n          `${insideIndent}/${k} ${serialize(v as any, dictIndent + 1)}`\n      )\n      .join('\\n')}\\n${outsideIndent}>>`;\n  } else if (typeof value === 'number') {\n    return safeNumber(value).toString(10);\n  } else {\n    return `${value}`;\n  }\n}\n","/** Types for writing to an output stream, with support for Node and Browsers. */\nimport type { Writable as NodeWritable } from 'stream';\nimport type nodeFs from 'fs';\n\nimport log from './log.js';\n\n/** Base interface to be implemented by all readers.  */\nexport interface Reader {\n  read(\n    dst: Uint8Array,\n    offset: number,\n    position: number,\n    length: number\n  ): Promise<number>;\n  size(): Promise<number>;\n}\n\n/** Base interface to be implemented by all writers. */\nexport interface Writer {\n  /** Write a chunk to the writer */\n  write(buffer: Uint8Array | string): Promise<void>;\n\n  /** Close the writer */\n  close(): Promise<void>;\n\n  /** Wait for the next drainage/flush event */\n  waitForDrain(): Promise<void>;\n}\n\n/** Reader implementation using the Web `File` API.  */\nexport class WebReader implements Reader {\n  private file: File;\n\n  constructor(file: File) {\n    this.file = file;\n  }\n\n  async read(\n    dst: Uint8Array,\n    offset: number,\n    position: number,\n    length: number\n  ): Promise<number> {\n    const blob = this.file.slice(position, position + length);\n    const buf = await blob.arrayBuffer();\n    dst.set(new Uint8Array(buf), offset);\n    return buf.byteLength;\n  }\n\n  size(): Promise<number> {\n    return new Promise((resolve) => resolve(this.file.size));\n  }\n}\n\n/** Wraps a writer and counts the bytes written to it. */\nexport class CountingWriter implements Writer {\n  private _writer: Writer;\n  bytesWritten = 0;\n\n  constructor(writer: Writer) {\n    this._writer = writer;\n  }\n\n  write(buffer: string | Uint8Array): Promise<void> {\n    this.bytesWritten += buffer.length;\n    return this._writer.write(buffer);\n  }\n\n  close(): Promise<void> {\n    return this._writer.close();\n  }\n\n  waitForDrain(): Promise<void> {\n    return this._writer.waitForDrain();\n  }\n}\n\n/** A Writer implemented using the `File System Access API` available in\n *  recent Chrome, Edge and Opera browsers. */\nexport class WebWriter implements Writer {\n  private _writer: WritableStreamDefaultWriter<any>;\n\n  constructor(stream: WritableStream) {\n    this._writer = stream.getWriter();\n  }\n\n  write(buffer: string | Uint8Array): Promise<void> {\n    return this._writer.write(buffer);\n  }\n\n  waitForDrain(): Promise<void> {\n    return this._writer.ready;\n  }\n\n  close(): Promise<void> {\n    return this._writer.close();\n  }\n}\n\n\n/** Writer implementation using the `Blob` API available in all browsers. */\nexport class BlobWriter implements Writer {\n  // TODO: A good reference seems to be the mega.nz implementation, which has always worked great for me on desktops at least:\n  // https://github.com/meganz/webclient/blob/f19289127b68ceaf19a5e884f2f48f15078304da/js/transfers/meths/memory.js\n  private _parts: Array<Uint8Array | string>;\n  private _blob?: Blob;\n\n  constructor() {\n    this._parts = [];\n  }\n\n  write(buffer: string | Uint8Array): Promise<void> {\n    if (this._blob) {\n      return Promise.reject('Cannot write to closed BlobWriter.');\n    }\n    this._parts.push(buffer);\n    return Promise.resolve();\n  }\n\n  waitForDrain(): Promise<void> {\n    if (this._blob) {\n      return Promise.reject('Cannot wait on a closed BlobWriter.');\n    }\n    return Promise.resolve();\n  }\n\n  close(): Promise<void> {\n    if (this._blob) {\n      return Promise.reject('BlobWriter is already closed');\n    }\n    this._blob = new Blob(this._parts);\n    this._parts = [];\n    return Promise.resolve();\n  }\n\n  get blob(): Blob {\n    if (!this._blob) {\n      throw 'BlobWriter must be closed first!';\n    }\n    return this._blob;\n  }\n}\n\n/** Reader implentation using the node.js filesystem API. */\nexport class NodeReader implements Reader {\n  private fileHandle: nodeFs.promises.FileHandle;\n\n  constructor(handle: nodeFs.promises.FileHandle) {\n    this.fileHandle = handle;\n  }\n\n  async read(\n    dst: Uint8Array,\n    offset: number,\n    position: number,\n    length: number\n  ): Promise<number> {\n    const { bytesRead } = await this.fileHandle.read(\n      dst,\n      offset,\n      length,\n      position\n    );\n    return bytesRead;\n  }\n\n  async size(): Promise<number> {\n    const stat = await this.fileHandle.stat();\n    return stat.size;\n  }\n}\n/** Writer implementation using the node.js filesystem API. */\nexport class NodeWriter implements Writer {\n  _writable: NodeWritable;\n  _drainWaiters: Array<() => void> = [];\n\n  constructor(writable: NodeWritable) {\n    this._writable = writable;\n    this._writable.on('drain', () => {\n      log.debug('Drained writer.');\n      for (const waiter of this._drainWaiters) {\n        waiter();\n      }\n      this._drainWaiters = [];\n    });\n    this._writable.on('close', () => {\n      for (const waiter of this._drainWaiters) {\n        waiter();\n      }\n      this._drainWaiters = [];\n    });\n  }\n\n  async write(buffer: string | Uint8Array): Promise<void> {\n    let waitForDrain = false;\n    const out = new Promise<void>((resolve, reject) => {\n      if (!this._writable.writable) {\n        reject('Cannot write to closed NodeWriter.');\n      }\n      waitForDrain = !this._writable.write(buffer, (err) =>\n        err ? reject(err) : resolve()\n      );\n    });\n    if (waitForDrain) {\n      log.debug('Waiting for writer to drain');\n      return await this.waitForDrain();\n    } else {\n      return await out;\n    }\n  }\n\n  waitForDrain(): Promise<void> {\n    return new Promise((resolve) => this._drainWaiters.push(resolve));\n  }\n\n  close(): Promise<void> {\n    return new Promise((resolve) => this._writable.end(() => resolve()));\n  }\n}\n\n/** Very basic Reader implementation using an Array. */\nexport class ArrayReader implements Reader {\n  _buf: Uint8Array;\n\n  constructor(buf: Uint8Array) {\n    this._buf = buf;\n  }\n\n  read(\n    dst: Uint8Array,\n    offset: number,\n    position: number,\n    length: number\n  ): Promise<number> {\n    const sub = this._buf.subarray(position, position + length);\n    dst.set(sub, offset);\n    return Promise.resolve(sub.length);\n  }\n\n  size(): Promise<number> {\n    return Promise.resolve(this._buf.length);\n  }\n}\n","/* Based on the `images` modules in `pdfkit` by Devon Govett, licensed under MIT.\n *\n * Ported to TypeScript and modified to better fit a web use case, by using  Uint8Array\n * instead of Buffer.\n *\n * https://github.com/foliojs/pdfkit/blob/master/lib/image/jpeg.js\n *\n * MIT LICENSE\n * Copyright (c) 2011 Devon Govett\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify, merge,\n * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n * to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or\n * substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nimport { PdfDictionary, serialize, PdfObject } from './common.js';\nimport { IS_BIG_ENDIAN } from './util.js';\n\nfunction readUint16BE(buf: Uint8Array, pos = 0): number {\n  const val = new Uint16Array(buf.slice(pos, pos + 2).buffer)[0];\n  if (IS_BIG_ENDIAN) {\n    return val;\n  } else {\n    // system is little endian, swap bytes in value from buffer\n    return ((val & 0xff) << 8) | ((val >> 8) & 0xff);\n  }\n}\n\nabstract class PdfImage {\n  static open(data: Uint8Array): PdfImage {\n    if (data[0] === 0xff && data[1] === 0xd8) {\n      return new JPEGImage(data);\n    } else {\n      throw new Error('Unknown image format.');\n    }\n  }\n\n  abstract toObjects(\n    startNum: number,\n    isOptional?: boolean,\n    optionalTitle?: string,\n    optionalDefaultState?: boolean\n  ): Array<PdfObject>;\n}\n\nclass JPEGImage extends PdfImage {\n  static MARKERS = [\n    0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0xffc9,\n    0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf,\n  ];\n  static COLOR_SPACE_MAP = {\n    1: 'DeviceGray',\n    3: 'DeviceRGB',\n    4: 'DeviceCMYK',\n  };\n  data: Uint8Array;\n\n  bits: number;\n  width: number;\n  height: number;\n  colorSpace: string;\n\n  constructor(data: Uint8Array) {\n    super();\n    let marker;\n    this.data = data;\n    if (readUint16BE(this.data, 0) !== 0xffd8) {\n      throw 'SOI not found in JPEG';\n    }\n\n    let pos = 2;\n    while (pos < this.data.length) {\n      marker = readUint16BE(this.data, pos);\n      pos += 2;\n      if (JPEGImage.MARKERS.includes(marker)) {\n        break;\n      }\n      pos += readUint16BE(this.data, pos);\n    }\n\n    if (!marker || !JPEGImage.MARKERS.includes(marker)) {\n      throw 'Invalid JPEG.';\n    }\n    pos += 2;\n\n    this.bits = this.data[pos++];\n    this.height = readUint16BE(this.data, pos);\n    pos += 2;\n\n    this.width = readUint16BE(this.data, pos);\n    pos += 2;\n\n    const channels = this.data[pos++];\n    if ([1, 3, 4].indexOf(channels) < 0) {\n      throw 'Bad number of channels, only 1, 3 or 4 are supported';\n    }\n    this.colorSpace = JPEGImage.COLOR_SPACE_MAP[channels as 1 | 3 | 4];\n  }\n\n  toObjects(startNum: number): Array<PdfObject> {\n    const obj: PdfDictionary = {\n      Type: '/XObject',\n      Subtype: '/Image',\n      BitsPerComponent: this.bits,\n      Width: this.width,\n      Height: this.height,\n      ColorSpace: `/${this.colorSpace}`,\n      Filter: '/DCTDecode',\n      Length: this.data.length,\n    };\n\n    // add extra decode params for CMYK images. By swapping the\n    // min and max values from the default, we invert the colors. See\n    // section 4.8.4 of the spec.\n    if (this.colorSpace === 'DeviceCMYK') {\n      obj.Decode = [1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0];\n    }\n    return [{ num: startNum, data: serialize(obj), stream: this.data }];\n  }\n}\n\nexport default PdfImage;\n","import { Reader } from '../io.js';\nimport { PdfObject, PdfValue, PdfDictionary, PdfRef } from './common.js';\nimport { textDecoder, textEncoder } from './util.js';\n\n// Polyfill Uint8Array.findLastIndex for older browsers\nif (!Uint8Array.prototype.findLastIndex) {\n  Uint8Array.prototype.findLastIndex = function (\n    predicate: (value: number, index: number, obj: Uint8Array) => boolean\n  ): number {\n    let l = this.length;\n    while (l--) {\n      if (predicate(this[l], l, this)) return l;\n    }\n    return -1;\n  };\n}\n\nconst ESCAPE_CHARS: Record<string, string> = {\n  n: '\\n',\n  r: '\\r',\n  t: '\\t',\n  b: '\\b',\n  f: '\\f',\n  '(': '(',\n  ')': ')',\n  '\\\\': '\\\\',\n};\n\n//          offset/nextFree|generation|inUse?\n//                      ▼       ▼        ▼\ntype CrossRefEntry = [number, number, boolean];\ninterface CrossRefSubSection {\n  startNum: number;\n  numObjs: number;\n  entries: Array<CrossRefEntry>;\n}\n\n/** Parse a section of the x-ref table, yielding `CrossRefSubSection` objects as\n *  we encounter them.\n *\n * @param reader The reader to read from.\n * @param offset The offset of the x-ref section in the file.\n * @param length The length of the x-ref section.\n */\nasync function* parseCrossRefSection(\n  reader: Reader,\n  offset: number,\n  length: number\n): AsyncGenerator<CrossRefSubSection> {\n  const buf = new Uint8Array(length);\n  offset += await reader.read(buf, 0, offset, buf.length);\n  if (!testForString(buf, 0, 'xref')) {\n    throw 'Invalid crossreference section, did not start with `xref` line.';\n  }\n  const trailerIdx = buf.findIndex((_x, idx) =>\n    testForString(buf, idx, 'trailer')\n  );\n  // Split into lines and skip first line (`xref`)\n  const parts = textDecoder\n    .decode(buf.subarray(0, trailerIdx))\n    .split(/[\\r ]?\\n/)\n    .slice(1);\n  let currentSection: CrossRefSubSection | undefined;\n  for (const part of parts) {\n    // Entries have length 18 (we stripped the newline already)\n    if (part.length === 18) {\n      if (!currentSection) {\n        throw 'Invalid crossreference section, entry outside of subsection.';\n      }\n      const entryParts = part.trim().split(' ');\n      currentSection.entries.push([\n        Number.parseInt(entryParts[0], 10),\n        Number.parseInt(entryParts[1], 10),\n        entryParts[2] === 'n',\n      ]);\n    } else {\n      if (currentSection) {\n        if (currentSection.numObjs !== currentSection.entries.length) {\n          throw `Invalid subsection, expected ${currentSection.numObjs} objects, found ${currentSection.entries.length}!`;\n        }\n        yield currentSection;\n        currentSection = undefined;\n      }\n      if (part.length === 0 || part.indexOf('trailer') >= 0) {\n        break;\n      }\n      const [startNum, numObjs] = part\n        .trimEnd()\n        .split(' ')\n        .map((p) => Number.parseInt(p, 10));\n      currentSection = {\n        startNum,\n        numObjs,\n        entries: [],\n      };\n    }\n  }\n  if (currentSection) {\n    yield currentSection;\n  }\n  const trailerBuf = buf.subarray(trailerIdx);\n  const trailerStartIdx = trailerBuf.findIndex((_x, idx) =>\n    testForString(trailerBuf, idx, '<<')\n  );\n  const trailerEndIdx = trailerBuf.findIndex((_x, idx) =>\n    testForString(trailerBuf, idx, '>>')\n  );\n\n  const trailerDict = new PdfValueParser(\n    trailerBuf.subarray(trailerStartIdx, trailerEndIdx + 2)\n  ).read() as PdfDictionary;\n  if (trailerDict.Prev) {\n    const previousXrefOffset = trailerDict.Prev as number;\n    yield* parseCrossRefSection(\n      reader,\n      previousXrefOffset,\n      offset - previousXrefOffset\n    );\n  }\n}\n\n/** Look for a string from a given location in a buffer. */\nfunction testForString(\n  buf: Uint8Array,\n  offset: number,\n  value: string,\n  backwards = false\n): boolean {\n  if (backwards) {\n    for (let idx = value.length - 1; idx >= 0; idx--) {\n      if (buf[offset + idx] !== value.charCodeAt(idx)) {\n        return false;\n      }\n    }\n  } else {\n    for (let idx = 0; idx < value.length; idx++) {\n      if (buf[offset + idx] !== value.charCodeAt(idx)) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\n/** Check if a string is the representation of an integer digit */\nfunction isDigit(c: string): boolean {\n  return !isNaN(parseInt(c, 10));\n}\n\n/** Check if a character is a hexadecimal digit ([0-9a-fA-F])  */\nfunction isHex(c: number): boolean {\n  return (\n    (c >= 0x30 && c <= 0x39) ||\n    (c >= 0x41 && c <= 0x46) ||\n    (c >= 0x61 && c <= 0x66)\n  );\n}\n\n/** Parse a PDF \"value\", which can be one of:\n * - number (integer or float)\n * - string\n * - name (represented as a JS string starting with `/`)\n * - boolean\n * - null\n * - date\n * - XRef\n * - Array\n * - Dictionary\n *\n * API walkthrough:\n * - `read()` is the main entry point, it will read the next value from the\n *   buffer and advance the cursor\n *  - `match*` methods check if the buffer at the current offset matches a\n *    certain type of value, either returning a boolean or the section of the\n *    buffer containing the value as a string.\n *  - `read*` methods read a value of a specific type from the buffer and\n *    advance the cursor\n */\nexport class PdfValueParser {\n  start = 0;\n  current = 0;\n  private readonly buf: Uint8Array;\n\n  /** Construct a parser for a buffer containing one or more PDF values. */\n  constructor(buf: Uint8Array) {\n    this.buf = buf;\n  }\n\n  /** Get the buffer content at the current offset as a character. */\n  private getChar(): string {\n    return String.fromCharCode(this.buf[this.current]);\n  }\n\n  /** Compares the buffer contents at the current offset against a string value. */\n  private matchValue(value: string): boolean {\n    const valueRead = textDecoder.decode(\n      this.buf.subarray(\n        this.current,\n        this.current + textEncoder.encode(value).length\n      )\n    );\n    return valueRead === value;\n  }\n\n  /** Checks if the buffer at the current offset contains a number.\n   *\n   * See ISO32000-2:2020 section 7.3.3.\n   */\n  private matchInteger(resetAfter = true): string | undefined {\n    this.start = this.current;\n    let chr: string;\n    let isInt = true;\n    const chars: string[] = [];\n    while (\n      !this.matchWhiteSpace((chr = this.getChar())) &&\n      !this.matchDelimiter(chr)\n    ) {\n      if (chr === '+' || chr === '-') {\n        if (this.current - this.start > 0) {\n          isInt = false;\n          break;\n        }\n      } else if (!isDigit(chr)) {\n        isInt = false;\n        break;\n      }\n      this.current++;\n      chars.push(chr);\n    }\n    if (resetAfter) {\n      this.current = this.start;\n    }\n    return isInt ? chars.join('') : undefined;\n  }\n\n  /** Read a PDF value from the current offset, advancing the cursor. */\n  read(): PdfValue {\n    let c = this.getChar();\n    if (this.matchWhiteSpace(c)) {\n      this.skipWhiteSpace();\n      c = this.getChar();\n    }\n    switch (this.getChar()) {\n      case '[':\n        return this.readArray();\n      case '<':\n        return this.matchValue('<<') ? this.readDict() : this.readHexString();\n      case '(':\n        return this.readLiteralString();\n      case '/':\n        return this.readName();\n      case 't':\n        if (this.matchValue('true')) {\n          this.current += 'true'.length;\n          return true;\n        }\n        throw new Error('Unexpected character while parsing');\n      case 'f':\n        if (this.matchValue('false')) {\n          this.current += 'false'.length;\n          return false;\n        }\n        throw new Error('Unexpected character while parsing');\n      case 'n':\n        if (this.matchValue('null')) {\n          this.current += 'null'.length;\n          return null;\n        }\n        throw new Error('Unexpected character while parsing');\n      case '.':\n        return this.readRealNumber();\n      default:\n        if (this.matchIndirectObject()) {\n          return this.readIndirectObject();\n        }\n        if (this.matchRealNumber()) {\n          return this.readRealNumber();\n        }\n        if (this.matchInteger()) {\n          return this.readInteger();\n        }\n        throw new Error(\n          `Encountered unexpected character during parsing: '${c}'`\n        );\n    }\n  }\n\n  /** Check if the input string contains PDF whitespace.\n   *\n   * See ISO32000-2:2020 section 7.2.3, Table 1.\n   */\n  matchWhiteSpace(c: string): boolean {\n    return (\n      c === ' ' ||\n      c === '\\x00' ||\n      c === '\\n' ||\n      c === '\\r' ||\n      c === '\\r\\n' ||\n      c == '\\x0C'\n    );\n  }\n\n  /** Read an integer from the current offset. */\n  readInteger(): number {\n    const intStr = this.matchInteger(false);\n    if (intStr === undefined) {\n      throw new Error('Failed to read integer.');\n    }\n    return Number.parseInt(intStr, 10);\n  }\n\n  /** Read an indirect object from the current offset. */\n  readIndirectObject(): PdfRef {\n    const match = this.matchIndirectObject(false);\n    if (match === undefined) {\n      throw new Error('Failed to read indirect object');\n    }\n    return new PdfRef(Number.parseInt(match.split(' ')[0]));\n  }\n\n  /** Check if the buffer contains an indirect object at the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.10.\n   */\n  matchIndirectObject(resetAfter = true): string | undefined {\n    this.start = this.current;\n    let c = this.getChar();\n    const chars: string[] = [];\n    const matchNumber = (): boolean => {\n      if (!isDigit(c)) {\n        return false;\n      }\n      chars.push(c);\n      this.current++;\n      while (isDigit((c = this.getChar()))) {\n        chars.push(c);\n        this.current++;\n      }\n      return true;\n    };\n    const matchWhitespace = (): boolean => this.skipWhiteSpace();\n    // Using a closure makes resetting afterwards less verbose\n    const match = (): boolean => {\n      // Object number\n      if (!matchNumber()) {\n        return false;\n      }\n      if (!matchWhitespace()) {\n        return false;\n      }\n      chars.push(' ');\n      c = this.getChar();\n      // Generation number\n      if (!matchNumber()) {\n        return false;\n      }\n      if (!matchWhitespace()) {\n        return false;\n      }\n      chars.push(' ');\n      if (this.getChar() !== 'R') {\n        return false;\n      }\n      chars.push('R');\n      this.current++;\n      return true;\n    };\n    const doesMatch = match();\n    if (resetAfter) {\n      this.current = this.start;\n    }\n    if (doesMatch) {\n      return chars.join('');\n    }\n  }\n\n  /** Check if the buffer contains a real number at the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.3.\n   */\n  matchRealNumber(resetAfter = true): string | undefined {\n    this.start = this.current;\n    let isRealNumber = true;\n    let digitSeen = false;\n    let separatorSeen = false;\n    const chars: string[] = [];\n    let c: string;\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      c = this.getChar();\n      if (c === '.') {\n        if (separatorSeen) {\n          isRealNumber = false;\n          break;\n        }\n        separatorSeen = true;\n      } else if (isDigit(c)) {\n        digitSeen = true;\n      } else if (c === '-' || c === '+') {\n        if (this.current - this.start > 0) {\n          break;\n        }\n      } else {\n        break;\n      }\n      chars.push(c);\n      this.current++;\n    }\n    if (resetAfter) {\n      this.current = this.start;\n    }\n    if (!isRealNumber) {\n      return undefined;\n    }\n    if (digitSeen && separatorSeen) {\n      return chars.join('');\n    }\n    return undefined;\n  }\n\n  /** Read a real number from the current offset. */\n  readRealNumber(): number {\n    const str = this.matchRealNumber(false);\n    if (!str) {\n      throw new Error('Could not read real number.');\n    }\n    return Number.parseFloat(str);\n  }\n\n  /** Skip a contiguous sequence of whitespae, advancing the cursor. */\n  skipWhiteSpace(): boolean {\n    let skipped = false;\n    while (!this.atEnd() && this.matchWhiteSpace(this.getChar())) {\n      this.current++;\n      skipped = true;\n    }\n    return skipped;\n  }\n\n  /** Check if we're at the end of the buffer. */\n  atEnd(): boolean {\n    return this.current >= this.buf.length;\n  }\n\n  /** Read a name from the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.5.\n   */\n  readName(): PdfValue {\n    const chars: string[] = ['/'];\n    this.current++;\n    let c: string;\n    while (\n      !this.matchWhiteSpace((c = this.getChar())) &&\n      !this.matchDelimiter(c)\n    ) {\n      if (c === '#') {\n        const a = this.buf[this.current++];\n        const b = this.buf[this.current++];\n        if (!isHex(a) || !isHex(b)) {\n          throw new Error('Illegal character escape in name.');\n        }\n        chars.push(\n          String.fromCharCode(\n            Number.parseInt(String.fromCharCode(a) + String.fromCharCode(b), 16)\n          )\n        );\n      } else {\n        chars.push(c);\n        this.current++;\n      }\n    }\n    return chars.join('');\n  }\n\n  /** Check if the current offset contains a delimiter.\n   *\n   * See ISO32000-2:2020 section 7.2.3, Table 2\n   */\n  matchDelimiter(c: string): boolean {\n    return '[]{}()<>/%'.indexOf(c) >= 0;\n  }\n\n  /** Read a hex string from the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.4.3\n   */\n  readHexString(): PdfValue {\n    this.current++;\n    const vals: Array<number> = [];\n    while (this.getChar() !== '>') {\n      const a = this.buf[this.current++];\n      const b = this.buf[this.current++];\n      if (!isHex(a) || !isHex(b)) {\n        throw new Error(`Invalid value in hex string: '${a}${b}`);\n      }\n      vals.push(\n        Number.parseInt(String.fromCharCode(a) + String.fromCharCode(b), 16)\n      );\n    }\n    this.current++;\n    return new Uint8Array(vals);\n  }\n\n  /** Read a literal string from the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.4.2\n   */\n  readLiteralString(): PdfValue {\n    this.current++;\n    const chars: string[] = [];\n    let openParens = 0;\n    let c: string;\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      c = this.getChar();\n      if (c === '\\\\') {\n        this.current++;\n        c = this.getChar();\n        if (isDigit(c)) {\n          let cs = [c];\n          this.current++;\n          while (isDigit(this.getChar())) {\n            cs.push(this.getChar());\n            this.current++;\n          }\n          if (cs.length > 3) {\n            this.current -= cs.length - 3;\n            cs = cs.slice(0, 3);\n          }\n          this.current--;\n          c = String.fromCharCode(Number.parseInt(cs.join(''), 8));\n        } else {\n          c = ESCAPE_CHARS[c];\n          if (c === undefined) {\n            throw new Error(\n              `Illegal escape sequence in string literal: '\\\\${c}`\n            );\n          }\n        }\n      } else if (c === '(') {\n        openParens++;\n      } else if (c === ')') {\n        openParens--;\n        if (openParens < 0) {\n          this.current++;\n          return chars.join('');\n        }\n      }\n      chars.push(c);\n      this.current++;\n    }\n  }\n\n  /** Read a dictionary from the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.7\n   */\n  readDict(): PdfValue {\n    this.current += 2;\n    const obj: Record<string, PdfValue> = {};\n    this.skipWhiteSpace();\n    while (this.getChar() !== '>') {\n      const name = this.read();\n      if (typeof name !== 'string' || !name.startsWith('/')) {\n        throw new Error(`Dictionary keys must be name objects, got '${name}`);\n      }\n      this.skipWhiteSpace();\n      const val = this.read();\n      if (val !== null) {\n        obj[name.substring(1)] = val;\n      }\n      this.skipWhiteSpace();\n    }\n    this.current += 2;\n    return obj;\n  }\n\n  /** Read an array from the current offset.\n   *\n   * See ISO32000-2:2020 section 7.3.6\n   */\n  readArray(): Array<PdfValue> {\n    this.current++;\n    const arr: Array<PdfValue> = [];\n    while (this.getChar() !== ']') {\n      arr.push(this.read());\n      this.skipWhiteSpace();\n    }\n    this.current++;\n    return arr;\n  }\n}\n\n/** Minimalist low-level PDF parser operating on a Reader object.\n *\n * Currently only supports discovering page objects and annotation objects, as well\n * as obtaining arbitrary objects given the object number and generation.\n */\nexport class PdfParser {\n  private reader: Reader;\n  private objectOffsets: Array<number>;\n  private sortedOffsets: Array<number>;\n  pdfSize: any;\n  objGenerations: number[];\n  infoNum: number;\n  catalogNum: number;\n\n  /** Construct a new parser from a Reader.\n   *\n   * Used instead of the constructor to allow for async initialization.\n   */\n  static async parse(reader: Reader): Promise<PdfParser> {\n    const trailerBuf = new Uint8Array(1024);\n    const pdfSize = await reader.size();\n    const bufStart = pdfSize - trailerBuf.length;\n    await reader.read(trailerBuf, 0, bufStart, trailerBuf.length);\n    const eofIdx =\n      trailerBuf.length - (trailerBuf[trailerBuf.length - 1] === 0x46 ? 5 : 6);\n    if (!testForString(trailerBuf, eofIdx, '%%EOF')) {\n      throw 'Invalid PDF, missing EOF comment at end of file';\n    }\n    const startXrefPos = trailerBuf.findLastIndex((_x, idx) =>\n      testForString(trailerBuf, idx, 'startxref')\n    );\n    if (startXrefPos < 0) {\n      throw 'Invalid PDF, missing startxref marker in file trailer.';\n    }\n    const objGenerations: Array<number> = [];\n    const objsDeleted: Array<boolean> = [];\n    const objOffsets: Array<number> = [];\n    const xrefStartOffset = Number.parseInt(\n      textDecoder.decode(trailerBuf.subarray(startXrefPos + 9, eofIdx)).trim(),\n      10\n    );\n    const dictEnd =\n      trailerBuf.findLastIndex((_x, idx) =>\n        testForString(trailerBuf, idx, '>>')\n      ) + 2;\n    const dictStart = trailerBuf.findLastIndex((_x, idx) =>\n      testForString(trailerBuf, idx, '<<')\n    );\n    const trailerDict = new PdfValueParser(\n      trailerBuf.subarray(dictStart, dictEnd)\n    ).read() as PdfDictionary;\n    for await (const { startNum, entries } of parseCrossRefSection(\n      reader,\n      xrefStartOffset,\n      bufStart + dictEnd - xrefStartOffset\n    )) {\n      for (const [idx, [offset, gen, inUse]] of entries.entries()) {\n        const objNum = idx + startNum;\n        if ((objGenerations[objNum] ?? -1) > gen) {\n          // Outdated entry, don't consider\n          continue;\n        }\n        objGenerations[objNum] = gen;\n        if (inUse) {\n          objOffsets[objNum] = offset;\n          objsDeleted[objNum] = false;\n        } else {\n          objOffsets[objNum] = -1;\n          objsDeleted[objNum] = true;\n        }\n      }\n    }\n    if (objOffsets.length !== trailerDict.Size) {\n      throw `Trailer dictionary has different number of objects than crossreference tables, ${objOffsets.length} vs. ${trailerDict.Size}`;\n    }\n    return new PdfParser(reader, objOffsets, objGenerations, trailerDict);\n  }\n\n  /** Private constructor, use factory method above. */\n  private constructor(\n    reader: Reader,\n    objOffsets: Array<number>,\n    objGenerations: Array<number>,\n    trailerDict: PdfDictionary\n  ) {\n    this.reader = reader;\n    this.objectOffsets = objOffsets;\n    this.sortedOffsets = [...objOffsets].sort((a, b) => a - b);\n    this.objGenerations = objGenerations;\n    this.catalogNum = (trailerDict.Root as PdfRef).refObj;\n    this.infoNum = (trailerDict.Info as PdfRef).refObj;\n  }\n\n  /** Retrieve the catalog dictionary. */\n  async catalog(): Promise<PdfDictionary> {\n    const obj = await this.getObject(this.catalogNum);\n    if (!obj) {\n      throw `Document has no catalog object (num as per trailer: ${this.catalogNum}!`;\n    }\n    return obj.data as PdfDictionary;\n  }\n\n  /** Retrieve the info dictionary. */\n  async info(): Promise<PdfDictionary> {\n    const obj = await this.getObject(this.infoNum);\n    if (!obj) {\n      throw `Document has no info object (num as per trailer: ${this.infoNum}!`;\n    }\n    return obj.data as PdfDictionary;\n  }\n\n  /** Yield all pages referenced in the given page dictionary. */\n  async *_pagesFromPagesObj(\n    pagesObj: PdfDictionary\n  ): AsyncGenerator<PdfObject> {\n    for (const pageRef of pagesObj.Kids as Array<PdfRef>) {\n      const page = await this.getObject(pageRef.refObj, true);\n      if (!page) {\n        throw `Could not find Page object with number ${pageRef.refObj}`;\n      }\n      const pageDict = page.data as PdfDictionary;\n      if (pageDict.Type === '/Pages') {\n        yield* this._pagesFromPagesObj(pageDict);\n      } else {\n        yield page;\n      }\n    }\n  }\n\n  /** Yield all pages in the PDF. */\n  async *pages(): AsyncGenerator<PdfObject> {\n    const catalog = await this.catalog();\n    const pagesRef = catalog.Pages as PdfRef;\n    const pagesRoot = await this.getObject(pagesRef.refObj);\n    if (!pagesRoot) {\n      throw `Could not find Pages object with number ${pagesRef.refObj}`;\n    }\n    const pagesDict = pagesRoot.data as PdfDictionary;\n    yield* this._pagesFromPagesObj(pagesDict);\n  }\n\n  /** Yield all annotations for the given page dictionary. */\n  async *annotations(pageDict: PdfDictionary): AsyncGenerator<PdfDictionary> {\n    const annots = pageDict.Annots;\n    if (!annots) {\n      return;\n    }\n    for (const annoRef of annots as Array<PdfRef>) {\n      const anno = await this.getObject(annoRef.refObj);\n      if (!anno) {\n        throw `Could not find Annotation object with number ${annoRef.refObj}`;\n      }\n      yield anno.data as PdfDictionary;\n    }\n  }\n\n  /** Resolve a PDF reference to the corresponding object. */\n  resolveRef(ref: PdfRef): Promise<PdfObject | undefined> {\n    return this.getObject(ref.refObj, true);\n  }\n\n  /** Get an object from the PDF from its number. */\n  async getObject(\n    num: number,\n    withStream = false\n  ): Promise<PdfObject | undefined> {\n    const offset = this.objectOffsets[num];\n    if (!offset) {\n      return;\n    }\n    if (!this.pdfSize) {\n      this.pdfSize = await this.reader.size();\n    }\n    const nextOffset =\n      this.sortedOffsets[this.sortedOffsets.indexOf(offset) + 1] ??\n      this.pdfSize;\n    const buf = new Uint8Array(nextOffset - offset);\n    await this.reader.read(buf, 0, offset, buf.length);\n    const objEndIdx = buf.findIndex((_x, idx) =>\n      testForString(buf, idx, 'endobj')\n    );\n    let streamIdx = buf.findIndex((_x, idx) =>\n      testForString(buf, idx, 'stream')\n    );\n    if (streamIdx >= 0) {\n      streamIdx += 'stream'.length;\n      if (buf[streamIdx] === '\\r'.charCodeAt(0)) {\n        streamIdx += 2;\n      } else {\n        streamIdx += 1;\n      }\n    }\n    const objSig = `${num} ${this.objGenerations[num]} obj`;\n    const objParser = new PdfValueParser(\n      buf.subarray(objSig.length, streamIdx < 0 ? objEndIdx : streamIdx)\n    );\n    const data = objParser.read();\n    if (typeof data !== 'object' || data === null) {\n      throw new Error('Illegal PDF object, does not start with a dictionary.');\n    }\n    let stream: Uint8Array | undefined;\n    if (withStream && streamIdx > 0) {\n      const streamLength = (data as PdfDictionary).Length as number | undefined;\n      if (streamLength === undefined) {\n        throw new Error(\n          'Illegal stream object, missing Length entry in object dictionary.'\n        );\n      }\n      stream = buf.subarray(streamIdx, streamIdx + streamLength);\n    }\n    return {\n      num,\n      data,\n      stream,\n    };\n  }\n}\n","export default '0.2.3';\n","import { crc32 } from '../util.js';\nimport { textEncoder } from './util.js';\n\nexport type LocalHeaderParams = {\n  creationDate?: Date;\n  filename: string;\n  data: Uint8Array;\n  compressedData?: Uint8Array;\n  extraDataLength: number;\n};\n\nexport type CentralDirectoryFileSpec = {\n  localHeaderOffset: number;\n  deflated: boolean;\n  creationDate: Date;\n  crc32: number;\n  dataLength: number;\n  compressedDataLength: number;\n  filename: string;\n};\n\nexport type CentralFileDirectorySpec = {\n  files: CentralDirectoryFileSpec[];\n  trailingLength: number;\n  offset: number;\n};\n\nexport function buildLocalZipHeader({\n  creationDate = new Date(),\n  filename,\n  data,\n  compressedData,\n  extraDataLength,\n}: LocalHeaderParams): Uint8Array {\n  const creationTimeZip =\n    (creationDate.getHours() << 11) |\n    (creationDate.getDay() << 5) |\n    Math.round(creationDate.getSeconds() / 2);\n  const creationDateZip =\n    ((creationDate.getFullYear() - 1980) << 9) |\n    ((creationDate.getMonth() + 1) << 5) |\n    creationDate.getDate();\n  const dataCrc = crc32(data);\n  const filenameEncoded = textEncoder.encode(filename);\n  // 2 bytes for zlib header\n  const compressedLength = compressedData ? (compressedData.length - 2) : data.length;\n  return new Uint8Array([\n    // PKZIP magic number\n    0x50,\n    0x4b,\n    // Local File Header magic\n    0x03,\n    0x04,\n    // Required PKZip version\n    0x14,\n    0x00,\n    // General purpose bit flag, 2 bytes\n    0b00000000,\n    0b00000000,\n    // Compression method, 2 bytes little endian\n    compressedData ? 0x08 : 0x00,\n    0x00,\n    // Creation time, 2 bytes little endian\n    creationTimeZip & 0xff,\n    creationTimeZip >> 8,\n    // Creation date, 2 bytes little endian\n    creationDateZip & 0xff,\n    creationDateZip >> 8,\n    // CRC32 of data, 4 bytes little endian\n    dataCrc & 0xff,\n    (dataCrc >> 8) & 0xff,\n    (dataCrc >> 16) & 0xff,\n    (dataCrc >> 24) & 0xff,\n    // Compressed size, 4 bytes little endian\n    compressedLength & 0xff,\n    (compressedLength >> 8) & 0xff,\n    (compressedLength >> 16) & 0xff,\n    (compressedLength >> 24) & 0xff,\n    // Uncompressed size, 4 bytes little endian\n    data.length & 0xff,\n    (data.length >> 8) & 0xff,\n    (data.length >> 16) & 0xff,\n    (data.length >> 24) & 0xff,\n    // Filename length, 2 bytes little endian\n    filenameEncoded.length & 0xff,\n    filenameEncoded.length >> 8, // Filename length in little endian\n    // Extra field length, 2 bytes little endian\n    (extraDataLength + 4) & 0xff,\n    (extraDataLength + 4) >> 8,\n    // Encoded file name\n    ...filenameEncoded,\n    // Beginning of extra field: identifier, 2 bytes\n    0xff,\n    0xff,\n    // Beginning of extra field: length, 2 bytes little endian\n    extraDataLength & 0xff,\n    extraDataLength >> 8,\n  ]);\n}\n\nexport function buildCentralFileDirectory({\n  files,\n  trailingLength,\n  offset\n}: CentralFileDirectorySpec): Uint8Array {\n  const chunks = files.map(buildCentralDirectoryFileHeader);\n  const cdSize =  chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n  chunks.push(new Uint8Array([\n    // PKZIP magic number\n    0x50,\n    0x4b,\n    // End of central directory magic\n    0x05,\n    0x06,\n    // Disk number\n    0x00,\n    0x00,\n    // Disk with central directory\n    0x00,\n    0x00,\n    // Disk entries\n    files.length & 0xff,\n    files.length >> 8,\n    // Total entries\n    files.length & 0xff,\n    files.length >> 8,\n    // Central directory size,\n    cdSize & 0xff,\n    (cdSize >> 8) & 0xff,\n    (cdSize >> 16) & 0xff,\n    (cdSize >> 24) & 0xff,\n    // Offset of central directory in file\n    offset & 0xff,\n    (offset >> 8) & 0xff,\n    (offset >> 16) & 0xff,\n    (offset >> 24) & 0xff,\n    // Length of trailing comment\n    trailingLength & 0xff,\n    trailingLength >> 8,\n  ]));\n  return new Uint8Array(\n    chunks.reduce((acc: number[], curr) => {\n      acc.push(...curr);\n      return acc;\n    }, [])\n  );\n}\n\nfunction buildCentralDirectoryFileHeader(\n  spec: CentralDirectoryFileSpec\n): Uint8Array {\n  const creationTimeZip =\n    (spec.creationDate.getHours() << 11) |\n    (spec.creationDate.getMinutes() << 5) |\n    Math.round(spec.creationDate.getSeconds() / 2);\n  const creationDateZip =\n    ((spec.creationDate.getFullYear() - 1980) << 9) |\n    ((spec.creationDate.getMonth() +1) << 5) |\n    spec.creationDate.getDate();\n  const filenameEncoded = textEncoder.encode(spec.filename);\n  return new Uint8Array([\n    // PKZIP magic number\n    0x50,\n    0x4b,\n    // Central directory file header magic\n    0x01,\n    0x02,\n    // Version\n    0x17,\n    0x03,\n    //  Version needed\n    0x14,\n    0x00,\n    // Flags, none set\n    0x00,\n    0x00,\n    // Compression method, 2 bytes little endian\n    spec.deflated ? 0x08 : 0x00,\n    0x00,\n    // Creation time, 2 bytes little endian\n    creationTimeZip & 0xff,\n    creationTimeZip >> 8,\n    // Creation date, 2 bytes little endian\n    creationDateZip & 0xff,\n    creationDateZip >> 8,\n    // CRC32 of data, 4 bytes little endian\n    spec.crc32 & 0xff,\n    (spec.crc32 >> 8) & 0xff,\n    (spec.crc32 >> 16) & 0xff,\n    (spec.crc32 >> 24) & 0xff,\n    // Compressed size, 4 bytes little endian\n    spec.compressedDataLength & 0xff,\n    (spec.compressedDataLength >> 8) & 0xff,\n    (spec.compressedDataLength >> 16) & 0xff,\n    (spec.compressedDataLength >> 24) & 0xff,\n    // Uncompressed size, 4 bytes little endian\n    spec.dataLength & 0xff,\n    (spec.dataLength >> 8) & 0xff,\n    (spec.dataLength >> 16) & 0xff,\n    (spec.dataLength >> 24) & 0xff,\n    // Filename length, 2 bytes little endian\n    filenameEncoded.length & 0xff,\n    filenameEncoded.length >> 8, // Filename length in little endian\n    // Extra field length, 2 bytes little endian\n    0x00,\n    0x00,\n    // File comment length, 2 bytes little endian\n    0x00,\n    0x00,\n    // Disk # start, 2 bytes little endian\n    0x00,\n    0x00,\n    // Internal Attribute, 2 bytes little endian\n    0x00,\n    0x00,\n    // External Attribute, 4 bytes little endian\n    0x00,\n    0x00,\n    0xa4,\n    0x81,\n    // Offset of local header, 4 bytes little endian\n    spec.localHeaderOffset & 0xff,\n    (spec.localHeaderOffset >> 8) &0xff,\n    (spec.localHeaderOffset >> 16) &0xff,\n    (spec.localHeaderOffset >> 24) &0xff,\n    ...filenameEncoded,\n  ]);\n}\n","import { PdfDictionary } from './common.js';\nimport { Annotation } from '../iiif.js';\nimport {\n  BoxSelector,\n  SelectorStyle,\n  SupportedSelector,\n  SvgSelector,\n} from '@iiif/vault-helpers/annotation-targets';\nimport { PointSelector } from '@iiif/presentation-3';\nimport Color from 'color';\nimport { SAXParser, SaxEventType, Text } from 'sax-wasm';\nimport { textEncoder } from './util.js';\n\nconst ALLOWED_CSS_RULES = [\n  'text-align',\n  'vertical-align',\n  'font-size',\n  'font-weight',\n  'font-style',\n  'font-family',\n  'font',\n  'color',\n  'text-decoration',\n  'font-stretch',\n];\nconst CSS_PAT = /\\s*(?<attrib>[^:]+)\\s*:\\s*(?<val>[^;]+)(?:;|$)/gm;\nconst RGB_PAT = /rgb\\((?<r>\\d+)\\s*,\\s*(?<g>\\d+)\\s*,\\s*(?<b>\\d+)\\)/;\nconst CSS_LENGTH_PAT = /(?<val>\\d+(?:\\.\\d+)?)\\s*(?<unit>[[a-z%]+)?/;\n\nfunction sanitizeCssForPdf(styleAttrib: string): string {\n  let parts: RegExpExecArray | null;\n  const out: Array<string> = [];\n  while ((parts = CSS_PAT.exec(styleAttrib)) !== null) {\n    const [, attrib, value] = parts;\n    if (!ALLOWED_CSS_RULES.includes(attrib)) {\n      continue;\n    }\n    out.push(`${attrib}: ${value}`);\n  }\n  return out.join('; ');\n}\n\nfunction htmlToPlainText(html: string): string {\n  const parser = new SAXParser(SaxEventType.Text, { highWaterMark: 1024 });\n  const txt: string[] = [];\n  parser.eventHandler = (ev, data) => {\n    txt.push((data as Text).value);\n  }\n  parser.write(textEncoder.encode(html));\n  return txt.join('').trim();\n}\n\nfunction toPdfRect(\n  selector: BoxSelector | SvgSelector,\n  pageHeight: number,\n  unitScale: number\n): PdfDictionary | null {\n  if (!selector.spatial) {\n    return null;\n  }\n  const lly = pageHeight - selector.spatial.y;\n  const ury = lly - selector.spatial.height;\n  return {\n    Subtype: '/Square',\n    Rect: [\n      selector.spatial.x * unitScale,\n      lly * unitScale,\n      (selector.spatial.x + selector.spatial.width) * unitScale,\n      ury * unitScale,\n    ],\n  };\n}\n\nfunction cssColorToRgb(cssColor: string): [number, number, number] | null {\n  return Color(cssColor).rgb().array() as [number, number, number];\n}\n\nfunction cssLengthToPdfUserspace(\n  cssLength: string,\n  unitScale: number,\n  referenceDimensionPx?: number\n): number | null {\n  const match = CSS_LENGTH_PAT.exec(cssLength);\n  if (!match || !match.groups) {\n    return null;\n  }\n  const val = parseFloat(match.groups.val);\n  const unit = match.groups.unit;\n  if (!unit) {\n    return val * unitScale;\n  }\n  switch (unit) {\n    case '%':\n      if (!referenceDimensionPx) {\n        return null;\n      }\n      return (val / 100) * referenceDimensionPx * unitScale;\n    case 'px':\n      return unitScale * val;\n    default:\n      console.warn(`Unsupported CSS length unit: ${unit}`);\n      return null;\n  }\n}\n\nfunction selectorStyleToPdf(\n  style: SelectorStyle,\n  unitScale: number\n): PdfDictionary {\n  const pdfStyle: PdfDictionary = {};\n  if (style.stroke || style.strokeDasharray || style.strokeWidth) {\n    pdfStyle.BS = {\n      Type: '/Border',\n      W: style.strokeWidth ?? 1,\n      S: style.strokeDasharray ? '/D' : '/S',\n    };\n    if (style.strokeDasharray) {\n      pdfStyle.BS.D = style.strokeDasharray;\n    }\n  }\n  if (style.fill) {\n    const rgb = cssColorToRgb(style.fill);\n    if (rgb) {\n      pdfStyle.IC = rgb.map((c) => c / 255);\n    }\n  }\n  // TODO: Check if fill-opacity is desired and use an Apperance Stream instead of IC\n  if (style.strokeWidth) {\n    const width = cssLengthToPdfUserspace(style.strokeWidth, unitScale);\n    pdfStyle.BS = {\n      Type: '/Border',\n      W: width,\n    };\n  }\n  return pdfStyle;\n}\n\nfunction selectorToPdf(\n  selector: SupportedSelector,\n  unitScale: number,\n  pageHeight: number\n): PdfDictionary {\n  const styleDict = selector.style\n    ? selectorStyleToPdf(selector.style, unitScale)\n    : {};\n  switch (selector.type) {\n    case 'BoxSelector':\n      return {\n        Subtype: '/Square',\n        ...toPdfRect(selector as BoxSelector, pageHeight, unitScale),\n        ...styleDict,\n      };\n    case 'PointSelector': {\n      // TODO: Use a /Stamp with a custom icon (flag?)\n      //       This is a bit complicated since we need to povide\n      //       an /AP dictionary with a custom /Form that\n      //       renders our icon. Luckily, this can be reused, so\n      //       we store it once and just reference it in all point-type\n      //       annotations.\n      const point = selector as PointSelector;\n      if (!point.x || !point.y) {\n        throw `Only PointSelectors with both x and y coordinates are supported!`;\n      }\n      return {\n        Subtype: '/Circle',\n        BS: {\n          Type: '/Border',\n          W: 2,\n          S: '/S',\n        },\n        IC: [1.0, 1.0, 1.0],\n        Rect: [\n          point.x * unitScale - 0.5,\n          point.y * unitScale - 0.5,\n          point.x * unitScale + 1.0,\n          point.y * unitScale + 1.0,\n        ],\n      };\n    }\n    case 'SvgSelector': {\n      const svgSel = selector as SvgSelector;\n      switch (svgSel.svgShape) {\n        case 'rect':\n          return {\n            Subtype: '/Square',\n            ...toPdfRect(svgSel, pageHeight, unitScale),\n            ...styleDict,\n          };\n        case 'circle':\n        case 'ellipse':\n          return {\n            Subtype: '/Circle',\n            Rect: toPdfRect(svgSel, pageHeight, unitScale),\n            ...styleDict,\n          };\n        case 'polyline':\n        case 'polygon':\n          return {\n            Subtype: svgSel.svgShape === 'polyline' ? '/PolyLine' : '/Polygon',\n            Vertices:\n              svgSel.points?.flatMap(([x, y]) => [\n                x * unitScale,\n                (pageHeight - y) * unitScale,\n              ]) ?? [],\n            ...styleDict,\n          };\n        case 'path':\n          return {\n            Subtype: '/Ink',\n            InkList:\n              svgSel.points?.flatMap(([x, y]) => [\n                x * unitScale,\n                (pageHeight - y) * unitScale,\n              ]) ?? [],\n            ...styleDict,\n          };\n        default:\n          throw new Error('not implemented yet');\n      }\n    }\n    default:\n      throw `${selector.type} selector is currently not supported`;\n  }\n}\n\nexport function exportPdfAnnotation(\n  anno: Annotation,\n  unitScale: number,\n  pageHeight: number\n): Array<PdfDictionary> {\n  const annoDict: PdfDictionary = {\n    Type: '/Annot',\n    NM: `(${anno.id})`,\n    Contents: `(${htmlToPlainText(anno.markup)})`,\n    F: 4,\n    C: [1, 0, 0], // Red title bar\n    CA: 1, // Constant opacity of 1\n    Border: [0, 0, 5],\n    //RC: `(${htmlToPdfRichText(anno.markup)})`,\n  };\n  if (anno.author) {\n    annoDict.T = `(${anno.author})`;\n  }\n  if (anno.lastModified) {\n    annoDict.M = anno.lastModified;\n  }\n  if (anno.target.selector) {\n    return [\n      {\n        ...annoDict,\n        ...selectorToPdf(anno.target.selector, unitScale, pageHeight),\n      },\n    ] as PdfDictionary[];\n  } else if (anno.target.selectors && anno.target.selectors.length > 0) {\n    return anno.target.selectors.map((s) => ({\n      ...annoDict,\n      ...selectorToPdf(s, unitScale, pageHeight),\n    })) as PdfDictionary[];\n  }\n  return [];\n}\n","export interface LicenseDescription {\n  text: string;\n  logo: string;\n}\nexport type LicenseList = Record<string, LicenseDescription>;\n\n// TODO: Re-generate this list based on the official CC RDF files:\n//  https://github.com/creativecommons/cc-licenses-data/blob/main/legacy/rdf-licenses\nexport const licenses: LicenseList = {\n  'http://creativecommons.org/licenses/by-nc-sa/2.0/fr/': {\n    text: 'Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France (CC-BY-NC-SA-2.0-FR)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/4.0/': {\n    text: 'Creative Commons Attribution Share Alike 4.0 International (CC-BY-SA-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/3.0/de/': {\n    text: 'Creative Commons Attribution 3.0 Germany (CC-BY-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/3.0/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported (CC-BY-NC-ND-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by/1.0/': {\n    text: 'Creative Commons Attribution 1.0 Generic (CC-BY-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/1.0/': {\n    text: 'Creative Commons Attribution No Derivatives 1.0 Generic (CC-BY-ND-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/3.0/de/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 3.0 Germany (CC-BY-NC-SA-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/1.0/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 1.0 Generic (CC-BY-NC-SA-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/4.0/': {\n    text: 'Creative Commons Attribution No Derivatives 4.0 International (CC-BY-ND-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/3.0/at/': {\n    text: 'Creative Commons Attribution Share Alike 3.0 Austria (CC-BY-SA-3.0-AT)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/3.0/at/': {\n    text: 'Creative Commons Attribution 3.0 Austria (CC-BY-3.0-AT)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by/3.0/': {\n    text: 'Creative Commons Attribution 3.0 Unported (CC-BY-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/2.0/': {\n    text: 'Creative Commons Attribution Non Commercial 2.0 Generic (CC-BY-NC-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/2.5/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 2.5 Generic (CC-BY-NC-SA-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/2.5/': {\n    text: 'Creative Commons Attribution Non Commercial 2.5 Generic (CC-BY-NC-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd-nc/1.0/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic (CC-BY-NC-ND-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/3.0/': {\n    text: 'Creative Commons Attribution No Derivatives 3.0 Unported (CC-BY-ND-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/2.5/': {\n    text: 'Creative Commons Attribution Share Alike 2.5 Generic (CC-BY-SA-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/2.0/uk/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales (CC-BY-NC-SA-2.0-UK)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/2.0/': {\n    text: 'Creative Commons Attribution 2.0 Generic (CC-BY-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/2.5/': {\n    text: 'Creative Commons Attribution No Derivatives 2.5 Generic (CC-BY-ND-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/2.0/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic (CC-BY-NC-ND-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/3.0/igo/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 3.0 IGO (CC-BY-NC-SA-3.0-IGO)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/publicdomain//': {\n    text: 'Creative Commons Public Domain Dedication and Certification (CC-PDDC)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/publicdomain.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/2.0/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 2.0 Generic (CC-BY-NC-SA-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/3.0/de/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany (CC-BY-NC-ND-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/3.0/': {\n    text: 'Creative Commons Attribution Non Commercial 3.0 Unported (CC-BY-NC-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/3.0/de/': {\n    text: 'Creative Commons Attribution Non Commercial 3.0 Germany (CC-BY-NC-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/1.0/': {\n    text: 'Creative Commons Attribution Share Alike 1.0 Generic (CC-BY-SA-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/3.0/de/': {\n    text: 'Creative Commons Attribution No Derivatives 3.0 Germany (CC-BY-ND-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/2.5/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic (CC-BY-NC-ND-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/3.0/': {\n    text: 'Creative Commons Attribution Share Alike 3.0 Unported (CC-BY-SA-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/4.0/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 4.0 International (CC-BY-NC-SA-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/2.0/': {\n    text: 'Creative Commons Attribution Share Alike 2.0 Generic (CC-BY-SA-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/2.1/jp/': {\n    text: 'Creative Commons Attribution Share Alike 2.1 Japan (CC-BY-SA-2.1-JP)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/2.5/': {\n    text: 'Creative Commons Attribution 2.5 Generic (CC-BY-2.5)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/2.0/uk/': {\n    text: 'Creative Commons Attribution Share Alike 2.0 England and Wales (CC-BY-SA-2.0-UK)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/3.0/nl/': {\n    text: 'Creative Commons Attribution 3.0 Netherlands (CC-BY-3.0-NL)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-sa/3.0/': {\n    text: 'Creative Commons Attribution Non Commercial Share Alike 3.0 Unported (CC-BY-NC-SA-3.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by/4.0/': {\n    text: 'Creative Commons Attribution 4.0 International (CC-BY-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by/3.0/us/': {\n    text: 'Creative Commons Attribution 3.0 United States (CC-BY-3.0-US)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/4.0/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 4.0 International (CC-BY-NC-ND-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-sa/3.0/de/': {\n    text: 'Creative Commons Attribution Share Alike 3.0 Germany (CC-BY-SA-3.0-DE)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-sa.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc-nd/3.0/igo/': {\n    text: 'Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO (CC-BY-NC-ND-3.0-IGO)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc-nd.svg',\n  },\n  'http://creativecommons.org/publicdomain/zero/1.0/': {\n    text: 'Creative Commons Zero v1.0 Universal (CC0-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg',\n  },\n  'http://creativecommons.org/publicdomain/mark/1.0/': {\n    text: 'Public Domain Mark 1.0: No Copyright',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/publicdomain.svg',\n  },\n  'http://creativecommons.org/licenses/by/2.5/au/': {\n    text: 'Creative Commons Attribution 2.5 Australia (CC-BY-2.5-AU)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by.svg',\n  },\n  'http://creativecommons.org/licenses/by-nd/2.0/': {\n    text: 'Creative Commons Attribution No Derivatives 2.0 Generic (CC-BY-ND-2.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nd.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/1.0/': {\n    text: 'Creative Commons Attribution Non Commercial 1.0 Generic (CC-BY-NC-1.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://creativecommons.org/licenses/by-nc/4.0/': {\n    text: 'Creative Commons Attribution Non Commercial 4.0 International (CC-BY-NC-4.0)',\n    logo: 'https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/by-nc.svg',\n  },\n  'http://rightsstatements.org/vocab/InC/1.0/': {\n    text: 'In Copyright',\n    logo: 'https://rightsstatements.org/files/buttons/InC.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/InC-OW-EU/1.0/': {\n    text: 'In Copyright - EU Orphan Work',\n    logo: 'https://rightsstatements.org/files/buttons/InC-OW-EU.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/InC-EDU/1.0/': {\n    text: 'In Copyright - Educational Use Permitted',\n    logo: 'https://rightsstatements.org/files/buttons/InC-EDU.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/InC-NC/1.0/': {\n    text: 'In Copyright - Non-Commercial Use Permitted',\n    logo: 'https://rightsstatements.org/files/buttons/InC-NC.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/InC-RUU/1.0/': {\n    text: 'In Copyright - Rights-holder(s) Unlocatable or Unidentifiable',\n    logo: 'https://rightsstatements.org/files/buttons/InC-RUU.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/NoC-CR/1.0/': {\n    text: 'No Copyright - Contractual Restrictions',\n    logo: 'https://rightsstatements.org/files/buttons/NoC-CR.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/NoC-NC/1.0/': {\n    text: 'No Copyright - Non-Commercial Use Only',\n    logo: 'https://rightsstatements.org/files/buttons/NoC-NC.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/NoC-OKLR/1.0/': {\n    text: 'No Copyright - Other Known Legal Restrictions',\n    logo: 'https://rightsstatements.org/files/buttons/NoC-OKLR.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/NoC-US/1.0/': {\n    text: 'No Copyright - United States',\n    logo: 'https://rightsstatements.org/files/buttons/NoC-US.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/CNE/1.0/': {\n    text: 'Copyright Not Evaluated',\n    logo: 'https://rightsstatements.org/files/buttons/CNE.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/UND/1.0/': {\n    text: 'Copyright Undetermined',\n    logo: 'https://rightsstatements.org/files/buttons/UND.dark.svg',\n  },\n  'http://rightsstatements.org/vocab/NKC/1.0/': {\n    text: 'No Known Copyright',\n    logo: 'https://rightsstatements.org/files/buttons/NKC.dark.svg',\n  },\n};\n\nexport function getLicenseInfo(uri: string): LicenseDescription | null {\n  uri = uri.replace(/^https:/, 'http:').replace(/\\/deed\\.[a-z]{2}$/, '');\n  if (!uri.endsWith('/')) {\n    uri += '/';\n  }\n  return licenses[uri];\n}\n"],"mappings":"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;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EACxE;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAC1E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC1E;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC1E;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EACtE;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACvE;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EACvE;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC1E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5E;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACzE;AAAA,EAAG;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAC5E;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAAI;AAAA,EAAG;AAAA,EAAG;AAAA,EAAG;AAAA,EAC3E;AAAA,EAAG;AAAA,EAAK;AAAA,EAAG;AAAA,EAA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","names":["prometheus","ImageServiceLoader_","x","isAlto","limit","scaleFactor","ppi","import_util","util","nodeCrypto","zlib","Color","dedent","prev","ref","canvasIdx","PQueue","events","ppi"]}