{"version":3,"sources":["building-kubes.mjs"],"sourcesContent":["// BUILDING KUBES (the owner's proposal of 42 ideas, confirmed Oct 13 02:23 UTC: \"confirmed building kubes. go ahead and\n// implement\"). Twenty-four were approved: crafted kubes for building with, each cut, cast, smelted or assembled from a\n// material the game already has, from the first day (a Toolbench and a Mineral) to the late game (a Quantum Assembler,\n// Titan Plate and Cor). Each is a kube and, but for the two lights, a bit, like every material (\"kubes and bits for\n// both\", the biolith decision).\n//\n// THE RULE IS DATA, THE RECIPES ARE WRITTEN OUT (as biolith.mjs does, for the same reasons): this module says what each\n// idea is made of, where, in what colours and what it looks like; tools/gen-building-catalogue.py writes the catalogue\n// entries (products.json, permanent ids from 1600) and one concrete recipe per variant into recipes.json, so craft()\n// spends by name and the servers validate a building kube exactly as they validate anything else.\n//\n// THE OWNER'S WORDS, kept in the names: \"Wood Panels\" (not planks), \"Buffed\" (not polished), \"Tektite\" (not obsidian),\n// and Hazard Stripes in \"all mineral bits for different color options\".\n//\n// COLOUR. A building kube wears the colour of what it is made from (its `madeOf`): Nova Chiselled Bricks are Nova\n// Mineral's yellow, Tread Plate is Aluminum's silver. Its texture (texture-building.js) is a grey canvas multiplied by\n// that colour, the crust's and the biolith's way, so all 32 pigments of an idea share one canvas. Four take a colour of\n// their own where the source's would hide the design: the Lantern's warm light, the Honeycomb Panel (Graphene is\n// near-black), Void's Polished Tektite (lifted a little so its sheen shows), and nothing else.\n//\n// THE PILLAR is one item that DRAWS as four (system-view.js): standing alone, a short column (base and capital); with\n// pillars above and below it, plain shaft; the bottom of a stack a base, the top a capital. Decided at draw time from\n// the cells above and below along the cell's up (pillarRole), so nothing about it is stored: it is a pure render rule.\n//\n// Pure: no DOM, no imports beyond organics.mjs and biolith.mjs (whose own are pure), so a tool, a test and the page\n// read one rule.\nimport { ORGANIC_MATERIALS, FAMILIES } from './organics.mjs';\nimport { BIOLITH_PIGMENTS, BIOLITH_MINE_DENSITY } from './biolith.mjs';\n\n// The 32 pigments of the crust (Mineral, Regolith, Glass), in kubes.json's order.\nexport const BUILD_PIGMENTS = BIOLITH_PIGMENTS;\nconst lifeOf = (fam) => ORGANIC_MATERIALS.filter((m) => m.family === fam);\n// Woods, glows, crystals, firns and tektites, as organics.mjs grows them (the variant is the pigment).\nconst WOODS = () => lifeOf('wood').map((m) => m.variant);\nconst GLOWS = () => lifeOf('glow').map((m) => m.variant);\nconst CRYSTALS = () => lifeOf('crystal').map((m) => m.variant);\nconst FIRNS = () => lifeOf('firn').map((m) => m.variant);\nconst TEKTITES = () => lifeOf('obsidian').map((m) => m.variant);   // the family key stays 'obsidian'; its suffix is Tektite (Oct 13)\nconst TEKTITE = () => FAMILIES.obsidian.suffix;\n\n// The ID BLOCK: building kubes take permanent ids from 1600 (bioliths hold 1000-1587, vessels 785-791). The generator\n// keeps every id already issued, by name, and gives a new entry the next number in this block.\nexport const BUILD_ID_BASE = 1600;\n\n// MINING. The game prices a mine by density (genDensity.mjs: 1 s at 3.05 to 5 s at 3.95), so masonry carries a mining\n// density of its own, the bioliths' (biolith.mjs: one and a half times a regolith's time); metals mine as their metal,\n// ice and snow quickly, and the open-work grate as glass.\nexport const MASONRY_MINE_DENSITY = BIOLITH_MINE_DENSITY;   // 3.89 → 4.73 s\nexport const SNOW_MINE_DENSITY = '3.05';                     // 1 s, the fastest a kube mines\nconst MASONRY = { metalness: 0.0, roughness: 0.75 };\nconst BUFFED = { metalness: 0.0, roughness: 0.3 };\nconst WOODY = { metalness: 0.05, roughness: 0.8 };\nconst ICY = { metalness: 0.0, roughness: 0.25 };\n\n// THE IDEAS, in the proposal's order. Each:\n//   id       the idea's key (the proposal's, but `buffed` for polished-mineral and `tektite` for obsidian)\n//   style    the texture-building.js canvas it wears ('build:<style>')\n//   family   the Kubipedia row a pigment idea's kubes share (\"Chiselled Bricks\": Solis, Gloam, …), null for one item\n//   pigments () => the variants (null for an idea of one item)\n//   name     (p) => the item's name\n//   from     (p) => the material it is cut from: its colour (madeOf) and its density, unless the idea says otherwise\n//   recipes  (p) => [{ key, inputs }] — one recipe per way of making it (the lantern's 32 glasses × 6 glows)\n//   out      how many one craft makes;  station (a machine) or bench (1 = a Toolbench)\n//   bit      false for the lights, which are fixtures, not materials\n//   text     (p) => what it looks like, the first half of its description\nexport const BUILDING_IDEAS = Object.freeze([\n  // ── CHISELLED MINERALS, DAY ONE: a Toolbench and one Mineral, any of the 32 ──────────────────────────────────────────\n  { id: 'chisel', style: 'chisel', family: 'Chiselled Bricks', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Chiselled Bricks`,\n    from: (p) => `${p} Mineral`, recipes: (p) => [{ key: p, inputs: { [`${p} Mineral`]: 1 } }], out: 1, bench: 1, props: MASONRY, mine: 'masonry',\n    text: (p) => `${p} Mineral hand-cut into large blocks, three courses a kube, the tool marks still on them` },\n  { id: 'pillar', style: 'pillar', family: 'Mineral Pillar', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Mineral Pillar`,\n    from: (p) => `${p} Mineral`, recipes: (p) => [{ key: p, inputs: { [`${p} Mineral`]: 1 } }], out: 1, bench: 1, props: MASONRY, mine: 'masonry', pillar: true,\n    text: (p) => `A fluted column of ${p} Mineral that, stacked, draws a base on the bottom kube, a capital on the top and plain shaft between, so any height reads as one pillar` },\n  { id: 'buffed', style: 'buffed', family: 'Buffed Mineral', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Buffed Mineral`,\n    from: (p) => `${p} Mineral`, recipes: (p) => [{ key: p, inputs: { [`${p} Mineral`]: 1 } }], out: 1, bench: 1, props: BUFFED, mine: 'masonry',\n    text: (p) => `${p} Mineral buffed smooth, with a soft sheen and clouding: floors, tabletops, a plaza` },\n  { id: 'tiles', style: 'tiles', family: 'Mineral Tiles', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Mineral Tiles`,\n    from: (p) => `${p} Mineral`, recipes: (p) => [{ key: p, inputs: { [`${p} Mineral`]: 1 } }], out: 1, bench: 1, props: MASONRY, mine: 'masonry',\n    text: (p) => `Four large ${p} Mineral tiles a face, two by two, with hairline joints, for large floors` },\n  { id: 'dressed', style: 'dressed', family: 'Dressed Mineral', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Dressed Mineral`,\n    from: (p) => `${p} Mineral`, recipes: (p) => [{ key: p, inputs: { [`${p} Mineral`]: 1 } }], out: 1, bench: 1, props: MASONRY, mine: 'masonry',\n    text: (p) => `A plain block of ${p} Mineral dressed with fine level tooling and two scored lines; from afar it reads as the raw stone` },\n  // ── GROUND INTO BUILDING ───────────────────────────────────────────────────────────────────────────────────────────\n  { id: 'rammed', style: 'rammed', family: 'Rammed Regolith', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Rammed Regolith`,\n    from: (p) => `${p} Regolith`, recipes: (p) => [{ key: p, inputs: { [`${p} Regolith`]: 2 } }], out: 1, bench: 1, props: MASONRY, mine: 'masonry',\n    text: (p) => `${p} Regolith packed hard in layers, each a slightly different shade: rammed earth, warm and cheap` },\n  { id: 'sintered', style: 'sintered', family: 'Sintered Regolith', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Sintered Regolith`,\n    from: (p) => `${p} Regolith`, recipes: (p) => [{ key: p, inputs: { [`${p} Regolith`]: 1 } }], out: 1, station: 'induction-smelter', props: MASONRY, mine: 'masonry',\n    text: (p) => `${p} Regolith fused in the smelter into a glassy, knobbly block, the way moon bases are planned to be built` },\n  // Concrete takes WATER as it is held: Water is an item (melt Water Ice at an Induction Smelter; a Thermos scoops a\n  // pool), and the Chemical Synthesizer's Sulfuric Acid already takes one, so a cast is 2 Regolith, 1 Slag and 1 Water.\n  { id: 'concrete', style: 'concrete', family: 'Regolith Concrete', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Regolith Concrete`,\n    from: (p) => `${p} Regolith`, recipes: (p) => [{ key: p, inputs: { [`${p} Regolith`]: 2, Slag: 1, Water: 1 } }], out: 4, station: 'induction-smelter', props: MASONRY, mine: 'masonry',\n    text: (p) => `Smooth cast blocks of ${p} Regolith, Slag and Water, with the board marks and four tie holes of their formwork` },\n  // ── WOOD ───────────────────────────────────────────────────────────────────────────────────────────────────────────\n  { id: 'panels', style: 'panels', family: 'Wood Panels', pigments: WOODS, name: (p) => `${p} Wood Panels`,\n    from: (p) => `${p} Timber`, recipes: (p) => [{ key: p, inputs: { [`${p} Timber`]: 1 } }], out: 2, bench: 1, props: WOODY,   // Timber, once Debarked Wood (the owner, Oct 21: 1 Timber still makes 2)\n    text: (p) => `Boards of ${p} Timber with staggered ends and their grain` },\n  { id: 'slats', style: 'slats', family: 'Wood Slats', pigments: WOODS, name: (p) => `${p} Wood Slats`,\n    from: (p) => `${p} Timber`, recipes: (p) => [{ key: p, inputs: { [`${p} Wood Panels`]: 1 } }], out: 2, bench: 1, props: WOODY,\n    text: (p) => `${p} Wood Panels cut into angled louvres with dark gaps, like a shutter or a sauna wall` },\n  // ── METAL ──────────────────────────────────────────────────────────────────────────────────────────────────────────\n  { id: 'tread', style: 'tread', family: null, pigments: () => [null], name: () => 'Tread Plate',\n    from: () => 'Aluminum', recipes: () => [{ key: '', inputs: { Aluminum: 1 } }], out: 2, bench: 1,\n    text: () => 'Aluminum sheet with raised diamond grips, the floor of every hangar and ramp' },\n  // THE GRATE IS SEEN THROUGH, like a pane (system-engine.js isGlassKubeName reads `seeThrough`), and as open work space\n  // passes it (vessel-life.mjs OPEN_WORK): a vessel's Suit Dock behind a grate still faces space.\n  { id: 'grate', style: 'grate', family: null, pigments: () => [null], name: () => 'Steel Grate',\n    from: () => 'Steel', recipes: () => [{ key: '', inputs: { Steel: 1 } }], out: 2, bench: 1, seeThrough: true, mine: 'glass',\n    text: () => 'Steel bars you can see and light through, for catwalks, balconies and cages' },\n  { id: 'corrugated', style: 'corrugated', family: null, pigments: () => [null], name: () => 'Corrugated Aluminum',\n    from: () => 'Aluminum', recipes: () => [{ key: '', inputs: { Aluminum: 1 } }], out: 2, bench: 1,\n    text: () => 'Ribbed aluminium sheet for sheds, roofs and outposts' },\n  // \"Add all mineral bits for different color options here\" (the owner): the stripes are the bit's Mineral, on black.\n  { id: 'hazard', style: 'hazard', family: 'Hazard Stripes', pigments: () => BUILD_PIGMENTS, name: (p) => `${p} Hazard Stripes`,\n    from: (p) => `${p} Mineral`, density: () => 'Steel', recipes: (p) => [{ key: p, inputs: { Steel: 1, [`${p} Mineral Bit`]: 1 } }], out: 2, bench: 1,\n    props: { metalness: 0.6, roughness: 0.45 },\n    text: (p) => `Diagonal stripes of ${p} Mineral on black steel: the edges of landing pads, docking ports and machine floors` },\n  { id: 'vent', style: 'vent', family: null, pigments: () => [null], name: () => 'Vent Grille',\n    from: () => 'Steel', recipes: () => [{ key: '', inputs: { Steel: 1 } }], out: 1, bench: 1,\n    text: () => 'A framed steel panel of dark slots, one on each face, to break up a long metal wall' },\n  // ── ICE AND SNOW ───────────────────────────────────────────────────────────────────────────────────────────────────\n  // ICE BRICKS MELT WHERE WATER WOULD: phase.mjs carries them as a second solid of the water family, so on a world warm\n  // enough to melt Water Ice a placed Ice Brick draws, and flows, as Water (and sublimates where the air is too thin).\n  { id: 'icebrick', style: 'icebrick', family: null, pigments: () => [null], name: () => 'Ice Bricks',\n    from: () => 'Water Ice', recipes: () => [{ key: '', inputs: { 'Water Ice': 1 } }], out: 1, bench: 1, props: ICY, melts: 'Water Ice',\n    text: () => 'Big clear blocks of Water Ice with frost lines, for igloos and ice halls on frozen worlds; they melt where water would' },\n  { id: 'snow', style: 'snow', family: 'Snow Blocks', pigments: FIRNS, name: (p) => `${p} Snow Blocks`,\n    from: (p) => `${p} Firn`, recipes: (p) => [{ key: p, inputs: { [`${p} Firn`]: 1 } }], out: 1, bench: 1, props: WOODY, mine: 'snow',\n    text: (p) => `${p} Firn packed and cut into bricks` },\n  // ── LIGHT: both cast real light round them at night (system-view.js, light-volume.mjs), as a beacon does ───────────────\n  { id: 'lantern', style: 'lantern', family: null, pigments: () => [null], name: () => 'Lantern Kube',\n    from: () => 'Iron', hex: () => '#FFCF6A', density: () => 'Nova Glass',\n    recipes: () => GLOWS().flatMap((g) => BUILD_PIGMENTS.map((p) => ({ key: `${slug(p)}-glass-${slug(g)}`, inputs: { [`${p} Glass`]: 1, Iron: 1, [`${g} Glow Biomass`]: 1 } }))),\n    variantNote: () => `any of the 32 glasses and any of the ${GLOWS().length} Glow Biomass`,\n    out: 2, bench: 1, bit: false, light: { color: '#FFCF6A', flicker: true }, props: { metalness: 0.2, roughness: 0.5 },\n    text: () => 'A framed lamp of glass and iron with glow tissue inside, lighting the cells round it at night: the first light a builder can place' },\n  { id: 'glowstrip', style: 'glowstrip', family: 'Glow Strip Panel', pigments: GLOWS, name: (p) => `${p} Glow Strip Panel`,\n    from: (p) => `${p} Glow Biomass`, density: () => 'Steel', recipes: (p) => [{ key: p, inputs: { Steel: 1, [`${p} Glow Biomass`]: 1 } }],\n    out: 2, bench: 1, bit: false, light: { color: 'hex', flicker: true }, props: { metalness: 0.4, roughness: 0.4 },\n    text: (p) => `A dark steel panel with two bands lit by ${p} Glow Biomass: corridor lighting, in the biomass's own colour` },\n  // GAS LAMPS (the owner's Nebulas round 2, NT2 and G5, Oct 29): a Lantern's frame round a gas bottled from a canister\n  { id: 'neonlamp', style: 'neonlamp', family: null, pigments: () => [null], name: () => 'Neon Lamp',\n    from: () => 'Neon', hex: () => '#A07BFF', density: () => 'Nova Glass', recipes: () => [{ key: '', inputs: { Neon: 1, 'Lantern Kube': 2 } }],\n    out: 2, bench: 1, bit: false, light: { color: '#A07BFF', flicker: false }, props: { metalness: 0.2, roughness: 0.4 },\n    text: () => 'A Lantern’s frame filled with Neon, glowing a steady violet and lighting the cells round it at night' },\n  { id: 'balloonlamp', style: 'balloonlamp', family: null, pigments: () => [null], name: () => 'Balloon Lamp',\n    from: () => 'Helium', hex: () => '#FFE6BF', density: () => 'Nova Glass', recipes: () => [{ key: '', inputs: { Helium: 1, 'Lantern Kube': 1 } }],\n    out: 2, bench: 1, bit: false, light: { color: '#FFE2A8', flicker: true }, props: { metalness: 0.05, roughness: 0.6 },\n    text: () => 'A pale skin of Helium round a Lantern’s glow, light enough to hang anywhere, lighting the cells round it at night' },\n  // ── STATIONS AND TECH ──────────────────────────────────────────────────────────────────────────────────────────────\n  { id: 'hull', style: 'hull', family: null, pigments: () => [null], name: () => 'Hull Plating',\n    from: () => 'Structural Alloy', recipes: () => [{ key: '', inputs: { 'Structural Alloy': 1 } }], out: 2, bench: 1,\n    text: () => 'Structural Alloy plate with panel lines, a stencil mark and a vent strip: the outside of a station or a ship' },\n  { id: 'honeycomb', style: 'honeycomb', family: null, pigments: () => [null], name: () => 'Honeycomb Panel',\n    from: () => 'Graphene Kube', hex: () => '#5A6068', recipes: () => [{ key: '', inputs: { 'Graphene Kube': 1 } }], out: 2, station: 'chemical-synthesizer',\n    props: { metalness: 0.35, roughness: 0.3 },\n    text: () => 'Hexagonal cells of carbon, light and strong: Kubicor\\'s honeycomb as a high-tech wall' },\n  { id: 'corinlay', style: 'corinlay', family: null, pigments: () => [null], name: () => 'Cor Inlaid Panel',\n    from: () => 'Cor', density: () => 'Titan Plate', recipes: () => [{ key: '', inputs: { 'Titan Plate': 1, Cor: 1 } }], out: 2, station: 'quantum-assembler',\n    glow: true, props: { metalness: 0.5, roughness: 0.3 },\n    text: () => 'Dark Titan Plate inlaid with glowing lines and nodes of Cor, like the seams of a Cor monolith' },\n  // ── FROM LIFE AND RARE STONE ───────────────────────────────────────────────────────────────────────────────────────\n  { id: 'crystal', style: 'crystal', family: 'Cut Crystal', pigments: CRYSTALS, name: (p) => `${p} Cut Crystal`,\n    from: (p) => `${p} Crystal`, recipes: (p) => [{ key: p, inputs: { [`${p} Crystal`]: 2 } }], out: 1, bench: 1, props: { metalness: 0.05, roughness: 0.2 },\n    text: (p) => `${p} Crystal from the crystal fields, cut into facets that catch the light` },\n  { id: 'tektite', style: 'tektite', family: 'Polished Tektite', pigments: TEKTITES, name: (p) => `${p} Polished ${TEKTITE()}`,\n    from: (p) => `${p} ${TEKTITE()}`, hex: (p) => (p === 'Void' ? '#2A2A31' : null),\n    recipes: (p) => [{ key: p, inputs: { [`${p} ${TEKTITE()} Bit`]: 2 } }], out: 1, bench: 1, props: { metalness: 0.05, roughness: 0.1 },\n    text: (p) => `Black ${p} ${TEKTITE()}, natural glass, ground mirror-smooth with the curved ripples of its fractures` },\n  // ── FROM ANIMALS (the owner's Alien Animals items, Oct 29): one kube each, not a colour range ──────────────────────\n  // SHELLSTONE is pressed from a Shell Plate and ANY regolith (one recipe per pigment, as the lantern takes any glass), and\n  // wears a pale colour of its own: the regolith is only its binder, and a Shell Plate's red-brown would hide the ridges.\n  { id: 'shellstone', style: 'shellstone', family: null, pigments: () => [null], name: () => 'Shellstone',\n    from: () => 'Shell Plate', hex: () => '#E4D9C6', density: () => 'Nova Regolith',\n    recipes: () => BUILD_PIGMENTS.map((p) => ({ key: p, inputs: { 'Shell Plate': 1, [`${p} Regolith`]: 1 } })),\n    variantNote: () => 'any of the 32 regoliths', how: () => '1 Shell Plate and 1 of any Regolith',\n    out: 2, bench: 1, props: MASONRY, mine: 'masonry',\n    text: () => 'Pale masonry pressed from Shell Plate and Regolith, ridged like the shell it came from' },\n  // SCALE TILES: scales laid in overlapping rows, as roof tiles are, in the Scales' own colour with a slight shimmer.\n  { id: 'scaletiles', style: 'scaletiles', family: null, pigments: () => [null], name: () => 'Scale Tiles',\n    from: () => 'Scales', recipes: () => [{ key: '', inputs: { Scales: 1 } }], out: 2, bench: 1,\n    props: { metalness: 0.35, roughness: 0.3 },\n    text: () => 'Scales laid in overlapping rows with a faint shimmer, for roofs and walls' },\n].map((d) => Object.freeze(d)));\nconst IDEA_BY_ID = new Map(BUILDING_IDEAS.map((d) => [d.id, d]));\nexport const buildingIdea = (id) => IDEA_BY_ID.get(id) || null;\n\nfunction slug(s) { return String(s).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); }\nconst article = (s) => (/^[AEIOU]/.test(s) ? 'an' : 'a');\n\n// EVERY BUILDING KUBE BY NAME → { idea, pigment, bit } (built once from the ideas; a bit is \"<name> Bit\").\nconst BY_NAME = new Map();\nfor (const d of BUILDING_IDEAS) for (const p of d.pigments()) {\n  const name = d.name(p);\n  BY_NAME.set(name, { idea: d.id, pigment: p, bit: false });\n  if (d.bit !== false) BY_NAME.set(name + ' Bit', { idea: d.id, pigment: p, bit: true });\n}\nexport function buildingOf(name) { return (typeof name === 'string' && BY_NAME.get(name)) || null; }\nexport const isBuildingKube = (name) => buildingOf(name) !== null;\n// The texture style a building kube or its bit wears ('chisel', 'pillar', …), or null.\nexport function buildingStyleOf(name) { const b = buildingOf(name); return b ? IDEA_BY_ID.get(b.idea).style : null; }\n// Every building kube's name (not the bits), in the ideas' order.\nexport const buildingNames = () => [...BY_NAME].filter(([, v]) => !v.bit).map(([n]) => n);\n\n// ── WHAT A FEW OF THEM DO ─────────────────────────────────────────────────────────────────────────────────────────────\n// The see-through ones, by name (bits included): a pane's path in the renderer (system-engine.js reads the catalogue's\n// `seeThrough`, which the generator writes from this).\nexport const isSeeThroughBuilding = (name) => { const b = buildingOf(name); return !!b && !!IDEA_BY_ID.get(b.idea).seeThrough; };\n// The ones that cast light, with how: { color, flicker }. A Glow Strip's light is its biomass's colour (`hex` resolved\n// by the caller from the catalogue).\nexport function buildingLightOf(name, hex) {\n  const b = buildingOf(name); if (!b) return null;\n  const L = IDEA_BY_ID.get(b.idea).light; if (!L) return null;\n  return { color: L.color === 'hex' ? (hex || '#ffffff') : L.color, flicker: !!L.flicker };\n}\n// The ones that glow without being a lamp (Cor Inlaid Panel and its bit).\nexport const isGlowingBuilding = (name) => { const b = buildingOf(name); return !!b && !!IDEA_BY_ID.get(b.idea).glow; };\nexport const isPillarName = (name) => { const b = buildingOf(name); return !!b && !b.bit && !!IDEA_BY_ID.get(b.idea).pillar; };\n\n// ── THE PILLAR'S RENDER RULE ──────────────────────────────────────────────────────────────────────────────────────────\n// A placed pillar draws by what stands above and below it ALONG ITS CELL'S UP (a world's outward axis; +Y aboard a\n// vessel): a pillar both sides is shaft ('m'), only above is the base ('b'), only below the capital ('t'), neither a\n// short column whole ('s'). Any Mineral Pillar counts, whatever its pigment, so a column may be banded in colours and\n// still read as one. A bit of a pillar is not a pillar cell and wears the shaft.\nexport const PILLAR_ROLES = Object.freeze(['s', 'b', 'm', 't']);\nexport function pillarRole(above, below) { return above && below ? 'm' : above ? 'b' : below ? 't' : 's'; }\n// The pillar canvas each role wears (texture-building.js), and the band of it an END face (the face along the up, top\n// or bottom) samples: the capital's abacus, the base's plinth, both for the short column, a stretch of flute for the\n// shaft, whose ends are always against another pillar. [v0, dv] in texture v (0 the canvas's bottom, 1 its top).\nexport const PILLAR_STYLE = Object.freeze({ s: 'pillar', b: 'pillarbase', m: 'pillarshaft', t: 'pillarcap' });\nexport const PILLAR_END_BAND = Object.freeze({ s: [0.93, 0.06], b: [0.01, 0.06], m: [0.45, 0.06], t: [0.93, 0.06] });\n// THE MAPPING, in JS: the uv a pillar face's vertex wears, given its object-space position and normal (a unit box) and\n// the cell's up. Side faces run v along the up (0 at the kube's foot) and u to the viewer's right (cross(up, n)), so\n// the column stands upright on every face of every world; an end face samples its role's band. pillarUvGLSL below is\n// this, in the shader's language, from the same constants (tests/building-kubes.test.mjs holds them equal).\nexport function pillarUv(pos, n, up, role) {\n  const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n  const cross = (a, b) => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n  if (Math.abs(dot(n, up)) > 0.5) {\n    const [v0, dv] = PILLAR_END_BAND[role] || PILLAR_END_BAND.s;\n    const t = Math.abs(n[0]) > 0.5 ? [0, 0, 1] : [1, 0, 0], s = cross(n, t);\n    return [dot(pos, t) + 0.5, v0 + (dot(pos, s) + 0.5) * dv];\n  }\n  return [dot(pos, cross(up, n)) + 0.5, dot(pos, up) + 0.5];\n}\n// The vertex-shader fragment: rewrites vMapUv for a pillar instance. `vessel` fixes the up at +Y; a world's is the\n// dominant axis of the cell's centre (system-view.js cellUpFace, the same tie-break).\nexport function pillarUvGLSL(role, vessel) {\n  const [v0, dv] = PILLAR_END_BAND[role] || PILLAR_END_BAND.s, f = (x) => x.toFixed(4);\n  return ['\\n#ifdef USE_MAP', '{',\n    '\\tvec3 pc_ = vec3(0.5);', '#ifdef USE_INSTANCING', '\\tpc_ = (instanceMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;', '#endif',\n    vessel ? '\\tvec3 pu_ = vec3(0.0, 1.0, 0.0);'\n      : '\\tvec3 pa_ = abs(pc_); vec3 pu_ = vec3(0.0);\\n\\tif (pa_.x >= pa_.y && pa_.x >= pa_.z) pu_.x = pc_.x >= 0.0 ? 1.0 : -1.0;\\n\\telse if (pa_.y >= pa_.z) pu_.y = pc_.y >= 0.0 ? 1.0 : -1.0;\\n\\telse pu_.z = pc_.z >= 0.0 ? 1.0 : -1.0;',\n    '\\tvec3 pn_ = normal;',\n    '\\tif (abs(dot(pn_, pu_)) > 0.5) {',\n    '\\t\\tvec3 pt_ = abs(pn_.x) > 0.5 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);',\n    `\\t\\tvMapUv = vec2(dot(position, pt_) + 0.5, ${f(v0)} + (dot(position, cross(pn_, pt_)) + 0.5) * ${f(dv)});`,\n    '\\t} else {',\n    '\\t\\tvMapUv = vec2(dot(position, cross(pu_, pn_)) + 0.5, dot(position, pu_) + 0.5);',\n    '\\t}', '}', '#endif'].join('\\n');\n}\n\n// ── THE CATALOGUE ENTRIES, without ids (the generator keeps or issues them). `entryOf(name)` is the catalogue's entry\n// for a source material (its hex, density, threejs-properties), from kubes.json and products.json.\nexport function buildingItems(entryOf) {\n  const out = [];\n  for (const d of BUILDING_IDEAS) for (const p of d.pigments()) {\n    const name = d.name(p), from = d.from(p), src = entryOf(from);\n    if (!src) throw new Error(`${name}: its material ${from} is not in the catalogue`);\n    const dens = d.density ? entryOf(d.density(p)) : src;\n    const hex = (d.hex && d.hex(p)) || src.hex;\n    const props = d.props || (src['threejs-properties'] ? { metalness: src['threejs-properties'].metalness ?? 0, roughness: src['threejs-properties'].roughness ?? 0.5 } : MASONRY);\n    const mineD = d.mine === 'masonry' ? MASONRY_MINE_DENSITY : d.mine === 'snow' ? SNOW_MINE_DENSITY\n      : d.mine === 'glass' ? entryOf('Nova Glass').density : null;\n    const rs = d.recipes(p), r0 = rs[0];\n    const how = (r0 && Object.entries(r0.inputs).map(([n, c]) => `${c} ${n}${c > 1 && / Bit$/.test(n) ? 's' : ''}`).join(' + ')) || '';\n    const where = d.station === 'induction-smelter' ? 'an Induction Smelter' : d.station === 'chemical-synthesizer' ? 'a Chemical Synthesizer'\n      : d.station === 'quantum-assembler' ? 'a Quantum Assembler' : 'a Toolbench';\n    const made = rs.length > 1 ? `Made at ${where}, ${d.out} at a time, from ${d.how ? d.how() : d.variantNote ? 'a Glass, 1 Iron and a Glow Biomass (' + d.variantNote() + ')' : how}.`\n      : `Made at ${where}${d.out > 1 ? `, ${d.out} at a time,` : ''} from ${how}.`;\n    const e = { name, state: 'solid', hex: hex.toUpperCase(), 'threejs-properties': { metalness: +props.metalness, roughness: +props.roughness }, rarity: '—',\n                density: dens.density, ...(mineD ? { mineDensity: mineD } : {}), craftOnly: true, building: d.style, madeOf: from };\n    if (d.seeThrough) Object.assign(e['threejs-properties'], { opacity: 0.9, transparent: true }), e.seeThrough = true;\n    e.desc = `${d.text(p)}. ${made}`;\n    out.push(e);\n    if (d.bit === false) continue;\n    const b = { name: name + ' Bit', hex: e.hex, density: e.density, ...(mineD ? { mineDensity: mineD } : {}), bitOf: name };\n    if (d.seeThrough) b.seeThrough = true;\n    b.desc = `One eighth of ${article(name)} ${name}${/ Kube$/.test(name) ? '' : ' kube'}. Eight bits merge back into one.`;   // the biolith bits' wording\n    out.push(b);\n  }\n  return out;\n}\n\n// THE RECIPES: each variant's craft (several for the lantern), then each kube's merge and split. `variantOf` groups an\n// idea's crafts as one row in the recipe book.\nexport function buildingRecipes() {\n  const crafts = [], conv = [];\n  for (const d of BUILDING_IDEAS) {\n    const ps = d.pigments(), many = ps.length > 1 || d.recipes(ps[0]).length > 1;\n    for (const p of ps) {\n      const name = d.name(p);\n      for (const r of d.recipes(p)) {\n        const rec = { id: `bk-${d.id}${r.key ? '-' + slug(r.key) : ''}`, name, inputs: { ...r.inputs }, outputs: [{ name, count: d.out }] };\n        if (d.station) rec.station = d.station; else rec.bench = d.bench || 1;\n        if (many) { rec.variantOf = `bk-${d.id}`; rec.variantNote = d.variantNote ? d.variantNote() : ps.length > 6 ? `any of the ${ps.length} ${ps.length === BUILD_PIGMENTS.length ? 'pigments' : 'colours'}, each making its own colour` : `${ps.slice(0, -1).join(', ')} or ${ps[ps.length - 1]}, each making its own colour`; }\n        crafts.push(rec);\n      }\n      if (d.bit === false) continue;\n      conv.push({ id: 'merge-' + slug(name), name: `${name} (merge bits)`, conversion: true, inputs: { [name + ' Bit']: 8 }, outputs: [{ name, count: 1 }] });\n      conv.push({ id: 'split-' + slug(name), name: `${name} (split to bits)`, conversion: true, inputs: { [name]: 1 }, outputs: [{ name: name + ' Bit', count: 8 }] });\n    }\n  }\n  return [...crafts, ...conv];\n}\nexport const isBuildingRecipe = (r) => !!r && typeof r.id === 'string' && (/^bk-/.test(r.id) || (/^(merge|split)-/.test(r.id) && (r.outputs || []).some((o) => isBuildingKube(o && o.name))));\n"],"mappings":"AA0BA,OAAS,kBAAmB,aAAgB,iBAC5C,OAAS,iBAAkB,yBAA4B,gBAGhD,aAAM,eAAiB,iBAC9B,MAAM,OAAU,KAAQ,kBAAkB,OAAQ,GAAM,EAAE,SAAW,GAAG,EAElE,MAAQ,IAAM,OAAO,MAAM,EAAE,IAAK,GAAM,EAAE,OAAO,EACjD,MAAQ,IAAM,OAAO,MAAM,EAAE,IAAK,GAAM,EAAE,OAAO,EACjD,SAAW,IAAM,OAAO,SAAS,EAAE,IAAK,GAAM,EAAE,OAAO,EACvD,MAAQ,IAAM,OAAO,MAAM,EAAE,IAAK,GAAM,EAAE,OAAO,EACjD,SAAW,IAAM,OAAO,UAAU,EAAE,IAAK,GAAM,EAAE,OAAO,EACxD,QAAU,IAAM,SAAS,SAAS,OAIjC,aAAM,cAAgB,KAKhB,qBAAuB,qBACvB,kBAAoB,OACjC,MAAM,QAAU,CAAE,UAAW,EAAK,UAAW,GAAK,EAC5C,OAAS,CAAE,UAAW,EAAK,UAAW,EAAI,EAC1C,MAAQ,CAAE,UAAW,IAAM,UAAW,EAAI,EAC1C,IAAM,CAAE,UAAW,EAAK,UAAW,GAAK,EAavC,aAAM,eAAiB,OAAO,OAAO,CAE1C,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,mBAAoB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,oBAC5G,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UACpI,KAAO,GAAM,GAAG,CAAC,yFAA0F,EAC7G,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,iBAAkB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,kBAC1G,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UAAW,OAAQ,GACvJ,KAAO,GAAM,sBAAsB,CAAC,0IAA2I,EACjL,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,iBAAkB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,kBAC1G,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,OAAQ,KAAM,UACnI,KAAO,GAAM,GAAG,CAAC,oFAAqF,EACxG,CAAE,GAAI,QAAS,MAAO,QAAS,OAAQ,gBAAiB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,iBACvG,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UACpI,KAAO,GAAM,cAAc,CAAC,2EAA4E,EAC1G,CAAE,GAAI,UAAW,MAAO,UAAW,OAAQ,kBAAmB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,mBAC7G,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UACpI,KAAO,GAAM,oBAAoB,CAAC,oGAAqG,EAEzI,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,kBAAmB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,mBAC3G,KAAO,GAAM,GAAG,CAAC,YAAa,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,WAAW,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UACtI,KAAO,GAAM,GAAG,CAAC,gGAAiG,EACpH,CAAE,GAAI,WAAY,MAAO,WAAY,OAAQ,oBAAqB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,qBACjH,KAAO,GAAM,GAAG,CAAC,YAAa,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,WAAW,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,QAAS,oBAAqB,MAAO,QAAS,KAAM,UAC1J,KAAO,GAAM,GAAG,CAAC,yGAA0G,EAG7H,CAAE,GAAI,WAAY,MAAO,WAAY,OAAQ,oBAAqB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,qBACjH,KAAO,GAAM,GAAG,CAAC,YAAa,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,WAAW,EAAG,EAAG,KAAM,EAAG,MAAO,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,QAAS,oBAAqB,MAAO,QAAS,KAAM,UAC7K,KAAO,GAAM,yBAAyB,CAAC,sFAAuF,EAEhI,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,cAAe,SAAU,MAAO,KAAO,GAAM,GAAG,CAAC,eACxF,KAAO,GAAM,GAAG,CAAC,UAAW,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,SAAS,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,MACnH,KAAO,GAAM,aAAa,CAAC,6CAA8C,EAC3E,CAAE,GAAI,QAAS,MAAO,QAAS,OAAQ,aAAc,SAAU,MAAO,KAAO,GAAM,GAAG,CAAC,cACrF,KAAO,GAAM,GAAG,CAAC,UAAW,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,cAAc,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,MACxH,KAAO,GAAM,GAAG,CAAC,qFAAsF,EAEzG,CAAE,GAAI,QAAS,MAAO,QAAS,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,cAC/E,KAAM,IAAM,WAAY,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,SAAU,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAC9F,KAAM,IAAM,8EAA+E,EAG7F,CAAE,GAAI,QAAS,MAAO,QAAS,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,cAC/E,KAAM,IAAM,QAAS,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,MAAO,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,WAAY,GAAM,KAAM,QACnH,KAAM,IAAM,6EAA8E,EAC5F,CAAE,GAAI,aAAc,MAAO,aAAc,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,sBACzF,KAAM,IAAM,WAAY,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,SAAU,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAC9F,KAAM,IAAM,sDAAuD,EAErE,CAAE,GAAI,SAAU,MAAO,SAAU,OAAQ,iBAAkB,SAAU,IAAM,eAAgB,KAAO,GAAM,GAAG,CAAC,kBAC1G,KAAO,GAAM,GAAG,CAAC,WAAY,QAAS,IAAM,QAAS,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,MAAO,EAAG,CAAC,GAAG,CAAC,cAAc,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EACjJ,MAAO,CAAE,UAAW,GAAK,UAAW,GAAK,EACzC,KAAO,GAAM,uBAAuB,CAAC,sFAAuF,EAC9H,CAAE,GAAI,OAAQ,MAAO,OAAQ,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,cAC7E,KAAM,IAAM,QAAS,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,MAAO,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EACxF,KAAM,IAAM,qFAAsF,EAIpG,CAAE,GAAI,WAAY,MAAO,WAAY,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,aACrF,KAAM,IAAM,YAAa,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,YAAa,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,IAAK,MAAO,YACxH,KAAM,IAAM,wHAAyH,EACvI,CAAE,GAAI,OAAQ,MAAO,OAAQ,OAAQ,cAAe,SAAU,MAAO,KAAO,GAAM,GAAG,CAAC,eACpF,KAAO,GAAM,GAAG,CAAC,QAAS,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,OAAO,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,MAAO,KAAM,OAC5H,KAAO,GAAM,GAAG,CAAC,kCAAmC,EAEtD,CAAE,GAAI,UAAW,MAAO,UAAW,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,eACnF,KAAM,IAAM,OAAQ,IAAK,IAAM,UAAW,QAAS,IAAM,aACzD,QAAS,IAAM,MAAM,EAAE,QAAS,GAAM,eAAe,IAAK,IAAO,CAAE,IAAK,GAAG,KAAK,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,GAAI,OAAQ,CAAE,CAAC,GAAG,CAAC,QAAQ,EAAG,EAAG,KAAM,EAAG,CAAC,GAAG,CAAC,eAAe,EAAG,CAAE,CAAE,EAAE,CAAC,EAC3K,YAAa,IAAM,wCAAwC,MAAM,EAAE,MAAM,gBACzE,IAAK,EAAG,MAAO,EAAG,IAAK,GAAO,MAAO,CAAE,MAAO,UAAW,QAAS,EAAK,EAAG,MAAO,CAAE,UAAW,GAAK,UAAW,EAAI,EAClH,KAAM,IAAM,oIAAqI,EACnJ,CAAE,GAAI,YAAa,MAAO,YAAa,OAAQ,mBAAoB,SAAU,MAAO,KAAO,GAAM,GAAG,CAAC,oBACnG,KAAO,GAAM,GAAG,CAAC,gBAAiB,QAAS,IAAM,QAAS,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,MAAO,EAAG,CAAC,GAAG,CAAC,eAAe,EAAG,CAAE,CAAE,CAAC,EACrI,IAAK,EAAG,MAAO,EAAG,IAAK,GAAO,MAAO,CAAE,MAAO,MAAO,QAAS,EAAK,EAAG,MAAO,CAAE,UAAW,GAAK,UAAW,EAAI,EAC9G,KAAO,GAAM,4CAA4C,CAAC,+DAAgE,EAE5H,CAAE,GAAI,WAAY,MAAO,WAAY,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,YACrF,KAAM,IAAM,OAAQ,IAAK,IAAM,UAAW,QAAS,IAAM,aAAc,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,KAAM,EAAG,eAAgB,CAAE,CAAE,CAAC,EAC1I,IAAK,EAAG,MAAO,EAAG,IAAK,GAAO,MAAO,CAAE,MAAO,UAAW,QAAS,EAAM,EAAG,MAAO,CAAE,UAAW,GAAK,UAAW,EAAI,EACnH,KAAM,IAAM,sGAAuG,EACrH,CAAE,GAAI,cAAe,MAAO,cAAe,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,eAC3F,KAAM,IAAM,SAAU,IAAK,IAAM,UAAW,QAAS,IAAM,aAAc,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,OAAQ,EAAG,eAAgB,CAAE,CAAE,CAAC,EAC9I,IAAK,EAAG,MAAO,EAAG,IAAK,GAAO,MAAO,CAAE,MAAO,UAAW,QAAS,EAAK,EAAG,MAAO,CAAE,UAAW,IAAM,UAAW,EAAI,EACnH,KAAM,IAAM,mHAAoH,EAElI,CAAE,GAAI,OAAQ,MAAO,OAAQ,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,eAC7E,KAAM,IAAM,mBAAoB,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,mBAAoB,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAChH,KAAM,IAAM,8GAA+G,EAC7H,CAAE,GAAI,YAAa,MAAO,YAAa,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,kBACvF,KAAM,IAAM,gBAAiB,IAAK,IAAM,UAAW,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,gBAAiB,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,QAAS,uBAClI,MAAO,CAAE,UAAW,IAAM,UAAW,EAAI,EACzC,KAAM,IAAM,sFAAwF,EACtG,CAAE,GAAI,WAAY,MAAO,WAAY,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,mBACrF,KAAM,IAAM,MAAO,QAAS,IAAM,cAAe,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,cAAe,EAAG,IAAK,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,QAAS,oBACtI,KAAM,GAAM,MAAO,CAAE,UAAW,GAAK,UAAW,EAAI,EACpD,KAAM,IAAM,+FAAgG,EAE9G,CAAE,GAAI,UAAW,MAAO,UAAW,OAAQ,cAAe,SAAU,SAAU,KAAO,GAAM,GAAG,CAAC,eAC7F,KAAO,GAAM,GAAG,CAAC,WAAY,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,UAAU,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,CAAE,UAAW,IAAM,UAAW,EAAI,EACvJ,KAAO,GAAM,GAAG,CAAC,wEAAyE,EAC5F,CAAE,GAAI,UAAW,MAAO,UAAW,OAAQ,mBAAoB,SAAU,SAAU,KAAO,GAAM,GAAG,CAAC,aAAa,QAAQ,CAAC,GACxH,KAAO,GAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAI,IAAM,GAAO,IAAM,OAAS,UAAY,KAC1E,QAAU,GAAM,CAAC,CAAE,IAAK,EAAG,OAAQ,CAAE,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAG,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAAG,MAAO,CAAE,UAAW,IAAM,UAAW,EAAI,EACnI,KAAO,GAAM,SAAS,CAAC,IAAI,QAAQ,CAAC,gFAAiF,EAIvH,CAAE,GAAI,aAAc,MAAO,aAAc,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,aACzF,KAAM,IAAM,cAAe,IAAK,IAAM,UAAW,QAAS,IAAM,gBAChE,QAAS,IAAM,eAAe,IAAK,IAAO,CAAE,IAAK,EAAG,OAAQ,CAAE,cAAe,EAAG,CAAC,GAAG,CAAC,WAAW,EAAG,CAAE,CAAE,EAAE,EACzG,YAAa,IAAM,0BAA2B,IAAK,IAAM,sCACzD,IAAK,EAAG,MAAO,EAAG,MAAO,QAAS,KAAM,UACxC,KAAM,IAAM,wFAAyF,EAEvG,CAAE,GAAI,aAAc,MAAO,aAAc,OAAQ,KAAM,SAAU,IAAM,CAAC,IAAI,EAAG,KAAM,IAAM,cACzF,KAAM,IAAM,SAAU,QAAS,IAAM,CAAC,CAAE,IAAK,GAAI,OAAQ,CAAE,OAAQ,CAAE,CAAE,CAAC,EAAG,IAAK,EAAG,MAAO,EAC1F,MAAO,CAAE,UAAW,IAAM,UAAW,EAAI,EACzC,KAAM,IAAM,2EAA4E,CAC5F,EAAE,IAAK,GAAM,OAAO,OAAO,CAAC,CAAC,CAAC,EAC9B,MAAM,WAAa,IAAI,IAAI,eAAe,IAAK,GAAM,CAAC,EAAE,GAAI,CAAC,CAAC,CAAC,EACxD,aAAM,aAAgB,IAAO,WAAW,IAAI,EAAE,GAAK,KAE1D,SAAS,KAAK,EAAG,CAAE,OAAO,OAAO,CAAC,EAAE,YAAY,EAAE,QAAQ,cAAe,GAAG,EAAE,QAAQ,SAAU,EAAE,CAAG,CACrG,MAAM,QAAW,GAAO,WAAW,KAAK,CAAC,EAAI,KAAO,IAG9C,QAAU,IAAI,IACpB,UAAW,KAAK,eAAgB,UAAW,KAAK,EAAE,SAAS,EAAG,CAC5D,MAAM,KAAO,EAAE,KAAK,CAAC,EACrB,QAAQ,IAAI,KAAM,CAAE,KAAM,EAAE,GAAI,QAAS,EAAG,IAAK,EAAM,CAAC,EACpD,EAAE,MAAQ,IAAO,QAAQ,IAAI,KAAO,OAAQ,CAAE,KAAM,EAAE,GAAI,QAAS,EAAG,IAAK,EAAK,CAAC,CACvF,CACO,gBAAS,WAAW,KAAM,CAAE,OAAQ,OAAO,MAAS,UAAY,QAAQ,IAAI,IAAI,GAAM,IAAM,CAC5F,aAAM,eAAkB,MAAS,WAAW,IAAI,IAAM,KAEtD,gBAAS,gBAAgB,KAAM,CAAE,MAAM,EAAI,WAAW,IAAI,EAAG,OAAO,EAAI,WAAW,IAAI,EAAE,IAAI,EAAE,MAAQ,IAAM,CAE7G,aAAM,cAAgB,IAAM,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,IAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAM,CAAC,EAK3E,qBAAwB,MAAS,CAAE,MAAM,EAAI,WAAW,IAAI,EAAG,MAAO,CAAC,CAAC,GAAK,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,UAAY,EAGxH,gBAAS,gBAAgB,KAAM,IAAK,CACzC,MAAM,EAAI,WAAW,IAAI,EAAG,GAAI,CAAC,EAAG,OAAO,KAC3C,MAAM,EAAI,WAAW,IAAI,EAAE,IAAI,EAAE,MAAO,OAAK,EACtC,CAAE,MAAO,EAAE,QAAU,MAAS,KAAO,UAAa,EAAE,MAAO,QAAS,CAAC,CAAC,EAAE,OAAQ,EADhC,IAEzD,CAEO,aAAM,kBAAqB,MAAS,CAAE,MAAM,EAAI,WAAW,IAAI,EAAG,MAAO,CAAC,CAAC,GAAK,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,IAAM,EACzG,aAAgB,MAAS,CAAE,MAAM,EAAI,WAAW,IAAI,EAAG,MAAO,CAAC,CAAC,GAAK,CAAC,EAAE,KAAO,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,MAAQ,EAOhH,aAAe,OAAO,OAAO,CAAC,IAAK,IAAK,IAAK,GAAG,CAAC,EACvD,gBAAS,WAAW,MAAO,MAAO,CAAE,OAAO,OAAS,MAAQ,IAAM,MAAQ,IAAM,MAAQ,IAAM,GAAK,CAInG,aAAM,aAAe,OAAO,OAAO,CAAE,EAAG,SAAU,EAAG,aAAc,EAAG,cAAe,EAAG,WAAY,CAAC,EAC/F,gBAAkB,OAAO,OAAO,CAAE,EAAG,CAAC,IAAM,GAAI,EAAG,EAAG,CAAC,IAAM,GAAI,EAAG,EAAG,CAAC,IAAM,GAAI,EAAG,EAAG,CAAC,IAAM,GAAI,CAAE,CAAC,EAK5G,gBAAS,SAAS,IAAK,EAAG,GAAI,KAAM,CACzC,MAAM,IAAM,CAAC,EAAG,IAAM,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EACtD,MAAQ,CAAC,EAAG,IAAM,CAAC,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAG,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAG,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,EAAI,EAAE,CAAC,CAAC,EACxG,GAAI,KAAK,IAAI,IAAI,EAAG,EAAE,CAAC,EAAI,GAAK,CAC9B,KAAM,CAAC,GAAI,EAAE,EAAI,gBAAgB,IAAI,GAAK,gBAAgB,EACpD,EAAI,KAAK,IAAI,EAAE,CAAC,CAAC,EAAI,GAAM,CAAC,EAAG,EAAG,CAAC,EAAI,CAAC,EAAG,EAAG,CAAC,EAAG,EAAI,MAAM,EAAG,CAAC,EACtE,MAAO,CAAC,IAAI,IAAK,CAAC,EAAI,GAAK,IAAM,IAAI,IAAK,CAAC,EAAI,IAAO,EAAE,CAC1D,CACA,MAAO,CAAC,IAAI,IAAK,MAAM,GAAI,CAAC,CAAC,EAAI,GAAK,IAAI,IAAK,EAAE,EAAI,EAAG,CAC1D,CAGO,gBAAS,aAAa,KAAM,OAAQ,CACzC,KAAM,CAAC,GAAI,EAAE,EAAI,gBAAgB,IAAI,GAAK,gBAAgB,EAAG,EAAK,GAAM,EAAE,QAAQ,CAAC,EACnF,MAAO,CAAC;AAAA,gBAAoB,IAC1B,yBAA2B,wBAAyB,0DAA4D,SAChH,OAAS,mCACL;AAAA;AAAA;AAAA,0CACJ,sBACA,mCACA,6EACA,6CAA+C,EAAE,EAAE,CAAC,+CAA+C,EAAE,EAAE,CAAC,KACxG,YACA,mFACA,KAAO,IAAK,QAAQ,EAAE,KAAK;AAAA,CAAI,CACnC,CAIO,gBAAS,cAAc,QAAS,CACrC,MAAM,IAAM,CAAC,EACb,UAAW,KAAK,eAAgB,UAAW,KAAK,EAAE,SAAS,EAAG,CAC5D,MAAM,KAAO,EAAE,KAAK,CAAC,EAAG,KAAO,EAAE,KAAK,CAAC,EAAG,IAAM,QAAQ,IAAI,EAC5D,GAAI,CAAC,IAAK,MAAM,IAAI,MAAM,GAAG,IAAI,kBAAkB,IAAI,0BAA0B,EACjF,MAAM,KAAO,EAAE,QAAU,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAI,IAC3C,IAAO,EAAE,KAAO,EAAE,IAAI,CAAC,GAAM,IAAI,IACjC,MAAQ,EAAE,QAAU,IAAI,oBAAoB,EAAI,CAAE,UAAW,IAAI,oBAAoB,EAAE,WAAa,EAAG,UAAW,IAAI,oBAAoB,EAAE,WAAa,EAAI,EAAI,SACjK,MAAQ,EAAE,OAAS,UAAY,qBAAuB,EAAE,OAAS,OAAS,kBAC5E,EAAE,OAAS,QAAU,QAAQ,YAAY,EAAE,QAAU,KACnD,GAAK,EAAE,QAAQ,CAAC,EAAG,GAAK,GAAG,CAAC,EAC5B,IAAO,IAAM,OAAO,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,EAAG,CAAC,IAAM,GAAG,CAAC,IAAI,CAAC,GAAG,EAAI,GAAK,QAAQ,KAAK,CAAC,EAAI,IAAM,EAAE,EAAE,EAAE,KAAK,KAAK,GAAM,GAC1H,MAAQ,EAAE,UAAY,oBAAsB,uBAAyB,EAAE,UAAY,uBAAyB,yBAC9G,EAAE,UAAY,oBAAsB,sBAAwB,cAC1D,KAAO,GAAG,OAAS,EAAI,WAAW,KAAK,KAAK,EAAE,GAAG,oBAAoB,EAAE,IAAM,EAAE,IAAI,EAAI,EAAE,YAAc,uCAAyC,EAAE,YAAY,EAAI,IAAM,GAAG,IAC7K,WAAW,KAAK,GAAG,EAAE,IAAM,EAAI,KAAK,EAAE,GAAG,cAAgB,EAAE,SAAS,GAAG,IACrE,EAAI,CAAE,KAAM,MAAO,QAAS,IAAK,IAAI,YAAY,EAAG,qBAAsB,CAAE,UAAW,CAAC,MAAM,UAAW,UAAW,CAAC,MAAM,SAAU,EAAG,OAAQ,IAC1I,QAAS,KAAK,QAAS,GAAI,MAAQ,CAAE,YAAa,KAAM,EAAI,CAAC,EAAI,UAAW,GAAM,SAAU,EAAE,MAAO,OAAQ,IAAK,EAI9H,GAHI,EAAE,aAAY,OAAO,OAAO,EAAE,oBAAoB,EAAG,CAAE,QAAS,GAAK,YAAa,EAAK,CAAC,EAAG,EAAE,WAAa,IAC9G,EAAE,KAAO,GAAG,EAAE,KAAK,CAAC,CAAC,KAAK,IAAI,GAC9B,IAAI,KAAK,CAAC,EACN,EAAE,MAAQ,GAAO,SACrB,MAAM,EAAI,CAAE,KAAM,KAAO,OAAQ,IAAK,EAAE,IAAK,QAAS,EAAE,QAAS,GAAI,MAAQ,CAAE,YAAa,KAAM,EAAI,CAAC,EAAI,MAAO,IAAK,EACnH,EAAE,aAAY,EAAE,WAAa,IACjC,EAAE,KAAO,iBAAiB,QAAQ,IAAI,CAAC,IAAI,IAAI,GAAG,SAAS,KAAK,IAAI,EAAI,GAAK,OAAO,oCACpF,IAAI,KAAK,CAAC,CACZ,CACA,OAAO,GACT,CAIO,gBAAS,iBAAkB,CAChC,MAAM,OAAS,CAAC,EAAG,KAAO,CAAC,EAC3B,UAAW,KAAK,eAAgB,CAC9B,MAAM,GAAK,EAAE,SAAS,EAAG,KAAO,GAAG,OAAS,GAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,EAAE,OAAS,EAC3E,UAAW,KAAK,GAAI,CAClB,MAAM,KAAO,EAAE,KAAK,CAAC,EACrB,UAAW,KAAK,EAAE,QAAQ,CAAC,EAAG,CAC5B,MAAM,IAAM,CAAE,GAAI,MAAM,EAAE,EAAE,GAAG,EAAE,IAAM,IAAM,KAAK,EAAE,GAAG,EAAI,EAAE,GAAI,KAAM,OAAQ,CAAE,GAAG,EAAE,MAAO,EAAG,QAAS,CAAC,CAAE,KAAM,MAAO,EAAE,GAAI,CAAC,CAAE,EAC9H,EAAE,QAAS,IAAI,QAAU,EAAE,QAAc,IAAI,MAAQ,EAAE,OAAS,EAChE,OAAQ,IAAI,UAAY,MAAM,EAAE,EAAE,GAAI,IAAI,YAAc,EAAE,YAAc,EAAE,YAAY,EAAI,GAAG,OAAS,EAAI,cAAc,GAAG,MAAM,IAAI,GAAG,SAAW,eAAe,OAAS,WAAa,SAAS,+BAAiC,GAAG,GAAG,MAAM,EAAG,EAAE,EAAE,KAAK,IAAI,CAAC,OAAO,GAAG,GAAG,OAAS,CAAC,CAAC,gCAC3R,OAAO,KAAK,GAAG,CACjB,CACI,EAAE,MAAQ,KACd,KAAK,KAAK,CAAE,GAAI,SAAW,KAAK,IAAI,EAAG,KAAM,GAAG,IAAI,gBAAiB,WAAY,GAAM,OAAQ,CAAE,CAAC,KAAO,MAAM,EAAG,CAAE,EAAG,QAAS,CAAC,CAAE,KAAM,MAAO,CAAE,CAAC,CAAE,CAAC,EACtJ,KAAK,KAAK,CAAE,GAAI,SAAW,KAAK,IAAI,EAAG,KAAM,GAAG,IAAI,mBAAoB,WAAY,GAAM,OAAQ,CAAE,CAAC,IAAI,EAAG,CAAE,EAAG,QAAS,CAAC,CAAE,KAAM,KAAO,OAAQ,MAAO,CAAE,CAAC,CAAE,CAAC,EACjK,CACF,CACA,MAAO,CAAC,GAAG,OAAQ,GAAG,IAAI,CAC5B,CACO,aAAM,iBAAoB,GAAM,CAAC,CAAC,GAAK,OAAO,EAAE,IAAO,WAAa,OAAO,KAAK,EAAE,EAAE,GAAM,kBAAkB,KAAK,EAAE,EAAE,IAAM,EAAE,SAAW,CAAC,GAAG,KAAM,GAAM,eAAe,GAAK,EAAE,IAAI,CAAC","names":[],"file":"building-kubes.mjs"}