{"version":3,"sources":["../src/error.ts","../src/calculator/base.ts","../src/calculator/v2.ts","../src/calculator/v3.ts"],"sourcesContent":["export class IIIFError extends Error {\n  statusCode?: number;\n\n  constructor (message: string, opts: { statusCode?: number } = {}) {\n    super(message);\n    this.statusCode = opts.statusCode;\n  }\n}\n\nexport default IIIFError;\n","import Debug from 'debug';\nimport { IIIFError } from '../error';\nimport type { BoundingBox, Dimensions, MaxDimensions } from '../types';\nimport type { Calculated, CalculatorOptions } from '../contracts';\n\nconst debug = Debug('iiif-processor:calculator');\n\nexport type ValidatorKey = 'quality' | 'format' | 'region' | 'size' | 'rotation' | 'density';\nexport type ValidatorMap = Record<ValidatorKey, string[]>;\n\nconst IR = '\\\\d+';\nconst FR = '\\\\d+(?:\\\\.\\\\d+)?';\nconst PCTR = /^pct:(?<val>[\\d.,]+)/;\n\nexport const Formats = ['gif', 'jpg', 'tif', 'png', 'webp'];\nexport const Qualities = ['color', 'gray', 'bitonal', 'default'];\n\n\nconst extraFormats = ['jpeg', 'tiff'];\n\nconst Validators: ValidatorMap = {\n  quality: Qualities,\n  format: [...Formats, ...extraFormats],\n  region: ['full', 'square', `pct:${FR},${FR},${FR},${FR}`, `${IR},${IR},${IR},${IR}`],\n  size: ['full', 'max', `pct:${FR}`, `${IR},`, `,${IR}`, `\\\\!?${IR},${IR}`],\n  rotation: [`\\\\!?${FR}`],\n  density: []\n};\n\ntype SizeDesc = { width?: number | null; height?: number | null; fit?: 'fill' | 'inside' };\ntype CanonicalInfo = { region: 'full' | BoundingBox; size: 'full' | 'max' | string; rotation: string; quality: string; format: string };\ntype ParsedInfo = { region: BoundingBox; size: SizeDesc; rotation: { flop: boolean; degree: number }; quality: string; format: { type: string; density?: number }; upscale: boolean };\n\nfunction validateDensity (v: unknown) {\n  debug('validating density %s', v);\n  if (v === null) return true;\n  if (v === undefined) return true;\n  if (typeof v !== 'number' || v < 0) {\n    throw new IIIFError(`Invalid density value: ${v}`);\n  }\n  return true;\n}\n\nexport class Base {\n  protected dims: Dimensions;\n  protected opts: { max?: MaxDimensions };\n  protected _canonicalInfo: CanonicalInfo;\n  protected _parsedInfo: ParsedInfo;\n  protected _sourceDims: Dimensions;\n\n  static _matchers(): typeof Validators {\n    return Validators;\n  }\n\n  static _validator(type: ValidatorKey) {\n    const result = this._matchers()[type].join('|');\n    return `(?<${type}>${result})`;\n  }\n\n  static parsePath(path: string) {\n    path = decodeURIComponent(path);\n    debug('parsing IIIF path: %s', path);\n    const idOnlyRe = new RegExp('^/?(?<id>.+)/?$');\n    const infoJsonRe = new RegExp('^/?(?<id>.+)/(?<info>info.json)$');\n    const transformRe = new RegExp(\n      '^/?(?<id>.+)/(?<region>.+)/(?<size>.+)/(?<rotation>.+)/(?<quality>.+)\\\\.(?<format>.+)$'\n    );\n\n    let result = infoJsonRe.exec(path)?.groups;\n    debug('info.json match result: %j', result);\n    if (result) return result;\n\n    result = transformRe.exec(path)?.groups;\n    debug('transform match result: %j', result);\n    if (result) {\n      for (const component of [\n        'region',\n        'size',\n        'rotation',\n        'quality',\n        'format'\n      ] as ValidatorKey[]) {\n        const validator = new RegExp(this._validator(component));\n        if (!validator.test(result[component] as string)) {\n          throw new IIIFError(`Invalid ${component} in IIIF path: ${path}`, {\n            statusCode: 400\n          });\n        }\n      }\n      return result;\n    }\n\n    result = idOnlyRe.exec(path)?.groups;\n    debug('ID only match result: %j', result);\n    if (result) return result;\n\n    throw new IIIFError(`Not a valid IIIF path: ${path}`, {\n      statusCode: 400\n    });\n  }\n\n  constructor(dims: Dimensions, opts: CalculatorOptions = {}) {\n    this.dims = { ...dims };\n    this.opts = { ...opts };\n    this._sourceDims = { ...dims };\n    this._canonicalInfo = {\n      region: 'full',\n      size: 'full',\n      rotation: '0',\n      quality: 'default',\n      format: 'jpg'\n    };\n    this._parsedInfo = {\n      region: { left: 0, top: 0, ...dims },\n      size: { width: dims.width, height: dims.height, fit: 'fill' },\n      rotation: { flop: false, degree: 0 },\n      quality: 'default',\n      format: { type: 'jpg' },\n      upscale: true\n    };\n  }\n\n  protected _validate(type: keyof typeof Validators | 'density', v: unknown) {\n    if (type === 'density') return validateDensity(v);\n    const re = new RegExp(`^${Base._validator(type)}$`);\n    debug('validating %s %s against %s', type, v, re);\n    if (!re.test(String(v))) {\n      throw new IIIFError(`Invalid ${type}: ${v}`, { statusCode: 400 });\n    }\n    return true;\n  }\n\n  region(v: string) {\n    this._validate('region', v);\n    const pct = PCTR.exec(v);\n    let isFull = false;\n    if (v === 'full') {\n      this._parsedInfo.region = { left: 0, top: 0, ...this.dims };\n      isFull = true;\n    } else if (v === 'square') {\n      this._parsedInfo.region = regionSquare(this.dims);\n    } else if (pct) {\n      this._parsedInfo.region = regionPct(pct.groups?.val as string, this.dims);\n    } else {\n      this._parsedInfo.region = regionXYWH(v);\n    }\n    this._canonicalInfo.region = isFull ? 'full' : this._parsedInfo.region;\n    this._constrainRegion();\n    return this;\n  }\n\n  size(v: string) {\n    this._validate('size', v);\n    const pct = PCTR.exec(v);\n    let isMax = false;\n    if (['full', 'max'].includes(v)) {\n      this._setSize(this._parsedInfo.region);\n      isMax = true;\n    } else if (pct) {\n      this._setSize(\n        sizePct(pct.groups?.val as string, this._parsedInfo.region)\n      );\n    } else {\n      this._setSize(sizeWH(v));\n    }\n    this._canonicalInfo.size = isMax ? v : this._canonicalSize();\n    return this;\n  }\n\n  rotation(v: string) {\n    this._validate('rotation', v);\n    this._canonicalInfo.rotation = v;\n    this._parsedInfo.rotation = {\n      flop: v[0] === '!',\n      degree: Number(v.replace(/^!/, ''))\n    };\n    return this;\n  }\n\n  quality(v: string) {\n    this._validate('quality', v);\n    this._canonicalInfo.quality = v;\n    this._parsedInfo.quality = v;\n    return this;\n  }\n\n  format(v: string, density?: number) {\n    this._validate('format', v);\n    this._validate('density', density);\n    this._canonicalInfo.format = v;\n    this._parsedInfo.format = { type: v, density };\n    return this;\n  }\n\n  info(): Calculated {\n    return {\n      ...this._parsedInfo,\n      fullSize: fullSize(this._sourceDims, this._parsedInfo)\n    } as Calculated;\n  }\n\n  canonicalPath() {\n    const { region, size, rotation, quality, format } = this._canonicalInfo;\n    return `${region}/${size}/${rotation}/${quality}.${format}`;\n  }\n\n  protected _setSize(v: BoundingBox | SizeDesc) {\n    const max: MaxDimensions = { ...(this.opts?.max || {}) };\n    max.height = max.height || max.width;\n    this._parsedInfo.size =\n      'left' in v\n        ? { width: v.width, height: v.height, fit: 'fill' }\n        : { ...v };\n    this._constrainSize(max);\n    return this;\n  }\n\n  protected _constrainSize(constraints: MaxDimensions) {\n    const full = fullSize(this._sourceDims, this._parsedInfo);\n    const constraint = minNum(\n      constraints.width / full.width,\n      constraints.height / full.height,\n      constraints.area / (full.width * full.height)\n    );\n    if (constraint < 1) {\n      if (this._parsedInfo.size.width) {\n        this._parsedInfo.size.width = Math.floor(\n          this._parsedInfo.size.width * constraint\n        );\n      }\n      if (this._parsedInfo.size.height) {\n        this._parsedInfo.size.height = Math.floor(\n          this._parsedInfo.size.height * constraint\n        );\n      }\n    }\n  }\n\n  protected _canonicalSize() {\n    const { width, height } = this._parsedInfo.size;\n    const result = `${width},${height}`;\n    return this._parsedInfo.size.fit === 'inside' ? `!${result}` : result;\n  }\n\n  protected _constrainRegion() {\n    let { left, top, width, height } = this._parsedInfo.region;\n    left = Math.max(left, 0);\n    top = Math.max(top, 0);\n    if (left > this.dims.width || top > this.dims.height) {\n      throw new IIIFError('Region is out of bounds', { statusCode: 400 });\n    }\n    width = Math.min(width, this.dims.width - left);\n    height = Math.min(height, this.dims.height - top);\n    this._parsedInfo.region = { left, top, width, height };\n  }\n}\n\nfunction minNum(...args: unknown[]) {\n  const nums = args.filter((arg) => typeof arg === 'number' && !isNaN(arg));\n  return Math.min(...(nums as number[]));\n}\n\nfunction fillMissingDimension(size: SizeDesc, aspect: number) {\n  if (!size.width && size.height != null)\n    size.width = Math.floor(size.height * aspect);\n  if (!size.height && size.width != null)\n    size.height = Math.floor(size.width / aspect);\n}\n\nfunction fullSize(dims: Dimensions, { region, size }: ParsedInfo) {\n  const regionAspect = region.width / region.height;\n  fillMissingDimension(size, regionAspect);\n  const scaleFactor = (size.width as number) / region.width;\n  const result = {\n    width: Math.floor(dims.width * scaleFactor),\n    height: Math.floor(dims.height * scaleFactor)\n  };\n  debug(\n    'Region %j at size %j yields full size %j, a scale factor of %f',\n    region,\n    size,\n    result,\n    scaleFactor\n  );\n  return result;\n}\n\nfunction regionSquare(dims: Dimensions): BoundingBox {\n  let result: BoundingBox = {\n    left: 0,\n    top: 0,\n    width: dims.width,\n    height: dims.height\n  };\n  if (dims.width !== dims.height) {\n    const side = Math.min(dims.width, dims.height);\n    result = { ...result, width: side, height: side };\n    const offset = Math.abs(Math.floor((dims.width - dims.height) / 2));\n    if (dims.width > dims.height) {\n      result.left = offset;\n      result.top = 0;\n    } else {\n      result.left = 0;\n      result.top = offset;\n    }\n  }\n  return result;\n}\n\nfunction regionPct(v: string, dims: Dimensions): BoundingBox {\n  let x: number, y: number, w: number, h: number;\n  [x, y, w, h] = v.split(/\\s*,\\s*/).map((pct) => Number(pct) / 100.0) as [\n    number,\n    number,\n    number,\n    number\n  ];\n  [x, w] = [x, w].map((val) => Math.floor(dims.width * val)) as [\n    number,\n    number\n  ];\n  [y, h] = [y, h].map((val) => Math.floor(dims.height * val)) as [\n    number,\n    number\n  ];\n  return regionXYWH([x, y, w, h]);\n}\n\nfunction regionXYWH(v: string | number[]): BoundingBox {\n  const parts: number[] =\n    typeof v === 'string' ? v.split(/\\s*,\\s*/).map((val) => Number(val)) : v;\n  const result: BoundingBox = {\n    left: parts[0],\n    top: parts[1],\n    width: parts[2],\n    height: parts[3]\n  };\n  if (result.width === 0 || result.height === 0) {\n    throw new IIIFError('Region width and height must both be > 0', {\n      statusCode: 400\n    });\n  }\n  return result;\n}\n\nfunction sizePct(v: string, dims: Dimensions) {\n  const pct = Number(v);\n  if (isNaN(pct) || pct <= 0) {\n    throw new IIIFError(`Invalid resize %: ${v}`, { statusCode: 400 });\n  }\n  const width = Math.floor(dims.width * (pct / 100.0));\n  return sizeWH(`${width},`);\n}\n\nfunction sizeWH(v: string) {\n  const result: SizeDesc = { fit: 'fill' };\n  if (v[0] === '!') {\n    result.fit = 'inside';\n    v = v.slice(1);\n  }\n  const parts: (number | null)[] = v\n    .split(/\\s*,\\s*/)\n    .map((val) => (val === '' ? null : Number(val)));\n  [result.width, result.height] = parts as [number | null, number | null];\n  if (result.width === 0 || result.height === 0) {\n    throw new IIIFError('Resize width and height must both be > 0', {\n      statusCode: 400\n    });\n  }\n  return result;\n}\n\nexport default { Base, Qualities, Formats };\n","import { Base } from './base';\n\nexport class Calculator extends Base {}\n\nexport * from './base';\n\nexport default { Calculator };\n","import { CalculatorOptions } from '../contracts';\nimport { Base, ValidatorMap } from './base';\nimport { IIIFError } from '../error';\n\nexport class Calculator extends Base {\n  static _matchers(): ValidatorMap {\n    const result: ValidatorMap = { ...super._matchers() };\n    result.size = [...result.size].reduce(\n      (sizes: string[], pattern: string) => {\n        if (pattern !== 'full') sizes.push(`\\\\^?${pattern}`);\n        return sizes;\n      },\n      [] as string[]\n    );\n    return result;\n  }\n\n  constructor(\n    dims: { width: number; height: number },\n    opts: CalculatorOptions = {}\n  ) {\n    super(dims, opts);\n    this._canonicalInfo.size = 'max';\n    this._parsedInfo.upscale = false;\n  }\n\n  size(v: string) {\n    if (v[0] === '^') {\n      this._parsedInfo.upscale = true;\n      v = v.slice(1, v.length);\n    }\n    super.size(v);\n    const { region, size, upscale } = this._parsedInfo;\n    if (!upscale) {\n      if (size.width > region.width || size.height > region.height) {\n        throw new IIIFError('Requested size requires upscaling', {\n          statusCode: 400\n        });\n      }\n    }\n    return this;\n  }\n}\n\nexport * from './base';\n\nexport default { Calculator };\n"],"mappings":"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","names":["Calculator"]}