{
  "version": 3,
  "sources": ["hatch_core.js"],
  "sourcesContent": ["/*\n * static/js/hatch_core.js \u2014 the diagonal-hatch tile the downloaded-areas\n * overlay is painted with.\n *\n * The downloaded squares and the danger choropleth fill the same polygons.\n * As two translucent tints they were unreadable together \u2014 worse, a green\n * wash over a yellow region reads as a danger colour that region does not\n * have \u2014 so SNOW-656 made the two mutually exclusive. A hatch makes no\n * colour claim: it covers a third of the area in hard-edged strokes and\n * leaves the rest showing whatever is underneath, which is how an atlas\n * draws one area layer over another. That is what lets both be on at once.\n *\n * This module owns the PIXELS, not the colour: `map.js` resolves a basemap's\n * identity colour (a CSS token value, so possibly `oklch()` \u2014 parsed by a\n * 1\u00D71 canvas fill, because nothing else parses every CSS colour syntax) and\n * passes the three channels in. Everything here is arithmetic, which is the\n * half worth testing: the stroke spacing has one invariant that fails\n * silently, and a seam down every pattern tile is not something a unit test\n * of `map.js` could ever catch.\n *\n * THE INVARIANT: `PERIOD` must divide `SIZE` exactly. A 45\u00B0 stroke is the\n * set of pixels where `(x + y) mod PERIOD` is under `WIDTH`; that repeats\n * with period `PERIOD` along both axes, so the image only tiles seamlessly\n * when its edge is a whole number of periods. Get it wrong and MapLibre\n * repeats an image whose right edge does not continue into its own left one\n * \u2014 a visible grid of joins, at every zoom, on every downloaded area.\n * `tilesSeamlessly()` states it as a predicate so the test asserts the\n * property rather than a hard-coded pixel count.\n *\n * Exports (frozen `self.pwaHatchCore`):\n *\n *   SIZE / PERIOD / WIDTH\n *   hatchPixels(r, g, b)   \u2014 a MapLibre StyleImage: {width, height, data}\n *   tilesSeamlessly(size, period)\n */\n\n// @ts-check\n\n(function () {\n  'use strict';\n\n  /**\n   * The image edge, in device pixels. Added to the map at `pixelRatio: 2`,\n   * so this is 6 CSS pixels on screen \u2014 fine enough to read as texture at\n   * country zoom, coarse enough that the colour underneath shows between\n   * the strokes rather than being averaged away.\n   */\n  const SIZE = 12;\n\n  /** Device pixels from one stroke to the next. Must divide `SIZE`. */\n  const PERIOD = 6;\n\n  /** Stroke thickness in device pixels \u2014 a third of the period, so a third\n   * of the area is covered and two thirds show the layer below. */\n  const WIDTH = 2;\n\n  /**\n   * Whether an image of `size` tiles seamlessly at `period`.\n   *\n   * @param {number} size Image edge in pixels.\n   * @param {number} period Pixels between strokes.\n   * @returns {boolean}\n   */\n  function tilesSeamlessly(size, period) {\n    return period > 0 && size % period === 0;\n  }\n\n  /**\n   * The hatch as raw RGBA, in one colour.\n   *\n   * Alpha is binary \u2014 a stroke pixel is fully opaque, everything else fully\n   * transparent \u2014 and the layer's `fill-opacity` is the single knob for how\n   * strongly the whole hatch reads. Two multiplying alphas would mean\n   * neither number is the one to tune.\n   *\n   * @param {number} r Red, 0\u2013255.\n   * @param {number} g Green, 0\u2013255.\n   * @param {number} b Blue, 0\u2013255.\n   * @returns {{width: number, height: number, data: Uint8ClampedArray}}\n   *   A MapLibre StyleImage.\n   */\n  function hatchPixels(r, g, b) {\n    const data = new Uint8ClampedArray(SIZE * SIZE * 4);\n    for (let y = 0; y < SIZE; y += 1) {\n      for (let x = 0; x < SIZE; x += 1) {\n        const i = (y * SIZE + x) * 4;\n        data[i] = r;\n        data[i + 1] = g;\n        data[i + 2] = b;\n        data[i + 3] = (x + y) % PERIOD < WIDTH ? 255 : 0;\n      }\n    }\n    return { width: SIZE, height: SIZE, data: data };\n  }\n\n  self.pwaHatchCore = Object.freeze({\n    SIZE: SIZE,\n    PERIOD: PERIOD,\n    WIDTH: WIDTH,\n    hatchPixels: hatchPixels,\n    tilesSeamlessly: tilesSeamlessly,\n  });\n})();\n"],
  "mappings": "CAsCC,UAAY,CACX,aAwBA,SAASA,EAAgBC,EAAMC,EAAQ,CACrC,OAAOA,EAAS,GAAKD,EAAOC,IAAW,CACzC,CAgBA,SAASC,EAAYC,EAAGC,EAAGC,EAAG,CAC5B,MAAMC,EAAO,IAAI,kBAAkB,GAAe,EAClD,QAASC,EAAI,EAAGA,EAAI,GAAMA,GAAK,EAC7B,QAASC,EAAI,EAAGA,EAAI,GAAMA,GAAK,EAAG,CAChC,MAAMC,GAAKF,EAAI,GAAOC,GAAK,EAC3BF,EAAKG,CAAC,EAAIN,EACVG,EAAKG,EAAI,CAAC,EAAIL,EACdE,EAAKG,EAAI,CAAC,EAAIJ,EACdC,EAAKG,EAAI,CAAC,GAAKD,EAAID,GAAK,EAAS,EAAQ,IAAM,CACjD,CAEF,MAAO,CAAE,MAAO,GAAM,OAAQ,GAAM,KAAMD,CAAK,CACjD,CAEA,KAAK,aAAe,OAAO,OAAO,CAChC,KAAM,GACN,OAAQ,EACR,MAAO,EACP,YAAaJ,EACb,gBAAiBH,CACnB,CAAC,CACH,GAAG",
  "names": ["tilesSeamlessly", "size", "period", "hatchPixels", "r", "g", "b", "data", "y", "x", "i"]
}
