{
  "version": 3,
  "sources": ["/cdn/shop/t/16/assets/build-your-rig.js?b=36970034d5"],
  "sourcesContent": ["/* Build your rig: Kinetic-X rope calculator. No outside libraries.\n * Data: assets/rig_data.json (from rig_data_v1_1.txt, scripts/build_your_rig/convert_rig_data.py).\n * Spec: coder_brief_FINAL_build_your_rig.md. Rope = size for the rig doing the pulling.\n */\n(function (root) {\n  'use strict';\n\n  // Vehicle pictures in Shopify Files: <image>.webp (1600 wide), <image>-800.webp.\n  var IMAGE_BASE = 'https://cdn.shopify.com/s/files/1/0663/3717/7821/files/';\n  // The paint mask's file name after the image id. Justin's v6 masks went up\n  // as <id>-mask2.png (11/4); the v7 masks (roof-edge and pillar dashes\n  // closed) as <id>-mask4.png (owner 11/4); the v8 masks (v7 with tinted\n  // glass kept unpainted: the owner caught painted rear glass on the Lexus\n  // GX) as <id>-mask5.png (11/4, checked pixel for pixel by Justin).\n  // v10 masks, full rebuild 11/4: trim/glass/lamps unpainted, hand-checked in\n  // white; every rig asks for <id>-mask10.png (the per-rig -mask6..9\n  // overrides are superseded, data mask_overrides is empty). Rollback:\n  // MASK_FILE back to '-mask5.png' and data/mask_overrides_superseded.json\n  // back into data/mask_overrides.json; the old files stay in Files.\n  var MASK_FILE = '-mask10.png';\n  // Real factory-colour pictures (owner 11/6): the body is no longer\n  // repainted through the masks. The swatches of the 220 trucks with real\n  // colours (8 pilot, 212 batch 1) swap in a real\n  // picture of that colour (data.real_colors: base image -> colour name ->\n  // Files id; <id>.png 1600 wide, <id>-800.png, pixel-aligned with the olive\n  // rig picture); every other rig shows its olive picture, no swatches.\n  // PAINT_ON true rolls back to the repaint (all of its code is still here).\n  var PAINT_ON = false;\n  // The rigs' army green (median body pixel): a fiberglass cap is body\n  // colour, so on an olive picture it takes this\n  var OLIVE_PAINT = '#5a633c';\n  // The build hash (owner 11/4): the section stamps it on the script and data\n  // URLs and on data-build; init() reads it here and the mask fetches carry\n  // it too, so a phone can't run old code or old masks after a deploy.\n  var BUILD = '';\n  // Per-rig masks (Justin, full-catalog sweep 11/4): 63 rigs whose glass was\n  // painted have fixed masks under another name; rig_data.json carries the\n  // map (mask_overrides: image id -> '-mask6.png' ...), so it is part of the\n  // build hash. Every other rig asks for MASK_FILE.\n  var maskOverrides = {};\n  var MASK_SUFFIX = /^-mask\\d*\\.png$/;\n  function maskFileFor(image) {\n    var f = Object.prototype.hasOwnProperty.call(maskOverrides, image) ? maskOverrides[image] : null;\n    return typeof f === 'string' && MASK_SUFFIX.test(f) ? f : MASK_FILE;\n  }\n  function setMaskOverrides(map) { maskOverrides = map && typeof map === 'object' ? map : {}; }\n  function maskUrl(base, image) { return base + image + maskFileFor(image) + (BUILD ? '?b=' + BUILD : ''); }\n\n  // Ram 3500 has its own derived entry, so the shared rows read as 2500 here.\n  var MODEL_LABELS = { 'Ram 2500 / 3500 (SRW)': 'Ram 2500 (SRW)' };\n\n  var SIZE_NOTE = 'Size your rope to the rig doing the pulling, not the stuck rig. ' +\n    'A rope too big for the pulling rig won\\u2019t stretch and can break parts.';\n\n  // Driver only (owner 11/11, coder_brief_byr_driver_only.md): in a recovery\n  // everyone but the driver is out of the rig, so step 2 counts one driver at\n  // per_adult_lb and nobody else (per_kid_lb and per_dog_lb stay in the data,\n  // unused); adults / kids / dogs in an old link or input are ignored\n  var DRIVER_NOTE = 'Sized for the driver only. Everyone else gets out and stands well clear before any pull.';\n  // The customer's own add-on weights (owner 11/11, coder_brief_byr_addon_weight_edit.md):\n  // a ticked (or page-added) chip's weight is its own tap target; whole lb in\n  // this range, else refused; the number counts everywhere the add-on's weight does\n  var GEAR_LB_LIMITS = [1, 5000];\n  var GEAR_EDIT_HELP = 'Know what yours weighs? Tick it, then tap the weight to change it.';\n  // \"Know your rig's weight?\" (owner 11/10): a weight the customer enters\n  // takes the row's curb weight's place; outside this range it's ignored\n  // (owner 11/11: the top raised from 40,000 to 200,000 lb)\n  var OWN_LIMITS = [1500, 200000];\n  // The kit builder's words on this page (owner 11/12, drafts)\n  var KIT_BUTTON = 'Build a kit for this rig';\n  var USE_BUTTON = 'Use this rig';\n  // The last rig sized, kept in the browser for the kit builder (owner 11/12):\n  // { name, lb (loaded), size, heavy, q (the link's query), own (typed in the\n  // builder as a weight), at }. The kit builder reads the same key.\n  var RIG_KEY = 'sandycats-rig';\n  function saveRig(s) {\n    if (!s) return;\n    try {\n      root.localStorage.setItem(RIG_KEY, JSON.stringify({\n        name: s.name, lb: s.lb, size: s.size, heavy: !!s.heavy, q: s.q || '', own: !!s.own, at: Date.now()\n      }));\n    } catch (ignore) { /* private mode or storage full: not remembered */ }   // eslint-disable-line no-unused-vars\n  }\n  function readRig() {\n    try {\n      var s = JSON.parse(root.localStorage.getItem(RIG_KEY) || 'null');\n      return s && typeof s.name === 'string' && s.lb > 0 && typeof s.size === 'string' ? s : null;\n    } catch (ignore) { return null; }   // eslint-disable-line no-unused-vars\n  }\n\n  // ------------------------------------------------------------------ logic\n\n  function modelLabel(model) {\n    return MODEL_LABELS[model] || model;\n  }\n\n  // Under the result's buttons (layout round 1, exact wording: brand rule)\n  var TRUST_LINE = 'Independently tested in California. Backed for the life of the product.';\n  // Product pages link here as ?from=<product handle> (owner approved): the\n  // result's main button is then that product in the result's size. Only\n  // these handles count; any other \"from\" is ignored (today's result).\n  var FROM_HANDLES = ['standard-recovery-kit', 'ultimate-recovery-kit', 'ultimate-recovery-kit-backcountry-red',\n    'ultimate-recovery-kit-kilo-black', 'ultimate-recovery-kit-shrek-green', 'ultimate-recovery-kit-revmaster-blue',\n    'titan-recovery-kit', 'titan-pro-recovery-kit', 'sandy-cats-kinetic-recovery-rope'];\n  /** The \"from\" handle in a query string ('?rig=..&from=ultimate-recovery-kit'), or null when absent or unknown. */\n  function fromHandle(search) {\n    var m = /[?&]from=([^&#]*)/.exec(String(search || ''));\n    if (!m) return null;\n    var h;\n    try {\n      h = decodeURIComponent(m[1].replace(/\\+/g, ' ')).trim().toLowerCase();\n    } catch (ignore) {   // eslint-disable-line no-unused-vars\n      return null;   // a broken escape: ignored\n    }\n    return FROM_HANDLES.indexOf(h) >= 0 ? h : null;\n  }\n  /**\n   * A product's page in a rope size (product: /products/<handle>.js): the\n   * variant whose title starts with the size x 30', else any variant of that\n   * size, else the product page with no variant.\n   */\n  function sizeVariant(handle, product, size) {\n    var norm = function (t) { return String(t || '').replace(/[\\u201c\\u201d\\u2033]/g, '\"').replace(/[\\u2018\\u2019\\u2032]/g, \"'\").trim(); };\n    var sz = norm(size);\n    var vs = (product && product.variants) || [];\n    var pick = function (prefix) { for (var i = 0; i < vs.length; i++) if (norm(vs[i].title).indexOf(prefix) === 0) return vs[i]; return null; };\n    var v30 = pick(sz + \" x 30'\");\n    var v = v30 || pick(sz + ' ');\n    return { url: '/products/' + handle + (v && v.id ? '?variant=' + v.id : ''), is30: !!(v30 && v30.id) };\n  }\n  function sizeVariantUrl(handle, product, size) { return sizeVariant(handle, product, size).url; }\n  /**\n   * The result card's kit links for a rope band (null for Heavy Duty): main\n   * {text, url}, step (the Titan step-up link or null), ultimate (or null),\n   * rope (false: no \"Shop the X rope\", the main button already goes there).\n   * No \"from\" (or its product not loaded): the Titan kit, then the Ultimate.\n   * Owner's tweaks to #171: from the rope page no rope button (the step-up\n   * stays); from the Titan or the Titan Pro no step-up line.\n   */\n  function kitLinks(rope, from, product) {\n    if (!rope || rope.rec_max_lb == null || !rope.titan_url) return null;\n    if (!from || !product || !product.title) {\n      return { main: { text: 'Get the Titan Recovery Kit with this rope', url: rope.titan_url }, step: null, ultimate: rope.ultimate_url || null, rope: true };\n    }\n    var sv = sizeVariant(from, product, rope.size);\n    // from the rope page (owner's wording): \"Get the 3/4\" \u00D7 30' rope\", or\n    // \"Get the 3/4\" rope\" when it fell back to another length or the page\n    var isRope = from === 'sandy-cats-kinetic-recovery-rope';\n    var mainText = isRope ? 'Get the ' + rope.size + (sv.is30 ? ' \\u00d7 30\\' rope' : ' rope') : 'Get the ' + product.title + ' with this rope';\n    return {\n      main: { text: mainText, url: sv.url },\n      step: from === 'titan-recovery-kit' || from === 'titan-pro-recovery-kit' ? null : rope.titan_url,\n      ultimate: from.indexOf('ultimate-recovery-kit') === 0 ? null : rope.ultimate_url || null,\n      rope: !isRope\n    };\n  }\n  // Under \"Heavy Duty\" (layout round 1 check, 11/4)\n  var HEAVY_LINE = 'Over 15,000 lb. You need 1.5\" rope or bigger from our Heavy Duty line.';\n\n  // Before a rig is picked (owner picked \"Placeholder idea 3\", 11/5): a\n  // showroom loop of real rigs, painted by the renderer like a picked rig,\n  // and one-tap quick picks. Change either list here.\n  // SHOWROOM: rig id (data.vehicles), factory colour name (its colour set),\n  // the year in the caption \"<year> <model> \u00B7 <colour>\".\n  var SHOWROOM = [\n    { rig: 'toyota-tacoma-4th-gen-double-cab-4x4-gas', color: 'Blueprint', year: 2024 },\n    { rig: 'jeep-wrangler-jl-unlimited-4-door-gas', color: 'Firecracker Red', year: 2024 },\n    { rig: 'ford-f-150-14th-gen-supercrew-4x4', color: 'Azure Gray', year: 2021 },\n    { rig: 'ford-bronco-6th-gen-4-door', color: 'Cactus Gray', year: 2021 }\n  ];\n  var SHOWROOM_MS = 3000;   // each rig this long, then a crossfade\n  // QUICK_PICKS: the chip's label, and the Make and Model it fills\n  var QUICK_PICKS = [\n    { label: 'Tacoma', make: 'Toyota', model: 'Tacoma' },\n    { label: 'Wrangler', make: 'Jeep', model: 'Wrangler' },\n    { label: 'F-150', make: 'Ford', model: 'F-150' },\n    { label: '4Runner', make: 'Toyota', model: '4Runner' },\n    { label: 'Bronco', make: 'Ford', model: 'Bronco' },\n    { label: 'Silverado', make: 'Chevrolet/GMC', model: 'Silverado 1500 / Sierra 1500' },\n    { label: 'Ram 1500', make: 'Ram/Dodge', model: 'Ram 1500' },\n    { label: 'Super Duty', make: 'Ford', model: 'F-250 / F-350 (SRW)' }\n  ];\n  /** The showroom entries that resolve: [{ v (vehicle row), c (colour), caption }]; an id or colour the data doesn't have is skipped. */\n  function showroomEntries(data) {\n    var out = [];\n    SHOWROOM.forEach(function (sr) {\n      var v = null;\n      data.vehicles.forEach(function (x) { if (x.id === sr.rig) v = x; });\n      var set = v && data.colorsets[v.colorset];\n      var c = null;\n      ((set && set.colors) || []).forEach(function (x) { if (x.name === sr.color) c = x; });\n      if (v && c) out.push({ v: v, c: c, caption: (sr.year ? sr.year + ' ' : '') + modelLabel(v.model) + ' \\u00b7 ' + c.name });\n    });\n    return out;\n  }\n  // Makes A-Z, the catch-alls last (Justin's layout round 1, 11/4)\n  var MAKES_LAST = ['Crossover / unibody SUV', 'UTV'];\n  function makes(data) {\n    var out = [];\n    data.vehicles.forEach(function (v) { if (out.indexOf(v.make) < 0) out.push(v.make); });\n    var last = function (m) { return MAKES_LAST.indexOf(m); };   // -1: an ordinary make, first\n    return out.sort(function (a, b) {\n      if (last(a) !== last(b)) return last(a) - last(b);\n      return a.toLowerCase() < b.toLowerCase() ? -1 : a.toLowerCase() > b.toLowerCase() ? 1 : 0;\n    });\n  }\n\n  /** Models of a make in data order; a derived model follows its base model. */\n  function models(data, make) {\n    var out = [];\n    data.vehicles.forEach(function (v) {\n      if (v.make !== make || out.some(function (m) { return m.model === v.model; })) return;\n      out.push({ model: v.model, label: modelLabel(v.model), derived: null });\n      data.derived.forEach(function (d) {\n        if (d.make === make && d.base_model === v.model) {\n          out.push({ model: d.model, label: modelLabel(d.model), derived: d });\n        }\n      });\n    });\n    return out;\n  }\n\n  function findDerived(data, make, model) {\n    for (var i = 0; i < data.derived.length; i++) {\n      var d = data.derived[i];\n      if (d.make === make && d.model === model) return d;\n    }\n    return null;\n  }\n\n  function covers(v, year) { return v.year_from <= year && year <= v.year_to; }\n\n  /** Every year any row of the model covers, newest first. */\n  function years(data, make, model) {\n    var d = findDerived(data, make, model);\n    var base = d ? d.base_model : model;\n    var set = {};\n    data.vehicles.forEach(function (v) {\n      if (v.make !== make || v.model !== base) return;\n      for (var y = v.year_from; y <= v.year_to; y++) {\n        if (!d || (d.year_from <= y && y <= d.year_to)) set[y] = true;\n      }\n    });\n    return Object.keys(set).map(Number).sort(function (a, b) { return b - a; });\n  }\n\n  /** The rows that cover the year, as calculator rows (derived: base row + add_lb). */\n  function trims(data, make, model, year) {\n    var d = findDerived(data, make, model);\n    var base = d ? d.base_model : model;\n    var rows = data.vehicles.filter(function (v) {\n      return v.make === make && v.model === base && covers(v, year);\n    }).map(function (v) {\n      if (!d) return Object.assign({}, v, { key: v.id, base_curb_lb: null, add_lb: 0 });\n      return Object.assign({}, v, {\n        key: d.model + '|' + v.id,\n        model: d.model,\n        curb_lb: v.curb_lb + d.add_lb,\n        base_curb_lb: v.curb_lb,\n        base_model: base,\n        add_lb: d.add_lb\n      });\n    });\n    var gens = {};\n    rows.forEach(function (r) { gens[r.generation] = true; });\n    var showGen = Object.keys(gens).length > 1;\n    rows.forEach(function (r) { r.label = showGen ? r.trim + ' (' + r.generation + ')' : r.trim; });\n    return rows;\n  }\n\n  function num(x, lo, hi) {\n    var n = typeof x === 'number' ? x : parseFloat(x);\n    if (!isFinite(n)) n = lo || 0;\n    if (lo != null && n < lo) n = lo;\n    if (hi != null && n > hi) n = hi;\n    return n;\n  }\n\n  /**\n   * The customer's own rig weight (lb, whole), or null: empty, not a number,\n   * or outside OWN_LIMITS (then the row's curb weight is used). Commas,\n   * spaces and a trailing \"lb\" are allowed.\n   */\n  function ownWeight(x) {\n    if (x == null) return null;\n    var s = String(x).replace(/[,\\s]/g, '').replace(/lbs?\\.?$/i, '');\n    if (!/^\\d+(\\.\\d+)?$/.test(s)) return null;\n    var n = Math.round(parseFloat(s));\n    return n >= OWN_LIMITS[0] && n <= OWN_LIMITS[1] ? n : null;\n  }\n\n  /**\n   * A customer's add-on weight (whole lb, GEAR_LB_LIMITS; commas, spaces and\n   * a trailing \"lb\" allowed), or null: empty, not a whole number, out of range.\n   */\n  function gearLbValue(x) {\n    if (x == null) return null;\n    var s = String(x).replace(/[,\\s]/g, '').replace(/lbs?\\.?$/i, '');\n    if (!/^\\d+$/.test(s)) return null;\n    var n = parseInt(s, 10);\n    return n >= GEAR_LB_LIMITS[0] && n <= GEAR_LB_LIMITS[1] ? n : null;\n  }\n\n  /** {id: lb} with the ids and weights that pass (gearLbValue); anything else dropped. */\n  function cleanGearLb(map) {\n    var out = {};\n    Object.keys(map || {}).forEach(function (id) {\n      var n = gearLbValue(map[id]);\n      if (n != null) out[id] = n;\n    });\n    return out;\n  }\n\n  /**\n   * &gearlb=<id>:<lb>,... -> {id: lb}: only ids in gear (the link's &gear=)\n   * with a weight in range; anything else is ignored.\n   */\n  function parseGearLb(str, gear) {\n    var out = {};\n    String(str || '').split(',').forEach(function (part) {\n      var m = /^\\s*([a-z0-9_]+)\\s*:\\s*([^,]+?)\\s*$/i.exec(part);\n      var n = m ? gearLbValue(m[2]) : null;\n      if (n != null && (gear || []).indexOf(m[1]) >= 0) out[m[1]] = n;\n    });\n    return out;\n  }\n\n  /** The link's &gearlb= value for the customer's weights ('' when there are none). */\n  function gearLbQuery(edits) {\n    return Object.keys(edits || {}).filter(function (id) { return gearLbValue(edits[id]) != null; })\n      .map(function (id) { return id + ':' + gearLbValue(edits[id]); }).join(',');\n  }\n\n  /**\n   * Clean inputs: weights and gallons are >= 0; own: ownWeight. People are\n   * the driver alone (adults / kids / dogs, if given, are ignored).\n   */\n  function cleanInputs(inp) {\n    inp = inp || {};\n    return {\n      gallons: num(inp.gallons, 0, null),\n      other: num(inp.other, 0, null),\n      gear: (inp.gear || []).slice(),\n      own: ownWeight(inp.own),\n      gearLb: cleanGearLb(inp.gearLb),   // the customer's own add-on weights {id: lb}\n      noAutoSpare: !!inp.noAutoSpare,    // the swing-out's spare dismissed (owner 11/11)\n      opts: (inp.opts || []).map(function (i) { var n = parseInt(i, 10); return n >= 0 ? n : 0; })\n    };\n  }\n\n  /** First band whose rec_max_lb is at or above the weight. Hard lines, no rounding. */\n  function pickRope(data, weight) {\n    for (var i = 0; i < data.ropes.length; i++) {\n      var r = data.ropes[i];\n      if (r.rec_max_lb == null || weight <= r.rec_max_lb) return r;\n    }\n    return data.ropes[data.ropes.length - 1];\n  }\n\n  /**\n   * A row's factory options as picked (owner 11/11, bed length): one choice a\n   * group, by index in opts (out of range or missing: the first, add_lb 0).\n   * -> [{ group, choice, index }], [] for a row with no options.\n   */\n  function rowOptions(row, opts) {\n    return ((row && row.options) || []).map(function (g, k) {\n      var i = opts && opts[k] >= 0 && opts[k] < g.choices.length ? opts[k] : 0;\n      return { group: g.group, choice: g.choices[i], index: i };\n    });\n  }\n\n  /**\n   * A choice as the picker shows it: a Bed choice with \" bed\" after it (\"6.5 ft\n   * bed\"); any other group's (Engine, Trim, Model, Battery / trim) as written\n   * (\"7.3L V8\", \"Platinum\").\n   */\n  function optionLabel(group, choice) {\n    return optionKey(group) === 'bed' ? choice.label + ' bed' : choice.label;\n  }\n\n  /** A group's name in a link: lower case, a dash for each run of other characters (\"Battery / trim\" -> \"battery-trim\"). */\n  function optionKey(group) {\n    return String(group).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');\n  }\n\n  /**\n   * The link's &opt= value for a row's picks: every group, \"<key>:<place from 0>\",\n   * comma separated (\"bed:1,engine:1\"); '' for a row with no options.\n   */\n  function optionQuery(row, opts) {\n    return rowOptions(row, opts).map(function (o) { return optionKey(o.group) + ':' + o.index; }).join(',');\n  }\n\n  function compute(data, row, inputs) {\n    var inp = cleanInputs(inputs);\n    var gearById = {};\n    data.gear.forEach(function (g) { gearById[g.id] = g; });\n    // One pick per group (the last one wins); each item counts once.\n    var lastInGroup = {};\n    inp.gear.forEach(function (id, i) { var g = gearById[id]; if (g && g.group) lastInGroup[g.group] = i; });\n    var picked = [];\n    inp.gear.forEach(function (id, i) {\n      var g = gearById[id];\n      if (!g || picked.indexOf(g) >= 0 || (g.group && lastInGroup[g.group] !== i)) return;\n      picked.push(g);\n    });\n    // A tent on a pickup sits on a cab-height bed rack: add one (and its weight)\n    // when the customer hasn't picked it.\n    var tent = picked.some(function (g) { return g.group === 'rtt'; });\n    if (tent && row.body_type === 'pickup' && gearById.bedrack && picked.indexOf(gearById.bedrack) < 0) {\n      picked.push(Object.assign({}, gearById.bedrack, { auto: true }));\n    }\n    // The swing-out carries a full-size spare (Justin FINAL 11/3: 200 lb + the\n    // spare's weight), unless the rig keeps its factory rear-door spare.\n    var carrier = picked.some(function (g) { return g.id === 'bumper_r_carrier'; });\n    // (owner 11/11: the customer can dismiss that spare, noAutoSpare, until the swing-out is unticked)\n    if (carrier && !row.has_rear_spare && !inp.noAutoSpare && gearById.spare && picked.indexOf(gearById.spare) < 0) {\n      picked.push(Object.assign({}, gearById.spare, { auto: true }));\n    }\n    // each add-on at its weight for this rig (lb_by_tire_in, lb_by_size; owner 11/11)\n    var pickedIds = picked.map(function (g) { return g.id; });\n    picked = picked.map(function (g) { return g.lb_by_size || g.lb_by_tire_in ? Object.assign({}, g, { lb: gearLb(g, row, pickedIds) }) : g; });\n    // ... or the customer's own number for it (owner 11/11): edited, our_lb kept\n    picked = picked.map(function (g) {\n      var mine = inp.gearLb[g.id];\n      return mine != null ? Object.assign({}, g, { lb: mine, edited: true, our_lb: g.lb }) : g;\n    });\n    var gearLbSum = picked.reduce(function (s, g) { return s + g.lb; }, 0);\n    var own = inp.own != null;   // the customer's own weight replaces the row's curb weight\n    // factory options (bed length): their add_lb on the row's curb weight; none\n    // with the customer's own weight (it already includes them)\n    var opts = own ? [] : rowOptions(row, inp.opts);\n    var optLb = opts.reduce(function (s, o) { return s + o.choice.add_lb; }, 0);\n    var parts = {\n      curb: own ? inp.own : row.curb_lb + optLb,\n      baseline: data.baseline_lb,\n      driver: data.per_adult_lb,   // the driver, always one (owner 11/11)\n      fuel: inp.gallons * data.lb_per_gal,\n      gear: gearLbSum,\n      other: inp.other\n    };\n    var loaded = parts.curb + parts.baseline + parts.driver +\n      parts.fuel + parts.gear + parts.other;\n    // Always the added-up weight (owner 11/4: the camper / chassis-cab switch\n    // that sized to the GVWR is gone; it only worked on rigs with a GVWR, and\n    // campers and flatbeds are in the gear list by their real weight).\n    var used = loaded;\n    return {\n      inputs: inp, parts: parts, gear: picked, loaded: loaded, own: own, opts: opts,\n      used: used, rope: pickRope(data, used)\n    };\n  }\n\n  /**\n   * The \"close call\" note in the answer card (owner 11/10): the weight used\n   * is within data.close_call_lb of a sizing line (ropes[].rec_max_lb),\n   * either side. It only informs: the rope is still pickRope's. Under a\n   * line, N is what steps up (as bandLine's \"Add N lb more\"); over it, how\n   * far past. No note over the top line (Heavy Duty), or without\n   * close_call_lb. -> { side: 'under' | 'over', lb, size, text } or null.\n   */\n  function closeCall(data, weight) {\n    var band = data && data.close_call_lb;\n    if (!(band > 0) || !(weight >= 0)) return null;\n    var ropes = data.ropes;\n    for (var i = 0; i < ropes.length - 1; i++) {\n      var line = ropes[i].rec_max_lb;\n      if (line == null) continue;\n      var small = ropes[i].size;\n      var big = ropes[i + 1].size;\n      if (weight <= line) {\n        var under = Math.max(1, Math.ceil(line + 1 - weight));\n        if (under > band) return null;\n        return { side: 'under', lb: under, size: big,\n          text: 'Close call: you\\u2019re ' + fmt(under) + ' lb under the line for the ' + big + '. If you usually run heavier than this, size up.' };\n      }\n      if (ropes[i + 1].rec_max_lb == null) return null;   // over the top line: Heavy Duty, no note\n      var over = Math.max(1, Math.floor(weight - line));\n      if (over <= band) {\n        return { side: 'over', lb: over, size: small,\n          text: 'Close call: you\\u2019re ' + fmt(over) + ' lb over the line for the ' + small + '. If you usually run lighter than this, the ' + small + ' fits.' };\n      }\n    }\n    return null;\n  }\n\n  // ---------------------------------------------------------------- repaint\n  // The body is repainted through the rig's mask (<image> + MASK_FILE, white =\n  // paint). The army green is dropped: each masked pixel keeps only its\n  // brightness relative to the typical body pixel. Shade scales the new\n  // colour (same light, different paint); brighter-than-body light\n  // (highlights, reflections) is added on top as white light. Everything\n  // outside the mask (glass, tyres, chrome, trim) is left as it is.\n  // The mask is a hard yes / no (owner 11/3): a pixel is painted when its\n  // mask value is over MASK_ON, fully, and never otherwise. Justin's own\n  // renders use mask > 128; the page used to blend by the mask value, so\n  // feathered or grey values round the glass got part-painted (ragged glass).\n  var MASK_ON = 128;\n  var LIGHT_CAP = 0.72;   // very light paints sit a little below pure white so highlights still show\n  var S2L = new Float32Array(256);\n  var L2S_N = 4096;\n  var L2S = new Uint8ClampedArray(L2S_N + 1);\n  (function () {\n    for (var i = 0; i < 256; i++) {\n      var c = i / 255;\n      S2L[i] = c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n    }\n    for (var j = 0; j <= L2S_N; j++) {\n      var l = j / L2S_N;\n      L2S[j] = Math.round(255 * (l <= 0.0031308 ? l * 12.92 : 1.055 * Math.pow(l, 1 / 2.4) - 0.055));\n    }\n  })();\n\n  function toSrgb(l) { return L2S[l <= 0 ? 0 : l >= 1 ? L2S_N : (l * L2S_N + 0.5) | 0]; }\n\n  function hexLinear(hex) {\n    var v = parseInt(String(hex).replace('#', ''), 16);\n    return [S2L[(v >> 16) & 255], S2L[(v >> 8) & 255], S2L[v & 255]];\n  }\n\n  /**\n   * Index the masked pixels (mask > MASK_ON) once per rig: position,\n   * luminance, body median. Also the alignment check (owner 11/4): the\n   * masked pixels' box, the rig silhouette's box (alpha > 128) and how many\n   * masked pixels land outside the silhouette; w is the pixel grid's width.\n   */\n  function prepPaint(px, maskPx, w) {\n    var n = px.length >> 2;\n    var count = 0;\n    var k;\n    for (k = 0; k < n; k++) if (maskPx[k * 4] > MASK_ON) count++;\n    var idx = new Uint32Array(count);\n    var Y = new Float32Array(count);\n    var BINS = 4096;\n    var hist = new Uint32Array(BINS);\n    var p = 0;\n    var mb = [1e9, 1e9, -1, -1];\n    var ab = [1e9, 1e9, -1, -1];\n    var outside = 0;\n    var box = function (bx, x, y) { if (x < bx[0]) bx[0] = x; if (y < bx[1]) bx[1] = y; if (x > bx[2]) bx[2] = x; if (y > bx[3]) bx[3] = y; };\n    for (k = 0; k < n; k++) {\n      var o = k * 4;\n      var x = w ? k % w : 0;\n      var yy = w ? (k / w) | 0 : 0;\n      if (px[o + 3] > 128) box(ab, x, yy);\n      if (maskPx[o] <= MASK_ON) continue;\n      box(mb, x, yy);\n      if (px[o + 3] <= 128) outside++;\n      var y = 0.2126 * S2L[px[o]] + 0.7152 * S2L[px[o + 1]] + 0.0722 * S2L[px[o + 2]];\n      idx[p] = o; Y[p] = y; p++;\n      hist[Math.min(BINS - 1, (y * BINS) | 0)]++;\n    }\n    var half = count / 2;\n    var acc = 0;\n    var b = 0;\n    for (; b < BINS - 1; b++) { acc += hist[b]; if (acc >= half) break; }\n    var Ys = smoothLuma(idx, Y, count, w, w ? n / w : 0, mb);\n    return { idx: idx, Y: Y, Ys: Ys, count: count, yb: Math.max((b + 0.5) / BINS, 0.002), maskBox: mb, alphaBox: ab, outside: outside };\n  }\n\n  // Light paints (owner 11/5: white / silver came out blotchy, the dark\n  // source photos' texture at full strength): a smoothed luminance per\n  // masked pixel, a Gaussian blur of Y inside the mask only (normalized\n  // convolution, blur(Y * mask) / blur(mask)), sigma 1.6 px at 1120 px wide,\n  // scaled with the picture's width.\n  var SMOOTH_SIGMA = 1.6;\n  var SMOOTH_AT_W = 1120;\n  /** Ys for the masked pixels (same order as idx / Y); w x h is the pixel grid, box the masked pixels' box. */\n  function smoothLuma(idx, Y, count, w, h, box) {\n    if (!w || !h || !count || !box || box[2] < box[0]) return new Float32Array(Y);\n    var sigma = SMOOTH_SIGMA * w / SMOOTH_AT_W;\n    var rad = Math.max(1, Math.ceil(3 * sigma));\n    var kern = new Float32Array(2 * rad + 1);\n    for (var i = -rad; i <= rad; i++) kern[i + rad] = Math.exp(-(i * i) / (2 * sigma * sigma));\n    var x0 = Math.max(0, box[0] - rad);\n    var y0 = Math.max(0, box[1] - rad);\n    var x1 = Math.min(w - 1, box[2] + rad);\n    var y1 = Math.min(h - 1, box[3] + rad);\n    var W = x1 - x0 + 1;\n    var H = y1 - y0 + 1;\n    // rows padded by rad zeros on each side: no edge tests in the loops\n    var PW = W + 2 * rad;\n    var A = new Float32Array(PW * H);   // Y * mask\n    var M = new Float32Array(PW * H);   // mask\n    var pos = new Uint32Array(count);\n    var p;\n    for (p = 0; p < count; p++) {\n      var k = idx[p] >> 2;\n      var x = k % w;\n      var y = (k - x) / w;\n      pos[p] = (y - y0) * W + (x - x0);\n      var q = (y - y0) * PW + (x - x0 + rad);\n      A[q] = Y[p];\n      M[q] = 1;\n    }\n    // across, everywhere in the box (columns padded by rad rows top and bottom for the next pass)\n    var HA = new Float32Array(W * (H + 2 * rad));\n    var HM = new Float32Array(W * (H + 2 * rad));\n    var taps = 2 * rad + 1;\n    for (var row = 0; row < H; row++) {\n      var src0 = row * PW;\n      var dst0 = (row + rad) * W;\n      for (var col = 0; col < W; col++) {\n        var sa = 0;\n        var sm = 0;\n        var s0 = src0 + col;\n        for (var t = 0; t < taps; t++) {\n          var kw = kern[t];\n          sa += kw * A[s0 + t];\n          sm += kw * M[s0 + t];\n        }\n        HA[dst0 + col] = sa;\n        HM[dst0 + col] = sm;\n      }\n    }\n    // down, only where the result is used (the masked pixels)\n    var Ys = new Float32Array(count);\n    for (p = 0; p < count; p++) {\n      var qq = pos[p];\n      var cx = qq % W;\n      var cy = (qq - cx) / W;\n      var o2 = cy * W + cx;   // row cy - rad in the padded columns\n      var ta = 0;\n      var tm = 0;\n      for (var u = 0; u < taps; u++, o2 += W) {\n        var kv = kern[u];\n        ta += kv * HA[o2];\n        tm += kv * HM[o2];\n      }\n      Ys[p] = tm > 0 ? ta / tm : Y[p];\n    }\n    return Ys;\n  }\n\n  /**\n   * How light a paint is, after LIGHT_CAP: 0 for a dark paint (painted\n   * exactly as before the softening), 1 for white; between 0.12 and 0.60\n   * linear luminance it ramps.\n   */\n  var LIGHT_LO = 0.12;\n  var LIGHT_HI = 0.60;\n  var SOFT_MIX = 0.45;      // share of the smoothed luminance at light = 1\n  var SOFT_GAMMA = 0.35;    // shading lifted by r^(1 - 0.35 light)\n  var POW_N = 16384;\n  function paintLightness(hex) {\n    var t = hexLinear(hex);\n    var yt = Math.min(LIGHT_CAP, 0.2126 * t[0] + 0.7152 * t[1] + 0.0722 * t[2]);\n    return Math.max(0, Math.min(1, (yt - LIGHT_LO) / (LIGHT_HI - LIGHT_LO)));\n  }\n\n  /** Repaint: write src with the masked body in `hex` into out (same size RGBA). */\n  function paint(prep, src, out, hex) {\n    var t = hexLinear(hex);\n    var yt = 0.2126 * t[0] + 0.7152 * t[1] + 0.0722 * t[2];\n    if (yt > LIGHT_CAP) { var s = LIGHT_CAP / yt; t = [t[0] * s, t[1] * s, t[2] * s]; yt = LIGHT_CAP; }\n    var light = Math.max(0, Math.min(1, (yt - LIGHT_LO) / (LIGHT_HI - LIGHT_LO)));\n    var yb = prep.yb;\n    var inv = 1 / yb;\n    var idx = prep.idx;\n    var Y = prep.Y;\n    var p;\n    var o;\n    var y;\n    var r;\n    var add;\n    if (!(light > 0) || !prep.Ys) {\n      for (p = 0; p < prep.count; p++) {   // exactly the masked pixels, fully; nothing else\n        o = idx[p];\n        y = Y[p];\n        r = y * inv;\n        add = 0;\n        if (r > 1) { add = y - yb; r = 1; }\n        out[o] = toSrgb(t[0] * r + add);\n        out[o + 1] = toSrgb(t[1] * r + add);\n        out[o + 2] = toSrgb(t[2] * r + add);\n        out[o + 3] = src[o + 3];\n      }\n      return;\n    }\n    // light paints (owner 11/5): part of the smoothed luminance, the shading lifted\n    var Ys = prep.Ys;\n    var ws = SOFT_MIX * light;\n    var wy = 1 - ws;\n    var g = 1 - SOFT_GAMMA * light;\n    var pw = new Float32Array(POW_N + 1);   // r^g, a table per paint (a pow per pixel is slow)\n    for (var j = 0; j <= POW_N; j++) pw[j] = Math.pow(j / POW_N, g);\n    for (p = 0; p < prep.count; p++) {\n      o = idx[p];\n      y = Y[p] * wy + Ys[p] * ws;\n      r = y * inv;\n      add = 0;\n      if (r > 1) { add = y - yb; r = 1; }\n      r = pw[(r * POW_N + 0.5) | 0];\n      out[o] = toSrgb(t[0] * r + add);\n      out[o + 1] = toSrgb(t[1] * r + add);\n      out[o + 2] = toSrgb(t[2] * r + add);\n      out[o + 3] = src[o + 3];\n    }\n  }\n\n  // Decoded rigs, newest last; each holds two full-size pixel buffers, so keep a few.\n  var PAINT_CACHE = [];\n  var PAINT_CACHE_MAX = 4;\n  // Same files through the shop's own domain, if the CDN won't allow canvas reads.\n  var SAME_ORIGIN_BASE = '/cdn/shop/files/';\n\n  function loadImage(url) {\n    return new Promise(function (resolve, reject) {\n      var im = new Image();\n      im.crossOrigin = 'anonymous';\n      im.decoding = 'async';\n      im.onload = function () { resolve(im); };\n      im.onerror = function () { reject(new Error('load ' + url)); };\n      im.src = url;\n    });\n  }\n\n  function decodeRig(base, image, w) {\n    var suffix = w > 800 ? '.webp' : '-800.webp';\n    var loads = [loadImage(base + image + suffix)];\n    if (PAINT_ON) loads.push(loadImage(maskUrl(base, image)));\n    return Promise.all(loads).then(function (ims) {\n      var h = w / 2;\n      var c = document.createElement('canvas');\n      c.width = w; c.height = h;\n      var ctx = c.getContext('2d', { willReadFrequently: true });\n      ctx.drawImage(ims[0], 0, 0, w, h);\n      var src = ctx.getImageData(0, 0, w, h);      // throws if the CDN didn't allow it\n      if (!PAINT_ON) {\n        // no repaint: the body is the olive picture as it is; the pixels are\n        // kept for the silhouette measures (rear bumper, cab roof). mask:\n        // undefined until the sliders need the rocker line (rigMask).\n        var olive = document.createElement('canvas');\n        olive.width = w; olive.height = h;\n        olive.getContext('2d').putImageData(src, 0, 0);\n        return { key: image + '@' + w, image: image, w: w, h: h, src: src, out: null, body: olive, prep: null, mask: undefined,\n          file: image + suffix, picW: ims[0].naturalWidth, picH: ims[0].naturalHeight };\n      }\n      ctx.clearRect(0, 0, w, h);\n      ctx.imageSmoothingEnabled = false;   // the mask resized without blending: a pixel is in or out\n      ctx.drawImage(ims[1], 0, 0, w, h);\n      ctx.imageSmoothingEnabled = true;\n      var mask = ctx.getImageData(0, 0, w, h);\n      var out = new ImageData(new Uint8ClampedArray(src.data), w, h);\n      var bodyCanvas = document.createElement('canvas');\n      bodyCanvas.width = w; bodyCanvas.height = h;\n      return { key: image + '@' + w, w: w, h: h, src: src, out: out, body: bodyCanvas, prep: prepPaint(src.data, mask.data, w), mask: mask.data,\n        // what was drawn, for the review's alignment check\n        file: image + suffix, picW: ims[0].naturalWidth, picH: ims[0].naturalHeight, maskW: ims[1].naturalWidth, maskH: ims[1].naturalHeight };\n    });\n  }\n\n  function getRig(image, w) {\n    var key = image + '@' + w;\n    for (var i = 0; i < PAINT_CACHE.length; i++) {\n      if (PAINT_CACHE[i].key === key) {\n        var hit = PAINT_CACHE.splice(i, 1)[0];\n        PAINT_CACHE.push(hit);\n        return Promise.resolve(hit);\n      }\n    }\n    return decodeRig(IMAGE_BASE, image, w).catch(function () {\n      return decodeRig(SAME_ORIGIN_BASE, image, w);\n    }).then(function (rig) {\n      PAINT_CACHE.push(rig);\n      while (PAINT_CACHE.length > PAINT_CACHE_MAX) PAINT_CACHE.shift();\n      return rig;\n    });\n  }\n\n  /**\n   * The paint mask with the paint off: only the rock sliders use it (their\n   * bottom on the rocker line, measureRocker), so it is fetched when they\n   * are ticked, once per decoded rig. Resolves with rig.mask set (null if\n   * it can't be read: the sliders then sit just over the hubs, as before).\n   */\n  function rigMask(rig) {\n    if (rig.maskReq) return rig.maskReq;\n    var w = rig.w;\n    var h = rig.h;\n    rig.maskReq = loadImage(maskUrl(IMAGE_BASE, rig.image)).catch(function () {\n      return loadImage(maskUrl(SAME_ORIGIN_BASE, rig.image));\n    }).then(function (im) {\n      var c = document.createElement('canvas');\n      c.width = w; c.height = h;\n      var ctx = c.getContext('2d', { willReadFrequently: true });\n      ctx.imageSmoothingEnabled = false;   // a pixel is in or out, as for the paint\n      ctx.drawImage(im, 0, 0, w, h);\n      rig.mask = ctx.getImageData(0, 0, w, h).data;\n    }).catch(function () { rig.mask = null; });\n    return rig.maskReq;\n  }\n\n  /** The real-colour pictures of a rig picture (data.real_colors[image]: colour name -> Files id), or null. */\n  function realColors(data, image) {\n    var m = data && data.real_colors && data.real_colors[image];\n    return m && typeof m === 'object' && Object.keys(m).length ? m : null;\n  }\n  /** A colour set's swatches: with the paint off, only the colours that have a real picture (none on other rigs). */\n  function swatchColors(data, row) {\n    var set = (row && data.colorsets[row.colorset]) || { colors: [] };\n    if (PAINT_ON) return set.colors.slice();\n    var real = row && realColors(data, row.image);\n    return real ? set.colors.filter(function (c) { return !!real[c.name]; }) : [];\n  }\n  // Real-colour pictures stored in Shopify Files under another name\n  // (data.file_aliases: '<id>.png' -> stored name). Shopify won't keep a\n  // name that ends like an image-size suffix ('MAHaHvR7_X0.png' reads as\n  // '_x0'), so it adds one of its own (batch 1, 11/8).\n  var fileAliases = {};\n  function setFileAliases(map) { fileAliases = map && typeof map === 'object' ? map : {}; }\n  /** Files URL of a real-colour picture at the rig picture's width (1600: <id>.png, else <id>-800.png). */\n  function colorPicUrl(base, id, w) {\n    var f = id + (w > 800 ? '.png' : '-800.png');\n    var a = Object.prototype.hasOwnProperty.call(fileAliases, f) ? fileAliases[f] : null;\n    return base + (typeof a === 'string' && /\\.png$/.test(a) ? a : f);\n  }\n  // Loaded real-colour pictures by URL: { img, p }; img stays null if it failed.\n  var colorPics = {};\n  function colorPic(id, w) {\n    var url = colorPicUrl(IMAGE_BASE, id, w);\n    var e = colorPics[url];\n    if (!e) {\n      e = colorPics[url] = { img: null, done: false };\n      e.p = loadImage(url).catch(function () { return loadImage(colorPicUrl(SAME_ORIGIN_BASE, id, w)); })\n        .then(function (im) { e.img = im; }, function () { e.img = null; })\n        .then(function () { e.done = true; return e.img; });\n    }\n    return e;\n  }\n\n  // ------------------------------------------------------- drawn-on accessories\n  // Generic side-profile parts, drawn once and placed on every rig by real\n  // inches from its anchor points (data.anchors[image], pixels of the 1600 x 800\n  // picture in a left-facing frame). px_per_in = wheelbase_px / wheelbase_in.\n  // Flat style: no perspective, key light top-left, matte black steel with one\n  // thin highlight line; tent shells dark grey or tan. Parts never recolour.\n\n  var PART = {\n    steel: '#1d1e20', steelHi: '#6a6f76', steelDark: '#0d0d0e',\n    shell: '#3a3d41', shellHi: '#7a7f86', tan: '#b7a684', tanDark: '#8f7f61',\n    tread: '#151515', sidewall: '#222223', rim: '#43474d', rimHi: '#8a9097', rimDark: '#121314',\n    alu: '#9a9ea3', aluHi: '#d3d6d9', camper: '#8a8c8e', camperDark: '#5f6163', glass: '#20262c',\n    awning: '#5c6168', awningDark: '#464a50', awningHi: '#8a9097',   // a mid grey, so the bag reads against the black rack and a tent (Justin 11/4)\n    treadEdge: '#0b0b0b', treadMid: '#1c1c1d', treadHi: '#3a3a3c', groove: '#060606',\n    fairlead: '#8d939a', fairleadHi: '#c4c9ce', lens: '#d9dee3', lensHi: '#ffffff'\n  };\n\n  // Tyre options: published diameter (in) and the lift that goes with it (in).\n  var TIRES = {\n    tires33: { d: 32.5, lift: 0 }, tires35: { d: 34.5, lift: 2 },\n    tires37: { d: 36.5, lift: 3 }, tires40: { d: 39.7, lift: 5 }\n  };\n  /** Biggest tyre option for a row (Justin 11/2: 33 mini pickup, 35 midsize, 37 half-ton/Jeep/SUV, 40 HD and built Jeeps). */\n  function tireMax(row) { return row && row.tire_max > 0 ? row.tire_max : 40; }\n  // Gear a rig can't take (Justin, round 4): tents and racks on the Class C motorhome and the pop-top van.\n  var ROOF_GEAR = ['rtt_soft', 'rtt_hard', 'rtt_large', 'platform_rack', 'bedrack'];\n  // No winch bumper on them either (Justin, winch sheet review 11/3).\n  function gearFits(row, id) {\n    return tireFits(row, id) && !(row && row.no_roof_gear && ROOF_GEAR.indexOf(id) >= 0) && !(row && row.no_bumper_f && FRONT_BUMPERS.indexOf(id) >= 0) &&\n      !(row && row.no_flatbed && (id === 'flatbed_alu' || id === 'flatbed_steel')) &&   // unibody (the Cybertruck, Justin sweep 11/4)\n      !(row && row.body_type !== 'pickup' && PICKUP_ONLY.indexOf(id) >= 0);\n  }\n  function tireFits(row, id) { return !TIRES[id] || parseInt(id.slice(5), 10) <= tireMax(row); }\n  // Fender clearance (Justin 11/2): the tyre top stays 1.5 in under the\n  // wheel opening's top; the body lifts more if it would come closer. The\n  // opening's top is FENDER_GAP_IN over the stock tyre (estimated: the\n  // anchors have no wheel-opening measurement yet), or the anchor's\n  // fwc_open_y / rwc_open_y when it has one.\n  var FENDER_CLEAR_IN = 1.5;\n  var FENDER_GAP_IN = 2;\n  // Hard-shell tents: when the rack under it (bed rack, roof rack; no rack:\n  // the roof) is shorter than 70 in, the 60 in shell, else the 85 in one\n  // (Justin, round 4).\n  var SHORT_ROOM_IN = 70;\n  var CAB_OVERHANG_IN = 12;  // a tent never overhangs the cab by more than this (Justin, round 4)\n  // Rear bumper and swing-out (Justin FINAL 11/3; Expedition One RangeMax,\n  // Chassis Unlimited Octane, CBI; mockups MAHZ1bN4IgA, MAHZ1YM_5vs,\n  // MAHZ1XOy5cQ, MAHZ1R2PAOU win on the look): a full-width steel box in the\n  // stock bumper's place (the stock bumper cleared), top 1 in under the\n  // tailgate / rear door bottom, 10 in tall (12 HD), 8 in deep behind the\n  // tailgate / door face, a 10 in end cap forward under the taillight.\n  var SLOPED_CAB_IN = 8;     // cab back this far behind the roof's rear corner: the roof slopes into the bed\n  // Owner review 11/3: the bumper has to read as a bumper: a solid black box\n  // across the tail, 12 in tall, from 8 in behind the tailgate / door face\n  // to 12 in forward under the taillight, the stock bumper cleared; the arm\n  // off its top. Its top: the rear tyre top + 3 in (Justin, universal rule).\n  var REAR_TOP_OVER_TYRE_IN = 3;\n  var REAR_BELOW_GATE_IN = 1;   // owner phone review 1 (11/4): top 1 in under the measured tailgate / rear door bottom\n  var REAR_H_IN = 12;\n  var REAR_DEPTH_IN = 8;\n  var REAR_CAP_IN = 12;\n  var REAR_FACE_AHEAD_OF_TAIL_IN = 5;\n  // Snow plows (Justin's sweep 2, 11/4): drawn, in front of the front bumper\n  var PLOW = { plow_half: { h: 28 }, plow_hd: { h: 32 } };   // blade height (in)\n  var PLOW_OFF_GROUND_IN = 3;   // blade bottom over the ground\n  var PLOW_GAP_IN = 16;         // bumper face to the blade's back\n  var PLOW_DEPTH_IN = 10;       // the moldboard's curve, side on\n  var PLOW_ROOM_IN = 2;         // extra room ahead of the blade in the fit (Justin 11/4: on the margin line it read as cut off on a phone)\n  var REAR_SILHOUETTE_BACK_IN = 3;   // SUV / van, from the silhouette (Justin sweep 11/4): face 3 in behind the stock face\n  var REAR_SILHOUETTE_UP_IN = 2;     // and the bottom 2 in over the stock bottom   // unmeasured SUV / van: the rear door face this far ahead of the tail\n  // Swing-out: 3 in square arm from the bumper's rear top corner to the hub,\n  // 6 in hinge block at its base; the spare edge-on (12.5 in), tread 3 in\n  // behind the face, bottom 4 in over the bumper top, the rig's tyre size.\n  var ARM_IN = 3;\n  var HINGE_IN = 6;\n  var SPARE_W_IN = 12.5;\n  var SPARE_BEHIND_FACE_IN = 3;\n  var SPARE_OVER_BUMPER_IN = 4;\n  // Bed campers and the flatbed (Justin 11/2 FINAL). Owner's decision: the\n  // approved mockups (MAHZznRdWDA, MAHZzkNfeA4, MAHZzornwc4, MAHZzsf-a0c,\n  // MAHZzoU3Bfg) win on the look (the pictures); Justin's written numbers\n  // win on the dimensions below.\n  var WEDGE_LID_OVER_CAB_IN = 7;     // lid top over the cab roof\n  var WEDGE_LID_IN = 6;              // lid thickness (GFC spec)\n  var WEDGE_BRIM_IN = 10;            // lid over the cab, past the box's front wall (the picture's 20 in, cut)\n  var SLIDEIN_ROOF_OVER_CAB_IN = 10; // closed roof over the cab roof\n  var SLIDEIN_NOSE_IN = 40;          // cabover length on a flatbed (owner 11/3)\n  // Slide-in (Justin, v3 review; owner: from the bed rail): scaled by HEIGHT, rail (or deck) to roof; the length\n  // follows the picture's shape. Its shape when the picture isn't measured:\n  var SLIDEIN_SHAPE = { aspect: 128 / 55.5, nose_right: 0.3052, roof_top: 0.0292, floor: 0.6331 };\n  // Flatbed FINAL (owner, against his SET flatbed F-250; mockup MAHZ1cXD4tA\n  // wins on the look, these on the dimensions): deck top 6 in over the stock\n  // tyre top (the old bed-floor line), 3 in thick; a continuous skirt of\n  // storage boxes under it from the cab back to the tail (12 in, 10 midsize)\n  // with a wheel arch cut 3 in round the rear tyre; the deck runs the full\n  // length, cab back to the end of the frame (the tailgate line; owner\n  // 11/3), the skirt's rear corner angled up; the headache rack (to the cab\n  // roof) on a bare flatbed only.\n  var FLATBED_DECK_OVER_TYRE_IN = 6;\n  var FLATBED_DECK_IN = 3;\n  var FLATBED_ARCH_CLEAR_IN = 3;\n  var FLATBED_TYRE_INSET_IN = 0.25;   // under a flatbed only the stock tyre is kept, this far inside its edge (Justin sweep 11/4)\n  var FLATBED_SKIRT_IN = { midsize: 10, other: 12 };\n  // Bed-only gear, offered on pickups only (Justin phone review 11/4: the\n  // slide-in, wedge, bed rack, flatbed, 8 ft drawers and caps were offered on\n  // SUVs, weight added and nothing drawn).\n  var PICKUP_ONLY = ['flatbed_alu', 'flatbed_steel', 'slide_in_camper', 'popup_topper', 'bedrack', 'drawers_8ft',\n    'cap_fiber', 'cap_alu', 'toolbox', 'sideboxes', 'ladderrack'];\n  // Winch bumper (Justin, winch sheet review 11/3): top at the headlight's\n  // bottom (or the measured stock bumper top when no headlight was found and\n  // it sits in the nose's upper third; else this far over the ground line),\n  // bottom 2 in below the stock bumper's bottom, 10 to 20 in tall.\n  var BUMPER_F_MIN_IN = 10;\n  var BUMPER_F_MAX_IN = 20;\n  var BUMPER_F_BELOW_STOCK_IN = 2;\n  // The wing always shows: where the block at its scale would leave the wing\n  // less than this share of the room in front of the opening, the block is\n  // narrowed (its height stays) and the wing gets the rest.\n  var BUMPER_F_WING_SHARE = 0.35;\n  var BUMPER_F_TOP_OVER_GROUND_IN = { midsize: 22, fullsize: 26, hd: 30, jeep: 20 };\n  // Light bar (Justin phone review 11/4): a 5 in tall, 8 in long dark\n  // rounded block sitting on the roof at the windshield header, no post.\n  var LIGHTBAR_H_IN = 5;\n  var LIGHTBAR_W_IN = 8;\n  var SHORT_SHELL_IN = 60;\n  // Owner phone review 1 (11/4): new drawn gear (simple shapes, no pictures).\n  var SLIDER_IN = 3;              // rock slider tube, bottom at the rocker bottom\n  var TOOLBOX_LEN_IN = 20;        // crossover tool box at the cab back\n  var TOOLBOX_H_IN = 12;          // over the bed rail\n  var TOOLBOX_LIP_IN = 4;         // lip down over the bed side\n  var SIDEBOX_H_IN = 16;          // side boxes over the rail\n  var SIDEBOX_SHORT_IN = 6;       // short of the tailgate\n  var LADDER_OVER_CAB_IN = 6;     // ladder rack top rail over the cab roof\n  var LADDER_TUBE_IN = 2;\n  var LADDER_REAR_IN = 4;         // rear upright ahead of the tailgate\n  var CAB_RACK_CLEAR_IN = 3;      // a platform rack on a pickup's cab: 3 in over the roof\n  // the bed taken (cap, wedge, slide-in, flatbed): no tool box, side boxes or ladder rack\n  var BED_COVER = ['cap_fiber', 'cap_alu', 'popup_topper', 'slide_in_camper', 'flatbed_alu', 'flatbed_steel'];\n  var BED_RAIL_GEAR = ['toolbox', 'sideboxes', 'ladderrack'];\n  function bedCovered(gear) { return BED_COVER.some(function (id) { return has(gear, id); }); }\n\n  // Roof top tents, closed: length x height (in). rtt_large uses the full hard shell.\n  var TENTS = {\n    rtt_soft: { len: 76, h: 11.5, kind: 'soft' },\n    rtt_hard: { len: 85, h: 13.5, kind: 'hard' },\n    rtt_large: { len: 85, h: 13.5, kind: 'hard' }\n    // (the wedge tent, drawn closed: removed with its gear item, owner 11/11)\n  };\n\n  /**\n   * Part pictures. The drawn parts are placeholders: data.part_images can give\n   * a photo cutout for any part key (white-background side profile like the\n   * rigs, front to the LEFT, transparent PNG/WebP in Shopify Files):\n   *   \"bumper_f\": { \"midsize\": { \"file\": \"part-bumper_f-mid.png\", \"width_in\": 66 },\n   *                 \"fullsize\": {...}, \"hd\": {...} }\n   * or one entry for every size: \"lightbar\": { \"file\": ..., \"width_in\": 4 }.\n   * width_in is the picture's full width in real inches, so it scales by the\n   * rig's px_per_in. Optional: height_in (exact bounds before it loads) and\n   * at: [fx, fy], the point of the picture (0..1 of its width/height) that\n   * goes on the part's pin; each part has a default pin (see planScene).\n   * Also:\n   *   \"jeep\": {...} next to the size classes: used on Jeep-class rigs\n   *     (falls back to midsize).\n   *   \"fit\": [{ file, width_in }, ...]: length variants (bed racks, caps,\n   *     platform racks, tents); the one whose width_in is nearest the room the\n   *     part has on the rig (bed length, roof length) is used.\n   *   \"scale\": \"height\": sized by height_in, width from the picture's shape\n   *     (the end-on light bar).\n   *   On bumper_r_carrier, \"hub\": [fx, fy] is the top of the swing arm; the\n   *     spare picture hangs there (needs height_in).\n   *   \"flip\": true: drawn mirrored left to right (popup_topper: the picture\n   *     has the tall end at the front).\n   *   On bumper_r_carrier, \"body_top\": where the bumper block starts under\n   *     the arm (fraction of the height); the spare's bottom clears it.\n   *   On bumper_f, \"top_profile\": the top edge front to back (fractions of\n   *     the height); a light bar on the bumper sits on it. \"face_top\": where\n   *     the bumper face's top edge is (fraction of the height); it goes on the\n   *     stock bumper's top, a hoop or tab rises above.\n   */\n  var SIZES = ['midsize', 'fullsize', 'hd'];\n  function sizeClass(row) {\n    if (row.tire_class === 'hd') return 'hd';\n    if (row.tire_class === 'half_ton' || row.body_type === 'van' || (row.body_type === 'suv' && row.wheelbase_in >= 115)) return 'fullsize';\n    return 'midsize';\n  }\n  // The front bumper's two styles (owner 11/11, coder_brief_byr_front_bumper_by_size.md):\n  // either is \"a front bumper\" (no_bumper_f, the winch, the plow line, the\n  // drawing: both draw the bumper_f art for now), one or the other (group front_bumper)\n  var FRONT_BUMPERS = ['bumper_f_stubby', 'bumper_f'];\n  /** The front bumper in a gear list, or null. */\n  function frontBumper(gear) { return firstOf(gear, FRONT_BUMPERS); }\n\n  /** A row's add-on size class: 'jeep' (tire_class jeep), else sizeClass (the part pictures' too). */\n  function gearSize(row) { return row ? (row.tire_class === 'jeep' ? 'jeep' : sizeClass(row)) : null; }\n  /**\n   * The rig's tire size in inches (owner 11/11): the ticked tire upgrade's\n   * nominal size (tires33 33 ... tires40 40), else the row's stock_tire_in.\n   */\n  function tireSizeIn(row, gear) {\n    var t = firstOf(gear || [], ['tires33', 'tires35', 'tires37', 'tires40']);\n    return t ? parseInt(t.slice(5), 10) : (row && row.stock_tire_in) || null;\n  }\n\n  /** lb_by_tire_in's weight for a tire: the largest listed size not bigger than it, the smallest below them all. */\n  function lbForTire(table, inches) {\n    var sizes = Object.keys(table || {}).map(Number).filter(function (n) { return n > 0; }).sort(function (x, y) { return x - y; });\n    if (!sizes.length || !(inches > 0)) return null;\n    var k = sizes[0];\n    sizes.forEach(function (n) { if (n <= inches) k = n; });\n    return table[String(k)];\n  }\n\n  /**\n   * An add-on's weight on a rig (owner 11/11): its lb_by_tire_in for the\n   * rig's tire size (gear: what's ticked, for a tire upgrade), else its\n   * lb_by_size for the rig's class, else lb (also with no rig yet). The\n   * customer's own number, when there is one, wins over all of them (compute).\n   */\n  function gearLb(g, row, gear) {\n    if (g && g.lb_by_tire_in && row) {\n      var t = lbForTire(g.lb_by_tire_in, tireSizeIn(row, gear));\n      if (t != null) return t;\n    }\n    var by = g && g.lb_by_size;\n    var k = gearSize(row);\n    return by && k && by[k] != null ? by[k] : g.lb;\n  }\n\n  /** size: a size class or 'jeep'; spanIn: room on the rig in inches, for \"fit\" variants. */\n  function partPicture(table, key, size, spanIn) {\n    var e = table && table[key];\n    if (!e) return null;\n    if (e.file) return e;\n    if (e.fit && e.fit.length) {\n      var best = e.fit[0];\n      if (spanIn > 0) {\n        e.fit.forEach(function (v) { if (Math.abs(v.width_in - spanIn) < Math.abs(best.width_in - spanIn)) best = v; });\n      }\n      return best;\n    }\n    if (e[size]) return e[size];\n    if (SIZES.indexOf(size) < 0) size = 'midsize';\n    if (e[size]) return e[size];\n    var i = SIZES.indexOf(size);\n    for (var d = 1; d < SIZES.length; d++) {\n      if (e[SIZES[i - d]]) return e[SIZES[i - d]];\n      if (e[SIZES[i + d]]) return e[SIZES[i + d]];\n    }\n    return null;\n  }\n\n  function has(gear, id) { return gear.indexOf(id) >= 0; }\n\n  /**\n   * The winch bumper's block in picture px (before any lift), Justin's\n   * winch sheet review (11/3): { top, bottom, how }.\n   *   top: the headlight's bottom (a.headlight = [top_y, bottom_y], measured\n   *     by scripts/build_your_rig/headlights.py); with no headlight, the\n   *     measured stock bumper top if it sits in the nose's upper third (hood\n   *     line to the stock bumper's bottom), else BUMPER_F_TOP_OVER_GROUND_IN\n   *     over the ground line by size.\n   *   bottom: 2 in below the stock bumper's bottom; the height between them\n   *     is held to 10..20 in (the top stays, the bottom moves).\n   */\n  function frontBumperBand(row, a) {\n    var ppi = a.wheelbase_px / row.wheelbase_in;\n    var cls = row.tire_class === 'jeep' ? 'jeep' : sizeClass(row);\n    var chin = a.bumper_bottom_y != null ? a.bumper_bottom_y : a.fwc[1];\n    var h = a.headlight;\n    var top;\n    var how;\n    if (h && h.length === 2 && h[1] > h[0]) {\n      top = h[1];\n      how = 'headlight';\n    } else if (a.bumper_top_y <= a.hood_y + (chin - a.hood_y) / 3) {\n      top = a.bumper_top_y;\n      how = 'measured';\n    } else if (cls === 'jeep' && a.bumper_top_y > a.hood_y && a.bumper_top_y < chin) {\n      // Justin phone review 2 (11/4): the stubby Jeep bumper bolts in where\n      // the stock one was; with no headlight measured its top is the stock\n      // bumper's top edge (the line under the headlights), never 20 in over\n      // the ground (that hung it off the stock bumper's bottom: the JL)\n      top = a.bumper_top_y;\n      how = 'stock top';\n    } else {\n      top = a.ground - BUMPER_F_TOP_OVER_GROUND_IN[cls] * ppi;\n      how = 'ground';\n    }\n    var hIn = (chin + BUMPER_F_BELOW_STOCK_IN * ppi - top) / ppi;\n    hIn = Math.max(BUMPER_F_MIN_IN, Math.min(BUMPER_F_MAX_IN, hIn));\n    return { top: top, bottom: top + hIn * ppi, how: how };\n  }\n\n  /**\n   * The rear steel bumper's face (picture px): the tailgate / rear door face\n   * the box runs 8 in behind and 12 in ahead of. Measured by\n   * scripts/build_your_rig/rear.py (a.rear_face_x); unmeasured: the pickup's\n   * tailgate x, or 5 in ahead of the tail. The box's TOP is not measured:\n   * rear tyre top + 3 in (Justin, universal rule 11/3), see planScene.\n   */\n  function rearBumperBand(row, a) {\n    var ppi = a.wheelbase_px / row.wheelbase_in;\n    var measured = a.rear_face_x != null;\n    var face = measured ? a.rear_face_x\n      : (a.pickup && row.body_type === 'pickup' ? a.pickup.tailgate_x : a.tail - REAR_FACE_AHEAD_OF_TAIL_IN * ppi);\n    return { face: face, how: measured ? 'measured' : 'estimate' };\n  }\n\n  /**\n   * Where a winch bumper picture's wing starts (fraction of its width): the\n   * data's wing_left, else from its top_profile, the first sharp drop of the\n   * top edge behind the block's top (face_top). null: no wing (the Jeep\n   * stubby's top slopes, it doesn't drop).\n   */\n  function bumperWingLeft(pic) {\n    if (typeof pic.wing_left === 'number') return pic.wing_left;\n    var prof = pic.top_profile;\n    if (!prof || prof.length < 3) return null;\n    var ft = pic.face_top || 0;\n    var i = 0;\n    while (i < prof.length && prof[i] > ft + 0.05) i++;   // to the block's top\n    for (i += 1; i < prof.length; i++) {\n      if (prof[i] - prof[i - 1] > 0.1 && prof[i] > ft + 0.12) return (i - 0.5) / (prof.length - 1);\n    }\n    return null;\n  }\n\n  /**\n   * Slices of a v4 bed picture: { slices: [{ src: [x, y, w, h] (fractions of\n   * the picture), dst: [x, y, w, h] (frame px), flip }], box } or null when\n   * the picture lacks its measurements.\n   *   wedge_camper (brim on the right, drawn mirrored): lid over the box, lid\n   *     brim (the picture's 20 in brim, brim_in, stretched or cut to\n   *     WEDGE_BRIM_IN), box; box = bed length, lid 6 in, box down to the rail.\n   *   slide_in (nose on the left): one piece at the planned scale; on a long\n   *     bed the box part stretched to the bed, the cabover at its own scale.\n   *   flatbed (rack on the left): rack at its own size, deck stretched to the\n   *     frame's end; deck top on the planned deck line.\n   */\n  function bedSlices(p, pic, P) {\n    var n = function (k) { return typeof pic[k] === 'number'; };\n    if (p.type === 'gfc' && n('box_right') && n('lid_bottom')) {\n      var br = pic.box_right;\n      var lb = pic.lid_bottom;\n      var brimFrac = Math.min(1, WEDGE_BRIM_IN / (pic.brim_in || 20));\n      return { box: [p.brimX, p.top, p.x1, p.rail], slices: [\n        { src: [0, 0, br, lb], dst: [p.x0, p.top, p.x1 - p.x0, p.lidBot - p.top], flip: true },\n        { src: [br, 0, (1 - br) * brimFrac, lb], dst: [p.brimX, p.top, p.x0 - p.brimX, p.lidBot - p.top], flip: true },\n        { src: [0, lb, br, 1 - lb], dst: [p.x0, p.lidBot, p.x1 - p.x0, p.rail - p.lidBot], flip: true }] };\n    }\n    if (p.type === 'slidein' && n('nose_right') && n('roof_top') && n('floor')) {\n      // one piece, the planned scale both ways (planScene sized it by height);\n      // a stretched box (long bed): the box widened to the bed, then the\n      // cabover at its own scale, 1 px over the seam\n      var top = p.top - pic.roof_top * p.k;\n      var sh = pic.floor * p.k;\n      if (!p.stretch) {\n        return { box: [p.nose, top, p.x1, p.floor], slices: [\n          { src: [0, 0, 1, pic.floor], dst: [p.nose, top, p.x1 - p.nose, sh] }] };\n      }\n      var nr = pic.nose_right;\n      var seam = 1 / (p.k * (pic.width_in / pic.height_in));   // 1 px, as a share of the picture's width\n      return { box: [p.nose, top, p.x1, p.floor], slices: [\n        { src: [nr, 0, 1 - nr, pic.floor], dst: [p.cb, top, p.x1 - p.cb, sh] },\n        { src: [0, 0, nr + seam, pic.floor], dst: [p.nose, top, p.cb - p.nose + 1, sh] }] };\n    }\n    if (p.type === 'flatbed' && n('deck_top') && n('rack_right') && pic.width_in > 0 && pic.height_in > 0) {\n      var w = P(pic.width_in);\n      var h = P(pic.height_in);\n      var y0 = p.deck - pic.deck_top * h;\n      var rw = pic.rack_right * w;\n      return { box: [p.x0, y0, p.x1, y0 + h], slices: [\n        { src: [0, 0, pic.rack_right, 1], dst: [p.x0, y0, rw, h] },\n        { src: [pic.rack_right, 0, 1 - pic.rack_right, 1], dst: [p.x0 + rw, y0, p.x1 - p.x0 - rw, h] }] };\n    }\n    return null;\n  }\n  function firstOf(gear, ids) { for (var i = 0; i < ids.length; i++) if (has(gear, ids[i])) return ids[i]; return null; }\n\n  /**\n   * Plan the scene for a row + its anchors + picked gear ids: body lift and the\n   * list of parts with geometry in pixels of the left-facing 1600 x 800 frame.\n   * Pure (no canvas), so it can be tested and its bounds measured.\n   */\n  function planScene(row, a, gear, pics) {\n    gear = gear.filter(function (id) { return gearFits(row, id); });\n    var ppi = a.wheelbase_px / row.wheelbase_in;\n    var P = function (inches) { return inches * ppi; };\n    var G = a.ground;\n    var pickup = row.body_type === 'pickup' && a.pickup;\n    var jeep = row.tire_class === 'jeep';\n    var parts = [];\n    var cabGuardIn = 0;\n\n    // 1. Tyres + lift (everything below is post-lift)\n    var tid = firstOf(gear, ['tires33', 'tires35', 'tires37', 'tires40']);\n    var D = tid ? TIRES[tid].d : row.stock_tire_in;\n    var riseIn = tid ? Math.max(0, (D - row.stock_tire_in) / 2 + TIRES[tid].lift) : 0;\n    var fenderIn = 0;\n    if (tid) {\n      // tyre top (on the ground, D tall) vs the wheel opening's top (moves up with the body)\n      [[a.fwc, a.fwc_open_y], [a.rwc, a.rwc_open_y]].forEach(function (w) {\n        var openY = w[1] != null ? w[1] : w[0][1] - w[0][2] - P(FENDER_GAP_IN);\n        var clearIn = (G - P(D) - (openY - P(riseIn))) / ppi;\n        fenderIn = Math.max(fenderIn, FENDER_CLEAR_IN - clearIn);\n      });\n      riseIn += fenderIn;\n    }\n    var rise = P(riseIn);\n    var L = function (y) { return y - rise; };\n    var hubR = L(a.rwc[1]);\n    var roofY = L(a.roof_y);\n    var tireR = tid ? P(D / 2) : null;\n    var utv = row.body_type === 'utv';\n    // Roof outline (lifted): measured points from header_x to roof_rear_x, else the flat roof line.\n    var RL = a.roof_line && a.roof_line.length > 1 ? a.roof_line : null;\n    var roofAt = function (x) {\n      if (!RL) return roofY;\n      var f = (x - a.header_x) / Math.max(1, a.roof_rear_x - a.header_x) * (RL.length - 1);\n      f = Math.max(0, Math.min(RL.length - 1, f));\n      var i = Math.min(RL.length - 2, Math.floor(f));\n      return L(RL[i] + (RL[i + 1] - RL[i]) * (f - i));\n    };\n    // Highest roof point under a span, so nothing sinks into the roof.\n    var roofTop = function (x0, x1) {\n      var y = Math.min(roofAt(x0), roofAt(x1));\n      if (RL) {\n        for (var i = 0; i < RL.length; i++) {\n          var x = a.header_x + (a.roof_rear_x - a.header_x) * i / (RL.length - 1);\n          if (x > x0 && x < x1) y = Math.min(y, L(RL[i]));\n        }\n      }\n      return y;\n    };\n\n    // A platform roof rack between px0 and px1, its underside `clear` over the\n    // highest roof point under it; each leg reaches down to the roof below it.\n    var platformRack = function (px0, px1, clear) {\n      var proof = roofTop(px0, Math.min(px1, a.roof_rear_x)) - clear;\n      // top = the rack picture's top when there is one (tent and awning sit on it), else 5 in (2 on a UTV cage)\n      var rpic = partPicture(pics, 'platform_rack', null, (px1 - px0) / ppi);\n      var ptop = proof - (rpic && rpic.height_in > 0 ? P(rpic.height_in) : P(utv ? 2 : 5));\n      var nLegs = Math.max(2, Math.round((px1 - px0) / P(30)) + 1);\n      var legs = [];\n      for (var li = 0; li < nLegs; li++) {\n        var lx = px0 + (px1 - px0 - P(3)) * li / (nLegs - 1);\n        legs.push([lx, roofAt(lx + P(1.5))]);\n      }\n      return { type: 'platform', key: 'platform_rack', x0: px0, x1: px1, top: ptop, t: P(2), roof: proof, legs: legs, P1: P(1),\n        pin: [(px0 + px1) / 2, proof], at: [0.5, 1], span: (px1 - px0) / ppi };\n    };\n\n    // Racks first (other parts sit on them)\n    var rack = null;\n    var cabRack = null;   // a platform rack on a pickup's cab (the bed rack, if any, stays the tent's carrier)\n    var capPart = null;\n    var tentId = firstOf(gear, ['rtt_soft', 'rtt_hard', 'rtt_large']);\n    var bedId = firstOf(gear, ['cap_fiber', 'cap_alu', 'popup_topper', 'slide_in_camper']);\n    var flatId = firstOf(gear, ['flatbed_alu', 'flatbed_steel']);\n    if (pickup) {\n      var cb = a.pickup.cab_back_x;\n      // Hard guard (owner 11/3): nothing in the bed (slide-in, wedge, bed\n      // rack, headache rack) starts forward of the last door's rear edge\n      // + 2 in (a.door_rear_x, scripts/build_your_rig/door_seam.py). A cab\n      // back forward of that is wrong; the plan reports how far (cabGuardIn).\n      if (a.door_rear_x != null && cb < a.door_rear_x + P(2)) {\n        cabGuardIn = (a.door_rear_x + P(2) - cb) / ppi;\n        cb = a.door_rear_x + P(2);\n      }\n      var tg = a.pickup.tailgate_x;\n      var rail = L(a.pickup.rail_y);\n      // A cab roof that slopes into the bed (the Cybertruck: the cab back 26 in\n      // behind the roof's end) has no cab line to build to: rail + 23 in.\n      var slopedCab = (cb - a.roof_rear_x) / ppi > SLOPED_CAB_IN;\n      var hasCab = a.pickup.cab_roof_y != null && !slopedCab;\n      // Cab height = the cab roof line. 23 in over the bed rail only when there's no cab roof anchor.\n      // A sloped cab can name the line instead (pickup.bed_top_y): the Cybertruck's\n      // bed rack top bar level with its roof peak (Justin's sweep 11/4).\n      var cabRoof = hasCab ? L(a.pickup.cab_roof_y) : a.pickup.bed_top_y != null ? L(a.pickup.bed_top_y) : rail - P(23);\n      var bs = cb + P(3);\n      if (flatId) {\n        var fmid = sizeClass(row) === 'midsize';\n        var deckTop = L(a.rwc[1] - a.rwc[2]) - P(FLATBED_DECK_OVER_TYRE_IN);\n        var deckX1 = tg;   // the full length: to the end of the frame, the tailgate line (owner 11/3)\n        var skirtBot = deckTop + P(fmid ? FLATBED_SKIRT_IN.midsize : FLATBED_SKIRT_IN.other);   // 12 in (10 midsize) below the deck top\n        var tyreR = tid ? P(D / 2) : a.rwc[2];\n        var tyreY = tid ? G - tyreR : hubR;\n        var fend = Math.max(deckX1, a.tail) + P(3);\n        // Justin phone review 11/4: the whole bed side comes off down to the\n        // frame (the rear hub's height), and the frame shows dark under the\n        // skirt, so no white bed side is left between the cab and the wheel\n        var frameY = Math.max(skirtBot, hubR);\n        if (frameY > skirtBot + P(0.5)) parts.push({ type: 'underframe', x0: cb + P(1), x1: deckX1, y0: skirtBot - P(1), y1: frameY });\n        parts.push({ type: 'flatbed', key: flatId, alu: flatId === 'flatbed_alu', x0: cb + P(1), x1: deckX1, deck: deckTop,\n          t: P(FLATBED_DECK_IN), skirtBot: skirtBot, arch: [a.rwc[0], tyreY, tyreR + P(FLATBED_ARCH_CLEAR_IN)], cabRoof: cabRoof,\n          headache: true, P1: P(1),\n          // the bed and everything behind the rear tyre under the skirt come off (the wheel stays)\n          erases: [[cb + P(1), rail - P(3), fend, frameY + P(1)], [a.rwc[0] + a.rwc[2] + P(1), skirtBot, fend, G + P(2)]],\n          // the hole kept is the tyre itself, a touch inside it (Justin's sweep\n          // 11/4: half an inch outside it kept a sliver of the bed side inside\n          // the arch on tight arches, the T100 and the 2000 Tundra)\n          eraseHole: [a.rwc[0], hubR, a.rwc[2] - P(FLATBED_TYRE_INSET_IN)], pin: [cb + P(1), deckTop], at: [0, 0] });\n        // the tyre draws over the skirt (owner 11/3): the stock wheel copied\n        // from the rig picture after the flatbed; a bigger tyre moved after it\n        if (tid) {\n          var tireParts = parts.filter(function (q) { return q.type === 'tire'; });\n          tireParts.forEach(function (q) { parts.splice(parts.indexOf(q), 1); parts.push(q); });\n        } else {\n          parts.push({ type: 'wheel_copy', cx: a.rwc[0], cy: hubR, r: a.rwc[2] - P(FLATBED_TYRE_INSET_IN) });   // the tyre only, no bed-side ring\n        }\n      }\n      if (bedId === 'popup_topper' || bedId === 'slide_in_camper') tentId = null;   // a camper takes the bed: no rack or tent\n      // Owner phone review 1 (11/4): bed-rail gear, drawn. A cap, the wedge, the\n      // slide-in or the flatbed takes the bed: none of the three.\n      var railGear = !bedCovered(gear);\n      var toolbox = null;\n      if (railGear && has(gear, 'toolbox')) {\n        // crossover tool box across the rails at the cab back, a lip down over the bed side\n        toolbox = { type: 'toolbox', key: 'toolbox', x0: cb, x1: cb + P(TOOLBOX_LEN_IN), top: rail - P(TOOLBOX_H_IN), rail: rail,\n          lip: rail + P(TOOLBOX_LIP_IN), P1: P(1) };\n      }\n      if (railGear && has(gear, 'sideboxes')) {\n        // side boxes on the rails, from the cab back (or behind the crossover box) to 6 in short of the tailgate\n        var sbx0 = toolbox ? toolbox.x1 : cb;\n        parts.push({ type: 'sideboxes', key: 'sideboxes', x0: sbx0, x1: tg - P(SIDEBOX_SHORT_IN), top: rail - P(SIDEBOX_H_IN), rail: rail, P1: P(1) });\n      }\n      if (toolbox) parts.push(toolbox);\n      if (has(gear, 'platform_rack')) {\n        // on the cab roof, front at the windshield header, rear at the cab back, 3 in over the roof\n        cabRack = platformRack(a.header_x, cb, P(CAB_RACK_CLEAR_IN));\n        parts.push(cabRack);\n      }\n      var ladder = null;\n      if (railGear && has(gear, 'ladderrack') && !has(gear, 'bedrack') && !(bedId === 'popup_topper' || bedId === 'slide_in_camper')) {\n        // black steel, 2 in square tube: uprights at the cab back and 4 in ahead\n        // of the tailgate, the top rail 6 in over the cab roof, on forward over\n        // the cab to the windshield header; it carries a tent like a bed rack\n        // the top rail clears the cab roof as the picture shows it too (Justin's\n        // sweep 11/4: on most rigs the over-cab rail was lost against the cab)\n        var ladderRoof = a.sil_cab_roof_y != null ? Math.min(cabRoof, L(a.sil_cab_roof_y)) : cabRoof;\n        ladder = { type: 'ladder', key: 'ladderrack', x0: cb, x1: tg - P(LADDER_REAR_IN), top: ladderRoof - P(LADDER_OVER_CAB_IN),\n          front: a.header_x, rail: rail, tube: P(LADDER_TUBE_IN), P1: P(1) };\n        parts.push(ladder);\n        rack = ladder;\n      }\n      var onCap = bedId === 'cap_fiber' || bedId === 'cap_alu';\n      // a tent on a bed cap sits on the cap's roof bars: no bed rack under the cap (owner 11/4)\n      if (!ladder && !(bedId === 'popup_topper' || bedId === 'slide_in_camper') && (has(gear, 'bedrack') || (tentId && !onCap))) {\n        // ends 2 in short of the tailgate (the rear end of the bed-rail line)\n        rack = { type: 'bedrack', x0: bs + P(1), x1: tg - P(2), top: cabRoof, rail: rail, bar: P(2) };\n        rack.auto = !has(gear, 'bedrack');\n        rack.key = 'bedrack';\n        rack.pin = [rack.x1, rack.top];   // rear of the rack at the tailgate\n        rack.at = [1, 0];\n        rack.span = (tg - cb) / ppi;      // bed length picks the rack picture\n        // Justin 11/3: the picture fitted to the bed both ways (front upright\n        // at the cab back, legs on the rail, top at the cab roof); the nearest\n        // fit length used to run 6-11 in forward onto the cab's rear glass.\n        rack.picW = rack.x1 - rack.x0;\n        rack.picH = rail - rack.top;\n        parts.push(rack);\n      }\n      if (bedId === 'cap_fiber' || bedId === 'cap_alu') {\n        // the cap's roof as drawn: its picture's top when there is one, else the cab roof line\n        var capPic = partPicture(pics, bedId, null, (tg - bs) / ppi);\n        capPart = { type: 'cap', key: bedId, alu: bedId === 'cap_alu', x0: bs, x1: tg, top: cabRoof, rake: P(1), rail: rail, P1: P(1),\n          pin: [tg, rail], at: [1, 1], span: (tg - bs) / ppi,\n          roofY: capPic && capPic.height_in > 0 ? rail - P(capPic.height_in) : cabRoof };\n        parts.push(capPart);\n      } else if (bedId === 'popup_topper') {\n        // Wedge camper (GFC style), a level box: front wall at the cab back,\n        // rear flush with the tailgate, bottom on the bed rail; the 6 in lid\n        // on top runs on over the cab (the brim).\n        var lidTop = cabRoof - P(WEDGE_LID_OVER_CAB_IN);\n        parts.push({ type: 'gfc', key: bedId, picKey: 'wedge_camper', x0: cb, x1: tg, brimX: cb - P(WEDGE_BRIM_IN), top: lidTop,\n          lidBot: lidTop + P(WEDGE_LID_IN), rail: rail, P1: P(1), pin: [cb, rail], at: [0, 1] });\n      } else if (bedId === 'slide_in_camper') {\n        // Slide-in (Four Wheel Campers style): box from the cab back to the\n        // tailgate, cabover nose 40 in over the cab, closed roof 10 in over\n        // the cab roof. In a bed it shows from the bed rail up (the bed sides\n        // stay, as in the mockups); on a flatbed it stands on the deck.\n        var flatP = parts.filter(function (q) { return q.type === 'flatbed'; })[0];\n        var floorY = flatP ? flatP.deck : rail;\n        var roofY2 = cabRoof - P(SLIDEIN_ROOF_OVER_CAB_IN);\n        // Scaled by height (bed rail or deck top to cab roof + 10 in: ~30 in\n        // on a full-size pickup, ~115 in long), the length follows; the rear\n        // wall at the tailgate (deck end), the front wall at the cab back: the\n        // box is stretched or squeezed to fit (Justin 11/3: a longer box ran\n        // forward over the cab's rear window); the height and the cabover\n        // keep their size.\n        var spic = partPicture(pics, 'slide_in', null, 0);\n        var shape = spic && typeof spic.floor === 'number' && spic.height_in > 0\n          ? { aspect: spic.width_in / spic.height_in, nose_right: spic.nose_right, roof_top: spic.roof_top, floor: spic.floor } : SLIDEIN_SHAPE;\n        var sx1 = flatP ? flatP.x1 : tg;\n        var sk = (floorY - roofY2) / (shape.floor - shape.roof_top);   // frame px per picture height\n        var sw = shape.aspect * sk;                                      // the whole picture's width\n        var sp = { type: 'slidein', key: bedId, picKey: 'slide_in', nose: sx1 - sw, cb: sx1 - (1 - shape.nose_right) * sw, x1: sx1,\n          top: roofY2, floor: floorY, k: sk, cabRoof: roofY2 + (shape.floor - shape.roof_top) * sk * 0.3, P1: P(1),\n          pin: [sx1, floorY], at: [1, 1] };\n        if (flatP) {\n          // on the flatbed (owner 11/3): no headache rack; the height deck top\n          // to cab roof + 10 in, the cabover 40 in, and only the box stretched\n          // (or squeezed) from the cab back to the deck end\n          flatP.headache = false;\n          sp.noseFit = true;   // Justin phone review 2: the 40 in cabover fitted down to the cab roof (drawScene)\n          sp.stretch = (sx1 - cb) / (sx1 - sp.cb);\n          sp.nose = cb - P(SLIDEIN_NOSE_IN);\n          sp.cb = cb;\n        } else if (Math.abs(sp.cb - cb) > 0.5) {\n          // Justin 11/3: front wall at the cab back, rear at the tailgate, in\n          // any bed (a box longer than the bed is squeezed: it never covers\n          // the cab's rear window)\n          sp.stretch = (sx1 - cb) / (sx1 - sp.cb);   // box length over its picture length\n          sp.nose = cb - shape.nose_right * sw;\n          sp.cb = cb;\n        }\n        sp.clipX = sx1;   // nothing past the deck end / tailgate (Justin 11/3)\n        // the cabover's underside sits on the cab roof (owner 11/3): nothing of\n        // the picture below the cab roof line forward of the cab back, on both paths\n        if (a.pickup.cab_roof_y != null) sp.clipUnder = [cb, L(a.pickup.cab_roof_y)];\n        sp.rail = sp.floor - P(6);\n        parts.push(sp);\n      }\n    } else if (has(gear, 'platform_rack')) {\n      rack = platformRack(a.header_x + P(2), a.roof_rear_x - P(2), 0);\n      parts.push(rack);\n    }\n\n    // Tent\n    if (tentId) {\n      var T = TENTS[tentId];\n      var roomIn = (rack ? rack.x1 - rack.x0 : a.roof_rear_x - a.header_x) / ppi;\n      // the 60 in shell under 70 in of room (Justin); off a pickup the tent can't\n      // overhang the windshield or run past its carrier (owner 11/4): the 60 in\n      // shell whenever the 85 in won't fit (the large tent is always the 85 in)\n      var shortShell = T.kind === 'hard' && roomIn < (pickup || tentId === 'rtt_large' ? SHORT_ROOM_IN : T.len);   // the large tent stays 85 in\n      var len = P(shortShell ? SHORT_SHELL_IN : T.len);\n      var h = P(T.h);\n      var bottom;\n      var front;\n      var rear;\n      var room;   // length available for the tent (picks the tent picture)\n      if (pickup) {\n        // on the cap's roof bars (owner 11/4), else the bed / ladder rack, else the cab roof line\n        bottom = capPart ? capPart.roofY : rack ? rack.top : cabRoof;\n        // Owner phone review 1 (11/4): the tent never runs past the back of\n        // what carries it (cap, bed rack, ladder rack): its rear is the\n        // carrier's rear; it overhangs the cab by 12 in at most\n        var tentEnd = capPart ? capPart.x1 : rack ? rack.x1 : a.pickup.tailgate_x - P(2);\n        room = rack ? rack.x1 - rack.x0 : tentEnd - a.pickup.cab_back_x;\n        rear = tentEnd;\n        front = rear - len;\n        if (front < a.pickup.cab_back_x - P(CAB_OVERHANG_IN)) front = a.pickup.cab_back_x - P(CAB_OVERHANG_IN);\n      } else if (utv) {\n        // UTV: no longer than the cage, seated on the cage top\n        room = a.roof_rear_x - a.header_x;\n        len = Math.min(len, room);\n        front = a.header_x;\n        rear = front + len;\n        bottom = rack ? rack.top : roofTop(front, rear);\n      } else {\n        rear = rack ? Math.min(rack.x1, a.roof_rear_x - P(2)) : a.roof_rear_x - P(2);   // the carrier's rear (owner 11/4)\n        front = rear - len;\n        room = a.roof_rear_x - a.header_x;\n        if (front < a.header_x) front = a.header_x;                                          // never past the windshield header (the rear stays)\n        bottom = rack ? rack.top : roofTop(front, rear) - P(3);\n        if (!rack) {\n          parts.push({ type: 'feet', key: 'feet', x0: front + P(6), x1: rear - P(6), top: bottom,\n            roof: roofAt(front + P(7)), roof1: roofAt(rear - P(7)), w: P(2) });\n        }\n      }\n      parts.push({ type: 'tent', key: tentId, kind: T.kind, x0: front, x1: rear, bottom: bottom, h: h,\n        P1: P(1), pin: [rear, bottom], at: [1, 1],\n        span: T.kind === 'hard' ? (shortShell ? SHORT_SHELL_IN : T.len) : room / ppi });   // hard shells: the 60 or 85 in picture\n    }\n\n    // Awning\n    var awnId = firstOf(gear, ['awning', 'awning270']);\n    if (awnId) {\n      var alen = P(awnId === 'awning270' ? 98 : 79);\n      // Justin 11/2: on the rack's top edge, never below the roof (no rack:\n      // on the roof's highest point). Justin phone review 2 (11/4): on a rack\n      // it hangs on the rack's side, its top flush with the rack's top edge,\n      // so a tent on the rack can't swallow it (sitting on the rack top it\n      // was drawn inside the tent's bottom band and read as the tent's base).\n      // Owner phone review 1 (11/4): with a tent it hangs on the side of\n      // whatever carries the tent (cap roof bars, bed rack, roof rack), its top\n      // level with the tent's base, 7 in down.\n      var tentP = parts.filter(function (q) { return q.type === 'tent'; })[0];\n      var carrier = capPart || rack || cabRack;\n      var mount = carrier ? { x0: carrier.x0, x1: carrier.x1, y: tentP ? tentP.bottom : carrier.roofY != null ? carrier.roofY : carrier.top }\n        : { x0: a.header_x, x1: a.roof_rear_x, y: tentP ? tentP.bottom : roofTop(a.header_x, a.roof_rear_x) };\n      var ax1;\n      var ax0;\n      // never longer than the rack (or the roof) it hangs on (owner 11/2: the FJ40)\n      var mountLen = mount.x1 - Math.max(mount.x0, a.header_x);\n      var awnCapped = alen > mountLen;\n      if (awnCapped) alen = mountLen;\n      if (awnId === 'awning270') { ax1 = mount.x1; ax0 = ax1 - alen; } else { ax0 = (mount.x0 + mount.x1) / 2 - alen / 2; ax1 = ax0 + alen; }\n      if (ax0 < a.header_x) ax0 = a.header_x;                                              // never past the windshield header\n      if (carrier && carrier !== cabRack && ax0 < carrier.x0) ax0 = carrier.x0;            // a bed rack (or cap) awning stays over the bed\n      var aroof = roofTop(Math.max(ax0, a.header_x), Math.min(ax1, a.roof_rear_x));\n      var atop;\n      var ah = P(7);\n      if (!carrier && !tentP) atop = Math.min(mount.y, aroof) - ah;\n      else {\n        atop = mount.y;                                                        // flush with the carrier's top edge / the tent's base\n        if (!carrier || carrier.type === 'platform') ah = Math.max(P(4), Math.min(ah, aroof - atop));   // over a roof: never below it\n      }\n      var abot = atop + ah;\n      parts.push({ type: 'awning', key: awnId, x0: ax0, x1: ax1, top: atop, h: ah, P1: P(1), picW: awnCapped ? alen : null, outline: carrier === capPart && !!capPart,\n        pin: [awnId === 'awning270' ? ax1 : ax0, abot], at: [awnId === 'awning270' ? 1 : 0, 1] });   // picture: bottom on the mount\n    }\n\n    // Rock sliders (owner phone review 1, 11/4): a 3 in dark steel tube along\n    // the rocker, its bottom at the rocker bottom (measured from the paint\n    // mask when the page has it, a.rocker_y; else just over the hubs), from\n    // 2 in behind the front wheel opening to 2 in ahead of the rear one; on a\n    // pickup it stops at the cab back.\n    if (has(gear, 'sliders')) {\n      var sx0s = a.fwc[0] + a.fwc[2] + P(FENDER_GAP_IN) + P(2);\n      var sx1s = a.rwc[0] - a.rwc[2] - P(FENDER_GAP_IN) - P(2);\n      if (pickup) sx1s = Math.min(sx1s, cb);\n      var rockY = L(a.rocker_y != null ? a.rocker_y : Math.min(a.fwc[1], a.rwc[1]) - 0.2 * Math.min(a.fwc[2], a.rwc[2]));\n      if (sx1s > sx0s + P(6)) parts.push({ type: 'slider', key: 'sliders', x0: sx0s, x1: sx1s, top: rockY - P(SLIDER_IN), h: P(SLIDER_IN), P1: P(1) });\n    }\n\n    // Front winch bumper (either style: the same art for now, owner 11/11)\n    if (frontBumper(gear)) {\n      var fx = a.nose - P(jeep ? 4 : 6);\n      // Justin 11/3: the block from the headlight's bottom to 2 in under the\n      // stock bumper, 10 to 20 in (frontBumperBand).\n      var band = frontBumperBand(row, a);\n      var ft = L(band.top);\n      var fb = L(band.bottom);\n      // The wing sweeps back to the fender opening (stock opening, or the bigger tyre).\n      var archR = Math.max(a.fwc[2] + P(1.5), (tireR || 0) + P(1));\n      var wing = a.fwc[0] - archR;\n      parts.push({ type: 'bumper_f', key: 'bumper_f', fx: fx, top: ft, bottom: fb, wing: Math.max(wing, fx + P(18)),\n        winch: firstOf(gear, ['winch_syn', 'winch_steel']), P1: P(1), pin: [fx, fb], at: [0, 1], how: band.how,\n        nose: a.nose, clipX: wing, arch: [a.fwc[0], L(a.fwc[1]), archR] });   // picture: face at the nose, wing to the wheel opening\n    }\n\n    // Snow plow (Justin's sweep 2, 11/4: accepted but never drawn): the blade\n    // in front of the front bumper, its bottom 3 in off the ground, 28 in\n    // tall (half-ton) or 32 in (HD), plow yellow; the mount frame back to\n    // the bumper line (the winch bumper's face when there is one).\n    var plowId = firstOf(gear, ['plow_half', 'plow_hd']);\n    if (plowId) {\n      var bf = parts.filter(function (q) { return q.type === 'bumper_f'; })[0];\n      var bline = bf ? bf.fx : a.nose;\n      var pbot = G - P(PLOW_OFF_GROUND_IN);\n      var ptop = pbot - P(PLOW[plowId].h);\n      var pback = bline - P(PLOW_GAP_IN);\n      var mountY = Math.min(pbot - P(6), L(a.fwc[1]));   // the push frame at hub height, under the blade's middle at most\n      parts.push({ type: 'plow', key: plowId, x0: pback - P(PLOW_DEPTH_IN), x1: pback, top: ptop, bottom: pbot,\n        bumper: bline, mountY: mountY, P1: P(1) });\n    }\n\n    // Rear bumper, with the swing-out spare when it's the carrier bumper\n    var rearId = firstOf(gear, ['bumper_r', 'bumper_r_carrier']);\n    if (rearId) {\n      var rband = rearBumperBand(row, a);\n      var rface = rband.face;\n      var rTyreTop = tid ? G - P(D) : L(a.rwc[1]) - a.rwc[2];\n      // owner phone review 1 (11/4): top 1 in under the measured tailgate /\n      // rear door bottom (rear.json); unmeasured rigs keep Justin's 11/3 rule,\n      // rear tyre top + 3 in\n      var gateY = a.tailgate_bottom_y != null ? L(a.tailgate_bottom_y) : null;\n      var rtop = gateY != null ? gateY + P(REAR_BELOW_GATE_IN) : rTyreTop - P(REAR_TOP_OVER_TYRE_IN);\n      var clearTop = gateY != null ? gateY + 1 : rtop - P(0.5);   // the stock bumper's full height, from the gate bottom down\n      var rbot = rtop + P(REAR_H_IN);\n      var rr = Math.max(a.rwc[2] + P(1), (tireR || 0) + P(1));\n      var rend = Math.max(a.tail, rface + P(REAR_DEPTH_IN)) + P(2);\n      var rb = { type: 'bumper_r', key: rearId, face: rface, x0: rface - P(REAR_CAP_IN), x1: rface + P(REAR_DEPTH_IN),\n        top: rtop, bottom: rbot, P1: P(1), how: rband.how, gate: gateY,\n        // the stock bumper cleared, its full height (owner 11/4): from the gate\n        // bottom (or the top line) down, under the body past the box and behind\n        // the face down past the hub (the wheel kept)\n        erases: [[rface - P(REAR_CAP_IN), clearTop, rend, rbot + P(1)],\n          [rface, clearTop, rend, Math.max(rbot, hubR) + P(3)]],\n        eraseHole: [a.rwc[0], hubR, rr] };   // drawn, never a picture: a solid box (owner 11/3)\n      // every rig (Justin's sweep 2, 11/4: on pickups the rear.json numbers\n      // floated the box too); rear.json / the tyre rule only when the\n      // silhouette can't be read\n      var sb = a.rear_bumper;\n      if (sb) {\n        // the stock bumper found in the\n        // picture's silhouette (measureRearBumper) is cleared and the new box\n        // drawn over the same span: top = the stock top, bottom 2 in over the\n        // stock bottom, face 3 in behind the stock face, the box 20 in long\n        // (never over the rear tyre)\n        var sTop = L(sb.top);\n        var sBot = L(sb.bottom);\n        var bx1 = sb.face + P(REAR_SILHOUETTE_BACK_IN);\n        rface = bx1 - P(REAR_DEPTH_IN);\n        rtop = sTop;\n        rbot = Math.max(sTop + P(6), sBot - P(REAR_SILHOUETTE_UP_IN));\n        var tyreBack = a.rwc[0] + rr;\n        var bx0 = Math.max(rface - P(REAR_CAP_IN), tyreBack);\n        rb.face = rface;\n        rb.x0 = bx0;\n        rb.x1 = bx1;\n        rb.top = rtop;\n        rb.bottom = rbot;\n        rb.how = 'silhouette';\n        rb.gate = null;\n        rb.erases = [[Math.max(bx0, a.rwc[0] + a.rwc[2]), sTop - P(0.5), Math.max(a.tail, bx1) + P(2), sBot + P(1)]];\n      }\n      parts.push(rb);\n      if (rearId === 'bumper_r_carrier' && !row.has_rear_spare) {\n        // a rig with a factory rear-door spare keeps the bumper only\n        var sd = P(D);\n        var sx0 = rface + P(SPARE_BEHIND_FACE_IN);\n        var stop = rtop - P(SPARE_OVER_BUMPER_IN) - sd;\n        var shub = [sx0 + P(SPARE_W_IN) / 2, stop + sd / 2];\n        parts.push({ type: 'spare', key: 'spare', x0: sx0, x1: sx0 + P(SPARE_W_IN), top: stop, h: sd, P1: P(1),\n          pin: [sx0, stop], at: [0, 0], picH: sd });   // the spare picture is drawn as tall as the tyre\n        // the arm is outboard at the corner: a vertical 3 in bar from the\n        // bumper's top rear corner up to the hub's height, drawn OVER the tyre\n        parts.push({ type: 'swing_arm', x: rb.x1 - P(ARM_IN) / 2, w: P(ARM_IN), y0: rtop, hinge: P(HINGE_IN), hub: [rb.x1 - P(ARM_IN) / 2, shub[1]], P1: P(1) });\n      }\n    }\n\n    // Light bar\n    if (has(gear, 'lightbar')) {\n      // Justin 11/4: a 5 in x 8 in dark rounded block on the roof at the\n      // windshield header (every rig, whatever else is ticked), no post.\n      var lbw = P(LIGHTBAR_W_IN);\n      var lbH = P(LIGHTBAR_H_IN);\n      var lbx = a.header_x;\n      var lby = Math.min(roofAt(lbx + P(1)), roofAt(lbx + lbw - P(1)));\n      parts.push({ type: 'lightbar', key: 'lightbar', x0: lbx, y0: lby - lbH, w: lbw, h: lbH, P1: P(1) });\n    }\n\n    // Tyres last (on top)\n    if (tid) {\n      [a.fwc[0], a.rwc[0]].forEach(function (x) {\n        parts.push({ type: 'tire', key: tid, cx: x, cy: G - P(D / 2), r: P(D / 2), rim: P(Math.min(9, D / 4)), P1: P(1),\n          pin: [x, G - P(D / 2)], at: [0.5, 0.5], picH: P(D) });   // picture: round, as tall as it is wide\n      });\n    }\n\n    // Photo cutouts replace drawn parts where the data has them\n    var size = sizeClass(row);\n    var picSize = jeep ? 'jeep' : size;\n    parts.forEach(function (p) {\n      var pic = p.key && p.pin ? partPicture(pics, p.picKey || p.key, picSize, p.span) : null;\n      if (!pic) return;\n      if (p.type === 'flatbed' && pic.auto) {\n        // the SET-style flatbed picture (MAHZ1QlMpyU): its deck, headache\n        // rack and wheel arch are measured from its own pixels once it has\n        // loaded (flatbedShape), then it is fitted to the planned deck, skirt\n        // and rear wheel (flatbedSlices); drawn until then\n        p.pic = pic;\n        p.autoShape = true;\n        p.picBox = partBounds(p);\n        return;\n      }\n      if (p.type === 'gfc' || p.type === 'slidein' || p.type === 'flatbed') {\n        // v4 bed pictures: cut into slices the page scales apart (measured by the pipeline)\n        var sl = bedSlices(p, pic, P);\n        if (!sl) return;     // a picture without its slice measurements: the drawn part stays\n        p.pic = pic;\n        p.slices = sl.slices;\n        p.picBox = sl.box;\n        return;\n      }\n      if (p.type === 'bumper_f' && !pic.at && pic.width_in > 0 && pic.height_in > 0) {\n        // Justin 11/3: the block (below face_top; a hoop rises above it)\n        // scaled to the planned block height, at that scale from the nose;\n        // then the wing from the block back along the fender to the wheel\n        // opening (where the arch is at the wing's top edge), scaled to that\n        // distance. Only what passes into the opening is cut (clipArc).\n        var bft = pic.face_top || 0;\n        var bph = (p.bottom - p.top) / (1 - bft);\n        var bpw = bph * pic.width_in / pic.height_in;\n        var by0 = p.top - bft * bph;\n        var bx0 = p.nose;\n        var wl = bumperWingLeft(pic);\n        var bw = (wl == null ? 1 : wl) * bpw;    // the block's width at this scale\n        var bx1;\n        var bsl;\n        if (wl == null) {                        // no wing (Jeep stubby): the picture at its scale\n          bsl = [{ src: [0, 0, 1, 1], dst: [bx0, by0, bw, bph] }];\n          bx1 = bx0 + bw;\n        } else {\n          // the opening's front edge at the height of the wing's top edge\n          var prof = pic.top_profile || [];\n          var wtop = 1;\n          for (var k = 0; k < prof.length; k++) if (k / (prof.length - 1) >= wl) wtop = Math.min(wtop, prof[k]);\n          var arc = p.arch;\n          var dy = arc[1] - (by0 + wtop * bph);\n          var reach = Math.abs(dy) < arc[2] ? arc[0] - Math.sqrt(arc[2] * arc[2] - dy * dy) : arc[0];\n          var room = Math.max(0, reach - bx0);\n          var blockW = Math.min(bw, (1 - BUMPER_F_WING_SHARE) * room);\n          if (!(blockW > 0)) blockW = bw;        // no room at all: the block, cut by the opening\n          bsl = [{ src: [0, 0, wl, 1], dst: [bx0, by0, blockW, bph] }];\n          bx1 = bx0 + blockW;\n          if (reach > bx1) {\n            bsl.push({ src: [wl, 0, 1 - wl, 1], dst: [bx1, by0, reach - bx1, bph] });\n            bx1 = reach;\n          }\n        }\n        p.pic = pic;\n        p.slices = bsl;\n        p.clipArc = p.arch;\n        p.picBox = [bx0, by0, bx1, by0 + bph];\n        return;\n      }\n      var byHeight = pic.scale === 'height';\n      if (byHeight ? !(pic.height_in > 0) : !(pic.width_in > 0)) return;\n      if (p.key === 'bumper_r_carrier' && !(pic.height_in > 0)) return;   // can't hang the spare without its height\n      p.pic = pic;\n      p.picAt = pic.at || p.at;\n      var h = p.picH || (pic.height_in > 0 ? P(pic.height_in) : 0);\n      // real width; sized by height, the width comes from the picture's shape (width_in, if given, is the estimate until it loads)\n      var w = p.picW || (pic.width_in > 0 ? P(pic.width_in) : h);   // picW: a capped length (the awning)\n      if (h > 0) {\n        var x = p.pin[0] - p.picAt[0] * w;\n        var y = p.pin[1] - p.picAt[1] * h;\n        p.picBox = [x, y, x + w, y + h];\n      }\n    });\n\n    // Bounds of everything (for fitting the scene in the picture box)\n    var minY = Math.min(a.roof_top_y - rise, G - 1);\n    var minX = a.nose;\n    var maxX = a.tail;\n    parts.forEach(function (p) {\n      var b = partBounds(p);\n      if (b) { minY = Math.min(minY, b[1]); minX = Math.min(minX, b[0]); maxX = Math.max(maxX, b[2]); }\n    });\n    return { ppi: ppi, rise: rise, riseIn: riseIn, tire: tid, size: size, parts: parts, autoRack: !!(rack && rack.auto), cabGuardIn: cabGuardIn,\n      bounds: [minX, minY, maxX, G], body: [a.nose, Math.min(a.roof_top_y - rise, G - 1), a.tail, G], facing: a.facing || 'left' };\n  }\n\n  function partBounds(p) {\n    if (p.picBox) return p.picBox;\n    switch (p.type) {\n      case 'bedrack': return [p.x0, p.top, p.x1, p.rail];\n      case 'platform': return [p.x0, p.top, p.x1, p.roof];\n      case 'tent': return [p.x0, p.bottom - p.h, p.x1, p.bottom];\n      case 'awning': return [p.x0, p.top, p.x1, p.top + p.h];\n      case 'bumper_f': return [p.fx, p.top, p.wing, p.bottom];\n      case 'bumper_r': return [p.x0, p.top, p.x1, p.bottom];\n      case 'plow': return [p.x0 - 3 * p.P1, p.top, p.bumper, p.bottom];\n      case 'swing_arm': return [Math.min(p.x, p.hub[0]) - p.w, p.hub[1] - p.w, Math.max(p.x, p.hub[0]) + p.w, p.y0];\n      case 'spare': return [p.x0, p.top, p.x1, p.top + p.h];\n      case 'lightbar': return [p.x0, p.y0, p.x0 + p.w, p.y0 + p.h];\n      case 'cap': return [p.x0, p.top, p.x1, p.rail];\n      case 'gfc': return [Math.min(p.x0, p.brimX), p.top, p.x1, p.rail];\n      case 'slidein': return [p.nose, p.top, p.x1, p.floor];\n      case 'underframe': return [p.x0, p.y0, p.x1, p.y1];\n      case 'slider': return [p.x0, p.top - 1.5 * p.P1, p.x1, p.top + p.h];\n      case 'toolbox': return [p.x0, p.top, p.x1, p.lip];\n      case 'sideboxes': return [p.x0, p.top, p.x1, p.rail];\n      case 'ladder': return [p.front, p.top, p.x1, p.rail];\n      case 'flatbed': return [p.x0, p.headache ? p.cabRoof : p.deck, p.x1, p.skirtBot || p.deck + p.t];\n      case 'tire': return [p.cx - p.r, p.cy - p.r, p.cx + p.r, p.cy + p.r];\n      default: return null;\n    }\n  }\n\n  // ---- drawing (canvas 2D; coordinates are frame pixels)\n\n  function rrect(ctx, x, y, w, h, r) {\n    r = Math.max(0, Math.min(r, w / 2, h / 2));\n    ctx.beginPath();\n    ctx.moveTo(x + r, y);\n    ctx.lineTo(x + w - r, y);\n    ctx.quadraticCurveTo(x + w, y, x + w, y + r);\n    ctx.lineTo(x + w, y + h - r);\n    ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n    ctx.lineTo(x + r, y + h);\n    ctx.quadraticCurveTo(x, y + h, x, y + h - r);\n    ctx.lineTo(x, y + r);\n    ctx.quadraticCurveTo(x, y, x + r, y);\n    ctx.closePath();\n  }\n\n  function poly(ctx, pts) {\n    ctx.beginPath();\n    ctx.moveTo(pts[0][0], pts[0][1]);\n    for (var i = 1; i < pts.length; i++) ctx.lineTo(pts[i][0], pts[i][1]);\n    ctx.closePath();\n  }\n\n  /** A faint diamond-plate texture over a box (the aluminum tool boxes). */\n  function diamond(ctx, x, y, w, h, u) {\n    ctx.save();\n    ctx.beginPath();\n    ctx.rect(x, y, w, h);\n    ctx.clip();\n    ctx.strokeStyle = 'rgba(255, 255, 255, 0.35)';\n    ctx.lineWidth = 0.25 * u;\n    var step = 2.2 * u;\n    for (var r = 0, yy = y + step / 2; yy < y + h; yy += step, r++) {\n      for (var xx = x + (r % 2 ? step : step / 2); xx < x + w; xx += 2 * step) {\n        ctx.beginPath(); ctx.moveTo(xx - 0.5 * u, yy + 0.3 * u); ctx.lineTo(xx + 0.5 * u, yy - 0.3 * u); ctx.stroke();\n      }\n    }\n    ctx.restore();\n  }\n\n  function hiLine(ctx, x0, y0, x1, y1, w, color) {\n    ctx.beginPath();\n    ctx.moveTo(x0, y0);\n    ctx.lineTo(x1, y1);\n    ctx.lineWidth = w;\n    ctx.strokeStyle = color || PART.steelHi;\n    ctx.lineCap = 'round';\n    ctx.stroke();\n  }\n\n  var DRAW = {\n    bedrack: function (ctx, p) {\n      var u = p.bar;\n      ctx.fillStyle = PART.steel;\n      // uprights at both ends and the middle, top rail, lower rail just above the bed rail\n      [p.x0, (p.x0 + p.x1) / 2 - u / 2, p.x1 - u].forEach(function (x) { ctx.fillRect(x, p.top, u, p.rail - p.top); });\n      rrect(ctx, p.x0 - u * 0.5, p.top, p.x1 - p.x0 + u, u, u * 0.3); ctx.fill();\n      ctx.fillRect(p.x0, p.rail - u * 2.2, p.x1 - p.x0, u * 0.75);\n      hiLine(ctx, p.x0, p.top + u * 0.18, p.x1, p.top + u * 0.18, u * 0.16);\n    },\n    platform: function (ctx, p) {\n      ctx.fillStyle = PART.steel;\n      // each leg reaches down to the roof below it\n      p.legs.forEach(function (l) { ctx.fillRect(l[0], p.top + p.t, 3 * p.P1, Math.max(l[1] - p.top - p.t, p.P1)); });\n      rrect(ctx, p.x0, p.top, p.x1 - p.x0, p.t, p.t * 0.25); ctx.fill();\n      hiLine(ctx, p.x0 + p.P1, p.top + p.t * 0.2, p.x1 - p.P1, p.top + p.t * 0.2, p.P1 * 0.3);\n    },\n    feet: function (ctx, p) {\n      ctx.fillStyle = PART.steel;\n      ctx.fillRect(p.x0, p.top, p.w, Math.max(p.roof - p.top, 1));\n      ctx.fillRect(p.x1 - p.w, p.top, p.w, Math.max(p.roof1 - p.top, 1));\n    },\n    tent: function (ctx, p) {\n      var P1 = p.P1;\n      var w = p.x1 - p.x0;\n      var soft = p.kind === 'soft';\n      ctx.fillStyle = soft ? PART.tan : PART.shell;\n      rrect(ctx, p.x0, p.bottom - p.h, w, p.h, (soft ? 3 : 2.5) * P1); ctx.fill();\n      // base / lid seam (hard) or zip line (soft)\n      hiLine(ctx, p.x0 + P1, p.bottom - (soft ? 0.45 : 0.3) * p.h, p.x1 - P1, p.bottom - (soft ? 0.45 : 0.3) * p.h,\n        0.35 * P1, soft ? PART.tanDark : PART.steelDark);\n      hiLine(ctx, p.x0 + 2 * P1, p.bottom - p.h + 0.7 * P1, p.x1 - 2 * P1, p.bottom - p.h + 0.7 * P1, 0.35 * P1,\n        soft ? '#d8cbb0' : PART.shellHi);\n      if (soft) {   // cover straps\n        ctx.fillStyle = PART.tanDark;\n        [0.2, 0.5, 0.8].forEach(function (f) { ctx.fillRect(p.x0 + f * w, p.bottom - p.h, 1.2 * P1, p.h); });\n      }\n    },\n    awning: function (ctx, p) {\n      // rolled awning bag, 7 in tall, a shade lighter than the rack steel\n      var P1 = p.P1;\n      var w = p.x1 - p.x0;\n      ctx.fillStyle = PART.awning;\n      rrect(ctx, p.x0, p.top, w, p.h, 3 * P1); ctx.fill();\n      if (p.outline) {   // on a cap's side (Justin sweep 11/4): a dark edge so it reads against any cap colour\n        ctx.strokeStyle = PART.steelDark;\n        ctx.lineWidth = 0.6 * P1;\n        ctx.stroke();\n      }\n      ctx.fillStyle = PART.awningDark;   // underside shade\n      rrect(ctx, p.x0 + 0.5 * P1, p.top + p.h * 0.62, w - P1, p.h * 0.38, 2.5 * P1); ctx.fill();\n      hiLine(ctx, p.x0 + 2.5 * P1, p.top + 1.1 * P1, p.x1 - 2.5 * P1, p.top + 1.1 * P1, 0.45 * P1, PART.awningHi);\n      ctx.fillStyle = PART.steelDark;    // end caps and mounting brackets up to the rack\n      ctx.fillRect(p.x0, p.top + 0.6 * P1, 1.6 * P1, p.h - 1.2 * P1);\n      ctx.fillRect(p.x1 - 1.6 * P1, p.top + 0.6 * P1, 1.6 * P1, p.h - 1.2 * P1);\n      [0.2, 0.5, 0.8].forEach(function (f) { ctx.fillRect(p.x0 + f * w - 0.75 * P1, p.top - P1, 1.5 * P1, p.h * 0.55 + P1); });\n    },\n    bumper_f: function (ctx, p) {\n      // winch bumper: front face, wing sweeping up and back to the fender opening\n      var u = p.P1;\n      var fx = p.fx;\n      var t = p.top;\n      var b = p.bottom;\n      var hgt = b - t;\n      var wx = p.wing;\n      var low = fx + Math.min(14 * u, (wx - fx) * 0.55);   // where the underside turns up into the wing\n      var wingLow = t + hgt * 0.7;\n      ctx.fillStyle = PART.steel;\n      poly(ctx, [[fx + 1.5 * u, t], [fx + 9 * u, t], [wx - 1.5 * u, t - 1.5 * u], [wx, t - 0.5 * u], [wx - 0.5 * u, wingLow - u],\n        [wx - 2.5 * u, wingLow], [low + 3 * u, b - 2 * u], [low, b], [fx + 3 * u, b], [fx, b - 3 * u], [fx, t + 1.5 * u]]);\n      ctx.fill();\n      // winch cavity (darker recess behind the face) and the lower plate seam\n      ctx.fillStyle = PART.steelDark;\n      rrect(ctx, fx + 2.5 * u, t + 2 * u, Math.min(9 * u, low - fx - 3 * u), hgt * 0.42, u); ctx.fill();\n      hiLine(ctx, fx + 1.5 * u, b - hgt * 0.3, low + 1.5 * u, b - hgt * 0.3, 0.3 * u, PART.steelDark);\n      // top edge highlight along the sweep\n      hiLine(ctx, fx + 1.5 * u, t + 0.4 * u, fx + 9 * u, t + 0.4 * u, 0.4 * u);\n      hiLine(ctx, fx + 9 * u, t + 0.4 * u, wx - 1.5 * u, t - 1.1 * u, 0.4 * u);\n      // shackle tab on top\n      ctx.fillStyle = PART.steel;\n      rrect(ctx, fx + 4 * u, t - 2.5 * u, 2 * u, 3 * u, 0.8 * u); ctx.fill();\n      ctx.fillStyle = PART.steelHi;\n      ctx.beginPath(); ctx.arc(fx + 5 * u, t - 1.3 * u, 0.45 * u, 0, 2 * Math.PI); ctx.fill();\n      // fairlead: a plate standing proud of the front face, upper third\n      var fy = t + Math.max(3 * u, hgt * 0.3);\n      ctx.fillStyle = p.winch === 'winch_steel' ? PART.steelDark : PART.fairlead;\n      rrect(ctx, fx - 1.6 * u, fy - 2.2 * u, 2.4 * u, 4.4 * u, 0.5 * u); ctx.fill();\n      hiLine(ctx, fx - 1.2 * u, fy - 1.8 * u, fx - 1.2 * u, fy + 1.8 * u, 0.3 * u, p.winch === 'winch_steel' ? PART.steelHi : PART.fairleadHi);\n    },\n    plow: function (ctx, p) {\n      // side on: the curved moldboard (plow yellow, its cutting edge steel),\n      // braces behind it, and the push frame and lift arm back to the bumper\n      var u = p.P1;\n      var x0 = p.x0;\n      var x1 = p.x1;\n      var t = p.top;\n      var b = p.bottom;\n      var mid = (t + b) / 2;\n      var th = 4 * u;     // moldboard thickness\n      ctx.fillStyle = PART.steel;   // push frame and lift arm\n      ctx.fillRect(x1, p.mountY - 2 * u, p.bumper - x1, 4 * u);\n      poly(ctx, [[x1, t + 4 * u], [x1 + 2 * u, t + 2.5 * u], [p.bumper, p.mountY - 10 * u], [p.bumper, p.mountY - 6 * u]]);\n      ctx.fill();\n      ctx.fillRect(x1 - 3 * u, t + 3 * u, 3 * u, b - t - 5 * u);   // the A-frame upright behind the blade\n      ctx.fillStyle = '#e3ae17';     // moldboard\n      ctx.beginPath();\n      ctx.moveTo(x0, b);\n      ctx.quadraticCurveTo(x1 + 2 * u, mid, x0 - 3 * u, t);\n      ctx.lineTo(x0 - 3 * u + th, t);\n      ctx.quadraticCurveTo(x1 + 2 * u + th, mid, x0 + th + 2 * u, b);\n      ctx.closePath();\n      ctx.fill();\n      ctx.strokeStyle = '#8f6c0b';   // its back edge, shaded\n      ctx.lineWidth = 0.6 * u;\n      ctx.beginPath();\n      ctx.moveTo(x0 + th + 2 * u, b);\n      ctx.quadraticCurveTo(x1 + 2 * u + th, mid, x0 - 3 * u + th, t);\n      ctx.stroke();\n      ctx.fillStyle = PART.steelDark;   // cutting edge\n      ctx.fillRect(x0 - u, b - 2 * u, th + 3 * u, 2 * u);\n    },\n    bumper_r: function (ctx, p) {\n      // a solid black box across the tail with a 1 in lighter top edge (owner 11/3)\n      var P1 = p.P1;\n      ctx.fillStyle = '#16171a';\n      ctx.fillRect(p.x0, p.top, p.x1 - p.x0, p.bottom - p.top);\n      ctx.fillStyle = '#44464b';\n      ctx.fillRect(p.x0, p.top, p.x1 - p.x0, P1);\n    },\n    swing_arm: function (ctx, p) {\n      // 6 in hinge block on the bumper's rear top corner, then the 3 in square\n      // tube from it up to the spare's hub\n      var u = p.P1;\n      var bx = p.x - p.w;\n      ctx.fillStyle = PART.steelDark;\n      ctx.fillRect(bx, p.y0 - p.hinge, 2 * p.w, p.hinge);\n      var x0 = p.x;\n      var y0 = p.y0 - p.hinge;\n      var dx = p.hub[0] - x0;\n      var dy = p.hub[1] - y0;\n      var len = Math.sqrt(dx * dx + dy * dy) || 1;\n      var nx = -dy / len * p.w / 2;\n      var ny = dx / len * p.w / 2;\n      ctx.fillStyle = PART.steel;\n      poly(ctx, [[x0 + nx, y0 + ny], [p.hub[0] + nx, p.hub[1] + ny], [p.hub[0] - nx, p.hub[1] - ny], [x0 - nx, y0 - ny]]);\n      ctx.fill();\n      hiLine(ctx, x0 + nx * 0.6, y0 + ny * 0.6, p.hub[0] + nx * 0.6, p.hub[1] + ny * 0.6, 0.3 * u);\n    },\n    spare: function (ctx, p) {\n      // swing-out spare seen edge-on: tread face, rounded top and bottom\n      var u = p.P1;\n      var x0 = p.x0;\n      var w = p.x1 - p.x0;\n      var top = p.top;\n      var h = p.h;\n      var R = h / 2;\n      var cy = top + R;\n      // tyre body with rounded ends\n      var ry = Math.min(5 * u, R);\n      var g = ctx.createLinearGradient(0, top, 0, top + h);\n      g.addColorStop(0, PART.treadEdge); g.addColorStop(0.12, PART.tread); g.addColorStop(0.5, PART.treadMid);\n      g.addColorStop(0.88, PART.tread); g.addColorStop(1, PART.treadEdge);\n      ctx.fillStyle = g;\n      ctx.beginPath();\n      ctx.moveTo(x0, top + ry);\n      ctx.bezierCurveTo(x0, top + ry * 0.3, x0 + w * 0.2, top, x0 + w / 2, top);\n      ctx.bezierCurveTo(x0 + w * 0.8, top, x0 + w, top + ry * 0.3, x0 + w, top + ry);\n      ctx.lineTo(x0 + w, top + h - ry);\n      ctx.bezierCurveTo(x0 + w, top + h - ry * 0.3, x0 + w * 0.8, top + h, x0 + w / 2, top + h);\n      ctx.bezierCurveTo(x0 + w * 0.2, top + h, x0, top + h - ry * 0.3, x0, top + h - ry);\n      ctx.closePath();\n      ctx.fill();\n      ctx.save();\n      ctx.clip();\n      // sidewall shoulders\n      ctx.fillStyle = PART.sidewall;\n      ctx.fillRect(x0, top + ry, 0.9 * u, h - 2 * ry);\n      ctx.fillRect(x0 + w - 0.9 * u, top + ry, 0.9 * u, h - 2 * ry);\n      // tread grooves: staggered lugs, closer together toward the ends (the tyre curves away)\n      ctx.fillStyle = PART.groove;\n      var n = Math.max(8, Math.round(Math.PI * R / (2.4 * u)));\n      for (var i = 1; i < n; i++) {\n        var y = cy - R * Math.cos(Math.PI * i / n);\n        var gh = Math.max(0.15 * u, 0.55 * u * Math.sin(Math.PI * i / n));\n        if (i % 2) ctx.fillRect(x0 + 1.2 * u, y - gh / 2, w / 2 - 1.6 * u, gh);\n        else ctx.fillRect(x0 + w / 2 + 0.4 * u, y - gh / 2, w / 2 - 1.6 * u, gh);\n      }\n      ctx.fillRect(x0 + w / 2 - 0.3 * u, top + ry * 0.6, 0.6 * u, h - 1.2 * ry);   // centre groove\n      hiLine(ctx, x0 + 1.4 * u, top + ry, x0 + 1.4 * u, top + h * 0.45, 0.35 * u, PART.treadHi);\n      ctx.restore();\n    },\n    lightbar: function (ctx, p) {\n      // a dark rounded block, a faint lens line along its face (Justin 11/4)\n      var u = p.P1;\n      ctx.fillStyle = '#131416';\n      rrect(ctx, p.x0, p.y0, p.w, p.h, 1.2 * u); ctx.fill();\n      hiLine(ctx, p.x0 + 1.2 * u, p.y0 + 0.6 * u, p.x0 + p.w - 1.2 * u, p.y0 + 0.6 * u, 0.3 * u);\n      ctx.fillStyle = PART.lens;\n      rrect(ctx, p.x0 - 0.1 * u, p.y0 + 1.2 * u, 0.9 * u, p.h - 2.4 * u, 0.3 * u); ctx.fill();\n    },\n    cap: function (ctx, p) {\n      var P1 = p.P1;\n      var paint = !p.alu && hexRgb(p.paint) ? p.paint : null;   // fiberglass: body colour (Justin sweep 11/4)\n      ctx.fillStyle = p.alu ? PART.alu : paint || PART.shell;\n      poly(ctx, [[p.x0, p.rail], [p.x0 + 2 * P1, p.top], [p.x1 - P1, p.top + p.rake], [p.x1, p.top + p.rake + 2 * P1], [p.x1, p.rail]]);\n      ctx.fill();\n      if (paint) {   // shaded like the body: lighter along the top, darker toward the rail\n        var sh = ctx.createLinearGradient(0, p.top, 0, p.rail);\n        sh.addColorStop(0, 'rgba(255,255,255,0.18)'); sh.addColorStop(0.45, 'rgba(255,255,255,0)'); sh.addColorStop(1, 'rgba(0,0,0,0.22)');\n        ctx.fillStyle = sh;\n        ctx.fill();\n      }\n      ctx.fillStyle = PART.glass;   // side window\n      rrect(ctx, p.x0 + 0.12 * (p.x1 - p.x0), p.top + 2.5 * P1, 0.6 * (p.x1 - p.x0), (p.rail - p.top) * 0.55, 1.5 * P1); ctx.fill();\n      hiLine(ctx, p.x0 + 2.5 * P1, p.top + 0.4 * P1, p.x1 - 2 * P1, p.top + p.rake + 0.4 * P1, 0.35 * P1, p.alu ? PART.aluHi : PART.shellHi);\n    },\n    gfc: function (ctx, p) {\n      // level box: charcoal side panel, black lid with the brim over the cab\n      var P1 = p.P1;\n      ctx.fillStyle = '#3b3d40';\n      ctx.fillRect(p.x0, p.lidBot, p.x1 - p.x0, p.rail - p.lidBot);\n      ctx.fillStyle = '#141516';\n      rrect(ctx, p.brimX, p.top, p.x1 - p.brimX, p.lidBot - p.top, 0.8 * P1); ctx.fill();\n      hiLine(ctx, p.brimX + P1, p.top + 0.5 * P1, p.x1 - P1, p.top + 0.5 * P1, 0.35 * P1, '#4a4c50');\n    },\n    slidein: function (ctx, p) {\n      var P1 = p.P1;\n      ctx.fillStyle = PART.camper;\n      poly(ctx, [[p.cb + P1, p.rail + 6 * P1], [p.cb + P1, p.cabRoof - P1], [p.nose + 6 * P1, p.cabRoof - P1], [p.nose, p.cabRoof - 6 * P1],\n        [p.nose + 4 * P1, p.top], [p.x1 - P1, p.top], [p.x1, p.top + 2 * P1], [p.x1, p.rail + 6 * P1]]);\n      ctx.fill();\n      ctx.fillStyle = PART.camperDark;   // body stripe\n      ctx.fillRect(p.nose + 3 * P1, p.cabRoof - 4 * P1, p.x1 - p.nose - 3 * P1, 1.5 * P1);\n      ctx.fillStyle = PART.glass;\n      rrect(ctx, p.cb + 0.35 * (p.x1 - p.cb), p.top + 4 * P1, 18 * P1, 10 * P1, 1.5 * P1); ctx.fill();\n    },\n    slider: function (ctx, p) {\n      // a 3 in dark steel tube along the rocker (owner 11/4)\n      var u = p.P1;\n      ctx.fillStyle = '#1b1c1f';\n      rrect(ctx, p.x0, p.top, p.x1 - p.x0, p.h, p.h * 0.45); ctx.fill();\n      hiLine(ctx, p.x0 + 1.5 * u, p.top + 0.7 * u, p.x1 - 1.5 * u, p.top + 0.7 * u, 0.35 * u, '#55585e');\n      ctx.fillStyle = '#121315';   // the two body mounts\n      [0.25, 0.75].forEach(function (f) { ctx.fillRect(p.x0 + f * (p.x1 - p.x0) - u, p.top - 1.5 * u, 2 * u, 1.5 * u); });\n    },\n    toolbox: function (ctx, p) {\n      // crossover tool box, light silver aluminum, a lip down over the bed side\n      var u = p.P1;\n      ctx.fillStyle = '#c9ccd0';\n      rrect(ctx, p.x0, p.top, p.x1 - p.x0, p.rail - p.top, 0.8 * u); ctx.fill();\n      ctx.fillStyle = '#b4b8bd';\n      ctx.fillRect(p.x0, p.rail, p.x1 - p.x0, p.lip - p.rail);\n      diamond(ctx, p.x0, p.top, p.x1 - p.x0, p.lip - p.top, u);\n      hiLine(ctx, p.x0 + u, p.top + 0.5 * u, p.x1 - u, p.top + 0.5 * u, 0.35 * u, '#eef0f2');\n      ctx.fillStyle = '#8d9298';   // the lid seam\n      ctx.fillRect(p.x0, p.top + 2 * u, p.x1 - p.x0, 0.35 * u);\n    },\n    sideboxes: function (ctx, p) {\n      // side boxes on the rails, aluminum, a door in each section\n      var u = p.P1;\n      ctx.fillStyle = '#c9ccd0';\n      rrect(ctx, p.x0, p.top, p.x1 - p.x0, p.rail - p.top, 0.8 * u); ctx.fill();\n      diamond(ctx, p.x0, p.top, p.x1 - p.x0, p.rail - p.top, u);\n      hiLine(ctx, p.x0 + u, p.top + 0.5 * u, p.x1 - u, p.top + 0.5 * u, 0.35 * u, '#eef0f2');\n      ctx.strokeStyle = '#8d9298';\n      ctx.lineWidth = 0.4 * u;\n      var n = Math.max(1, Math.round((p.x1 - p.x0) / (30 * u)));\n      for (var i = 0; i < n; i++) {\n        var dx = p.x0 + (p.x1 - p.x0) * i / n;\n        ctx.strokeRect(dx + 1.5 * u, p.top + 2.5 * u, (p.x1 - p.x0) / n - 3 * u, p.rail - p.top - 4 * u);\n      }\n    },\n    ladder: function (ctx, p) {\n      // black steel ladder rack, 2 in square tube: two uprights from the rail,\n      // the top rail on forward over the cab to the windshield header\n      var t = p.tube;\n      ctx.fillStyle = '#16171a';\n      ctx.fillRect(p.x0, p.top, t, p.rail - p.top);\n      ctx.fillRect(p.x1 - t, p.top, t, p.rail - p.top);\n      ctx.fillRect(p.front, p.top, p.x1 - p.front, t);\n      hiLine(ctx, p.front + p.P1, p.top + 0.4 * p.P1, p.x1 - p.P1, p.top + 0.4 * p.P1, 0.3 * p.P1, '#3c3e43');\n    },\n    underframe: function (ctx, p) {\n      ctx.fillStyle = '#18191b';   // the frame and what hangs off it, in shadow under the flatbed\n      ctx.fillRect(p.x0, p.y0, p.x1 - p.x0, p.y1 - p.y0);\n    },\n    flatbed: function (ctx, p) {\n      var P1 = p.P1;\n      var top = p.deck + p.t;\n      var ch = Math.min(6 * P1, (p.skirtBot - top) * 0.6);   // the skirt's rear corner angles up\n      // skirt of storage boxes; the wheel arch is a dark wheel well, never\n      // the background (the tyre is drawn over it). Aluminum: bare silver\n      // (Justin's sweep 2), shaded like the aluminum cap\n      ctx.fillStyle = p.alu ? PART.alu : PART.steelDark;\n      poly(ctx, [[p.x0, top], [p.x1, top], [p.x1, p.skirtBot - ch], [p.x1 - 1.6 * ch, p.skirtBot], [p.x0, p.skirtBot]]);\n      ctx.fill();\n      ctx.strokeStyle = p.alu ? '#6f747a' : PART.steel;   // box doors\n      ctx.lineWidth = 0.4 * P1;\n      var n = Math.max(2, Math.round((p.x1 - p.x0) / (24 * P1)));\n      for (var i = 1; i < n; i++) {\n        var x = p.x0 + (p.x1 - p.x0) * i / n;\n        ctx.beginPath(); ctx.moveTo(x, top + P1); ctx.lineTo(x, p.skirtBot - P1); ctx.stroke();\n      }\n      ctx.save();\n      ctx.beginPath();\n      ctx.rect(p.x0, top, p.x1 - p.x0, p.skirtBot - top);\n      ctx.clip();\n      ctx.fillStyle = '#0e0f10';\n      ctx.beginPath(); ctx.arc(p.arch[0], p.arch[1], p.arch[2], 0, Math.PI * 2); ctx.fill();\n      ctx.restore();\n      // deck\n      ctx.fillStyle = p.alu ? PART.alu : PART.steel;\n      ctx.fillRect(p.x0, p.deck, p.x1 - p.x0, p.t);\n      hiLine(ctx, p.x0 + P1, p.deck + 0.35 * P1, p.x1 - P1, p.deck + 0.35 * P1, 0.35 * P1, p.alu ? PART.aluHi : PART.steelHi);\n      if (p.headache) {   // headache rack: posts from the deck to the cab roof, top bar\n        ctx.fillStyle = p.alu ? PART.alu : PART.steel;\n        ctx.fillRect(p.x0, p.cabRoof, 2.5 * P1, p.deck - p.cabRoof);\n        ctx.fillRect(p.x0, p.cabRoof, 6 * P1, 2 * P1);\n      }\n    },\n    tire: function (ctx, p) {\n      var P1 = p.P1;\n      var cx = p.cx;\n      var cy = p.cy;\n      ctx.fillStyle = PART.tread;\n      ctx.beginPath(); ctx.arc(cx, cy, p.r, 0, Math.PI * 2); ctx.fill();\n      // tread blocks round the edge\n      ctx.strokeStyle = '#262627';\n      ctx.lineWidth = 0.9 * P1;\n      ctx.setLineDash([1.6 * P1, 1.4 * P1]);\n      ctx.beginPath(); ctx.arc(cx, cy, p.r - 0.8 * P1, 0, Math.PI * 2); ctx.stroke();\n      ctx.setLineDash([]);\n      ctx.fillStyle = PART.sidewall;\n      ctx.beginPath(); ctx.arc(cx, cy, p.r - 2 * P1, 0, Math.PI * 2); ctx.fill();\n      // key light top-left on the shoulder\n      ctx.strokeStyle = '#3c3c3e';\n      ctx.lineWidth = 0.7 * P1;\n      ctx.beginPath(); ctx.arc(cx, cy, p.r - 2.6 * P1, Math.PI * 1.05, Math.PI * 1.45); ctx.stroke();\n      // wheel: rim, 6 spokes (dark windows between), hub\n      ctx.fillStyle = PART.rim;\n      ctx.beginPath(); ctx.arc(cx, cy, p.rim, 0, Math.PI * 2); ctx.fill();\n      ctx.fillStyle = PART.rimDark;\n      for (var i = 0; i < 6; i++) {\n        var a0 = i * Math.PI / 3 + 0.2;\n        var a1 = a0 + Math.PI / 3 - 0.4;\n        ctx.beginPath();\n        ctx.arc(cx, cy, p.rim * 0.82, a0, a1);\n        ctx.arc(cx, cy, p.rim * 0.38, a1 - 0.12, a0 + 0.12, true);\n        ctx.closePath();\n        ctx.fill();\n      }\n      ctx.strokeStyle = PART.rimHi;\n      ctx.lineWidth = 0.45 * P1;\n      ctx.beginPath(); ctx.arc(cx, cy, p.rim - 0.3 * P1, Math.PI * 1.0, Math.PI * 1.5); ctx.stroke();\n      ctx.fillStyle = '#2a2c30';\n      ctx.beginPath(); ctx.arc(cx, cy, p.rim * 0.26, 0, Math.PI * 2); ctx.fill();\n      ctx.fillStyle = PART.rimHi;\n      ctx.beginPath(); ctx.arc(cx, cy, p.rim * 0.1, 0, Math.PI * 2); ctx.fill();\n    }\n  };\n\n  /**\n   * Draw a planned scene: body picture (lifted), then parts in order, fitted\n   * so nothing leaves the 1600 x 800 frame. body: a canvas/image holding the\n   * (repainted) picture at any resolution with a 2:1 shape.\n   */\n  /** A part's photo cutout, scaled by its real width and set on the part's pin. */\n  function drawPicture(ctx, p, img, ppi) {\n    if (p.slices) {\n      var W = img.naturalWidth;\n      var H = img.naturalHeight;\n      var clipped = p.clipArc || p.clipX != null || p.clipUnder;\n      if (clipped) ctx.save();\n      if (p.clipUnder) {   // nothing below the cab roof line forward of the cab back (the slide-in's cabover)\n        ctx.beginPath();\n        ctx.rect(-1e4, -1e4, 3e4, 3e4);\n        ctx.rect(-1e4, p.clipUnder[1], p.clipUnder[0] + 1e4, 1e4);\n        ctx.clip('evenodd');\n      }\n      if (p.clipArc) {   // nothing inside the wheel opening (the winch bumper's wing)\n        ctx.beginPath();\n        ctx.rect(-1e4, -1e4, 3e4, 3e4);\n        ctx.arc(p.clipArc[0], p.clipArc[1], p.clipArc[2], 0, Math.PI * 2);\n        ctx.clip('evenodd');\n      }\n      if (p.clipX != null && p.type !== 'bumper_f') {   // nothing behind this x (the slide-in's rear wall)\n        ctx.beginPath();\n        ctx.rect(-1e4, -1e4, p.clipX + 1e4, 3e4);\n        ctx.clip();\n      }\n      p.slices.forEach(function (s) {\n        var d = s.dst;\n        if (!(d[2] > 0 && d[3] > 0)) return;\n        if (s.flip) {\n          ctx.save();\n          ctx.translate(d[0] + d[2], d[1]);\n          ctx.scale(-1, 1);\n          ctx.drawImage(img, s.src[0] * W, s.src[1] * H, s.src[2] * W, s.src[3] * H, 0, 0, d[2], d[3]);\n          ctx.restore();\n        } else {\n          ctx.drawImage(img, s.src[0] * W, s.src[1] * H, s.src[2] * W, s.src[3] * H, d[0], d[1], d[2], d[3]);\n        }\n      });\n      if (clipped) ctx.restore();\n      return;\n    }\n    if (p.clipX != null) {   // nothing behind this x (the winch bumper's wing stops at the wheel opening)\n      ctx.save();\n      ctx.beginPath();\n      ctx.rect(-1e5, -1e5, p.clipX + 1e5, 2e5);\n      ctx.clip();\n      drawPictureAt(ctx, p, img, ppi);\n      ctx.restore();\n      return;\n    }\n    drawPictureAt(ctx, p, img, ppi);\n  }\n  function drawPictureAt(ctx, p, img, ppi) {\n    var shape = img.naturalHeight / img.naturalWidth;\n    var w;\n    var h;\n    if (p.pic.scale === 'height') {          // sized by its height, width from its shape\n      h = p.picH || p.pic.height_in * ppi;\n      w = h / shape;\n    } else {\n      w = p.picW || p.pic.width_in * ppi;\n      h = p.picH || (p.pic.height_in > 0 ? p.pic.height_in * ppi : w * shape);   // spare: as tall as the tyre\n    }\n    var x = p.pin[0] - p.picAt[0] * w;\n    var y = p.pin[1] - p.picAt[1] * h;\n    if (p.pic.flip) {   // mirrored in its own box (the wedge camper's tall end goes at the back)\n      ctx.save();\n      ctx.translate(x + w, y);\n      ctx.scale(-1, 1);\n      ctx.drawImage(img, 0, 0, w, h);\n      ctx.restore();\n      return;\n    }\n    ctx.drawImage(img, x, y, w, h);\n  }\n\n  /**\n   * The flatbed picture measured from its alpha (Justin phone review 11/4:\n   * use MAHZ1QlMpyU as briefed). Fractions of the picture: deck = the first\n   * row at least 60% solid; bottom = the last solid row; the headache rack =\n   * the columns standing above the deck at one end (that end is the front:\n   * flip when it is on the right); the wheel arch = the widest run of empty\n   * columns in the skirt's bottom quarter that touches neither end.\n   * alpha(x, y) -> 0..255. Null when there is no deck.\n   */\n  function measureFlatbed(alpha, w, h) {\n    var rows = [];\n    var x;\n    var y;\n    for (y = 0; y < h; y++) {\n      var n = 0;\n      for (x = 0; x < w; x++) if (alpha(x, y) >= 128) n++;\n      rows.push(n);\n    }\n    var deck = -1;\n    var bottom = -1;\n    for (y = 0; y < h; y++) {\n      if (deck < 0 && rows[y] >= 0.6 * w) deck = y;\n      if (rows[y] > 0) bottom = y;\n    }\n    if (deck < 0 || bottom <= deck) return null;\n    var lim = deck - Math.max(2, Math.round(0.02 * h));\n    var above = [];\n    for (x = 0; x < w; x++) {\n      var hit = false;\n      for (y = 0; y < lim && !hit; y++) if (alpha(x, y) >= 128) hit = true;\n      above.push(hit);\n    }\n    var lm = 0;\n    var rm = 0;\n    for (x = 0; x < w; x++) if (above[x]) { if (x < 0.35 * w) lm++; else if (x >= 0.65 * w) rm++; }\n    var flip = rm > lm;\n    var col = function (i) { return flip ? w - 1 - i : i; };   // front-first column -> picture column\n    var rack = 0;\n    for (var i = 0; i < 0.45 * w; i++) if (above[col(i)]) rack = i + 1;\n    var b0 = Math.round(bottom - 0.25 * (bottom - deck));\n    var best = null;\n    var run = -1;\n    for (i = 0; i <= w; i++) {\n      var empty = i < w;\n      if (empty) for (y = b0; y <= bottom && empty; y++) if (alpha(col(i), y) >= 128) empty = false;\n      if (empty && run < 0) run = i;\n      if (!empty && run >= 0) {\n        if (run > 0 && i < w && i - run >= 0.06 * w && (!best || i - run > best[1] - best[0])) best = [run, i];\n        run = -1;\n      }\n    }\n    return { flip: flip, deck: deck / h, bottom: (bottom + 1) / h, rack: rack / w,\n      arch: best ? [best[0] / w, best[1] / w] : null, aspect: w / h };\n  }\n\n  /**\n   * The measured flatbed picture fitted to the plan: deck top on the deck\n   * line, skirt bottom on the skirt line (the scale), the headache rack at its\n   * own size at the cab back (on a camper only its deck and skirt), the arch\n   * over the rear wheel (the planned arch, tyre + 3 in), the deck before and\n   * after it stretched to fit, to the deck's end. Null when it can't fit.\n   */\n  function flatbedSlices(p, sh) {\n    var hf = (p.skirtBot - p.deck) / (sh.bottom - sh.deck);   // frame px per picture height\n    var wf = hf * sh.aspect;                                  // ... per picture width\n    var y0 = p.deck - sh.deck * hf;\n    var out = [];\n    var ok = true;\n    var add = function (u0, u1, dx, dw, v0) {\n      if (!(u1 > u0) || !(dw > 0.5)) { ok = false; return; }\n      out.push({ src: [sh.flip ? 1 - u1 : u0, v0, u1 - u0, sh.bottom - v0], dst: [dx, y0 + v0 * hf, dw, (sh.bottom - v0) * hf], flip: sh.flip });\n    };\n    var x = p.x0;\n    if (sh.rack > 0) {\n      add(0, sh.rack, x, sh.rack * wf, p.headache ? 0 : sh.deck);\n      x += sh.rack * wf;\n    }\n    var ax0 = p.arch[0] - p.arch[2];\n    var ax1 = p.arch[0] + p.arch[2];\n    if (sh.arch && ax0 > x + 1 && p.x1 > ax1 + 1) {\n      add(sh.rack, sh.arch[0], x, ax0 - x, 0);\n      add(sh.arch[0], sh.arch[1], ax0, ax1 - ax0, 0);\n      add(sh.arch[1], 1, ax1, p.x1 - ax1, 0);\n    } else {\n      add(sh.rack, 1, x, p.x1 - x, 0);\n    }\n    return ok ? out : null;\n  }\n\n  /**\n   * The slide-in picture's cabover underside (fraction of its height): over\n   * the nose (the columns ahead of nose_right), the median bottom of the\n   * first solid run from the top. Null when it can't be told.\n   */\n  function measureCabover(alpha, w, h, nr) {\n    var ends = [];\n    for (var x = Math.round(0.15 * nr * w); x < Math.round(0.75 * nr * w); x++) {\n      var y = 0;\n      while (y < h && alpha(x, y) < 128) y++;\n      if (y >= h) continue;\n      while (y < h && alpha(x, y) >= 128) y++;\n      ends.push(y / h);\n    }\n    if (ends.length < 3) return null;\n    ends.sort(function (m, n) { return m - n; });\n    return ends[Math.floor(ends.length / 2)];\n  }\n\n  /**\n   * On a flatbed (Justin phone review 2, 11/4): the camper is taller there\n   * than in a bed, so clipping the picture at the cab roof cut its whole\n   * cabover away. The nose slice is fitted instead: the picture from its top\n   * down to the cabover's underside, between the camper's top line and the\n   * cab roof (its underside on the cab roof), the box as planned.\n   */\n  function fitCabover(p, u) {\n    if (!(u > 0.05) || !p.clipUnder) return false;\n    var ns = (p.slices || []).filter(function (sl) { return Math.abs(sl.dst[0] - p.nose) < 0.5; })[0];\n    if (!ns || !(u < ns.src[1] + ns.src[3]) || !(p.clipUnder[1] > ns.dst[1] + 1)) return false;\n    ns.src = [ns.src[0], 0, ns.src[2], u];\n    ns.dst = [ns.dst[0], ns.dst[1], ns.dst[2], p.clipUnder[1] - ns.dst[1]];\n    return true;\n  }\n\n  // The slide-in camper is mid grey everywhere, in the bed and on the\n  // flatbed (owner decision, Justin's sweep round 1 item 8). The real\n  // picture's body is near-black, so its pixels are remapped (Justin, 11/4):\n  // the body's own brightness is rescaled so its median lands on\n  // SLIDEIN_GREY, light and dark kept relative to it; the windows, trim and\n  // lights (darker than the body, or coloured) are left as they are.\n  var SLIDEIN_GREY = '#8A8C8E';\n  var SLIDEIN_RGB = [0x8a, 0x8c, 0x8e];\n  var REMAP_CHROMA = 40;      // max - min channel at or above this: a coloured pixel (a light), kept\n  var REMAP_DARK = 0.6;       // below this share of the body median: window, trim or shadow, kept\n  var REMAP_BLEND = 0.8;      // from DARK to this share the remap fades in (no hard edge)\n  function luma(r, g, b) { return 0.2126 * r + 0.7152 * g + 0.0722 * b; }\n\n  /**\n   * Remap a camper picture's RGBA pixels in place to the grey: the body is\n   * the commonest brightness among the neutral (uncoloured) solid pixels;\n   * its median maps to rgb, everything as light or lighter scales with it\n   * (highlights roll off below white instead of clipping), everything well\n   * darker than the body and every coloured pixel is kept.\n   * -> { body, dark, n } (the body median luma, the keep-dark line, pixels changed) or null.\n   */\n  function remapGrey(d, rgb) {\n    var hist = [];\n    var i;\n    var total = 0;\n    for (i = 0; i < 256; i++) hist.push(0);\n    for (i = 0; i < d.length; i += 4) {\n      if (d[i + 3] < 128) continue;\n      var mx = Math.max(d[i], d[i + 1], d[i + 2]);\n      var mn = Math.min(d[i], d[i + 1], d[i + 2]);\n      if (mx - mn >= REMAP_CHROMA) continue;\n      hist[Math.round(luma(d[i], d[i + 1], d[i + 2]))]++;\n      total++;\n    }\n    if (total < 16) return null;\n    // the body: the brightness band (x0.8 .. x1.25 of its centre) holding the\n    // most pixels, then the median of the pixels around it\n    var cum = [0];\n    for (i = 0; i < 256; i++) cum.push(cum[i] + hist[i]);\n    var best = -1;\n    var mode = 0;\n    for (i = 1; i < 256; i++) {\n      var inBand = cum[Math.min(256, Math.floor(i * 1.25) + 1)] - cum[Math.ceil(i * 0.8)];\n      if (inBand > best) { best = inBand; mode = i; }\n    }\n    var lo = Math.max(0, Math.floor(mode * REMAP_DARK));\n    var hi = Math.min(255, Math.ceil(mode * 2.5 + 10));\n    var cnt = 0;\n    for (i = lo; i <= hi; i++) cnt += hist[i];\n    var half = cnt / 2;\n    var body = mode;\n    for (i = lo, cnt = 0; i <= hi; i++) { cnt += hist[i]; if (cnt >= half) { body = Math.max(1, i); break; } }\n    var dark = body * REMAP_DARK;\n    var full = body * REMAP_BLEND;\n    var n = 0;\n    for (i = 0; i < d.length; i += 4) {\n      if (d[i + 3] === 0) continue;\n      var r = d[i];\n      var g = d[i + 1];\n      var b = d[i + 2];\n      if (Math.max(r, g, b) - Math.min(r, g, b) >= REMAP_CHROMA) continue;   // a light: kept\n      var y = luma(r, g, b);\n      if (y < dark) continue;                                            // window, trim: kept\n      var t = y / body;                                                   // 1 = the body median\n      var w = y >= full ? 1 : (y - dark) / (full - dark);                 // fade in above the dark line\n      for (var c = 0; c < 3; c++) {\n        var v = t <= 1 ? rgb[c] * t : rgb[c] + (255 - rgb[c]) * (1 - Math.exp(-(t - 1) * rgb[c] / (255 - rgb[c])));\n        d[i + c] = Math.round(d[i + c] + (v - d[i + c]) * w);\n      }\n      n++;\n    }\n    return { body: body, dark: dark, n: n };\n  }\n\n  var remapPics = {};\n  /**\n   * A part picture remapped to a colour (remapGrey: its body's median to rgb,\n   * shading kept, windows / trim / lights kept): a canvas, made once per\n   * picture and colour, or null when the page can't read the picture (then\n   * the drawn part is used).\n   */\n  function remapPicture(img, rgb) {\n    var key = img.src + '|' + rgb.join(',');\n    if (!(key in remapPics)) {\n      remapPics[key] = null;\n      try {\n        var w = img.naturalWidth;\n        var h = img.naturalHeight;\n        var c = document.createElement('canvas');\n        c.width = w; c.height = h;\n        var g = c.getContext('2d', { willReadFrequently: true });\n        g.drawImage(img, 0, 0);\n        var px = g.getImageData(0, 0, w, h);    // throws if the CDN didn't allow it\n        if (remapGrey(px.data, rgb)) {\n          g.putImageData(px, 0, 0);\n          c.naturalWidth = w;\n          c.naturalHeight = h;\n          remapPics[key] = c;\n        }\n      } catch (err) {\n        if (root.console) root.console.warn('Build your rig: part picture not recoloured, drawn instead', err);\n      }\n    }\n    return remapPics[key];\n  }\n  /** The slide-in picture in its grey, or null: then the drawn slide-in. */\n  function greyPicture(img) { return remapPicture(img, SLIDEIN_RGB); }\n  /** '#rrggbb' -> [r, g, b] (null if it isn't one). */\n  function hexRgb(hex) {\n    var m = /^#?([0-9a-f]{6})$/i.exec(String(hex || ''));\n    if (!m) return null;\n    var v = parseInt(m[1], 16);\n    return [(v >> 16) & 255, (v >> 8) & 255, v & 255];\n  }\n\n  var flatShapes = {};\n  var caboverShapes = {};\n  function caboverShape(img, nr) {\n    img = img.raw || img;   // the outline as photographed\n    var key = img.src;\n    if (!(key in caboverShapes)) {\n      caboverShapes[key] = null;\n      try {\n        var w = img.naturalWidth;\n        var h = img.naturalHeight;\n        var c = document.createElement('canvas');\n        c.width = w; c.height = h;\n        var cx = c.getContext('2d', { willReadFrequently: true });\n        cx.drawImage(img, 0, 0);\n        var d = cx.getImageData(0, 0, w, h).data;\n        caboverShapes[key] = measureCabover(function (x, y) { return d[(y * w + x) * 4 + 3]; }, w, h, nr);\n      } catch (err) {\n        if (root.console) root.console.warn('Build your rig: slide-in cabover not measured', err);\n      }\n    }\n    return caboverShapes[key];\n  }\n\n  function flatbedShape(img) {\n    img = img.raw || img;   // the outline as photographed (openings cleared only for drawing)\n    var key = img.src;\n    if (!(key in flatShapes)) {\n      flatShapes[key] = null;   // a picture the page can't read (cross-origin) stays drawn\n      try {\n        var w = img.naturalWidth;\n        var h = img.naturalHeight;\n        var c = document.createElement('canvas');\n        c.width = w; c.height = h;\n        var cx = c.getContext('2d', { willReadFrequently: true });\n        cx.drawImage(img, 0, 0);\n        var d = cx.getImageData(0, 0, w, h).data;\n        flatShapes[key] = measureFlatbed(function (x, y) { return d[(y * w + x) * 4 + 3]; }, w, h);\n      } catch (err) {\n        if (root.console) root.console.warn('Build your rig: flatbed picture not measured, drawn instead', err);\n      }\n    }\n    return flatShapes[key];\n  }\n\n  // Openings in part pictures (Justin, #177 check 11/5): the cutouts keep the\n  // studio background inside closed gaps (between a bed rack's tubes, inside\n  // a bumper hoop), which showed as light boxes on the dark top section. On\n  // the parts with openings, a closed light, grey, even patch is made\n  // transparent, and its 2 px edge is un-mixed from the background so no\n  // light fringe is left. Patches that reach the picture's outline are\n  // surfaces, never touched; light or painted parts (caps, tents, campers)\n  // aren't in the list.\n  var OPENING_PARTS = ['bedrack', 'platform_rack', 'bumper_f', 'bumper_r_carrier', 'flatbed_alu', 'flatbed_steel'];\n  var OPEN_LIGHT = 170;     // a background pixel: at least this light (luma, 0-255) ...\n  var OPEN_CHROMA = 28;     // ... this grey (max - min channel) ...\n  var OPEN_SPREAD = 14;     // ... and its patch this even (luma standard deviation)\n  var OPEN_MIN_PX = 12;     // patches smaller than this stay (a highlight, a lens)\n  var openingFiles = {};\n  /** The picture files of the parts with openings (data.part_images: file, fit[], size classes). */\n  function noteOpenings(partImages) {\n    var walk = function (v) {\n      if (!v || typeof v !== 'object') return;\n      if (Array.isArray(v)) { v.forEach(walk); return; }\n      if (typeof v.file === 'string') openingFiles[v.file] = true;\n      Object.keys(v).forEach(function (k) { if (v[k] && typeof v[k] === 'object') walk(v[k]); });\n    };\n    OPENING_PARTS.forEach(function (k) { walk(partImages && partImages[k]); });\n  }\n  /**\n   * Clear the closed openings in RGBA pixels (in place). A patch (4-connected)\n   * of opaque light grey pixels that touches no see-through pixel and no edge\n   * of the picture, and is even enough, is the background showing through a\n   * gap: made transparent. Then the 2 px round it are un-mixed: a pixel part\n   * way between the part's dark colour and the background keeps only the\n   * part's share (alpha) in the part's colour. -> the number of pixels cleared.\n   */\n  function clearOpenings(d, w, h) {\n    var n = w * h;\n    var lum = new Float32Array(n);\n    var cand = new Uint8Array(n);\n    var i;\n    for (i = 0; i < n; i++) {\n      var r = d[i * 4];\n      var g = d[i * 4 + 1];\n      var b = d[i * 4 + 2];\n      lum[i] = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n      cand[i] = d[i * 4 + 3] >= 250 && lum[i] >= OPEN_LIGHT && Math.max(r, g, b) - Math.min(r, g, b) <= OPEN_CHROMA ? 1 : 0;\n    }\n    var seen = new Uint8Array(n);\n    var clear = new Uint8Array(n);\n    var stack = [];\n    var patch = [];\n    var cleared = 0;\n    var bgSum = 0;\n    for (var s0 = 0; s0 < n; s0++) {\n      if (!cand[s0] || seen[s0]) continue;\n      patch.length = 0;\n      stack.push(s0);\n      seen[s0] = 1;\n      var open = false;\n      var sum = 0;\n      var sq = 0;\n      while (stack.length) {\n        var k = stack.pop();\n        patch.push(k);\n        sum += lum[k]; sq += lum[k] * lum[k];\n        var x = k % w;\n        var y = (k - x) / w;\n        if (x === 0 || y === 0 || x === w - 1 || y === h - 1) open = true;\n        var nb = [x > 0 ? k - 1 : -1, x < w - 1 ? k + 1 : -1, y > 0 ? k - w : -1, y < h - 1 ? k + w : -1];\n        for (var j = 0; j < 4; j++) {\n          var q = nb[j];\n          if (q < 0) continue;\n          if (d[q * 4 + 3] < 250) open = true;\n          if (cand[q] && !seen[q]) { seen[q] = 1; stack.push(q); }\n        }\n      }\n      var m = sum / patch.length;\n      var sd = Math.sqrt(Math.max(0, sq / patch.length - m * m));\n      if (open || patch.length < OPEN_MIN_PX || sd > OPEN_SPREAD) continue;\n      patch.forEach(function (p) { clear[p] = 1; d[p * 4 + 3] = 0; });\n      cleared += patch.length;\n      bgSum += sum;\n    }\n    if (!cleared) return 0;\n    var bg = bgSum / cleared;\n    // the edge: up to 2 px from a cleared pixel, lighter than the part's dark\n    // colour; un-mixed c = a * f + (1 - a) * bg with f the darkest of its\n    // neighbours (the tube), so it keeps the tube's colour at its share\n    var ring = new Uint8Array(n);\n    for (var pass = 1; pass <= 2; pass++) {\n      for (i = 0; i < n; i++) {\n        if (clear[i] || ring[i] || d[i * 4 + 3] < 250) continue;\n        var xi = i % w;\n        var yi = (i - xi) / w;\n        var near = false;\n        for (var dy = -1; dy <= 1 && !near; dy++) {\n          for (var dx = -1; dx <= 1 && !near; dx++) {\n            var xx = xi + dx;\n            var yy = yi + dy;\n            if (xx < 0 || yy < 0 || xx >= w || yy >= h) continue;\n            var t = yy * w + xx;\n            if (clear[t] || (pass === 2 && ring[t] === 1)) near = true;\n          }\n        }\n        if (near) ring[i] = pass;\n      }\n    }\n    for (i = 0; i < n; i++) {\n      if (!ring[i]) continue;\n      // the part's colour here: the darkest opaque, uncleared pixel within 2 px\n      var xi2 = i % w;\n      var yi2 = (i - xi2) / w;\n      var f = -1;\n      for (var ey = -2; ey <= 2; ey++) {\n        for (var ex = -2; ex <= 2; ex++) {\n          var x2 = xi2 + ex;\n          var y2 = yi2 + ey;\n          if (x2 < 0 || y2 < 0 || x2 >= w || y2 >= h) continue;\n          var u = y2 * w + x2;\n          if (clear[u] || ring[u] || d[u * 4 + 3] < 250) continue;\n          if (f < 0 || lum[u] < lum[f]) f = u;\n        }\n      }\n      var fl = f >= 0 ? lum[f] : 25;\n      if (!(bg - fl > 20) || lum[i] <= fl) continue;\n      var a = Math.max(0, Math.min(1, (bg - lum[i]) / (bg - fl)));\n      if (f >= 0) { d[i * 4] = d[f * 4]; d[i * 4 + 1] = d[f * 4 + 1]; d[i * 4 + 2] = d[f * 4 + 2]; }\n      d[i * 4 + 3] = Math.round(a * 255);\n    }\n    return cleared;\n  }\n  /**\n   * A loaded part picture with its openings cleared: a canvas standing in for\n   * it (naturalWidth / naturalHeight / src kept, the raw picture on .raw for\n   * the outline measurements), or the picture itself when there is nothing to\n   * clear or its pixels can't be read.\n   */\n  function openedPicture(img) {\n    try {\n      var w = img.naturalWidth;\n      var h = img.naturalHeight;\n      var c = document.createElement('canvas');\n      c.width = w; c.height = h;\n      var g = c.getContext('2d', { willReadFrequently: true });\n      g.drawImage(img, 0, 0);\n      var px = g.getImageData(0, 0, w, h);\n      if (!clearOpenings(px.data, w, h)) return img;\n      g.putImageData(px, 0, 0);\n      c.naturalWidth = w;\n      c.naturalHeight = h;\n      c.src = img.src;\n      c.raw = img;\n      return c;\n    } catch (err) {\n      if (root.console) root.console.warn('Build your rig: part picture openings not cleared', err);\n      return img;\n    }\n  }\n\n  // Part pictures, loaded once per file; the scene redraws when one arrives.\n  var partPics = {};\n  function partPic(file, onload) {\n    var e = partPics[file];\n    if (!e) {\n      e = partPics[file] = { img: new Image(), ok: false, waiters: [] };\n      e.img.crossOrigin = 'anonymous';\n      e.img.decoding = 'async';\n      e.img.onload = function () {\n        if (openingFiles[file]) e.img = openedPicture(e.img);   // gaps see-through (the dark top section)\n        e.ok = true;\n        e.waiters.splice(0).forEach(function (f) { f(); });\n      };\n      e.img.onerror = function () { e.failed = true; e.waiters.splice(0).forEach(function (f) { f(); }); };   // the drawn part is used\n      e.img.src = IMAGE_BASE + file;\n    }\n    if (e.ok) return e.img;\n    if (onload && e.waiters.indexOf(onload) < 0) e.waiters.push(onload);\n    return null;\n  }\n\n  /** Has a part picture loaded or failed? If not, onload runs when it does. */\n  function partPicSettled(file, onload) {\n    partPic(file, onload);\n    var e = partPics[file];\n    return e.ok || !!e.failed;\n  }\n\n  /**\n   * The rocker's bottom (frame px, the left-facing frame): over the span\n   * between the wheel openings (a pickup's up to the cab back), the lowest\n   * painted row of the paint mask near the hub line, the median of 24\n   * columns. Null when it can't be told. mask: RGBA of the mask at w x w/2.\n   */\n  function measureRocker(mask, w, a) {\n    var s = w / 1600;\n    var x0 = a.fwc[0] + 1.2 * a.fwc[2];\n    var x1 = a.rwc[0] - 1.2 * a.rwc[2];\n    if (a.pickup && a.pickup.cab_back_x != null) x1 = Math.min(x1, a.pickup.cab_back_x);\n    if (!mask || x1 - x0 < 20) return null;\n    var hub = Math.min(a.fwc[1], a.rwc[1]);\n    var r = Math.min(a.fwc[2], a.rwc[2]);\n    var y0 = Math.max(0, Math.round((hub - 1.6 * r) * s));\n    var y1 = Math.min(Math.round(w / 2), Math.round(Math.min(a.ground, hub + 0.6 * r) * s));\n    var ys = [];\n    for (var k = 0; k < 24; k++) {\n      var fx = x0 + (x1 - x0) * (k + 0.5) / 24;\n      var px = Math.round((a.facing === 'right' ? 1599 - fx : fx) * s);\n      var last = -1;\n      for (var y = y0; y < y1; y++) if (mask[(y * w + px) * 4] > MASK_ON) last = y;\n      if (last >= 0) ys.push(last / s);\n    }\n    if (ys.length < 6) return null;\n    ys.sort(function (m, n) { return m - n; });\n    return ys[Math.floor(ys.length / 2)];\n  }\n\n  /**\n   * The stock rear bumper of an SUV / van, from the rig picture's own\n   * silhouette (Justin's sweep 11/4: rear.json's tailgate numbers put the\n   * box in the air or at taillight height on SUVs). alpha(px, py) -> 0..255\n   * in a w-wide picture; a: anchors (left-facing 1600 frame); ppi: frame px\n   * per inch. Rows in the lower 40% of the silhouette (on a rig with a\n   * rear-door spare, only from 2 in over the rear wheel top down, under the\n   * spare), each row's rear-most solid pixel behind the rear tyre: the\n   * bumper face is the rear-most line at least 3 in of rows reach; the\n   * bumper block is the tallest run of rows within 1.5 in of it.\n   * -> { face, top, bottom } (frame px) or null.\n   */\n  function measureRearBumper(alpha, w, a, ppi, hasSpare) {\n    var s = w / 1600;\n    var right = a.facing === 'right';\n    var G0 = a.ground;\n    var H = G0 - a.roof_top_y;\n    if (!(H > 0) || !(ppi > 0)) return null;\n    var yTop = G0 - 0.4 * H;\n    if (hasSpare) yTop = Math.max(yTop, a.rwc[1] - a.rwc[2] - 2 * ppi);\n    var yBot = G0 - 2 * ppi;\n    var xt = a.rwc[0] + a.rwc[2] + ppi;   // behind the rear tyre\n    var py0 = Math.max(0, Math.round(yTop * s));\n    var py1 = Math.min(Math.round(w / 2) - 1, Math.round(yBot * s));\n    var pxT = Math.round((right ? 1599 - xt : xt) * s);\n    var rows = [];\n    for (var py = py0; py <= py1; py++) {\n      var rx = null;\n      var px;\n      if (!right) {\n        for (px = w - 1; px > pxT; px--) if (alpha(px, py) >= 128) { rx = px / s; break; }\n      } else {\n        for (px = 0; px < pxT; px++) if (alpha(px, py) >= 128) { rx = 1599 - px / s; break; }\n      }\n      rows.push({ y: py / s, rx: rx });\n    }\n    var xs = rows.filter(function (q) { return q.rx != null; }).map(function (q) { return q.rx; });\n    var k = Math.max(2, Math.round(3 * ppi * s));\n    if (xs.length < k) return null;\n    xs.sort(function (m, n) { return n - m; });\n    var face = xs[k - 1];\n    if (face < a.tail - 15 * ppi || face > a.tail + 3 * ppi) return null;\n    var near = face - 1.5 * ppi;\n    var gapMax = Math.max(1, Math.round(0.5 * ppi * s));\n    var best = null;\n    var cur = null;\n    var gap = 0;\n    rows.forEach(function (q) {\n      if (q.rx != null && q.rx >= near) {\n        if (cur && gap <= gapMax) cur.b = q.y;\n        else cur = { t: q.y, b: q.y };\n        gap = 0;\n        if (!best || cur.b - cur.t > best.b - best.t) best = { t: cur.t, b: cur.b };\n      } else if (cur) {\n        gap++;\n        if (gap > gapMax) cur = null;\n      }\n    });\n    if (!best || best.b - best.t < 3 * ppi || best.b - best.t > 24 * ppi) return null;\n    return { face: face, top: best.t, bottom: best.b };\n  }\n\n  /**\n   * The cab roof's highest line from the silhouette (Justin's sweep 11/4:\n   * the ladder rack's over-cab rail), between the windshield header and the\n   * cab back: the second-highest of 24 column tops (one stray pixel, an\n   * antenna, doesn't count). -> y (frame px) or null.\n   */\n  function measureCabRoof(alpha, w, a) {\n    if (!a.pickup || a.header_x == null || a.pickup.cab_back_x == null) return null;\n    var s = w / 1600;\n    var x0 = a.header_x + 0.05 * (a.pickup.cab_back_x - a.header_x);\n    var x1 = Math.min(a.pickup.cab_back_x, a.roof_rear_x != null ? a.roof_rear_x : a.pickup.cab_back_x) - 0.03 * (a.pickup.cab_back_x - a.header_x);\n    if (x1 - x0 < 20) return null;\n    var yEnd = Math.round((a.pickup.rail_y != null ? a.pickup.rail_y : a.ground) * s);\n    var tops = [];\n    for (var k = 0; k < 24; k++) {\n      var fx = x0 + (x1 - x0) * (k + 0.5) / 24;\n      var px = Math.round((a.facing === 'right' ? 1599 - fx : fx) * s);\n      for (var py = 0; py < yEnd; py++) if (alpha(px, py) >= 128) { tops.push(py / s); break; }\n    }\n    if (tops.length < 12) return null;\n    tops.sort(function (m, n) { return m - n; });\n    return tops[1];\n  }\n\n  /**\n   * A stand-in 2D context that draws nothing and keeps the box of everything\n   * that would be painted (fills, strokes, rectangles, pictures), in the\n   * coordinates of the transform it starts with. Clips and clears are not\n   * counted. Paths count their points and curve control points (a curve stays\n   * inside them), arcs their whole circle: the box can only be a touch big.\n   */\n  function BoundsCtx() {\n    this.box = null;\n    this.m = [1, 0, 0, 1, 0, 0];\n    this.stack = [];\n    this.path = [];\n    this.lineWidth = 1;\n  }\n  BoundsCtx.prototype = {\n    pt: function (x, y) {\n      var m = this.m;\n      return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];\n    },\n    add: function (q, pad) {\n      var b = this.box || (this.box = [Infinity, Infinity, -Infinity, -Infinity]);\n      pad = pad || 0;\n      if (!isFinite(q[0]) || !isFinite(q[1])) return;\n      b[0] = Math.min(b[0], q[0] - pad); b[1] = Math.min(b[1], q[1] - pad);\n      b[2] = Math.max(b[2], q[0] + pad); b[3] = Math.max(b[3], q[1] + pad);\n    },\n    quad: function (x, y, w, h, pad) {\n      this.add(this.pt(x, y), pad); this.add(this.pt(x + w, y), pad);\n      this.add(this.pt(x, y + h), pad); this.add(this.pt(x + w, y + h), pad);\n    },\n    save: function () { this.stack.push({ m: this.m.slice(), lineWidth: this.lineWidth }); },\n    restore: function () { var s = this.stack.pop(); if (s) { this.m = s.m; this.lineWidth = s.lineWidth; } },\n    setTransform: function (a, b, c, d, e, f) { this.m = [a, b, c, d, e, f]; },\n    transform: function (a, b, c, d, e, f) {\n      var m = this.m;\n      this.m = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d,\n        m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]];\n    },\n    translate: function (x, y) { this.transform(1, 0, 0, 1, x, y); },\n    scale: function (x, y) { this.transform(x, 0, 0, y, 0, 0); },\n    beginPath: function () { this.path = []; },\n    closePath: function () {},\n    moveTo: function (x, y) { this.path.push(this.pt(x, y)); },\n    lineTo: function (x, y) { this.path.push(this.pt(x, y)); },\n    quadraticCurveTo: function (cx, cy, x, y) { this.path.push(this.pt(cx, cy), this.pt(x, y)); },\n    bezierCurveTo: function (c1x, c1y, c2x, c2y, x, y) { this.path.push(this.pt(c1x, c1y), this.pt(c2x, c2y), this.pt(x, y)); },\n    arc: function (x, y, r) {\n      this.path.push(this.pt(x - r, y - r), this.pt(x + r, y - r), this.pt(x - r, y + r), this.pt(x + r, y + r));\n    },\n    rect: function (x, y, w, h) {\n      this.path.push(this.pt(x, y), this.pt(x + w, y), this.pt(x, y + h), this.pt(x + w, y + h));\n    },\n    fill: function () { var self = this; this.path.forEach(function (q) { self.add(q); }); },\n    stroke: function () {\n      var self = this;\n      var pad = this.lineWidth / 2 * Math.sqrt(Math.abs(this.m[0] * this.m[3] - this.m[1] * this.m[2]));\n      this.path.forEach(function (q) { self.add(q, pad); });\n    },\n    clip: function () { this.path = []; },\n    fillRect: function (x, y, w, h) { this.quad(x, y, w, h); },\n    strokeRect: function (x, y, w, h) {\n      this.quad(x, y, w, h, this.lineWidth / 2 * Math.sqrt(Math.abs(this.m[0] * this.m[3] - this.m[1] * this.m[2])));\n    },\n    clearRect: function () {},\n    drawImage: function (img, a, b, c, d, e, f, g, h) {\n      if (arguments.length >= 9) this.quad(e, f, g, h);\n      else if (arguments.length >= 5) this.quad(a, b, c, d);\n      else this.quad(a, b, img.naturalWidth || img.width || 0, img.naturalHeight || img.height || 0);\n    },\n    createLinearGradient: function () { return { addColorStop: function () {} }; },\n    setLineDash: function () {}\n  };\n\n  /**\n   * The parts of a plan drawn in the left-facing frame (ctx already set to\n   * it). measure: the bounds pass (BoundsCtx), which skips the erases and the\n   * rig's own wheel (both inside the body).\n   */\n  function drawParts(ctx, plan, getPic, body, mirror, measure) {\n    var W = 1600;\n    var H = 800;\n    if (!measure) {\n      plan.parts.forEach(function (p) {\n        (p.erases || (p.erase ? [p.erase] : [])).forEach(function (e) {\n          if (p.eraseHole) {   // clear the rectangle but keep the wheel inside it\n            ctx.save();\n            ctx.beginPath();\n            ctx.rect(e[0], e[1], e[2] - e[0], e[3] - e[1]);\n            ctx.arc(p.eraseHole[0], p.eraseHole[1], p.eraseHole[2], 0, Math.PI * 2);\n            ctx.clip('evenodd');\n            ctx.clearRect(e[0], e[1], e[2] - e[0], e[3] - e[1]);\n            ctx.restore();\n          } else {\n            ctx.clearRect(e[0], e[1], e[2] - e[0], e[3] - e[1]);\n          }\n        });\n      });\n    }\n    plan.parts.forEach(function (p) {\n      if (p.type === 'wheel_copy') {   // the rig's own wheel again, over the flatbed skirt\n        if (measure) return;\n        ctx.save();\n        ctx.beginPath();\n        ctx.arc(p.cx, p.cy, p.r, 0, Math.PI * 2);\n        ctx.clip();\n        if (mirror) ctx.transform(-1, 0, 0, 1, W, 0);\n        ctx.drawImage(body, 0, -plan.rise, W, H);\n        ctx.restore();\n        return;\n      }\n      var img = p.pic && getPic ? getPic(p.pic.file) : null;\n      if (img && p.noseFit && !p.noseFitted && p.pic && typeof p.pic.nose_right === 'number') {\n        p.noseFitted = fitCabover(p, caboverShape(img, p.pic.nose_right));\n      }\n      if (img && p.autoShape) {\n        if (!p.slices) {\n          var fsh = flatbedShape(img);\n          p.slices = fsh ? flatbedSlices(p, fsh) : null;\n        }\n        if (!p.slices) img = null;   // not measurable: the drawn flatbed\n        else if (p.alu) img = remapPicture(img, hexRgb(PART.alu));   // bare aluminum (Justin's sweep 2); null: drawn\n        if (img) {\n          // the arch is a dark wheel well, never the background (owner 11/3):\n          // dark behind the picture's arch, under the deck; the tyre goes over it\n          ctx.fillStyle = '#0e0f10';\n          ctx.fillRect(p.arch[0] - p.arch[2], p.deck + p.t, 2 * p.arch[2], p.skirtBot - p.deck - p.t);\n        }\n      }\n      if (p.clipY != null) {   // only what's above this line shows (the slide-in behind the bed sides)\n        ctx.save();\n        ctx.beginPath();\n        ctx.rect(-1e5, -1e5, 2e5, p.clipY + 1e5);\n        ctx.clip();\n      }\n      if (img && p.type === 'slidein') img = greyPicture(img);   // mid grey (owner, sweep item 8); null: the drawn one\n      if (p.type === 'cap' && !p.alu) {\n        // a fiberglass cap is body colour (Justin's sweep 11/4): the picked\n        // paint, shaded like the body; the aluminum cap stays grey\n        p.paint = plan.paint || null;\n        var prgb = hexRgb(p.paint);\n        if (img && prgb) img = remapPicture(img, prgb);\n      }\n      if (img) drawPicture(ctx, p, img, plan.ppi);\n      else if (DRAW[p.type]) DRAW[p.type](ctx, p);\n      if (p.clipY != null) ctx.restore();\n    });\n  }\n\n  /** Margin kept clear on every side of the picture box (frame px, of 1600 x 800). */\n  var FIT_MARGIN = 16;\n\n  /**\n   * The fit of a scene in the 1600 x 800 frame (Justin 11/4: framed on the\n   * stock rig, added parts ran off the edge): box = what is drawn, the body's\n   * outline and every part as it is really drawn (its loaded picture, the\n   * fitted cabover and flatbed). Scaled about the ground line (never up),\n   * so the whole box fits inside the margin, then moved sideways only as far\n   * as it must. -> { g, dx }: x' = cx + g (x - cx) + dx, y' = G + g (y - G).\n   */\n  function fitScene(box, G, margin) {\n    var W = 1600;\n    var H = 800;\n    var cx = W / 2;\n    var m = margin == null ? FIT_MARGIN : margin;\n    var g = 1;\n    if (box[2] - box[0] > 0) g = Math.min(g, (W - 2 * m) / (box[2] - box[0]));\n    if (G - box[1] > 0) g = Math.min(g, (G - m) / (G - box[1]));\n    if (box[3] - G > 0) g = Math.min(g, (H - m - G) / (box[3] - G));\n    var left = cx + g * (box[0] - cx);\n    var right = cx + g * (box[2] - cx);\n    var dx = 0;\n    if (left < m) dx = m - left;\n    else if (right > W - m) dx = W - m - right;\n    return { g: g, dx: dx };\n  }\n\n  /** The box of everything a plan draws (frame px): the body's outline and the parts as drawn. */\n  function sceneBox(plan, getPic) {\n    var b = plan.body || plan.bounds;\n    var rec = new BoundsCtx();\n    drawParts(rec, plan, getPic, null, false, true);\n    var box = [b[0], b[1], b[2], b[3]];\n    if (rec.box) {\n      box[0] = Math.min(box[0], rec.box[0]); box[1] = Math.min(box[1], rec.box[1]);\n      box[2] = Math.max(box[2], rec.box[2]); box[3] = Math.max(box[3], rec.box[3]);\n    }\n    plan.parts.forEach(function (p) {   // the plow blade gets 2 in of room beyond the margin\n      if (p.type === 'plow') box[0] = Math.min(box[0], p.x0 - 3 * p.P1 - PLOW_ROOM_IN * plan.ppi);\n    });\n    return box;\n  }\n\n  // The small desktop picture's fixed frame (owner 11/11, coder_brief_byr_mini_picture_width.md):\n  // every setup of add-ons a rig can carry, at the most each can reach, the\n  // page's own rules applied (one a group, a camper or flatbed takes the bed).\n  var MAX_BASE_GEAR = ['bumper_f', 'winch_steel', 'bumper_r_carrier', 'skids_steel', 'sliders', 'spare', 'lightbar',\n    'awning270', 'fridge', 'toolbox', 'sideboxes', 'drawers_8ft'];\n  var MAX_RACKS = [[], ['bedrack'], ['platform_rack'], ['ladderrack'], ['bedrack', 'platform_rack'], ['ladderrack', 'platform_rack']];\n  var MAX_TENTS = [null, 'rtt_soft', 'rtt_hard', 'rtt_large'];\n  var MAX_BEDS = [null, 'cap_fiber', 'cap_alu', 'popup_topper', 'slide_in_camper', 'flatbed_alu', 'flatbed_steel'];\n  var MAX_PLOWS = ['plow_half', 'plow_hd'];\n\n  /** A gear list as the page would leave it on this row (gearFits, the bed rules of capGear / bedExclusive). */\n  function cleanMaxGear(row, gear) {\n    gear = gear.filter(function (id) { return id && gearFits(row, id); });\n    var pickup = row.body_type === 'pickup';\n    if (pickup && gear.some(function (id) { return id === 'popup_topper' || id === 'slide_in_camper'; })) {\n      gear = gear.filter(function (id) { return ['bedrack', 'rtt_soft', 'rtt_hard', 'rtt_large'].indexOf(id) < 0; });\n    }\n    if (pickup && has(gear, 'ladderrack')) gear = gear.filter(function (id) { return id !== 'bedrack'; });\n    if (bedCovered(gear)) gear = gear.filter(function (id) { return BED_RAIL_GEAR.indexOf(id) < 0; });\n    return gear;\n  }\n\n  /**\n   * The boxes (frame px) of a rig with every add-on it can carry: the union\n   * of sceneBox over each rack x tent x bed setup on its stock tyres and the\n   * biggest it takes, each bed on every size, with the bumpers, winch,\n   * swing-out and the rest -> base; and that with each plow on every size too\n   * -> plow (owner 11/11, option C: the plow reaches far ahead of the bumper,\n   * so the small picture keeps room for it only while one is ticked). Parts\n   * are measured as drawn (no part pictures), so the boxes never depend on\n   * what has loaded. Fixed for a row and its anchors. -> { base, plow }\n   */\n  function maxSceneBoxes(row, a, pics) {\n    var tires = [null].concat(['tires33', 'tires35', 'tires37', 'tires40'].filter(function (id) { return gearFits(row, id); }));\n    var seen = {};\n    var partBoxes = {};   // a part's own box, by its geometry: the same tyre is measured once\n    var box = null;\n    var noPic = function () { return null; };\n    var grow = function (b) {\n      if (!box) box = b.slice();\n      else { box[0] = Math.min(box[0], b[0]); box[1] = Math.min(box[1], b[1]); box[2] = Math.max(box[2], b[2]); box[3] = Math.max(box[3], b[3]); }\n    };\n    // a box is the union of its parts' own boxes, so the plow's setups only\n    // add to the base box: the base first, then the plows on top of a copy\n    var add = function (gear) {\n      gear = cleanMaxGear(row, gear);\n      var key = gear.slice().sort().join(',');\n      if (seen[key]) return;\n      seen[key] = true;\n      var plan = planScene(row, a, gear, pics);\n      // sceneBox(plan), a part at a time (parts are measured on their own:\n      // no pictures, clips not counted)\n      grow(plan.body || plan.bounds);\n      plan.parts.forEach(function (p) {\n        var k = plan.ppi + JSON.stringify(p);\n        if (!partBoxes[k]) partBoxes[k] = sceneBox(Object.assign({}, plan, { parts: [p] }), noPic);\n        grow(partBoxes[k]);\n      });\n    };\n    // every rack x tent x bed on the stock tyres and the biggest (they reach\n    // highest); each bed and plow on every size (a flatbed's skirt sits lowest\n    // on some size between)\n    tires.forEach(function (t, i) {\n      var base = MAX_BASE_GEAR.concat(t ? [t] : []);\n      var all = i === 0 || i === tires.length - 1;\n      (all ? MAX_RACKS : [[]]).forEach(function (racks) {\n        (all ? MAX_TENTS : [null]).forEach(function (tent) {\n          MAX_BEDS.forEach(function (bed) { add(base.concat(racks, [tent, bed])); });\n        });\n      });\n    });\n    var baseBox = box.slice();\n    tires.forEach(function (t) {\n      var base = MAX_BASE_GEAR.concat(t ? [t] : []);\n      MAX_PLOWS.forEach(function (plow) { add(base.concat([plow])); });\n    });\n    return { base: baseBox, plow: box };\n  }\n\n  /** The rig's box with everything it can carry, the plow included (maxSceneBoxes().plow). */\n  function maxSceneBox(row, a, pics) {\n    return maxSceneBoxes(row, a, pics).plow;\n  }\n\n  /** Whether a gear list has a plow on (the small picture then uses its with-plow window). */\n  function hasPlow(gear) {\n    return MAX_PLOWS.some(function (id) { return has(gear, id); });\n  }\n\n  /**\n   * The small picture's window on the scene (frame px, before the big\n   * picture's fit): the box, MINI_PAD css px clear of each edge at the zoom\n   * that fills a cw x ch frame (css px), centred. -> { x, y, w, h, z } (z: css\n   * px per frame px).\n   */\n  var MINI_PAD = 6;\n  function miniView(box, cw, ch) {\n    var bw = Math.max(1, box[2] - box[0]);\n    var bh = Math.max(1, box[3] - box[1]);\n    var z = Math.min((cw - 2 * MINI_PAD) / bw, (ch - 2 * MINI_PAD) / bh);\n    var w = cw / z;\n    var h = ch / z;\n    return { x: (box[0] + box[2]) / 2 - w / 2, y: (box[1] + box[3]) / 2 - h / 2, w: w, h: h, z: z };\n  }\n\n  /**\n   * Draw a planned scene: body picture (lifted), then parts in order, fitted\n   * (fitScene) so nothing comes within the margin of the 1600 x 800 frame's\n   * edge. body: a canvas/image holding the (repainted) picture at any\n   * resolution with a 2:1 shape. getPic(file) returns a loaded picture or\n   * null (then the drawn part is used). -> the fit { g, dx, box }.\n   */\n  function drawScene(ctx, canvasW, body, plan, getPic) {\n    var W = 1600;\n    var H = 800;\n    var k = canvasW / W;\n    var G = plan.bounds[3];\n    var cx = W / 2;\n    var box = sceneBox(plan, getPic);\n    var fit = fitScene(box, G);\n    var g = fit.g;\n    var tx = cx * (1 - g) + fit.dx;\n    // Every rig faces left on the page (Justin phone review 11/4): a\n    // right-facing picture (anchors facing: right; its anchors are already in\n    // the left-facing frame) is drawn mirrored, its paint with it, and the\n    // parts go on in the plain frame.\n    var mirror = plan.facing === 'right';\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.clearRect(0, 0, canvasW, canvasW / 2);\n    // body: lifted; a right-facing picture mirrored (column i lands on W - 1 - i, as the anchors)\n    ctx.setTransform(k * g, 0, 0, k * g, k * tx, k * (G * (1 - g) - g * plan.rise));\n    if (mirror) ctx.transform(-1, 0, 0, 1, W, 0);\n    ctx.drawImage(body, 0, 0, W, H);\n    // parts: the left-facing frame\n    ctx.setTransform(k * g, 0, 0, k * g, k * tx, k * G * (1 - g));\n    drawParts(ctx, plan, getPic, body, mirror, false);\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    return { g: g, dx: fit.dx, box: box };\n  }\n\n  // --------------------------------------------------------------------- UI\n\n  function fmt(n) {\n    return Number(n).toLocaleString('en-US', { maximumFractionDigits: 1 });\n  }\n\n  function el(tag, attrs, kids) {\n    var e = document.createElement(tag);\n    Object.keys(attrs || {}).forEach(function (k) {\n      var v = attrs[k];\n      if (v == null || v === false) return;\n      if (k === 'text') e.textContent = v;\n      else if (k === 'class') e.className = v;\n      else if (k.slice(0, 2) === 'on') e.addEventListener(k.slice(2), v);\n      else e.setAttribute(k, v === true ? '' : v);\n    });\n    (kids || []).forEach(function (c) { if (c != null) e.appendChild(typeof c === 'string' ? document.createTextNode(c) : c); });\n    return e;\n  }\n\n  var uid = 0;\n\n  function select(label, onChange) {\n    var id = 'byr-sel-' + (++uid);\n    var s = el('select', { id: id, class: 'byr-select', onchange: onChange, disabled: true });\n    var wrap = el('div', { class: 'byr-field' }, [el('label', { for: id, text: label }), s]);\n    return { wrap: wrap, el: s };\n  }\n\n  function fill(sel, placeholder, options) {\n    sel.innerHTML = '';\n    sel.appendChild(el('option', { value: '', text: placeholder }));\n    options.forEach(function (o) { sel.appendChild(el('option', { value: o.value, text: o.label })); });\n    sel.disabled = options.length === 0;\n    if (options.length === 1) sel.value = options[0].value;\n  }\n\n  function numberField(label, name, min, max, value, hint) {\n    var id = 'byr-' + name + '-' + (++uid);\n    var input = el('input', {\n      id: id, type: 'number', inputmode: 'decimal', name: name,\n      min: min, max: max, step: 1, value: value, class: 'byr-number'\n    });\n    var kids = [el('label', { for: id, text: label }), input];\n    if (hint) kids.push(el('span', { class: 'byr-hint', text: hint }));\n    return { wrap: el('div', { class: 'byr-field byr-field--num' }, kids), el: input };\n  }\n\n  /**\n   * A minus / plus counter (new look, owner approved 11/5): 44 px buttons,\n   * the value between them. o: { name, label, hint, min, max (null: none),\n   * step, value, unit, less, more (button labels), onChange }. The value is\n   * kept in range here; compute() still cleans it.\n   */\n  function stepper(o) {\n    var id = 'byr-' + o.name + '-' + (++uid);\n    var st = { value: o.value };\n    var out = el('output', { class: 'byr-count', 'aria-live': 'polite' });\n    var minus = el('button', { type: 'button', class: 'byr-pm byr-pm--less', 'aria-label': o.less, text: '\\u2212' });\n    var plus = el('button', { type: 'button', class: 'byr-pm byr-pm--more', 'aria-label': o.more, text: '+' });\n    st.set = function (v) {\n      v = Math.max(o.min, o.max == null ? v : Math.min(o.max, v));\n      st.value = v;\n      out.textContent = fmt(v) + (o.unit ? ' ' + o.unit : '');\n      // aria-disabled, not disabled: the button keeps keyboard focus at the end of the range\n      minus.setAttribute('aria-disabled', v <= o.min ? 'true' : 'false');\n      plus.setAttribute('aria-disabled', o.max != null && v >= o.max ? 'true' : 'false');\n    };\n    var bump = function (d) {\n      var before = st.value;\n      st.set(st.value + d);\n      if (st.value !== before) o.onChange();\n    };\n    minus.addEventListener('click', function () { bump(-o.step); });\n    plus.addEventListener('click', function () { bump(o.step); });\n    st.set(o.value);\n    st.wrap = el('div', { class: 'byr-counter', role: 'group', 'aria-labelledby': id }, [\n      el('span', { class: 'byr-counter-label', id: id, text: o.label }),\n      el('span', { class: 'byr-hint', text: o.hint }),\n      el('div', { class: 'byr-counter-ctl' }, [minus, out, plus])\n    ]);\n    return st;\n  }\n\n  // Gear chips in three groups (new look, owner approved 11/5). Every item in\n  // the data shows: one the list doesn't name goes in the last group.\n  var GEAR_SECTIONS = [\n    { title: 'Armor and recovery', ids: ['winch_syn', 'winch_steel', 'bumper_f_stubby', 'bumper_f', 'bumper_r', 'bumper_r_carrier', 'spare',\n      'sliders', 'skids_alu', 'skids_steel', 'tires33', 'tires35', 'tires37', 'tires40', 'lightbar'] },\n    { title: 'Roof and bed', ids: ['rtt_soft', 'rtt_hard', 'rtt_large', 'platform_rack', 'bedrack',\n      'awning', 'awning270', 'cap_fiber', 'cap_alu', 'popup_topper', 'slide_in_camper', 'flatbed_alu', 'flatbed_steel',\n      'drawers_mid', 'drawers_full', 'drawers_8ft'] },\n    { title: 'Camp and work', ids: ['fridge', 'toilet', 'toolbox', 'sideboxes', 'ladderrack', 'plow_half', 'plow_hd'] }\n  ];\n  /** The gear list in its chip groups: [{ title, items }], each data item exactly once. */\n  function gearSections(gear) {\n    var byId = {};\n    gear.forEach(function (g) { byId[g.id] = g; });\n    var used = {};\n    var out = GEAR_SECTIONS.map(function (s) {\n      return { title: s.title, items: s.ids.filter(function (id) { return byId[id] && !used[id]; }).map(function (id) { used[id] = true; return byId[id]; }) };\n    });\n    gear.forEach(function (g) { if (!used[g.id]) { used[g.id] = true; out[out.length - 1].items.push(g); } });\n    return out;\n  }\n\n  // A chip is picked when aria-pressed is \"true\".\n  function isOn(c) { return c.getAttribute('aria-pressed') === 'true'; }\n  function setOn(c, on) { c.setAttribute('aria-pressed', on ? 'true' : 'false'); }\n\n  // The result's rope-band bar labels (owner approved 11/5)\n  var BAND_LABELS = { '1.25\"': '1-1/4\"' };\n  /** The bands under Heavy Duty by the sizing lines: [{ rope, from, to }] (lb, both ends sized to that rope). */\n  function ropeBands(data) {\n    var out = [];\n    var from = 0;\n    data.ropes.forEach(function (r) {\n      if (r.rec_max_lb == null) return;\n      out.push({ rope: r, from: from, to: r.rec_max_lb });\n      from = r.rec_max_lb + 1;\n    });\n    return out;\n  }\n  /**\n   * The line under the band bar: the band's range (the weights pickRope sizes\n   * to it) and how much more steps up to the next size; no step-up sentence\n   * at the top band; Heavy Duty: HEAVY_LINE.\n   */\n  function bandLine(data, rope, weight) {\n    if (!rope || rope.rec_max_lb == null) return HEAVY_LINE;\n    var bands = ropeBands(data);\n    var i = -1;\n    bands.forEach(function (b, j) { if (b.rope.size === rope.size) i = j; });\n    if (i < 0) return '';\n    var b = bands[i];\n    var range = b.from > 0 ? fmt(b.from) + '\\u2013' + fmt(b.to) + ' lb' : 'up to ' + fmt(b.to) + ' lb';\n    var line = 'Right in the ' + rope.size + ' range (' + range + ').';\n    if (i < bands.length - 1) {\n      var more = Math.max(1, Math.ceil(b.to + 1 - weight));\n      line += ' Add ' + fmt(more) + ' lb more and you step up to ' + bands[i + 1].rope.size + '.';\n    }\n    return line;\n  }\n\n  /**\n   * The picture box before a rig is picked: a faint truck outline on the\n   * panel and \"Pick your rig to see it here.\" (owner 11/5).\n   */\n  function emptyPic() {\n    var p = el('div', { class: 'byr-pic-empty' });\n    p.innerHTML = '<svg class=\"byr-pic-outline\" viewBox=\"0 0 640 260\" aria-hidden=\"true\" focusable=\"false\">' +\n      '<path d=\"M60 190h520v-36l-26-10H420l-8-58c-2-12-12-20-24-20H250c-10 0-19 6-23 15l-26 63H96c-20 0-36 16-36 36Z\" fill=\"#D9D6CE\"/>' +\n      '<circle cx=\"170\" cy=\"196\" r=\"38\" fill=\"#CBC8BF\"/><circle cx=\"470\" cy=\"196\" r=\"38\" fill=\"#CBC8BF\"/>' +\n      '<circle cx=\"170\" cy=\"196\" r=\"16\" fill=\"#E2DFD8\"/><circle cx=\"470\" cy=\"196\" r=\"16\" fill=\"#E2DFD8\"/></svg>';\n    p.appendChild(el('span', { text: 'Pick your rig to see it here.' }));\n    return p;\n  }\n\n  function Calculator(rootEl, data) {\n    this.root = rootEl;\n    this.data = data;\n    setMaskOverrides(data.mask_overrides);\n    setFileAliases(data.file_aliases);\n    noteOpenings(data.part_images);\n    this.row = null;\n    this.color = null;\n    // Embedded in another page (data-byr-embed: the kit builder's \"Add it up\n    // for me\" panel, owner 11/12): the result ends on \"Use this rig\" (no shop\n    // buttons). Desktop: the picture area opens on the showroom loop, as on\n    // this page (owner 11/12). A phone: no rig picture at all, no showroom.\n    this.embed = !!(rootEl.hasAttribute && rootEl.hasAttribute('data-byr-embed'));\n    if (this.embed && (root.innerWidth || 0) < 990) {\n      this.startShowroom = function () {};\n      this.showRig = function () { if (this.stage) this.stage.classList.toggle('byr-stage--empty', !this.row); };\n    }\n    // ?from=<product handle>: that product's variants, read at runtime\n    this.from = fromHandle(root.location && root.location.search);\n    this.fromProduct = null;\n    var self = this;\n    if (this.from && typeof fetch === 'function') {\n      fetch('/products/' + this.from + '.js', { credentials: 'same-origin' })\n        .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })\n        .then(function (p) { self.fromProduct = p; if (self.row) self.update(); })\n        .catch(function () { self.fromProduct = null; });   // unknown or unreadable: today's result\n    }\n    this.build();\n  }\n\n  // The site's own header and bars, by name (the theme's sticky header section among them)\n  var TOP_BAR_SELECTOR = '.shopify-section-header, .js-section__header, .js-header, header, [role=\"banner\"], ' +\n    '.announcement-bar, .js-announcement, sticky-header, .header-wrapper, #shopify-section-header';\n\n  /** A step card: numbered circle, title, the running weight on the right, then its body. */\n  function stepCard(n, title, total, kids) {\n    var hid = 'byr-step-' + n + '-' + (++uid);\n    return el('section', { class: 'byr-card byr-card--step', 'aria-labelledby': hid }, [\n      el('div', { class: 'byr-card-head' }, [\n        el('span', { class: 'byr-num', 'aria-hidden': 'true', text: String(n) }),\n        el('h2', { class: 'byr-card-title', id: hid, text: title }),\n        total\n      ])\n    ].concat(kids));\n  }\n\n  Calculator.prototype.build = function () {\n    var self = this;\n    var data = this.data;\n    var r = this.root;\n    // The section renders the dark top (headline, intro, stats) with an empty\n    // stage for the picture and an app slot for the rest; without them\n    // (an old section file) everything goes in the root, as before.\n    var app = r.querySelector('[data-byr-app]') || r;\n    app.innerHTML = '';\n    var stage = r.querySelector('[data-byr-stage]');\n    if (!stage) { stage = el('div', { class: 'byr-stage' }); app.appendChild(stage); }\n    stage.innerHTML = '';\n    this.stage = stage;\n\n    // 1. Pick the rig\n    this.make = select('Make', function () { self.onMake(); });\n    this.model = select('Model', function () { self.onModel(); });\n    this.year = select('Year', function () { self.onYear(); });\n    this.trim = select('Trim / cab', function () { self.onTrim(); });\n    this.make.wrap.classList.add('byr-field--make');\n    this.model.wrap.classList.add('byr-field--model');\n    this.year.wrap.classList.add('byr-field--year');\n    this.trim.wrap.classList.add('byr-field--trim');\n    fill(this.make.el, 'Choose make', makes(data).map(function (m) { return { value: m, label: m }; }));\n    if (makes(data).length === 1) this.make.el.value = makes(data)[0];\n\n    // The picture on its dark ground, and the factory colour strip under it\n    this.img = el('img', { class: 'byr-img', alt: '', loading: 'lazy', decoding: 'async', width: 1600, height: 800 });\n    this.img.addEventListener('error', function () { self.pic.classList.add('byr-pic--missing'); });\n    this.img.addEventListener('load', function () { self.pic.classList.remove('byr-pic--missing'); });\n    this.canvas = el('canvas', { class: 'byr-canvas', role: 'img' });\n    this.pic = el('div', { class: 'byr-pic byr-pic--empty' }, [\n      this.img,\n      this.canvas,\n      emptyPic(),\n      this.showSlides = el('div', { class: 'byr-show-slides', 'aria-hidden': 'true' }),\n      el('p', { class: 'byr-pic-loading', text: 'Loading your rig' }),\n      // the rope-size pill on the picture's top right, once a rig is picked; a tap goes to the result\n      this.badge = el('button', { type: 'button', class: 'byr-badge', hidden: true, onclick: function () {\n        self.result.scrollIntoView({ behavior: 'smooth', block: 'start' });\n      } })\n    ]);\n    // its own light panel inside the dark top (owner 11/5: 146 of the 324\n    // photos show white through open windows, white panels on the dark)\n    // the panel is what pins on a phone; the factory colours go right under it, in the top section (owner 11/5)\n    // before a rig is picked: the showroom caption, \"Popular rigs\" quick picks and a line\n    this.showCap = el('p', { class: 'byr-show-cap' });\n    var count = Object.keys(data.anchors || {}).length || data.vehicles.length;\n    this.showWrap = el('div', { class: 'byr-show' }, [\n      this.showCap,\n      el('p', { class: 'byr-show-title', id: 'byr-pop-' + (++uid), text: 'Popular rigs' }),\n      el('div', { class: 'byr-show-chips', role: 'group', 'aria-label': 'Popular rigs' }, QUICK_PICKS.filter(function (q) {\n        return makes(data).indexOf(q.make) >= 0 && models(data, q.make).some(function (m) { return m.model === q.model; });\n      }).map(function (q) {\n        return el('button', { type: 'button', class: 'byr-show-chip', text: q.label, onclick: function () { self.quickPick(q); } });\n      })),\n      el('p', { class: 'byr-show-note' }, [\n        el('span', { class: 'byr-show-note--wide', text: 'Or pick any of ' + count + ' on the left.' }),\n        el('span', { class: 'byr-show-note--narrow', text: 'Or pick any of ' + count + ' above.' })\n      ])\n    ]);\n    this.pinEl = el('div', { class: 'byr-stage-pic' }, [el('div', { class: 'byr-panel' }, [this.pic, this.showWrap])]);\n    stage.appendChild(this.pinEl);\n    this.swatches = el('div', { class: 'byr-swatches', role: 'radiogroup', 'aria-label': 'Paint color' });\n    this.colorName = el('p', { class: 'byr-color-name', 'aria-live': 'polite' });\n    this.colorWrap = el('div', { class: 'byr-colors', hidden: true }, [\n      el('div', { class: 'byr-colors-in' }, [\n        el('p', { class: 'byr-colors-label', text: 'Factory color' }), this.swatches, this.colorName\n      ])\n    ]);\n    stage.appendChild(this.colorWrap);\n    // the rope answer strip under the colours (owner picked Option B, 11/5):\n    // the size, three short lines, \"Shop it\"; live with the result card\n    this.answer = el('div', { class: 'byr-answer byr-answer--empty', 'aria-live': 'polite' });\n    stage.appendChild(this.answer);\n\n    // 2. Who's in the rig (owner 11/11: driver only): a fixed driver tile and\n    // the fuel / water counter, the line under them says why\n    var onInput = function () { self.update(); };\n    var driverId = 'byr-driver-' + (++uid);\n    this.driver = el('div', { class: 'byr-counter byr-counter--fixed', role: 'group', 'aria-labelledby': driverId }, [\n      el('span', { class: 'byr-counter-label', id: driverId, text: 'Driver' }),\n      el('span', { class: 'byr-hint', text: fmt(data.per_adult_lb) + ' lb' }),\n      el('div', { class: 'byr-counter-ctl' }, [el('output', { class: 'byr-count', text: '1' })])\n    ]);\n    this.gallons = stepper({ name: 'gallons', label: 'Extra fuel / water', hint: 'about 7 lb per gallon', min: 0, max: null, step: 5, value: 0, unit: 'gal',\n      less: 'Five gallons less', more: 'Five gallons more', onChange: onInput });\n    this.other = numberField('Anything else (lb)', 'other', 0, null, 0, null);\n    this.other.el.addEventListener('input', onInput);\n    this.other.el.addEventListener('change', onInput);\n\n    // 3. What's bolted on: chips in three groups; a pick-one group (winch,\n    // bumpers, tyres, tent, bed, flatbed, drawers, plow ...) keeps one, and a\n    // picked chip tapped again is un-picked\n    var onChip = function (e) { self.toggleGear(e.currentTarget); };\n    // the customer's own add-on weights (owner 11/11): {id: lb}, kept while the add-on stays picked\n    this.gearEdits = {};\n    // the swing-out's spare dismissed by the customer (owner 11/11): off until the swing-out is unticked\n    this.spareDismissed = false;\n    var gearBox = el('div', { class: 'byr-gear' });\n    gearSections(data.gear).forEach(function (s) {\n      var hid = 'byr-gs-' + (++uid);\n      var chips = s.items.map(function (g) {\n        var chip = el('button', {\n          type: 'button', class: 'byr-gchip', value: g.id, 'data-gear': g.id, 'data-group': g.group || '',\n          'aria-pressed': 'false', onclick: onChip\n        }, [\n          el('span', { class: 'byr-gchip-name', text: g.label }), ' ',\n          el('span', { class: 'byr-gchip-lb' }, [el('span', { class: 'byr-gchip-n', text: '+' + fmt(g.lb) }), el('span', { class: 'byr-vh', text: ' lb' })]),\n          el('span', { class: 'byr-gchip-why' })\n        ]);\n        // the weight's own tap target (a picked chip only), beside the chip\n        // button and laid over its \"+N\": it opens the weight card (openGearEdit)\n        var edit = el('button', { type: 'button', class: 'byr-gchip-edit', hidden: true, 'data-edit': g.id,\n          'aria-haspopup': 'dialog', onclick: function () { self.openGearEdit(g.id); } });\n        return el('span', { class: 'byr-gchip-box', 'data-chip': g.id }, [chip, edit]);\n      });\n      gearBox.appendChild(el('div', { class: 'byr-gear-group', role: 'group', 'aria-labelledby': hid }, [\n        el('p', { class: 'byr-gear-title', id: hid, text: s.title }),\n        el('div', { class: 'byr-chips' }, chips)\n      ]));\n    });\n\n    this.buildGearCard();\n\n    // 4. Result: the black card, then \"How we got X lb\" (closed) and the note\n    this.result = el('div', { class: 'byr-result', 'aria-live': 'polite' });\n    this.howSum = el('summary', { class: 'byr-how-sum' });\n    this.howBody = el('div', { class: 'byr-how-body' });\n    this.how = el('details', { class: 'byr-how', hidden: true }, [this.howSum, this.howBody]);\n\n    this.tot1 = el('span', { class: 'byr-tot' });\n    // \"Know your rig's weight? Enter it\" (owner 11/10): under the pickers once\n    // a rig is picked; the number takes the row's curb weight's place\n    var ownId = 'byr-own-' + (++uid);\n    this.ownOpen = el('button', {\n      type: 'button', class: 'byr-own-open', 'aria-expanded': 'false', 'aria-controls': ownId + '-box',\n      text: 'Know your rig\\u2019s weight? Enter it', onclick: function () { self.openOwn(); }\n    });\n    this.ownInput = el('input', {\n      id: ownId, type: 'number', inputmode: 'numeric', name: 'own_lb', min: OWN_LIMITS[0], max: OWN_LIMITS[1], step: 1,\n      autocomplete: 'off', class: 'byr-number byr-own-input', 'aria-describedby': ownId + '-hint',\n      oninput: function () { self.update(); }\n    });\n    this.ownMsg = el('span', { class: 'byr-own-msg', 'aria-live': 'polite' });\n    this.ownBox = el('div', { class: 'byr-own', id: ownId + '-box', hidden: true }, [\n      el('label', { for: ownId, text: 'Your rig\\u2019s weight (lb)' }),\n      this.ownInput,\n      el('span', { class: 'byr-hint byr-own-hint', id: ownId + '-hint',\n        text: 'From a scale ticket or your registration. Weighed with your gear already on? Leave the gear buttons off.' }),\n      this.ownMsg\n    ]);\n    this.own = el('div', { class: 'byr-own-wrap', hidden: true }, [this.ownOpen, this.ownBox]);\n    // factory options (owner 11/11, bed length): one picker a group, built per row (setOptions)\n    this.optSelects = [];\n    this.optsBox = el('div', { class: 'byr-pickers byr-opts', hidden: true });\n    this.tot2 = el('span', { class: 'byr-tot' });\n    this.tot3 = el('span', { class: 'byr-tot' });\n    // Step 1, \"Pick your rig\", sits in the dark top section under the intro\n    // (owner 11/5); the form below starts at step 2. A section file without\n    // the slot gets it as the form's first card.\n    var pickHid = 'byr-pick-' + (++uid);\n    var pickCard = el('section', { class: 'byr-pick', 'aria-labelledby': pickHid }, [\n      el('div', { class: 'byr-card-head byr-pick-head' }, [\n        el('span', { class: 'byr-num byr-num--olive', 'aria-hidden': 'true', text: '1' }),\n        el('h2', { class: 'byr-pick-title', id: pickHid, text: 'Pick your rig' }),\n        this.tot1\n      ]),\n      el('div', { class: 'byr-pickers' }, [this.make.wrap, this.model.wrap, this.year.wrap, this.trim.wrap]),\n      this.optsBox,\n      this.own\n    ]);\n    var pickSlot = r.querySelector('[data-byr-picker]');\n    if (pickSlot) { pickSlot.innerHTML = ''; pickSlot.appendChild(pickCard); }\n    var form = el('div', { class: 'byr-form' }, [\n      pickSlot ? null : pickCard,\n      this.peopleCard = stepCard(2, 'Who\\u2019s in the rig', this.tot2, [\n        el('div', { class: 'byr-people' }, [this.driver, this.gallons.wrap]),\n        el('p', { class: 'byr-people-note', text: DRIVER_NOTE })\n      ]),\n      stepCard(3, 'What\\u2019s bolted on', this.tot3, [\n        el('p', { class: 'byr-card-intro', text: 'Tap what\\u2019s on the truck. It shows up on the picture and in the weight.' }),\n        el('p', { class: 'byr-card-help', text: GEAR_EDIT_HELP }),\n        gearBox,\n        el('div', { class: 'byr-other' }, [this.other.wrap])\n      ])\n    ]);\n    // Desktop (owner 11/11): a small copy of the drawn picture at the top of the\n    // sticky result column, so the gear shows up on the truck while step 3 is\n    // being ticked; copied from the big canvas after every draw (syncMini)\n    this.miniCanvas = el('canvas', { class: 'byr-mini-canvas' });\n    this.mini = el('div', { class: 'byr-mini', hidden: true, 'aria-hidden': 'true' }, [this.miniCanvas]);\n    var side = el('div', { class: 'byr-side' }, [this.mini, this.result, this.how, el('p', { class: 'byr-note', text: SIZE_NOTE })]);\n    app.appendChild(el('div', { class: 'byr-layout' }, [form, side]));\n    this.fitMini();\n    window.addEventListener('resize', function () { self.fitMini(); });\n    // the chips' weight targets follow the chips (a resize, the web fonts arriving)\n    var resyncGear = function () { if (self.row && self.lastRes) self.syncGearWeights(self.lastRes); };\n    window.addEventListener('resize', resyncGear);\n    if (typeof document !== 'undefined' && document.fonts && document.fonts.ready && document.fonts.ready.then) document.fonts.ready.then(resyncGear);\n\n    // Phones: once a rig is picked, the answer stays in a bar fixed to the\n    // bottom of the screen: the rope and weight (a tap goes to the result)\n    // and \"Shop it\", the result's main button.\n    this.barValue = el('span', { class: 'byr-bar-value' });\n    this.barShop = el('a', { class: 'byr-bar-shop', href: '#', text: 'Shop it' });\n    if (this.embed) {\n      this.barShop = el('button', { type: 'button', class: 'byr-bar-shop', text: USE_BUTTON, onclick: function () { self.use(); } });\n    }\n    this.bar = el('div', { class: 'byr-bar', hidden: true }, [\n      el('button', { type: 'button', class: 'byr-bar-info', onclick: function () {\n        self.result.scrollIntoView({ behavior: 'smooth', block: 'start' });\n      } }, [el('span', { class: 'byr-bar-label', text: 'Your rope' }), this.barValue]),\n      this.barShop\n    ]);\n    app.appendChild(this.bar);\n    // The site's own sticky header: whatever fixed or sticky bar covers the\n    // top of the screen (not ours) is measured as the page scrolls; the\n    // result column (desktop) and the pinned picture (phones) sit under it.\n    var stickyQueued = false;\n    var lastTop = -1;\n    var still = 0;\n    var follow = 0;\n    this.syncStickyTop = function () {\n      stickyQueued = false;\n      var W = window.innerWidth || 0;\n      var vh0 = window.innerHeight || document.documentElement.clientHeight || 0;\n      // The visible bottom of whatever sits over the top of the screen,\n      // measured live on every scroll (it grows and shrinks with the\n      // announcement bar and the reviews bar, and this theme's header slides\n      // away on the way down and back on the way up): the elements under the\n      // top edge, and the theme's header itself by name (Justin, #178\n      // check: the top edge alone missed it). Every fixed or sticky box round\n      // them near the top counts with its bottom edge as it is on screen now\n      // (getBoundingClientRect, 0 when slid away; #179 check: measured where\n      // it sticks, the picture stayed 158 px down under a hidden header);\n      // the lowest wins, never more than half the screen.\n      var bottom = 0;\n      var cands = [];\n      if (document.elementsFromPoint) {\n        [8, Math.round(W / 2), W - 8].forEach(function (x) {\n          document.elementsFromPoint(x, 1).forEach(function (e) { cands.push(e); });\n        });\n      }\n      Array.prototype.forEach.call(document.querySelectorAll(TOP_BAR_SELECTOR), function (e) { cands.push(e); });\n      var done = [];\n      cands.forEach(function (e) {\n        if (r.contains(e)) return;\n        for (var n = e; n && n !== document.body && n !== document.documentElement; n = n.parentElement) {\n          if (done.indexOf(n) >= 0) break;\n          done.push(n);\n          var cs = window.getComputedStyle(n);\n          if (cs.position !== 'fixed' && cs.position !== 'sticky') continue;\n          var rc = n.getBoundingClientRect();\n          if (!(rc.height > 0)) continue;\n          if (rc.top > 0.25 * vh0) continue;   // not a bar at the top\n          var b = Math.max(0, rc.bottom);\n          if (b > bottom && b < 0.5 * vh0) bottom = b;\n        }\n      });\n      // embedded: the host says what covers the top of its own scroller\n      if (typeof r.byrTop === 'function') bottom = r.byrTop() || 0;\n      bottom = Math.round(bottom);\n      r.style.setProperty('--byr-sticky-top', bottom + 'px');\n      // The header slides on its own, starting just after the scroll that\n      // set it off: after every scroll the measure is taken again each frame\n      // (the picture moves with the header) until it has held still for\n      // about 0.4 s, at most about 2 s.\n      if (bottom !== lastTop) { lastTop = bottom; still = 0; }\n      else still++;\n      if (follow > 0 && still < 24) { follow--; queueSticky(); } else follow = 0;\n      // Phones: the picture is pinned only while Who's in the rig and the gear\n      // are on screen, and never over the result card (Justin, layout round\n      // 1 check): it lets go before the card comes up under it.\n      var pin = false;\n      if (W < 990 && self.row) {\n        var vh = window.innerHeight || document.documentElement.clientHeight;\n        var pc = self.peopleCard.getBoundingClientRect();\n        var rb = self.result.getBoundingClientRect();\n        var sh = self.pinEl.getBoundingClientRect().height;\n        pin = pc.top < vh && rb.top > bottom + sh + 8;\n      }\n      self.pinEl.classList.toggle('byr-stage--pinned', pin);\n      // Phones: the bottom bar steps aside while the answer strip (the same\n      // answer and button) is on screen, and comes back once it scrolls away\n      // (embedded, with no answer strip on a phone: while the result's \"Use this rig\" is)\n      var away = false;\n      var awayEl = self.embed ? self.result.querySelector('.byr-buttons') : self.answer;\n      if (W < 990 && self.row && awayEl) {\n        var ar = awayEl.getBoundingClientRect();\n        away = ar.height > 0 && ar.bottom > bottom && ar.top < vh0;\n      }\n      self.bar.classList.toggle('byr-bar--away', away);\n      self.syncChat();\n      self.keepButtonsClear();\n    };\n    // Phones: a chat launcher (or any other site widget) fixed over the\n    // bottom bar's right end (Justin, #177 check: Chat sat on \"Shop it\").\n    // What covers the bar is found by hit-testing across it, so it works\n    // whatever the widget is built with; the bar's right end is kept clear\n    // of it (+ 12 px) and \"Shop it\" moves left. The widget itself is not\n    // moved: lifting it would lift its open chat window too.\n    this.syncChat = function () {\n      var bar = self.bar;\n      var pad = 0;\n      if (bar.classList.contains('byr-bar--away')) return;   // out of sight: nothing to clear\n      if (!bar.hidden && (window.innerWidth || 0) < 990 && document.elementFromPoint) {\n        bar.style.paddingRight = '';\n        var rc = bar.getBoundingClientRect();\n        var left = null;\n        if (rc.height > 0) {\n          [rc.top + 6, rc.top + rc.height / 2, rc.bottom - 6].forEach(function (y) {\n            for (var x = rc.right - 2; x > rc.left + rc.width / 3; x -= 6) {\n              var e = document.elementFromPoint(x, y);\n              if (!e || r.contains(e) || e === document.body || e === document.documentElement) continue;\n              // its own box when it has one (a launcher's round edge is wider than where a probe hit it); else the probe's step\n              var eb = e.getBoundingClientRect();\n              var l = eb.width > 0 && eb.width < rc.width / 2 && eb.left < x ? eb.left : x - 6;\n              if (left == null || l < left) left = l;\n            }\n          });\n        }\n        if (left != null) pad = Math.round(rc.right - left + 12);\n        if (pad > 0.45 * rc.width) pad = 0;   // not a launcher (a banner across the bar): left alone\n      }\n      bar.style.paddingRight = pad ? pad + 'px' : '';\n      bar.classList.toggle('byr-bar--cleared', pad > 0);\n    };\n    // widgets load late and open and close: check again now and then while the bar shows on a phone\n    window.setInterval(function () {\n      if (self.row) self.syncStickyTop();   // the header's height can change without a scroll (announcement closed)\n      if (!self.bar.hidden && (window.innerWidth || 0) < 990) self.syncChat();\n      else if (self.bar.style.paddingRight) self.syncChat();\n      self.keepButtonsClear();\n    }, 1500);\n    var queueSticky = function () {\n      if (stickyQueued) return;\n      stickyQueued = true;\n      (window.requestAnimationFrame || window.setTimeout)(self.syncStickyTop);\n    };\n    var onScroll = function () { follow = 120; still = 0; queueSticky(); };\n    // the picture's cap follows the left column (fonts arriving, the headline's fit, a resize)\n    var fitQueued = false;\n    var queueFitStage = function () {\n      if (fitQueued) return;\n      fitQueued = true;\n      (window.requestAnimationFrame || window.setTimeout)(function () { fitQueued = false; self.fitStage(); });\n    };\n    window.addEventListener('resize', queueFitStage);\n    if (document.fonts && document.fonts.ready && document.fonts.ready.then) document.fonts.ready.then(queueFitStage);\n    if (document.fonts && document.fonts.addEventListener) document.fonts.addEventListener('loadingdone', queueFitStage);\n    window.addEventListener('scroll', onScroll, { passive: true });\n    // embedded in a panel that scrolls on its own (data-byr-scroll)\n    var scroller = r.closest ? r.closest('[data-byr-scroll]') : null;\n    if (scroller) scroller.addEventListener('scroll', onScroll, { passive: true });\n    // a theme that scrolls the body (or a wrapper) instead of the window: its\n    // scroll events reach the document only on the way down (capture)\n    document.addEventListener('scroll', onScroll, { passive: true, capture: true });\n    window.addEventListener('resize', queueSticky);\n    queueSticky();\n    this.onMake();\n  };\n\n  Calculator.prototype.onMake = function () {\n    var make = this.make.el.value;\n    var opts = make ? models(this.data, make).map(function (m) { return { value: m.model, label: m.label }; }) : [];\n    fill(this.model.el, make ? 'Choose model' : 'Choose make first', opts);\n    this.onModel();\n  };\n\n  Calculator.prototype.onModel = function () {\n    var make = this.make.el.value;\n    var model = this.model.el.value;\n    var opts = model ? years(this.data, make, model).map(function (y) { return { value: String(y), label: String(y) }; }) : [];\n    fill(this.year.el, model ? 'Choose year' : 'Choose model first', opts);\n    this.onYear();\n  };\n\n  Calculator.prototype.onYear = function () {\n    var year = parseInt(this.year.el.value, 10);\n    this.rows = year ? trims(this.data, this.make.el.value, this.model.el.value, year) : [];\n    fill(this.trim.el, year ? 'Choose trim / cab' : 'Choose year first',\n      this.rows.map(function (t) { return { value: t.key, label: t.label }; }));\n    this.onTrim();\n  };\n\n  Calculator.prototype.onTrim = function () {\n    var key = this.trim.el.value;\n    var row = null;\n    (this.rows || []).forEach(function (t) { if (t.key === key) row = t; });\n    var changed = !this.row || !row || this.row.key !== row.key;\n    this.row = row;\n    this.capGear();\n    if (changed) {\n      this.setOptions(row);   // the new row's pickers, at their first choice\n      this.closeOwn();   // the customer's own weight was for the last rig\n      this.showRig();\n    }\n    this.update();\n  };\n\n  /**\n   * The option pickers for a row (owner 11/11): one select a group, labelled\n   * with the group's name, each choice per optionLabel (\"6.5 ft bed\", \"7.3L V8\"),\n   * the first picked. None for a row with no options.\n   */\n  Calculator.prototype.setOptions = function (row) {\n    var self = this;\n    this.optsBox.innerHTML = '';\n    this.optSelects = ((row && row.options) || []).map(function (g) {\n      var f = select(g.group, function () { self.update(); });\n      g.choices.forEach(function (c, i) { f.el.appendChild(el('option', { value: String(i), text: optionLabel(g.group, c) })); });\n      f.el.disabled = false;\n      f.el.value = '0';\n      f.wrap.classList.add('byr-field--opt');\n      self.optsBox.appendChild(f.wrap);\n      return f.el;\n    });\n  };\n\n  /** Open the \"your rig's weight\" field and put the cursor in it. */\n  Calculator.prototype.openOwn = function () {\n    this.ownOpen.hidden = true;\n    this.ownOpen.setAttribute('aria-expanded', 'true');\n    this.ownBox.hidden = false;\n    this.update();\n    try { this.ownInput.focus({ preventScroll: true }); } catch (ignore) { this.ownInput.focus(); }   // eslint-disable-line no-unused-vars\n  };\n\n  /** Empty and close the field: the row's curb weight again. */\n  Calculator.prototype.closeOwn = function () {\n    this.ownInput.value = '';\n    this.ownBox.hidden = true;\n    this.ownOpen.hidden = false;\n    this.ownOpen.setAttribute('aria-expanded', 'false');\n  };\n\n  /** \"reset\": back to the row's curb weight, focus on the link that reopens the field. */\n  Calculator.prototype.resetOwn = function () {\n    this.closeOwn();\n    this.update();\n    this.ownOpen.focus();\n  };\n\n  /** The gear chips, in page order. */\n  Calculator.prototype.chips = function () {\n    return Array.prototype.slice.call(this.root.querySelectorAll('[data-gear]'));\n  };\n\n  /** Pick a chip: the rest of its pick-one group is un-picked. */\n  Calculator.prototype.pickGear = function (c) {\n    var grp = c.getAttribute('data-group');\n    if (grp) this.chips().forEach(function (o) { if (o !== c && o.getAttribute('data-group') === grp) setOn(o, false); });\n    setOn(c, true);\n  };\n\n  /** A tap on a chip: pick it, or un-pick it when it was picked. */\n  Calculator.prototype.toggleGear = function (c) {\n    // the spare the page added for the swing-out: a tap turns it off (owner 11/11);\n    // the swing-out stays ticked, and the spare stays off until it is unticked\n    if (c.value === 'spare' && !isOn(c) && c.classList.contains('byr-gchip--auto')) {\n      this.spareDismissed = true;\n      this.update();\n      return;\n    }\n    if (isOn(c)) setOn(c, false);\n    else { this.pickGear(c); this.bedExclusive(c); }\n    this.capGear();\n    this.update();\n  };\n\n  /**\n   * Hide (and un-pick) gear this rig can't take: tyre sizes over its cap\n   * (Justin 11/2; UTVs 30, so none), and tents and racks on the Class C and\n   * the pop-top van (round 4). A chip group with nothing left is hidden.\n   */\n  Calculator.prototype.capGear = function () {\n    var row = this.row;\n    // owner 11/4: a cap, the wedge, the slide-in or the flatbed takes the bed:\n    // the tool box, side boxes and ladder rack go away (and come back with it)\n    var covered = bedCovered(this.inputs().gear);\n    this.chips().forEach(function (i) {\n      var fits = (!row || gearFits(row, i.value)) && !(covered && BED_RAIL_GEAR.indexOf(i.value) >= 0);\n      i.style.display = fits ? '' : 'none';   // inline: the theme's display rules beat [hidden]\n      if (i.parentNode && i.parentNode.hasAttribute('data-chip')) i.parentNode.style.display = fits ? '' : 'none';   // its box too (no empty slot in the row)\n      if (!fits && isOn(i)) setOn(i, false);\n    });\n    Array.prototype.forEach.call(this.root.querySelectorAll('.byr-gear-group'), function (gp) {\n      var any = Array.prototype.some.call(gp.querySelectorAll('[data-gear]'), function (i) { return i.style.display !== 'none'; });\n      gp.style.display = any ? '' : 'none';\n    });\n  };\n\n  /**\n   * A camper takes the whole bed (Justin 11/2): picking the wedge or the\n   * slide-in clears the bed rack and the roof top tent, and picking either of\n   * those clears a camper.\n   */\n  var CAMPERS = ['popup_topper', 'slide_in_camper'];\n  var BED_TOP = ['bedrack', 'rtt_soft', 'rtt_hard', 'rtt_large'];\n  Calculator.prototype.bedExclusive = function (t) {\n    if (!t || !isOn(t) || !t.value || !this.row || this.row.body_type !== 'pickup') return;\n    var clear = CAMPERS.indexOf(t.value) >= 0 ? BED_TOP : BED_TOP.indexOf(t.value) >= 0 ? CAMPERS : null;\n    // owner 11/4: the ladder rack and the bed rack are one or the other\n    if (t.value === 'ladderrack') clear = ['bedrack'];\n    else if (t.value === 'bedrack') clear = CAMPERS.concat(['ladderrack']);\n    if (!clear) return;\n    this.chips().forEach(function (i) {\n      if (clear.indexOf(i.value) >= 0 && isOn(i)) setOn(i, false);\n    });\n  };\n\n  Calculator.prototype.showRig = function () {\n    var self = this;\n    var row = this.row;\n    if (this.stage) this.stage.classList.toggle('byr-stage--empty', !row);\n    if (row) this.stopShowroom(); else this.startShowroom();\n    if (!row) {\n      this.pic.classList.add('byr-pic--empty');\n      this.img.removeAttribute('src');\n      this.img.removeAttribute('srcset');\n      this.img.alt = '';\n      this.colorWrap.hidden = true;\n      this.paintToken = null;\n      this.rig = null;\n      this.pic.classList.remove('byr-pic--loading', 'byr-pic--painted', 'byr-pic--photo');\n      return;\n    }\n    this.pic.classList.remove('byr-pic--empty');\n    this.img.src = IMAGE_BASE + row.image + '.webp';\n    this.img.srcset = IMAGE_BASE + row.image + '-800.webp 800w, ' + IMAGE_BASE + row.image + '.webp 1600w';\n    this.img.sizes = '(min-width: 990px) 660px, 100vw';\n    this.img.alt = row.make + ' ' + modelLabel(row.model) + ' ' + row.trim;\n    // every rig faces left (Justin 11/4): a right-facing picture shows mirrored until the canvas is drawn\n    this.img.classList.toggle('byr-img--mirror', ((this.data.anchors || {})[row.image] || {}).facing === 'right');\n\n    // Colour picker: swatch + factory name. Paint off (owner 11/6): only on\n    // a rig with real-colour pictures, only the colours that have one, none\n    // picked at first (the olive picture); the colours' phone-size pictures\n    // load now so a swatch swaps at once. Paint on: the body repainted\n    // through the mask, the first colour applied.\n    var colors = swatchColors(this.data, row);\n    this.swatchList = colors;\n    this.color = null;\n    this.colorImg = null;\n    this.loadPaint(row, colors.length > 0);\n    this.swatches.innerHTML = '';\n    this.colorName.textContent = '';\n    var real = !PAINT_ON && realColors(this.data, row.image);\n    if (real) colors.forEach(function (c) { colorPic(real[c.name], 800); });\n    colors.forEach(function (c, i) {\n      var b = el('button', {\n        type: 'button', class: 'byr-swatch', role: 'radio', 'aria-checked': 'false',\n        'aria-label': c.name, title: c.name\n      }, [el('span', { class: 'byr-dot', style: 'background-color:' + c.hex })]);\n      b.addEventListener('click', function () { self.pickColor(i); });\n      self.swatches.appendChild(b);\n    });\n    this.colorWrap.hidden = colors.length === 0;\n    if (PAINT_ON && colors.length) this.pickColor(0);    // first factory colour, already applied\n  };\n\n  /** Decode the current rig's picture and mask (cached), then paint the chosen colour. */\n  Calculator.prototype.loadPaint = function (row, hasColors) {\n    var self = this;\n    var token = {};\n    this.paintToken = token;\n    this.rig = null;\n    this.pic.classList.remove('byr-pic--painted', 'byr-pic--photo');\n    // no colours to paint (paint on), or no canvas: the stock photo, as it is.\n    // Paint off, every rig is drawn (olive or a real colour, plus its gear).\n    if ((PAINT_ON && !hasColors) || typeof ImageData === 'undefined') { this.pic.classList.remove('byr-pic--loading'); this.pic.classList.add('byr-pic--photo'); return; }\n    this.pic.classList.add('byr-pic--loading');\n    var need = (this.pic.clientWidth || 800) * (window.devicePixelRatio || 1);\n    var w = need > 820 ? 1600 : 800;\n    getRig(row.image, w).then(function (rig) {\n      if (self.paintToken !== token) return;\n      self.rig = rig;\n      self.renderPaint();\n    }, function () {\n      // Can't read the pixels (e.g. blocked by the browser): show the photo as it is.\n      if (self.paintToken === token) { self.pic.classList.remove('byr-pic--loading'); self.pic.classList.add('byr-pic--photo'); }\n    });\n  };\n\n  Calculator.prototype.renderPaint = function () {\n    var rig = this.rig;\n    if (!PAINT_ON) {\n      if (!rig) return;\n      this.canvas.setAttribute('aria-label', this.img.alt + (this.color ? ', ' + this.color.name : ''));\n      this.renderScene();\n      return;\n    }\n    if (!rig || !this.color) return;\n    paint(rig.prep, rig.src.data, rig.out.data, this.color.hex);\n    rig.body.getContext('2d').putImageData(rig.out, 0, 0);\n    this.canvas.setAttribute('aria-label', this.img.alt + ', ' + this.color.name);\n    this.renderScene();\n  };\n\n  /**\n   * The body picture: the picked colour's real picture (paint off; the\n   * rig's width, or the phone size until that has loaded), else the rig's\n   * own (olive, or repainted with the paint on).\n   */\n  Calculator.prototype.bodyPicture = function () {\n    return (!PAINT_ON && this.color && this.colorImg) || this.rig.body;\n  };\n\n  /** Body (repainted, lifted) plus the drawn-on parts for the ticked gear. */\n  Calculator.prototype.renderScene = function () {\n    var rig = this.rig;\n    if (!rig || !this.row || (PAINT_ON && !this.color)) return;\n    var body = this.bodyPicture();\n    if (this.canvas.width !== rig.w) { this.canvas.width = rig.w; this.canvas.height = rig.h; }\n    var ctx = this.canvas.getContext('2d');\n    var anchors = this.data.anchors && this.data.anchors[this.row.image];\n    var gear = cleanInputs(this.inputs()).gear;\n    if (!anchors || !anchors.fwc || !this.row.wheelbase_in) {\n      if (anchors === undefined && typeof console !== 'undefined') console.warn('build-your-rig: no anchors for ' + this.row.image);\n      ctx.setTransform(1, 0, 0, 1, 0, 0);\n      ctx.clearRect(0, 0, rig.w, rig.h);\n      ctx.drawImage(body, 0, 0, rig.w, rig.h);\n      this.sceneFit = { g: 1, dx: 0, G: 800 };\n      if (this.maxFor !== this.row.key) { this.maxFor = this.row.key; this.maxBoxes = { base: [0, 0, 1600, 800], plow: [0, 0, 1600, 800] }; this.miniLooks = {}; }\n      this.setLoading(false);\n      this.miniDirty = true;\n      this.syncMini();\n      return;\n    }\n    var self = this;\n    if (!this.redraw) this.redraw = function () { self.renderScene(); };\n    // paint off: the mask only for the sliders' rocker line, fetched when they are ticked\n    if (!PAINT_ON && rig.mask === undefined && has(gear, 'sliders')) {\n      this.setLoading(true);\n      rigMask(rig).then(function () { if (self.rig === rig) self.renderScene(); });\n      return;\n    }\n    if (rig.mask && rig.rockerFor === this.row.image && !rig.rockerMasked) {\n      rig.rockerY = measureRocker(rig.mask, rig.w, anchors);\n      rig.rockerMasked = true;\n    }\n    if (rig.rockerFor !== this.row.image) {\n      rig.rockerY = measureRocker(rig.mask, rig.w, anchors);\n      rig.rockerMasked = !!rig.mask;\n      // the picture's own silhouette (Justin's sweep 11/4): the stock rear\n      // bumper of an SUV / van, and the cab roof's highest line\n      var sd = rig.src && rig.src.data;\n      var sw = rig.w;\n      var alpha = sd ? function (x, y) { return sd[(y * sw + x) * 4 + 3]; } : null;\n      var ppi0 = anchors.wheelbase_px / this.row.wheelbase_in;\n      rig.rearBumper = alpha ? measureRearBumper(alpha, sw, anchors, ppi0, !!this.row.has_rear_spare) : null;\n      rig.cabRoofY = alpha ? measureCabRoof(alpha, sw, anchors) : null;\n      rig.rockerFor = this.row.image;\n    }\n    var extra = {};\n    if (rig.rockerY != null) extra.rocker_y = rig.rockerY;\n    if (rig.rearBumper) extra.rear_bumper = rig.rearBumper;\n    if (rig.cabRoofY != null) extra.sil_cab_roof_y = rig.cabRoofY;\n    var a = Object.keys(extra).length ? Object.assign({}, anchors, extra) : anchors;\n    // the small picture's frame: every add-on this rig can carry, worked out\n    // once a rig (on desktop, where it shows; else when it first does)\n    this.sceneAnchors = a;\n    this.sceneAnchorsFor = this.row.key;\n    var plan = planScene(this.row, a, gear, this.data.part_images);\n    plan.paint = this.color ? this.color.hex : OLIVE_PAINT;   // a fiberglass cap is painted with it (Justin sweep 11/4)\n    // Owner phone review 1 (11/4): nothing is drawn until every part picture\n    // the scene needs has loaded (or failed: then its drawn part); the grey\n    // box says \"Loading your rig\" meanwhile. Then the scene is drawn once.\n    var files = [];\n    plan.parts.forEach(function (p) { if (p.pic && p.pic.file && files.indexOf(p.pic.file) < 0) files.push(p.pic.file); });\n    var waiting = files.filter(function (f) { return !partPicSettled(f, self.redraw); });\n    if (waiting.length) { this.setLoading(true); return; }\n    var fit = drawScene(ctx, rig.w, body, plan, function (file) { var e = partPics[file]; return e && e.ok ? e.img : null; });\n    this.sceneFit = { g: fit.g, dx: fit.dx, G: plan.bounds[3] };\n    this.sceneBoxNow = fit.box;   // what this draw holds (frame px): checks only\n    this.setLoading(false);\n    this.miniDirty = true;\n    this.syncMini();\n  };\n\n  /**\n   * The small picture's size (desktop only, owner 11/11): miniStep for this\n   * window, set here at start and on a resize only (never on a scroll, the\n   * header's slide or a change in the card). Its canvas, and the same room\n   * under the form (--byr-mini-space, CSS) so the taller column lets go at the\n   * end of the calculator where it did before.\n   */\n  Calculator.prototype.fitMini = function () {\n    var vw = window.innerWidth || 0;\n    var vh = window.innerHeight || document.documentElement.clientHeight || 0;\n    if (this.miniFit && this.miniFit.vw === vw && this.miniFit.vh === vh) return;\n    this.miniFit = { vw: vw, vh: vh };\n    var h = vw >= 990 ? miniStep(vh, !!this.from) : 0;\n    this.miniH = h;\n    if (h) {\n      // the rope card's width (the column's), less the 1 px border each side\n      var side = this.mini.parentNode;\n      var w = Math.max(2 * h, ((side && side.clientWidth) || 400) - MINI_BORDER);\n      this.miniW = w;\n      var dpr = window.devicePixelRatio || 1;\n      var c = this.miniCanvas;\n      var cw = Math.round(w * dpr);\n      var ch = Math.round(h * dpr);\n      if (c.width !== cw || c.height !== ch) { c.width = cw; c.height = ch; this.miniDirty = true; }\n      c.style.height = h + MINI_BORDER + 'px';\n      this.miniLooks = {};\n    }\n    this.syncMini();\n  };\n\n  /**\n   * The small picture's window on the scene (miniView): the rig's box with\n   * every add-on it can carry but the plow (maxSceneBoxes, once a rig),\n   * filling the frame; with a plow ticked, the box that holds the plow too\n   * (owner 11/11, option C). So the zoom changes once when the plow goes on\n   * and back when it comes off, and for nothing else but a new rig or a\n   * resize.\n   */\n  Calculator.prototype.miniWindow = function () {\n    var row = this.row;\n    if (this.maxFor !== row.key) {\n      this.maxFor = row.key;\n      var a = this.sceneAnchorsFor === row.key ? this.sceneAnchors : null;\n      this.maxBoxes = a ? maxSceneBoxes(row, a, this.data.part_images) : { base: [0, 0, 1600, 800], plow: [0, 0, 1600, 800] };\n      this.miniLooks = {};\n    }\n    if (!this.miniLooks) this.miniLooks = {};\n    var which = hasPlow(cleanInputs(this.inputs()).gear.filter(function (id) { return gearFits(row, id); })) ? 'plow' : 'base';\n    this.miniState = which;\n    if (!this.miniLooks[which]) this.miniLooks[which] = miniView(this.maxBoxes[which], this.miniW, this.miniH);\n    this.miniLook = this.miniLooks[which];\n    return this.miniLook;\n  };\n\n  /**\n   * drawImage of a source rectangle onto the whole of a w x h canvas, the part\n   * outside the source canvas left clear (not every browser draws a source\n   * rectangle that runs off its image).\n   */\n  function copyClipped(ctx, src, sx, sy, sw, sh, w, h) {\n    var x0 = Math.max(0, sx);\n    var y0 = Math.max(0, sy);\n    var x1 = Math.min(src.width, sx + sw);\n    var y1 = Math.min(src.height, sy + sh);\n    if (x1 <= x0 || y1 <= y0) return;\n    var kx = w / sw;\n    var ky = h / sh;\n    ctx.drawImage(src, x0, y0, x1 - x0, y1 - y0, (x0 - sx) * kx, (y0 - sy) * ky, (x1 - x0) * kx, (y1 - y0) * ky);\n  }\n\n  /**\n   * The small picture's pixels and whether it shows: the big canvas copied\n   * down after every draw (no second download). Hidden at size 0, before a\n   * rig is drawn and while a new rig loads; the last frame stays while the\n   * big picture waits for a part picture.\n   */\n  Calculator.prototype.syncMini = function () {\n    var mini = this.mini;\n    if (!mini) return;\n    var h = this.miniH || 0;\n    var painted = this.pic.classList.contains('byr-pic--painted');\n    if (h && this.row && this.rig && this.miniDirty && painted && this.sceneFit) {\n      var c = this.miniCanvas;\n      var ctx = c.getContext('2d');\n      ctx.setTransform(1, 0, 0, 1, 0, 0);\n      ctx.clearRect(0, 0, c.width, c.height);\n      // one fixed window on the scene a rig and a size: the big picture's own\n      // fit (which shrinks the scene as add-ons reach the edge) undone, so\n      // ticking gear, scrolling or the header never zooms this one\n      var v = this.miniWindow();\n      var f = this.sceneFit;\n      var k = this.canvas.width / 1600;\n      copyClipped(ctx, this.canvas,\n        k * (800 + f.g * (v.x - 800) + f.dx), k * (f.G + f.g * (v.y - f.G)), k * f.g * v.w, k * f.g * v.h,\n        c.width, c.height);\n      this.miniDirty = false;\n      this.miniDrawn = true;\n      this.miniFor = this.row.key;\n    }\n    var show = !!(h && this.row && this.miniDrawn && this.miniFor === this.row.key &&\n      (painted || this.pic.classList.contains('byr-pic--loading')));\n    mini.hidden = !show;\n    this.root.style.setProperty('--byr-mini-space', show ? h + MINI_BORDER + MINI_GAP + 'px' : '0px');\n  };\n\n  /** The picture box: \"Loading your rig\" (nothing drawn), or the drawn scene. */\n  Calculator.prototype.setLoading = function (on) {\n    this.pic.classList.toggle('byr-pic--loading', on);\n    this.pic.classList.toggle('byr-pic--painted', !on);\n  };\n\n  /** Swatch i (of this.swatchList): paint on, repaint; paint off, swap in that colour's real picture. */\n  Calculator.prototype.pickColor = function (i) {\n    var c = (this.swatchList || [])[i];\n    if (!c) return;\n    this.color = c;\n    Array.prototype.forEach.call(this.swatches.children, function (b, j) {\n      b.setAttribute('aria-checked', j === i ? 'true' : 'false');\n    });\n    this.colorName.textContent = c.name;\n    if (PAINT_ON) { this.renderPaint(); return; }\n    this.showColorPicture();\n  };\n\n  /**\n   * Paint off: the picked colour's real picture as the body. At the rig's\n   * width when loaded; else the phone size (preloaded on rig pick) now and\n   * the full size when it arrives; else the picture stays until it loads.\n   */\n  Calculator.prototype.showColorPicture = function () {\n    var self = this;\n    var c = this.color;\n    var real = this.row && realColors(this.data, this.row.image);\n    var id = c && real && real[c.name];\n    if (!id) { this.colorImg = null; this.renderPaint(); return; }\n    // the stock <img> under the canvas too (shown if the canvas can't be drawn)\n    this.img.src = colorPicUrl(IMAGE_BASE, id, 1600);\n    this.img.srcset = colorPicUrl(IMAGE_BASE, id, 800) + ' 800w, ' + colorPicUrl(IMAGE_BASE, id, 1600) + ' 1600w';\n    var need = this.rig ? this.rig.w : ((this.pic.clientWidth || 800) * (window.devicePixelRatio || 1) > 820 ? 1600 : 800);\n    var full = colorPic(id, need);\n    var small = colorPic(id, 800);\n    var show = function (img) {\n      if (self.color !== c || !img) return;\n      self.colorImg = img;\n      self.renderPaint();\n    };\n    if (full.img) { show(full.img); return; }\n    if (small.img) show(small.img);\n    full.p.then(function (img) { show(img || small.img); });\n  };\n\n  Calculator.prototype.inputs = function () {\n    var gear = [];\n    this.chips().forEach(function (c) { if (isOn(c) && c.value) gear.push(c.value); });\n    return {\n      gallons: this.gallons.value, other: this.other.el.value,\n      gear: gear, own: this.ownBox.hidden ? '' : this.ownInput.value,\n      gearLb: Object.assign({}, this.gearEdits),\n      noAutoSpare: this.spareDismissed,\n      opts: this.optSelects.map(function (s) { return parseInt(s.value, 10) || 0; })\n    };\n  };\n\n  /**\n   * The answer strip under the picture (owner picked Option B, 11/5): the\n   * rope size (as on the result card), three short lines, \"Shop it\" (the\n   * result card's main button: its link, ?from= included). a: { rope,\n   * heavy, used, url }, or null before a rig is picked: kept in place,\n   * muted, a dash and \"Pick your rig to get your rope size\", no button.\n   */\n  // The small picture at the top of the sticky result column (desktop, owner\n  // 11/11; fixed sizes 11/11 after Oleg's live check: it kept changing size\n  // as the header slid and the card changed, and sat near its smallest). Its\n  // height is one of MINI_STEPS, chosen from the window's height alone, once\n  // and again only on a resize. The room above the result card assumes the\n  // site's header is showing (MINI_HEADER_PX), and below the picture the card\n  // down to its second buy button (MINI_BUTTONS_PX, or MINI_BUTTONS_FROM_PX\n  // when the visit came from a product page: a step-up line sits between the\n  // buttons then). Measured on the draft at 400 px column width: 529 and 583.\n  var MINI_STEPS = [200, 160, 120];\n  var MINI_HEADER_PX = 130;      // the site's header (129 px), as if it were showing\n  var MINI_TOP_PX = 24;          // .byr-side's sticky top under it\n  var MINI_GAP = 16;             // .byr-side's gap\n  var MINI_BORDER = 2;           // the picture's 1 px border, top and bottom\n  var MINI_MARGIN = 8;           // kept clear under the second buy button\n  var MINI_BUTTONS_PX = 530;\n  var MINI_BUTTONS_FROM_PX = 585;\n  /**\n   * The small picture's height for a window vh px tall: the biggest of\n   * MINI_STEPS that leaves both buy buttons on screen with the header showing,\n   * or 0 (hidden). fromProduct: the visit came with ?from= (the card is taller).\n   */\n  function miniStep(vh, fromProduct) {\n    var below = fromProduct ? MINI_BUTTONS_FROM_PX : MINI_BUTTONS_PX;\n    for (var i = 0; i < MINI_STEPS.length; i++) {\n      var h = MINI_STEPS[i];\n      if (MINI_HEADER_PX + MINI_TOP_PX + h + MINI_BORDER + MINI_GAP + below + MINI_MARGIN <= vh) return h;\n    }\n    return 0;\n  }\n\n  /**\n   * The answer card's weight line (owner 11/11): the vehicle's own weight (step 1's\n   * \"Curb weight\" with any option picked, or the customer's \"Your weight\"), not\n   * the loaded weight; the rope beside it still comes from the loaded weight.\n   * \"19,600 lb break strength \\u00b7 4,600 lb vehicle weight\"; Heavy Duty: the weight only.\n   */\n  function answerLine(rope, heavy, vehicleLb) {\n    return (heavy ? '' : fmt(rope.mbs_lb) + ' lb break strength \\u00b7 ') + fmt(vehicleLb) + ' lb vehicle weight';\n  }\n\n  Calculator.prototype.renderAnswer = function (a) {\n    var self = this;\n    var box = this.answer;\n    if (!box) return;\n    box.innerHTML = '';\n    box.classList.toggle('byr-answer--empty', !a);\n    if (!a) {\n      box.appendChild(el('p', { class: 'byr-ans-size', 'aria-hidden': 'true', text: '\\u2014' }));\n      box.appendChild(el('div', { class: 'byr-ans-text' }, [el('p', { class: 'byr-ans-title', text: 'Pick your rig to get your rope size' })]));\n      return;\n    }\n    var who = this.peopleCard;\n    box.appendChild(el('p', { class: 'byr-ans-size' + (a.heavy ? ' byr-ans-size--heavy' : ''), text: a.rope.size }));\n    box.appendChild(el('div', { class: 'byr-ans-text' }, [\n      el('p', { class: 'byr-ans-title', text: a.heavy ? 'Heavy Duty recovery for this rig' : 'Kinetic-X rope for this rig' }),\n      el('p', { class: 'byr-ans-line', text: answerLine(a.rope, a.heavy, a.vehicle) }),\n      a.close ? el('p', { class: 'byr-ans-line byr-ans-close', text: a.close.text }) : null,\n      el('a', { class: 'byr-ans-more', href: '#', text: 'Add your gear below to fine-tune', onclick: function (e) {\n        if (e && e.preventDefault) e.preventDefault();\n        self.toStep2(who);\n      } })\n    ]));\n    box.appendChild(el('a', { class: 'byr-ans-shop', href: a.url, text: 'Shop it' }));\n  };\n\n  // The truck's height on a 1366-wide screen before the one-screen top\n  // section (owner 11/5): the picture never gets smaller than this to fit\n  var PIC_MIN_H = 268;\n  var SHOW_MIN_H = 110;   // the showroom loop's picture may go down to this\n  // the showroom picture's height on this page next to the headline (168 px at\n  // every desktop width, 1024 to 1920, measured 11/12): the embedded panel's\n  var EMBED_SHOW_H = 167.5;   // drawn 335 x 168, as here\n  /**\n   * Desktop (owner 11/5, one laptop screen): the right column (picture +\n   * colours + answer strip) is no taller than the left (headline, intro,\n   * \"Pick your rig\"). The picture keeps its 2:1 shape and is made shorter\n   * (and so narrower, centred on its panel) as far as that needs, but never\n   * below PIC_MIN_H (or its own full size, on a narrow desktop).\n   */\n  Calculator.prototype.fitStage = function () {\n    var pic = this.pic;\n    var text = this.root.querySelector('.byr-hero-text');\n    if (!pic || !this.stage) return;\n    pic.style.width = '';\n    if ((window.innerWidth || 0) < 990 || !text || !this.stage.parentNode) return;\n    var left = text.getBoundingClientRect().height;\n    var right = this.stage.getBoundingClientRect().height;\n    var h = pic.getBoundingClientRect().height;\n    if (!(h > 0) || right <= left + 0.5) return;\n    // a picked rig never below PIC_MIN_H; the showroom loop shrinks instead of the chips\n    // embedded (the kit builder's panel, owner 11/12: \"exactly the way Build Your\n    // Rig does\"): no headline beside it, so the showroom keeps this page's size\n    var floor = this.row ? PIC_MIN_H : (this.embed ? EMBED_SHOW_H : SHOW_MIN_H);\n    var want = Math.max(Math.min(h, floor), h - (right - left));\n    if (want < h - 0.5) pic.style.width = Math.floor(2 * want) + 'px';\n  };\n\n  /**\n   * Every screen size (Justin, #184 check: at 1288 x 715 the Chat launcher\n   * sat on the answer strip's \"Shop it\"): a site widget fixed in the lower\n   * half of the screen (a chat launcher) that covers one of our buttons, or\n   * comes within 12 px of it, is kept 12 px clear by moving the button, never\n   * the widget: the strip's \"Shop it\" moves left; a full-width button on the\n   * result card gets narrower from the right. Found by hit-testing round the\n   * button, so it works whatever the widget is built with.\n   */\n  var CLEAR_PX = 12;\n  Calculator.prototype.keepButtonsClear = function () {\n    if (!document.elementFromPoint) return;\n    var r = this.root;\n    var vw = window.innerWidth || 0;\n    var vh = window.innerHeight || 0;\n    var btns = Array.prototype.slice.call(r.querySelectorAll('.byr-ans-shop, .byr-buttons .byr-buy'));\n    // desktop (owner 11/11): the theme animates every property of a link\n    // (0.2 s), so a margin set here was being measured half-way through\n    // its own animation and the button stopped short of the launcher\n    if (vw >= 990) btns.forEach(function (b) { b.style.transition = 'none'; });\n    btns.forEach(function (b) { b.style.marginRight = ''; });\n    btns.forEach(function (b) {\n      var rc = b.getBoundingClientRect();\n      if (!(rc.width > 0) || rc.bottom < 0 || rc.top > vh) return;\n      var left = null;\n      for (var y = rc.top - CLEAR_PX; y <= rc.bottom + CLEAR_PX; y += 6) {\n        if (y < 0 || y >= vh) continue;\n        for (var x = rc.right + CLEAR_PX; x >= rc.left; x -= 6) {\n          if (x < 0 || x >= vw) continue;\n          var e = document.elementFromPoint(x, y);\n          if (!e || r.contains(e) || e === document.body || e === document.documentElement) continue;\n          // into an open shadow root (a web-component launcher)\n          for (var d = 0; d < 4 && e.shadowRoot && e.shadowRoot.elementFromPoint; d++) {\n            var inner = e.shadowRoot.elementFromPoint(x, y);\n            if (!inner || inner === e) break;\n            e = inner;\n          }\n          var box = null;\n          for (var n = e; n && n !== document.body && n !== document.documentElement; n = n.parentElement || (n.getRootNode && n.getRootNode().host) || null) {\n            var pos = window.getComputedStyle(n).position;\n            if (pos === 'fixed' || pos === 'sticky') { box = n.getBoundingClientRect(); break; }\n          }\n          var eb = e.getBoundingClientRect();\n          // desktop (owner 11/11, the small picture brings the buttons lower): a\n          // launcher whose fixed box is no help, full-screen or zero-size\n          // (Shopify Inbox's <shopify-chat>: its fixed runtime is 0 x 0, the\n          // button absolutely placed inside it): the biggest box between the\n          // hit and that fixed one, under half the screen, stands in (the chat\n          // button); the probe's step when there is none (a closed root)\n          if (box && vw >= 990 && y >= 0.5 * vh && (!(box.width > 0 && box.height > 0) || box.width > 0.5 * vw || box.height > 0.5 * vh)) {\n            var best = null;\n            for (var m = e; m && m !== n; m = m.parentElement || (m.getRootNode && m.getRootNode().host) || null) {\n              var mb = m.getBoundingClientRect();\n              if (mb.width > 0 && mb.height > 0 && mb.width <= 0.5 * vw && mb.height <= 0.5 * vh && (!best || mb.width * mb.height > best.width * best.height)) best = mb;\n            }\n            box = best || (e === n ? { left: x - 6, top: y, right: x, bottom: y, width: 6, height: 6 } : box);\n          }\n          if (!box) {\n            // a closed shadow root: the host has no box of its own but is hit, so\n            // what it shows is laid out on its own (fixed); taken at the probe\n            if ((eb.width > 0 && eb.height > 0) || y < 0.5 * vh) continue;\n            box = { left: x - 6, top: y, right: x, bottom: y, width: 6, height: 6 };\n          }\n          // only a widget in the lower half (not the site's header), smaller than half the screen (not a banner)\n          if (box.bottom < 0.5 * vh || box.width > 0.5 * vw || box.height > 0.5 * vh) continue;\n          var l = eb.width > 0 && eb.width <= box.width ? Math.min(eb.left, x) : Math.min(box.left, x);\n          if (left == null || l < left) left = l;\n        }\n      }\n      if (left == null) return;\n      var push = Math.ceil(rc.right - (left - CLEAR_PX));\n      if (push > 0 && push < rc.width + 0.6 * vw) b.style.marginRight = push + 'px';\n    });\n  };\n\n  /**\n   * The showroom loop (no rig picked): the first rig painted now, the rest\n   * once the page is idle (so first paint isn't slower), a crossfade every\n   * SHOWROOM_MS; held on the first with reduced motion; no change while the\n   * tab is hidden; stopped once a rig is picked, back if the picker is\n   * cleared. Drawn exactly as a picked rig in that colour: paint off, its\n   * real-colour picture (owner 11/6; the olive picture if it has none);\n   * paint on, its picture repainted through the mask.\n   */\n  Calculator.prototype.startShowroom = function () {\n    var self = this;\n    if (!this.showSlides || this.showOn) return;\n    this.showOn = true;\n    if (!this.shows) {\n      this.shows = showroomEntries(this.data).map(function (e) {\n        var cv = el('canvas', { class: 'byr-show-slide' });\n        self.showSlides.appendChild(cv);\n        return { e: e, canvas: cv, ready: false, busy: false };\n      });\n      this.showAt = -1;\n      this.showReduce = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);\n    }\n    // the first rig right away (a tick later, so a ?rig= link that picks a\n    // rig at once doesn't fetch it), the rest when the page is idle; with\n    // reduced motion only the first\n    var idle = window.requestIdleCallback || function (f) { return window.setTimeout(f, 1500); };\n    var next = function (i) {\n      if (i >= self.shows.length || self.showReduce || !self.showOn) return;\n      idle(function () { if (self.showOn) self.renderShow(i, function () { next(i + 1); }); }, { timeout: 5000 });\n    };\n    window.setTimeout(function () {\n      if (!self.showOn || !self.shows.length) return;\n      self.renderShow(0, function () { next(1); });\n    }, 0);\n    if (!this.showReduce && !this.showTimer) {\n      this.showTimer = window.setInterval(function () { self.tickShow(); }, SHOWROOM_MS);\n    }\n  };\n\n  Calculator.prototype.stopShowroom = function () {\n    this.showOn = false;\n    if (this.showTimer) { window.clearInterval(this.showTimer); this.showTimer = null; }\n  };\n\n  /** Paint one showroom rig into its own canvas (only while no rig is picked: the decoded picture is shared). */\n  Calculator.prototype.renderShow = function (i, done) {\n    var self = this;\n    var sh = this.shows[i];\n    var finish = function () { if (done) done(); };\n    if (!sh || sh.ready || sh.busy || this.row) { finish(); return; }\n    if (typeof ImageData === 'undefined') { finish(); return; }\n    sh.busy = true;\n    var need = (this.pic.clientWidth || 600) * (window.devicePixelRatio || 1);\n    var w = need > 820 ? 1600 : 800;\n    var real = !PAINT_ON && realColors(this.data, sh.e.v.image);\n    var id = real && real[sh.e.c.name];\n    var draw = function (body) {\n      sh.busy = false;\n      if (self.row || !body) { finish(); return; }   // a rig was picked meanwhile: leave its picture alone\n      var v = sh.e.v;\n      sh.canvas.width = w;\n      sh.canvas.height = w / 2;\n      var ctx = sh.canvas.getContext('2d');\n      var a = self.data.anchors && self.data.anchors[v.image];\n      if (a && a.fwc && v.wheelbase_in) {\n        var plan = planScene(v, a, [], self.data.part_images);\n        plan.paint = sh.e.c.hex;\n        drawScene(ctx, w, body, plan, function () { return null; });\n      } else {\n        ctx.drawImage(body, 0, 0, w, w / 2);\n      }\n      sh.ready = true;\n      if (self.showAt < 0) self.showSlide(i);\n      finish();\n    };\n    var fail = function () { sh.busy = false; finish(); };   // can't load or read it: the outline stays\n    if (id) { colorPic(id, w).p.then(draw, fail); return; }\n    getRig(sh.e.v.image, w).then(function (rig) {\n      if (PAINT_ON && !self.row) {\n        paint(rig.prep, rig.src.data, rig.out.data, sh.e.c.hex);\n        rig.body.getContext('2d').putImageData(rig.out, 0, 0);\n      }\n      draw(rig.body);\n    }, fail);\n  };\n\n  // The crossfade's length (the stylesheet's .byr-show-slide transition): the\n  // caption fades out over its first half, changes at the midpoint and fades\n  // back in with the new rig (Justin, #187 check: the new name used to show\n  // over the old picture for a second)\n  var SHOW_FADE_MS = 600;\n  Calculator.prototype.showSlide = function (i) {\n    var self = this;\n    var sh = this.shows[i];\n    if (!sh || !sh.ready) return;\n    var first = this.showAt < 0;\n    this.showAt = i;\n    this.shows.forEach(function (x, j) { x.canvas.classList.toggle('is-on', j === i); });\n    this.pic.classList.add('byr-pic--show');\n    var cap = this.showCap;\n    window.clearTimeout(this.capTimer);\n    if (first || this.showReduce) { cap.classList.remove('is-out'); cap.textContent = sh.e.caption; return; }\n    cap.classList.add('is-out');\n    this.capTimer = window.setTimeout(function () {\n      cap.textContent = sh.e.caption;\n      cap.classList.remove('is-out');\n      self.capTimer = null;\n    }, SHOW_FADE_MS / 2);\n  };\n\n  Calculator.prototype.tickShow = function () {\n    if (!this.showOn || this.row || (typeof document !== 'undefined' && document.hidden)) return;\n    var n = this.shows ? this.shows.length : 0;\n    for (var k = 1; k <= n; k++) {\n      var j = (this.showAt + k) % n;\n      if (this.shows[j].ready) { if (j !== this.showAt) this.showSlide(j); return; }\n    }\n  };\n\n  /**\n   * A quick-pick chip: Make and Model filled, then on to Year (focus and a\n   * short olive highlight; on a phone, Year scrolled into view).\n   */\n  Calculator.prototype.quickPick = function (q) {\n    var self = this;\n    this.make.el.value = q.make;\n    this.onMake();\n    this.model.el.value = q.model;\n    this.onModel();\n    var y = this.year;\n    var phone = (window.innerWidth || 0) < 990;\n    if (phone && y.wrap.scrollIntoView) y.wrap.scrollIntoView({ behavior: 'smooth', block: 'center' });\n    try { y.el.focus({ preventScroll: true }); } catch (ignore) { y.el.focus(); }   // eslint-disable-line no-unused-vars\n    y.wrap.classList.remove('byr-field--next');\n    void y.wrap.offsetWidth;   // restart the highlight\n    y.wrap.classList.add('byr-field--next');\n    window.clearTimeout(this.nextTimer);\n    this.nextTimer = window.setTimeout(function () { y.wrap.classList.remove('byr-field--next'); }, 1800);\n    self.fitStage();\n  };\n\n  /** Scroll to \"Who's in the rig\", clear of the site's header (and the pinned picture on a phone), and move focus there. */\n  Calculator.prototype.toStep2 = function (card) {\n    if (!card) return;\n    var top = parseFloat(this.root.style.getPropertyValue('--byr-sticky-top')) || 0;\n    var pinH = (window.innerWidth || 0) < 990 && this.pinEl ? this.pinEl.getBoundingClientRect().height : 0;\n    card.style.scrollMarginTop = Math.round(top + pinH + 12) + 'px';\n    card.scrollIntoView({ behavior: 'smooth', block: 'start' });\n    var h = card.querySelector('h2');\n    if (h) { h.setAttribute('tabindex', '-1'); try { h.focus({ preventScroll: true }); } catch (ignore) { h.focus(); } }   // eslint-disable-line no-unused-vars\n  };\n\n  /** \"+335 lb \u00B7 3 items\" */\n  function addLine(lb, items) {\n    var s = '+' + fmt(lb) + ' lb';\n    if (items != null && items > 0) s += ' \\u00b7 ' + items + (items === 1 ? ' item' : ' items');\n    return s;\n  }\n\n  /** The rope-band bar: the bands by lb range, the result's in olive, a marker at the weight. */\n  function bandBar(data, rope, weight) {\n    var bands = ropeBands(data);\n    if (!bands.length) return null;\n    var total = bands[bands.length - 1].to + 1;\n    var kids = function (label) {\n      return bands.map(function (b) {\n        var on = !!rope && b.rope.size === rope.size;\n        return el('span', {\n          class: (label ? 'byr-band-label' : 'byr-band') + (on ? ' is-on' : ''),\n          style: 'flex-grow:' + (b.to + 1 - b.from),\n          text: label ? BAND_LABELS[b.rope.size] || b.rope.size : null\n        });\n      });\n    };\n    var at = Math.max(0, Math.min(weight, total)) / total * 100;\n    return el('div', { class: 'byr-bands', 'aria-hidden': 'true' }, [\n      el('div', { class: 'byr-bands-track' }, [\n        el('div', { class: 'byr-bands-bar' }, kids(false)),\n        el('span', { class: 'byr-bands-mark', style: 'left:' + at.toFixed(2) + '%' })\n      ]),\n      el('div', { class: 'byr-bands-labels' }, kids(true))\n    ]);\n  }\n\n  Calculator.prototype.update = function () {\n    var self = this;\n    var out = this.result;\n    out.innerHTML = '';\n    var chips = this.chips();\n    if (!this.row) {\n      this.bar.hidden = true;\n      this.root.classList.remove('byr--bar');\n      this.badge.hidden = true;\n      this.how.hidden = true;\n      this.own.hidden = true;\n      this.optsBox.hidden = true;\n      this.mini.hidden = true;\n      this.root.style.setProperty('--byr-mini-space', '0px');\n      [this.tot1, this.tot2, this.tot3].forEach(function (t) { t.textContent = ''; });\n      chips.forEach(function (c) { c.classList.remove('byr-gchip--auto'); c.querySelector('.byr-gchip-why').textContent = ''; });\n      // the customer's weights stay through a rig change (the pickers pass through \"no rig\")\n      this.syncGearWeights(null);\n      out.appendChild(el('p', { class: 'byr-result-label', text: 'Your Kinetic-X rope' }));\n      out.appendChild(el('p', { class: 'byr-result-empty', text: 'Pick your rig to see your rope size.' }));\n      this.renderAnswer(null);\n      this.fitStage();\n      return;\n    }\n    this.renderScene();\n    var res = compute(this.data, this.row, this.inputs());\n    // the customer's weights last while their add-on is picked (unticked, the\n    // group's other choice, a rig that can't take it: dropped)\n    var pickedIds = res.gear.map(function (g) { return g.id; });\n    Object.keys(this.gearEdits).forEach(function (id) { if (pickedIds.indexOf(id) < 0) delete self.gearEdits[id]; });\n    if (pickedIds.indexOf('bumper_r_carrier') < 0) this.spareDismissed = false;   // unticked: its spare comes back next time\n    var rope = res.rope;\n    var p = res.parts;\n    var heavy = rope.rec_max_lb == null;\n\n    // the running weight on each step card\n    this.own.hidden = false;\n    // the option pickers: hidden while the customer's own weight is in use (it includes the bed)\n    this.optsBox.hidden = !this.optSelects.length || res.own;\n    this.tot1.textContent = (res.own ? 'Your weight ' : 'Curb weight ') + fmt(p.curb) + ' lb';\n    if (res.own) {\n      this.tot1.appendChild(el('button', {\n        type: 'button', class: 'byr-own-reset', text: 'reset',\n        'aria-label': 'Reset to this rig\\u2019s listed weight, ' + fmt(this.row.curb_lb) + ' lb',\n        onclick: function () { self.resetOwn(); }\n      }));\n    }\n    var typed = String(this.ownInput.value || '').trim();\n    this.ownMsg.textContent = !this.ownBox.hidden && (typed || this.ownInput.validity && this.ownInput.validity.badInput) && !res.own\n      ? 'Enter ' + fmt(OWN_LIMITS[0]) + ' to ' + fmt(OWN_LIMITS[1]) + ' lb. Until then we use ' + fmt(this.row.curb_lb) + ' lb.' : '';\n    this.tot2.textContent = addLine(p.driver + p.fuel);\n    this.tot3.textContent = addLine(p.gear + p.other, res.gear.length);\n    // gear the page adds on its own: a dashed olive chip with the reason\n    var why = {};\n    res.gear.forEach(function (g) { if (g.auto) why[g.id] = g.id === 'bedrack' ? 'added for the tent' : 'added for the swing-out'; });\n    var spareAdded = !!why.spare;\n    chips.forEach(function (c) {\n      var w = why[c.value];\n      c.classList.toggle('byr-gchip--auto', !!w);\n      // the swing-out says what it brings (owner 11/11): \"plus the spare\" while the page adds it\n      var note = w || (c.value === 'bumper_r_carrier' && spareAdded ? 'plus the spare' : '');\n      c.querySelector('.byr-gchip-why').textContent = note ? '\\u00a0\\u00b7 ' + note : '';   // nbsp: a flex item drops a leading space\n    });\n    this.lastRes = res;\n    this.syncGearWeights(res);\n\n    // Layout round 1 (11/4): the Titan kit with this rope (30 ft) first, the\n    // rope under it, the Ultimate kit as a text link; above 1.25\" only the rope\n    // ?from=<product handle> (owner approved): that product in this size is\n    // the main button, the Titan as a step-up link (unless it is the Titan),\n    // no Ultimate link when it came from an Ultimate (kitLinks)\n    var kit = heavy ? null : kitLinks(rope, this.from, this.fromProduct);\n    var buttons = [];\n    var mainUrl = kit ? kit.main.url : rope.url;\n    if (kit) buttons.push(el('a', { class: 'byr-buy byr-buy--main byr-kit', href: kit.main.url, text: kit.main.text }));\n    if (kit && kit.step) buttons.push(el('a', { class: 'byr-alt', href: kit.step, text: 'Or step up to the Titan Recovery Kit' }));\n    if (!kit || kit.rope) {\n      buttons.push(el('a', {\n        class: 'byr-buy ' + (kit ? 'byr-buy--second' : 'byr-buy--main'), href: rope.url,\n        text: heavy ? 'Shop Heavy Duty recovery gear' : 'Shop the ' + rope.size + ' rope'\n      }));\n    }\n    if (kit && kit.ultimate) buttons.push(el('a', { class: 'byr-alt', href: kit.ultimate, text: 'Or the Ultimate Recovery Kit' }));\n    // \"Build a kit for this rig\" (owner 11/12, draft): the kit builder with\n    // this rig, its add-ons and the loaded weight (the link carries the rig;\n    // the builder also finds it remembered, saveRig)\n    var kitUrl = this.root.getAttribute('data-kit-url');\n    if (kitUrl) buttons.push(el('a', { class: 'byr-buy byr-buy--second byr-kitlink', href: kitUrl + this.linkQuery(), text: KIT_BUTTON }));\n    // Embedded (the kit builder's panel): one button, \"Use this rig\", in place of all of them\n    if (this.embed) buttons = [el('button', { type: 'button', class: 'byr-buy byr-buy--main byr-use', text: USE_BUTTON, onclick: function () { self.use(); } })];\n\n    out.appendChild(el('p', { class: 'byr-result-label', text: 'Your Kinetic-X rope' }));\n    out.appendChild(el('div', { class: 'byr-size-row' }, [\n      el('p', { class: 'byr-size' + (heavy ? ' byr-size--heavy' : ''), text: rope.size }),\n      heavy ? null : el('p', { class: 'byr-size-side' }, ['\\u00d7 30 ft', el('br'), fmt(rope.mbs_lb) + ' lb break strength'])\n    ]));\n    out.appendChild(el('p', { class: 'byr-loaded' }, [el('span', { text: 'Your rig, loaded' }), el('strong', { text: fmt(res.used) + ' lb' })]));\n    out.appendChild(bandBar(this.data, heavy ? null : rope, res.used));\n    out.appendChild(el('p', { class: 'byr-band-line', text: bandLine(this.data, rope, res.used) }));\n    out.appendChild(el('div', { class: 'byr-buttons' }, buttons));\n    if (!this.embed) out.appendChild(el('p', { class: 'byr-trust', text: TRUST_LINE }));\n\n    // the pill on the picture and the phone bar\n    this.badge.hidden = false;\n    this.badge.textContent = heavy ? 'Heavy Duty' : rope.size + ' rope';\n    this.badge.setAttribute('aria-label', 'Your rope: ' + this.badge.textContent + '. Go to the result');\n    this.bar.hidden = false;\n    this.root.classList.add('byr--bar');\n    this.barValue.innerHTML = '';\n    this.barValue.appendChild(document.createTextNode(rope.size + ' '));\n    this.barValue.appendChild(el('span', { class: 'byr-bar-lb', text: '\\u00b7 ' + fmt(res.used) + ' lb' }));\n    this.barShop.href = mainUrl;\n    // remembered for the kit builder (owner 11/12: nobody enters a rig twice);\n    // embedded, only once the customer says \"Use this rig\"\n    if (!this.embed) saveRig(this.summary());\n    // the rope, the link and the close-call note follow the loaded weight; the line names the vehicle's weight\n    this.renderAnswer({ rope: rope, heavy: heavy, used: res.used, vehicle: p.curb, url: mainUrl, close: closeCall(this.data, res.used) });\n    this.fitStage();\n    this.keepButtonsClear();\n\n    // \"How we got X lb\", closed until opened (it stays as the customer left it)\n    var rows = [];\n    var curbNote = [];\n    if (this.row.add_lb) curbNote.push(modelLabel(this.row.base_model) + ' row ' + fmt(this.row.base_curb_lb) + ' lb + ' + fmt(this.row.add_lb) + ' lb');\n    if (this.row.verified === 'E') curbNote.push('weight estimated');\n    var curbName = res.own ? 'Your weight'\n      : 'Curb weight' + (res.opts.length ? ' (' + res.opts.map(function (o) { return optionLabel(o.group, o.choice); }).join(', ') + ')' : '');\n    rows.push([curbName, fmt(p.curb) + ' lb', res.own ? null : curbNote.join(' \\u00b7 ') || null]);\n    rows.push(['Baseline gear', fmt(p.baseline) + ' lb', null]);\n    rows.push(['Driver', fmt(p.driver) + ' lb', null]);\n    rows.push(['Fuel/water (' + fmt(res.inputs.gallons) + ' gal)', fmt(p.fuel) + ' lb', null]);\n    // one gear item a line, each with its weight (layout round 1: the\n    // names have commas in them, \"Fridge, stocked\")\n    if (!res.gear.length) rows.push(['Gear', '0 lb', null]);\n    else {\n      rows.push(['Gear', '', null, 'byr-group']);\n      res.gear.forEach(function (g) {\n        rows.push([g.label, fmt(g.lb) + ' lb' + (g.edited ? ' (your number)' : ''), why[g.id] && g.auto ? why[g.id] : null, 'byr-sub']);\n      });\n    }\n    rows.push(['Other', fmt(p.other) + ' lb', null]);\n    var tbody = el('tbody');\n    rows.forEach(function (rw) {\n      var th = el('th', { scope: 'row' }, [rw[0]]);\n      if (rw[2]) th.appendChild(el('small', { class: 'byr-small', text: rw[2] }));\n      tbody.appendChild(el('tr', rw[3] ? { class: rw[3] } : {}, [th, el('td', { text: rw[1] })]));\n    });\n    var tfoot = el('tfoot', {}, [el('tr', {}, [el('th', { scope: 'row', text: 'Weight used' }), el('td', { text: fmt(res.used) + ' lb' })])]);\n    this.how.hidden = false;\n    this.howSum.textContent = 'How we got ' + fmt(res.used) + ' lb';\n    this.howBody.innerHTML = '';\n    this.howBody.appendChild(el('table', { class: 'byr-breakdown' }, [tbody, tfoot]));\n    this.syncMini();   // a new rig hides the last one's small picture until it is drawn (its size stays)\n    if (self.syncStickyTop) self.syncStickyTop();   // the card's height changed: pin or not\n  };\n\n  /**\n   * The chips' weights and their edit targets (owner 11/11): each chip reads\n   * its weight on this rig (lb_by_size; the customer's number, dotted\n   * underline, when edited); a picked or page-added chip gets the weight's own\n   * tap target, laid over the \"+N\" (at least 40 px tall). res: compute's\n   * result, or null before a rig is picked.\n   */\n  Calculator.prototype.syncGearWeights = function (res) {\n    var self = this;\n    var row = this.row;\n    var byId = {};\n    this.data.gear.forEach(function (g) { byId[g.id] = g; });\n    var used = {};\n    ((res && res.gear) || []).forEach(function (g) { used[g.id] = g; });\n    var onIds = Object.keys(used);   // a tire upgrade sets the spare's size (lb_by_tire_in)\n    Array.prototype.forEach.call(this.root.querySelectorAll('[data-chip]'), function (box) {\n      var id = box.getAttribute('data-chip');\n      var g = byId[id];\n      if (!g) return;\n      var u = used[id];\n      var lb = u ? u.lb : gearLb(g, row, onIds);\n      var n = box.querySelector('.byr-gchip-n');\n      var txt = '+' + fmt(lb);\n      if (n.textContent !== txt) n.textContent = txt;\n      box.classList.toggle('byr-gchip--edited', !!(u && u.edited));\n      var edit = box.querySelector('.byr-gchip-edit');\n      edit.hidden = !u;\n      if (!u) return;\n      edit.setAttribute('aria-label', 'Change the weight of ' + g.label + ', ' + fmt(lb) + ' pounds' + (u.edited ? ' (your number)' : ''));\n      self.placeGearEdit(box, edit);\n    });\n  };\n\n  /** Lay a chip's weight target over its \"+N\": at least 40 px tall, to the chip's end. */\n  Calculator.prototype.placeGearEdit = function (box, target) {\n    var lbEl = box.querySelector('.byr-gchip-lb');\n    var br = box.getBoundingClientRect();\n    var r = lbEl.getBoundingClientRect();\n    if (!br.width || !r.width) return;\n    var left = Math.max(0, r.left - br.left - 6);\n    var right = br.right - r.right < 28 ? br.width : Math.min(br.width, r.right - br.left + 6);\n    var h = Math.min(br.height, Math.max(40, r.height + 16));\n    var top = Math.max(0, Math.min(br.height - h, r.top - br.top + r.height / 2 - h / 2));\n    var w = right - left;\n    target.style.left = Math.round(left) + 'px';\n    target.style.top = Math.round(top) + 'px';\n    target.style.width = Math.round(w) + 'px';\n    target.style.height = Math.round(h) + 'px';\n  };\n\n  /**\n   * The weight card (owner 11/11, coder_brief_byr_phone_weight_editor.md: on\n   * an iPhone the number pad has no Done key, so nothing on screen saved the\n   * field over the chip). One card for every add-on: \"Your weight\", the\n   * add-on's full name, a large number field with \"lb\", Save, \"Use our weight\n   * (N lb)\" and a close (X). Phones (989 px and under, CSS): fixed to the top\n   * of the screen over a dimmed page, the rope bar and the chat bubble hidden\n   * while it's open, so where the keypad sits never matters. Laptops: a\n   * popover under the chip. Built once; openGearEdit fills it.\n   */\n  Calculator.prototype.buildGearCard = function () {\n    var self = this;\n    var nameId = 'byr-lbcard-name-' + (++uid);\n    var rangeId = 'byr-lbcard-range-' + (++uid);\n    this.lbName = el('p', { class: 'byr-lbcard-name', id: nameId });\n    // not a login, payment or address field: everything that might keep the\n    // phone's AutoFill strip away (iOS may still show it; it can't be forced off)\n    this.lbInput = el('input', {\n      type: 'text', class: 'byr-lbcard-input', inputmode: 'numeric', pattern: '[0-9]*', maxlength: '5',\n      autocomplete: 'off', autocorrect: 'off', autocapitalize: 'off', spellcheck: 'false', name: 'byr-addon-lb',\n      'data-form-type': 'other', 'data-lpignore': 'true', 'data-1p-ignore': 'true', 'aria-describedby': rangeId,\n      'aria-label': 'Weight in pounds, ' + fmt(GEAR_LB_LIMITS[0]) + ' to ' + fmt(GEAR_LB_LIMITS[1])\n    });\n    this.lbRange = el('p', { class: 'byr-lbcard-range', id: rangeId, hidden: true,\n      text: fmt(GEAR_LB_LIMITS[0]) + ' to ' + fmt(GEAR_LB_LIMITS[1]) + ' lb' });\n    this.lbSave = el('button', { type: 'button', class: 'byr-lbcard-save', text: 'Save', onclick: function () { self.closeGearEdit('save'); } });\n    this.lbOurs = el('button', { type: 'button', class: 'byr-lbcard-ours', onclick: function () { self.closeGearEdit('ours'); } });\n    this.lbCard = el('div', { class: 'byr-lbcard', role: 'dialog', 'aria-labelledby': nameId, hidden: true }, [\n      el('button', { type: 'button', class: 'byr-lbcard-x', 'aria-label': 'Close without saving', text: '\\u00d7',\n        onclick: function () { self.closeGearEdit('cancel'); } }),\n      el('p', { class: 'byr-lbcard-kicker', text: 'Your weight' }),\n      this.lbName,\n      el('div', { class: 'byr-lbcard-row' }, [\n        el('label', { class: 'byr-lbcard-field' }, [this.lbInput, el('span', { class: 'byr-lbcard-unit', text: 'lb' })]),\n        this.lbSave\n      ]),\n      this.lbRange,\n      this.lbOurs\n    ]);\n    // a phone's dimmed page takes the tap itself (on click, so the release\n    // can't land on a chip underneath once it's gone)\n    this.lbScrim = el('div', { class: 'byr-lbscrim', hidden: true, 'aria-hidden': 'true',\n      onclick: function (e) { e.preventDefault(); e.stopPropagation(); self.closeGearEdit('outside'); } });\n    this.root.appendChild(this.lbScrim);\n    this.lbInput.addEventListener('input', function () { self.checkGearEdit(); });\n    this.lbInput.addEventListener('keydown', function (e) {\n      if (e.key === 'Enter') { e.preventDefault(); if (!self.lbSave.disabled) self.closeGearEdit('save'); }\n      else if (e.key === 'Escape' || e.key === 'Esc') { e.preventDefault(); self.closeGearEdit('cancel'); }\n    });\n    this.lbCard.addEventListener('keydown', function (e) {\n      if ((e.key === 'Escape' || e.key === 'Esc') && e.target !== self.lbInput) { e.preventDefault(); self.closeGearEdit('cancel'); }\n    });\n    // a tap outside the card keeps a valid, changed number (the same as Save);\n    // otherwise it just closes. The field losing focus (the keypad put away) does nothing.\n    this.onLbOutside = function (e) {\n      if (!self.gearEditing || self.lbCard.contains(e.target) || e.target === self.lbScrim) return;\n      var edit = e.target.closest && e.target.closest('.byr-gchip-edit');\n      if (edit && edit.getAttribute('data-edit') === self.gearEditing) { e.preventDefault(); return; }   // its own weight: stays open\n      self.closeGearEdit('outside');\n    };\n  };\n\n  /** The card's number now: { typed, n (a valid weight or null), ok (Save allowed: empty or valid) }. */\n  Calculator.prototype.gearEditValue = function () {\n    var typed = String(this.lbInput.value || '').trim();\n    var n = gearLbValue(typed);\n    return { typed: typed, n: n, ok: typed === '' || n != null };\n  };\n\n  /** Save on or off as the number allows; out of range, \"1 to 5,000 lb\" shows. */\n  Calculator.prototype.checkGearEdit = function () {\n    var v = this.gearEditValue();\n    this.lbSave.disabled = !v.ok;\n    this.lbRange.hidden = v.ok;\n    this.lbCard.classList.toggle('byr-lbcard--bad', !v.ok);\n  };\n\n  /** Open the weight card for a picked (or page-added) add-on, its number selected. */\n  Calculator.prototype.openGearEdit = function (id) {\n    var box = this.root.querySelector('[data-chip=\"' + id + '\"]');\n    var g = null;\n    this.data.gear.forEach(function (x) { if (x.id === id) g = x; });\n    var u = null;\n    ((this.lastRes && this.lastRes.gear) || []).forEach(function (x) { if (x.id === id) u = x; });\n    if (!box || !g || !u) return;\n    if (this.gearEditing) this.closeGearEdit('cancel');\n    this.gearEditing = id;\n    this.gearEditOurs = u.edited ? u.our_lb : u.lb;\n    this.gearEditNow = u.lb;\n    this.lbName.textContent = g.label;\n    this.lbOurs.textContent = 'Use our weight (' + fmt(this.gearEditOurs) + ' lb)';\n    this.lbInput.value = String(u.lb);\n    this.checkGearEdit();\n    box.appendChild(this.lbCard);   // a popover under the chip (desktop); fixed at the top on a phone\n    this.lbCard.hidden = false;\n    this.placeGearCard(box);\n    this.lbScrim.hidden = false;\n    this.root.classList.add('byr--lbopen');\n    if (document.documentElement) document.documentElement.classList.add('byr-lbopen');   // the chat bubble lives outside the section\n    document.addEventListener('pointerdown', this.onLbOutside, true);\n    try { this.lbInput.focus({ preventScroll: true }); } catch (ignore) { this.lbInput.focus(); }   // eslint-disable-line no-unused-vars\n    try { this.lbInput.select(); } catch (ignore) { /* not every field selects */ }   // eslint-disable-line no-unused-vars\n  };\n\n  /** Desktop: the popover under the chip, kept inside the row (phones: CSS fixes it to the top). */\n  Calculator.prototype.placeGearCard = function (box) {\n    var card = this.lbCard;\n    card.style.left = '0px';\n    if (window.innerWidth < 990) return;\n    var row = box.parentNode.getBoundingClientRect();\n    var br = box.getBoundingClientRect();\n    var w = card.offsetWidth;\n    var left = Math.min(0, row.right - br.left - w);   // run left of the chip when the row ends first\n    card.style.left = Math.round(Math.max(row.left - br.left, left)) + 'px';\n  };\n\n  /**\n   * Close the weight card. 'save': a valid number is the customer's (our own\n   * number, or an empty field, is no edit); 'ours': our weight back; 'cancel'\n   * (X, Escape): nothing changes; 'outside' (a tap away): a valid, changed\n   * number is saved, anything else just closes. Focus goes back to the\n   * chip's weight button.\n   */\n  Calculator.prototype.closeGearEdit = function (how) {\n    var id = this.gearEditing;\n    if (!id) return;\n    var v = this.gearEditValue();\n    if (how === 'ours' || (how === 'save' && v.typed === '')) delete this.gearEdits[id];\n    else if ((how === 'save' || how === 'outside') && v.n != null && (how === 'save' || v.n !== this.gearEditNow)) {\n      if (v.n === this.gearEditOurs) delete this.gearEdits[id];   // our own number: not an edit\n      else this.gearEdits[id] = v.n;\n    }\n    this.gearEditing = null;\n    document.removeEventListener('pointerdown', this.onLbOutside, true);\n    this.lbCard.hidden = true;\n    this.lbScrim.hidden = true;\n    this.root.classList.remove('byr--lbopen');\n    if (document.documentElement) document.documentElement.classList.remove('byr-lbopen');\n    try { this.lbInput.blur(); } catch (ignore) { /* closed */ }   // eslint-disable-line no-unused-vars\n    this.update();\n    var edit = this.root.querySelector('[data-edit=\"' + id + '\"]');\n    if (edit && !edit.hidden) {\n      try { edit.focus({ preventScroll: true }); } catch (ignore) { edit.focus(); }   // eslint-disable-line no-unused-vars\n    }\n  };\n\n  /**\n   * The rig as the kit builder shows it (owner 11/12): { name: \"2027 Toyota\n   * Tacoma\", lb: the loaded weight, size: the rope's size (\"Heavy Duty\" over\n   * the top line), heavy, q: linkQuery() }, or null before a rig is picked.\n   */\n  Calculator.prototype.summary = function () {\n    var res = this.lastRes;\n    if (!this.row || !res) return null;\n    var y = this.year.el.value;\n    return {\n      name: (y ? y + ' ' : '') + this.row.make + ' ' + modelLabel(this.row.model),\n      lb: res.used, size: res.rope.size, heavy: res.rope.rec_max_lb == null, q: this.linkQuery()\n    };\n  };\n\n  /** Embedded: \"Use this rig\" hands the rig to the page round it (a byr:use event, detail: summary()). */\n  Calculator.prototype.use = function () {\n    var s = this.summary();\n    if (!s || typeof CustomEvent !== 'function') return;\n    this.root.dispatchEvent(new CustomEvent('byr:use', { bubbles: true, detail: s }));\n  };\n\n  /**\n   * The review link's query for what's on the page now: rig, year, gear and\n   * the customer's weights (&gearlb=, only when there are some), options, own\n   * weight, from. '' before a rig is picked.\n   */\n  Calculator.prototype.linkQuery = function () {\n    if (!this.row) return '';\n    var inp = this.inputs();\n    var q = ['rig=' + encodeURIComponent(this.row.id), 'year=' + encodeURIComponent(this.year.el.value)];\n    if (inp.gear.length) q.push('gear=' + inp.gear.join(','));\n    var lbq = gearLbQuery(inp.gearLb);\n    if (lbq) q.push('gearlb=' + lbq);\n    var oq = optionQuery(this.row, inp.opts);\n    if (oq) q.push('opt=' + encodeURIComponent(oq));\n    var w = ownWeight(inp.own);\n    if (w != null) q.push('weight=' + w);\n    if (this.from) q.push('from=' + encodeURIComponent(this.from));\n    return '?' + q.join('&');\n  };\n\n  /**\n   * Open on a given rig and gear, for review links and screenshots:\n   * ?rig=<vehicle id>&gear=id,id[&gearlb=id:<lb>,...][&color=<n>][&year=<yyyy>][&opt=bed:<n>,engine:<n>][&weight=<lb>] (the newest year of\n   * the row when no year is given, or one the row doesn't cover). Unknown ids are ignored.\n   */\n  Calculator.prototype.prefill = function (q) {\n    var self = this;\n    var data = this.data;\n    var id = q.get('rig');\n    var v = null;\n    data.vehicles.forEach(function (x) { if (x.id === id) v = x; });\n    if (!v) return;\n    this.make.el.value = v.make;\n    this.onMake();\n    this.model.el.value = v.model;\n    this.onModel();\n    var ys = years(data, v.make, v.model).filter(function (y) { return y >= v.year_from && y <= v.year_to; });\n    if (!ys.length) return;\n    var yq = parseInt(q.get('year'), 10);\n    this.year.el.value = String(ys.indexOf(yq) >= 0 ? yq : Math.max.apply(null, ys));\n    this.onYear();\n    this.trim.el.value = v.id;\n    var gear = (q.get('gear') || '').split(',');\n    this.chips().forEach(function (c) { if (c.value && gear.indexOf(c.value) >= 0) self.pickGear(c); });\n    // &gearlb=<id>:<lb>,...: the customer's own weights, for ids also in &gear= (gearLbQuery writes it)\n    this.gearEdits = parseGearLb(q.get('gearlb'), gear);\n    this.onTrim();\n    // &opt=bed:1[,engine:0]: a factory option by its group's name (any case;\n    // \"battery-trim\" or \"Battery / trim\" alike, see optionKey) and the choice's\n    // place in the list (0 = the first); optionQuery writes it\n    var optQ = String(q.get('opt') || '');\n    if (optQ && this.row && this.row.options) {\n      var groups = this.row.options.map(function (g) { return optionKey(g.group); });\n      optQ.split(',').forEach(function (part) {\n        var m = /^\\s*([^:]+):(\\d+)\\s*$/.exec(part);\n        var k = m ? groups.indexOf(optionKey(m[1])) : -1;\n        var i = m ? parseInt(m[2], 10) : -1;\n        if (k >= 0 && i < self.row.options[k].choices.length) self.optSelects[k].value = String(i);\n      });\n      this.update();\n    }\n    // &weight=<lb>: the customer's own rig weight, when it's in range\n    var w = ownWeight(q.get('weight'));\n    if (w != null) {\n      this.ownInput.value = String(w);\n      this.openOwn();\n    }\n    var c = parseInt(q.get('color'), 10);\n    // ?color=<n>: the n-th colour of the rig's colour set, if it has a swatch\n    var set = this.row && this.data.colorsets[this.row.colorset];\n    var want = c >= 0 && set && set.colors[c];\n    if (want && (PAINT_ON ? c > 0 : true)) this.pickColor((this.swatchList || []).indexOf(want));\n  };\n\n  /**\n   * The headline's two lines never run off the column (Justin, #181 check:\n   * before Barlow Condensed loads, the wider fallback ran off the right\n   * edge). Back to the stylesheet's size (the most it may be), then, if a\n   * line's text is wider than the column, down until the widest fits.\n   */\n  function fitTitles() {\n    if (typeof document === 'undefined' || !document.createRange) return;\n    Array.prototype.forEach.call(document.querySelectorAll('.byr-wrap .byr-title'), function (h) {\n      h.style.fontSize = '';\n      var avail = h.clientWidth;\n      if (!(avail > 0)) return;\n      var widest = 0;\n      Array.prototype.forEach.call(h.querySelectorAll('.byr-title-line'), function (line) {\n        var rg = document.createRange();\n        rg.selectNodeContents(line);\n        widest = Math.max(widest, rg.getBoundingClientRect().width);\n      });\n      if (widest <= avail) return;\n      var size = parseFloat(window.getComputedStyle(h).fontSize);\n      if (size > 0) h.style.fontSize = Math.max(12, Math.floor(size * (avail - 1) / widest * 10) / 10) + 'px';\n    });\n  }\n\n  /**\n   * Start a calculator on rootEl. data: rig_data.json already read (the kit\n   * builder's panel), else fetched from data-src. Embedded, the page round it\n   * prefills it (prefill), not this page's own link.\n   */\n  function init(rootEl, data0) {\n    var src = rootEl.getAttribute('data-src');\n    BUILD = rootEl.getAttribute('data-build') || '';\n    rootEl.classList.add('byr--loading');\n    return (data0 ? Promise.resolve(data0) : fetch(src, { credentials: 'same-origin' })\n      .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }))\n      .then(function (data) {\n        rootEl.classList.remove('byr--loading');\n        rootEl.byr = new Calculator(rootEl, data);\n        if (!rootEl.hasAttribute('data-byr-embed') && typeof URLSearchParams !== 'undefined' && window.location && window.location.search.indexOf('rig=') >= 0) {\n          rootEl.byr.prefill(new URLSearchParams(window.location.search));\n        }\n        return rootEl.byr;\n      })\n      .catch(function () {\n        rootEl.classList.remove('byr--loading');\n        var app = rootEl.querySelector('[data-byr-app]') || rootEl;\n        app.innerHTML = '';\n        app.appendChild(el('p', { class: 'byr-error', text: 'The rope calculator didn\\u2019t load. Please refresh the page.' }));\n        return null;\n      });\n  }\n\n  /** A calculator on an element added after the page loaded (the kit builder's panel): -> a promise of its Calculator. */\n  function mount(rootEl, data) {\n    if (rootEl.byr) return Promise.resolve(rootEl.byr);\n    if (!rootEl.byrStart) rootEl.byrStart = init(rootEl, data);\n    return rootEl.byrStart;\n  }\n\n  root.BuildYourRig = {\n    IMAGE_BASE: IMAGE_BASE, SIZE_NOTE: SIZE_NOTE, DRIVER_NOTE: DRIVER_NOTE, GEAR_EDIT_HELP: GEAR_EDIT_HELP, GEAR_LB_LIMITS: GEAR_LB_LIMITS, gearLbValue: gearLbValue, parseGearLb: parseGearLb, gearLbQuery: gearLbQuery,\n    makes: makes, models: models, years: years, trims: trims,\n    cleanInputs: cleanInputs, pickRope: pickRope, compute: compute, modelLabel: modelLabel,\n    mount: mount, saveRig: saveRig, readRig: readRig, RIG_KEY: RIG_KEY, KIT_BUTTON: KIT_BUTTON, USE_BUTTON: USE_BUTTON,\n    ownWeight: ownWeight, OWN_LIMITS: OWN_LIMITS, closeCall: closeCall, answerLine: answerLine, miniStep: miniStep, MINI_STEPS: MINI_STEPS, rowOptions: rowOptions, optionLabel: optionLabel, optionKey: optionKey, optionQuery: optionQuery,\n    prepPaint: prepPaint, paint: paint, paintLightness: paintLightness, smoothLuma: smoothLuma, planScene: planScene, drawScene: drawScene, BoundsCtx: BoundsCtx, sceneBox: sceneBox, fitScene: fitScene, maxSceneBox: maxSceneBox, maxSceneBoxes: maxSceneBoxes, hasPlow: hasPlow, cleanMaxGear: cleanMaxGear, miniView: miniView, MINI_PAD: MINI_PAD, FIT_MARGIN: FIT_MARGIN, TIRES: TIRES, TENTS: TENTS, sizeClass: sizeClass, gearSize: gearSize, gearLb: gearLb, tireSizeIn: tireSizeIn, lbForTire: lbForTire, FRONT_BUMPERS: FRONT_BUMPERS, frontBumper: frontBumper, partPicture: partPicture, frontBumperBand: frontBumperBand, rearBumperBand: rearBumperBand, REAR_TOP_OVER_TYRE_IN: REAR_TOP_OVER_TYRE_IN, bumperWingLeft: bumperWingLeft, bedCovered: bedCovered, BED_RAIL_GEAR: BED_RAIL_GEAR, MASK_FILE: MASK_FILE, measureFlatbed: measureFlatbed, flatbedSlices: flatbedSlices, measureCabover: measureCabover, fitCabover: fitCabover, measureRocker: measureRocker, measureRearBumper: measureRearBumper, measureCabRoof: measureCabRoof, PLOW: PLOW, PLOW_ROOM_IN: PLOW_ROOM_IN, PICKUP_ONLY: PICKUP_ONLY, maskUrl: function (image) { return maskUrl(IMAGE_BASE, image); }, maskFileFor: maskFileFor, setMaskOverrides: setMaskOverrides, setFileAliases: setFileAliases, greyPicture: greyPicture, remapGrey: remapGrey, remapPicture: remapPicture, hexRgb: hexRgb, SLIDEIN_GREY: SLIDEIN_GREY, PART: PART, setBuild: function (b) { BUILD = b || ''; },\n    PAINT_ON: PAINT_ON, OLIVE_PAINT: OLIVE_PAINT, realColors: realColors, swatchColors: swatchColors, colorPicUrl: colorPicUrl,\n    tireMax: tireMax, tireFits: tireFits, gearFits: gearFits, SHOWROOM: SHOWROOM, QUICK_PICKS: QUICK_PICKS, showroomEntries: showroomEntries, clearOpenings: clearOpenings, OPENING_PARTS: OPENING_PARTS, gearSections: gearSections, GEAR_SECTIONS: GEAR_SECTIONS, ropeBands: ropeBands, bandLine: bandLine, BAND_LABELS: BAND_LABELS, TRUST_LINE: TRUST_LINE, HEAVY_LINE: HEAVY_LINE, fromHandle: fromHandle, sizeVariantUrl: sizeVariantUrl, kitLinks: kitLinks, FROM_HANDLES: FROM_HANDLES\n  };\n\n  if (typeof document !== 'undefined') {\n    var start = function () {\n      fitTitles();\n      Array.prototype.forEach.call(document.querySelectorAll('[data-byr]'), function (n) {\n        if (!n.byr && !n.classList.contains('byr--loading')) init(n);\n      });\n    };\n    // the headline, whatever font is showing: now, at the next paint, when\n    // the fonts are in, on resize\n    var fitQueued = false;\n    var queueFit = function () {\n      var later = window.requestAnimationFrame || window.setTimeout;\n      if (fitQueued || typeof later !== 'function') return;\n      fitQueued = true;\n      later(function () { fitQueued = false; fitTitles(); });\n    };\n    queueFit();\n    if (document.fonts) {\n      if (document.fonts.ready && document.fonts.ready.then) document.fonts.ready.then(queueFit);\n      if (document.fonts.addEventListener) document.fonts.addEventListener('loadingdone', queueFit);\n    }\n    if (typeof window.addEventListener === 'function') {\n      window.addEventListener('resize', queueFit);\n      window.addEventListener('load', queueFit);\n    }\n    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start);\n    else start();\n  }\n})(typeof window !== 'undefined' ? window : this);\n"],
  "mappings": "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",
  "names": ["x", "y", "ptop", "mount", "bx0", "bx1", "room", "h", "paint", "i", "b", "fitQueued", "c"]
}
