@adatechnology/game-floorplan-structure 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +364 -311
- package/dist/index.global.js +7 -0
- package/dist/index.global.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/registry.ts","../src/geometry.ts","../src/presets.ts","../src/construction.ts","../src/locales/en.json","../src/locales/pt-BR.json","../src/types.ts","../src/density.ts","../src/structure/builder.ts","../src/structure/legacy-key.ts","../src/structure/context.ts","../src/structure/balconies.ts","../src/structure/canvas.ts","../src/structure/extras.ts","../src/structure/floor-deck.ts","../src/structure/foundation.ts","../src/structure/ground-beams.ts","../src/structure/wall-pillars.ts","../src/structure/plates.ts","../src/structure/porch.ts","../src/structure/porch-roof.ts","../src/structure/roof.ts","../src/structure/stairs.ts","../src/structure/openings.ts","../src/structure/steps.ts","../src/structure/tank-parts.ts","../src/structure/upper-floor.ts","../src/structure/walls.ts","../src/structure/index.ts","../src/utilities/content-tables.ts","../src/utilities/content.ts","../src/utilities/shared.ts","../src/utilities/wall-points.ts","../src/utilities/electrical-outlets.ts","../src/utilities/electrical-entrance.ts","../src/utilities/electrical-circuits.ts","../src/utilities/electrical.ts","../src/utilities/gas.ts","../src/utilities/plumbing.ts","../src/utilities/solar.ts","../src/utilities/index.ts","../src/utilities/outbuildings.ts","../src/water-tank.ts","../src/viewer-layer.ts","../src/register.ts","../src/to-destructible-spec.ts","../src/loads.ts","../src/slab-panels/layout.ts","../src/slab-panels/apply.ts","../src/slab-panels/options.ts","../src/wall-detail/index.ts","../src/wall-detail/apply.ts","../src/wall-detail/courses.ts","../src/wall-detail/panels.ts","../src/validate/codes.ts","../src/validate/load-path.ts","../src/validate/masonry.ts","../src/validate/openings.ts","../src/validate/spec.ts","../src/validate/index.ts","../src/wall-specimen.ts","../src/tower.ts","../src/skyscraper.ts","../src/skyscraper-plan.ts","../src/index.ts"],"sourcesContent":["import type { JointKind } from '@adatechnology/game-contracts'\n\nimport type { Construction, ConstructionSystem, PlanContext, StructureExtras } from './types'\n\n/** What a wall system is made of and how its parts are tied. Timber systems sit on joists, carry the roof on timber plates and have wooden porch posts. */\nexport interface ConstructionSystemDef {\n /** Wall assembly of `game-destruction` (`registerAssembly`) the detailed wall is built from. Empty: no walls (a tent). */\n walls: string\n joints: Record<'wall' | 'slab' | 'beam' | 'column' | 'truss', JointKind>\n /** Thickness of the structural floor under each storey (m). */\n slabThickness: number\n /** Height of the top plate or bond beam (m). */\n plateThickness: number\n timber: boolean\n /** `rules`: bearing when external, under another wall or beside a porch; `bearing`: every wall (logs); `partition`: none (posts carry the roof). */\n wallRole: 'rules' | 'bearing' | 'partition'\n /** Solid fraction of a bearing wall in the structure weight (studs and air). */\n wallFill: number\n studs?: { spacing: number; section: string }\n}\n\nconst uniform = (joint: JointKind): ConstructionSystemDef['joints'] => ({ wall: joint, slab: joint, beam: joint, column: joint, truss: joint })\n\nexport const CONSTRUCTION_SYSTEMS = new Map<string, ConstructionSystemDef>([\n ['masonry', { walls: 'brick_wall_plastered', joints: { wall: 'mortar', slab: 'rebar', beam: 'mortar', column: 'rebar', truss: 'bolt' }, slabThickness: 0.12, plateThickness: 0.2, timber: false, wallRole: 'rules', wallFill: 1 }],\n ['wood_frame', { walls: 'wood_frame_wall', joints: uniform('nail'), slabThickness: 0.28, plateThickness: 0.1, timber: true, wallRole: 'rules', wallFill: 0.35, studs: { spacing: 0.4, section: '38x89' } }],\n ['log', { walls: 'log_wall', joints: { wall: 'bolt', slab: 'nail', beam: 'bolt', column: 'bolt', truss: 'bolt' }, slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'bearing', wallFill: 1 }],\n ['improvised', { walls: 'sheet_metal_shack', joints: uniform('nail'), slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'partition', wallFill: 1 }],\n ['canvas', { walls: '', joints: uniform('tie'), slabThickness: 0, plateThickness: 0, timber: false, wallRole: 'partition', wallFill: 1 }],\n])\n\n/** Adds or replaces a construction system (`id` is a `ConstructionSystem` or any name a construction refers to). */\nexport function registerConstructionSystem(id: ConstructionSystem | string, def: ConstructionSystemDef): void {\n CONSTRUCTION_SYSTEMS.set(id, def)\n}\n\nexport interface RoofCoveringDef {\n material: string\n /** How the covering is fixed to the trusses. */\n joint: JointKind\n}\n\nexport const ROOF_COVERINGS = new Map<string, RoofCoveringDef>([\n ['colonial', { material: 'ceramic', joint: 'resting' }],\n ['fiber_cement', { material: 'concrete', joint: 'bolt' }],\n ['slab', { material: 'concrete', joint: 'rebar' }],\n ['asphalt', { material: 'plastic', joint: 'nail' }],\n ['zinc', { material: 'steel', joint: 'nail' }],\n ['wood', { material: 'wood_soft', joint: 'nail' }],\n ['canvas', { material: 'fabric', joint: 'tie' }],\n ['thatch', { material: 'foliage', joint: 'tie' }],\n])\n\nexport function registerRoofCovering(id: string, def: RoofCoveringDef): void {\n ROOF_COVERINGS.set(id, def)\n}\n\nexport interface ConstructionBuild {\n construction: Construction\n extras?: StructureExtras\n}\nexport type ConstructionBuilder = (context: PlanContext) => ConstructionBuild\n\nexport const CONSTRUCTIONS = new Map<string, ConstructionBuilder>()\n\n/** Registers how a template's building is made: `TemplateDef.construction` names it. A template without one gets the masonry default. */\nexport function registerConstruction(id: string, builder: ConstructionBuilder): void {\n CONSTRUCTIONS.set(id, builder)\n}\n","import type { Rect, SourceWall } from './types'\n\nexport const WALL_THICKNESS = 0.15\n\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\n\nexport function touches(a: Rect, b: Rect, tolerance: number): boolean {\n return a[0] < b[2] + tolerance && a[2] > b[0] - tolerance && a[1] < b[3] + tolerance && a[3] > b[1] - tolerance\n}\n\nexport function distanceBetween(a: Rect, b: Rect): number {\n return Math.hypot(Math.max(a[0] - b[2], b[0] - a[2], 0), Math.max(a[1] - b[3], b[1] - a[3], 0))\n}\n\nexport function unionOf(rects: readonly Rect[]): Rect {\n const out: Rect = [1e9, 1e9, -1e9, -1e9]\n for (const rect of rects) {\n out[0] = Math.min(out[0], rect[0])\n out[1] = Math.min(out[1], rect[1])\n out[2] = Math.max(out[2], rect[2])\n out[3] = Math.max(out[3], rect[3])\n }\n return out\n}\n\n/** The wall's centre line thickened to its box in the plan. */\nexport function wallBox(wall: Pick<SourceWall, 'u0' | 'v0' | 'u1' | 'v1' | 'thickness'>): Rect {\n const half = (wall.thickness ?? WALL_THICKNESS) / 2\n return [Math.min(wall.u0, wall.u1) - half, Math.min(wall.v0, wall.v1) - half, Math.max(wall.u0, wall.u1) + half, Math.max(wall.v0, wall.v1) + half]\n}\n\nexport const centreOf = (rect: Rect): [number, number] => [(rect[0] + rect[2]) / 2, (rect[1] + rect[3]) / 2]\n\n/** The nearest `count` of `candidates` to `target`, nearest first. */\nexport function nearestTo<T extends { aabb: Rect }>(target: Rect, candidates: readonly T[], count: number): T[] {\n return candidates.slice().sort((a, b) => distanceBetween(target, a.aabb) - distanceBetween(target, b.aabb)).slice(0, count)\n}\n","import type { Construction, FoundationType, StructureSource } from './types'\nimport { WALL_THICKNESS } from './geometry'\nimport { ROOF_COVERINGS } from './registry'\n\nconst SLAB_COVERING = 'slab'\nconst PLASTERED_FINISHES = ['plaster', 'partial_plaster']\n\n/** Masonry house of the engine's own templates: brick with plaster, concrete frame, tiles by facade; a unit in a building gets a flat slab roof. */\nexport function masonryConstruction(source: StructureSource): Construction {\n const unit = source.floorNumber !== undefined\n const covering = unit ? SLAB_COVERING : (source.facade.roof ?? 'colonial')\n const finish = source.facade.finish ?? 'roughcast'\n const budget = source.style === 'budget'\n const flat = unit || covering === SLAB_COVERING\n return {\n system: 'masonry',\n walls: { material: 'brick', cladding: PLASTERED_FINISHES.includes(finish) ? 'plaster' : null, finish, thickness: WALL_THICKNESS, ...(finish === 'exposed_block' ? { assembly: 'concrete_block_wall' } : {}) },\n floor: { material: budget ? 'concrete' : 'ceramic', finish: budget ? 'burnt_cement' : 'ceramic_tile' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'ceramic', covering, shape: flat ? 'slab' : 'gable', pitch: flat ? 0 : covering === 'colonial' ? 30 : 15, timber: 'wood_soft' },\n frame: { material: 'concrete', pillars: 'concrete', beams: 'concrete', slabs: 'concrete', timber: 'wood_soft', rebar: 'steel' },\n foundation: { type: unit ? 'building' : 'strip_footing', material: 'concrete', elevation: 0 },\n }\n}\n\nexport interface WoodFrameOptions {\n foundation?: 'basement' | 'crawl_space' | 'raft'\n covering?: string\n finish?: string\n /** Cladding of the outer face (default soft wood). */\n cladding?: string\n}\n\nconst FOUNDATIONS: Record<NonNullable<WoodFrameOptions['foundation']>, Construction['foundation']> = {\n basement: { type: 'basement', material: 'concrete', elevation: 0.5, depth: 2.4 },\n crawl_space: { type: 'crawl_space', material: 'concrete', elevation: 0.6 },\n raft: { type: 'raft', material: 'concrete', elevation: 0.2 },\n}\n\nconst TIMBER_FRAME: Construction['frame'] = { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'plywood', timber: 'wood_soft', rebar: null }\n\n/** American wood frame house: 38x89 studs every 40 cm, plaster inside, wood outside, asphalt shingles. */\nexport function woodFrameConstruction(options: WoodFrameOptions = {}): Construction {\n const covering = options.covering ?? 'asphalt'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'plaster', cladding: options.cladding ?? 'wood_soft', finish: options.finish ?? 'wood_siding', thickness: WALL_THICKNESS, studs: '38x89 every 40 cm', insulation: 'foam' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'plastic', covering, shape: 'gable', pitch: 28, timber: 'wood_soft', eave: 0.5 },\n frame: { ...TIMBER_FRAME },\n foundation: { ...FOUNDATIONS[options.foundation ?? 'raft'] },\n }\n}\n\nexport interface ChaletOptions {\n covering?: string\n finish?: string\n piles?: boolean\n}\n\n/** Mountain chalet: A-frame roof at 52 degrees with gables front and back, 38x140 studs. */\nexport function chaletConstruction(options: ChaletOptions = {}): Construction {\n const covering = options.covering ?? 'colonial'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'wood_soft', cladding: 'wood_hard', finish: options.finish ?? 'vertical_boards', thickness: WALL_THICKNESS, studs: '38x140 every 40 cm' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 52, timber: 'wood_soft', eave: 0.8, axis: 'v', profile: 'a_frame', gables: ['front', 'back'] },\n frame: { ...TIMBER_FRAME },\n foundation: options.piles ? { type: 'piles', material: 'stone', elevation: 0.9 } : { type: 'raft', material: 'concrete', elevation: 0.2 },\n }\n}\n\n/** Log cabin: every wall is a stack of 26 cm logs, notched at the corners, on stone piles. */\nexport function logCabinConstruction(options: { covering?: string } = {}): Construction {\n const covering = options.covering ?? 'wood'\n return {\n system: 'log',\n walls: { material: 'wood_hard', interior: 'wood_hard', cladding: null, finish: 'log', thickness: WALL_THICKNESS, logDiameter: 0.26, joint: 'notched_corners' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 32, timber: 'wood_hard', eave: 0.6 },\n frame: { material: 'wood_hard', pillars: 'wood_hard', beams: 'wood_hard', slabs: 'wood_hard', timber: 'wood_hard', rebar: null },\n foundation: { type: 'piles', material: 'stone', elevation: 0.5 },\n }\n}\n\nexport interface ShackOptions {\n material?: 'wood' | 'zinc' | 'mixed'\n floor?: 'soil' | 'concrete'\n}\n\nconst MIXED_SCRAP = ['wood_soft', 'steel', 'plywood', 'steel', 'wood_soft']\n\n/** Shack of scrap boards and zinc sheets: timber posts carry the roof, the walls only close. */\nexport function shackConstruction(options: ShackOptions = {}): Construction {\n const material = options.material === 'zinc' ? 'steel' : 'wood_soft'\n const onSoil = options.floor === 'soil'\n return {\n system: 'improvised',\n walls: { material, interior: options.material === 'zinc' ? 'plywood' : material, cladding: null, finish: 'scrap', thickness: WALL_THICKNESS, ...(options.material === 'mixed' ? { mixed: MIXED_SCRAP } : {}) },\n floor: onSoil ? { material: 'soil', finish: 'packed_earth' } : { material: 'concrete', finish: 'burnt_cement' },\n roof: { material: 'steel', covering: 'zinc', shape: 'gable', pitch: 12, timber: 'wood_soft', eave: 0.3, fastening: 'nails_and_stones' },\n frame: { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'concrete', timber: 'wood_soft', rebar: null },\n foundation: onSoil ? { type: 'ground', material: 'soil', elevation: 0 } : { type: 'raft', material: 'concrete', elevation: 0.08 },\n }\n}\n\n/** Camping: canvas over aluminium poles on the ground; there are no walls. */\nexport function campConstruction(): Construction {\n return {\n system: 'canvas',\n walls: { material: 'fabric', interior: 'fabric', cladding: null, finish: 'nylon', thickness: 0.002 },\n floor: { material: 'plastic', finish: 'waterproof_mat' },\n roof: { material: 'fabric', covering: 'canvas', shape: 'tent', pitch: 0, timber: 'aluminium', eave: 0 },\n frame: { material: 'aluminium', pillars: 'aluminium', beams: 'aluminium', slabs: 'plastic', timber: 'aluminium', rebar: null },\n foundation: { type: 'ground', material: 'soil', elevation: 0 },\n }\n}\n\n/** The construction a system gets on any plan when the options force it (`options.construction`). */\nexport function constructionOfSystem(system: string, source: StructureSource): Construction | undefined {\n const covering = source.facade.roof\n const keep = covering && covering !== SLAB_COVERING ? { covering } : {}\n switch (system) {\n case 'masonry':\n return masonryConstruction(source)\n case 'wood_frame':\n return woodFrameConstruction(keep)\n case 'log':\n return logCabinConstruction(keep)\n case 'improvised':\n return shackConstruction()\n case 'canvas':\n return campConstruction()\n default:\n return undefined\n }\n}\n\nexport type { FoundationType }\n","import { CONSTRUCTIONS } from './registry'\nimport type { ConstructionBuild } from './registry'\nimport { constructionOfSystem, masonryConstruction } from './presets'\nimport type { PlanContext, StructureSource, Tent } from './types'\n\n/** The construction of a plan: the one it already carries, else the masonry default of the engine's templates. */\nexport function resolveConstruction(source: StructureSource): ConstructionBuild {\n const extras = source.structureExtras ?? {}\n return { construction: source.construction ?? masonryConstruction(source), extras }\n}\n\nconst TENT_LABEL = /^tent_(dome|tunnel)(?:_|$)/\n\n/**\n * Tents of a plan whose template names the `canvas` construction and registers none of its own: one per room of type `tent`, standing on the room's footprint\n * (a label `tent_<kind>_<people>` names the kind, any other is a long tunnel) as high as the room's ceiling.\n */\nexport function tentsOf(source: StructureSource): Tent[] {\n const tents: Tent[] = []\n for (const room of source.rooms) {\n if (room.type !== 'tent' || room.floor !== 0 || !room.parts[0]) continue\n const { label } = room as { label?: unknown }\n tents.push({ id: room.id, kind: TENT_LABEL.exec(typeof label === 'string' ? label : '')?.[1] ?? 'tunnel', height: room.ceiling ?? source.floors[0]?.ceiling ?? 2.4, aabb: room.parts[0] })\n }\n return tents\n}\n\n/**\n * Picks the construction for a plan being generated: `options.construction` (a registered construction or a system name) wins over the template's\n * own (`TemplateDef.construction`), which wins over the masonry default.\n */\nexport function constructionFor(context: PlanContext): ConstructionBuild {\n const forced = context.options?.construction\n const named = typeof forced === 'string' ? forced : (context.template?.construction as string | undefined)\n if (named === undefined) return { construction: masonryConstruction(context.result) }\n const registered = CONSTRUCTIONS.get(named)\n if (registered) return registered(context)\n const preset = constructionOfSystem(named, context.result)\n if (preset) return { construction: preset, ...(named === 'canvas' ? { extras: { tents: tentsOf(context.result) } } : {}) }\n throw new Error(`Unknown construction \"${named}\": register it with registerConstruction`)\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Structure\",\n \"structure_column_concrete\": \"Concrete pillar\",\n \"structure_column_steel\": \"Steel post\",\n \"structure_column_masonry\": \"Masonry pillar\",\n \"structure_column_wood\": \"Wood post\",\n \"structure_beam_concrete\": \"Bond beam / beam (concrete)\",\n \"structure_beam_wood\": \"Plate / beam (wood)\",\n \"structure_roof_frame\": \"Trusses, rafters and ridge (roof view)\"\n },\n \"labels\": {\n \"elevator_lobby\": \"Elevator lobby\",\n \"service_shaft\": \"Service shaft\",\n \"plant_room\": \"Plant room\",\n \"mechanical_floor\": \"Mechanical floor\",\n \"typical_floor\": \"Typical floor\"\n }\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Estrutura\",\n \"structure_column_concrete\": \"Pilar de concreto\",\n \"structure_column_steel\": \"Poste de aço\",\n \"structure_column_masonry\": \"Pilar de alvenaria\",\n \"structure_column_wood\": \"Pilar de madeira\",\n \"structure_beam_concrete\": \"Cinta / viga (concreto)\",\n \"structure_beam_wood\": \"Prato / viga (madeira)\",\n \"structure_roof_frame\": \"Tesouras, caibros e cumeeira (vista do telhado)\"\n },\n \"labels\": {\n \"elevator_lobby\": \"Antessala dos elevadores\",\n \"service_shaft\": \"Shaft de serviço\",\n \"plant_room\": \"Casa de máquinas\",\n \"mechanical_floor\": \"Andar técnico\",\n \"typical_floor\": \"Andar tipo\"\n }\n}\n","import type { JointKind, MaterialId, StructureRole } from '@adatechnology/game-contracts'\n\n/** Axis-aligned rectangle `[u0, v0, u1, v1]` in the plan (metres). */\nexport type Rect = [number, number, number, number]\n\nexport type ConstructionSystem = 'masonry' | 'wood_frame' | 'log' | 'improvised' | 'canvas'\nexport type WallDetail = 'coarse' | 'panels' | 'units'\n/** What a structural part is called in a plan: a column is a pillar, `wall` is a bearing wall, `partition` a wall that only closes. */\nexport type PartRole = Exclude<StructureRole, 'foundation'>\n\nexport const GROUND = 'ground'\n\n/** A piece of the structure with its box in the plan, its height range and the mass it weighs. `y` is absolute: the ground floor sits at `foundation.elevation`. */\nexport interface StructurePart {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n floor: number\n mass: number\n /** Part this one is cut out of (a pier of a wall in `panels` detail). */\n host?: string\n /** Wall assembly of `game-destruction` the part is built from in the destructible spec (layers, units, rebar, breach). */\n assembly?: string\n /** A brick, block or log: the unit of a wall (`units` detail, log courses), not a piece of it. */\n unit?: true\n /** Distance between repeated members (joists, ceiling joists). */\n spacing?: number\n /** `plate` (timber top plate), `bond_beam` (masonry bond beam) or `ground_beam` (the masonry ground beam, viga baldrame, buried under a ground-floor wall). */\n beamKind?: 'plate' | 'bond_beam' | 'ground_beam'\n /** An exterior wall (it carries the bond beam and the pillars of confined masonry). */\n exterior?: true\n steps?: number\n door?: string\n /** Slab that is the roof (flat roof). */\n cover?: boolean\n /** Litres a tank holds. */\n liters?: number\n studs?: { spacing: number; section: string }\n pitch?: number\n tent?: string\n form?: string\n /** Rooms a concrete slab covers (the rectangles of the storey it carries); the slab itself is their bounding box. `toDestructibleSpec` cuts the slab into panels over it. */\n footprint?: Rect[]\n /** Slab the panel, beam or column was made for (`toDestructibleSpec` with `slabPanels`; a `StructurePart` of `buildStructure` never has it). */\n slab?: string\n}\n\n/** `part` rests on `on` (`GROUND` or another part) through `joint`. `bears: false` ties the two without carrying load. */\nexport interface Support {\n part: string\n on: string\n joint: JointKind\n bears?: false\n}\n\nexport interface RoofPane {\n id: string\n aabb: Rect\n y0: number\n y1: number\n flat?: true\n}\n\nexport type RoofShape = 'gable' | 'slab' | 'tent'\n\nexport interface Roof {\n shape: RoofShape\n covering: string\n material: MaterialId\n pitch: number\n /** Floor the roof rests on. */\n bearingFloor: number\n panes: (RoofPane | string)[]\n trusses: number\n axis?: 'u' | 'v'\n ridge?: number\n eave?: number\n y0?: number\n aabb?: Rect\n}\n\n/** A window in a wall (the doors are gaps between walls: a lintel part bridges them). Heights are absolute. */\nexport interface Opening {\n id: string\n kind: 'window' | 'door'\n wall: string\n /** Along the wall (u for a wall along u, v for one along v). */\n from: number\n to: number\n y0: number\n y1: number\n}\n\nexport interface Structure {\n parts: StructurePart[]\n supports: Support[]\n openings: Opening[]\n /** Absolute height of the floor level of each storey. */\n levels: number[]\n elevation: number\n roof: Roof\n construction: Construction\n /** A reinforced concrete frame carries the building (apartments, commercial buildings, three storeys or more); the walls are infill. */\n framed: boolean\n}\n\nexport interface WallMaterials {\n material: MaterialId\n interior?: MaterialId\n cladding?: MaterialId | null\n finish?: string\n /** Wall assembly of `game-destruction` (default by system, and by finish in masonry). */\n assembly?: string\n thickness: number\n studs?: string\n /** Materials drawn per wall by a hash of its legacy key (the improvised shack). */\n mixed?: MaterialId[]\n [extra: string]: unknown\n}\n\nexport interface Construction {\n system: ConstructionSystem\n walls: WallMaterials\n floor: { material: MaterialId; finish: string }\n roof: {\n material: MaterialId\n covering: string\n shape: RoofShape\n pitch: number\n timber: MaterialId\n eave?: number\n axis?: 'u' | 'v'\n bearingFloor?: number\n profile?: string\n gables?: string[]\n fastening?: string\n }\n frame: { material: MaterialId; pillars: MaterialId; beams: MaterialId; slabs: MaterialId; timber: MaterialId; rebar: MaterialId | null }\n foundation: { type: FoundationType; material: MaterialId; elevation: number; depth?: number }\n guard?: MaterialId\n stairs?: MaterialId\n}\n\nexport type FoundationType = 'strip_footing' | 'building' | 'raft' | 'crawl_space' | 'piles' | 'basement' | 'ground'\n\nexport interface Chimney {\n kind: 'fireplace' | 'flue'\n material: MaterialId\n aabb: Rect\n flue?: boolean\n top?: number\n height?: number\n}\n\nexport interface Tent {\n id: string\n kind: string\n height: number\n aabb: Rect\n}\n\n/** What a construction needs besides walls and roof, from the template: a chimney, a well, an attic floor, tents. */\nexport interface StructureExtras {\n chimney?: Chimney\n well?: { aabb: Rect; height?: number }\n attic?: boolean\n tents?: Tent[]\n [extra: string]: unknown\n}\n\nexport interface TankPlatform {\n aabb: Rect\n baseY: number\n height: number\n thickness: number\n topY: number\n pillars: { u: number; v: number; side: number }[]\n ladder: boolean\n}\n\nexport interface WaterTank {\n id: 'water_tank'\n kind: 'water_tank'\n itemType: string\n place: 'slab' | 'attic' | 'raised_slab' | 'trestle' | string\n floor: number\n room: string\n u: number\n v: number\n y: number\n w: number\n d: number\n h: number\n capacity: number\n material?: MaterialId\n aabb: Rect\n platform?: TankPlatform\n /** Trestle tank (a stand of its own: rural water). */\n stand?: { pillars: { u: number; v: number; side: number }[]; material: MaterialId; height: number; baseJoint?: JointKind; joint?: JointKind; tie?: JointKind; braces?: boolean }\n}\n\n/** The fields of a generated plan the structure reads. */\nexport interface StructureSource {\n floors: { y0: number; ceiling: number }[]\n rooms: { id: string; type: string; floor: number; parts: Rect[]; ceiling?: number | null }[]\n walls: SourceWall[]\n doors: SourceDoor[]\n windows?: SourceWindow[]\n items: { id?: string; type: string; category?: string; floor: number; aabb?: Rect; link?: { from: number; to: number } | string | null }[]\n facade: { roof?: string; finish?: string; [extra: string]: unknown }\n style?: string\n template?: string\n lot?: unknown\n w: number\n d: number\n floorNumber?: number\n waterTank?: WaterTank | null\n construction?: Construction\n structureExtras?: StructureExtras\n [extra: string]: unknown\n}\n\nexport interface SourceWall {\n floor: number\n axis: 'u' | 'v'\n u0: number\n v0: number\n u1: number\n v1: number\n thickness?: number\n sides: string[]\n exterior: boolean\n type: string\n h?: number\n /** Gable wall: the plate does not sit on top of it. */\n gable?: boolean\n structureHeight?: number\n}\n\nexport interface SourceWindow {\n id: string\n floor: number\n axis: 'u' | 'v'\n /** Coordinate of the wall line across its axis. */\n pos: number\n /** Centre along the wall. */\n at: number\n width: number\n y0: number\n y1: number\n}\n\nexport interface SourceDoor {\n id: string\n floor: number\n a: string\n b: string\n exterior?: boolean\n model?: string\n type?: string\n u: number\n v: number\n width: number\n side?: string | null\n axis: 'u' | 'v'\n steps?: number\n}\n\nexport interface StructureOptions {\n construction?: Construction\n extras?: StructureExtras\n tank?: WaterTank | null\n /** The porch roof is carried by its posts alone (the tie to the house wall carries nothing). Default: when the detail is not `coarse`. */\n porchRoofOnPostsOnly?: boolean\n /** Gable roofs as rafters of each side and a ridge beam (a side falls with the wall it rests on) instead of whole trusses. Default: when the detail is not `coarse`. */\n rafterRoof?: boolean\n wallDetail?: WallDetail\n /** `false`: no roof (a free-standing wall, a garden wall). Default `true`. */\n roof?: boolean\n /**\n * Concrete pillars along the exterior masonry walls besides the corner ones (at the free ends and door jambs, beside the windows, where walls meet and at\n * most every `spacing` metres, default `WALL_PILLAR_SPACING`). `false`: only the corner pillars. Default `true`.\n */\n wallPillars?: boolean | { spacing?: number }\n /** A reinforced concrete ground beam (viga baldrame) under each ground-floor wall of a masonry house on strip footings (`GROUND_BEAM_DEPTH` deep). Default `true`. */\n groundBeams?: boolean\n /** The sections the Visor de casas 3D drew below the NBR 6118 minimum (16 cm balcony pillars), for the team's golden only. Default `false`. */\n visorSections?: boolean\n}\n\n/** What a construction builder and the tank get to see: the generated plan, its seed and the template. */\nexport interface PlanContext {\n result: StructureSource\n seed: number | string\n /** The template definition (`TemplateDef`) when known: it may carry `tank` and `tankLocation` hooks. */\n template?: Record<string, unknown>\n options?: { floors?: number; [extra: string]: unknown }\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\n/** kg/m3 the plan structure weighs its parts with (the table of the Visor de casas 3D; a material outside it weighs like soft wood). */\nexport const DENSITY: Readonly<Record<string, number>> = {\n steel: 7850, cast_iron: 7200, aluminium: 2700, copper: 8900, wood_soft: 500, wood_hard: 800, plywood: 600, mdf: 750, glass: 2500,\n tempered_glass: 2500, ceramic: 2000, concrete: 2400, brick: 1800, plaster: 1000, stone: 2600, plastic: 950, rubber: 1100, fabric: 400,\n foam: 30, leather: 900, paper: 800, foliage: 100, green_wood: 900, cactus: 700, flesh_fruit: 900, wax: 900, soil: 1600,\n}\nexport const DEFAULT_DENSITY = 500\n\nexport const densityOf = (material: MaterialId): number => DENSITY[material] ?? DEFAULT_DENSITY\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { densityOf } from '../density'\nimport { round2 } from '../geometry'\nimport { GROUND } from '../types'\nimport type { PartRole, Rect, StructurePart, Support } from '../types'\n\nexport type PartExtras = Partial<Pick<StructurePart, 'host' | 'exterior' | 'spacing' | 'beamKind' | 'steps' | 'door' | 'cover' | 'studs' | 'pitch' | 'tent' | 'form' | 'liters' | 'assembly' | 'footprint'>>\nexport interface PartOptions extends PartExtras {\n floor?: number\n /** Solid fraction of the box (studs, trusses, tile roofs). */\n fill?: number\n}\n\nexport interface PartDraft {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n}\n\n/** Collects the parts and what each rests on. A part id is unique: a second one is a bug of the builder. */\nexport class StructureBuilder {\n readonly parts: StructurePart[] = []\n readonly supports: Support[] = []\n private readonly ids = new Set<string>()\n\n add(draft: PartDraft, options: PartOptions = {}): StructurePart {\n const { id, role, material, aabb, y0, y1 } = draft\n if (this.ids.has(id)) throw new Error(`Part repeated in the structure: ${id}`)\n this.ids.add(id)\n const { floor, fill, ...extras } = options\n const volume = Math.max(0, (aabb[2] - aabb[0]) * (aabb[3] - aabb[1]) * (y1 - y0)) * (fill ?? 1)\n const part: StructurePart = {\n id, role, material, aabb: aabb.map(round2) as Rect, y0: round2(y0), y1: round2(y1), floor: floor ?? 0,\n mass: Math.max(1, Math.round(volume * densityOf(material))),\n }\n for (const [key, value] of Object.entries(extras)) if (value !== undefined) (part as unknown as Record<string, unknown>)[key] = value\n this.parts.push(part)\n return part\n }\n\n rest(part: StructurePart | string, on: StructurePart | string, joint: JointKind): void {\n const id = typeof part === 'string' ? part : part.id\n const base = typeof on === 'string' ? on : on.id\n this.supports.push({ part: id, on: base === GROUND ? GROUND : base, joint })\n }\n\n has(id: string): boolean {\n return this.ids.has(id)\n }\n\n find(id: string): StructurePart | undefined {\n return this.parts.find((part) => part.id === id)\n }\n}\n","/** The string hash of the floor plan engine (`engine.hashString`), copied so that this package never imports the engine at run time. */\nexport function hashLegacyKey(key: string): number {\n let hash = 1779033703 ^ key.length\n for (let i = 0; i < key.length; i++) {\n hash = Math.imul(hash ^ key.charCodeAt(i), 3432918353)\n hash = (hash << 13) | (hash >>> 19)\n }\n hash = Math.imul(hash ^ (hash >>> 16), 2246822507)\n hash = Math.imul(hash ^ (hash >>> 13), 3266489909)\n return (hash ^ (hash >>> 16)) >>> 0\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\nimport { unionOf, wallBox, round2 } from '../geometry'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\nimport type { ConstructionSystemDef } from '../registry'\nimport { GROUND } from '../types'\nimport type { Construction, PartRole, Rect, Roof, StructureExtras, StructurePart, StructureSource, WaterTank, SourceWall } from '../types'\nimport { StructureBuilder } from './builder'\nimport { hashLegacyKey } from './legacy-key'\n\nexport const OPEN_ROOM_TYPES: readonly string[] = ['balcony', 'terrace', 'porch']\nconst GUARD_HEIGHT = 1.1\n\nexport interface BuildWall extends SourceWall {\n id: string\n /** The id the Visor de casas 3D gave the wall (`w<floor>_<index>`); seeded choices hash it so old seeds keep their draws. */\n legacyKey: string\n role: PartRole\n material: MaterialId\n box: Rect\n}\n\nexport interface PorchPosts {\n posts: StructurePart[]\n ceilingY: number\n}\n\ntype Base = StructurePart | typeof GROUND | undefined\n\n/** Everything the steps that build the structure share: the plan, the construction, the parts so far and what each storey rests on. */\nexport interface BuildContext {\n source: StructureSource\n construction: Construction\n system: ConstructionSystemDef\n extras: StructureExtras\n tank: WaterTank | null\n builder: StructureBuilder\n porchRoofOnPostsOnly: boolean\n /** Gable roofs are built as rafters of each side plus a ridge beam, so a side falls with the wall it rests on. */\n rafterRoof: boolean\n /** Most metres between the pillars along a masonry wall (`StructureOptions.wallPillars`); 0: only the corner pillars. */\n wallPillarSpacing: number\n /** `StructureOptions.visorSections`. */\n visorSections: boolean\n floorCount: number\n isUnit: boolean\n elevation: number\n isTimber: boolean\n walls: BuildWall[]\n wallParts: Map<string, StructurePart>\n /** The ground beam under each ground-floor masonry wall, by wall id (`addGroundBeams`). */\n groundBeams: Map<string, StructurePart>\n carriers: Map<number, StructurePart[]>\n plates: Map<number, StructurePart[]>\n pillars: Map<number, StructurePart[]>\n porches: Map<string, PorchPosts>\n base0: Base\n houseBox: Rect\n topBox: Rect\n hasBasement: boolean\n topSlab?: StructurePart\n ceilingJoists?: StructurePart[]\n roof: Roof\n level(floor: number): number\n ceilingOf(floor: number): number\n topOf(floor: number): number\n rectsOf(floor: number, exclude?: readonly string[]): Rect[]\n baseOf(floor: number): Base\n}\n\nexport interface ContextOptions {\n porchRoofOnPostsOnly: boolean\n rafterRoof: boolean\n wallPillarSpacing: number\n visorSections: boolean\n}\n\nexport function createContext(source: StructureSource, construction: Construction, extras: StructureExtras, tank: WaterTank | null, options: ContextOptions): BuildContext {\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)\n if (!system) throw new Error(`Unknown construction system \"${construction.system}\"`)\n const floorCount = source.floors.length\n const isUnit = source.floorNumber !== undefined\n const elevation = construction.foundation.elevation || 0\n const level = (floor: number): number => round2(elevation + (source.floors[floor]?.y0 ?? 0))\n const ceilingOf = (floor: number): number => source.floors[floor]?.ceiling ?? 0\n const topOf = (floor: number): number => (floor < floorCount - 1 && !isUnit ? level(floor + 1) - system.slabThickness : level(floor) + ceilingOf(floor))\n const rectsOf = (floor: number, exclude: readonly string[] = []): Rect[] =>\n source.rooms.filter((room) => room.floor === floor && !exclude.includes(room.type)).flatMap((room) => room.parts)\n const builder = new StructureBuilder()\n const context: BuildContext = {\n source, construction, system, extras, tank, builder, porchRoofOnPostsOnly: options.porchRoofOnPostsOnly, rafterRoof: options.rafterRoof, wallPillarSpacing: options.wallPillarSpacing, visorSections: options.visorSections, floorCount, isUnit, elevation, isTimber: system.timber,\n walls: [], wallParts: new Map(), groundBeams: new Map(), carriers: new Map(), plates: new Map(), pillars: new Map(), porches: new Map(), base0: GROUND,\n houseBox: [0, 0, 0, 0], topBox: [0, 0, 0, 0], hasBasement: false,\n roof: { shape: 'slab', covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n level, ceilingOf, topOf, rectsOf,\n baseOf: (floor) => (floor === 0 ? context.base0 : builder.find(`slab_${floor}`)),\n }\n const closed = rectsOf(0, ['balcony', 'porch'])\n context.houseBox = unionOf(closed.length ? closed : rectsOf(0))\n context.walls = classifyWalls(context)\n return context\n}\n\nconst isBearingOnTop = (wall: BuildWall, walls: readonly BuildWall[]): boolean => {\n const along = (w: SourceWall, pick: (a: number, b: number) => number): number => (w.axis === 'u' ? pick(w.u0, w.u1) : pick(w.v0, w.v1))\n const across = (w: SourceWall): number => (w.axis === 'u' ? w.v0 : w.u0)\n return walls.some(\n (other) =>\n other.floor === wall.floor + 1 && other.type === 'wall' && other.axis === wall.axis && Math.abs(across(other) - across(wall)) < 0.2 &&\n Math.min(along(wall, Math.max), along(other, Math.max)) - Math.max(along(wall, Math.min), along(other, Math.min)) > 0.3,\n )\n}\n\nfunction roleOf(context: BuildContext, wall: BuildWall, walls: readonly BuildWall[], porchIds: ReadonlySet<string>): PartRole {\n if (wall.type === 'railing') return 'partition'\n const { wallRole } = context.system\n if (wallRole === 'bearing') return 'wall'\n if (wallRole === 'partition') return 'partition'\n const bearingFloor = context.construction.roof.bearingFloor ?? context.floorCount - 1\n if (wall.floor > bearingFloor) return 'partition'\n if (wall.exterior || wall.sides.some((id) => porchIds.has(id))) return 'wall'\n return wall.floor < context.floorCount - 1 && isBearingOnTop(wall, walls) ? 'wall' : 'partition'\n}\n\nfunction materialOf(context: BuildContext, wall: BuildWall): MaterialId {\n const { walls, guard } = context.construction\n if (wall.type === 'railing') return guard ?? (context.isTimber ? 'wood_soft' : 'steel')\n if (walls.mixed?.length) return walls.mixed[hashLegacyKey(wall.legacyKey) % walls.mixed.length] as MaterialId\n return wall.exterior ? walls.material : (walls.interior ?? walls.material)\n}\n\nfunction classifyWalls(context: BuildContext): BuildWall[] {\n const countByFloor = new Map<number, number>()\n const all: BuildWall[] = context.source.walls.map((wall) => {\n const index = countByFloor.get(wall.floor) ?? 0\n countByFloor.set(wall.floor, index + 1)\n return { ...wall, id: `wall_${wall.floor}_${index}`, legacyKey: `w${wall.floor}_${index}`, role: 'wall', material: '', box: wallBox(wall) }\n })\n const built = all.filter((wall) => wall.type === 'wall' || wall.type === 'railing')\n const porchIds = new Set(context.source.rooms.filter((room) => room.type === 'porch').map((room) => room.id))\n for (const wall of built) {\n wall.role = roleOf(context, wall, built, porchIds)\n wall.material = materialOf(context, wall)\n }\n return built\n}\n\nexport const guardHeightOf = (wall: BuildWall): number => wall.h || GUARD_HEIGHT\n","import { GROUND } from '../types'\nimport { unionOf } from '../geometry'\nimport type { BuildContext } from './context'\n\n/** Cantilevered balconies: a slab tied to the floor of its storey, or on a pillar of its own when it is at ground level. */\nexport function addBalconies(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'balcony' && r.floor >= 0)) {\n const floor = room.floor\n const box = unionOf(room.parts)\n const base = floor === 0 ? undefined : context.baseOf(floor)\n const deck = builder.add({ id: `slab_${floor}_${room.id}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(floor) - system.slabThickness, y1: context.level(floor) }, { floor })\n if (base) {\n builder.rest(deck, base, system.joints.slab)\n continue\n }\n // a 20 cm pillar (NBR 6118); the Visor de casas 3D drew 16 cm\n const half = context.visorSections ? 0.08 : 0.1\n const pillar = builder.add({ id: `balcony_column_${room.id}`, role: 'column', material: construction.frame.pillars, aabb: [box[0] - half, box[1] - half, box[0] + half, box[1] + half], y0: 0, y1: context.level(floor) - system.slabThickness }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n builder.rest(deck, pillar, 'rebar')\n }\n}\n","import { GROUND } from '../types'\nimport type { Construction, Rect, Roof, Structure, StructureExtras } from '../types'\nimport { StructureBuilder } from './builder'\n\nconst GROUNDSHEET = 0.02\n\n/** Camping tents: canvas over aluminium poles, a plastic groundsheet and pegs with guy ropes; no walls. */\nexport function buildCanvasStructure(construction: Construction, extras: StructureExtras): Structure {\n const builder = new StructureBuilder()\n const panes: string[] = []\n for (const tent of extras.tents ?? []) {\n const [u0, v0, u1, v1] = tent.aabb\n const centreU = (u0 + u1) / 2\n const centreV = (v0 + v1) / 2\n const sheet = builder.add({ id: `groundsheet_${tent.id}`, role: 'slab', material: 'plastic', aabb: tent.aabb, y0: 0, y1: GROUNDSHEET }, { floor: 0, tent: tent.id })\n builder.rest(sheet, GROUND, 'resting')\n const canvas = builder.add({ id: `canvas_${tent.id}`, role: 'roof', material: 'fabric', aabb: tent.aabb, y0: GROUNDSHEET, y1: tent.height }, { floor: 0, fill: 0.04, tent: tent.id, form: tent.kind })\n panes.push(canvas.id)\n const poles: [Rect, number][] =\n tent.kind === 'tunnel'\n ? [0.25, 0.75].map((fraction, k): [Rect, number] => [[u0 + (u1 - u0) * fraction - 0.015, v0 + 0.05, u0 + (u1 - u0) * fraction + 0.015, v1 - 0.05], k])\n : [[[u0 + 0.05, centreV - 0.015, u1 - 0.05, centreV + 0.015], 0], [[centreU - 0.015, v0 + 0.05, centreU + 0.015, v1 - 0.05], 1]]\n for (const [aabb, k] of poles) {\n const pole = builder.add({ id: `pole_${tent.id}_${k}`, role: 'column', material: construction.frame.pillars, aabb, y0: GROUNDSHEET, y1: tent.height - GROUNDSHEET }, { floor: 0, fill: 0.05, tent: tent.id })\n builder.rest(pole, GROUND, 'resting')\n builder.rest(canvas, pole, 'tie')\n }\n const corners: [number, number][] = [[u0 - 0.2, v0 - 0.2], [u1 + 0.2, v0 - 0.2], [u0 - 0.2, v1 + 0.2], [u1 + 0.2, v1 + 0.2]]\n corners.forEach(([u, v], k) => {\n const peg = builder.add({ id: `peg_${tent.id}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - 0.02, v - 0.02, u + 0.02, v + 0.02], y0: 0, y1: 0.2 }, { floor: 0 })\n builder.rest(peg, GROUND, 'nail')\n builder.rest(canvas, peg, 'tie')\n })\n }\n const roof: Roof = { shape: 'tent', covering: 'canvas', material: 'fabric', pitch: 0, bearingFloor: 0, panes, trusses: 0 }\n return { parts: builder.parts, supports: builder.supports, levels: [0], elevation: 0, roof, construction, framed: false, openings: [] }\n}\n","import { GROUND } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst CHIMNEY_CLEARANCE_ABOVE_RIDGE = 0.6\n\n/** A masonry chimney or a stove flue next to the house, tied to the wall it touches, rising above the ridge. */\nexport function addChimney(context: BuildContext): void {\n const chimney = context.extras.chimney\n if (!chimney) return\n const { builder } = context\n const top = context.floorCount - 1\n const ridge = context.roof.ridge || context.level(top) + context.ceilingOf(top)\n const height = Math.max(ridge, chimney.top || 0) + CHIMNEY_CLEARANCE_ABOVE_RIDGE\n const part = builder.add({ id: 'chimney', role: 'column', material: chimney.material || 'brick', aabb: chimney.aabb, y0: chimney.flue ? context.level(0) : 0, y1: height }, { floor: 0, fill: chimney.flue ? 0.15 : 0.7 })\n if (chimney.flue) builder.rest(part, context.base0 ?? GROUND, 'resting')\n else builder.rest(part, GROUND, 'mortar')\n const walls = builder.parts.filter((wall) => wall.role === 'wall' && wall.floor === 0 && !wall.id.startsWith('basement') && touches(wall.aabb, part.aabb, 0.1))\n for (const wall of walls) builder.rest(part, wall, 'bolt')\n chimney.height = round2(height)\n}\n\n/** The stone mouth of a well. */\nexport function addWell(context: BuildContext): void {\n const well = context.extras.well\n if (!well) return\n const part = context.builder.add({ id: 'well', role: 'column', material: 'stone', aabb: well.aabb, y0: -0.5, y1: well.height || 0.9 }, { floor: 0, fill: 0.5 })\n context.builder.rest(part, GROUND, 'mortar')\n}\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, touches } from '../geometry'\nimport type { Rect, StructurePart } from '../types'\nimport type { BuildContext } from './context'\n\nexport interface JoistOptions {\n floor: number\n box: Rect\n thickness: number\n carriers: readonly StructurePart[]\n material: MaterialId\n joint: JointKind\n suffix?: string\n}\n\nconst JOIST_PITCH = 0.6\n\n/** Joists every 0.6 m under the floor of `floor`, each resting on what touches it from below (or the nearest carrier). */\nexport function addJoists(context: BuildContext, options: JoistOptions): StructurePart[] {\n const { floor, box, thickness, carriers, material, joint, suffix = '' } = options\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / JOIST_PITCH) + 1)\n const top = context.level(floor) - thickness * 0.15\n const out: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const centre = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [centre - 0.025, box[1], centre + 0.025, box[3]] : [box[0], centre - 0.025, box[2], centre + 0.025]\n const joist = context.builder.add({ id: `joist_${floor}${suffix}_${k}`, role: 'beam', material, aabb, y0: context.level(floor) - thickness, y1: top }, { floor, fill: 1, spacing: JOIST_PITCH })\n out.push(joist)\n const below = carriers.filter((carrier) => carrier.y0 <= top + 0.05)\n const touching = below.filter((carrier) => touches(aabb, carrier.aabb, 0.2))\n const pool = below.length ? below : carriers\n const chosen = touching.length ? touching : pool.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 1)\n for (const carrier of chosen) context.builder.rest(joist, carrier, joint)\n }\n return out\n}\n\n/** The deck (floor boards, slab) of `floor` on its joists. */\nexport function addDeck(context: BuildContext, id: string, material: MaterialId, options: Pick<JoistOptions, 'floor' | 'box' | 'thickness' | 'joint'>, joists: readonly StructurePart[]): StructurePart {\n const { floor, box, thickness, joint } = options\n const deck = context.builder.add({ id, role: 'slab', material, aabb: box, y0: context.level(floor) - thickness * 0.15, y1: context.level(floor) }, { floor })\n for (const joist of joists) context.builder.rest(deck, joist, joint)\n return deck\n}\n","import type { StructurePart, Rect } from '../types'\nimport { GROUND } from '../types'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\nconst raft = (context: BuildContext, thickness: number, material: string): StructurePart => {\n const [u0, v0, u1, v1] = context.houseBox\n const part = context.builder.add({ id: 'foundation_raft', role: 'slab', material, aabb: [u0 - 0.1, v0 - 0.1, u1 + 0.1, v1 + 0.1], y0: 0, y1: thickness }, { floor: 0 })\n context.builder.rest(part, GROUND, 'resting')\n return part\n}\n\n/** A unit in a building: the building's pillars go down to the ground and carry a slab under the unit. */\nfunction addBuildingBase(context: BuildContext): void {\n const { builder, construction, houseBox: box } = context\n const corners: [number, number][] = [[box[0], box[1]], [box[2], box[1]], [box[0], box[3]], [box[2], box[3]]]\n const top = context.level(0) - context.system.slabThickness\n const pillars = corners.map(([u, v], k) => {\n const pillar = builder.add({ id: `building_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: 0, y1: top }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'slab_base', role: 'slab', material: construction.frame.slabs, aabb: box, y0: top, y1: context.level(0) }, { floor: 0, footprint: [box] })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n context.base0 = slab\n}\n\nfunction addBasement(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation } = context\n const depth = context.construction.foundation.depth || 2.4\n const floor = builder.add({ id: 'basement_slab', role: 'slab', material: 'concrete', aabb: box, y0: -depth - 0.15, y1: -depth }, { floor: -1 })\n builder.rest(floor, GROUND, 'resting')\n const sides: [string, Rect][] = [\n ['front', [box[0], box[1] - 0.1, box[2], box[1] + 0.1]], ['back', [box[0], box[3] - 0.1, box[2], box[3] + 0.1]],\n ['left', [box[0] - 0.1, box[1], box[0] + 0.1, box[3]]], ['right', [box[2] - 0.1, box[1], box[2] + 0.1, box[3]]],\n ]\n const carried: StructurePart[] = []\n for (const [name, aabb] of sides) {\n const wall = builder.add({ id: `basement_wall_${name}`, role: 'wall', material: 'concrete', aabb, y0: -depth, y1: elevation }, { floor: -1 })\n builder.rest(wall, GROUND, 'rebar')\n builder.rest(wall, floor, 'rebar')\n carried.push(wall)\n }\n const count = Math.max(1, Math.floor((box[2] - box[0]) / 3.0))\n for (let k = 0; k < count; k++) {\n const u = box[0] + ((k + 0.5) * (box[2] - box[0])) / count\n const v = (box[1] + box[3]) / 2\n const column = builder.add({ id: `basement_column_${k}`, role: 'column', material: 'concrete', aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: -depth, y1: elevation - 0.3 }, { floor: -1 })\n builder.rest(column, floor, 'rebar')\n builder.rest(column, GROUND, 'rebar')\n carried.push(column)\n }\n context.hasBasement = true\n return carried\n}\n\n/** Pier footings every ~2 m with a base beam through each line of them (crawl space, piles). */\nfunction addPiers(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation, construction } = context\n const columns = Math.max(2, Math.ceil((box[2] - box[0]) / 2.0) + 1)\n const rows = Math.max(2, Math.ceil((box[3] - box[1]) / 2.0) + 1)\n const height = Math.max(0.1, elevation - context.system.slabThickness - 0.15)\n const piers: StructurePart[] = []\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < columns; i++) {\n const u = box[0] + (i * (box[2] - box[0])) / (columns - 1)\n const v = box[1] + (j * (box[3] - box[1])) / (rows - 1)\n const pier = builder.add({ id: `footing_pier_${j}_${i}`, role: 'column', material: construction.foundation.material || 'concrete', aabb: [u - 0.12, v - 0.12, u + 0.12, v + 0.12], y0: 0, y1: height }, { floor: 0 })\n builder.rest(pier, GROUND, 'resting')\n piers.push(pier)\n }\n }\n const alongU = box[2] - box[0] >= box[3] - box[1]\n const beams: StructurePart[] = []\n const lines = alongU ? rows : columns\n for (let line = 0; line < lines; line++) {\n const at = alongU ? box[1] + (line * (box[3] - box[1])) / (rows - 1) : box[0] + (line * (box[2] - box[0])) / (columns - 1)\n const aabb: Rect = alongU ? [box[0], at - 0.07, box[2], at + 0.07] : [at - 0.07, box[1], at + 0.07, box[3]]\n const beam = builder.add({ id: `base_beam_${line}`, role: 'beam', material: construction.frame.timber, aabb, y0: height, y1: elevation - context.system.slabThickness }, { floor: 0 })\n const centre = (q: StructurePart): number => (alongU ? (q.aabb[1] + q.aabb[3]) / 2 : (q.aabb[0] + q.aabb[2]) / 2)\n for (const pier of piers.filter((q) => Math.abs(centre(q) - at) < 0.05)) builder.rest(beam, pier, 'bolt')\n beams.push(beam)\n }\n return beams\n}\n\nfunction addRaisedFloor(context: BuildContext): void {\n const { construction, system, houseBox: box } = context\n const carriers = construction.foundation.type === 'basement' ? addBasement(context) : addPiers(context)\n const thickness = system.slabThickness\n const joists = addJoists(context, { floor: 0, box, thickness, carriers, material: construction.frame.timber, joint: construction.foundation.type === 'basement' ? 'bolt' : 'nail' })\n const deckMaterial = context.isTimber ? (construction.floor.material === 'wood_hard' ? 'wood_hard' : 'plywood') : construction.frame.slabs\n context.base0 = addDeck(context, 'slab_0', deckMaterial, { floor: 0, box, thickness, joint: 'nail' }, joists)\n}\n\n/** Foundation and floor of the ground storey: raft, crawl space, piles, basement, a unit's building base or nothing (strip footing). */\nexport function addFoundation(context: BuildContext): void {\n const { type, material } = context.construction.foundation\n if (context.isUnit) return addBuildingBase(context)\n if (type === 'raft') context.base0 = raft(context, Math.max(0.1, context.elevation), material || 'concrete')\n else if (type === 'crawl_space' || type === 'piles' || type === 'basement') addRaisedFloor(context)\n else if (context.isTimber && type !== 'ground') context.base0 = raft(context, Math.max(0.12, context.elevation), 'concrete')\n}\n","import { GROUND } from '../types'\nimport type { StructurePart } from '../types'\nimport type { BuildContext } from './context'\n\n/** Depth of the ground beam (viga baldrame) under a ground-floor masonry wall, metres: the usual 15 x 30 cm, as wide as the wall. */\nexport const GROUND_BEAM_DEPTH = 0.3\n\n/**\n * The ground beams of a masonry house on strip footings: one reinforced concrete beam under each ground-floor wall, buried with its top at the floor, cast\n * on the footing. The wall stands on it instead of on the soil; the pillars go down through it to the footing.\n */\nexport function addGroundBeams(context: BuildContext): void {\n const { builder, construction } = context\n if (construction.system !== 'masonry' || context.isUnit || construction.foundation.type !== 'strip_footing') return\n const top = context.level(0)\n for (const wall of context.walls) {\n if (wall.floor !== 0 || wall.type !== 'wall') continue\n const beam: StructurePart = builder.add({ id: `ground_beam_${context.groundBeams.size}`, role: 'beam', material: construction.frame.beams, aabb: wall.box, y0: top - GROUND_BEAM_DEPTH, y1: top }, { floor: 0, beamKind: 'ground_beam' })\n builder.rest(beam, GROUND, 'rebar')\n context.groundBeams.set(wall.id, beam)\n }\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext, BuildWall } from './context'\n\n/**\n * Most a masonry wall runs between two of its concrete pillars, metres. Confined masonry (alvenaria confinada / de vedação with a concrete frame) puts a pillar\n * every 3 to 5 m, at the corners, where walls meet and beside the openings; 4 m is the middle of that range.\n */\nexport const WALL_PILLAR_SPACING = 4\n/** Side of a wall pillar, metres: 0.2 x 0.2 m, as the corner pillars (NBR 6118 asks at least 19 cm for a pillar). */\nexport const WALL_PILLAR_SIDE = 0.2\n/** Two pillars closer than this along a wall are one (the corner pillar or a jamb pillar already stands there). */\nconst MERGE_DISTANCE = 0.45\nconst HALF = WALL_PILLAR_SIDE / 2\nconst TOLERANCE = 0.03\n\ninterface Stretch {\n wall: BuildWall\n from: number\n to: number\n}\n\nconst alongRange = (wall: BuildWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\nconst acrossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\n\n/** The solid stretches of a wall: the wall cut at its windows (a door is already a gap between two walls). */\nfunction stretchesOf(context: BuildContext, wall: BuildWall): Stretch[] {\n const [low, high] = alongRange(wall)\n const windows = (context.source.windows ?? [])\n .filter((w) => w.floor === wall.floor && w.axis === wall.axis && Math.abs(w.pos - acrossOf(wall)) <= TOLERANCE && w.at + w.width / 2 > low && w.at - w.width / 2 < high)\n .map((w): [number, number] => [w.at - w.width / 2, w.at + w.width / 2])\n .sort((a, b) => a[0] - b[0])\n const out: Stretch[] = []\n let cursor = low\n for (const [from, to] of windows) {\n if (from - cursor > TOLERANCE) out.push({ wall, from: cursor, to: from })\n cursor = Math.max(cursor, to)\n }\n if (high - cursor > TOLERANCE) out.push({ wall, from: cursor, to: high })\n return out\n}\n\n/** Where another wall meets this one inside its length (a T): the along coordinates of the meeting points. */\nfunction junctionsOf(context: BuildContext, wall: BuildWall): number[] {\n const [low, high] = alongRange(wall)\n const line = acrossOf(wall)\n const out: number[] = []\n for (const other of context.walls) {\n if (other === wall || other.floor !== wall.floor || other.axis === wall.axis || other.type !== 'wall') continue\n const at = acrossOf(other)\n const [a, b] = alongRange(other)\n const meets = Math.abs(a - line) <= (wall.thickness ?? 0.15) / 2 + TOLERANCE || Math.abs(b - line) <= (wall.thickness ?? 0.15) / 2 + TOLERANCE\n if (meets && at > low + HALF && at < high - HALF) out.push(at)\n }\n return out\n}\n\n/**\n * Centres of the pillars of a stretch: at each end (inside the stretch, flush with it), at the walls that meet it, and in between so that no span passes\n * `spacing`. A short pier still gets one at each end (a door jamb beside a corner keeps its own pillar; `addWallPillars` drops the one a pillar already\n * stands near); one too short for two gets one in its middle, and one too short for a pillar none.\n */\nexport function pillarStations(from: number, to: number, junctions: readonly number[], spacing: number): number[] {\n const length = to - from\n if (length < WALL_PILLAR_SIDE - 1e-6) return []\n if (length < 2 * WALL_PILLAR_SIDE) return [(from + to) / 2]\n if (length < WALL_PILLAR_SIDE + MERGE_DISTANCE) return [from + HALF, to - HALF]\n const fixed = [from + HALF, ...junctions.filter((at) => at > from + HALF + MERGE_DISTANCE && at < to - HALF - MERGE_DISTANCE), to - HALF].sort((a, b) => a - b)\n const out: number[] = []\n fixed.forEach((at, k) => {\n out.push(at)\n const next = fixed[k + 1]\n if (next === undefined) return\n const spans = Math.ceil((next - at) / spacing - 1e-6)\n for (let s = 1; s < spans; s++) out.push(at + ((next - at) * s) / spans)\n })\n return out\n}\n\n/**\n * Concrete pillars along the exterior masonry walls of a storey, besides the corner pillars: at the free ends and door jambs, beside the windows, where an\n * inner wall meets them and at most every `spacing` metres. Each is as deep as the wall's centre line (0.2 x 0.2 m, so it sits in the wall under the\n * plaster), rests on what the storey rests on and carries the bond beam over it, so the bond beam stands on the pillars when the bricks under it go.\n */\nexport function addWallPillars(context: BuildContext, walls: readonly BuildWall[], floor: number, plates: readonly StructurePart[], taken: readonly StructurePart[], spacing: number): StructurePart[] {\n const { builder } = context\n const pillars: StructurePart[] = []\n const placed: [number, number][] = taken.map((p) => [(p.aabb[0] + p.aabb[2]) / 2, (p.aabb[1] + p.aabb[3]) / 2])\n const base = context.baseOf(floor)\n for (const wall of walls) {\n if (!wall.exterior || wall.type !== 'wall') continue\n const top = context.wallParts.get(wall.id)!.y1\n const across = acrossOf(wall)\n const junctions = junctionsOf(context, wall)\n for (const stretch of stretchesOf(context, wall)) {\n // a pillar already standing at an end of the stretch (a corner, the end of the next wall) is where the spacing counts from\n const standing = (end: number): number | undefined => placed.map(([pu, pv]) => (wall.axis === 'u' ? [pu, pv] : [pv, pu]) as [number, number]).find(([a, c]) => Math.abs(c - across) <= TOLERANCE && Math.abs(a - end) < MERGE_DISTANCE + HALF)?.[0]\n const first = standing(stretch.from)\n const last = standing(stretch.to)\n const from = first === undefined ? stretch.from : Math.min(stretch.from, first - HALF)\n const to = last === undefined ? stretch.to : Math.max(stretch.to, last + HALF)\n for (const along of pillarStations(from, to, junctions, spacing)) {\n const [u, v] = wall.axis === 'u' ? [along, across] : [across, along]\n // a pillar near the end of a stretch only stands for it when it is near the end itself (a short pier keeps its jamb pillar)\n const end = Math.abs(along - stretch.from) < Math.abs(along - stretch.to) ? stretch.from : stretch.to\n const endPoint = wall.axis === 'u' ? [end, across] : [across, end]\n const isEnd = Math.abs(along - end) <= HALF + TOLERANCE\n if (placed.some(([pu, pv]) => Math.hypot(pu - u, pv - v) < MERGE_DISTANCE && (!isEnd || Math.hypot(pu - endPoint[0]!, pv - endPoint[1]!) < MERGE_DISTANCE))) continue\n placed.push([u, v])\n const box: Rect = [u - HALF, v - HALF, u + HALF, v + HALF]\n const pillar = builder.add({ id: `wall_column_${floor}_${pillars.length}`, role: 'column', material: context.construction.frame.pillars, aabb: box, y0: context.level(floor), y1: top }, { floor })\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n for (const plate of plates.filter((p) => touches(p.aabb, box, 0.01))) builder.rest(plate, pillar, 'rebar')\n pillars.push(pillar)\n }\n }\n }\n return pillars\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext, BuildWall } from './context'\nimport { addWallPillars } from './wall-pillars'\n\nconst MAX_GAP_WITHIN_RUN = 3.2\nconst POST_SPACING = 2.4\nconst POST_SIDE = 0.05\n\ninterface Run {\n from: number\n to: number\n walls: BuildWall[]\n}\n\nconst alongOf = (wall: BuildWall, pick: (a: number, b: number) => number): number => (wall.axis === 'u' ? pick(wall.u0, wall.u1) : pick(wall.v0, wall.v1))\nconst acrossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\n\n/** Continuous runs of exterior wall on one line and height: a plate or bond beam runs along each. */\nfunction runsOf(context: BuildContext, walls: readonly BuildWall[], floor: number): Run[][] {\n const lines = new Map<string, BuildWall[]>()\n for (const wall of walls) {\n if (!wall.exterior || wall.type !== 'wall') continue\n const top = round2(context.wallParts.get(wall.id)!.y1)\n const key = `${floor}|${wall.axis}|${acrossOf(wall).toFixed(2)}|${top.toFixed(2)}`\n lines.set(key, [...(lines.get(key) ?? []), wall])\n }\n return [...lines.values()].map((line) => {\n const sorted = line.slice().sort((a, b) => alongOf(a, Math.min) - alongOf(b, Math.min))\n const runs: Run[] = []\n for (const wall of sorted) {\n const from = alongOf(wall, Math.min)\n const to = alongOf(wall, Math.max)\n const last = runs[runs.length - 1]\n if (last && from - last.to <= MAX_GAP_WITHIN_RUN) {\n last.to = Math.max(last.to, to)\n last.walls.push(wall)\n } else runs.push({ from, to, walls: [wall] })\n }\n return runs\n })\n}\n\n/** Timber posts of a shack: the corner and every ~2.4 m carry the plate; the sheet walls only close. */\nfunction addShackPosts(context: BuildContext, run: Run, plate: StructurePart, floor: number, index: number): StructurePart[] {\n const first = run.walls[0]!\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const count = Math.max(1, Math.ceil((run.to - run.from) / POST_SPACING))\n const posts: StructurePart[] = []\n for (let k = 0; k <= count; k++) {\n const along = run.from + ((run.to - run.from) * k) / count\n const [u, v] = first.axis === 'u' ? [along, across] : [across, along]\n const half = 0.05 + POST_SIDE / 2\n const post = context.builder.add({ id: `post_${floor}_${index}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - half, v - half, u + half, v + half], y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n if (base === GROUND || !base) context.builder.rest(post, GROUND, 'tie')\n else context.builder.rest(post, base, 'nail')\n context.builder.rest(plate, post, 'nail')\n posts.push(post)\n }\n return posts\n}\n\nexport interface PlatesResult {\n plates: StructurePart[]\n pillars: StructurePart[]\n}\n\nfunction addPlates(context: BuildContext, walls: readonly BuildWall[], floor: number): PlatesResult {\n const { builder, system, construction } = context\n const plates: StructurePart[] = []\n const pillars: StructurePart[] = []\n let counter = 0\n for (const runs of runsOf(context, walls, floor)) {\n for (const run of runs) {\n const first = run.walls[0]!\n const half = (first.thickness ?? 0.15) / 2\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const aabb: Rect = first.axis === 'u' ? [run.from - half, across - half, run.to + half, across + half] : [across - half, run.from - half, across + half, run.to + half]\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const plate = builder.add({ id: `plate_${floor}_${counter++}`, role: 'beam', material, aabb, y0: top, y1: top + system.plateThickness }, { floor, beamKind: context.isTimber ? 'plate' : 'bond_beam' })\n if (construction.system === 'improvised') pillars.push(...addShackPosts(context, run, plate, floor, counter))\n else for (const wall of run.walls) builder.rest(plate, context.wallParts.get(wall.id)!, system.joints.beam)\n plates.push(plate)\n }\n }\n return { plates, pillars }\n}\n\nfunction cornerPoints(walls: readonly BuildWall[]): [number, number][] {\n const ends = walls\n .filter((wall) => wall.exterior && wall.type === 'wall')\n .flatMap((wall): [number, number, string][] =>\n wall.axis === 'u'\n ? [[Math.min(wall.u0, wall.u1), wall.v0, 'u'], [Math.max(wall.u0, wall.u1), wall.v0, 'u']]\n : [[wall.u0, Math.min(wall.v0, wall.v1), 'v'], [wall.u0, Math.max(wall.v0, wall.v1), 'v']],\n )\n const points: [number, number][] = []\n for (const a of ends) {\n const joinsOtherAxis = ends.some((b) => b[2] !== a[2] && Math.hypot(a[0] - b[0], a[1] - b[1]) < 0.12)\n if (joinsOtherAxis && !points.some((q) => Math.hypot(q[0] - a[0], q[1] - a[1]) < 0.12)) points.push([a[0], a[1]])\n }\n return points\n}\n\n/** Concrete corner pillars of a masonry storey where two exterior walls of different axes meet; they run up to the highest plate they touch. */\nfunction addCornerPillars(context: BuildContext, walls: readonly BuildWall[], floor: number, plates: readonly StructurePart[]): StructurePart[] {\n const { builder } = context\n const topOfFloor = context.topOf(floor)\n return cornerPoints(walls).map(([u, v], k) => {\n const box: Rect = [u - 0.1, v - 0.1, u + 0.1, v + 0.1]\n const top = Math.max(topOfFloor, ...plates.filter((plate) => touches(plate.aabb, box, 0.05)).map((plate) => plate.y0))\n const pillar = builder.add({ id: `column_${floor}_${k}`, role: 'column', material: context.construction.frame.pillars, aabb: box, y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n for (const plate of plates.filter((p) => touches(p.aabb, pillar.aabb, 0.05))) builder.rest(plate, pillar, 'rebar')\n return pillar\n })\n}\n\n/** Plates (bond beams) over the exterior walls of a storey and, in masonry, the corner pillars and the pillars along the walls (`addWallPillars`); records what carries the storey above. */\nexport function addPlatesAndPillars(context: BuildContext, floor: number): void {\n const walls = context.walls.filter((wall) => wall.floor === floor)\n const { plates, pillars } = addPlates(context, walls, floor)\n if (context.construction.system === 'masonry') {\n const corners = addCornerPillars(context, walls, floor, plates)\n pillars.push(...corners)\n if (context.wallPillarSpacing) pillars.push(...addWallPillars(context, walls, floor, plates, corners, context.wallPillarSpacing))\n }\n context.pillars.set(floor, pillars)\n context.plates.set(floor, plates)\n const innerBearing = walls.filter((wall) => wall.role === 'wall' && !wall.exterior).map((wall) => context.wallParts.get(wall.id)!)\n context.carriers.set(floor, [...plates, ...pillars, ...innerBearing])\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst POST_HALF = 0.08\nconst FOOTING_HALF = 0.12\nconst BEAM_DEPTH = 0.2\nconst BEAM_WIDTH = 0.16\n\n/** Footings and posts under the porch roof: two at the front corners and one more in the middle of a wide porch. */\nfunction addPosts(context: BuildContext, porchId: string, rect: Rect, deck: StructurePart, floor: number): StructurePart[] {\n const { builder, construction } = context\n const hasUpperFloor = floor < context.floorCount - 1\n const ceilingY = hasUpperFloor ? context.level(floor + 1) - context.system.slabThickness : context.level(floor) + context.ceilingOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const spots: [number, number][] = [[rect[0] + 0.1, rect[1] + 0.1], [rect[2] - 0.1, rect[1] + 0.1]]\n if (rect[2] - rect[0] > 4.5) spots.push([(rect[0] + rect[2]) / 2, rect[1] + 0.1])\n const posts = spots.map(([u, v], k) => {\n const footing = builder.add({ id: `porch_footing_${porchId}_${k}`, role: 'column', material: 'concrete', aabb: [u - FOOTING_HALF, v - FOOTING_HALF, u + FOOTING_HALF, v + FOOTING_HALF], y0: 0, y1: context.level(floor) - deckDepth }, { floor: 0 })\n builder.rest(footing, GROUND, 'resting')\n builder.rest(deck, footing, 'resting')\n const material = context.isTimber ? construction.frame.timber : construction.frame.pillars\n const post = builder.add({ id: `porch_post_${porchId}_${k}`, role: 'column', material, aabb: [u - POST_HALF, v - POST_HALF, u + POST_HALF, v + POST_HALF], y0: context.level(floor), y1: hasUpperFloor ? ceilingY - BEAM_DEPTH : ceilingY }, { floor })\n builder.rest(post, deck, context.isTimber ? 'nail' : 'rebar')\n return post\n })\n context.porches.set(porchId, { posts, ceilingY })\n return posts\n}\n\n/** With a storey above the porch, a head beam over the posts and two side beams carry the floor of that storey. */\nfunction addUpperBeams(context: BuildContext, porchId: string, rect: Rect, posts: StructurePart[], floor: number): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const joint = context.isTimber ? 'nail' : 'rebar'\n const ceilingY = context.porches.get(porchId)!.ceilingY\n const y0 = ceilingY - BEAM_DEPTH\n const carriers = context.carriers.get(floor)!\n const head = builder.add({ id: `porch_beam_${porchId}`, role: 'beam', material, aabb: [rect[0], rect[1], rect[2], rect[1] + BEAM_WIDTH], y0, y1: ceilingY }, { floor })\n for (const post of posts) builder.rest(head, post, joint)\n carriers.push(head)\n const sides: [string, Rect, StructurePart][] = [['e', [rect[0], rect[1], rect[0] + BEAM_WIDTH, rect[3]], posts[0]!], ['d', [rect[2] - BEAM_WIDTH, rect[1], rect[2], rect[3]], posts[1]!]]\n for (const [name, aabb, post] of sides) {\n const side = builder.add({ id: `porch_beam_${porchId}_${name}`, role: 'beam', material, aabb, y0, y1: ceilingY }, { floor })\n builder.rest(side, post, joint)\n builder.rest(side, head, joint)\n for (const wall of context.walls.filter((w) => w.floor === floor && w.role === 'wall' && touches(w.box, side.aabb, 0.3))) builder.rest(side, context.wallParts.get(wall.id)!, joint)\n carriers.push(side)\n }\n}\n\n/** Deck, footings, posts (concrete in masonry, wood in timber houses) and, with a storey above, the beams of every porch of the storey. */\nexport function addPorches(context: BuildContext, floor: number): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch' && r.floor === floor)) {\n const rect = room.parts[0]!\n const base = context.baseOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const deck = builder.add({ id: `porch_floor_${room.id}`, role: 'slab', material: context.isTimber ? 'wood_soft' : construction.frame.slabs, aabb: rect, y0: context.level(floor) - deckDepth, y1: context.level(floor) }, { floor })\n if (base && base !== GROUND) builder.rest(deck, base, context.isTimber ? 'nail' : context.system.joints.slab)\n const posts = addPosts(context, room.id, rect, deck, floor)\n if (floor < context.floorCount - 1) addUpperBeams(context, room.id, rect, posts, floor)\n }\n}\n","import { ROOF_COVERINGS } from '../registry'\nimport type { BuildContext } from './context'\n\nconst ROOF_RISE = 0.6\n\n/** A porch under the top storey has a roof of its own, resting on its posts and on the wall of the house. */\nexport function addPorchRoofs(context: BuildContext): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const floor = room.floor\n const rect = room.parts[0]!\n const posts = context.porches.get(room.id)\n if (floor !== context.floorCount - 1 || !posts) continue\n const material = ROOF_COVERINGS.get(construction.roof.covering)?.material ?? 'ceramic'\n const roof = builder.add({ id: `porch_roof_${room.id}`, role: 'roof', material, aabb: [rect[0] - 0.3, rect[1] - 0.5, rect[2] + 0.3, rect[3]], y0: posts.ceilingY, y1: posts.ceilingY + ROOF_RISE }, { floor })\n for (const post of posts.posts) builder.rest(roof, post, context.isTimber ? 'nail' : 'bolt')\n const housewalls = context.walls.filter((w) => w.floor === floor && !w.exterior && w.sides.includes(room.id) && w.type === 'wall')\n for (const wall of housewalls) {\n if (context.porchRoofOnPostsOnly) builder.supports.push({ part: roof.id, on: wall.id, joint: 'nail', bears: false })\n else builder.rest(roof, context.wallParts.get(wall.id)!, 'nail')\n }\n }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, round2, touches, unionOf } from '../geometry'\nimport { ROOF_COVERINGS } from '../registry'\nimport type { Rect, RoofPane, StructurePart } from '../types'\nimport type { BuildContext } from './context'\nimport { OPEN_ROOM_TYPES } from './context'\n\nconst TRUSS_PITCH = 1.2\nconst DEFAULT_PITCH = 20\nconst DEFAULT_EAVE = 0.4\nconst CLOSED_ONLY: readonly string[] = [...OPEN_ROOM_TYPES, 'void']\n\ninterface RoofUnit {\n suffix: string\n box: Rect\n floor: number\n annex: boolean\n}\n\n/** The main roof, plus an own roof for every room of a lower storey that the storey above does not cover (a ground floor wider than the upper one). */\nfunction roofUnits(context: BuildContext, bearing: number): RoofUnit[] {\n const units: RoofUnit[] = [{ suffix: '', box: context.topBox, floor: bearing, annex: false }]\n if (context.floorCount <= 1 || context.isUnit || bearing !== context.floorCount - 1) return units\n for (let floor = 0; floor < context.floorCount - 1; floor++) {\n const above = context.source.rooms.filter((room) => room.floor === floor + 1).flatMap((room) => room.parts)\n const rooms = context.source.rooms.filter((room) => room.floor === floor && !OPEN_ROOM_TYPES.includes(room.type) && room.type !== 'void' && room.type !== 'elevator')\n for (const room of rooms) {\n const area = room.parts.reduce((total, part) => total + (part[2] - part[0]) * (part[3] - part[1]), 0)\n const covered = room.parts.reduce((total, part) => total + above.reduce((sum, other) => sum + Math.max(0, Math.min(part[2], other[2]) - Math.max(part[0], other[0])) * Math.max(0, Math.min(part[3], other[3]) - Math.max(part[1], other[1])), 0), 0)\n if (covered < area * 0.7) units.push({ suffix: `_${room.id}`, box: unionOf(room.parts), floor, annex: true })\n }\n }\n return units\n}\n\n/** Everything that carries the roof of one unit: the plates at its height, the pillars and the inner bearing walls under it. */\nfunction roofCarriers(context: BuildContext, unit: RoofUnit): StructurePart[] {\n const platesHere = context.plates.get(unit.floor) ?? []\n const allPlates = [...context.plates.values()].flat()\n const eaveHeight = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : 0\n const plates = allPlates.filter((plate) => Math.abs(plate.y1 - eaveHeight) < 0.4 && touches(plate.aabb, unit.box, 0.3))\n const pillars = (context.pillars.get(unit.floor) ?? []).filter((pillar) => touches(pillar.aabb, unit.box, 0.3))\n const walls = context.walls.filter((wall) => wall.floor === unit.floor && wall.role === 'wall' && !wall.exterior && touches(wall.box, unit.box, 0.2)).map((wall) => context.wallParts.get(wall.id)!)\n return [...plates, ...pillars, ...walls]\n}\n\nfunction addFlatRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[]): RoofPane {\n const { builder, construction, system } = context\n const top = context.level(unit.floor) + context.ceilingOf(unit.floor)\n const [u0, v0, u1, v1] = unit.box\n const slab = builder.add({ id: `slab_top${unit.suffix}`, role: 'slab', material: construction.frame.slabs, aabb: [u0 - 0.15, v0 - 0.15, u1 + 0.15, v1 + 0.15], y0: top, y1: top + 0.12 }, { floor: unit.floor, cover: true, footprint: [unit.box] })\n for (const carrier of carriers.length ? carriers : (context.plates.get(unit.floor) ?? [])) builder.rest(slab, carrier, system.joints.slab)\n if (unit.suffix === '') context.topSlab = slab\n return { id: slab.id, aabb: slab.aabb, y0: slab.y0, y1: slab.y1, flat: true }\n}\n\nfunction addTrusses(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): StructurePart[] {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const trusses: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const aabb: Rect = axis === 'u' ? [at - 0.04, box[1] - eave * 0.5, at + 0.04, box[3] + eave * 0.5] : [box[0] - eave * 0.5, at - 0.04, box[2] + eave * 0.5, at + 0.04]\n const truss = builder.add({ id: `truss${unit.suffix}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(truss, carrier, system.joints.truss)\n trusses.push(truss)\n }\n return trusses\n}\n\ninterface GableGeometry {\n axis: 'u' | 'v'\n length: number\n eave: number\n rise: number\n eaveY: number\n}\n\nfunction geometryOf(context: BuildContext, unit: RoofUnit): GableGeometry {\n const { box } = unit\n const roof = context.construction.roof\n const platesHere = context.plates.get(unit.floor) ?? []\n const width = box[2] - box[0]\n const depth = box[3] - box[1]\n const axis = roof.axis ?? (width >= depth ? 'u' : 'v')\n const span = axis === 'u' ? depth : width\n const pitch = unit.annex ? Math.min(roof.pitch || DEFAULT_PITCH, 20) : roof.pitch || DEFAULT_PITCH\n const eaveY = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : context.level(unit.floor) + context.ceilingOf(unit.floor)\n return { axis, length: axis === 'u' ? width : depth, eave: roof.eave ?? DEFAULT_EAVE, rise: round2((span / 2) * Math.tan((pitch * Math.PI) / 180)), eaveY }\n}\n\ninterface Frames {\n all: StructurePart[]\n sideA: StructurePart[]\n sideB: StructurePart[]\n}\n\n/** Rafters of each side at the truss positions, each resting only on what is under its own side, and a ridge beam that rests on all of them. */\nfunction addRafters(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const middle = axis === 'u' ? (box[1] + box[3]) / 2 : (box[0] + box[2]) / 2\n const frames: Frames = { all: [], sideA: [], sideB: [] }\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const halves: [string, Rect][] =\n axis === 'u'\n ? [['a', [at - 0.04, box[1] - eave * 0.5, at + 0.04, middle]], ['b', [at - 0.04, middle, at + 0.04, box[3] + eave * 0.5]]]\n : [['a', [box[0] - eave * 0.5, at - 0.04, middle, at + 0.04]], ['b', [middle, at - 0.04, box[2] + eave * 0.5, at + 0.04]]]\n for (const [side, aabb] of halves) {\n const rafter = builder.add({ id: `rafter${unit.suffix}_${side}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((x, y) => distanceBetween(aabb, x.aabb) - distanceBetween(aabb, y.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(rafter, carrier, system.joints.truss)\n frames.all.push(rafter)\n if (side === 'a') frames.sideA.push(rafter)\n else frames.sideB.push(rafter)\n }\n }\n if (!unit.annex) {\n const ridgeBox: Rect = axis === 'u' ? [box[0] - eave, middle - 0.05, box[2] + eave, middle + 0.05] : [middle - 0.05, box[1] - eave, middle + 0.05, box[3] + eave]\n const ridge = builder.add({ id: `ridge${unit.suffix}`, role: 'beam', material: construction.frame.timber, aabb: ridgeBox, y0: eaveY + rise - 0.12, y1: eaveY + rise }, { floor: unit.floor })\n for (const rafter of frames.all) builder.rest(ridge, rafter, system.joints.truss)\n }\n context.roof.trusses += count\n return frames\n}\n\nfunction panesOf(unit: RoofUnit, geometry: GableGeometry): Rect[] {\n const [u0, v0, u1, v1] = unit.box\n const { eave, axis } = geometry\n if (unit.annex) return [[u0 - eave, v0 - eave, u1 + eave, v1 + eave]]\n const midV = (v0 + v1) / 2\n const midU = (u0 + u1) / 2\n return axis === 'u'\n ? [[u0 - eave, v0 - eave, u1 + eave, midV], [u0 - eave, midV, u1 + eave, v1 + eave]]\n : [[u0 - eave, v0 - eave, midU, v1 + eave], [midU, v0 - eave, u1 + eave, v1 + eave]]\n}\n\nfunction coarseFrames(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const trusses = addTrusses(context, unit, carriers, geometry)\n context.roof.trusses += trusses.length\n return { all: trusses, sideA: trusses, sideB: trusses }\n}\n\nfunction addGableRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], covering: JointKind): RoofPane[] {\n const { builder, construction } = context\n const geometry = geometryOf(context, unit)\n const frames: Frames = context.rafterRoof ? addRafters(context, unit, carriers, geometry) : coarseFrames(context, unit, carriers, geometry)\n const panes: RoofPane[] = []\n panesOf(unit, geometry).forEach((aabb, k) => {\n const name = unit.annex ? 'annex' : k === 0 ? 'a' : 'b'\n const options = { floor: unit.floor, fill: construction.roof.covering === 'colonial' ? 0.12 : 0.05, ...(construction.roof.pitch === undefined ? {} : { pitch: construction.roof.pitch }) }\n const pane = builder.add({ id: `roof${unit.suffix}_${name}`, role: 'roof', material: construction.roof.material, aabb, y0: geometry.eaveY, y1: geometry.eaveY + geometry.rise + 0.05 }, options)\n const carried = unit.annex || !context.rafterRoof ? frames.all : k === 0 ? frames.sideA : frames.sideB\n for (const frame of carried) builder.rest(pane, frame, covering)\n panes.push({ id: pane.id, aabb: pane.aabb, y0: pane.y0, y1: pane.y1 })\n })\n if (!unit.annex) {\n const roof = context.roof\n roof.axis = geometry.axis\n roof.ridge = round2(geometry.eaveY + geometry.rise)\n roof.eave = geometry.eave\n roof.y0 = round2(geometry.eaveY)\n roof.aabb = [unit.box[0] - geometry.eave, unit.box[1] - geometry.eave, unit.box[2] + geometry.eave, unit.box[3] + geometry.eave].map(round2) as Rect\n }\n return panes\n}\n\n/** Roof of a timber house: ceiling joists every 0.6 m tie the trusses and carry the attic floor. */\nfunction addCeilingJoists(context: BuildContext): void {\n const { builder, construction } = context\n const bearing = context.roof.bearingFloor\n const rects = context.rectsOf(bearing, CLOSED_ONLY)\n const box = unionOf(rects.length ? rects : [context.topBox])\n const carriers = [...(context.plates.get(bearing) ?? []), ...context.walls.filter((w) => w.floor === bearing && w.role === 'wall' && !w.exterior).map((w) => context.wallParts.get(w.id)!)]\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / 0.6) + 1)\n const beamTops = carriers.filter((carrier) => carrier.role === 'beam').map((carrier) => carrier.y0)\n const y0 = carriers.length ? Math.max(...beamTops, context.level(bearing) + 1) : context.topOf(bearing)\n const joists: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [at - 0.025, box[1], at + 0.025, box[3]] : [box[0], at - 0.025, box[2], at + 0.025]\n const joist = builder.add({ id: `ceiling_joist_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: y0 - 0.02, y1: y0 + context.system.plateThickness - 0.02 }, { floor: bearing, spacing: 0.6 })\n const beams = carriers.filter((carrier) => carrier.role === 'beam' && touches(aabb, carrier.aabb, 0.2))\n for (const carrier of beams.length ? beams : carriers.slice(0, 2)) builder.rest(joist, carrier, 'nail')\n joists.push(joist)\n }\n context.ceilingJoists = joists\n}\n\n/** The roof over the top storey: a flat slab or trusses and two panes, and the ceiling joists of a timber house. */\nexport function addRoof(context: BuildContext): void {\n const { construction } = context\n const covering = ROOF_COVERINGS.get(construction.roof.covering)\n const bearing = construction.roof.bearingFloor ?? context.floorCount - 1\n const open = context.rectsOf(context.floorCount - 1, OPEN_ROOM_TYPES)\n const topRects = context.rectsOf(context.floorCount - 1, CLOSED_ONLY)\n const body = unionOf(open.length ? open : topRects)\n context.topBox = context.floorCount - 1 === bearing ? body : unionOf(context.rectsOf(bearing, OPEN_ROOM_TYPES))\n context.roof = { shape: construction.roof.shape, covering: construction.roof.covering, material: construction.roof.material, pitch: construction.roof.pitch || 0, bearingFloor: bearing, panes: [], trusses: 0 }\n for (const unit of roofUnits(context, bearing)) {\n const carriers = roofCarriers(context, unit)\n if (construction.roof.shape === 'slab') context.roof.panes.push(addFlatRoof(context, unit, carriers))\n else context.roof.panes.push(...addGableRoof(context, unit, carriers, covering?.joint ?? 'nail'))\n }\n if (context.isTimber && construction.roof.shape !== 'slab') addCeilingJoists(context)\n}\n","import { GROUND } from '../types'\nimport type { StructureSource } from '../types'\nimport type { BuildContext } from './context'\n\ntype SourceItem = StructureSource['items'][number]\n/** A stair item: its `link` names the storeys it joins. */\ntype StairItem = SourceItem & { link: { from: number; to: number } }\n\nconst isStair = (item: SourceItem): item is StairItem => item.category === 'stairs' && typeof item.link === 'object' && item.link !== null\n\n/** One flight per pair of linked storeys, taken from the item of the lower storey when both are present. */\nfunction flightsOf(items: readonly SourceItem[]): Map<string, StairItem> {\n const flights = new Map<string, StairItem>()\n for (const item of items.filter(isStair)) {\n const key = `${item.link.from}_${item.link.to}`\n if (!flights.has(key) || item.floor === item.link.from) flights.set(key, item)\n }\n return flights\n}\n\n/** Interior stairs between storeys, resting on the floor below and tied to the one above, plus the basement stairs. */\nexport function addStairs(context: BuildContext): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : (construction.stairs ?? 'concrete')\n for (const [key, item] of flightsOf(context.source.items)) {\n const { from, to } = item.link\n const flight = builder.add({ id: `stairs_${key}`, role: 'stair', material, aabb: item.aabb!, y0: context.level(from), y1: context.level(to) }, { floor: from, steps: Math.round((context.level(to) - context.level(from)) / 0.18) })\n const base = context.baseOf(from)\n builder.rest(flight, !base || base === GROUND ? GROUND : base, !base || base === GROUND ? 'resting' : context.isTimber ? 'nail' : 'mortar')\n const upper = context.baseOf(to)\n if (upper && upper !== GROUND) builder.rest(flight, upper, context.isTimber ? 'nail' : 'bolt')\n }\n if (!context.hasBasement) return\n const item = context.source.items.find((it) => it.type === 'basement_stairs')\n if (!item?.aabb) return\n const depth = construction.foundation.depth || 2.4\n const flight = builder.add({ id: 'basement_stairs', role: 'stair', material: 'wood_soft', aabb: item.aabb, y0: -depth, y1: context.level(0) }, { floor: -1, steps: Math.round((context.level(0) + depth) / 0.18) })\n builder.rest(flight, builder.find('basement_slab')!, 'resting')\n if (context.base0 && context.base0 !== GROUND) builder.rest(flight, context.base0, 'nail')\n}\n","import { GROUND } from '../types'\nimport type { Opening, Rect, SourceDoor, StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\nimport { WALL_PILLAR_SIDE } from './wall-pillars'\n\nconst TOLERANCE = 0.02\n/** Height of a door leaf, which the plan does not store (m). */\nexport const DOOR_HEIGHT = 2.1\nconst LINTEL_DEPTH = 0.2\nconst LINTEL_BEARING = 0.2\n\nconst crossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\nconst alongRange = (wall: BuildWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** The windows of the plan, each in the wall it sits in. */\nexport function findOpenings(context: BuildContext): Opening[] {\n const openings: Opening[] = []\n for (const window of context.source.windows ?? []) {\n const from = window.at - window.width / 2\n const to = window.at + window.width / 2\n const wall = context.walls.find((w) => {\n if (w.floor !== window.floor || w.axis !== window.axis || w.type !== 'wall' || Math.abs(crossOf(w) - window.pos) > TOLERANCE) return false\n const [low, high] = alongRange(w)\n return from >= low - TOLERANCE && to <= high + TOLERANCE\n })\n if (!wall) continue\n const base = context.level(window.floor)\n openings.push({ id: window.id, kind: 'window', wall: wall.id, from, to, y0: base + window.y0, y1: base + window.y1 })\n }\n return openings\n}\n\n/**\n * A lintel over every door gap, 0.2 m deep, bearing 0.2 m on the wall at each side (a concrete beam in masonry, a header in timber houses). The bond beam or\n * plate over the door rests on it as well as on the walls beside it.\n */\nexport function addDoorLintels(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const door of context.source.doors.filter((d) => d.a !== undefined && d.type !== 'zipper')) {\n const along = door.axis === 'u' ? door.u : door.v\n const cross = door.axis === 'u' ? door.v : door.u\n const from = along - door.width / 2\n const to = along + door.width / 2\n const beside = context.walls.filter((w) => w.floor === door.floor && w.axis === door.axis && w.type === 'wall' && Math.abs(crossOf(w) - cross) <= TOLERANCE && (Math.abs(alongRange(w)[1] - from) <= 0.05 || Math.abs(alongRange(w)[0] - to) <= 0.05))\n if (!beside.length) continue\n const half = (beside[0]!.thickness ?? 0.15) / 2\n const lo = from - LINTEL_BEARING\n const hi = to + LINTEL_BEARING\n const box: Rect = door.axis === 'u' ? [lo, cross - half, hi, cross + half] : [cross - half, lo, cross + half, hi]\n const y0 = context.level(door.floor) + DOOR_HEIGHT\n // h = L/10 of reinforced concrete: a wide door (a garage) needs a deeper lintel\n const depth = Math.max(LINTEL_DEPTH, (door.width + LINTEL_BEARING) / 10)\n const lintel = builder.add({ id: `lintel_${door.id}`, role: 'beam', material: system.timber ? construction.frame.timber : 'concrete', aabb: box, y0, y1: y0 + depth }, { floor: door.floor, ...(system.timber ? {} : { assembly: 'reinforced_concrete' }) })\n for (const wall of beside) builder.rest(lintel, context.wallParts.get(wall.id) as StructurePart, system.joints.beam)\n // the pillars at the jambs carry the lintel too (confined masonry: a wide door rests on the frame, not on the bricks alone)\n const jambs = (context.pillars.get(door.floor) ?? []).filter((pillar) => pillar.material === 'concrete' && overlapsInPlan(pillar.aabb, box) && pillar.y1 >= y0)\n if (construction.system === 'masonry' && hi - lo > WIDE_DOOR) jambs.push(...addJambPillars(context, { door, beside, from, to, cross }, jambs))\n for (const pillar of jambs) builder.rest(lintel, pillar, 'rebar')\n for (const plate of context.plates.get(door.floor) ?? []) if (overlapsInPlan(plate.aabb, box)) builder.rest(plate, lintel, system.joints.beam)\n }\n}\n\n/** A lintel longer than this (metres) does not rest on masonry alone: it gets a concrete pillar at each jamb that has none (`MAX_LINTEL_ON_MASONRY` of the validator). */\nconst WIDE_DOOR = 3\nconst HALF_PILLAR = WALL_PILLAR_SIDE / 2\n\ninterface DoorGap {\n door: SourceDoor\n beside: BuildWall[]\n from: number\n to: number\n cross: number\n}\n\n/** Concrete pillars in the walls at the jambs of a wide door (an inner door has none of the exterior walls' pillars), from the floor to the top of the wall. */\nfunction addJambPillars(context: BuildContext, gap: DoorGap, standing: readonly StructurePart[]): StructurePart[] {\n const { builder, construction } = context\n const top = Math.max(...gap.beside.map((w) => context.wallParts.get(w.id)!.y1))\n const base = context.baseOf(gap.door.floor)\n const out: StructurePart[] = []\n for (const [k, along] of ([[0, gap.from - HALF_PILLAR], [1, gap.to + HALF_PILLAR]] as const)) {\n const [u, v] = gap.door.axis === 'u' ? [along, gap.cross] : [gap.cross, along]\n const box: Rect = [u - HALF_PILLAR, v - HALF_PILLAR, u + HALF_PILLAR, v + HALF_PILLAR]\n if (standing.some((p) => overlapsInPlan(p.aabb, box))) continue\n const pillar = builder.add({ id: `jamb_column_${gap.door.id}_${k}`, role: 'column', material: construction.frame.pillars, aabb: box, y0: context.level(gap.door.floor), y1: top }, { floor: gap.door.floor })\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n out.push(pillar)\n }\n return out\n}\n\nconst overlapsInPlan = (a: Rect, b: Rect): boolean => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]\n","import { GROUND } from '../types'\nimport type { Rect } from '../types'\nimport type { BuildContext } from './context'\n\nconst RISER = 0.18\nconst TREAD = 0.28\n\nconst stepCount = (elevation: number): number => Math.max(1, Math.ceil(elevation / RISER))\n\n/** Steps from each porch door down to the ground: concrete in masonry, wood otherwise, resting on the porch floor. */\nfunction addPorchSteps(context: BuildContext): void {\n const { builder } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const deck = builder.find(`porch_floor_${room.id}`)\n for (const door of context.source.doors.filter((d) => d.floor === room.floor && d.b === 'outside' && d.a === room.id)) {\n const count = stepCount(context.elevation)\n const depth = count * TREAD\n const aabb: Rect = [door.u - door.width / 2, door.v - depth, door.u + door.width / 2, door.v]\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb, y0: 0, y1: context.level(room.floor) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n if (deck) builder.rest(flight, deck, context.isTimber ? 'nail' : 'mortar')\n }\n }\n}\n\nfunction boxOfSteps(door: { u: number; v: number; width: number; axis: string; side?: string | null }, depth: number): Rect {\n const direction = door.axis === 'u' ? (door.side === 'front' ? -1 : 1) : door.side === 'left' ? -1 : 1\n if (door.axis === 'u') return [door.u - door.width / 2, Math.min(door.v, door.v + direction * depth), door.u + door.width / 2, Math.max(door.v, door.v + direction * depth)]\n return [Math.min(door.u, door.u + direction * depth), door.v - door.width / 2, Math.max(door.u, door.u + direction * depth), door.v + door.width / 2]\n}\n\n/** Steps at the other outside doors of the ground storey when the floor sits above the ground. */\nfunction addDoorSteps(context: BuildContext): void {\n if (context.elevation <= 0.1) return\n const { builder } = context\n const doors = context.source.doors.filter((d) => d.floor === 0 && d.exterior && d.model !== 'steel' && d.type !== 'steps' && d.type !== 'zipper')\n for (const door of doors) {\n const count = stepCount(context.elevation)\n const depth = Math.min(TREAD * count, 0.9)\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb: boxOfSteps(door, depth), y0: 0, y1: context.level(0) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n const base = context.base0\n if (base && base !== GROUND) builder.rest(flight, base, context.isTimber ? 'nail' : 'mortar')\n }\n}\n\nexport function addExteriorSteps(context: BuildContext): void {\n addPorchSteps(context)\n addDoorSteps(context)\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart, WaterTank } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst TANK_FILL = 0.08\n\nconst squareAround = (u: number, v: number, side: number): Rect => [u - side / 2, v - side / 2, u + side / 2, v + side / 2]\n\nfunction addTank(context: BuildContext, tank: WaterTank, floor: number, y0: number): StructurePart {\n return context.builder.add({ id: 'water_tank', role: 'none', material: tank.material ?? 'plastic', aabb: tank.aabb, y0, y1: y0 + tank.h }, { floor, fill: TANK_FILL, liters: tank.capacity })\n}\n\n/** The slab under the roof that carries a tank in the attic or on a raised platform: a ceiling slab on the top plates, pillars and bearing walls. */\nfunction ensureCeilingSlab(context: BuildContext, y: number): StructurePart {\n const { builder, construction, system } = context\n const existing = builder.find('slab_ceiling')\n if (existing) return existing\n const top = context.floorCount - 1\n const box = context.topBox\n const carriers = builder.parts.filter(\n (part) =>\n ((part.role === 'beam' && part.id.startsWith(`plate_${top}_`)) || (part.role === 'column' && part.floor === top) || (part.role === 'wall' && part.floor === top && !part.id.startsWith('basement'))) &&\n touches(box, part.aabb, 0.1),\n )\n const slab = builder.add({ id: 'slab_ceiling', role: 'slab', material: construction.frame.slabs, aabb: box, y0: y - 0.12, y1: y }, { floor: top, footprint: [box] })\n for (const carrier of carriers) builder.rest(slab, carrier, system.joints.slab)\n return slab\n}\n\nfunction addRaisedPlatform(context: BuildContext, tank: WaterTank): void {\n const { builder, construction } = context\n const platform = tank.platform!\n const top = context.floorCount - 1\n const ceiling = ensureCeilingSlab(context, platform.baseY)\n const pillars = platform.pillars.map((q, k) => {\n const pillar = builder.add({ id: `tank_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: squareAround(q.u, q.v, q.side), y0: platform.baseY, y1: platform.topY - platform.thickness }, { floor: top })\n builder.rest(pillar, ceiling, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'tank_slab', role: 'slab', material: construction.frame.slabs, aabb: platform.aabb, y0: platform.topY - platform.thickness, y1: platform.topY }, { floor: top })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n builder.rest(addTank(context, tank, top, tank.y), slab, 'resting')\n}\n\nfunction addAtticTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const top = context.floorCount - 1\n if (!context.isTimber) {\n const ceiling = ensureCeilingSlab(context, tank.y)\n builder.rest(addTank(context, tank, top, tank.y), ceiling, 'resting')\n return\n }\n const supports = context.topSlab ? [context.topSlab] : (context.ceilingJoists ?? builder.parts.filter((part) => part.role === 'beam' && part.id.startsWith(`plate_${top}_`)))\n const y0 = supports[0] ? supports[0].y1 : tank.y - 0.03\n const floor = builder.add({ id: 'attic_floor', role: 'slab', material: 'plywood', aabb: context.topBox, y0, y1: y0 + 0.03 }, { floor: top })\n for (const support of supports) if (touches(floor.aabb, support.aabb, 0.1)) builder.rest(floor, support, 'nail')\n builder.rest(addTank(context, tank, top, tank.y), floor, 'resting')\n}\n\nfunction addSlabTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const supports = builder.parts.filter((part) => part.role === 'slab' && Math.abs(part.y1 - tank.y) < 0.3 && touches(part.aabb, tank.aabb, 0.1))\n const carrier = supports.sort((a, b) => Math.abs(a.y1 - tank.y) - Math.abs(b.y1 - tank.y))[0] ?? context.topSlab\n const part = addTank(context, tank, tank.floor, tank.y)\n builder.rest(part, carrier ?? GROUND, 'resting')\n}\n\nfunction addTrestleTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const stand = tank.stand!\n const columns = stand.pillars.map((q, k) => {\n const column = builder.add({ id: `trestle_column_${k}`, role: 'column', material: stand.material, aabb: squareAround(q.u, q.v, q.side), y0: 0, y1: stand.height }, { floor: 0 })\n builder.rest(column, GROUND, stand.baseJoint ?? 'resting')\n return column\n })\n const [u0, v0, u1, v1] = tank.aabb\n const beams = ([[u0 - 0.1, v0 - 0.1, u1 + 0.1, v0 + 0.05], [u0 - 0.1, v1 - 0.05, u1 + 0.1, v1 + 0.1]] as Rect[]).map((aabb, k) => {\n const beam = builder.add({ id: `trestle_beam_${k}`, role: 'beam', material: stand.material, aabb, y0: stand.height - 0.12, y1: stand.height }, { floor: 0 })\n for (const column of columns.filter((c) => touches(beam.aabb, c.aabb, 0.15))) builder.rest(beam, column, stand.joint ?? 'nail')\n return beam\n })\n const part = addTank(context, tank, 0, stand.height)\n for (const beam of beams) builder.rest(part, beam, stand.tie ?? 'resting')\n}\n\n/** The water tank as a part (role `none`: it weighs on what holds it and carries nothing) with whatever holds it up. */\nexport function addWaterTank(context: BuildContext): void {\n const tank = context.tank\n if (!tank) return\n switch (tank.place) {\n case 'slab':\n return addSlabTank(context, tank)\n case 'raised_slab':\n return addRaisedPlatform(context, tank)\n case 'attic':\n return addAtticTank(context, tank)\n case 'trestle':\n return addTrestleTank(context, tank)\n }\n}\n","import { touches, unionOf } from '../geometry'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\n/** The floor of the storey above `floor`: a concrete slab, or joists and boards in timber, resting on what carries `floor`. */\nexport function addUpperFloor(context: BuildContext, floor: number): void {\n if (floor >= context.floorCount - 1 || context.isUnit) return\n const next = floor + 1\n const rects = context.rectsOf(next, ['balcony', 'porch', 'void'])\n const box = rects.length ? unionOf(rects) : context.houseBox\n const carriers = context.carriers.get(floor)!\n const { system, construction, builder } = context\n const thickness = system.slabThickness\n if (context.isTimber) {\n const joists = addJoists(context, { floor: next, box, thickness, carriers, material: construction.frame.timber, joint: system.joints.beam })\n addDeck(context, `slab_${next}`, construction.frame.slabs, { floor: next, box, thickness, joint: system.joints.slab }, joists)\n return\n }\n const slab = builder.add({ id: `slab_${next}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(next) - thickness, y1: context.level(next) }, { floor: next, footprint: rects.length ? rects : [context.houseBox] })\n const below = carriers.filter((carrier) => carrier.y0 <= slab.y0 + 0.05)\n const touching = below.filter((carrier) => touches(slab.aabb, carrier.aabb, 0.2))\n for (const carrier of touching.length ? touching : below) builder.rest(slab, carrier, system.joints.slab)\n}\n","import { GROUND } from '../types'\nimport type { StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\nimport { guardHeightOf, OPEN_ROOM_TYPES } from './context'\n\n/** Highest ceiling among the rooms the wall touches (a double-height room lifts its outer wall to the eave). */\nexport function wallCeiling(context: BuildContext, wall: BuildWall): number {\n const rooms = wall.sides.map((id) => context.source.rooms.find((room) => room.id === id && room.floor === wall.floor)).filter((room) => room !== undefined)\n return Math.max(context.ceilingOf(wall.floor), ...rooms.map((room) => room.ceiling || 0))\n}\n\nfunction wallTop(context: BuildContext, wall: BuildWall, floor: number): number {\n const y0 = context.level(floor)\n if (wall.type === 'railing') return y0 + guardHeightOf(wall)\n const ceiling = wallCeiling(context, wall)\n const height = wall.structureHeight || wall.h || context.ceilingOf(floor)\n if (wall.exterior && floor < context.floorCount - 1 && !context.isUnit && ceiling > context.ceilingOf(floor) + 0.01) return y0 + ceiling\n if (floor === context.floorCount - 1 || context.isUnit) return y0 + Math.max(height, ceiling)\n const top = context.topOf(floor)\n return Math.max(y0 + height, y0 + ceiling > top ? top : y0 + ceiling)\n}\n\n/** What a railing rests on: the slab of its own balcony or the floor of its porch. */\nfunction railingBase(context: BuildContext, wall: BuildWall, floor: number): StructurePart | string | undefined {\n const open = wall.sides\n .map((id) => context.source.rooms.find((room) => room.id === id && room.floor === floor))\n .find((room) => room && (room.type === 'balcony' || room.type === 'porch'))\n if (!open) return context.baseOf(floor)\n return open.type === 'porch' ? `porch_floor_${open.id}` : `slab_${floor}_${open.id}`\n}\n\nconst assemblyOf = (context: BuildContext): string | undefined => context.construction.walls.assembly ?? (context.system.walls || undefined)\n\nfunction addWallPart(context: BuildContext, wall: BuildWall, floor: number): void {\n const { system, builder } = context\n const isRailing = wall.type === 'railing'\n const y0 = context.level(floor)\n const top = wallTop(context, wall, floor)\n const y1 = isRailing ? top : wall.exterior && !wall.gable ? top - system.plateThickness : top\n const framed = system.studs !== undefined && !isRailing\n const part = builder.add(\n { id: wall.id, role: wall.role, material: wall.material, aabb: wall.box, y0, y1: Math.max(y1, y0 + 0.2) },\n { floor, fill: context.isTimber && wall.role === 'wall' ? system.wallFill : 1, ...(framed ? { studs: system.studs } : {}), ...(isRailing ? {} : { assembly: assemblyOf(context) }), ...(wall.exterior && !isRailing ? { exterior: true as const } : {}) },\n )\n context.wallParts.set(wall.id, part)\n const base = isRailing ? railingBase(context, wall, floor) : (context.groundBeams.get(wall.id) ?? context.baseOf(floor))\n const joint = isRailing ? 'nail' : system.joints.wall\n if (base === GROUND || (floor === 0 && !base)) builder.rest(part, GROUND, joint)\n else if (base) builder.rest(part, base, joint)\n}\n\n/** One part per wall of the storey, resting on the floor below it (or the ground). */\nexport function addWalls(context: BuildContext, floor: number): void {\n for (const wall of context.walls.filter((w) => w.floor === floor)) addWallPart(context, wall, floor)\n}\n\nexport const isOpenRoomType = (type: string): boolean => OPEN_ROOM_TYPES.includes(type)\n","import { createContext } from './context'\nimport type { BuildContext } from './context'\nimport { addBalconies } from './balconies'\nimport { buildCanvasStructure } from './canvas'\nimport { addChimney, addWell } from './extras'\nimport { addFoundation } from './foundation'\nimport { addGroundBeams } from './ground-beams'\nimport { addPlatesAndPillars } from './plates'\nimport { addPorches } from './porch'\nimport { addPorchRoofs } from './porch-roof'\nimport { addRoof } from './roof'\nimport { addStairs } from './stairs'\nimport { addDoorLintels, findOpenings } from './openings'\nimport { addExteriorSteps } from './steps'\nimport { addWaterTank } from './tank-parts'\nimport { addUpperFloor } from './upper-floor'\nimport { addWalls } from './walls'\nimport { WALL_PILLAR_SPACING } from './wall-pillars'\nimport { resolveConstruction } from '../construction'\nimport type { Structure, StructureOptions, StructureSource } from '../types'\n\nfunction buildFloors(context: BuildContext): void {\n for (let floor = 0; floor < context.floorCount; floor++) {\n addWalls(context, floor)\n addPlatesAndPillars(context, floor)\n addPorches(context, floor)\n addUpperFloor(context, floor)\n }\n}\n\nconst wallPillarSpacingOf = (options: StructureOptions): number => {\n const pillars = options.wallPillars ?? true\n if (pillars === false) return 0\n return pillars === true ? WALL_PILLAR_SPACING : (pillars.spacing ?? WALL_PILLAR_SPACING)\n}\n\n/**\n * The structure of a generated plan: every part that carries load (foundation, floors, walls, plates and bond beams, pillars, porch posts, trusses,\n * roof, stairs, tank) with what each rests on. The plan itself is not modified.\n */\nexport function buildStructure(source: StructureSource, options: StructureOptions = {}): Structure {\n const refined = options.wallDetail !== 'coarse'\n const built = options.construction ? { construction: options.construction, extras: options.extras ?? {} } : resolveConstruction(source)\n const construction = built.construction\n const extras = options.extras ?? built.extras ?? {}\n if (construction.system === 'canvas') return buildCanvasStructure(construction, extras)\n const tank = options.tank !== undefined ? options.tank : (source.waterTank ?? null)\n const context = createContext(source, construction, extras, tank, { porchRoofOnPostsOnly: options.porchRoofOnPostsOnly ?? refined, rafterRoof: options.rafterRoof ?? refined, wallPillarSpacing: wallPillarSpacingOf(options), visorSections: options.visorSections === true })\n addFoundation(context)\n if (options.groundBeams !== false) addGroundBeams(context)\n buildFloors(context)\n addBalconies(context)\n addPorchRoofs(context)\n addExteriorSteps(context)\n addStairs(context)\n if (options.roof !== false) addRoof(context)\n if (refined) addDoorLintels(context)\n addWaterTank(context)\n addChimney(context)\n addWell(context)\n const levels = source.floors.map((_, floor) => context.level(floor))\n const framed = construction.system === 'masonry' && (context.isUnit || source.style === 'commercial' || context.floorCount >= 3)\n return { parts: context.builder.parts, supports: context.builder.supports, levels, elevation: context.elevation, roof: context.roof, construction, framed, openings: findOpenings(context) }\n}\n","export type ContentGroup = 'food' | 'water' | 'medicine' | 'tool' | 'cleaning' | 'improvised_weapon' | 'clothes' | 'document' | 'utensil' | 'trash'\n\nexport interface ContentEntry {\n itemId: string\n min: number\n max: number\n group: ContentGroup\n pickable: boolean\n weight: number\n}\n\nconst entry = (itemId: string, min: number, max: number, group: ContentGroup, pickable: boolean, weight: number): ContentEntry => ({ itemId, min, max, group, pickable, weight })\n\nconst FRIDGE = [\n entry('water_bottle', 1, 3, 'water', true, 3), entry('milk_carton', 1, 2, 'food', true, 2), entry('eggs', 1, 1, 'food', true, 2), entry('packed_meat', 1, 2, 'food', true, 1.5), entry('fruit', 1, 4, 'food', true, 2),\n entry('yogurt', 1, 3, 'food', true, 1), entry('soda', 1, 2, 'water', true, 1), entry('cheese', 1, 1, 'food', true, 1), entry('insulin', 1, 1, 'medicine', true, 0.4), entry('leftovers', 1, 2, 'food', true, 1),\n]\nconst BEDSIDE = [entry('medicine', 1, 2, 'medicine', true, 2), entry('book', 1, 2, 'document', true, 1.5), entry('charger', 1, 1, 'tool', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('glasses', 1, 1, 'tool', true, 0.7)]\nconst WARDROBE = [\n entry('shirt', 2, 6, 'clothes', true, 3), entry('trousers', 1, 4, 'clothes', true, 3), entry('coat', 1, 2, 'clothes', true, 1.5), entry('sneakers', 1, 2, 'clothes', true, 1.5),\n entry('shoes', 1, 2, 'clothes', true, 1), entry('blanket', 1, 2, 'clothes', true, 1.5), entry('backpack', 1, 1, 'tool', true, 0.8),\n]\nconst DRESSER = [entry('underwear', 2, 6, 'clothes', true, 3), entry('socks', 2, 6, 'clothes', true, 2), entry('t_shirt', 1, 4, 'clothes', true, 2), entry('documents', 1, 2, 'document', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('batteries', 1, 2, 'tool', true, 0.7)]\nconst FILING = [entry('documents', 1, 4, 'document', true, 3), entry('pen', 1, 3, 'tool', true, 1.5), entry('keys', 1, 2, 'tool', true, 1), entry('stapler', 1, 1, 'improvised_weapon', true, 0.5)]\nconst TRASH = [entry('full_trash_bag', 1, 1, 'trash', false, 2), entry('packaging', 1, 4, 'trash', true, 3), entry('empty_can', 1, 3, 'trash', true, 2), entry('crumpled_paper', 1, 3, 'trash', true, 1)]\n\n/** What each kind of container may hold, by category (or by type when a type differs from its category). */\nexport const CONTENT_TABLES: Record<string, ContentEntry[]> = {\n fridge: FRIDGE,\n display_fridge: [entry('soda', 2, 6, 'water', true, 3), entry('water_bottle', 2, 6, 'water', true, 3), entry('yogurt', 2, 5, 'food', true, 2)],\n freezer: [entry('frozen_meat', 2, 5, 'food', true, 3), entry('ice_cream', 1, 2, 'food', true, 1)],\n kitchen_cabinet: [\n entry('pot', 1, 2, 'tool', true, 1.5), entry('kitchen_knife', 1, 2, 'improvised_weapon', true, 1.5), entry('dish_soap', 1, 2, 'cleaning', true, 2), entry('sponge', 1, 2, 'cleaning', true, 1), entry('rice', 1, 2, 'food', true, 1.5),\n entry('beans', 1, 2, 'food', true, 1.5), entry('pasta', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 1, 'food', true, 1), entry('canned_tuna', 1, 3, 'food', true, 1.5), entry('disinfectant', 1, 1, 'cleaning', true, 1), entry('trash_bag', 1, 2, 'trash', true, 0.7),\n ],\n overhead_cabinet: [entry('plates', 4, 8, 'utensil', false, 3), entry('glasses', 3, 6, 'utensil', false, 3), entry('mug', 1, 3, 'utensil', true, 1.5), entry('coffee', 1, 2, 'food', true, 1.5), entry('canned_corn', 1, 3, 'food', true, 1.5), entry('spices', 1, 3, 'food', true, 1)],\n washbasin: [\n entry('painkiller', 1, 2, 'medicine', true, 2), entry('bandages', 1, 2, 'medicine', true, 2), entry('soap', 1, 3, 'cleaning', true, 2), entry('toilet_paper', 1, 4, 'cleaning', true, 2), entry('shampoo', 1, 2, 'cleaning', true, 1),\n entry('toothbrush', 1, 2, 'cleaning', true, 1), entry('scissors', 1, 1, 'improvised_weapon', true, 0.5), entry('rubbing_alcohol', 1, 1, 'medicine', true, 1),\n ],\n wardrobe: WARDROBE,\n wardrobe_large: WARDROBE,\n dresser: DRESSER,\n console_table: DRESSER,\n nightstand: BEDSIDE,\n filing_cabinet: FILING,\n pantry: [\n entry('rice', 2, 4, 'food', true, 2), entry('beans', 2, 4, 'food', true, 2), entry('canned_tuna', 2, 5, 'food', true, 2), entry('water_jug', 1, 2, 'water', true, 2), entry('flour', 1, 2, 'food', true, 1),\n entry('sugar', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 2, 'food', true, 1), entry('biscuits', 1, 4, 'food', true, 1.5),\n ],\n tv_unit: [entry('remote_control', 1, 1, 'tool', true, 2), entry('dvds', 1, 4, 'document', true, 1), entry('cables', 1, 3, 'tool', true, 1.5), entry('batteries', 1, 2, 'tool', true, 1)],\n laundry_cabinet: [entry('washing_powder', 1, 2, 'cleaning', true, 3), entry('bleach', 1, 2, 'cleaning', true, 2), entry('disinfectant', 1, 2, 'cleaning', true, 2), entry('bucket', 1, 1, 'tool', true, 1), entry('broom', 1, 1, 'improvised_weapon', true, 1), entry('rubber_gloves', 1, 2, 'cleaning', true, 1)],\n laundry_shelf: [entry('washing_powder', 1, 1, 'cleaning', true, 2), entry('softener', 1, 2, 'cleaning', true, 2), entry('clothespins', 1, 1, 'tool', true, 1)],\n workbench: [entry('hammer', 1, 1, 'improvised_weapon', true, 2), entry('screwdriver', 1, 2, 'tool', true, 2), entry('pliers', 1, 1, 'tool', true, 1.5), entry('insulating_tape', 1, 2, 'tool', true, 1), entry('screws', 1, 2, 'tool', true, 1)],\n tool_shelf: [entry('hammer', 1, 1, 'improvised_weapon', true, 1.5), entry('hand_saw', 1, 1, 'improvised_weapon', true, 1), entry('paint_can', 1, 3, 'trash', true, 1.5), entry('rope', 1, 1, 'tool', true, 1), entry('nails', 1, 2, 'tool', true, 1.5)],\n mailbox: [entry('letter', 1, 4, 'document', true, 3), entry('bill', 1, 2, 'document', true, 2), entry('flyer', 1, 4, 'trash', true, 2)],\n trash_bin: TRASH,\n outdoor_bin: TRASH,\n china_cabinet: [entry('china_plates', 3, 6, 'utensil', false, 3), entry('wine_glasses', 2, 5, 'utensil', false, 2)],\n}\n\n/** Groups of things somebody who locked themselves in would have stocked up. */\nexport const SUPPLY_GROUPS: readonly ContentGroup[] = ['food', 'water', 'medicine', 'tool']\n","import type { FindStack } from '@adatechnology/game-floorplan'\n\nimport { CONTENT_TABLES, SUPPLY_GROUPS } from './content-tables'\nimport type { ContentEntry } from './content-tables'\nimport type { Rng } from './shared'\n\nexport interface ContentStack extends FindStack {\n group: string\n pickable: boolean\n}\n\nexport interface ContentQuery {\n /** Category or type of the container (`fridge`, `kitchen_cabinet`, `overhead_cabinet`...). */\n container: string\n state: string\n rng: Rng\n /** Footprint of the container in m2. */\n footprint: number\n}\n\n/** How a state changes what a container holds: how many kinds, how likely each is, how many of each, and what is left over. */\nexport interface ContentStateRule {\n kinds(base: number, available: number, rng: Rng): number\n weight(entry: ContentEntry): number\n extraQuantity(entry: ContentEntry): number\n leftovers?(found: ContentStack[], container: string, rng: Rng): void\n}\n\nconst FRIDGES = ['fridge', 'display_fridge', 'freezer']\nconst isSupply = (entry: ContentEntry): boolean => SUPPLY_GROUPS.includes(entry.group)\n\n/** The normal world is the base; `fortified` and `abandoned` are the genre's rules, kept here until the item catalogue and the genre pack own them. */\nexport const CONTENT_STATES: Record<string, ContentStateRule> = {\n normal: { kinds: (base) => base, weight: (entry) => entry.weight, extraQuantity: () => 0 },\n fortified: { kinds: (base, available) => Math.min(available, base + 2), weight: (entry) => (isSupply(entry) ? entry.weight * 2.5 : entry.weight), extraQuantity: (entry) => (isSupply(entry) ? 1 : 0) },\n abandoned: {\n kinds: (_base, _available, rng) => (rng() < 0.4 ? 0 : 1),\n weight: (entry) => entry.weight,\n extraQuantity: () => 0,\n leftovers(found, container, rng) {\n if (found.length === 0 && rng() < 0.5) found.push({ itemId: 'scraps_and_papers', count: 1, pickable: false, group: 'trash' })\n if (FRIDGES.includes(container)) found.push({ itemId: 'spoiled_food', count: 1, pickable: false, group: 'trash' })\n },\n },\n}\n\nexport function registerContentState(state: string, rule: ContentStateRule): void {\n CONTENT_STATES[state] = rule\n}\n\n/** Weighted draw without replacement. */\nfunction weightedOrder<T extends { weight: number }>(candidates: T[], rng: Rng): T[] {\n const pool = candidates.slice()\n const out: T[] = []\n while (pool.length) {\n let x = rng() * pool.reduce((sum, c) => sum + c.weight, 0)\n let i = 0\n for (; i < pool.length - 1; i++) {\n x -= pool[i]!.weight\n if (x < 0) break\n }\n out.push(pool.splice(i, 1)[0]!)\n }\n return out\n}\n\n/** What a container holds in a state: a few kinds of thing from the table of its category, more of the useful ones when fortified, almost nothing when abandoned. */\nexport function contentOf(query: ContentQuery): ContentStack[] {\n const pool = CONTENT_TABLES[query.container]\n if (!pool) return []\n const rule = CONTENT_STATES[query.state] ?? CONTENT_STATES.normal!\n const { rng } = query\n const base = Math.max(2, Math.min(5, Math.round(1.5 + query.footprint * 3 + rng() * 1.5)))\n const kinds = rule.kinds(base, pool.length, rng)\n const found: ContentStack[] = []\n for (const candidate of weightedOrder(pool.map((entry) => ({ entry, weight: rule.weight(entry) })), rng).slice(0, kinds)) {\n const { entry } = candidate\n const count = entry.min + Math.floor(rng() * (entry.max - entry.min + 1)) + rule.extraQuantity(entry)\n found.push({ itemId: entry.itemId, count, pickable: entry.pickable, group: entry.group })\n }\n rule.leftovers?.(found, query.container, rng)\n return found\n}\n\nexport const hasContent = (container: string): boolean => container in CONTENT_TABLES\n\n","import type { Plan, PlacedItemFields, PlanWall } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\n\nexport type Rng = () => number\n\nexport const HALF_WALL = 0.075\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\nexport const clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport const overlaps = (a: Rect, b: Rect, epsilon = 1e-6): boolean => a[0] < b[2] - epsilon && a[2] > b[0] + epsilon && a[1] < b[3] - epsilon && a[3] > b[1] + epsilon\n\nexport const inner = (rect: Rect): Rect => [rect[0] + HALF_WALL, rect[1] + HALF_WALL, rect[2] - HALF_WALL, rect[3] - HALF_WALL]\n\n/** A solid item: not a rug, not resting on something, and not decoration unless it stands on the floor. */\nexport const isSolid = (item: Pick<PlacedItemFields, 'flat' | 'on' | 'decor' | 'mount'>): boolean => !item.flat && !item.on && (!item.decor || item.mount === 'floor')\n\nexport const distanceToRect = (u: number, v: number, rect: Rect): number => Math.hypot(Math.max(rect[0] - u, 0, u - rect[2]), Math.max(rect[1] - v, 0, v - rect[3]))\n\n/** Room types without sockets, switches or circuits. */\nexport const NO_SOCKET_ROOMS: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch', 'tent']\n\n/** Unit vector pointing out of the house from a wall (`sides[0]` or `sides[1]` is `outside`). */\nexport const outwardOf = (wall: PlanWall): [number, number] => {\n const sign = wall.sides[0] === 'outside' ? -1 : 1\n return wall.axis === 'u' ? [0, sign] : [sign, 0]\n}\n\nexport const sideNameOf = (vector: [number, number]): string => (Math.abs(vector[0]) > Math.abs(vector[1]) ? (vector[0] > 0 ? 'right' : 'left') : vector[1] > 0 ? 'back' : 'front')\n\nexport const alongRange = (wall: PlanWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** Exterior ground-floor wall at least 1 m long, the front one first when there is one (a gas meter and an inverter go on them). */\nexport function groundExteriorWalls(plan: Plan): PlanWall[] {\n return plan.walls.filter((wall) => wall.exterior && wall.floor === 0 && wall.type === 'wall' && Math.hypot(wall.u1 - wall.u0, wall.v1 - wall.v0) >= 1.0)\n}\n","import type { Plan, PlanWindow, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport { HALF_WALL, isSolid, round2 } from './shared'\n\nexport interface WallPoint {\n u: number\n v: number\n /** Position along the wall. */\n c: number\n axis: 'u' | 'v'\n pos: number\n side: number\n nu: number\n nv: number\n a0: number\n a1: number\n exterior: boolean\n windows: PlanWindow[]\n /** A solid item within 12 cm of the point reaches higher than `height`. */\n blocked(height: number): boolean\n}\n\nconst STEP = 0.05\nconst SURFACE_OFFSET = 0.012\n\n/** Points on the inner face of the walls of a room, away from corners (`margin`), where sockets, switches and a panel may go. */\nexport function wallPointsOf(plan: Plan, room: Room, items: ResultItem[], margin = 0.3): WallPoint[] {\n const points: WallPoint[] = []\n const windows = plan.windows.filter((w) => w.floor === room.floor)\n const solids = items.filter((m) => m.floor === room.floor && !m.outdoor && m.room === room.id && isSolid(m))\n for (const wall of plan.walls) {\n if (wall.floor !== room.floor || wall.type !== 'wall' || !wall.sides.includes(room.id)) continue\n const side = wall.sides[1] === room.id ? 1 : -1\n const a0 = wall.axis === 'u' ? Math.min(wall.u0, wall.u1) : Math.min(wall.v0, wall.v1)\n const a1 = wall.axis === 'u' ? Math.max(wall.u0, wall.u1) : Math.max(wall.v0, wall.v1)\n const pos = wall.axis === 'u' ? wall.v0 : wall.u0\n const nearby = windows.filter((w) => w.axis === wall.axis && Math.abs(w.pos - pos) < 1e-3 && w.at + w.width / 2 > a0 && w.at - w.width / 2 < a1)\n for (let c = a0 + margin; c <= a1 - margin + 1e-9; c += STEP) {\n const u = wall.axis === 'u' ? c : pos + side * (HALF_WALL + SURFACE_OFFSET)\n const v = wall.axis === 'u' ? pos + side * (HALF_WALL + SURFACE_OFFSET) : c\n points.push({\n u: round2(u), v: round2(v), c: round2(c), axis: wall.axis, pos, side, nu: wall.axis === 'u' ? 0 : side, nv: wall.axis === 'u' ? side : 0, a0, a1, exterior: wall.exterior, windows: nearby,\n blocked: (height) => solids.some((m) => m.aabb && Math.hypot(Math.max(m.aabb[0] - u, 0, u - m.aabb[2]), Math.max(m.aabb[1] - v, 0, v - m.aabb[3])) < 0.12 && (m.y || 0) + m.h > height),\n })\n }\n }\n return points\n}\n\nexport const hasWindowAt = (point: WallPoint, y: number, clearance = 0.2): boolean =>\n point.windows.some((w) => y + 0.1 > w.y0 - 0.05 && y - 0.1 < w.y1 + 0.05 && Math.abs(point.c - w.at) < w.width / 2 + clearance)\n\nexport const atDoor = (plan: Plan, room: Room, point: WallPoint, clearance: number): boolean =>\n plan.doors.some((d) => d.floor === room.floor && d.axis === point.axis && Math.abs(d.pos - point.pos) < 1e-3 && Math.abs(d.at - point.c) < d.width / 2 + clearance)\n","import type { ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { keyOf } from './electrical'\nimport { distanceToRect } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { Outlet } from './types'\n\n/** Categories that need a socket of their own. */\nconst APPLIANCES = ['fridge', 'display_fridge', 'freezer', 'tv', 'appliance', 'washing_machine', 'air_conditioner', 'cash_register', 'table_light']\nconst COUNTERS = ['kitchen_cabinet', 'workbench', 'checkout_counter']\nconst LAMPS = ['table_light', 'lamp']\n\nconst needsSocket = (item: ResultItem): boolean => APPLIANCES.includes(item.category) || item.category === 'shower'\n\ninterface Pick {\n point: WallPoint\n y: number\n score: number\n}\n\n/** Sockets: one for each appliance (the shower heater too), then enough for the size of each room, two at counter height in a kitchen with a counter. */\nexport function addOutlets(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n let counter = 0\n const outletsOf = (room: Room): Outlet[] => electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const newOutlet = (room: Room, point: WallPoint, y: number): Outlet => {\n const outlet: Outlet = { id: `outlet${++counter}`, room: room.id, floor: room.floor, u: point.u, v: point.v, y, c: point.c, axis: point.axis, pos: point.pos, frontU: point.nu, frontV: point.nv, type: '2P+T', voltage: 127 }\n electrical.outlets.push(outlet)\n return outlet\n }\n const counters = items.filter((m) => COUNTERS.includes(m.category) && !m.outdoor)\n const heightFor = (room: Room, point: WallPoint): number =>\n room.type === 'kitchen' && counters.some((m) => m.floor === room.floor && m.room === room.id && distanceToRect(point.u, point.v, m.aabb) < 0.45) ? 1.1 : 0.3\n const valid = (room: Room, point: WallPoint, y: number): boolean =>\n !hasWindowAt(point, y, 0.25) && !atDoor(plan, room, point, 0.45) && !outletsOf(room).some((t) => Math.hypot(t.u - point.u, t.v - point.v) < 0.5 && t.y === y)\n const pick = (room: Room, score: (point: WallPoint) => number, fixedY: number | null, ignoreBlocked?: boolean): Pick | null => {\n let best: Pick | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n const y = fixedY ?? heightFor(room, point)\n if (!valid(room, point, y)) continue\n const total = score(point) + (point.blocked(y) && !ignoreBlocked ? 5 : 0)\n if (!best || total < best.score) best = { point, y, score: total }\n }\n return best\n }\n const roomOf = (item: ResultItem): Room | undefined => rooms.find((x) => x.id === item.room && x.floor === item.floor)\n const appliances = items.filter((m) => !m.outdoor && needsSocket(m) && rooms.some((c) => c.id === m.room && c.floor === m.floor) && m.category !== 'table_light')\n for (const item of appliances) connectAppliance(item)\n function connectAppliance(item: ResultItem): void {\n const room = roomOf(item)!\n const target = item.aabb\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, target) })).filter((o) => o.d <= 1.2 && o.t.y <= 1.1).sort((a, b) => a.d - b.d)[0]\n const isShower = item.category === 'shower'\n let outlet: Outlet | null = nearest && !isShower ? nearest.t : null\n if (!outlet) {\n const height = isShower ? 1.1 : item.y > 0.7 ? 1.1 : null\n const best = pick(room, (p) => { const d = distanceToRect(p.u, p.v, target); return isShower && d < 0.6 ? 50 + d : d }, height)\n let chosen = best\n if (!isShower && (!best || distanceToRect(best.point.u, best.point.v, target) > 1.4)) {\n const behind = pick(room, (p) => distanceToRect(p.u, p.v, target), item.y > 0.7 ? 1.1 : null, true)\n if (behind && (!best || distanceToRect(behind.point.u, behind.point.v, target) < distanceToRect(best.point.u, best.point.v, target))) chosen = behind\n }\n if (chosen) outlet = newOutlet(room, chosen.point, chosen.y)\n }\n if (!outlet) return\n item.outlet = outlet.id\n if (isShower) item.showerHeater = { electric: true, powerW: 5500, outlet: outlet.id }\n }\n for (const room of rooms) {\n const area = room.parts.reduce((sum: number, q: number[]) => sum + (q[2]! - q[0]!) * (q[3]! - q[1]!), 0)\n const wanted = Math.max(room.type === 'kitchen' ? 3 : 2, Math.min(6, Math.round(area / 7)))\n const farthest = (existing: Outlet[]) => (p: WallPoint) => -Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v)))\n for (let guard = 0; outletsOf(room).length < wanted && guard < 12; guard++) {\n const best = pick(room, farthest(outletsOf(room)), null)\n if (!best) break\n newOutlet(room, best.point, best.y)\n }\n if (room.type !== 'kitchen' || !counters.some((m) => m.room === room.id)) continue\n for (let guard = 0; outletsOf(room).filter((t) => t.y === 1.1).length < 2 && guard < 4; guard++) {\n const existing = outletsOf(room)\n const best = pick(room, (p) => (heightFor(room, p) === 1.1 ? 0 : 20) - Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v))), 1.1)\n if (!best) break\n newOutlet(room, best.point, 1.1)\n }\n }\n for (const item of appliances) {\n if (item.category === 'shower' || !item.outlet) continue\n const room = roomOf(item)!\n const current = outletsOf(room).find((t) => t.id === item.outlet)\n if (!current || distanceToRect(current.u, current.v, item.aabb) <= 1.2) continue\n const other = outletsOf(room).filter((t) => t.y <= 1.1).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (other && other.d < distanceToRect(current.u, current.v, item.aabb) && other.d <= 1.2) item.outlet = other.t.id\n }\n for (const item of items.filter((m) => LAMPS.includes(m.category) && !m.outdoor)) {\n const room = roomOf(item)\n if (!room) continue\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (nearest) item.outlet = nearest.t.id\n }\n}\n\n","import type { Plan, PlanDoor } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport { clamp, round2 } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { ElectricMeter } from './types'\n\nconst METER_SIZE = { w: 0.35, d: 0.2, h: 0.5 }\n\nexport const mainDoorOf = (plan: Plan): PlanDoor | undefined => plan.doors.find((p) => p.floor === 0 && p.exterior && p.side === 'front') || plan.doors.find((p) => p.floor === 0 && p.exterior)\n\n/** Pole, drop, meter and descent: the meter on the gate pillar (or the facade without a gate); an apartment or shop has it on the facade. */\nexport function placeEntrance(layout: Layout): void {\n const { plan, electrical } = layout\n const gate = plan.gates.find((g) => g.type === 'pedestrian')\n const door = mainDoorOf(plan)\n const lot = plan.lot\n if (lot && plan.style !== 'commercial') {\n const rect = lot.rect\n const poleU = clamp(gate ? gate.u + 3 : plan.w / 2, rect[0] + 0.5, rect[2] - 0.5)\n const poleV = rect[1] - 0.6\n let placed: Omit<ElectricMeter, 'id'>\n if (gate) {\n const direction = gate.u - gate.width / 2 - 0.4 >= rect[0] + 0.3 ? -1 : 1\n placed = { place: 'gate_pillar', u: round2(gate.u + direction * (gate.width / 2 + 0.25)), v: round2(gate.v), y: 1.4, side: 'front', ...METER_SIZE }\n } else placed = { place: 'facade', u: round2(door ? door.at + 1.2 : plan.w / 2), v: -0.1, y: 1.4, side: 'front', ...METER_SIZE }\n const meter: ElectricMeter = Object.assign(placed, { id: 'meter' })\n electrical.serviceEntrance = { pole: { u: round2(poleU), v: round2(poleV), h: 7.5 }, drop: [[round2(poleU), round2(poleV), 6.5], [meter.u, meter.v, 2.6]], meter, descent: [[meter.u, meter.v, 2.6], [meter.u, meter.v, 1.65]], internalRun: null }\n } else if (lot === null || plan.style === 'commercial') {\n const front = door ? { u: round2(door.at + 1.0), v: -0.1 } : { u: round2(plan.w / 2), v: -0.1 }\n electrical.serviceEntrance = {\n pole: { u: round2(front.u + 2), v: -3, h: 7.5 }, drop: [[round2(front.u + 2), -3, 6.5], [front.u, front.v, 3.2]],\n meter: { id: 'meter', place: 'facade', u: front.u, v: front.v, y: 1.4, side: 'front', ...METER_SIZE }, descent: [[front.u, front.v, 3.2], [front.u, front.v, 1.65]], internalRun: null,\n }\n }\n}\n\n/** The distribution panel in the room of the main door, on the wall nearest the meter, clear of doors and windows and of tall furniture. */\nexport function placePanel(layout: Layout): void {\n const { plan, rooms, electrical, pointsOf } = layout\n const door = mainDoorOf(plan)\n const room = (door && rooms.find((c) => c.id === door.a && c.floor === 0)) || rooms.find((c) => c.floor === 0) || rooms[0]\n if (!room) return\n const meter = electrical.serviceEntrance?.meter\n const targetU = meter ? meter.u : plan.w / 2\n const targetV = meter ? Math.max(0, meter.v) : 0\n let best: { point: WallPoint | undefined; score: number } | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n if (point.blocked(1.5) || hasWindowAt(point, 1.5, 0.3) || atDoor(plan, room, point, 0.8)) continue\n const score = Math.hypot(point.u - targetU, point.v - targetV) + (point.exterior ? 0 : 3)\n if (!best || score < best.score) best = { point, score }\n }\n if (!best) best = { point: (pointsOf.get(keyOf(room)) ?? [])[0], score: 0 }\n if (best.point) {\n const p = best.point\n electrical.panel = { id: 'panel', room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.5, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, w: 0.3, h: 0.4, breakers: 0 }\n }\n if (electrical.serviceEntrance && electrical.panel) {\n const entrance = electrical.serviceEntrance\n const meterOf = entrance.meter as ElectricMeter // placeEntrance always sets the meter; only the tap pass clears it, later\n entrance.internalRun = [[meterOf.u, meterOf.v, 0.1], [electrical.panel.u, electrical.panel.v, heightOf(plan, electrical.panel.floor, electrical.panel.y)]]\n }\n}\n","import type { PlanDoor, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport { mainDoorOf } from './electrical-entrance'\nimport { round2 } from './shared'\nimport { atDoor, hasWindowAt, wallPointsOf } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { Circuit, Point3, WallFixture } from './types'\n\nconst LAMP_CATEGORIES = ['ceiling_light', 'lamp', 'table_light']\n\nconst lampsOf = (layout: Layout): ResultItem[] => layout.items.filter((m) => !m.outdoor && LAMP_CATEGORIES.includes(m.category))\n\n/** A switch by the latch of the main door of each room that has a lamp (and of the room of the front door, for the outside lamp), at 1.10 m. */\nexport function addSwitches(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n const lamps = lampsOf(layout)\n const door = mainDoorOf(plan)\n let counter = 0\n const positionFor = (room: Room): { point: WallPoint; door: PlanDoor; latch: boolean } | null => {\n const doors = plan.doors\n .filter((p) => p.floor === room.floor && (p.a === room.id || p.b === room.id))\n .sort((a, b) => (a.opensTo === room.id ? 0 : 1) - (b.opensTo === room.id ? 0 : 1) || (a.width < b.width ? 1 : -1))\n const points = wallPointsOf(plan, room, items, 0.12)\n for (const tolerance of [0.16, 0.3]) {\n for (const d of doors) {\n for (const direction of [1, -1]) {\n const target = d.at + direction * (d.width / 2 + 0.18)\n const point = points.filter((q) => q.axis === d.axis && Math.abs(q.pos - d.pos) < 1e-3 && !hasWindowAt(q, 1.1, 0.2)).sort((a, b) => Math.abs(a.c - target) - Math.abs(b.c - target))[0]\n if (point && Math.abs(point.c - target) <= tolerance && !atDoor(plan, room, point, 0.0) && Math.abs(point.c - d.at) >= d.width / 2 + 0.12) return { point, door: d, latch: direction === 1 }\n }\n }\n }\n return null\n }\n for (const room of rooms.concat(plan.rooms.filter((x) => ['stairs'].includes(x.type)))) {\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n const extra = door && door.a === room.id && room.floor === 0 && plan.lot ? [`outdoor_${door.id}`] : []\n if (!roomLamps.length && !extra.length) continue\n if (!pointsOf.get(keyOf(room))) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const found = positionFor(room)\n if (!found) continue\n const p = found.point\n electrical.switches.push({ id: `switch${++counter}`, room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.1, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, door: found.door.id, latchSide: found.latch, controls: roomLamps.map((m) => m.id).concat(extra) })\n }\n if (door && plan.lot) {\n const id = `outdoor_${door.id}`\n electrical.outdoorLamps.push({ id, u: round2(door.at + door.width / 2 + 0.32), v: round2(door.pos), y: 2.15, door: door.id, switch: electrical.switches.find((s) => s.controls.includes(id))?.id ?? null })\n }\n}\n\n/** One circuit per room with sockets or switches, and the conduits: from the panel up to the ceiling, along it to the room and down to each point. */\nexport function addConduits(layout: Layout): void {\n const { plan, rooms, electrical } = layout\n const panel = electrical.panel\n const lamps = lampsOf(layout)\n for (const room of rooms) {\n const outlets = electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const switches = electrical.switches.filter((i) => i.room === room.id && i.floor === room.floor)\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n if (!outlets.length && !switches.length) continue\n const ceiling = (room.ceiling || plan.floors[room.floor].ceiling) - 0.12\n const part = room.parts[0]\n const centreU = round2((part[0] + part[2]) / 2)\n const centreV = round2((part[1] + part[3]) / 2)\n const circuit: Circuit = { id: `circuit_${room.id}_${room.floor}`, room: room.id, floor: room.floor, outlets: outlets.map((t) => t.id), switches: switches.map((i) => i.id), lamps: roomLamps.map((m) => m.id), exposed: electrical.exposed, gauge_mm2: outlets.length > 3 ? 2.5 : 1.5 }\n electrical.circuits.push(circuit)\n const base = heightOf(plan, room.floor, 0)\n const riser: Point3[] = panel ? [[panel.u, panel.v, heightOf(plan, panel.floor, panel.y)], [panel.u, panel.v, heightOf(plan, panel.floor, 0) + ceiling]] : []\n if (panel) electrical.conduits.push({ id: `conduit_${circuit.id}`, circuit: circuit.id, from: 'panel', to: room.id, exposed: electrical.exposed, diameter: 0.025, points: riser.concat([[centreU, centreV, base + ceiling]]) })\n for (const point of (outlets as WallFixture[]).concat(switches)) {\n electrical.conduits.push({ id: `conduit_${point.id}`, circuit: circuit.id, from: circuit.id, to: point.id, exposed: electrical.exposed, diameter: 0.02, points: [[centreU, centreV, base + ceiling], [point.u, point.v, base + ceiling], [point.u, point.v, base + point.y]] })\n }\n }\n if (panel) panel.breakers = electrical.circuits.length + 1\n}\n","import type { Plan, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Rng } from './shared'\nimport type { Circuit, Conduit, ElectricalPanel, LightSwitch, OutdoorLamp, Outlet, ServiceEntrance } from './types'\nimport { NO_SOCKET_ROOMS } from './shared'\nimport { addOutlets } from './electrical-outlets'\nimport { addConduits, addSwitches } from './electrical-circuits'\nimport { placeEntrance, placePanel } from './electrical-entrance'\nimport { wallPointsOf } from './wall-points'\nimport type { WallPoint } from './wall-points'\n\nexport type EnergyMode = 'grid' | 'tap' | 'offgrid'\n\n/** What a template says about its energy (a shack taps the grid without a meter, a cabin may run off-grid on solar). */\nexport interface EnergyConfig {\n mode: EnergyMode\n solar?: boolean\n}\n\nexport interface Electrical {\n mode: EnergyMode\n serviceEntrance: ServiceEntrance | null\n panel: ElectricalPanel | null\n outlets: Outlet[]\n switches: LightSwitch[]\n circuits: Circuit[]\n conduits: Conduit[]\n exposed: boolean\n outdoorLamps: OutdoorLamp[]\n source?: 'solar' | 'lamp'\n}\n\nexport interface ElectricalContext {\n plan: Plan\n items: ResultItem[]\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Shared state of the steps that lay the installation out. */\nexport interface Layout {\n plan: Plan\n items: ResultItem[]\n rooms: Room[]\n electrical: Electrical\n pointsOf: Map<string, WallPoint[]>\n}\n\nexport const keyOf = (room: Room): string => `${room.id}@${room.floor}`\n\nconst absolute = (plan: Plan, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\nexport const heightOf = absolute\n\n/**\n * The electrical installation: sockets for the appliances and by room size, the service entrance (pole, drop, meter, descent; a tap without meter for a shack),\n * the panel near the entrance, switches by the door latch, circuits and conduits. Items that plug in are annotated (`outlet`, `showerHeater`).\n */\nexport function planElectrical(context: ElectricalContext): Electrical {\n const { plan, items, rng, energy } = context\n const mode: EnergyMode = energy?.mode ?? 'grid'\n const electrical: Electrical = { mode, serviceEntrance: null, panel: null, outlets: [], switches: [], circuits: [], conduits: [], exposed: false, outdoorLamps: [] }\n electrical.exposed = plan.style === 'budget' ? rng() < 0.65 : plan.style === 'mid' ? rng() < 0.12 : false\n if (mode !== 'grid') electrical.exposed = true\n if (mode === 'offgrid') {\n electrical.source = energy?.solar ? 'solar' : 'lamp'\n return electrical\n }\n const rooms = plan.rooms.filter((room) => !NO_SOCKET_ROOMS.includes(room.type) && !room.outdoor)\n const pointsOf = new Map<string, WallPoint[]>()\n for (const room of rooms) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const layout: Layout = { plan, items, rooms, electrical, pointsOf }\n addOutlets(layout)\n placeEntrance(layout)\n placePanel(layout)\n addSwitches(layout)\n addConduits(layout)\n const entrance = electrical.serviceEntrance\n const meter = entrance?.meter\n if (mode === 'tap' && entrance && meter) {\n entrance.tap = true\n entrance.connection = { u: meter.u, v: meter.v, y: 2.6 }\n entrance.meter = null\n }\n return electrical\n}\n","import type { Plan, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\nimport type { Rng } from './shared'\nimport { HALF_WALL, clamp, groundExteriorWalls, inner, isSolid, outwardOf, overlaps, round2, sideNameOf } from './shared'\n\nexport const CYLINDER_TYPE = 'cooking_gas_cylinder'\nconst CYLINDER = { w: 0.36, d: 0.36, h: 0.48 }\nconst CYLINDER_KG = 13\n\nexport interface GasMeter {\n id: 'gas.meter'\n u: number\n v: number\n y: number\n side: string\n w: number\n d: number\n h: number\n}\n\nexport interface Gas {\n type: 'piped' | 'cylinder'\n meter: GasMeter | null\n}\n\ninterface Spot {\n mode: 'beside' | 'niche' | 'under'\n x: number\n z: number\n rect: Rect\n outdoor?: boolean\n cabinet?: string\n}\n\n/** Gas meter on the front wall of the ground floor, 1.2 m up. */\nfunction placeMeter(plan: Plan): GasMeter | null {\n const segments = groundExteriorWalls(plan).sort((a, b) => (b.sides.includes('outside') ? 1 : 0) - (a.sides.includes('outside') ? 1 : 0) || (a.axis === 'u' && a.v0 === 0 ? -1 : 1))\n const wall = segments.find((w) => w.axis === 'u' && w.v0 === 0) || segments[0]\n if (!wall) return null\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const vector = outwardOf(wall)\n const offset = HALF_WALL + 0.1\n return {\n id: 'gas.meter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.2, side: sideNameOf(vector), w: 0.3, d: 0.15, h: 0.4,\n }\n}\n\ninterface Context {\n plan: Plan\n items: ResultItem[]\n stateItems: ResultItem[]\n rng: Rng\n}\n\nfunction besideStove(context: Context, stove: ResultItem, room: Room, solids: Rect[], doorZones: Rect[]): Spot | undefined {\n const t: [number, number] = [-(stove.frontV ?? 1), (stove.frontU ?? 0)]\n const parts = room.parts.map(inner)\n for (const s of context.rng() < 0.5 ? [1, -1] : [-1, 1]) {\n const cx = stove.x + t[0] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - ((stove.frontU ?? 0) * (stove.d - CYLINDER.d)) / 2\n const cz = stove.z + t[1] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - ((stove.frontV ?? 1) * (stove.d - CYLINDER.d)) / 2\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const inside = parts.some((q: Rect) => rect[0] >= q[0] - 0.011 && rect[2] <= q[2] + 0.011 && rect[1] >= q[1] - 0.011 && rect[3] <= q[3] + 0.011)\n if (inside && !solids.some((o) => overlaps(rect, o, 0.011)) && !doorZones.some((z) => overlaps(rect, z, 0.011))) return { mode: 'beside', x: cx, z: cz, rect }\n }\n return undefined\n}\n\nfunction inNiche(context: Context, stove: ResultItem, room: Room, doorZones: Rect[]): Spot | undefined {\n const { plan, items, stateItems } = context\n const wall = plan.walls.find(\n (p) =>\n p.exterior && p.floor === stove.floor && p.type === 'wall' && p.sides.includes(room.id) &&\n (p.axis === 'u'\n ? Math.abs(stove.x - clamp(stove.x, p.u0, p.u1)) < 1.6 && Math.abs(stove.z - p.v0) < 1.6\n : Math.abs(stove.z - clamp(stove.z, p.v0, p.v1)) < 1.6 && Math.abs(stove.x - p.u0) < 1.6),\n )\n if (!wall || stove.floor !== 0) return undefined\n const vector = outwardOf(wall)\n const cx = wall.axis === 'u' ? clamp(stove.x, wall.u0 + 0.4, wall.u1 - 0.4) : wall.u0 + vector[0] * (HALF_WALL + CYLINDER.w / 2 + 0.05)\n const cz = wall.axis === 'u' ? wall.v0 + vector[1] * (HALF_WALL + CYLINDER.d / 2 + 0.05) : clamp(stove.z, wall.v0 + 0.4, wall.v1 - 0.4)\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const blockedByItem = items.some((o) => o.outdoor && isSolid(o) && overlaps(rect, o.aabb, 0.011))\n const blockedByState = stateItems.some((o) => o.outdoor && o.aabb && !o.flat && o.mount !== 'ground' && overlaps(rect, o.aabb, 0.011))\n const blockedByPath = plan.paths.some((c) => c.rects.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByGate = plan.gates.some((g) => g.zones.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByFence = !plan.lot || plan.lot.perimeter.some((q) => overlaps(rect, [Math.min(q.u0, q.u1) - HALF_WALL, Math.min(q.v0, q.v1) - HALF_WALL, Math.max(q.u0, q.u1) + HALF_WALL, Math.max(q.v0, q.v1) + HALF_WALL], 0.011))\n if (blockedByItem || blockedByState || blockedByPath || doorZones.some((z) => overlaps(rect, z, 0.011)) || blockedByGate || blockedByFence) return undefined\n return { mode: 'niche', x: cx, z: cz, rect, outdoor: true }\n}\n\nfunction underCounter(context: Context, stove: ResultItem): Spot | undefined {\n const distance = (m: ResultItem): number => Math.hypot(m.x - stove.x, m.z - stove.z)\n const cabinets = context.items\n .filter(\n (m) => m.floor === stove.floor && m.room === stove.room && !m.outdoor && !m.on && !m.flat && ['kitchen_cabinet', 'workbench'].includes(m.category) && m.aabb && m.id !== stove.id &&\n Math.min(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.d - 0.011 && Math.max(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.w + 0.02,\n )\n .sort((a, b) => (a.category === 'kitchen_cabinet' ? 0 : 1) - (b.category === 'kitchen_cabinet' ? 0 : 1) || distance(a) - distance(b))\n for (const cabinet of cabinets) {\n if (distance(cabinet) > 3) continue\n const box = cabinet.aabb as Rect\n const hw = CYLINDER.w / 2\n const hd = CYLINDER.d / 2\n const cx = clamp(stove.x, box[0] + hw + 0.01, box[2] - hw - 0.01)\n const cz = clamp(stove.z, box[1] + hd + 0.01, box[3] - hd - 0.01)\n const rect = [cx - hw, cz - hd, cx + hw, cz + hd].map(round2) as Rect\n if (rect[0] < box[0] || rect[2] > box[2] || rect[1] < box[1] || rect[3] > box[3] || overlaps(rect, stove.aabb, 0.011)) continue\n return { mode: 'under', x: cx, z: cz, rect, cabinet: cabinet.id }\n }\n return undefined\n}\n\nconst PLACEMENT = { beside: 'beside', niche: 'external_niche', under: 'under_counter' } as const\n\nfunction cylinderItem(stove: ResultItem, spot: Spot): ResultItem {\n const item: ResultItem = {\n id: `${stove.room}.${CYLINDER_TYPE}`, type: CYLINDER_TYPE, category: CYLINDER_TYPE, x: round2(spot.x), z: round2(spot.z), ry: 0, w: CYLINDER.w, d: CYLINDER.d, h: CYLINDER.h, y: 0,\n frontU: -(stove.frontU ?? 0), frontV: -(stove.frontV ?? 1), room: stove.room, floor: stove.floor, outdoor: !!spot.outdoor, slot: 'cylinder', on: null, mode: null, clearance: 0, flat: false, low: false,\n aabb: spot.rect, link: stove.id, placement: PLACEMENT[spot.mode], hose: [[round2(spot.x), round2(spot.z), 0.3], [stove.x, stove.z, 0.5]], capacityKg: CYLINDER_KG,\n }\n if (spot.cabinet) {\n item.on = spot.cabinet\n item.hidden = true\n }\n if (spot.outdoor) item.floor = -1\n item.color = stove.color\n return item\n}\n\n/**\n * Gas for the stoves of the house: a cylinder beside the stove, in an outside niche with a hose or under the counter, or (high-end houses, or when\n * nothing fits) piped gas with a meter on the facade. The cylinders are added to `items`; the stoves are annotated (`gas`, `cylinder`, `gasMeter`).\n */\nexport function planGas(context: Context): Gas | null {\n const { plan, items, stateItems, rng } = context\n const stoves = items.filter((m) => m.category === 'stove' && !m.outdoor)\n if (!stoves.length) return null\n const high = plan.style === 'high'\n const piped = plan.style !== 'commercial' && (high ? rng() < 0.8 : plan.style === 'mid' ? rng() < 0.1 : false)\n const out: Gas = { type: piped ? 'piped' : 'cylinder', meter: null }\n const ensureMeter = (): void => {\n if (!out.meter) out.meter = placeMeter(plan)\n }\n for (const stove of stoves) {\n const room = plan.rooms.find((c) => c.id === stove.room && c.floor === stove.floor)\n if (!room) continue\n stove.gas = piped ? 'piped' : 'cylinder'\n if (piped) {\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const solids = items.filter((m) => m.floor === stove.floor && m.room === stove.room && isSolid(m) && m.id !== stove.id).map((m) => m.aabb as Rect)\n .concat(stateItems.filter((m) => m.aabb && m.room === stove.room && m.floor === stove.floor && !m.flat && !m.on && m.mount !== 'window' && m.mount !== 'ground').map((m) => m.aabb as Rect))\n const doorZones = plan.doors.filter((p) => p.floor === stove.floor).flatMap((p) => p.zones as Rect[])\n const order: Spot['mode'][] = rng() < 0.7 ? ['beside', 'niche', 'under'] : ['niche', 'beside', 'under']\n let spot: Spot | undefined\n for (const mode of order) {\n if (spot) break\n spot = mode === 'beside' ? besideStove(context, stove, room, solids, doorZones) : mode === 'niche' ? inNiche(context, stove, room, doorZones) : underCounter(context, stove)\n }\n if (!spot) {\n stove.gas = 'piped'\n out.type = 'piped'\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const cylinder = cylinderItem(stove, spot)\n items.push(cylinder)\n stove.cylinder = cylinder.id\n }\n return out\n}\n","import type { Plan, ResultItem } from '@adatechnology/game-floorplan'\nimport { round2 } from './shared'\nimport type { WaterTank } from '../types'\nimport type { Plumbing, PlumbingPoint, PlumbingRun } from './types'\n\nconst FIXTURES: Record<string, string> = { kitchen_cabinet: 'tap', washbasin: 'tap', shower: 'shower', toilet: 'flush', laundry_tub: 'tub', washing_machine: 'machine' }\nconst FLOW_LPM: Record<string, number> = { tap: 6, shower: 9, flush: 6, tub: 8, machine: 12 }\nconst POINT_HEIGHT: Record<string, number> = { shower: 2.1, flush: 0.9, machine: 0.8 }\nconst DEFAULT_CAPACITY = { budget: 500, mid: 1000 }\n\nexport interface PlumbingContext {\n plan: Plan\n items: ResultItem[]\n tank: WaterTank | null\n}\n\nconst absolute = (plan: Plan, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\n\n/**\n * Plumbing as logic: a point for every tap, shower, toilet, tub and machine, and the runs you can see: the outlet of the tank, under each sink and in the wall\n * from the tank to every wet room (hidden in the wall, it shows only where the wall breaks).\n */\nexport function planPlumbing(context: PlumbingContext): Plumbing {\n const { plan, items, tank } = context\n const fixtures = items.filter((m) => FIXTURES[m.category] && !m.decor)\n const points: PlumbingPoint[] = []\n const runs: PlumbingRun[] = []\n const capacity = tank?.capacity ?? (plan.style === 'budget' ? DEFAULT_CAPACITY.budget : plan.style === 'mid' ? DEFAULT_CAPACITY.mid : plan.tpl?.id === 'mansion' ? 3000 : 2000)\n const plumbing: Plumbing = { tank: tank ? 'water_tank' : null, capacityL: tank || !plan.tpl.noWalls ? capacity : 0, points, visibleRuns: runs }\n const top = plan.floors.length - 1\n fixtures.forEach((item, index) => {\n const kind = FIXTURES[item.category]!\n points.push({ id: `pt${index + 1}`, kind, item: item.id, room: item.room, floor: item.outdoor ? -1 : item.floor, u: item.x, v: item.z, y: POINT_HEIGHT[kind] ?? 0.9, flowLpm: FLOW_LPM[kind], run: null })\n })\n if (!tank) return plumbing\n const slabY = absolute(plan, top, plan.floors[top].ceiling)\n const tankY = tank.place === 'raised_slab' ? tank.platform!.topY : tank.place === 'attic' ? slabY + 0.5 : tank.y\n runs.push({ id: 'run_outlet', from: 'water_tank', to: 'ceiling', points: [[tank.u, tank.v, round2(tankY + 0.15)], [tank.u, tank.v, round2(slabY - 0.15)]], diameter: 0.032, exposed: 'tank_outlet' })\n for (const point of points) {\n const item = fixtures.find((x) => x.id === point.item)!\n if (point.kind !== 'tap' || item.outdoor) continue\n const front = [item.frontU || 0, item.frontV || 1]\n const behind = [item.x - front[0]! * (item.d / 2 + 0.02), item.z - front[1]! * (item.d / 2 + 0.02)]\n runs.push({ id: `run_under_${point.id}`, from: 'valve', to: point.id, points: [[round2(behind[0]!), round2(behind[1]!), absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.75)]], diameter: 0.025, exposed: 'under_sink' })\n }\n const wet: { room: string | null; floor: number; points: PlumbingPoint[] }[] = []\n for (const point of points) {\n if (!wet.some((c) => c.room === point.room && c.floor === point.floor)) wet.push({ room: point.room, floor: point.floor, points: points.filter((q) => q.room === point.room && q.floor === point.floor) })\n }\n for (const room of wet) {\n const found = plan.rooms.find((c) => c.id === room.room && c.floor === room.floor)\n const zone = plan.zones.find((z) => z.id === room.room)\n const parts = (found || zone || { parts: [[tank.u, tank.v, tank.u, tank.v]] }).parts\n const centreU = (parts[0][0] + parts[0][2]) / 2\n const centreV = (parts[0][1] + parts[0][3]) / 2\n const ceiling = found ? found.ceiling || plan.floors[found.floor].ceiling : 2.8\n const y0 = found ? absolute(plan, found.floor, 0) : 0\n const id = `run_wall_${room.room}${room.floor === -1 ? '_outside' : `_${room.floor}`}`\n runs.push({ id, from: 'water_tank', to: room.room, points: [[tank.u, tank.v, round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(y0 + ceiling - 0.15)], [round2(centreU), round2(centreV), round2(y0 + 0.6)]], diameter: 0.025, exposed: 'wall' })\n for (const point of room.points) point.run = id\n }\n return plumbing\n}\n","import type { Plan } from '@adatechnology/game-floorplan'\nimport { outwardOf, groundExteriorWalls, HALF_WALL, round2, sideNameOf } from './shared'\nimport type { Rng } from './shared'\nimport type { Inverter, Solar, SolarPanel } from './types'\nimport type { EnergyConfig } from './electrical'\n\nconst PANEL_WIDTH = 1.0\nconst PANEL_LENGTH = 1.65\nconst NO_PANELS_UNDER: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch']\n\nexport interface SolarContext {\n plan: Plan\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Inverter on a side wall of the ground floor, 1.5 m up. */\nfunction placeInverter(plan: Plan): Inverter | null {\n const wall = groundExteriorWalls(plan).filter((q) => q.sides.includes('outside')).sort((a, b) => (a.axis === 'v' ? 0 : 1) - (b.axis === 'v' ? 0 : 1))[0]\n if (!wall) return null\n const vector = outwardOf(wall)\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const offset = HALF_WALL + 0.08\n return { id: 'inverter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.5, side: sideNameOf(vector), w: 0.4, d: 0.15, h: 0.5, outdoor: true, link: 'panel' }\n}\n\n/**\n * Solar panels: about 6% of budget houses, 25% of mid and 50% of the rest; on the roof slope that faces north or on tilted racks on a flat roof, with the\n * inverter on the wall. A template with its own energy decides (`energy.solar`).\n */\nexport function planSolar(context: SolarContext): Solar | null {\n const { plan, rng, energy } = context\n if (!plan.lot || plan.style === 'commercial' || !plan.facade) return null\n const chance = plan.style === 'budget' ? 0.06 : plan.style === 'mid' ? 0.25 : 0.5\n const forced = energy ? (energy.solar ? 1 : 0) : null\n const draw = rng()\n if (forced !== null ? !forced : draw >= chance) return null\n const floor = plan.floors.length - 1\n const level = plan.floors[floor]\n const flat = plan.facade.roof === 'slab'\n const tops = plan.rooms.filter((c) => c.floor === floor && !NO_PANELS_UNDER.includes(c.type))\n if (!tops.length) return null\n const parts: number[][] = tops.flatMap((c) => c.parts)\n const box = [Math.min(...parts.map((q) => q[0]!)), Math.min(...parts.map((q) => q[1]!)), Math.max(...parts.map((q) => q[2]!)), Math.max(...parts.map((q) => q[3]!))] as [number, number, number, number]\n const north = rng() < 0.5 ? 'front' : 'back'\n const angle = flat ? 15 : 25\n const projection = round2(PANEL_LENGTH * Math.cos((angle * Math.PI) / 180))\n const margin = 0.6\n const uStart = box[0] + margin\n const uEnd = box[2] - margin\n const columns = Math.max(1, Math.floor((uEnd - uStart) / (PANEL_WIDTH + 0.05)))\n const vMiddle = (box[1] + box[3]) / 2\n const vArea = flat ? [box[1] + margin, box[3] - margin] : north === 'front' ? [box[1] + 0.4, vMiddle - 0.2] : [vMiddle + 0.2, box[3] - 0.4]\n const step = flat ? projection + 0.5 : projection + 0.05\n const rowsMax = Math.max(1, Math.floor((vArea[1]! - vArea[0]!) / step))\n const wanted = forced !== null ? 1 + Math.floor(rng() * 2) : 3 + Math.floor(rng() * (plan.style === 'high' ? 12 : 8))\n const rows = Math.max(1, Math.min(rowsMax, Math.ceil(wanted / columns)))\n const count = Math.min(wanted, rows * columns)\n const u0 = uStart + (uEnd - uStart - columns * (PANEL_WIDTH + 0.05)) / 2\n const vStart = north === 'front' ? vArea[0]! : vArea[1]! - rows * step\n const panels: SolarPanel[] = []\n for (let k = 0; k < count; k++) {\n const row = Math.floor(k / columns)\n const column = k % columns\n panels.push({ id: `pv${k + 1}`, u: round2(u0 + column * (PANEL_WIDTH + 0.05) + PANEL_WIDTH / 2), v: round2(vStart + row * step + (flat ? 0.25 : 0) + projection / 2), w: PANEL_WIDTH, d: projection, length: PANEL_LENGTH })\n }\n const area = [round2(u0), round2(vStart), round2(u0 + columns * (PANEL_WIDTH + 0.05)), round2(vStart + rows * step)]\n return { type: flat ? 'slab_rack' : 'roof', orientation: 'north', north, slopeSide: flat ? null : north, tilt: angle, area, areaM2: round2(count * PANEL_WIDTH * PANEL_LENGTH), count, floor, y: round2(level.y0 + level.ceiling), panels, inverter: placeInverter(plan) }\n}\n","import type { FindStack, FindsQuery, Plan, ResultItem } from '@adatechnology/game-floorplan'\n\nimport type { WaterTank } from '../types'\nimport { hasContent } from './content'\nimport type { EnergyConfig, Electrical } from './electrical'\nimport { planElectrical } from './electrical'\nimport { planGas } from './gas'\nimport type { Gas } from './gas'\nimport { planPlumbing } from './plumbing'\nimport type { Rng } from './shared'\nimport type { Plumbing, Solar } from './types'\nimport { planSolar } from './solar'\n\nexport interface Utilities {\n gas: Gas | null\n electrical: Electrical\n solar: Solar | null\n plumbing: Plumbing\n}\n\nexport interface UtilitiesContext {\n plan: Plan\n items: ResultItem[]\n stateItems: ResultItem[]\n tank: WaterTank | null\n energy?: EnergyConfig\n /** Seeded stream by name: `gas`, `electrical`, `solar`. */\n rngFor(key: string): Rng\n}\n\n/** Gas, electricity, solar panels and plumbing of a house, in the order that lets the later ones see the cylinders the first adds to `items`. */\nexport function planUtilities(context: UtilitiesContext): Utilities {\n const { plan, items, stateItems, tank, energy, rngFor } = context\n const gas = planGas({ plan, items, stateItems, rng: rngFor('gas') })\n const electrical = planElectrical({ plan, items, rng: rngFor('eletrica'), ...(energy ? { energy } : {}) })\n const solar = planSolar({ plan, rng: rngFor('solar'), ...(energy ? { energy } : {}) })\n const plumbing = planPlumbing({ plan, items, tank })\n return { gas, electrical, solar, plumbing }\n}\n\nconst OVERHEAD = 'overhead_cabinet'\nconst ALWAYS_HOLD: readonly string[] = ['trash_bin', 'outdoor_bin', 'mailbox']\n\nexport interface ContentsContext {\n items: ResultItem[]\n state: string\n place: string\n /** Outbreak days and region of the world, passed to the finds provider. */\n day?: number\n region?: string\n rngFor(key: string): Rng\n findsFor(query: FindsQuery): readonly FindStack[]\n}\n\n/** What every container holds, asked of the registered finds provider: by item id, and `<id>#overhead` for the wall cabinet over a sink. */\nexport function planContents(context: ContentsContext): Record<string, readonly FindStack[]> {\n const out: Record<string, readonly FindStack[]> = {}\n const ask = (item: ResultItem, container: string, key: string): readonly FindStack[] =>\n context.findsFor({ place: context.place, container, state: context.state, rng: context.rngFor(key), footprint: item.w * item.d, key: item.id, ...(context.day === undefined ? {} : { day: context.day }), ...(context.region === undefined ? {} : { region: context.region }) })\n for (const item of context.items) {\n if (item.decor && item.mount !== 'wall_top') continue\n const container = hasContent(item.type) ? item.type : item.category\n if (!hasContent(container)) continue\n if (!ALWAYS_HOLD.includes(container) && item.decor) continue\n out[item.id] = ask(item, container, `content:${item.id}`)\n if (container === 'kitchen_cabinet' && item.overhead !== false) out[`${item.id}#overhead`] = ask(item, OVERHEAD, `content:${item.id}:overhead`)\n }\n return out\n}\n","import type { FurnitureDef, Plan, ResultItem, ResultLot, Vec2 } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\nimport type { Rng } from './shared'\nimport type { Outbuilding, OutbuildingItem, OutbuildingOpening, OutbuildingWall } from './types'\nimport { isSolid, overlaps, round2 } from './shared'\n\nconst WALL = 0.15\nconst DOOR_WIDTH = 0.85\nconst DOOR_HEIGHT = 2.1\nconst USES: Record<string, string[]> = { guest_room: ['single_bed', 'nightstand'], office: ['desk', 'shelf_unit_small'], storage: ['tool_shelf', 'crate'], gourmet: ['dining_table_small', 'workbench'] }\nconst USE_WEIGHTS: Record<string, number> = { guest_room: 3, office: 2, storage: 2, gourmet: 2 }\nconst PATH_WIDTH = 1.0\n\nexport interface OutbuildingContext {\n plan: Plan\n items: ResultItem[]\n catalog: Record<string, FurnitureDef>\n rngFor(key: string): Rng\n}\n\n/**\n * Name of the seeded stream of an outbuilding. It is the name the Visor de casas 3D gave it (`edif:<room>.<slot>` in Portuguese: `quintal.edicula`), kept verbatim so that an\n * old seed draws the same use and furniture; it never appears in the output.\n */\nconst LEGACY_ROOMS: Record<string, string> = { backyard: 'quintal' }\nconst LEGACY_SLOTS: Record<string, string> = { outbuilding: 'edicula' }\nexport const streamOf = (itemId: string): string => {\n const [room = '', ...slot] = itemId.split('.')\n return `edif:${LEGACY_ROOMS[room] ?? room}.${slot.map((part) => LEGACY_SLOTS[part] ?? part).join('.')}`\n}\n\nfunction pickWeighted(rng: Rng, weights: Record<string, number>): string {\n const keys = Object.keys(weights)\n let x = rng() * keys.reduce((sum, key) => sum + weights[key]!, 0)\n for (const key of keys) {\n x -= weights[key]!\n if (x < 0) return key\n }\n return keys[keys.length - 1]!\n}\n\nconst sideOf = (x: number, z: number): string => (Math.abs(x) > Math.abs(z) ? (x > 0 ? 'right' : 'left') : z > 0 ? 'back' : 'front')\n\ninterface Frame {\n n: [number, number]\n t: [number, number]\n cx: number\n cz: number\n depth: number\n width: number\n horizontal: boolean\n sideToMiddle: number\n}\n\nconst at = (frame: Frame, a: number, b: number): [number, number] => [frame.cx + frame.n[0] * a + frame.t[0] * b, frame.cz + frame.n[1] * a + frame.t[1] * b]\n\nfunction opening(frame: Frame, id: string, a: number, b: number, vector: [number, number], width: number, extra: Partial<OutbuildingOpening>): OutbuildingOpening {\n const [u, v] = at(frame, a, b)\n const alongU = Math.abs(vector[0]) !== 1\n return { id, axis: alongU ? 'u' : 'v', pos: round2(alongU ? v : u), at: round2(alongU ? u : v), u: round2(u), v: round2(v), width: round2(width), side: sideOf(vector[0], vector[1]), ...extra }\n}\n\nfunction wallsOf(box: Rect, door: OutbuildingOpening, height: number): OutbuildingWall[] {\n const walls: OutbuildingWall[] = []\n const sides: { axis: 'u' | 'v'; pos: number; i0: number; i1: number; side: string }[] = [\n { axis: 'u', pos: box[1], i0: box[0], i1: box[2], side: 'front' }, { axis: 'u', pos: box[3], i0: box[0], i1: box[2], side: 'back' },\n { axis: 'v', pos: box[0], i0: box[1], i1: box[3], side: 'left' }, { axis: 'v', pos: box[2], i0: box[1], i1: box[3], side: 'right' },\n ]\n for (const w of sides) {\n const cut = w.axis === door.axis && Math.abs(w.pos - door.pos) < 0.02 ? [door.at - door.width / 2, door.at + door.width / 2] : null\n const segments = cut ? [[w.i0, cut[0]!], [cut[1]!, w.i1]] : [[w.i0, w.i1]]\n for (const [x0, x1] of segments) {\n if (x1! - x0! <= 1e-3) continue\n walls.push(w.axis === 'u' ? { axis: 'u', u0: round2(x0!), v0: round2(w.pos), u1: round2(x1!), v1: round2(w.pos), thickness: WALL, h: height, side: w.side } : { axis: 'v', u0: round2(w.pos), v0: round2(x0!), u1: round2(w.pos), v1: round2(x1!), thickness: WALL, h: height, side: w.side })\n }\n }\n return walls\n}\n\nfunction furnish(context: OutbuildingContext, frame: Frame, use: string, interior: Rect, insideDoor: Rect): OutbuildingItem[] {\n const placed: OutbuildingItem[] = []\n USES[use]!.forEach((type, k) => {\n const def = context.catalog[type]!\n const facing: [number, number] = k === 0 ? frame.n : [frame.t[0] * frame.sideToMiddle, frame.t[1] * frame.sideToMiddle]\n const [a, b] = k === 0 ? [-frame.depth / 2 + WALL + def.d / 2, frame.sideToMiddle * -0.4] : [-0.1, -frame.sideToMiddle * (frame.width / 2 - WALL - def.d / 2)]\n const [u, v] = at(frame, a, b)\n const eu = Math.abs(facing[0]) === 1 ? def.d : def.w\n const ev = Math.abs(facing[0]) === 1 ? def.w : def.d\n const box = [u - eu / 2, v - ev / 2, u + eu / 2, v + ev / 2].map(round2) as Rect\n if (box[0] < interior[0] - 0.011 || box[2] > interior[2] + 0.011 || box[1] < interior[1] - 0.011 || box[3] > interior[3] + 0.011 || overlaps(box, insideDoor) || placed.some((o) => overlaps(box, o.aabb))) return\n placed.push({ type, category: def.category, u: round2(u), v: round2(v), w: def.w, d: def.d, h: def.h, ry: Math.atan2(facing[0], facing[1]), frontU: facing[0], frontV: facing[1], aabb: box })\n })\n return placed\n}\n\n/**\n * The outbuilding at the back of the yard is a small building of its own: walls with a gap for the door, a door of 0.85 m facing the yard, two windows and the\n * furniture of a drawn use (guest room, office, storage, gourmet space).\n */\nexport function planOutbuildings(context: OutbuildingContext): Outbuilding[] {\n const { plan, items } = context\n const lot = plan.lot\n if (!lot) return []\n const out: Outbuilding[] = []\n for (const item of items.filter((m) => m.category === 'outbuilding')) {\n const rng = context.rngFor(streamOf(item.id))\n const [a0, a1, a2, a3] = item.aabb as Rect\n const frontU = item.frontU ?? 0\n const frontV = item.frontV ?? 1\n const n: [number, number] = [frontU, frontV]\n const t: [number, number] = [-frontV, frontU]\n const horizontal = Math.abs(frontU) === 1\n const cx = (a0 + a2) / 2\n const cz = (a1 + a3) / 2\n const depth = horizontal ? a2 - a0 : a3 - a1\n const width = horizontal ? a3 - a1 : a2 - a0\n const sideToMiddle = ((lot.rect[0] + lot.rect[2]) / 2 - cx) * t[0] + ((lot.rect[1] + lot.rect[3]) / 2 - cz) * t[1] >= 0 ? 1 : -1\n const frame: Frame = { n, t, cx, cz, depth, width, horizontal, sideToMiddle }\n const doorOffset = sideToMiddle * (width / 2 - 0.95)\n const door = opening(frame, `${item.id}.d0`, depth / 2, doorOffset, n, DOOR_WIDTH, { height: DOOR_HEIGHT, exterior: true })\n const windowFront = opening(frame, `${item.id}.w0`, depth / 2, -sideToMiddle * (width / 2 - 0.9), n, Math.min(1.0, width / 2 - 0.6), { y0: 1.0, y1: 2.0 })\n const windowSide = opening(frame, `${item.id}.w1`, 0, (sideToMiddle * width) / 2, [t[0] * sideToMiddle, t[1] * sideToMiddle], Math.min(1.0, depth - 0.8), { y0: 1.0, y1: 2.0 })\n const [p, q] = [at(frame, depth / 2, doorOffset), at(frame, depth / 2 - 0.9, doorOffset)]\n door.zone = (horizontal ? [Math.min(p[0], q[0]), p[1] - door.width / 2, Math.max(p[0], q[0]), p[1] + door.width / 2] : [p[0] - door.width / 2, Math.min(p[1], q[1]), p[0] + door.width / 2, Math.max(p[1], q[1])]).map(round2) as Rect\n const interior: Rect = [a0 + WALL, a1 + WALL, a2 - WALL, a3 - WALL]\n const use = pickWeighted(rng, USE_WEIGHTS)\n out.push({ id: item.id, type: 'outbuilding', use, floor: 0, aabb: item.aabb.slice() as Rect, interior: [interior.map(round2) as Rect], ceiling: item.h, thickness: WALL, front: n, walls: wallsOf(item.aabb, door, item.h), doors: [door], windows: [windowFront, windowSide], items: furnish(context, frame, use, interior, door.zone) })\n }\n return out\n}\n\n/** A pedestrian path from every door of an outbuilding: a 1 m stub out of the door and an L to the nearest existing path, away from furniture, the building and the fence. */\nexport function addOutbuildingPaths(lot: ResultLot, outbuildings: Outbuilding[], items: ResultItem[]): void {\n const half = PATH_WIDTH / 2\n const rect = lot.rect\n const solids = items.filter((m) => m.outdoor && m.aabb && isSolid(m)).map((m) => m.aabb as Rect)\n const fence = lot.perimeter.map((q) => [Math.min(q.u0, q.u1) - 0.075, Math.min(q.v0, q.v1) - 0.075, Math.max(q.u0, q.u1) + 0.075, Math.max(q.v0, q.v1) + 0.075] as Rect)\n const strip = (p: number[], q: number[]): Rect => [Math.min(p[0]!, q[0]!) - half, Math.min(p[1]!, q[1]!) - half, Math.max(p[0]!, q[0]!) + half, Math.max(p[1]!, q[1]!) + half]\n for (const building of outbuildings) {\n for (const door of building.doors) {\n if (lot.paths.some((c) => c.to === door.id)) continue\n const z = door.zone as Rect\n const zc = door.axis === 'v' ? (z[0] + z[2]) / 2 : (z[1] + z[3]) / 2\n const outside = zc > door.pos ? -1 : 1\n const A = door.axis === 'v' ? [door.pos, door.at] : [door.at, door.pos]\n const S = door.axis === 'v' ? [door.pos + outside * PATH_WIDTH, door.at] : [door.at, door.pos + outside * PATH_WIDTH]\n const stub: Rect = door.axis === 'v' ? [Math.min(A[0]!, S[0]!), A[1]! - half, Math.max(A[0]!, S[0]!), A[1]! + half] : [A[0]! - half, Math.min(A[1]!, S[1]!), A[0]! + half, Math.max(A[1]!, S[1]!)]\n const cost = (rs: Rect[]): number => {\n let n = 0\n for (const r of rs) {\n const c: Rect = [r[0] + 0.02, r[1] + 0.02, r[2] - 0.02, r[3] - 0.02]\n for (const q of solids) if (overlaps(c, q, 0.011)) n += 2\n if (overlaps(c, building.aabb, 0.011)) n += 3\n for (const q of fence) if (overlaps(c, q, 0.011)) n += 3\n if (r[0] < rect[0] || r[1] < rect[1] || r[2] > rect[2] || r[3] > rect[3]) n += 3\n }\n return n\n }\n let best: { v: number; k: { rects: Rect[]; points: number[][] }; from: string | null } | null = null\n for (const c of lot.paths.filter((p) => p.type === 'pedestrian' || p.id === 'cargo_path')) {\n for (const r of c.rects as Rect[]) {\n const T = [Math.min(Math.max(S[0]!, r[0] + half), r[2] - half), Math.min(Math.max(S[1]!, r[1] + half), r[3] - half)]\n const candidates: { rects: Rect[]; points: number[][] }[] = []\n if (Math.abs(T[0]! - S[0]!) < 1e-6 && Math.abs(T[1]! - S[1]!) < 1e-6) candidates.push({ rects: [stub], points: [A, S] })\n else for (const via of [[T[0]!, S[1]!], [S[0]!, T[1]!]]) candidates.push({ rects: [stub, strip(S, via), strip(via, T)].filter((q) => q[2] - q[0] > 1e-6), points: [A, S, via, T] })\n for (const k of candidates) {\n const distance = k.points.slice(1).reduce((sum, q, i) => sum + Math.abs(q[0]! - k.points[i]![0]!) + Math.abs(q[1]! - k.points[i]![1]!), 0)\n const value = cost(k.rects.slice(1)) * 100 + distance\n if (!best || value < best.v) best = { v: value, k, from: c.from }\n }\n }\n }\n const chosen = best ? best.k : { rects: [stub], points: [A, S] }\n lot.paths.push({ id: `path_${door.id}`, type: 'pedestrian', from: best ? best.from : null, to: door.id, width: PATH_WIDTH, rects: chosen.rects.map((q) => q.map(round2) as Rect), points: chosen.points.map((q) => q.map(round2) as Vec2) })\n }\n }\n}\n","import { round2 } from './geometry'\nimport type { Rect, StructureSource, WaterTank } from './types'\n\ntype Rng = () => number\n\nconst TANK_SIDE = 1.1\n/** Side of the concrete pillars of a raised tank slab, metres: NBR 6118 asks at least 19 cm. */\nexport const TANK_PILLAR_SIDE = 0.2\n/** The 0.12 m pillars of the Visor de casas 3D, below the NBR 6118 minimum (`visorSections`, for the team's golden only). */\nexport const VISOR_TANK_PILLAR_SIDE = 0.12\nconst NOT_UNDER_TANK = ['void', 'elevator', 'stairs', 'balcony', 'porch']\nconst WET_ROOMS = ['bathroom', 'kitchen', 'laundry']\nconst ATTIC_CHANCE = 0.12\nconst clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport interface TankPlanOptions {\n /** Litres by template id or style id (default: budget 500, mid 1000, mansion 3000, any other 2000). */\n capacities?: Record<string, number>\n /** Where the tank goes; default: on the slab of a flat roof, else on a raised platform (the attic one time in eight). */\n location?: (source: StructureSource, rng: Rng) => WaterTank['place']\n /** A template with its own tank (a trestle for the rural water) answers here instead. */\n custom?: (source: StructureSource, rng: Rng) => WaterTank | null\n /** Side of the platform's concrete pillars (default `TANK_PILLAR_SIDE`; the Visor de casas 3D drew 0.12 m). */\n pillarSide?: number\n}\n\nconst DEFAULT_CAPACITIES: Record<string, number> = { budget: 500, mid: 1000, mansion: 3000 }\n\nfunction capacityOf(source: StructureSource, capacities: Record<string, number>): number {\n return capacities[source.style ?? ''] ?? capacities[source.template ?? ''] ?? 2000\n}\n\n/** Candidate spot: the room part with the least weight (wet rooms first, terraces last, near the reference point or the middle). */\nfunction bestSpot(source: StructureSource, floor: number, reference: { u: number; v: number } | undefined): { roomType: string; roomId: string; rect: Rect } | undefined {\n const centre: [number, number] = reference ? [reference.u, reference.v] : [source.w / 2, source.d / 2]\n let best: { roomType: string; roomId: string; rect: Rect; weight: number } | undefined\n for (const room of source.rooms.filter((r) => r.floor === floor && !NOT_UNDER_TANK.includes(r.type))) {\n for (const part of room.parts) {\n const rect: Rect = [part[0] + 0.4, part[1] + 0.4, part[2] - 0.4, part[3] - 0.4]\n if (rect[2] - rect[0] < TANK_SIDE || rect[3] - rect[1] < TANK_SIDE) continue\n const base = WET_ROOMS.includes(room.type) ? 0 : room.type === 'terrace' ? 500 : 100\n const weight = base + Math.hypot((rect[0] + rect[2]) / 2 - centre[0], (rect[1] + rect[3]) / 2 - centre[1])\n if (!best || weight < best.weight) best = { roomType: room.type, roomId: room.id, rect, weight }\n }\n }\n return best\n}\n\nfunction raisedPlatform(source: StructureSource, spot: { u: number; v: number; baseY: number }, side: number): NonNullable<WaterTank['platform']> {\n const { u, v, baseY } = spot\n const margin = 0.12\n const edge = Math.max(0, Math.min(u, source.w - u, v, source.d - v))\n const rise = round2(clamp(edge * 0.35 + 0.7, 1.1, 2.4))\n const thickness = 0.12\n const reach = TANK_SIDE / 2 + margin - side / 2\n const pillars = ([[-1, -1], [1, -1], [-1, 1], [1, 1]] as const).map(([a, b]) => ({ u: round2(u + a * reach), v: round2(v + b * reach), side }))\n const half = TANK_SIDE / 2 + margin\n return { aabb: [u - half, v - half, u + half, v + half].map(round2) as Rect, baseY, height: rise, thickness, topY: round2(baseY + rise + thickness), pillars, ladder: true }\n}\n\n/**\n * The water tank of a house: on the roof slab, in the attic, or on a platform that rises out of the roof, never in the yard. Null for a plan without\n * a lot (an apartment) or a commercial building, and when no room has space.\n */\nexport function planWaterTank(source: StructureSource, rng: Rng, options: TankPlanOptions = {}): WaterTank | null {\n if (!source.lot || source.style === 'commercial') return null\n if (options.custom) return options.custom(source, rng)\n const floor = source.floors.length - 1\n const level = source.floors[floor]!\n const capacity = capacityOf(source, { ...DEFAULT_CAPACITIES, ...options.capacities })\n const height = capacity >= 2000 ? 1.4 : capacity === 1000 ? 1.0 : 0.85\n const place = options.location ? options.location(source, rng) : source.facade.roof === 'slab' ? 'slab' : rng() < ATTIC_CHANCE ? 'attic' : 'raised_slab'\n const reference = (source.facade.slab as { waterTank?: { u: number; v: number } } | undefined)?.waterTank\n const spot = bestSpot(source, floor, reference)\n if (!spot) return null\n const target = reference ? [reference.u, reference.v] : [(spot.rect[0] + spot.rect[2]) / 2, (spot.rect[1] + spot.rect[3]) / 2]\n const u = clamp(target[0]!, spot.rect[0] + TANK_SIDE / 2, spot.rect[2] - TANK_SIDE / 2)\n const v = clamp(target[1]!, spot.rect[1] + TANK_SIDE / 2, spot.rect[3] - TANK_SIDE / 2)\n const where = spot.roomType === 'terrace' ? 'slab' : place\n const slabY = round2(spot.roomType === 'terrace' ? level.y0 : level.y0 + level.ceiling)\n const tank: WaterTank = {\n id: 'water_tank', kind: 'water_tank', itemType: 'water_tank', place: where, floor, room: spot.roomId, u: round2(u), v: round2(v), y: slabY, w: TANK_SIDE, d: TANK_SIDE, h: height,\n capacity, aabb: [u - TANK_SIDE / 2, v - TANK_SIDE / 2, u + TANK_SIDE / 2, v + TANK_SIDE / 2].map(round2) as Rect,\n }\n if (where === 'raised_slab') {\n tank.platform = raisedPlatform(source, { u, v, baseY: slabY }, options.pillarSide ?? TANK_PILLAR_SIDE)\n tank.y = tank.platform.topY\n }\n return tank\n}\n","import type { ViewerLayer, ViewerLayerContext, ViewerLayerLegendEntry } from '@adatechnology/game-floorplan'\n\nimport type { Roof, Structure, StructurePart } from './types'\n\ntype MaterialGroup = 'concrete' | 'steel' | 'masonry' | 'wood'\n\nconst COLORS: Record<MaterialGroup, string> = { concrete: '#7d8590', steel: '#3d6fb0', masonry: '#b5654b', wood: '#a0693a' }\nconst BEAM_IDS = ['plate_', 'porch_beam', 'base_beam', 'trestle_beam']\n\nexport const LAYER_ID = 'structure'\n\nexport function groupOf(material: string): MaterialGroup {\n if (material === 'concrete') return 'concrete'\n if (material === 'steel' || material === 'aluminium' || material === 'cast_iron') return 'steel'\n if (material === 'brick' || material === 'stone' || material === 'ceramic') return 'masonry'\n return 'wood'\n}\n\nconst isRoofFrame = (part: StructurePart): boolean => ['truss', 'rafter', 'ridge'].some((prefix) => part.id.startsWith(prefix))\nconst isDrawnBeam = (part: StructurePart): boolean => part.role === 'beam' && BEAM_IDS.some((prefix) => part.id.startsWith(prefix))\n\nfunction drawColumns(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n for (const part of parts.filter((p) => p.role === 'column')) {\n const color = COLORS[groupOf(part.material)]\n if (groupOf(part.material) === 'wood') context.rect(part.aabb, null, color, 2)\n else context.rect(part.aabb, color, null)\n context.hit(part.aabb, `${part.id} · column · ${part.material} · ${part.mass} kg`)\n }\n}\n\nfunction drawBeams(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([6, 4])\n for (const part of parts.filter(isDrawnBeam)) {\n context.rect(part.aabb, null, COLORS[groupOf(part.material)], 1.5)\n context.hit(part.aabb, `${part.id} · beam · ${part.material} · ${part.mass} kg`)\n }\n context.g.restore()\n}\n\nfunction drawRoofFrames(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.strokeStyle = COLORS.wood\n context.g.lineWidth = 1\n for (const part of parts.filter(isRoofFrame)) {\n const [u0, v0, u1, v1] = part.aabb\n const alongV = v1 - v0 > u1 - u0\n context.g.beginPath()\n if (alongV) { context.g.moveTo(context.X((u0 + u1) / 2), context.Z(v0)); context.g.lineTo(context.X((u0 + u1) / 2), context.Z(v1)) }\n else { context.g.moveTo(context.X(u0), context.Z((v0 + v1) / 2)); context.g.lineTo(context.X(u1), context.Z((v0 + v1) / 2)) }\n context.g.stroke()\n }\n context.g.restore()\n}\n\nfunction drawPorchRoofs(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([2, 4])\n for (const part of parts.filter((p) => p.id.startsWith('porch_roof'))) context.rect(part.aabb, null, COLORS.wood, 1)\n context.g.restore()\n}\n\n/** What the viewer draws at one storey: pillars (filled for concrete, steel and masonry, hollow for wood), dashed beams, trusses on the top storey, the porch roof outline. */\nexport function drawStructure(context: ViewerLayerContext): void {\n // the structure and roof extensions of this pack wrote these into the result\n const structure = context.plan.structure as Structure | undefined\n if (!structure) return\n const floor = context.all ? 0 : context.floor\n const here = structure.parts.filter((part) => part.floor === floor)\n drawPorchRoofs(context, here)\n if (floor === ((context.plan.roof as Roof | null | undefined)?.bearingFloor ?? 0)) drawRoofFrames(context, structure.parts)\n drawBeams(context, here)\n drawColumns(context, here)\n}\n\nexport function structureLegend(plan: Readonly<Record<string, unknown>>): ViewerLayerLegendEntry[] {\n const parts = (plan.structure as Pick<Structure, 'parts'> | undefined)?.parts ?? [] // written by the structure extension\n const entries: ViewerLayerLegendEntry[] = []\n for (const group of ['concrete', 'steel', 'masonry', 'wood'] as const) {\n const columns = parts.some((p) => p.role === 'column' && groupOf(p.material) === group)\n if (columns) entries.push({ label: `structure_column_${group}`, color: COLORS[group], shape: group === 'wood' ? 'hollow' : 'filled' })\n }\n for (const group of ['concrete', 'wood'] as const) {\n if (parts.some((p) => isDrawnBeam(p) && groupOf(p.material) === group)) entries.push({ label: `structure_beam_${group}`, color: COLORS[group], shape: 'dashed' })\n }\n if (parts.some(isRoofFrame)) entries.push({ label: 'structure_roof_frame', color: COLORS.wood, shape: 'line' })\n return entries\n}\n\nexport const structureLayer: ViewerLayer = {\n id: LAYER_ID,\n label: 'structure_layer',\n defaultOn: false,\n draw: drawStructure,\n legend: structureLegend,\n}\n","import type { FloorplanEngine, ResultExtensionContext } from '@adatechnology/game-floorplan'\n\nimport { constructionFor } from './construction'\nimport enLocale from './locales/en.json'\nimport ptBrLocale from './locales/pt-BR.json'\nimport type { ConstructionBuild } from './registry'\nimport type { WaterTank } from './types'\nimport { buildStructure } from './structure'\nimport { contentOf } from './utilities/content'\nimport { planContents, planUtilities } from './utilities'\nimport { addOutbuildingPaths, planOutbuildings } from './utilities/outbuildings'\nimport type { EnergyConfig } from './utilities/electrical'\nimport type { TankPlanOptions } from './water-tank'\nimport { VISOR_TANK_PILLAR_SIDE, planWaterTank } from './water-tank'\nimport { structureLayer } from './viewer-layer'\nimport type { Roof, StructureOptions, WallDetail } from './types'\n\nexport interface StructurePackOptions {\n /** Litres of the tank by template id or style id. */\n tankCapacities?: Record<string, number>\n}\n\ntype Cache = { build: ConstructionBuild; roof?: Roof }\nconst CACHE = new WeakMap<object, Cache>()\n\nconst cacheOf = (result: object): Cache => {\n const cache = CACHE.get(result)\n if (!cache) throw new Error('The construction extension did not run for this plan')\n return cache\n}\n\nfunction constructionExtension(context: ResultExtensionContext): unknown {\n const build = constructionFor({ result: context.result as never, seed: context.seed, template: context.plan.tpl as never, options: context.options })\n CACHE.set(context.result, { build })\n return build.construction\n}\n\nfunction structureExtension(context: ResultExtensionContext): unknown {\n const cache = cacheOf(context.result)\n const options: StructureOptions = { construction: cache.build.construction, extras: cache.build.extras ?? {}, tank: tankOf(context), wallDetail: (context.options.wallDetail ?? 'panels') as WallDetail, ...(context.options.wallPillars !== undefined ? { wallPillars: context.options.wallPillars as StructureOptions['wallPillars'] } : {}), ...(context.options.groundBeams !== undefined ? { groundBeams: context.options.groundBeams === true } : {}), ...(context.options.visorSections === true ? { visorSections: true } : {}) }\n const { roof, ...structure } = buildStructure(context.result, options)\n cache.roof = roof\n for (const part of structure.parts) {\n if (part.door === undefined || part.steps === undefined) continue\n const door = context.result.doors.find((d: { id: string }) => d.id === part.door)\n if (door) door.steps = part.steps\n }\n return structure\n}\n\nconst COOKING_CYLINDER = { type: 'cooking_gas_cylinder', category: 'cooking_gas_cylinder', w: 0.36, d: 0.36, h: 0.48 }\n\n/** The tank the `waterTank` extension (registered here) wrote into the result. */\nconst tankOf = (context: ResultExtensionContext): WaterTank | null => (context.result.waterTank as WaterTank | null | undefined) ?? null\n\nfunction energyOf(context: ResultExtensionContext): EnergyConfig | undefined {\n const energy = context.plan.tpl.energy\n return typeof energy === 'function' ? energy(context.options, context.plan.w, context.plan.d) : undefined\n}\n\n/**\n * Registers the structure into the engine: `result.construction`, `result.structureExtras`, `result.waterTank`, `result.structure` and `result.roof` of every plan,\n * and the structure layer of the 2D viewer. Register the content packs first.\n */\nexport function register(engine: FloorplanEngine, options: StructurePackOptions = {}): void {\n engine.registerLocale('en', enLocale)\n engine.registerLocale('pt-BR', ptBrLocale)\n engine.registerResultExtension('construction', constructionExtension)\n engine.registerResultExtension('structureExtras', (context) => cacheOf(context.result).build.extras ?? {}, { after: ['construction'] })\n engine.registerResultExtension(\n 'waterTank',\n (context) => {\n const tank: TankPlanOptions = { capacities: options.tankCapacities, custom: context.plan.tpl.tank as TankPlanOptions['custom'], location: context.plan.tpl.tankLocation as TankPlanOptions['location'], ...(context.options.visorSections === true ? { pillarSide: VISOR_TANK_PILLAR_SIDE } : {}) } // templates declare their own tank hooks\n return planWaterTank(context.result as never, context.rng, tank)\n },\n { after: ['construction'], seedKey: 'caixa' },\n )\n engine.registerResultExtension('structure', structureExtension, { after: ['construction', 'structureExtras', 'waterTank'] })\n engine.registerResultExtension('roof', (context) => cacheOf(context.result).roof ?? null, { after: ['structure'] })\n engine.registerViewerLayer(structureLayer)\n engine.registerItem(COOKING_CYLINDER)\n engine.registerResultExtension('contents', (context) => planContents({ items: context.result.items, state: context.result.state, place: context.plan.tpl.place ?? 'house', ...(typeof context.options.day === 'number' ? { day: context.options.day } : {}), ...(typeof context.options.region === 'string' ? { region: context.options.region } : {}), rngFor: (key) => engine.createRng(context.seed, key), findsFor: (query) => { const answered = engine.findsAnswer(query); return answered ?? contentOf({ container: query.container, state: query.state, rng: query.rng, footprint: query.footprint ?? 0.5 }) } }))\n engine.registerResultExtension('outbuildings', (context) => {\n const outbuildings = planOutbuildings({ plan: context.plan, items: context.result.items, catalog: engine.catalog, rngFor: (key) => engine.createRng(context.seed, key) })\n if (context.result.lot) addOutbuildingPaths(context.result.lot, outbuildings, context.result.items)\n return outbuildings\n }, { after: ['contents'] })\n engine.registerResultExtension('utilities', (context) => planUtilities({ plan: context.plan, items: context.result.items, stateItems: context.result.stateItems, tank: tankOf(context), ...(energyOf(context) ? { energy: energyOf(context) } : {}), rngFor: (key) => engine.createRng(context.seed, key) }), { after: ['outbuildings', 'waterTank'] })\n}\n","import type { DestructibleSpec, JointSpec, MaterialId, PartSpec, PileSpec, SoilProfile, StructureRole } from '@adatechnology/game-contracts'\nimport { GRAVITY, MATERIALS, SOILS, assemblyPart, partMass, pileLength, profileOf, sizeRebar } from '@adatechnology/game-destruction'\nimport type { SoilDef } from '@adatechnology/game-destruction'\nimport { sizeCapacities } from './loads'\nimport { GROUND } from './types'\nimport { resolveSlabPanels } from './slab-panels'\nimport type { SlabPanelOptions } from './slab-panels'\nimport { applySlabPanels, beamDepthFor, deepenBondBeams } from './slab-panels'\nimport { applyPanels, applyUnits } from './wall-detail'\nimport type { FoundationType, PartRole, Structure, StructurePart, WallDetail } from './types'\n\nexport interface DestructibleSpecOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest (default 0.65). */\n safety?: number\n /** After losing any other pillar or bearing wall, the most of its capacity one of them uses (default 0.97: the house holds one loss and falls with two). */\n redundancy?: number\n /** Fraction of capacity beams, slabs, roofs, stairs and partitions use at rest (default 0.45). */\n safetyOthers?: number\n /** Bearing walls close but do not carry: a frame of pillars and beams carries the building. Default: for a framed building unless the detail is `coarse`. */\n portico?: boolean\n /** How finely the walls are split (default `panels`; `coarse` is one part per wall as the Visor de casas 3D builds it). */\n wallDetail?: WallDetail\n /**\n * Cuts the concrete slabs into panels with a beam under each edge, and adds the pillars those beams and the bond beams need (design T10 §12): `true` for\n * `SLAB_PANEL_DEFAULTS`, options to change them, `false` for the slab as one piece, as the Visor de casas 3D describes it. Default `true`.\n */\n slabPanels?: boolean | Partial<SlabPanelOptions>\n /** Name of the spec (default `house`). */\n name?: string\n /** Leaves parts out (and what rests on them is dropped from the joints). */\n filter?: (part: StructurePart) => boolean\n /** `false` keeps the capacity of the material instead of sizing it from the load. */\n sized?: boolean\n /** Metres the anchored terrain slab reaches beyond the parts (default 6). */\n terrainMargin?: number\n /**\n * Declares the tension steel of the concrete beams, slabs, roofs and stairs of a construction with rebar (`structure.rebar.ratio`), so the destruction\n * world bends them (`structure.flexure` of game-destruction): `true` for the default ratios (`REBAR_RATIOS`), or ratios per role. When the spec is\n * sized the steel is sized too (`sizeRebar`: at rest at `safetyOthers`, after the loss of any pillar or bearing wall under `redundancy`). On by\n * default (a house of concrete is reinforced concrete, with the slab in panels on real beams, `slabPanels`); `false` leaves the concrete plain, as the\n * Visor de casas 3D describes it.\n */\n rebar?: boolean | Partial<Record<'beam' | 'slab' | 'roof' | 'stair', number>>\n /**\n * The ground the house stands on (`DestructibleSpec.soil` of game-contracts: a soil class id such as `clay_stiff`, or a profile of layers). With it\n * the foundations bear on the soil (game-destruction `soil`): the house settles, and tips over where the soil cannot carry it. A raft foundation\n * (`raft`, `basement`, `building`) becomes a concrete raft under the footprint (`RAFT_THICKNESS`) instead of the anchored terrain; any other\n * foundation keeps the terrain and every wall and pillar on it bears on a footing at least `footingWidth` wide. Off by default.\n */\n soil?: string | SoilProfile\n /** Foundation used with `soil` (default the construction's `foundation.type`). */\n foundation?: FoundationType\n /**\n * Deep concrete piles under the raft (a piled raft; with `soil` only). `length` omitted: each pile goes down to where it carries its share of the\n * house with the NBR 6122 safety (`pileLength`). Defaults: diameter 0.4 m, one pile per `PILE_AREA` m² of raft, at least 4, bored.\n */\n piles?: true | Partial<PileSpec>\n /** Soil classes beyond `SOILS` that `soil` names (the same ones given to the destruction world in `soil.soils`). */\n soils?: readonly SoilDef[]\n}\n\n/** Thickness of the raft of a house on the soil, metres (usual 0.20 to 0.30 m). */\nexport const RAFT_THICKNESS = 0.25\n/** Raft area per pile when the count is not given, m² (a 3 x 3 m grid). */\nexport const PILE_AREA = 9\n/** Metres the raft reaches beyond the walls. */\nconst RAFT_MARGIN = 0.15\nconst RAFT_FOUNDATIONS: ReadonlySet<FoundationType> = new Set(['raft', 'basement', 'building'])\n\n/**\n * Tension steel ratio a concrete member starts with before sizing, `As / (b d)`: beams 0.8%, slabs and roof slabs 0.25%, stairs 0.4% (inside the\n * usual ranges of NBR 6118; the minimum for C25 is 0.15%).\n */\nexport const REBAR_RATIOS: Readonly<Record<'beam' | 'slab' | 'roof' | 'stair', number>> = { beam: 0.008, slab: 0.0025, roof: 0.0025, stair: 0.004 }\n\nconst CONTRACT_ROLE: Record<PartRole, StructureRole> = { column: 'column', beam: 'beam', slab: 'slab', wall: 'wall', partition: 'partition', roof: 'roof', stair: 'stair', none: 'none' }\n\nconst TERRAIN_MARGIN = 6\nconst TERRAIN_THICKNESS = 0.5\n\nconst boxSpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n return {\n id: part.id, material: part.material, shape: { kind: 'box', size: [Math.max(0.01, u1 - u0), Math.max(0.01, part.y1 - part.y0), Math.max(0.01, v1 - v0)] },\n position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], mass: Math.max(0.1, part.mass || 1),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity },\n }\n}\n\n/** A wall piece as its assembly builds it (layers, rebar, units, breach), with the mass the structure gave it. A brick or log is the unit itself, so it keeps no units or breach. */\nconst assemblySpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n const alongU = u1 - u0 >= v1 - v0\n const spec = assemblyPart(part.assembly!, {\n id: part.id, width: alongU ? u1 - u0 : v1 - v0, height: part.y1 - part.y0, position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], ...(alongU ? {} : { rotation: [0, Math.PI / 2, 0] }),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity }, extra: { mass: Math.max(0.1, part.mass || 1) },\n })\n if (part.unit) {\n delete spec.units\n delete spec.breach\n }\n return spec\n}\n\n/** The cage of a concrete beam or pillar (four bars in a small section, an NBR 6118 minimum) and the blocks a shot or a blow knocks out of its concrete. */\nexport const MEMBER_CAGE = { spacing: 0.1, diameter: 0.008, unit: 0.1 }\nconst CAGED_ROLES: ReadonlySet<PartRole> = new Set(['beam', 'column'])\n/** Concrete cover to the bars of a member, metres (NBR 6118, class I of aggressiveness: 2.5 cm, plus the stirrup). */\nconst CAGE_COVER = 0.03\n/** Share of the bars' crushing load a bare cage keeps: without the concrete around them the bars buckle between the stirrups well before they yield. */\nconst CAGE_BUCKLING_SHARE = 0.5\nconst DEFAULT_RESIDUAL = 0.15\n\n/**\n * What the bare cage of a concrete pillar still carries once its concrete is blown off, as the share of the pillar's `capacity` (kg) the destruction\n * world keeps for it (`reinforcement.residualCapacity`): its perimeter bars (at most `spacing` apart, at least two a face) by the steel's crushing\n * strength, halved for buckling between the stirrups. A pillar under a light bond beam keeps standing on its cage; a loaded one still gives way.\n */\nexport function cageResidualCapacity(size: readonly number[], reinforcement: { material: string; spacing: number; diameter: number }, capacity: number | undefined): number {\n const [a = 0, b = 0] = [...size].sort((x, y) => x - y)\n const perSide = (w: number): number => Math.max(2, Math.floor(Math.max(0, w - 2 * CAGE_COVER) / reinforcement.spacing) + 1)\n const bars = 2 * perSide(a) + 2 * perSide(b) - 4\n const steel = MATERIALS.find((m) => m.id === reinforcement.material)?.compressive ?? 0\n const carries = bars * Math.PI * (reinforcement.diameter / 2) ** 2 * steel * CAGE_BUCKLING_SHARE\n if (!capacity || capacity <= 0 || carries <= 0) return DEFAULT_RESIDUAL\n return Math.min(1, Math.max(DEFAULT_RESIDUAL, carries / capacity))\n}\n\n/**\n * A concrete beam or pillar of a frame with rebar, in detail: its steel cage (`reinforcement`) and its concrete as blocks (`units`), so shots and blows\n * take out the concrete where they land, the bars show there and the cage is what is left when the concrete is gone.\n */\nconst caged = (spec: PartSpec, part: StructurePart, rebar: MaterialId | null): PartSpec => {\n if (!rebar || part.material !== 'concrete' || !CAGED_ROLES.has(part.role) || spec.reinforcement) return spec\n const size = spec.shape.kind === 'box' ? spec.shape.size : null\n if (!size) return spec\n const thin = Math.min(...size)\n const reinforcement = { material: rebar, spacing: MEMBER_CAGE.spacing, diameter: MEMBER_CAGE.diameter }\n return {\n ...spec,\n reinforcement: part.role === 'column' ? { ...reinforcement, residualCapacity: cageResidualCapacity(size, reinforcement, spec.structure?.capacity) } : reinforcement,\n units: { size: [MEMBER_CAGE.unit, MEMBER_CAGE.unit, thin], bond: 'stack', mortar: 'concrete' },\n }\n}\n\nconst partSpecOf = (part: StructurePart, capacity: number | undefined, detailed: boolean, rebar: MaterialId | null): PartSpec => {\n if (detailed && part.assembly) return assemblySpec(part, capacity)\n const spec = boxSpec(part, capacity)\n const out = detailed ? caged(spec, part, rebar) : spec\n // a ground beam is buried in the soil on its footing: part of the foundation, it holds what stands on it and never falls\n return part.beamKind === 'ground_beam' ? { ...out, anchored: true, structure: { role: 'foundation' } } : out\n}\n\n/**\n * The structure as a `DestructibleSpec` in the space of the house (x = u, y = height, z = v; the ground is y = 0), one box per part and a terrain slab\n * that anchors it. Capacities are sized from the loads at rest, as a designer would: a house stands whole, holds the loss of one pillar or bearing wall\n * and falls with two.\n */\nexport function toDestructibleSpec(structure: Structure, options: DestructibleSpecOptions = {}): DestructibleSpec {\n const { safety = 0.65, redundancy = 0.97, safetyOthers = 0.45 } = options\n const kept = structure.parts.filter((part) => !options.filter || options.filter(part))\n const portico = options.portico ?? (options.wallDetail !== 'coarse' && structure.framed)\n const roled = portico ? kept.map((part): StructurePart => (part.role === 'wall' ? { ...part, role: 'partition' } : part)) : kept\n const ids = new Set(roled.map((part) => part.id))\n const filtered = structure.supports.filter((support) => !options.filter || (ids.has(support.part) && (support.on === GROUND || ids.has(support.on))))\n const detail = options.wallDetail ?? 'panels'\n const resolved = resolveSlabPanels(options.slabPanels ?? true)\n const slabOptions = resolved && structure.levels.length <= resolved.maxStoreys ? resolved : undefined\n const slabbed = slabOptions ? applySlabPanels({ parts: roled, supports: filtered }, structure, slabOptions) : { parts: roled, supports: filtered }\n const walled = applyPanels(slabbed, structure, detail, slabOptions && structure.construction.frame.rebar ? (span) => beamDepthFor(span, slabOptions) : undefined)\n const panels = slabOptions && detail !== 'coarse' ? deepenBondBeams(walled, structure, slabOptions) : walled\n const sizing = { safety, redundancy, safetyOthers }\n // a ground beam is foundation, as the anchored world sees it: what stands on it is as near the ground as what stands on the soil\n const foundation = new Set(panels.parts.filter((part) => part.beamKind === 'ground_beam').map((part) => part.id))\n const onFoundation = foundation.size ? panels.supports.filter((s) => !foundation.has(s.part)).map((s) => (foundation.has(s.on) ? { ...s, on: GROUND } : s)) : panels.supports\n const sized = { ...panels, capacities: options.sized === false ? new Map<string, number>() : sizeCapacities(panels.parts.filter((part) => !foundation.has(part.id)), onFoundation, sizing) }\n const { parts, supports, capacities } = detail === 'units' ? applyUnits(sized, structure) : sized\n const specs = parts.map((part) => partSpecOf(part, capacities.get(part.id), detail !== 'coarse', structure.construction.frame.rebar))\n const margin = options.terrainMargin ?? TERRAIN_MARGIN\n const x0 = Math.min(...parts.map((part) => part.aabb[0]))\n const z0 = Math.min(...parts.map((part) => part.aabb[1]))\n const x1 = Math.max(...parts.map((part) => part.aabb[2]))\n const z1 = Math.max(...parts.map((part) => part.aabb[3]))\n if (parts.length) specs.push({ id: GROUND, material: 'concrete', shape: { kind: 'box', size: [x1 - x0 + margin, TERRAIN_THICKNESS, z1 - z0 + margin] }, position: [(x0 + x1) / 2, -TERRAIN_THICKNESS / 2, (z0 + z1) / 2], hp: 1e12, structure: { role: 'foundation' }, anchored: true, tags: ['terrain'] })\n const present = new Set([...parts.map((part) => part.id), GROUND])\n // in a frame (`portico`) the walls only close: a beam rests on the pillars, not on the wall under it, and is sized for the span between pillars (a wall that is lost does not bring the beam down)\n const infill = new Set(portico && slabOptions ? kept.filter((part) => part.role === 'wall').map((part) => part.id) : [])\n const beams = new Set(parts.filter((part) => part.role === 'beam' && (part.beamKind === 'bond_beam' || part.slab !== undefined)).map((part) => part.id))\n const joints: JointSpec[] = supports.filter((s) => present.has(s.part) && present.has(s.on)).map((s) => ({ id: `${s.part}~${s.on}`, a: s.part, b: s.on, kind: s.joint, bears: s.bears === false || (beams.has(s.part) && infill.has(s.on)) ? false : 'a_on_b' }))\n const spec: DestructibleSpec = { name: options.name ?? 'house', parts: specs, joints, tags: ['structure', 'house'] }\n return onSoil(withRebar(spec, structure, options, portico, slabOptions !== undefined), structure, options)\n}\n\nfunction withRebar(spec: DestructibleSpec, structure: Structure, options: DestructibleSpecOptions, portico: boolean, panelled: boolean): DestructibleSpec {\n const { redundancy = 0.97, safetyOthers = 0.45 } = options\n const rebar = options.rebar ?? panelled\n if (!rebar || !structure.construction.frame.rebar) return spec\n const ratios = { ...REBAR_RATIOS, ...(rebar === true ? {} : rebar) }\n for (const part of spec.parts) {\n const role = part.structure?.role\n if (!role || !(role in ratios) || part.structure!.rebar || !MATERIALS.find((m) => m.id === part.material)?.strength?.tensileMPa) continue\n part.structure = { ...part.structure!, rebar: { ratio: ratios[role as keyof typeof ratios] } }\n }\n if (options.sized === false) return spec\n return sizeRebar(spec, { safety: safetyOthers, redundancy, redundancyRoles: portico ? ['column'] : ['column', 'wall'] })\n}\n\n/** Puts the house on its soil: the raft (with its piles) in place of the terrain, or the terrain with a footing under each part on it. */\nfunction onSoil(spec: DestructibleSpec, structure: Structure, options: DestructibleSpecOptions): DestructibleSpec {\n if (options.soil === undefined) return spec\n const out: DestructibleSpec = { ...spec, soil: options.soil }\n const type = options.foundation ?? structure.construction.foundation.type\n const ground = out.parts.findIndex((p) => p.id === GROUND)\n if (ground < 0 || (!RAFT_FOUNDATIONS.has(type) && !options.piles)) return out\n const house = out.parts.filter((p) => p.id !== GROUND)\n // the raft is under what stands on the ground (walls, pillars, the ground floor), not under the eaves\n const onGround = new Set((out.joints ?? []).filter((j) => j.b === GROUND).map((j) => j.a))\n const footprint = house.filter((p) => onGround.has(p.id))\n const half = (p: PartSpec, k: number) => (p.shape.kind === 'box' ? p.shape.size[k] / 2 : p.shape.kind === 'cylinder' ? (k === 1 ? p.shape.height / 2 : p.shape.radius) : p.shape.radius)\n const under = footprint.length ? footprint : house\n const x0 = Math.min(...under.map((p) => p.position[0] - half(p, 0))) - RAFT_MARGIN, x1 = Math.max(...under.map((p) => p.position[0] + half(p, 0))) + RAFT_MARGIN\n const z0 = Math.min(...under.map((p) => p.position[2] - half(p, 2))) - RAFT_MARGIN, z1 = Math.max(...under.map((p) => p.position[2] + half(p, 2))) + RAFT_MARGIN\n const raft: PartSpec = {\n id: GROUND, material: 'concrete', shape: { kind: 'box', size: [x1 - x0, RAFT_THICKNESS, z1 - z0] }, position: [(x0 + x1) / 2, -RAFT_THICKNESS / 2, (z0 + z1) / 2],\n structure: { role: 'foundation' }, tags: ['raft'],\n }\n if (options.piles) {\n const given = options.piles === true ? {} : options.piles\n const count = given.count ?? Math.max(4, Math.ceil(((x1 - x0) * (z1 - z0)) / PILE_AREA))\n const diameter = given.diameter ?? 0.4\n const method = given.method ?? 'bored'\n const materials = new Map(MATERIALS.map((m) => [m.id, m]))\n const mass = [...house, raft].reduce((sum, p) => sum + (p.mass ?? partMass(p, materials.get(p.material)!)), 0)\n const soils = new Map(SOILS.map((d) => [d.id, d]))\n for (const d of options.soils ?? []) soils.set(d.id, d)\n const length = given.length ?? pileLength(profileOf(options.soil), { load: (mass * GRAVITY) / count, diameter, top: RAFT_THICKNESS, method, soils })\n raft.structure = { role: 'foundation', pile: { length, diameter, count, method } }\n }\n out.parts = out.parts.map((p, i) => (i === ground ? raft : p))\n return out\n}\n","import { GROUND } from './types'\nimport type { StructurePart, Support } from './types'\n\n/**\n * Load each part carries at rest, by the rules of the Visor de casas 3D (which the destruction world shares): load only goes down to supports closer to\n * the ground, shared equally, and a partition wall carries nothing, so what rests only on partitions has no load. `without` leaves one part out (as if it\n * had failed). Parts that are not structural (the tank) are not loaded.\n */\nexport function loadsAtRest(parts: readonly StructurePart[], supports: readonly Support[], without?: string): Map<string, number> {\n const byId = new Map(parts.filter((part) => part.id !== without).map((part) => [part.id, part]))\n const resting = new Map<string, string[]>()\n const carrying = new Map<string, string[]>()\n const push = (map: Map<string, string[]>, key: string, value: string): void => {\n const list = map.get(key)\n if (list) list.push(value)\n else map.set(key, [value])\n }\n for (const support of supports) {\n if (support.bears === false) continue\n if (!byId.has(support.part) || (support.on !== GROUND && !byId.has(support.on))) continue\n push(resting, support.part, support.on)\n push(carrying, support.on, support.part)\n }\n const partition = (id: string): boolean => byId.get(id)?.role === 'partition'\n const structural = (id: string): boolean => byId.has(id) && byId.get(id)!.role !== 'none'\n const distance = new Map<string, number>([[GROUND, 0]])\n const queue = [GROUND]\n for (let head = 0; head < queue.length; head++) {\n const current = queue[head]!\n if (current !== GROUND && partition(current)) continue\n for (const above of carrying.get(current) ?? []) {\n if (distance.has(above) || !structural(above)) continue\n distance.set(above, distance.get(current)! + 1)\n queue.push(above)\n }\n }\n const incoming = new Map<string, number>()\n const loads = new Map<string, number>()\n for (let head = queue.length - 1; head >= 1; head--) {\n const id = queue[head]!\n const total = (byId.get(id)!.mass || 1) + (incoming.get(id) ?? 0)\n loads.set(id, total)\n const below = (resting.get(id) ?? []).filter((other) => distance.has(other) && distance.get(other)! < distance.get(id)! && !(other !== GROUND && partition(other)))\n for (const other of below) incoming.set(other, (incoming.get(other) ?? 0) + total / below.length)\n }\n return loads\n}\n\nexport interface SizingOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest. */\n safety: number\n /** The most of its capacity a pillar or bearing wall uses after any other pillar or bearing wall is lost. */\n redundancy: number\n /** Fraction of capacity every other structural part uses at rest. */\n safetyOthers: number\n}\n\nconst isBearing = (part: StructurePart): boolean => part.role === 'column' || part.role === 'wall'\n\n/**\n * Capacity of each loaded part, as a designer would size it: a pillar or bearing wall uses `safety` of it at rest and stays under `redundancy` when\n * any other pillar or bearing wall is lost (the house holds one loss and falls with two); every other part uses `safetyOthers`.\n * `sizeStructure` of game-destruction gives the same numbers except for beams of a framed building (it holds them under `redundancy` too).\n */\nexport function sizeCapacities(parts: readonly StructurePart[], supports: readonly Support[], options: SizingOptions): Map<string, number> {\n const loads = loadsAtRest(parts, supports)\n const worst = new Map<string, number>()\n for (const part of parts.filter(isBearing)) {\n for (const [id, load] of loadsAtRest(parts, supports, part.id)) {\n const before = loads.get(id)\n if (before && load / before > (worst.get(id) ?? 1)) worst.set(id, load / before)\n }\n }\n const capacities = new Map<string, number>()\n for (const part of parts) {\n const load = loads.get(part.id)\n if (load === undefined || part.role === 'none') continue\n const factor = isBearing(part) ? Math.max(1 / options.safety, (worst.get(part.id) ?? 1) / options.redundancy) : 1 / options.safetyOthers\n capacities.set(part.id, Math.max(1, load * factor))\n }\n return capacities\n}\n","import type { Rect } from '../types'\nimport type { SlabPanelOptions } from './options'\n\n/** A line of wall seen from above: it runs along `dir` at the coordinate `at` of the other axis, over `[from, to]`. */\nexport interface WallLine {\n dir: 'u' | 'v'\n at: number\n from: number\n to: number\n}\n\n/** A beam line: it runs along `dir` at `at` over `[from, to]`. A cut along `v` at `u = at` separates the panels on its two sides. */\nexport type Cut = WallLine\n\nexport interface Layout {\n leaves: Rect[]\n cuts: Cut[]\n}\n\nconst EPS = 1e-6\n\n/** The wall boxes `[u0, v0, u1, v1]` as lines. */\nexport function linesOf(boxes: readonly Rect[]): WallLine[] {\n return boxes.map(([u0, v0, u1, v1]) => (u1 - u0 >= v1 - v0 ? { dir: 'u', at: (v0 + v1) / 2, from: u0, to: u1 } : { dir: 'v', at: (u0 + u1) / 2, from: v0, to: v1 }))\n}\n\n/** Share of `[from, to]` the walls of the line `(dir, at)` cover, with gaps up to `doorGap` counted as wall. */\nfunction coverage(lines: readonly WallLine[], dir: 'u' | 'v', at: number, from: number, to: number, options: SlabPanelOptions): number {\n const spans = lines\n .filter((line) => line.dir === dir && Math.abs(line.at - at) <= options.lineTolerance)\n .map((line): [number, number] => [Math.max(from, line.from), Math.min(to, line.to)])\n .filter(([a, b]) => b > a)\n .sort((x, y) => x[0] - y[0])\n let covered = 0\n let end = from\n let start = NaN\n for (const [a, b] of spans) {\n if (Number.isNaN(start)) {\n start = a\n end = b\n } else if (a - end <= options.doorGap) end = Math.max(end, b)\n else {\n covered += end - start\n start = a\n end = b\n }\n }\n if (!Number.isNaN(start)) covered += end - start\n return to > from ? covered / (to - from) : 0\n}\n\n/** Positions of the lines of one direction, walls closer than the tolerance merged. */\nfunction positions(lines: readonly WallLine[], dir: 'u' | 'v', tolerance: number): number[] {\n const sorted = lines.filter((line) => line.dir === dir).map((line) => line.at).sort((a, b) => a - b)\n const out: number[] = []\n let group: number[] = []\n for (const at of sorted) {\n if (group.length && at - group[group.length - 1]! > tolerance) {\n out.push(group.reduce((s, x) => s + x, 0) / group.length)\n group = []\n }\n group.push(at)\n }\n if (group.length) out.push(group.reduce((s, x) => s + x, 0) / group.length)\n return out\n}\n\ninterface Candidate {\n dir: 'u' | 'v'\n at: number\n coverage: number\n /** 0 at the middle of the rectangle, 1 at its edge. */\n skew: number\n}\n\nconst round = (x: number): number => Math.round(x * 100) / 100\n\n/** The cut of `rect`: along `dir` at `at`, or none when it is already a panel. */\nfunction choose(rect: Rect, lines: readonly WallLine[], options: SlabPanelOptions): { dir: 'u' | 'v'; at: number } | null {\n const [u0, v0, u1, v1] = rect\n const width = u1 - u0\n const depth = v1 - v0\n const tooWide = width > options.maxSpan + EPS\n const tooDeep = depth > options.maxSpan + EPS\n const candidates: Candidate[] = []\n for (const at of positions(lines, 'v', options.lineTolerance)) {\n if (at < u0 + options.minPanel - EPS || at > u1 - options.minPanel + EPS) continue\n candidates.push({ dir: 'v', at, coverage: coverage(lines, 'v', at, v0, v1, options), skew: Math.abs(at - (u0 + u1) / 2) / (width / 2) })\n }\n for (const at of positions(lines, 'u', options.lineTolerance)) {\n if (at < v0 + options.minPanel - EPS || at > v1 - options.minPanel + EPS) continue\n candidates.push({ dir: 'u', at, coverage: coverage(lines, 'u', at, u0, u1, options), skew: Math.abs(at - (v0 + v1) / 2) / (depth / 2) })\n }\n const boundary = candidates.filter((c) => c.coverage >= options.lineCoverage)\n if (tooWide || tooDeep) {\n // cut across the longer side when both are too long\n const across: 'u' | 'v' = tooWide && (!tooDeep || width >= depth) ? 'v' : 'u'\n const pool = boundary.filter((c) => c.dir === across)\n if (pool.length) {\n const best = pool.reduce((a, b) => (b.skew - 0.25 * b.coverage < a.skew - 0.25 * a.coverage ? b : a))\n return { dir: best.dir, at: round(best.at) }\n }\n const length = across === 'v' ? width : depth\n const origin = across === 'v' ? u0 : v0\n return { dir: across, at: round(origin + length / Math.ceil(length / options.maxSpan - EPS)) }\n }\n if (!boundary.length) return null\n const best = boundary.reduce((a, b) => (b.coverage - 0.25 * b.skew > a.coverage - 0.25 * a.skew ? b : a))\n return { dir: best.dir, at: round(best.at) }\n}\n\n/** Cuts `rect` along the walls and into pieces no wider than `maxSpan` (the panels of a slab) and returns them with the cut lines. */\nexport function layoutPanels(rect: Rect, lines: readonly WallLine[], options: SlabPanelOptions): Layout {\n const leaves: Rect[] = []\n const cuts: Cut[] = []\n const walk = (r: Rect, depth: number): void => {\n const cut = depth < 16 ? choose(r, lines, options) : null\n if (!cut) {\n leaves.push(r)\n return\n }\n if (cut.dir === 'v') {\n cuts.push({ dir: 'v', at: cut.at, from: r[1], to: r[3] })\n walk([r[0], r[1], cut.at, r[3]], depth + 1)\n walk([cut.at, r[1], r[2], r[3]], depth + 1)\n } else {\n cuts.push({ dir: 'u', at: cut.at, from: r[0], to: r[2] })\n walk([r[0], r[1], r[2], cut.at], depth + 1)\n walk([r[0], cut.at, r[2], r[3]], depth + 1)\n }\n }\n walk(rect, 0)\n return { leaves, cuts }\n}\n\nexport const areaOf = (rect: Rect): number => Math.max(0, rect[2] - rect[0]) * Math.max(0, rect[3] - rect[1])\n\nexport function overlapArea(a: Rect, b: Rect): number {\n return Math.max(0, Math.min(a[2], b[2]) - Math.max(a[0], b[0])) * Math.max(0, Math.min(a[3], b[3]) - Math.max(a[1], b[1]))\n}\n\n/** Share of `rect` inside the union of `footprint` (the rectangles of the footprint do not overlap). */\nexport function shareInside(rect: Rect, footprint: readonly Rect[]): number {\n const area = areaOf(rect)\n return area > 0 ? Math.min(1, footprint.reduce((sum, other) => sum + overlapArea(rect, other), 0) / area) : 0\n}\n\n/** The stretches of the cut that border at least one of `panels` (the beams under the kept panels), as `[from, to]` runs. */\nexport function runsOf(cut: Cut, panels: readonly Rect[], tolerance = 0.02): [number, number][] {\n const spans: [number, number][] = []\n for (const [u0, v0, u1, v1] of panels) {\n if (cut.dir === 'v') {\n if (Math.abs(u0 - cut.at) < tolerance || Math.abs(u1 - cut.at) < tolerance) spans.push([Math.max(v0, cut.from), Math.min(v1, cut.to)])\n } else if (Math.abs(v0 - cut.at) < tolerance || Math.abs(v1 - cut.at) < tolerance) spans.push([Math.max(u0, cut.from), Math.min(u1, cut.to)])\n }\n const sorted = spans.filter(([a, b]) => b - a > tolerance).sort((x, y) => x[0] - y[0])\n const runs: [number, number][] = []\n for (const [a, b] of sorted) {\n const last = runs[runs.length - 1]\n if (last && a <= last[1] + tolerance) last[1] = Math.max(last[1], b)\n else runs.push([a, b])\n }\n return runs\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { densityOf } from '../density'\nimport { round2, touches } from '../geometry'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\nimport { GROUND } from '../types'\nimport type { Rect, Structure, StructurePart, Support } from '../types'\nimport type { PartsAndSupports } from '../wall-detail/apply'\nimport { layoutPanels, linesOf, runsOf, shareInside } from './layout'\nimport type { Cut } from './layout'\nimport type { SlabPanelOptions } from './options'\n\nconst SLAB_ID = /^slab_(\\d+|top.*|ceiling|base)$/\nconst PLAN_TOLERANCE = 0.05\n/** Metres a support may end below the bottom of what it holds and still hold it (walls end under the bond beam, pillars at the slab). */\nconst BELOW = 0.35\nconst UP = 0.15\n/** A beam needs a support this close to each of its ends. */\nconst END_REACH = 0.35\nconst EPS = 1e-6\n\ntype Interval = [number, number]\n\nconst ceilTo = (value: number, step: number): number => Math.ceil(value / step - 1e-9) * step\nconst isConcreteSlab = (part: StructurePart, material: string): boolean => part.role === 'slab' && part.material === material && SLAB_ID.test(part.id)\nconst isBondBeam = (part: StructurePart, material: string): boolean => part.role === 'beam' && part.beamKind === 'bond_beam' && part.material === material\n\nfunction merged(intervals: readonly Interval[]): Interval[] {\n const out: Interval[] = []\n for (const [a, b] of intervals.slice().sort((x, y) => x[0] - y[0])) {\n const last = out[out.length - 1]\n if (last && a <= last[1] + EPS) last[1] = Math.max(last[1], b)\n else out.push([a, b])\n }\n return out\n}\n\n/**\n * The span the destruction world measures for a beam from `0` to `length` held at `supports`: twice the farthest any point is from its nearest support\n * (two supports `g` apart give `g`; a beam hanging `e` past its last support gives `2e`). `at` is where a new support helps the most.\n */\nexport function beamSpan(length: number, supports: readonly Interval[]): { span: number; at: number; lo: number; hi: number } {\n const held = merged(supports.map(([a, b]): Interval => [Math.max(0, a), Math.min(length, b)]).filter(([a, b]) => b > a))\n if (!held.length) return { span: Infinity, at: length / 2, lo: 0, hi: length }\n let span = 0\n let at = length / 2\n let lo = 0\n let hi = length\n const lead = held[0]![0]\n if (2 * lead > span) {\n span = 2 * lead\n at = 0\n lo = 0\n hi = lead\n }\n const trail = length - held[held.length - 1]![1]\n if (2 * trail > span) {\n span = 2 * trail\n at = length\n lo = length - trail\n hi = length\n }\n for (let k = 1; k < held.length; k++) {\n const gap = held[k]![0] - held[k - 1]![1]\n if (gap > span) {\n span = gap\n at = (held[k]![0] + held[k - 1]![1]) / 2\n lo = held[k - 1]![1]\n hi = held[k]![0]\n }\n }\n return { span, at, lo, hi }\n}\n\n/** A beam as a line in the plan: it runs along `dir` at the coordinate `at` of the other axis, from `from` to `to`. */\ninterface Line {\n dir: 'u' | 'v'\n at: number\n from: number\n to: number\n}\n\nconst lineOf = (aabb: Rect, dir: 'u' | 'v'): Line => (dir === 'u' ? { dir, at: (aabb[1] + aabb[3]) / 2, from: aabb[0], to: aabb[2] } : { dir, at: (aabb[0] + aabb[2]) / 2, from: aabb[1], to: aabb[3] })\nconst pointOf = (line: Line, s: number): [number, number] => (line.dir === 'u' ? [line.from + s, line.at] : [line.at, line.from + s])\n\n/** Where `box` holds a beam of `line` and `width`: the stretch of the beam (from its start), or undefined when it does not touch. */\nfunction holds(line: Line, width: number, box: Rect): Interval | undefined {\n const [across0, across1, along0, along1] = line.dir === 'u' ? [box[1], box[3], box[0], box[2]] : [box[0], box[2], box[1], box[3]]\n if (across0 >= line.at + width / 2 + PLAN_TOLERANCE || across1 <= line.at - width / 2 - PLAN_TOLERANCE) return undefined\n const a = Math.max(along0 - PLAN_TOLERANCE, line.from)\n const b = Math.min(along1 + PLAN_TOLERANCE, line.to)\n return b > a ? [a - line.from, b - line.from] : undefined\n}\n\n/** What can hold a beam from below: a pillar or a bearing wall, with how many steps it is from the ground (the destruction world only rests a part on the nearest-to-ground of its supports). */\ninterface Prop {\n box: Rect\n dist: number\n part?: StructurePart\n}\n\ninterface Spot {\n u: number\n v: number\n}\n\ninterface Context {\n structure: Structure\n options: SlabPanelOptions\n beamMaterial: string\n pillarMaterial: string\n joint: JointKind\n wallThickness: number\n parts: StructurePart[]\n supports: Support[]\n panelsOf: Map<string, StructurePart[]>\n pillars: number\n groundBase: string\n /** The distances of the last call to `distancesOf`, kept while no part or support is added (a tower asks for them once per bond beam and per slab). */\n distCache?: { parts: number; supports: number; map: Map<string, number> }\n}\n\nconst boxOfSpot = (spot: Spot, side: number): Rect => [spot.u - side / 2, spot.v - side / 2, spot.u + side / 2, spot.v + side / 2]\n\n/** Steps from the ground of every part, the way the destruction world counts them: through the supports that carry, and not through a partition. */\nfunction distancesOf(context: Context): Map<string, number> {\n const cache = context.distCache\n if (cache && cache.parts === context.parts.length && cache.supports === context.supports.length) return cache.map\n const map = distances(context.parts, context.supports)\n context.distCache = { parts: context.parts.length, supports: context.supports.length, map }\n return map\n}\n\nfunction distances(parts: readonly StructurePart[], supports: readonly Support[]): Map<string, number> {\n const byId = new Map(parts.map((p) => [p.id, p]))\n const carrying = new Map<string, string[]>()\n for (const s of supports) {\n if (s.bears === false || !byId.has(s.part) || (s.on !== GROUND && !byId.has(s.on))) continue\n const list = carrying.get(s.on)\n if (list) list.push(s.part)\n else carrying.set(s.on, [s.part])\n }\n const dist = new Map<string, number>([[GROUND, 0]])\n const queue = [GROUND]\n for (let head = 0; head < queue.length; head++) {\n const current = queue[head]!\n if (current !== GROUND && byId.get(current)?.role === 'partition') continue\n for (const above of carrying.get(current) ?? []) {\n if (dist.has(above) || byId.get(above)?.role === 'none') continue\n dist.set(above, dist.get(current)! + 1)\n queue.push(above)\n }\n }\n return dist\n}\n\n/** Pillars and bearing walls that end where `y0` is (under a beam or a bond beam at that height). */\nfunction propsUnder(context: Context, dist: ReadonlyMap<string, number>, y0: number, y1: number, floor: number): Prop[] {\n return context.parts\n .filter((q) => (q.role === 'column' || q.role === 'wall') && q.floor === floor && dist.has(q.id) && q.y0 < y0 - PLAN_TOLERANCE && q.y1 >= y0 - BELOW && q.y1 <= y1 + UP)\n .map((q) => ({ box: q.aabb, dist: dist.get(q.id)!, part: q }))\n}\n\n/** What holds the beam: of the props that touch it only the ones nearest to the ground do (the world rests a part on those). */\nfunction heldBy(line: Line, width: number, props: readonly Prop[]): { intervals: Interval[]; used: Prop[] } {\n const touching = props.map((prop) => ({ prop, interval: holds(line, width, prop.box) })).filter((x): x is { prop: Prop; interval: Interval } => x.interval !== undefined)\n if (!touching.length) return { intervals: [], used: [] }\n const nearest = Math.min(...touching.map((x) => x.prop.dist))\n const used = touching.filter((x) => x.prop.dist === nearest)\n return { intervals: used.map((x) => x.interval), used: used.map((x) => x.prop) }\n}\n\n/**\n * Finds where a beam (or bond beam) needs pillars so that it never goes more than `maxSpan` without a support (and, for a beam, so that each end is\n * held). `spots` collects the pillars, which then hold the beams after it; `dist` is how far from the ground a pillar is.\n */\nfunction pillarsFor(\n line: Line, width: number, props: readonly Prop[], spots: Array<Spot & { dist: number }>, dist: number, options: SlabPanelOptions, ends: boolean, ground: readonly Rect[] = [],\n): Interval[] {\n const length = line.to - line.from\n const side = options.columnSide\n const all = (): Prop[] => [...props, ...spots.map((spot) => ({ box: boxOfSpot(spot, side), dist: spot.dist }))]\n // a pillar of a storey above the first stands on a beam or a bond beam of the slab under it, not on the middle of a panel\n const allowed = merged(ground.map((box) => holds(line, 0.02, box)).filter((x): x is Interval => x !== undefined))\n const place = (at: number, lo: number, hi: number): number => {\n if (!allowed.length) return at\n let best: number | undefined\n let gap = Infinity\n for (const [a, b] of allowed) {\n const from = Math.max(a + side / 2, lo + 0.2)\n const to = Math.min(b - side / 2, hi - 0.2)\n if (to < from) continue\n const clamped = Math.min(to, Math.max(from, at))\n if (Math.abs(clamped - at) < gap) {\n gap = Math.abs(clamped - at)\n best = clamped\n }\n }\n return best ?? at\n }\n let held = heldBy(line, width, all()).intervals\n for (let guard = 0; guard < 64; guard++) {\n let at: number | undefined\n let lo = 0\n let hi = length\n if (ends && !held.some(([a]) => a <= END_REACH)) at = 0\n else if (ends && !held.some(([, b]) => b >= length - END_REACH)) at = length\n else {\n const found = beamSpan(length, held)\n if (found.span <= options.maxSpan + 1e-3) break\n at = found.at\n lo = found.lo\n hi = found.hi\n }\n const [u, v] = pointOf(line, at === 0 || at === length ? at : place(at, lo, hi))\n const spot = { u: round2(u), v: round2(v), dist }\n if (spots.some((other) => Math.hypot(other.u - spot.u, other.v - spot.v) < 0.15)) break\n spots.push(spot)\n held = heldBy(line, width, all()).intervals\n }\n return held\n}\n\nconst make = (draft: Omit<StructurePart, 'mass'>): StructurePart => {\n const [u0, v0, u1, v1] = draft.aabb\n const volume = Math.max(0, (u1 - u0) * (v1 - v0) * (draft.y1 - draft.y0))\n return { ...draft, aabb: draft.aabb.map(round2) as Rect, y0: round2(draft.y0), y1: round2(draft.y1), mass: Math.max(1, Math.round(volume * densityOf(draft.material))) }\n}\n\nconst rest = (context: Context, on: StructurePart | string, below: StructurePart, joint: JointKind = context.joint): void => {\n context.supports.push({ part: below.id, on: typeof on === 'string' ? on : on.id, joint })\n}\n\nconst distance = (a: Rect, b: Rect): number => Math.hypot(Math.max(a[0] - b[2], b[0] - a[2], 0), Math.max(a[1] - b[3], b[1] - a[3], 0))\n\n/** The panels of `slab` that `box` touches (the nearest one when none does). */\nfunction panelsUnder(context: Context, slab: string, box: Rect): StructurePart[] {\n const panels = context.panelsOf.get(slab) ?? []\n const touching = panels.filter((panel) => touches(panel.aabb, box, PLAN_TOLERANCE))\n return touching.length ? touching : panels.slice().sort((a, b) => distance(a.aabb, box) - distance(b.aabb, box)).slice(0, 1)\n}\n\n/** The pillar at `spot` from `bottom` to `top`, on the ground or on the slab of the storey below. */\nfunction addPillar(context: Context, spot: Spot, bottom: number, top: number, floor: number, below: string | undefined, slab: string): StructurePart {\n const pillar = make({\n id: `pillar_${floor}_${context.pillars++}`, role: 'column', material: context.pillarMaterial, floor, slab, aabb: boxOfSpot(spot, context.options.columnSide), y0: bottom, y1: top,\n })\n context.parts.push(pillar)\n if (below && context.panelsOf.has(below)) for (const panel of panelsUnder(context, below, pillar.aabb)) rest(context, panel, pillar, 'rebar')\n else rest(context, context.groundBase, pillar, 'rebar')\n return pillar\n}\n\n/** The storey under a slab: its floor, the slab it stands on (none: the ground) and the height its pillars start at. */\nfunction storeyUnder(context: Context, slab: StructurePart): { floor: number; below: string | undefined; bottom: number } {\n const levels = context.structure.levels\n const match = /^slab_(\\d+)$/.exec(slab.id)\n const floor = match && Number(match[1]) >= 1 ? Number(match[1]) - 1 : slab.id === 'slab_base' ? 0 : slab.floor\n return { floor, below: slab.id === 'slab_base' || floor < 1 ? undefined : `slab_${floor}`, bottom: slab.id === 'slab_base' ? 0 : (levels[floor] ?? 0) }\n}\n\n/** Steps from the ground of a pillar that stands under `slab`. */\nfunction pillarDist(context: Context, dist: ReadonlyMap<string, number>, storey: { below: string | undefined }): number {\n if (storey.below && context.panelsOf.has(storey.below)) return Math.min(...context.panelsOf.get(storey.below)!.map((p) => dist.get(p.id) ?? 99)) + 1\n return (dist.get(context.groundBase) ?? 0) + 1\n}\n\n/** Where a pillar can stand on the slab `below`: on its beams and on the bond beams at its level. */\nfunction groundOf(context: Context, below: string): Rect[] {\n const panels = context.panelsOf.get(below) ?? []\n const level = panels[0]?.y1\n if (level === undefined) return []\n return context.parts.filter((q) => q.role === 'beam' && (q.slab === below || (q.beamKind === 'bond_beam' && Math.abs(q.y1 - level) < 0.4))).map((q) => q.aabb)\n}\n\n/** Thickness of the panels of a slab: the shortest side of the widest of them over `thicknessRatio`, not under the minimum of the use. */\nfunction thicknessOf(leaves: readonly Rect[], roof: boolean, options: SlabPanelOptions): number {\n const shortest = Math.max(...leaves.map((leaf) => Math.min(leaf[2] - leaf[0], leaf[3] - leaf[1])))\n return Math.max(roof ? options.roofMinThickness : options.floorMinThickness, ceilTo(shortest / options.thicknessRatio, 0.01))\n}\n\nconst restThickness = (slab: StructurePart, thickness: number, roof: boolean): void => {\n if (roof) slab.y1 = round2(slab.y0 + thickness)\n else slab.y0 = round2(slab.y1 - thickness)\n slab.mass = Math.max(1, Math.round((slab.aabb[2] - slab.aabb[0]) * (slab.aabb[3] - slab.aabb[1]) * (slab.y1 - slab.y0) * densityOf(slab.material)))\n}\n\n/** Cuts one slab into panels, adds the beams under their edges and the pillars those need; re-points what rested on the slab. */\nfunction cutSlab(context: Context, slab: StructurePart, wallBoxes: readonly Rect[]): void {\n const { options } = context\n const roof = slab.cover === true\n const layout = layoutPanels(slab.aabb, linesOf(wallBoxes), options)\n const footprint = slab.footprint ?? [slab.aabb]\n const kept = layout.leaves.filter((leaf) => shareInside(leaf, footprint) >= options.footprintShare)\n const leaves = kept.length ? kept : [slab.aabb]\n const thickness = thicknessOf(leaves, roof, options)\n if (leaves.length === 1 && layout.cuts.length === 0) {\n restThickness(slab, thickness, roof)\n context.panelsOf.set(slab.id, [slab])\n return\n }\n const own = context.supports.filter((s) => s.part === slab.id && s.bears !== false)\n const resting = context.supports.filter((s) => s.on === slab.id)\n context.supports = context.supports.filter((s) => s.part !== slab.id && s.on !== slab.id)\n const [y0, y1] = roof ? [slab.y0, slab.y0 + thickness] : [slab.y1 - thickness, slab.y1]\n const panels = leaves.map((leaf, k) =>\n make({\n id: `${slab.id}_p${k}`, role: 'slab', material: slab.material, aabb: leaf, y0, y1, floor: slab.floor, ...(slab.cover ? { cover: true } : {}), slab: slab.id,\n ...(slab.footprint ? { footprint: slab.footprint } : {}),\n }),\n )\n context.parts.splice(context.parts.indexOf(slab), 1, ...panels)\n context.panelsOf.set(slab.id, panels)\n\n // the beams: under the edges of the panels, on pillars and bearing walls; a bond beam that already runs there is the beam\n const top = roof ? slab.y0 : y0\n const dist = distancesOf(context)\n const storey = storeyUnder(context, slab)\n const props = propsUnder(context, dist, top, slab.y1, storey.floor)\n const near = props.length ? Math.min(...props.map((p) => p.dist)) : pillarDist(context, dist, storey)\n const spots: Array<Spot & { dist: number }> = []\n const bonds = context.parts.filter((q) => q.role === 'beam' && q.beamKind === 'bond_beam' && q.y1 >= top - BELOW && q.y0 < slab.y1)\n const ground = storey.below ? groundOf(context, storey.below) : []\n const covered = (line: Line): boolean => {\n const width = context.wallThickness\n const spans = merged(bonds.map((bond) => holds(line, width + 0.5, bond.aabb)).filter((x): x is Interval => x !== undefined))\n return spans.reduce((sum, [a, b]) => sum + Math.max(0, Math.min(b, line.to - line.from) - Math.max(a, 0)), 0) >= (line.to - line.from) * 0.9\n }\n const [su0, sv0, su1, sv1] = slab.aabb\n const borders: Cut[] = [\n { dir: 'u', at: sv0, from: su0, to: su1 }, { dir: 'u', at: sv1, from: su0, to: su1 }, { dir: 'v', at: su0, from: sv0, to: sv1 }, { dir: 'v', at: su1, from: sv0, to: sv1 },\n ]\n const beams: Array<{ part: StructurePart; line: Line; width: number }> = []\n let count = 0\n for (const cut of [...layout.cuts, ...borders]) {\n for (const [from, to] of runsOf(cut, leaves)) {\n const line: Line = { dir: cut.dir === 'v' ? 'v' : 'u', at: cut.at, from, to }\n if (covered(line)) continue\n const held = pillarsFor(line, context.wallThickness, props, spots, near, options, true, ground)\n const span = Math.min(beamSpan(to - from, held).span, options.maxSpan)\n const depth = beamDepthFor(span, options)\n const width = Math.max(context.wallThickness, round2(depth / options.beamWidthRatio))\n const aabb: Rect = line.dir === 'u' ? [from, cut.at - width / 2, to, cut.at + width / 2] : [cut.at - width / 2, from, cut.at + width / 2, to]\n beams.push({ part: make({ id: `${slab.id}_b${count++}`, role: 'beam', material: context.beamMaterial, aabb, y0: top - depth, y1: top, floor: slab.floor, slab: slab.id }), line, width })\n }\n }\n const pillars = spots.map((spot) => addPillar(context, spot, storey.bottom, top, storey.floor, storey.below, slab.id))\n context.parts.splice(context.parts.indexOf(panels[panels.length - 1]!) + 1, 0, ...beams.map((b) => b.part))\n const all: Prop[] = [...props, ...pillars.map((p, k) => ({ box: p.aabb, dist: spots[k]!.dist, part: p }))]\n for (const { part: beam, line, width } of beams) for (const used of heldBy(line, width, all).used) rest(context, used.part!, beam)\n\n // the panels rest on the beams of their edges and on the bond beams (the walls and pillars under them hold the beams)\n for (const panel of panels) {\n for (const { part: beam } of beams) if (touches(panel.aabb, beam.aabb, PLAN_TOLERANCE)) rest(context, beam, panel)\n for (const bond of bonds) if (touches(panel.aabb, bond.aabb, PLAN_TOLERANCE)) rest(context, bond, panel, own.find((s) => s.on === bond.id)?.joint ?? context.joint)\n }\n for (const panel of panels.filter((p) => !context.supports.some((s) => s.part === p.id))) {\n const nearest = [...beams.map((b) => b.part), ...bonds].sort((a, b) => distance(a.aabb, panel.aabb) - distance(b.aabb, panel.aabb))[0]\n if (nearest) rest(context, nearest, panel)\n }\n // what rested on the slab rests on the panels it touches\n for (const support of resting) {\n const upper = context.parts.find((q) => q.id === support.part)\n if (!upper) continue\n for (const panel of panelsUnder(context, slab.id, upper.aabb)) context.supports.push({ ...support, on: panel.id })\n }\n}\n\n/** Depth of a beam over `span` metres: `span / beamDepthRatio` up to a multiple of `beamStep`, not under `minimum`. */\nexport const beamDepthFor = (span: number, options: SlabPanelOptions, minimum = options.beamMinDepth): number => Math.max(minimum, ceilTo(span / options.beamDepthRatio, options.beamStep))\n\n/**\n * After the walls are cut at their windows: a bond beam over a wide opening spans it (the destruction world rests it on the piers, the nearest of its supports\n * to the ground), so it gets the depth and the width of a beam of that span. Returns copies of the parts it changes.\n */\nexport function deepenBondBeams(input: PartsAndSupports, structure: Structure, options: SlabPanelOptions): PartsAndSupports {\n const frame = structure.construction.frame\n if (!frame.rebar) return input\n const dist = distances(input.parts, input.supports)\n const context = { parts: input.parts } as Context\n let changed = false\n const parts = input.parts.map((part) => {\n if (!isBondBeam(part, frame.beams) || !dist.has(part.id)) return part\n const dir: 'u' | 'v' = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1] ? 'u' : 'v'\n const line = lineOf(part.aabb, dir)\n const width = dir === 'u' ? part.aabb[3] - part.aabb[1] : part.aabb[2] - part.aabb[0]\n const span = beamSpan(line.to - line.from, heldBy(line, width, propsUnder(context, dist, part.y0, part.y1, part.floor)).intervals).span\n if (!(span > 1.5) || !Number.isFinite(span)) return part\n const depth = Math.max(part.y1 - part.y0, beamDepthFor(span, options))\n const wide = Math.max(width, round2(depth / options.beamWidthRatio))\n const grow = (wide - width) / 2\n changed = true\n const aabb: Rect = dir === 'u' ? [part.aabb[0], part.aabb[1] - grow, part.aabb[2], part.aabb[3] + grow] : [part.aabb[0] - grow, part.aabb[1], part.aabb[2] + grow, part.aabb[3]]\n return make({ ...part, aabb, y0: part.y1 - depth })\n })\n return changed ? { parts, supports: input.supports } : input\n}\n\n/** Adds the pillars a concrete bond beam needs under it (a frame whose walls only close has none between its corners) and deepens it over a wide span. */\nfunction supportBondBeam(context: Context, plate: StructurePart): void {\n const { options } = context\n const dir: 'u' | 'v' = plate.aabb[2] - plate.aabb[0] >= plate.aabb[3] - plate.aabb[1] ? 'u' : 'v'\n const line = lineOf(plate.aabb, dir)\n const width = dir === 'u' ? plate.aabb[3] - plate.aabb[1] : plate.aabb[2] - plate.aabb[0]\n const dist = distancesOf(context)\n const floor = plate.floor\n const props = propsUnder(context, dist, plate.y0, plate.y1, floor)\n const storey = { floor, below: floor >= 1 ? `slab_${floor}` : undefined, bottom: context.structure.levels[floor] ?? 0 }\n const spots: Array<Spot & { dist: number }> = []\n const near = props.length ? Math.min(...props.map((p) => p.dist)) : pillarDist(context, dist, storey)\n const held = pillarsFor(line, width, props, spots, near, options, false)\n const span = beamSpan(line.to - line.from, held).span\n if (span > 1.5) {\n const depth = Math.max(plate.y1 - plate.y0, beamDepthFor(Math.min(span, options.maxSpan), options))\n plate.y0 = round2(plate.y1 - depth)\n plate.mass = Math.max(1, Math.round((plate.aabb[2] - plate.aabb[0]) * (plate.aabb[3] - plate.aabb[1]) * depth * densityOf(plate.material)))\n }\n for (const spot of spots) {\n const pillar = addPillar(context, spot, storey.bottom, plate.y0 + PLAN_TOLERANCE, floor, storey.below, plate.id)\n rest(context, pillar, plate, 'rebar')\n }\n}\n\n/**\n * The slabs of concrete cut into panels with beams (`SlabPanelOptions`): see `T10-estrutura-real.md` §12. `input` is the structure as\n * `toDestructibleSpec` has it (walls with their roles), and the result has the panels, the beams, the pillars they need and the supports re-pointed.\n */\nexport function applySlabPanels(input: PartsAndSupports, structure: Structure, options: SlabPanelOptions): PartsAndSupports {\n const frame = structure.construction.frame\n const system = CONSTRUCTION_SYSTEMS.get(structure.construction.system)\n if (!frame.rebar || !system || system.timber || structure.levels.length > options.maxStoreys) return input\n const parts = input.parts.map((p) => ({ ...p }))\n const slabs = parts.filter((p) => isConcreteSlab(p, frame.slabs))\n const bonds = parts.filter((p) => isBondBeam(p, frame.beams))\n if (!slabs.length && !bonds.length) return input\n const firstColumn = input.supports.find((s) => /^(column_0_|building_column_)/.test(s.part) && !/^(column_0_|building_column_)/.test(s.on))\n const context: Context = {\n structure, options, beamMaterial: frame.beams, pillarMaterial: frame.pillars, joint: system.joints.slab, wallThickness: (structure.construction.walls.thickness as number | undefined) ?? 0.15,\n parts, supports: input.supports.slice(), panelsOf: new Map(), pillars: 0, groundBase: firstColumn?.on ?? GROUND,\n }\n const walls = parts.filter((p) => /^wall_/.test(p.id) && (p.role === 'wall' || p.role === 'partition'))\n const jobs = [...bonds.map((part) => ({ part, bond: true })), ...slabs.map((part) => ({ part, bond: false }))].sort((a, b) => a.part.y0 - b.part.y0 || Number(b.bond) - Number(a.bond))\n for (const job of jobs) {\n if (job.bond) {\n supportBondBeam(context, job.part)\n continue\n }\n const slab = job.part\n const boxes = walls.filter((w) => (w.y0 >= slab.y1 - 0.1 && w.y0 <= slab.y1 + 0.4) || (w.y1 >= slab.y0 - 0.4 && w.y1 <= slab.y0 + 0.1 && w.y0 < slab.y0)).map((w) => w.aabb)\n cutSlab(context, slab, boxes)\n }\n if (structure.construction.foundation.type === 'building') anchorBalconies(context)\n return { parts: context.parts, supports: context.supports }\n}\n\n/**\n * A unit of a building stands high above the ground, and the balcony of its plan comes with a pillar of its own that starts at the ground floor: the\n * pillar would be five storeys of a single column under one corner. The balcony is a cantilever of the unit's slab (`slab_base`) and the pillar goes.\n */\nfunction anchorBalconies(context: Context): void {\n const base = context.panelsOf.get('slab_base')\n if (!base) return\n const decks = context.parts.filter((p) => p.role === 'slab' && /^slab_\\d+_/.test(p.id) && context.supports.some((s) => s.part === p.id && /^balcony_column_/.test(s.on)))\n for (const deck of decks) {\n const pillars = new Set(context.supports.filter((s) => s.part === deck.id && /^balcony_column_/.test(s.on)).map((s) => s.on))\n context.supports = context.supports.filter((s) => s.part !== deck.id && !pillars.has(s.part) && !pillars.has(s.on))\n context.parts = context.parts.filter((p) => !pillars.has(p.id))\n for (const panel of panelsUnder(context, 'slab_base', deck.aabb)) rest(context, panel, deck)\n }\n}\n\n/**\n * The panels `toDestructibleSpec` makes of the slabs of a structure (named as it names them), for a renderer that draws the floor of each room apart:\n * `panels` (each with `slab`, the id of the slab it was cut from), `replaced` (those slabs, which the spec no longer has) and the `supports` that touch the panels.\n */\nexport function slabPanelView(structure: Structure, options: SlabPanelOptions): { panels: StructurePart[]; replaced: string[]; supports: Support[] } {\n const out = applySlabPanels({ parts: structure.parts, supports: structure.supports }, structure, options)\n const panels = out.parts.filter((p) => p.slab !== undefined && p.role === 'slab')\n const ids = new Set(panels.map((p) => p.id))\n return { panels, replaced: [...new Set(panels.map((p) => p.slab!))], supports: out.supports.filter((s) => ids.has(s.part) || ids.has(s.on)) }\n}\n\n/** The panels of `slabPanelView`, alone. */\nexport const slabPanelsOf = (structure: Structure, options: SlabPanelOptions): StructurePart[] => slabPanelView(structure, options).panels\n","/**\n * How a concrete slab of a house is cut into panels with beams under their edges, and where pillars are added so that every beam spans a\n * reasonable distance (design T10-estrutura-real.md §12). Every number is a choice of the design and can be changed per call\n * (`toDestructibleSpec({ slabPanels: { maxSpan: 4 } })`).\n */\nexport interface SlabPanelOptions {\n /** Longest side of a panel and longest stretch of a beam or bond beam without a support, metres (default 5). */\n maxSpan: number\n /** A cut never leaves a piece narrower than this, metres (default 1.5). */\n minPanel: number\n /** Share of a line of the panel a wall must cover (doors included) for the line to be a room boundary the panel is cut along (default 0.6). */\n lineCoverage: number\n /** A gap in a line of walls up to this wide is a door and counts as wall, metres (default 1.3). */\n doorGap: number\n /** Walls whose lines are this close are one line, metres (default 0.2). */\n lineTolerance: number\n /** A panel with less than this share of its area inside the footprint of the slab is left out (default 0.5). */\n footprintShare: number\n /** Thickness of a panel is its short side over this (default 40: `h = L/40`). */\n thicknessRatio: number\n /** Thinnest floor slab, metres (default 0.10). */\n floorMinThickness: number\n /** Thinnest roof slab, metres (default 0.08). */\n roofMinThickness: number\n /** Depth of a beam is its span over this (default 10: `h = L/10`, a simply supported beam of NBR 6118, and deep enough for the frame to carry the loss of one pillar; continuous beams are L/12). */\n beamDepthRatio: number\n /** Shallowest beam, metres (default 0.25). */\n beamMinDepth: number\n /** Depth of beams and bond beams is rounded up to a multiple of this, metres (default 0.05). */\n beamStep: number\n /** Width of a beam is the thickness of the wall it hides in, or its depth over this when that is wider (default 3). */\n beamWidthRatio: number\n /** Side of the pillars that are added, metres (default 0.20; NBR 6118 13.2.3 asks for 19 cm). */\n columnSide: number\n /**\n * Most storeys of a building that gets panels (default 8). A tall building is a frame of its own (`buildTower`, the skyscraper presets), and cutting its 40 slabs and\n * sizing every pillar for the loss of each other one is quadratic: minutes for the 40-storey tower of the plan engine. It keeps its slabs whole, and the steel is not declared.\n */\n maxStoreys: number\n}\n\nexport const SLAB_PANEL_DEFAULTS: Readonly<SlabPanelOptions> = {\n maxSpan: 5, minPanel: 1.5, lineCoverage: 0.6, doorGap: 1.3, lineTolerance: 0.2, footprintShare: 0.5, thicknessRatio: 40, floorMinThickness: 0.1, roofMinThickness: 0.08,\n beamDepthRatio: 10, beamMinDepth: 0.25, beamStep: 0.05, beamWidthRatio: 3, columnSide: 0.2, maxStoreys: 8,\n}\n\nexport const resolveSlabPanels = (options?: boolean | Partial<SlabPanelOptions>): SlabPanelOptions | undefined => {\n if (options === false) return undefined\n const given = options === true || options === undefined ? {} : options\n const out = { ...SLAB_PANEL_DEFAULTS }\n for (const key of Object.keys(given) as (keyof SlabPanelOptions)[]) if (given[key] !== undefined) out[key] = given[key]!\n return out\n}\n","import { getAssembly } from '@adatechnology/game-destruction'\n\nimport type { Construction, Rect, Structure, StructurePart, WallDetail } from '../types'\nimport { applySplits } from './apply'\nimport type { PartsAndSupports } from './apply'\nimport { splitIntoCourses } from './courses'\nimport type { CourseSpec } from './courses'\nimport { splitIntoPanels } from './panels'\nimport type { WallSplit } from './panels'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\n\nconst LOG_DIAMETER = 0.26\nconst isWall = (part: StructurePart): boolean => part.id.startsWith('wall_') && part.assembly !== undefined && (part.role === 'wall' || part.role === 'partition')\n\nfunction logSpec(construction: Construction, part: StructurePart): CourseSpec {\n const diameter = (construction.walls.logDiameter as number | undefined) ?? LOG_DIAMETER\n return { rowHeight: diameter, bond: 'stack', joint: CONSTRUCTION_SYSTEMS.get(construction.system)!.joints.wall, assembly: part.assembly! }\n}\n\n/** Walls cut at their windows (piers, sills, lintels, spandrels); the walls of logs as courses of logs. */\nfunction panelSplits(input: PartsAndSupports, structure: Structure, lintelDepth?: (span: number) => number): Map<string, WallSplit> {\n const { construction } = structure\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)!\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts.filter(isWall)) {\n if (construction.system === 'log') {\n splits.set(part.id, splitIntoCourses(part, structure.openings, logSpec(construction, part)))\n continue\n }\n const split = splitIntoPanels(part, structure.openings, {\n lintelMaterial: system.timber ? construction.frame.timber : 'concrete', ...(system.timber ? {} : { lintelAssembly: 'reinforced_concrete' }), lintelJoint: system.joints.beam, wallJoint: system.joints.wall, ...(lintelDepth && !system.timber ? { lintelDepth } : {}), ...(construction.system === 'masonry' ? { sillBeam: true } : {}),\n })\n if (split.pieces.length > 1) splits.set(part.id, split)\n }\n return splits\n}\n\n/** Splits the walls the way `detail` says: `coarse` keeps one part per wall, `panels` cuts them at the windows, `units` goes on to bricks and blocks. */\nexport function applyPanels(input: PartsAndSupports, structure: Structure, detail: WallDetail, lintelDepth?: (span: number) => number): PartsAndSupports {\n if (detail === 'coarse') return input\n return onJambPillars(applySplits(input, panelSplits(input, structure, lintelDepth)))\n}\n\nconst OPENING_BEAM = /_(lintel|sillbeam)_\\d+$/\nconst overlaps = (a: Rect, b: Rect): boolean => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]\n\n/** The lintels and sill beams of the windows bear on the concrete pillars at the jambs as well as on the masonry beside them. */\nfunction onJambPillars(split: PartsAndSupports): PartsAndSupports {\n const pillars = split.parts.filter((part) => part.role === 'column' && part.material === 'concrete')\n const extra: PartsAndSupports['supports'] = []\n for (const beam of split.parts) {\n if (beam.role !== 'beam' || !OPENING_BEAM.test(beam.id)) continue\n for (const pillar of pillars) if (pillar.floor === beam.floor && overlaps(pillar.aabb, beam.aabb) && pillar.y0 <= beam.y0 && pillar.y1 >= beam.y1 - 0.01) extra.push({ part: beam.id, on: pillar.id, joint: 'rebar' })\n }\n return extra.length ? { parts: split.parts, supports: [...split.supports, ...extra] } : split\n}\n\nexport interface Sized extends PartsAndSupports {\n capacities: Map<string, number>\n}\n\n/** Cuts each wall piece that its assembly lays in units (bricks, blocks, concrete panels) into those units; a unit takes the share of the piece's capacity its width has (it carries its column of the wall). */\nexport function applyUnits(input: Sized, structure: Structure): Sized {\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts) {\n if (part.unit || !part.assembly || part.role === 'beam' || part.role === 'none') continue\n const units = getAssembly(part.assembly)?.units\n if (!units) continue\n const joint = CONSTRUCTION_SYSTEMS.get(structure.construction.system)!.joints.wall\n splits.set(part.id, splitIntoCourses(part, [], { rowHeight: units.size[1], unitLength: units.size[0], bond: units.bond, joint: units.mortar === 'concrete' ? 'mortar' : joint, assembly: part.assembly }))\n }\n const next = applySplits(input, splits)\n const capacities = new Map(input.capacities)\n for (const [id, split] of splits) {\n const capacity = input.capacities.get(id)\n capacities.delete(id)\n if (capacity === undefined) continue\n const along = (box: Rect): number => Math.max(box[2] - box[0], box[3] - box[1])\n const length = along(input.parts.find((part) => part.id === id)!.aabb)\n for (const piece of split.pieces) capacities.set(piece.id, Math.max(1, (capacity * along(piece.aabb)) / length))\n }\n return { ...next, capacities }\n}\n","import { touches } from '../geometry'\nimport type { Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface PartsAndSupports {\n parts: StructurePart[]\n supports: Support[]\n}\n\n/** Replaces each part that has a split by its pieces, and re-points what rested on it or what it rested on (the pieces touching the part resting on it get the load). */\nexport function applySplits(input: PartsAndSupports, splits: ReadonlyMap<string, WallSplit>): PartsAndSupports {\n if (!splits.size) return input\n const boxes = new Map<string, Rect>(input.parts.map((part) => [part.id, part.aabb]))\n const pieceBox = new Map<string, Rect>()\n for (const split of splits.values()) for (const piece of split.pieces) pieceBox.set(piece.id, piece.aabb)\n const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part])\n const supports: Support[] = []\n for (const support of input.supports) {\n const own = splits.get(support.part)\n const host = splits.get(support.on)\n const resting = boxes.get(support.part)\n const targets = host ? host.top.filter((id) => resting && touches(pieceBox.get(id)!, resting, 0.05)) : [support.on]\n const carriers = host ? (targets.length ? targets : host.top) : targets\n for (const part of own ? own.base : [support.part]) for (const on of carriers) supports.push({ ...support, part, on })\n }\n for (const split of splits.values()) supports.push(...split.internal)\n return { parts, supports }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface CourseSpec {\n rowHeight: number\n /** Length of a unit along the wall; without it a course is one piece per stretch (a log). */\n unitLength?: number\n bond: 'running' | 'stack'\n /** Joint of a unit on the units under it. */\n joint: JointKind\n assembly: string\n}\n\nconst MIN_UNIT = 0.02\n\ninterface Cell {\n from: number\n to: number\n row: number\n y0: number\n y1: number\n}\n\nfunction cutAt(from: number, to: number, openings: readonly Opening[], y0: number, y1: number): [number, number][] {\n let stretches: [number, number][] = [[from, to]]\n for (const opening of openings.filter((o) => o.y0 < y1 - MIN_UNIT && o.y1 > y0 + MIN_UNIT)) {\n stretches = stretches.flatMap(([a, b]): [number, number][] => {\n if (opening.to <= a || opening.from >= b) return [[a, b]]\n return [[a, Math.min(b, opening.from)], [Math.max(a, opening.to), b]].filter(([x, y]) => (y as number) - (x as number) > MIN_UNIT) as [number, number][]\n })\n }\n return stretches\n}\n\nfunction unitsOf(from: number, to: number, row: number, spec: CourseSpec): [number, number][] {\n const length = spec.unitLength\n if (!length) return [[from, to]]\n const offset = spec.bond === 'running' && row % 2 === 1 ? length / 2 : 0\n const cuts: number[] = [from]\n for (let at = from + (offset || length); at < to - MIN_UNIT; at += length) cuts.push(at)\n cuts.push(to)\n return cuts.slice(0, -1).map((start, k): [number, number] => [start, cuts[k + 1]!]).filter(([a, b]) => b - a > MIN_UNIT)\n}\n\n/**\n * Cuts a wall into courses of units (bricks laid in bond, or logs): each course is cut at the openings it meets, and each unit rests on the units of the course\n * below that it overlaps. A wall whose lowest course goes loses every course above it. The mass of the wall is shared among the units by volume.\n */\nexport function splitIntoCourses(wall: StructurePart, openings: readonly Opening[], spec: CourseSpec): WallSplit {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n const from = alongU ? wall.aabb[0] : wall.aabb[1]\n const to = alongU ? wall.aabb[2] : wall.aabb[3]\n const cross: [number, number] = alongU ? [wall.aabb[1], wall.aabb[3]] : [wall.aabb[0], wall.aabb[2]]\n const rows = Math.max(1, Math.round((wall.y1 - wall.y0) / spec.rowHeight))\n const rowHeight = (wall.y1 - wall.y0) / rows\n const cells: Cell[] = []\n for (let row = 0; row < rows; row++) {\n const y0 = wall.y0 + row * rowHeight\n const y1 = wall.y0 + (row + 1) * rowHeight\n for (const [a, b] of cutAt(from, to, openings.filter((o) => o.wall === wall.id), y0, y1)) for (const [x0, x1] of unitsOf(a, b, row, spec)) cells.push({ from: x0, to: x1, row, y0, y1 })\n }\n const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0)\n const box = (cell: Cell): Rect => (alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to])\n const pieces = cells.map((cell, index): StructurePart => ({\n id: `${wall.id}_${spec.unitLength ? 'u' : 'log'}${cell.row}_${index}`, role: wall.role, material: wall.material, aabb: box(cell), y0: cell.y0, y1: cell.y1, floor: wall.floor,\n mass: round2(Math.max(0.1, (wall.mass * (cell.to - cell.from) * (cell.y1 - cell.y0)) / total)), host: wall.id, assembly: spec.assembly, unit: true,\n }))\n const internal: Support[] = []\n cells.forEach((cell, index) => {\n if (cell.row === 0) return\n const below = cells.map((other, k) => ({ other, k })).filter(({ other }) => other.row === cell.row - 1 && Math.min(other.to, cell.to) - Math.max(other.from, cell.from) > MIN_UNIT)\n for (const { k } of below) internal.push({ part: pieces[index]!.id, on: pieces[k]!.id, joint: spec.joint })\n })\n return { pieces, internal, base: pieces.filter((_, i) => cells[i]!.row === 0).map((p) => p.id), top: pieces.filter((_, i) => cells[i]!.row === rows - 1).map((p) => p.id) }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\n\nexport interface PanelStyle {\n lintelMaterial: string\n lintelAssembly?: string\n /** Joint of a lintel on its piers and of the wall above it on the lintel. */\n lintelJoint: JointKind\n wallJoint: JointKind\n /** Depth of the lintel over an opening of the given width, metres (default `LINTEL_DEPTH`): a wide opening needs a deeper beam. */\n lintelDepth?: (span: number) => number\n /** A concrete sill beam (contraverga) under each window, `SILL_BEAM_DEPTH` deep and bearing `LINTEL_BEARING` on the piers: masonry walls have one. */\n sillBeam?: boolean\n}\n\nexport interface WallSplit {\n pieces: StructurePart[]\n /** What the pieces rest on among themselves (lintel on piers, spandrel on lintel). */\n internal: Support[]\n /** Pieces that rest on what the wall rests on. */\n base: string[]\n /** Pieces that carry what rests on the wall. */\n top: string[]\n}\n\nexport const LINTEL_DEPTH = 0.2\nexport const LINTEL_BEARING = 0.2\n/** Depth of the sill beam under a window of a masonry wall, metres (a contraverga is usually 10 cm). */\nexport const SILL_BEAM_DEPTH = 0.1\n/** A lintel is at least a tenth of its span deep (span: the opening plus one bearing, h = L/10). */\nconst LINTEL_SPAN_RATIO = 10\nconst MIN_PIECE = 0.05\n\ninterface Frame {\n alongU: boolean\n from: number\n to: number\n cross: [number, number]\n}\n\nconst frameOf = (wall: StructurePart): Frame => {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n return alongU ? { alongU, from: wall.aabb[0], to: wall.aabb[2], cross: [wall.aabb[1], wall.aabb[3]] } : { alongU, from: wall.aabb[1], to: wall.aabb[3], cross: [wall.aabb[0], wall.aabb[2]] }\n}\n\nconst boxOf = (frame: Frame, from: number, to: number): Rect => (frame.alongU ? [from, frame.cross[0], to, frame.cross[1]] : [frame.cross[0], from, frame.cross[1], to])\n\ninterface Draft {\n id: string\n role: StructurePart['role']\n material: string\n assembly?: string\n from: number\n to: number\n y0: number\n y1: number\n /** Volume that counts for the mass share (pieces tile the wall: a lintel keeps the bearing it shares with the piers). */\n volume: number\n}\n\n/**\n * Cuts a wall at its windows: piers between them at full height, a sill wall under each window, a lintel over it that bears 0.2 m on the piers and the wall\n * above the lintel up to the top. The mass of the wall is shared among the pieces by volume, so the total is the wall's.\n */\nexport function splitIntoPanels(wall: StructurePart, openings: readonly Opening[], style: PanelStyle): WallSplit {\n const frame = frameOf(wall)\n const own = openings.filter((o) => o.wall === wall.id && o.to > frame.from + MIN_PIECE && o.from < frame.to - MIN_PIECE).sort((a, b) => a.from - b.from)\n if (!own.length) return { pieces: [wall], internal: [], base: [wall.id], top: [wall.id] }\n const drafts: Draft[] = []\n const piers: Draft[] = []\n const lintels: Draft[] = []\n const sillBeams: Draft[] = []\n const spandrels: (Draft | undefined)[] = []\n const height = wall.y1 - wall.y0\n let cursor = frame.from\n const roleOf = wall.role\n const addPier = (to: number): void => {\n if (to - cursor < MIN_PIECE) return\n piers.push({ id: `${wall.id}_pier_${piers.length}`, role: roleOf, material: wall.material, from: cursor, to, y0: wall.y0, y1: wall.y1, volume: (to - cursor) * height })\n }\n own.forEach((opening, k) => {\n addPier(Math.max(cursor, opening.from))\n const span = opening.to - opening.from\n const lintelTop = Math.min(wall.y1, opening.y1 + Math.max(LINTEL_DEPTH, style.lintelDepth?.(span) ?? 0, (span + LINTEL_BEARING) / LINTEL_SPAN_RATIO))\n const lintelFrom = Math.max(frame.from, opening.from - LINTEL_BEARING)\n const lintelTo = Math.min(frame.to, opening.to + LINTEL_BEARING)\n const lintelHeight = lintelTop - opening.y1\n const sillTop = style.sillBeam && opening.y0 - wall.y0 > SILL_BEAM_DEPTH + MIN_PIECE ? opening.y0 - SILL_BEAM_DEPTH : opening.y0\n if (sillTop - wall.y0 > MIN_PIECE) drafts.push({ id: `${wall.id}_sill_${k}`, role: 'partition', material: wall.material, from: opening.from, to: opening.to, y0: wall.y0, y1: sillTop, volume: (opening.to - opening.from) * (sillTop - wall.y0) })\n if (sillTop < opening.y0) sillBeams.push({ id: `${wall.id}_sillbeam_${k}`, role: 'beam', material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: sillTop, y1: opening.y0, volume: (lintelTo - lintelFrom) * SILL_BEAM_DEPTH })\n lintels.push({ id: `${wall.id}_lintel_${k}`, role: 'beam', material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: opening.y1, y1: lintelTop, volume: (lintelTo - lintelFrom) * lintelHeight })\n spandrels.push(wall.y1 - lintelTop > MIN_PIECE ? { id: `${wall.id}_spandrel_${k}`, role: roleOf, material: wall.material, from: opening.from, to: opening.to, y0: lintelTop, y1: wall.y1, volume: (opening.to - opening.from) * (wall.y1 - lintelTop) } : undefined)\n cursor = opening.to\n })\n addPier(frame.to)\n // the piers give the bearing zone of each lintel and sill beam to it\n for (const pier of piers) {\n for (const lintel of [...lintels, ...sillBeams]) {\n const overlap = Math.max(0, Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from))\n pier.volume -= overlap * (lintel.y1 - lintel.y0)\n }\n }\n const all = [...piers, ...drafts, ...sillBeams, ...lintels, ...spandrels.filter((d): d is Draft => d !== undefined)]\n const total = all.reduce((sum, d) => sum + d.volume, 0)\n const pieces = all.map((d): StructurePart => ({\n id: d.id, role: d.role, material: d.material, aabb: boxOf(frame, d.from, d.to), y0: d.y0, y1: d.y1, floor: wall.floor, mass: round2(Math.max(0.1, (wall.mass * d.volume) / total)), host: wall.id,\n ...(d.role === 'beam' ? (style.lintelAssembly ? { assembly: style.lintelAssembly } : {}) : wall.assembly ? { assembly: wall.assembly } : {}),\n }))\n const internal: Support[] = []\n // a sill beam rests on the masonry under the window and bears on the piers at each side\n for (const beam of sillBeams) {\n const sill = drafts.find((d) => d.id === beam.id.replace('_sillbeam_', '_sill_'))\n if (sill) internal.push({ part: beam.id, on: sill.id, joint: style.lintelJoint })\n for (const pier of piers) if (Math.min(pier.to, beam.to) - Math.max(pier.from, beam.from) > 0) internal.push({ part: beam.id, on: pier.id, joint: style.lintelJoint })\n }\n lintels.forEach((lintel, k) => {\n for (const pier of piers) if (Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from) > 0) internal.push({ part: lintel.id, on: pier.id, joint: style.lintelJoint })\n const spandrel = spandrels[k]\n if (spandrel) internal.push({ part: spandrel.id, on: lintel.id, joint: style.wallJoint })\n })\n const base = [...piers, ...drafts.filter((d) => d.id.includes('_sill_'))].map((d) => d.id)\n const top = [...piers.map((p) => p.id), ...lintels.map((l, k) => spandrels[k]?.id ?? l.id)]\n return { pieces, internal, base, top }\n}\n","/** Stable codes of what `validateStructure` and `validateSpec` find wrong in a construction. */\nexport const STRUCTURAL_VIOLATION = {\n /** A pillar with no load path to the ground, or that starts above what it rests on. */\n PILLAR_NOT_GROUNDED: 'PILLAR_NOT_GROUNDED',\n /** A pillar of a masonry wall that stops short of the bond beam, or that the bond beam does not rest on. */\n PILLAR_DOES_NOT_REACH_BOND_BEAM: 'PILLAR_DOES_NOT_REACH_BOND_BEAM',\n /** A masonry wall that runs more than `MAX_PILLAR_SPACING` between two of its pillars. */\n WALL_SPAN_WITHOUT_PILLAR: 'WALL_SPAN_WITHOUT_PILLAR',\n /** A free end of a masonry wall (a door jamb, the end of a garden wall) with no pillar. */\n WALL_END_WITHOUT_PILLAR: 'WALL_END_WITHOUT_PILLAR',\n /** Two masonry walls meet at a corner with no pillar there. */\n CORNER_WITHOUT_PILLAR: 'CORNER_WITHOUT_PILLAR',\n /** Another wall meets a masonry wall inside its length (a T) with no pillar there. */\n WALL_JUNCTION_WITHOUT_PILLAR: 'WALL_JUNCTION_WITHOUT_PILLAR',\n /** A window or door in a masonry wall with no lintel (verga) over it. */\n OPENING_WITHOUT_LINTEL: 'OPENING_WITHOUT_LINTEL',\n /** A window in a masonry wall with no sill beam (contraverga) under it. */\n OPENING_WITHOUT_SILL: 'OPENING_WITHOUT_SILL',\n /** An exterior masonry wall with no bond beam (cinta de amarração) on top. */\n MISSING_BOND_BEAM: 'MISSING_BOND_BEAM',\n /** A ground-floor masonry wall standing on the soil with no ground beam (viga baldrame) or foundation under it. */\n MISSING_GROUND_BEAM: 'MISSING_GROUND_BEAM',\n /** A part with no load path down to the ground. */\n FLOATING_PART: 'FLOATING_PART',\n /** A concrete beam longer than a lintel that rests on masonry alone (no pillar, beam or slab carries it). */\n BEAM_ON_WEAK_MASONRY: 'BEAM_ON_WEAK_MASONRY',\n /** A concrete pillar or beam below the NBR 6118 minimum section, or a beam between point supports shallower than a tenth of its span. */\n CONCRETE_BELOW_MIN_SECTION: 'CONCRETE_BELOW_MIN_SECTION',\n /** A concrete pillar or beam with no steel (the construction has no rebar). */\n UNREINFORCED_CONCRETE: 'UNREINFORCED_CONCRETE',\n /** A brick or block wall laid in stack bond: the vertical joints line up and the wall splits along them. */\n UNBONDED_MASONRY: 'UNBONDED_MASONRY',\n /** A plastered brick wall without plaster on both faces. */\n MISSING_PLASTER: 'MISSING_PLASTER',\n} as const\n\nexport type StructuralViolationCode = (typeof STRUCTURAL_VIOLATION)[keyof typeof STRUCTURAL_VIOLATION]\n\n/** One thing a construction gets wrong: the code, the part (or opening) it is about and the rule it breaks, in words. */\nexport interface StructuralViolation {\n readonly code: StructuralViolationCode\n readonly part: string\n readonly message: string\n}\n\n/** Most metres a masonry wall runs between two pillars (confined masonry: 3 to 4 m; `WALL_PILLAR_SPACING` is 4). */\nexport const MAX_PILLAR_SPACING = 4\n/** NBR 6118 13.2.3: no side of a pillar under 19 cm, and at least 360 cm² of section. */\nexport const MIN_PILLAR_SIDE = 0.19\nexport const MIN_PILLAR_AREA = 0.036\n/** NBR 6118 13.2.2: a beam at least 12 cm wide. */\nexport const MIN_BEAM_WIDTH = 0.12\n/** A beam between point supports is at least a tenth of its span deep (pre-sizing of reinforced concrete beams, h = L/10). */\nexport const BEAM_DEPTH_RATIO = 10\n/** A concrete beam that only masonry carries may be a lintel up to this span; a longer one needs pillars. */\nexport const MAX_LINTEL_ON_MASONRY = 3\n","import { GROUND } from '../types'\nimport type { Structure, StructurePart, Support } from '../types'\nimport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\n/** A part this close above the top of what it rests on still rests on it (metres). */\nconst CONTACT = 0.05\nconst EPSILON = 0.005\n\n/** The parts with a load path down to the ground over the supports that bear. */\nexport function groundedParts(parts: readonly StructurePart[], supports: readonly Support[]): Set<string> {\n const ids = new Set(parts.map((part) => part.id))\n const grounded = new Set<string>([GROUND])\n const bearing = supports.filter((s) => s.bears !== false && ids.has(s.part))\n let grew = true\n while (grew) {\n grew = false\n for (const support of bearing) {\n if (grounded.has(support.part) || !grounded.has(support.on)) continue\n grounded.add(support.part)\n grew = true\n }\n }\n return grounded\n}\n\n/** Every part with a load path to the ground, and every pillar standing on what it rests on. */\nexport function loadPathViolations(structure: Pick<Structure, 'parts' | 'supports'>): StructuralViolation[] {\n const { parts, supports } = structure\n const grounded = groundedParts(parts, supports)\n const byId = new Map(parts.map((part) => [part.id, part]))\n const out: StructuralViolation[] = []\n for (const part of parts) {\n if (part.role === 'none') continue\n const pillar = part.role === 'column'\n if (!grounded.has(part.id)) {\n out.push({ code: pillar ? STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED : STRUCTURAL_VIOLATION.FLOATING_PART, part: part.id, message: `${part.id} has no load path to the ground` })\n continue\n }\n if (!pillar) continue\n const bases = supports.filter((s) => s.part === part.id && s.bears !== false)\n const standsOnBase = bases.some((s) => {\n if (s.on === GROUND) return part.y0 <= CONTACT\n const base = byId.get(s.on)\n return base !== undefined && part.y0 >= base.y0 - EPSILON && part.y0 <= base.y1 + CONTACT\n })\n if (!standsOnBase) out.push({ code: STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED, part: part.id, message: `${part.id} starts at ${part.y0} m, above what it rests on` })\n }\n return out\n}\n\nconst alongOf = (part: StructurePart): { alongU: boolean; from: number; to: number; width: number } => {\n const alongU = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1]\n return alongU\n ? { alongU, from: part.aabb[0], to: part.aabb[2], width: part.aabb[3] - part.aabb[1] }\n : { alongU, from: part.aabb[1], to: part.aabb[3], width: part.aabb[2] - part.aabb[0] }\n}\n\n/** The along ranges of a beam where each of its bearing supports holds it. */\nfunction bearingsOf(beam: StructurePart, supports: readonly Support[], byId: ReadonlyMap<string, StructurePart>): Bearing[] {\n const frame = alongOf(beam)\n return supports\n .filter((s) => s.part === beam.id && s.bears !== false && s.on !== GROUND)\n .map((s) => byId.get(s.on))\n .filter((on): on is StructurePart => on !== undefined)\n .map((on) => {\n const [low, high] = frame.alongU ? [on.aabb[0], on.aabb[2]] : [on.aabb[1], on.aabb[3]]\n return { on, from: Math.max(frame.from, low), to: Math.min(frame.to, high) }\n })\n .filter((bearing) => bearing.to - bearing.from > -EPSILON)\n}\n\nconst isWallLike = (part: StructurePart): boolean => part.role === 'wall' || part.role === 'partition'\n/** A plain concrete pedestal (a footing block under a post) may go without steel: no taller than three times its least side (ACI 318 14.3.3). */\nconst PEDESTAL_RATIO = 3\nconst isPedestal = (part: StructurePart): boolean => part.role === 'column' && part.y1 - part.y0 <= PEDESTAL_RATIO * Math.min(part.aabb[2] - part.aabb[0], part.aabb[3] - part.aabb[1])\n\n/**\n * Concrete pillars and beams against NBR 6118: the minimum sections (13.2.2, 13.2.3), the steel of a reinforced member, a beam between point supports at\n * least a tenth of its span deep, and no long beam that only masonry carries.\n */\nexport function concreteViolations(structure: Pick<Structure, 'parts' | 'supports' | 'construction'>, isMasonry: (part: StructurePart) => boolean): StructuralViolation[] {\n const { parts, supports } = structure\n const byId = new Map(parts.map((part) => [part.id, part]))\n const out: StructuralViolation[] = []\n for (const part of parts) {\n if (part.material !== 'concrete' || (part.role !== 'column' && part.role !== 'beam')) continue\n if (!structure.construction.frame.rebar && !isPedestal(part)) out.push({ code: STRUCTURAL_VIOLATION.UNREINFORCED_CONCRETE, part: part.id, message: `${part.id} is concrete without steel` })\n if (part.role === 'column') {\n const sides = [part.aabb[2] - part.aabb[0], part.aabb[3] - part.aabb[1]]\n if (Math.min(...sides) < MIN_PILLAR_SIDE - EPSILON || sides[0]! * sides[1]! < MIN_PILLAR_AREA - EPSILON)\n out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${sides.map((s) => s.toFixed(2)).join(' x ')} m: NBR 6118 asks at least ${MIN_PILLAR_SIDE} m a side and ${MIN_PILLAR_AREA} m²` })\n continue\n }\n const castOn = supports\n .filter((s) => s.on === part.id && s.bears !== false)\n .map((s) => byId.get(s.part))\n .filter((top): top is StructurePart => top !== undefined && top.role === 'beam' && top.material === 'concrete' && Math.abs(top.y0 - part.y1) < 0.01)\n .reduce((most, top) => Math.max(most, top.y1 - top.y0), 0)\n out.push(...beamViolations(part, bearingsOf(part, supports, byId), { isMasonry, castOn }))\n }\n return out\n}\n\n/** Longest effective span between the bearings of a beam: the clear span plus, at each end, half the bearing up to 0.3 of the depth (NBR 6118 14.6.2.4). */\nfunction effectiveSpan(bearings: readonly { from: number; to: number }[], depth: number): number {\n const sorted = [...bearings].sort((a, b) => a.from - b.from)\n let most = 0\n for (let k = 1; k < sorted.length; k++) {\n const previous = sorted.slice(0, k).reduce((a, b) => (b.to > a.to ? b : a))\n const next = sorted[k]!\n const clear = next.from - previous.to\n if (clear <= 0) continue\n most = Math.max(most, clear + Math.min((previous.to - previous.from) / 2, 0.3 * depth) + Math.min((next.to - next.from) / 2, 0.3 * depth))\n }\n return most\n}\n\ninterface Bearing {\n on: StructurePart\n from: number\n to: number\n}\n\nfunction beamViolations(beam: StructurePart, bearings: readonly Bearing[], context: { isMasonry: (part: StructurePart) => boolean; castOn: number }): StructuralViolation[] {\n const out: StructuralViolation[] = []\n const frame = alongOf(beam)\n const length = frame.to - frame.from\n // a beam cast together with the one on it (a lintel under the bond beam) works as one section\n const depth = beam.y1 - beam.y0 + context.castOn\n if (frame.width < MIN_BEAM_WIDTH - EPSILON) out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: beam.id, message: `${beam.id} is ${frame.width.toFixed(2)} m wide: NBR 6118 asks at least ${MIN_BEAM_WIDTH} m` })\n if (!bearings.length) return out\n const continuous = bearings.some((b) => isWallLike(b.on) && b.to - b.from >= length / 2)\n const span = continuous ? 0 : effectiveSpan(bearings, depth)\n if (depth < span / BEAM_DEPTH_RATIO - EPSILON) out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: beam.id, message: `${beam.id} is ${depth.toFixed(2)} m deep over a ${span.toFixed(2)} m span: it needs at least L/${BEAM_DEPTH_RATIO} = ${(span / BEAM_DEPTH_RATIO).toFixed(2)} m` })\n if (length > MAX_LINTEL_ON_MASONRY && bearings.every((b) => context.isMasonry(b.on)))\n out.push({ code: STRUCTURAL_VIOLATION.BEAM_ON_WEAK_MASONRY, part: beam.id, message: `${beam.id} spans ${length.toFixed(2)} m on masonry alone: no pillar carries it` })\n return out\n}\n","import { getAssembly } from '@adatechnology/game-destruction'\n\nimport { GROUND } from '../types'\nimport type { Structure, StructurePart } from '../types'\nimport { MAX_PILLAR_SPACING, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\nconst TOLERANCE = 0.05\n/** A pillar this close (along the wall) to a corner, an end or a junction stands there (`WALL_PILLAR_SIDE` plus the merge distance of `addWallPillars`). */\nconst AT_POINT = 0.45\nconst EXPOSED_FINISHES: readonly string[] = ['exposed_brick', 'exposed_block']\n\n/** A wall of the plan as a line: its axis, the line across, where its centre line starts and ends, its half thickness. */\nexport interface WallLine {\n part: StructurePart\n alongU: boolean\n line: number\n from: number\n to: number\n half: number\n}\n\nexport const lineOf = (part: StructurePart): WallLine => {\n const alongU = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1]\n const half = (alongU ? part.aabb[3] - part.aabb[1] : part.aabb[2] - part.aabb[0]) / 2\n const [from, to] = alongU ? [part.aabb[0], part.aabb[2]] : [part.aabb[1], part.aabb[3]]\n return { part, alongU, line: alongU ? part.aabb[1] + half : part.aabb[0] + half, from: from + half, to: to - half, half }\n}\n\n/** A wall laid in bricks or blocks with mortar (not a concrete wall, not timber). */\nexport function isMasonryWall(part: StructurePart): boolean {\n if (!part.id.startsWith('wall_') || !part.assembly || (part.role !== 'wall' && part.role !== 'partition')) return false\n const units = getAssembly(part.assembly)?.units\n return units !== undefined && units.mortar !== 'concrete'\n}\n\nconst pointOf = (wall: WallLine, along: number): [number, number] => (wall.alongU ? [along, wall.line] : [wall.line, along])\nconst alongOfPoint = (wall: WallLine, point: readonly [number, number]): number => (wall.alongU ? point[0] : point[1])\nconst acrossOfPoint = (wall: WallLine, point: readonly [number, number]): number => (wall.alongU ? point[1] : point[0])\nconst centre = (part: StructurePart): [number, number] => [(part.aabb[0] + part.aabb[2]) / 2, (part.aabb[1] + part.aabb[3]) / 2]\nconst onLine = (wall: WallLine, point: readonly [number, number], slack = 0): boolean =>\n Math.abs(acrossOfPoint(wall, point) - wall.line) <= wall.half + TOLERANCE && alongOfPoint(wall, point) >= wall.from - wall.half - slack && alongOfPoint(wall, point) <= wall.to + wall.half + slack\n\n/** What the end of a wall meets: another wall end at a corner, the side of another wall (a T), the next wall on the same line, or nothing (a free end, a door jamb). */\nfunction endKind(wall: WallLine, along: number, others: readonly WallLine[]): 'corner' | 'junction' | 'continued' | 'free' {\n const point = pointOf(wall, along)\n const meeting = others.filter((other) => onLine(other, point))\n const across = meeting.filter((other) => other.alongU !== wall.alongU)\n const continued = meeting.length > across.length\n if (!across.length) return continued ? 'continued' : 'free'\n // the side of a wall that the line goes on through, or that meets it in its length, is a junction; two ends alone are a corner\n const atEnd = (other: WallLine): boolean => Math.min(Math.abs(alongOfPoint(other, point) - other.from), Math.abs(alongOfPoint(other, point) - other.to)) <= other.half + wall.half + TOLERANCE\n return !continued && across.every(atEnd) ? 'corner' : 'junction'\n}\n\ninterface WallContext {\n wall: WallLine\n pillars: StructurePart[]\n stations: number[]\n /** Along ranges of the windows in the wall (no masonry to confine there). */\n windows: [number, number][]\n}\n\n/** Metres of masonry between two points along a wall: the distance less the windows between them. */\nconst masonryBetween = (from: number, to: number, windows: readonly [number, number][]): number =>\n windows.reduce((left, [a, b]) => left - Math.max(0, Math.min(to, b) - Math.max(from, a)), to - from)\n\nfunction pointViolations(context: WallContext, others: readonly WallLine[]): StructuralViolation[] {\n const { wall, stations } = context\n const out: StructuralViolation[] = []\n const covered = (along: number): boolean => stations.some((at) => Math.abs(at - along) <= AT_POINT)\n for (const along of [wall.from, wall.to]) {\n const kind = endKind(wall, along, others)\n if (kind === 'continued' || covered(along)) continue\n const code = kind === 'corner' ? STRUCTURAL_VIOLATION.CORNER_WITHOUT_PILLAR : kind === 'junction' ? STRUCTURAL_VIOLATION.WALL_JUNCTION_WITHOUT_PILLAR : STRUCTURAL_VIOLATION.WALL_END_WITHOUT_PILLAR\n out.push({ code, part: wall.part.id, message: `${wall.part.id} has no pillar at its ${kind} end (${along.toFixed(2)} m along)` })\n }\n for (const other of others) {\n if (other.alongU === wall.alongU) continue\n for (const end of [other.from, other.to]) {\n const point = pointOf(other, end)\n const at = alongOfPoint(wall, point)\n if (!onLine(wall, point) || at <= wall.from + AT_POINT || at >= wall.to - AT_POINT || covered(at)) continue\n out.push({ code: STRUCTURAL_VIOLATION.WALL_JUNCTION_WITHOUT_PILLAR, part: wall.part.id, message: `${other.part.id} meets ${wall.part.id} at ${at.toFixed(2)} m along with no pillar there` })\n }\n }\n const line = [...stations].sort((a, b) => a - b)\n for (let k = 1; k < line.length; k++) {\n const gap = masonryBetween(line[k - 1]!, line[k]!, context.windows)\n if (gap > MAX_PILLAR_SPACING + TOLERANCE) out.push({ code: STRUCTURAL_VIOLATION.WALL_SPAN_WITHOUT_PILLAR, part: wall.part.id, message: `${wall.part.id} runs ${gap.toFixed(2)} m between pillars (at most ${MAX_PILLAR_SPACING} m)` })\n }\n if (!line.length && wall.to - wall.from > MAX_PILLAR_SPACING) out.push({ code: STRUCTURAL_VIOLATION.WALL_SPAN_WITHOUT_PILLAR, part: wall.part.id, message: `${wall.part.id} runs ${(wall.to - wall.from).toFixed(2)} m with no pillar` })\n return out\n}\n\nfunction bondBeamViolations(context: WallContext, structure: Pick<Structure, 'parts' | 'supports'>): StructuralViolation[] {\n const { wall, pillars } = context\n const resting = new Set(structure.supports.filter((s) => s.on === wall.part.id).map((s) => s.part))\n const beams = structure.parts.filter((p) => p.beamKind === 'bond_beam' && resting.has(p.id))\n if (!beams.length) return [{ code: STRUCTURAL_VIOLATION.MISSING_BOND_BEAM, part: wall.part.id, message: `${wall.part.id} has no bond beam on top` }]\n const out: StructuralViolation[] = []\n for (const pillar of pillars) {\n const [u, v] = centre(pillar)\n const over = beams.filter((b) => u >= b.aabb[0] - TOLERANCE && u <= b.aabb[2] + TOLERANCE && v >= b.aabb[1] - TOLERANCE && v <= b.aabb[3] + TOLERANCE)\n const carries = over.some((b) => pillar.y1 >= b.y0 - TOLERANCE && structure.supports.some((s) => s.part === b.id && s.on === pillar.id && s.bears !== false))\n if (!carries) out.push({ code: STRUCTURAL_VIOLATION.PILLAR_DOES_NOT_REACH_BOND_BEAM, part: pillar.id, message: `${pillar.id} stops at ${pillar.y1} m and does not carry the bond beam of ${wall.part.id}` })\n }\n return out\n}\n\n/** The units and coats of a masonry wall: a running bond, and plaster on both faces of a plastered brick wall. */\nfunction assemblyViolations(part: StructurePart, finish: string | undefined): StructuralViolation[] {\n const def = getAssembly(part.assembly ?? '')\n if (!def) return []\n const out: StructuralViolation[] = []\n if (def.units && def.units.bond !== 'running') out.push({ code: STRUCTURAL_VIOLATION.UNBONDED_MASONRY, part: part.id, message: `${part.id} is laid in ${def.units.bond} bond: the joints must be staggered` })\n const plastered = (def.layers ?? []).some((layer) => layer.material === 'plaster' && layer.faces === 'both')\n if (def.core.material === 'brick' && !plastered && !EXPOSED_FINISHES.includes(finish ?? '')) out.push({ code: STRUCTURAL_VIOLATION.MISSING_PLASTER, part: part.id, message: `${part.id} is brick without plaster on both faces` })\n return out\n}\n\n/**\n * Confined masonry: every exterior masonry wall stands on a ground beam (or a foundation), has a concrete pillar at each end, corner and junction and at most\n * every `MAX_PILLAR_SPACING` metres, from the floor up to the bond beam on top, which rests on them; its bricks are bonded and plastered on both faces.\n */\nexport function masonryViolations(structure: Pick<Structure, 'parts' | 'supports' | 'construction' | 'openings'>): StructuralViolation[] {\n const walls = structure.parts.filter(isMasonryWall)\n const columns = structure.parts.filter((p) => p.role === 'column' && p.material === 'concrete')\n const out: StructuralViolation[] = []\n for (const part of walls) {\n out.push(...assemblyViolations(part, structure.construction.walls.finish))\n if (part.floor === 0 && structure.supports.some((s) => s.part === part.id && s.on === GROUND))\n out.push({ code: STRUCTURAL_VIOLATION.MISSING_GROUND_BEAM, part: part.id, message: `${part.id} stands on the soil with no ground beam under it` })\n if (!part.exterior) continue\n const wall = lineOf(part)\n // a pillar of the next wall on the line, standing just past this one's end, confines this end too\n const pillars = columns.filter((c) => c.floor === part.floor && onLine(wall, centre(c), AT_POINT) && Math.min(c.y1, part.y1) - Math.max(c.y0, part.y0) > 0.5)\n const windows = structure.openings.filter((o) => o.wall === part.id).map((o): [number, number] => [o.from, o.to])\n const context: WallContext = { wall, pillars, stations: pillars.map((p) => alongOfPoint(wall, centre(p))), windows }\n const others = walls.filter((w) => w !== part && w.floor === part.floor).map(lineOf)\n out.push(...pointViolations(context, others), ...bondBeamViolations(context, structure))\n }\n return out\n}\n","import type { Opening, SourceDoor, Structure, StructurePart } from '../types'\nimport { DOOR_HEIGHT } from '../structure/openings'\nimport { LINTEL_DEPTH, SILL_BEAM_DEPTH } from '../wall-detail/panels'\nimport { STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\nimport { isMasonryWall, lineOf } from './masonry'\nimport type { WallLine } from './masonry'\n\nconst TOLERANCE = 0.05\n/** A window this close to the floor has too little masonry under it for a sill beam (a French window). */\nconst LOW_WINDOW = SILL_BEAM_DEPTH + 0.05\n\n/**\n * A beam in the wall's line that covers `[from, to]` along it, with its underside (`side: 'y0'`) within a lintel's depth over `y` (the bond beam is the\n * lintel of a window right under it) or its top (`'y1'`) at `y`.\n */\nfunction beamAcross(parts: readonly StructurePart[], wall: WallLine, span: { from: number; to: number }, side: 'y0' | 'y1', y: number): boolean {\n return parts.some((part) => {\n const off = part[side] - y\n if (part.role !== 'beam' || off < -TOLERANCE || off > (side === 'y0' ? LINTEL_DEPTH : TOLERANCE)) return false\n const [from, to, low, high] = wall.alongU ? [part.aabb[0], part.aabb[2], part.aabb[1], part.aabb[3]] : [part.aabb[1], part.aabb[3], part.aabb[0], part.aabb[2]]\n return from <= span.from + TOLERANCE && to >= span.to - TOLERANCE && low <= wall.line + TOLERANCE && high >= wall.line - TOLERANCE\n })\n}\n\nfunction windowViolations(opening: Opening, wall: StructurePart, built: readonly StructurePart[]): StructuralViolation[] {\n const line = lineOf(wall)\n const out: StructuralViolation[] = []\n if (!beamAcross(built, line, opening, 'y0', opening.y1)) out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_LINTEL, part: opening.id, message: `window ${opening.id} in ${wall.id} has no lintel over it` })\n if (opening.y0 - wall.y0 > LOW_WINDOW && !beamAcross(built, line, opening, 'y1', opening.y0))\n out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_SILL, part: opening.id, message: `window ${opening.id} in ${wall.id} has no sill beam under it` })\n return out\n}\n\n/** The masonry walls beside a door gap (the door is the gap between two walls on one line). */\nfunction wallsBeside(door: SourceDoor, walls: readonly StructurePart[]): WallLine[] {\n const along = door.axis === 'u' ? door.u : door.v\n const across = door.axis === 'u' ? door.v : door.u\n const from = along - door.width / 2\n const to = along + door.width / 2\n return walls\n .filter((w) => w.floor === door.floor)\n .map(lineOf)\n .filter((w) => w.alongU === (door.axis === 'u') && Math.abs(w.line - across) <= TOLERANCE && (Math.abs(w.to - from) <= TOLERANCE || Math.abs(w.from - to) <= TOLERANCE))\n}\n\n/** Lintels and sill beams: a lintel over every window and door of a masonry wall, a sill beam under every window that has masonry under it. */\nexport function openingViolations(structure: Pick<Structure, 'parts' | 'openings' | 'levels'>, built: readonly StructurePart[], doors: readonly SourceDoor[]): StructuralViolation[] {\n const walls = structure.parts.filter(isMasonryWall)\n const hosts = new Map(walls.map((wall) => [wall.id, wall]))\n const out: StructuralViolation[] = []\n for (const opening of structure.openings) {\n const wall = hosts.get(opening.wall)\n if (wall) out.push(...windowViolations(opening, wall, built))\n }\n for (const door of doors) {\n const beside = wallsBeside(door, walls)\n if (!beside.length) continue\n const along = door.axis === 'u' ? door.u : door.v\n const span = { from: along - door.width / 2, to: along + door.width / 2 }\n const lintel = beamAcross(built, beside[0]!, span, 'y0', (structure.levels[door.floor] ?? 0) + DOOR_HEIGHT)\n if (!lintel) out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_LINTEL, part: door.id, message: `door ${door.id} has no lintel over it` })\n }\n return out\n}\n","import type { DestructibleSpec, JointSpec, PartSpec } from '@adatechnology/game-contracts'\n\nimport { MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\nconst EPSILON = 0.005\n\nconst carries = (part: PartSpec | undefined): boolean => part?.structure !== undefined && part.structure.role !== 'none'\n\n/** The directions load flows over a joint: `[from, to]` pairs (a part rests on the second). */\nfunction flows(joint: JointSpec, byId: ReadonlyMap<string, PartSpec>): [string, string][] {\n const bears = joint.bears ?? (carries(byId.get(joint.a)) && carries(byId.get(joint.b)))\n if (bears === false) return []\n if (bears === 'a_on_b') return [[joint.a, joint.b]]\n if (bears === 'b_on_a') return [[joint.b, joint.a]]\n return [[joint.a, joint.b], [joint.b, joint.a]]\n}\n\nfunction groundedOf(spec: DestructibleSpec, byId: ReadonlyMap<string, PartSpec>): Set<string> {\n const grounded = new Set(spec.parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id))\n const edges = (spec.joints ?? []).flatMap((joint) => flows(joint, byId))\n let grew = true\n while (grew) {\n grew = false\n for (const [part, on] of edges) {\n if (grounded.has(part) || !grounded.has(on)) continue\n grounded.add(part)\n grew = true\n }\n }\n return grounded\n}\n\nfunction sectionViolation(part: PartSpec): StructuralViolation | null {\n if (part.material !== 'concrete' || part.shape.kind !== 'box') return null\n const role = part.structure?.role\n const [x, y, z] = part.shape.size\n if (role === 'column' && (Math.min(x, z) < MIN_PILLAR_SIDE - EPSILON || x * z < MIN_PILLAR_AREA - EPSILON))\n return { code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${x.toFixed(2)} x ${z.toFixed(2)} m: NBR 6118 asks at least ${MIN_PILLAR_SIDE} m a side` }\n if (role === 'beam' && Math.min(x, z) < MIN_BEAM_WIDTH - EPSILON && y >= Math.min(x, z))\n return { code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${Math.min(x, z).toFixed(2)} m wide: NBR 6118 asks at least ${MIN_BEAM_WIDTH} m` }\n return null\n}\n\n/** Every structural part of the spec reaches an anchored part over the joints that bear; every concrete pillar and beam has the NBR 6118 minimum section. */\nexport function specViolations(spec: DestructibleSpec): StructuralViolation[] {\n const byId = new Map(spec.parts.map((part) => [part.id, part]))\n const grounded = groundedOf(spec, byId)\n const out: StructuralViolation[] = []\n for (const part of spec.parts) {\n if (!carries(part)) continue\n if (!grounded.has(part.id)) {\n const pillar = part.structure!.role === 'column'\n out.push({ code: pillar ? STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED : STRUCTURAL_VIOLATION.FLOATING_PART, part: part.id, message: `${part.id} has no load path to an anchored part` })\n }\n const section = sectionViolation(part)\n if (section) out.push(section)\n }\n return out\n}\n","import type { DestructibleSpec } from '@adatechnology/game-contracts'\n\nimport { applyPanels } from '../wall-detail'\nimport type { SourceDoor, Structure, WallDetail } from '../types'\nimport { STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\nimport { concreteViolations, loadPathViolations } from './load-path'\nimport { isMasonryWall, masonryViolations } from './masonry'\nimport { openingViolations } from './openings'\nimport { specViolations } from './spec'\n\nexport interface ValidateStructureOptions {\n /** Detail the walls are built in for play (default `panels`, as the houses are): the lintels and sill beams of the windows come from it. */\n wallDetail?: WallDetail\n /** The doors of the plan (`plan.doors`): each door gap in a masonry wall needs a lintel. Without them only the windows are checked. */\n doors?: readonly SourceDoor[]\n}\n\n/**\n * What a structure gets wrong as a real building: load paths (every part down to the ground, every pillar on what carries it), reinforced concrete (NBR\n * 6118 sections, steel, beam depth) and, in masonry, confined masonry (ground beam, pillars at ends, corners, junctions and every 4 m up to the bond beam,\n * lintels and sill beams, bonded and plastered bricks). An empty list is a structure that a structural engineer would sign.\n */\nexport function validateStructure(structure: Structure, options: ValidateStructureOptions = {}): StructuralViolation[] {\n const detail = options.wallDetail ?? 'panels'\n const built = applyPanels({ parts: structure.parts, supports: structure.supports }, structure, detail)\n const out = [...loadPathViolations(structure), ...concreteViolations({ ...built, construction: structure.construction }, isMasonryWall)]\n if (structure.construction.system !== 'masonry') return out\n return [...out, ...masonryViolations(structure), ...openingViolations(structure, built.parts, options.doors ?? [])]\n}\n\n/** What a destructible spec built straight as one (towers, skyscrapers) gets wrong: load paths and concrete sections. */\nexport function validateSpec(spec: DestructibleSpec): StructuralViolation[] {\n return specViolations(spec)\n}\n\n/** The violations counted by code (for reports and tests). */\nexport function countViolations(violations: readonly StructuralViolation[]): Partial<Record<keyof typeof STRUCTURAL_VIOLATION, number>> {\n const out: Partial<Record<keyof typeof STRUCTURAL_VIOLATION, number>> = {}\n for (const violation of violations) out[violation.code] = (out[violation.code] ?? 0) + 1\n return out\n}\n\nexport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MAX_PILLAR_SPACING, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nexport type { StructuralViolation, StructuralViolationCode } from './codes'\n","import type { DestructibleSpec } from '@adatechnology/game-contracts'\nimport { assemblyDepth, assemblyPart, getAssembly } from '@adatechnology/game-destruction'\n\nimport { GROUND } from './types'\nimport { constructionOfSystem } from './presets'\nimport { CONSTRUCTION_SYSTEMS } from './registry'\nimport { toDestructibleSpec } from './to-destructible-spec'\nimport type { Opening, StructureSource, WallDetail } from './types'\n\nexport interface WallSpecimenOptions {\n /** Wall assembly of `game-destruction` (`brick_wall_plastered`, `concrete_block_wall`, `reinforced_concrete`, `drywall`, `wood_frame_wall`, `log_wall`, `sheet_metal_shack`...). */\n assembly: string\n /** Width and height in metres (the test area uses 2.4 x 2.1). */\n w: number\n h: number\n opening?: 'door' | 'window' | null\n /** Default `panels`: piers, lintel with its 0.2 m bearing, sill, plaster and rebar; `units` also lays the bricks, blocks or concrete panels one by one. */\n detail?: WallDetail\n}\n\nconst SYSTEM_OF_ASSEMBLY: Record<string, string> = { log_wall: 'log', wood_frame_wall: 'wood_frame', sheet_metal_shack: 'improvised' }\nconst DOOR_WIDTH = 0.9\nconst WINDOW_WIDTH = 1.0\n\nfunction openingOf(kind: 'door' | 'window', height: number): Opening {\n return kind === 'door'\n ? { id: 'door', kind, wall: 'wall_specimen', from: -DOOR_WIDTH / 2, to: DOOR_WIDTH / 2, y0: 0, y1: height * 0.8 }\n : { id: 'window', kind, wall: 'wall_specimen', from: -WINDOW_WIDTH / 2, to: WINDOW_WIDTH / 2, y0: height * 0.33, y1: height * 0.8 }\n}\n\n/**\n * A test wall as its assembly builds it, standing on a plinth: in `panels` the piers beside the opening, the lintel over it (reinforced concrete bearing 0.2 m on\n * the piers; a header in timber walls), the sill under a window and the wall above; with the plaster coat and the rebar of the assembly. The mass is the\n * assembly's for the whole w x h, whatever the detail.\n */\nexport function buildWallSpecimen(options: WallSpecimenOptions): DestructibleSpec {\n const { assembly, w, h, opening = null, detail = 'panels' } = options\n const def = getAssembly(assembly)\n if (!def) throw new Error(`unknown assembly \"${assembly}\"`)\n const system = SYSTEM_OF_ASSEMBLY[assembly] ?? 'masonry'\n const depth = assemblyDepth(def)\n const mass = assemblyPart(assembly, { id: 'wall_specimen', width: w, height: h, position: [0, h / 2, 0] }).mass ?? 1\n const construction = constructionOfSystem(system, { facade: {}, floors: [], rooms: [], walls: [], doors: [], items: [], w, d: depth } as StructureSource)!\n const joint = CONSTRUCTION_SYSTEMS.get(system)!.joints.wall\n const structure = {\n parts: [{ id: 'wall_specimen', role: 'wall' as const, material: def.core.material, aabb: [-w / 2, -depth / 2, w / 2, depth / 2] as [number, number, number, number], y0: 0, y1: h, floor: 0, mass, assembly }],\n supports: [{ part: 'wall_specimen', on: GROUND, joint }],\n openings: opening ? [openingOf(opening, h)] : [],\n levels: [0], elevation: 0, construction, framed: false,\n roof: { shape: 'slab' as const, covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n }\n return toDestructibleSpec(structure, { wallDetail: detail, sized: false, terrainMargin: 0.6, name: `wall_${assembly}` })\n}\n","import type { DestructibleSpec, JointSpec, PartSpec, Vec3, WindExposure } from '@adatechnology/game-contracts'\nimport { MATERIALS, buildFrame, partMass, sizeStructure } from '@adatechnology/game-destruction'\nimport type { FrameOptions, SizeStructureOptions, WindOptions } from '@adatechnology/game-destruction'\n\n/**\n * Building systems of a multi-storey building, as parts added to a frame spec: the rigid concrete core (shear-wall tube with the stairs and the\n * elevator shafts inside), the glass curtain wall hung from the slab edges, the flat roof (screed sloped to the drains and a waterproofing\n * membrane) and the mechanical floor under it (elevator machines, the water tank, chillers). Every number is an option with a real default; see the\n * design T10-estrutura-real.md §9.\n */\n\n/** The frame the systems are added to, in metres: what `buildFrame` was given. */\nexport interface TowerGeometry {\n floors: number\n /** Clear height of a storey (`buildFrame` `height`). */\n height: number\n /** Slab thickness. */\n slab: number\n spanX: number\n spanZ: number\n columnSize: number\n /** Columns along x and z (`buildFrame` `columnsX`, `columnsZ`; default 3 and 4, as `TOWER_DEFAULTS`). */\n columnsX?: number\n columnsZ?: number\n /** Depth of the beams (`buildFrame` `beamHeight`; default 0.6 m, as `TOWER_DEFAULTS`). */\n beamHeight?: number\n /** The top slab is a roof (`roof` id) instead of `slab_<floors-1>`. */\n roof: boolean\n}\n\nconst slabId = (g: TowerGeometry, f: number): string => (f === g.floors - 1 && g.roof ? 'roof' : `slab_${f}`)\n/** Bottom of storey `f` (top of the slab under it; storey 0 starts at the ground). */\nconst storeyBase = (g: TowerGeometry, f: number): number => f * (g.height + g.slab)\n/** Half sizes of the slabs (`buildFrame` makes them the span plus a column and 0.1 m each side). */\nconst slabHalf = (g: TowerGeometry): [number, number] => [(g.spanX + g.columnSize + 0.2) / 2, (g.spanZ + g.columnSize + 0.2) / 2]\n\nconst box = (size: Vec3) => ({ kind: 'box' as const, size })\nconst rests = (joints: JointSpec[], a: string, b: string, kind: JointSpec['kind'], bears: JointSpec['bears'] = 'a_on_b') => joints.push({ id: `${a}~${b}`, a, b, kind, bears })\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Rigid core\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface CoreOptions {\n /** Centre of the core in plan, object-local `[x, z]` (default `[0, 0]`). */\n center?: [number, number]\n /** Thickness of the outer walls of the tube (default 0.35 m: 30 to 60 cm in high-rise cores; at least h/25, NBR 6118 18.5 / EN 1992-1-1 9.6). */\n wallThickness?: number\n /** Thickness of the walls inside it, between the stair and the shafts and between shafts (default 0.2 m). */\n innerThickness?: number\n /** Elevator shafts (default 2), each `shaft` wide along z and `shaftDepth` deep along x. */\n elevators?: number\n shaft?: number\n shaftDepth?: number\n /** Stair compartment: width along x (two flights of 1.2 m side by side) and length along z (default 2.6 x 4.8 m, NBR 9077). */\n stairWidth?: number\n stairLength?: number\n /** Concrete of the walls (default `concrete`). */\n material?: string\n /** Rebar cage of the walls: bars of `diameter` every `spacing` (default 12.5 mm every 0.15 m: about 0.5% of the section, above the 0.2% of EN 1992-1-1 9.6.2). */\n rebar?: { spacing?: number; diameter?: number }\n /** Thickness of the mat foundation under the core when the frame has no raft (default 1.2 m). */\n matThickness?: number\n}\n\nexport const CORE_DEFAULTS = {\n wallThickness: 0.35, innerThickness: 0.2, elevators: 2, shaft: 2.2, shaftDepth: 2.4, stairWidth: 2.6, stairLength: 4.8, material: 'concrete',\n rebar: { spacing: 0.15, diameter: 0.0125 }, matThickness: 1.2,\n} as const\n\n/** Outer size of the core in plan, `[x, z]`, from its options: the stair compartment beside the row of shafts. */\nexport const coreSize = (o: CoreOptions = {}): [number, number] => {\n const c = { ...CORE_DEFAULTS, ...o }\n const shafts = c.elevators * c.shaft + Math.max(0, c.elevators - 1) * c.innerThickness\n return [2 * c.wallThickness + c.stairWidth + c.innerThickness + c.shaftDepth, 2 * c.wallThickness + Math.max(c.stairLength, shafts)]\n}\n\n/**\n * Adds the concrete core: four shear walls per storey forming a tube, the wall between the stair and the shafts and the walls between shafts, each\n * resting on the one below (continuous from the foundation to the roof) with its rebar cage, the slab of each storey resting on the tube, two\n * flights and a landing of stairs per storey inside, and an elevator car parked at the bottom of each shaft. Part ids: `core_<f>_<n|s|e|w|stair|shaft_k>`,\n * `stair_<f>_a|b`, `landing_<f>`, `elevator_<k>`, `core_mat`.\n */\nexport function addCore(spec: DestructibleSpec, g: TowerGeometry, options: CoreOptions = {}): DestructibleSpec {\n const c = { ...CORE_DEFAULTS, ...options, rebar: { ...CORE_DEFAULTS.rebar, ...options.rebar } }\n const [cx, cz] = options.center ?? [0, 0]\n const [W, L] = coreSize(options)\n const t = c.wallThickness, ti = c.innerThickness\n const x0 = cx - W / 2, z0 = cz - L / 2\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const reinforcement = { material: 'steel', spacing: c.rebar.spacing, diameter: c.rebar.diameter }\n const raft = parts.find((p) => p.id === 'raft')\n let base = raft?.id\n if (!base) {\n base = 'core_mat'\n parts.push({ id: base, material: c.material, shape: box([W + 1, c.matThickness, L + 1]), position: [cx, -c.matThickness / 2, cz], structure: { role: 'foundation' }, anchored: true })\n }\n const innerX = x0 + t + c.stairWidth + ti / 2\n for (let f = 0; f < g.floors; f++) {\n const yb = storeyBase(g, f), H = g.height\n const wall = (name: string, size: Vec3, pos: [number, number]) => {\n const id = `core_${f}_${name}`\n parts.push({ id, material: c.material, shape: box(size), position: [pos[0], yb + H / 2, pos[1]], structure: { role: 'wall' }, reinforcement, tags: ['core'] })\n rests(joints, id, f === 0 ? base! : `core_${f - 1}_${name}`, 'rebar')\n return id\n }\n const tube = [\n wall('w', [t, H, L], [x0 + t / 2, cz]),\n wall('e', [t, H, L], [x0 + W - t / 2, cz]),\n wall('n', [W - 2 * t, H, t], [cx, z0 + L - t / 2]),\n wall('s', [W - 2 * t, H, t], [cx, z0 + t / 2]),\n ]\n wall('stair', [ti, H, L - 2 * t], [innerX, cz])\n for (let k = 1; k < c.elevators; k++) {\n wall(`shaft_${k}`, [c.shaftDepth, H, ti], [innerX + ti / 2 + c.shaftDepth / 2, z0 + t + k * c.shaft + (k - 1) * ti + ti / 2])\n }\n for (const w of tube) rests(joints, slabId(g, f), w, 'rebar')\n // the stairs: two flights of half the storey each and the landing between them, cast into the walls of the tube\n const rise = (H + g.slab) / 2\n const flightWidth = (c.stairWidth - 0.2) / 2\n const landing = 1.2\n const run = c.stairLength - 2 * landing\n const angle = Math.atan2(rise, run)\n const length = Math.hypot(rise, run)\n const sx = x0 + t\n const landingId = `landing_${f}`\n parts.push({ id: landingId, material: c.material, shape: box([c.stairWidth, 0.15, landing]), position: [sx + c.stairWidth / 2, yb + rise - 0.075, z0 + t + c.stairLength - landing / 2], structure: { role: 'stair' }, tags: ['stair'] })\n rests(joints, landingId, `core_${f}_w`, 'rebar')\n rests(joints, landingId, `core_${f}_stair`, 'rebar')\n const zMid = z0 + t + landing + run / 2\n for (const [k, side] of [['a', 0], ['b', 1]] as const) {\n const id = `stair_${f}_${k}`\n const up = side === 0 ? 1 : -1\n parts.push({\n id, material: c.material, shape: box([flightWidth, 0.15, length]), position: [sx + flightWidth / 2 + side * (flightWidth + 0.2), yb + rise / 2 + side * rise, zMid],\n rotation: [up * angle * -1, 0, 0], structure: { role: 'stair' }, tags: ['stair'],\n })\n rests(joints, id, landingId, 'rebar')\n rests(joints, id, side === 0 ? `core_${f}_w` : `core_${f}_stair`, 'rebar')\n }\n }\n // a car at the bottom of each shaft (it hangs from its machine on the mechanical floor; parked, it rests on the pit)\n for (let k = 0; k < c.elevators; k++) {\n const id = `elevator_${k}`\n parts.push({\n id, material: 'steel', shape: box([c.shaftDepth - 0.6, 2.3, c.shaft - 0.6]), position: [innerX + ti / 2 + c.shaftDepth / 2, 1.15 + 0.05, z0 + t + k * (c.shaft + ti) + c.shaft / 2],\n fill: 0.03, mass: 1500, tags: ['elevator_car'],\n })\n rests(joints, id, base, 'resting', false)\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Curtain wall\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface CurtainWallOptions {\n /** Width of a panel (default 1.5 m). */\n panel?: number\n /** Glass of the panels (default `glass`: annealed or laminated glass that breaks in large shards; `tempered_glass` breaks in small cubes). */\n material?: string\n /** Glass thickness in metres: the two panes of an insulated unit (default 0.012, 6 + 6 mm). */\n thickness?: number\n /** Mass of the aluminium frame per m² of facade (default 10 kg/m²). */\n frameKgM2?: number\n /** Size of the pieces a broken panel falls in (default 0.6 m: a laminated pane breaks in large shards held by the interlayer). */\n shard?: number\n /** Gap from the slab edge to the glass (default 0.1 m). */\n offset?: number\n /** Storeys without glass (the mechanical floor has louvres): default none. */\n skip?: (floor: number) => boolean\n}\n\nexport const CURTAIN_DEFAULTS = { panel: 1.5, material: 'glass', thickness: 0.012, frameKgM2: 10, shard: 0.6, offset: 0.1 } as const\n\n/**\n * Adds a glass curtain wall around the frame: one panel per bay and storey, floor to floor, hung from the edge of the slab above it (`bolt`, carries\n * nothing: role none). In a blast the panels shatter into `shard`-sized pieces (`units`) that fall from the facade; a panel whose slab falls goes\n * with it. Part ids: `glass_<f>_<side>_<k>` with side `n`, `s`, `e`, `w`.\n */\nexport function addCurtainWall(spec: DestructibleSpec, g: TowerGeometry, options: CurtainWallOptions = {}): DestructibleSpec {\n const c = { ...CURTAIN_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const [hx, hz] = slabHalf(g)\n const h = g.height + g.slab\n const sides = [\n { name: 'n', along: 0, length: 2 * hx, fixed: hz + c.offset, axis: 2 },\n { name: 's', along: 0, length: 2 * hx, fixed: -hz - c.offset, axis: 2 },\n { name: 'e', along: 2, length: 2 * hz, fixed: hx + c.offset, axis: 0 },\n { name: 'w', along: 2, length: 2 * hz, fixed: -hx - c.offset, axis: 0 },\n ]\n for (let f = 0; f < g.floors; f++) {\n if (c.skip?.(f)) continue\n const yb = storeyBase(g, f)\n for (const s of sides) {\n const n = Math.max(1, Math.round(s.length / c.panel))\n const w = s.length / n\n for (let k = 0; k < n; k++) {\n const id = `glass_${f}_${s.name}_${k}`\n const at = -s.length / 2 + (k + 0.5) * w\n const size: Vec3 = s.axis === 2 ? [w - 0.01, h - 0.01, c.thickness] : [c.thickness, h - 0.01, w - 0.01]\n const position: Vec3 = s.axis === 2 ? [at, yb + h / 2, s.fixed] : [s.fixed, yb + h / 2, at]\n parts.push({\n id, material: c.material, shape: box(size), position, mass: (2500 * c.thickness + c.frameKgM2) * w * h, thickness: c.thickness,\n units: { size: [c.shard, c.shard, c.thickness], bond: 'stack', mortar: 'plastic' }, tags: ['curtain_wall', 'glass'],\n })\n rests(joints, id, slabId(g, f), 'bolt', false)\n }\n }\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Punched facade\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface PunchedFacadeOptions {\n /** Material of the infill wall (default `brick`: a masonry or block wall between the columns, as the residential towers are built). */\n material?: string\n /** Thickness of the wall in metres (default 0.2). */\n thickness?: number\n /** Width of the window as a share of the clear bay (default 0.6). */\n window?: number\n /** Sill and head of the window above the floor of the storey (default 0.9 and 2.4 m; the head is kept under the beam). */\n sill?: number\n head?: number\n /** Glass of the window and its thickness (default `glass`, 12 mm: an insulated unit). */\n glass?: string\n glassThickness?: number\n /** Storeys without infill (louvres on a mechanical floor): default none. */\n skip?: (floor: number) => boolean\n}\n\nexport const PUNCHED_DEFAULTS = { material: 'brick', thickness: 0.2, window: 0.6, sill: 0.9, head: 2.4, glass: 'glass', glassThickness: 0.012 } as const\n\n/**\n * Closes the perimeter bays of every storey with an infill wall that has a window in it (the alternative to the curtain wall): a sill wall under the\n * window, a wall over it and a pier at each side, all resting on the columns of the bay (role partition: they load the columns and carry nothing, as the\n * walls of `buildFrame`), and the glass in the opening, which rests on the sill and carries nothing. Part ids: `infill_<f>_<side>_<k>_sill|head|pl|pr`,\n * `glass_<f>_<side>_<k>` with side `n`, `s`, `e`, `w` (the same ids as the curtain wall, so the two exclude each other).\n */\nexport function addPunchedFacade(spec: DestructibleSpec, g: TowerGeometry, options: PunchedFacadeOptions = {}): DestructibleSpec {\n const c = { ...PUNCHED_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const nx = Math.max(2, g.columnsX ?? 3), nz = Math.max(2, g.columnsZ ?? 4)\n const xs = Array.from({ length: nx }, (_, i) => -g.spanX / 2 + (i * g.spanX) / (nx - 1))\n const zs = Array.from({ length: nz }, (_, j) => -g.spanZ / 2 + (j * g.spanZ) / (nz - 1))\n const beamUnder = g.beamHeight ?? TOWER_DEFAULTS.beamHeight\n for (let f = 0; f < g.floors; f++) {\n if (c.skip?.(f)) continue\n const yb = storeyBase(g, f)\n const room = g.height - beamUnder\n const head = Math.min(c.head, room - 0.3), sill = Math.min(c.sill, head - 0.6)\n const wall = (id: string, size: Vec3, position: Vec3, on: string[]) => {\n parts.push({ id, material: c.material, shape: box(size), position, structure: { role: 'partition' }, tags: ['infill'] })\n for (const o of on) rests(joints, id, o, 'mortar')\n }\n const bay = (side: string, k: number, along: 0 | 2, centre: number, fixed: number, length: number, c1: string, c2: string) => {\n const clear = length - g.columnSize\n const win = clear * c.window\n const pier = (clear - win) / 2\n const at = (u: number): Vec3 => (along === 0 ? [u, 0, fixed] : [fixed, 0, u])\n const size = (u: number, h: number): Vec3 => (along === 0 ? [u, h, c.thickness] : [c.thickness, h, u])\n const put = (name: string, u: number, h: number, y: number, centreU: number, on: string[]) => {\n const p = at(centreU)\n wall(`infill_${f}_${side}_${k}_${name}`, size(u, h), [p[0], y, p[2]], on)\n }\n const id = (name: string) => `infill_${f}_${side}_${k}_${name}`\n put('sill', clear, sill, yb + sill / 2, centre, [c1, c2])\n put('pl', pier, head - sill, yb + sill + (head - sill) / 2, centre - clear / 2 + pier / 2, [c1, id('sill')])\n put('pr', pier, head - sill, yb + sill + (head - sill) / 2, centre + clear / 2 - pier / 2, [c2, id('sill')])\n put('head', clear, room - head, yb + head + (room - head) / 2, centre, [c1, c2])\n const gp = at(centre)\n const gid = `glass_${f}_${side}_${k}`\n parts.push({\n id: gid, material: c.glass, shape: box(size(win - 0.01, head - sill)), position: [gp[0], yb + sill + (head - sill) / 2, gp[2]], thickness: c.glassThickness,\n units: { size: [0.6, 0.6, c.glassThickness], bond: 'stack', mortar: 'plastic' }, tags: ['window', 'glass'],\n })\n rests(joints, gid, id('sill'), 'glue', false)\n }\n for (const [side, j] of [['s', 0], ['n', nz - 1]] as const) {\n for (let i = 0; i < nx - 1; i++) bay(side, i, 0, (xs[i] + xs[i + 1]) / 2, zs[j], xs[i + 1] - xs[i], `column_${f}_${i}_${j}`, `column_${f}_${i + 1}_${j}`)\n }\n for (const [side, i] of [['w', 0], ['e', nx - 1]] as const) {\n for (let j = 0; j < nz - 1; j++) bay(side, j, 2, (zs[j] + zs[j + 1]) / 2, xs[i], zs[j + 1] - zs[j], `column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`)\n }\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Flat roof\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface FlatRoofOptions {\n /** Slope of the screed to the drains (default 0.01: 1%, the minimum of NBR 9575 for flat roofs). */\n slope?: number\n /** Screed thickness at the drains (default 0.02 m). */\n screedMin?: number\n /** Density of the screed (default 2000 kg/m³, cement and sand). */\n screedDensity?: number\n /** Membrane material and thickness (default `rubber` 1.5 mm: an EPDM sheet). */\n membrane?: string\n membraneThickness?: number\n /** Drains (default one per 150 m² of roof, at least 2, on the long centre line). */\n drains?: number\n /** Water standing on the membrane in metres (default 0.005: 5 mm of a storm on its way to the drains); set it in game with `setLiters`. */\n water?: number\n}\n\nexport const FLAT_ROOF_DEFAULTS = { slope: 0.01, screedMin: 0.02, screedDensity: 2000, membrane: 'rubber', membraneThickness: 0.0015, water: 0.005, areaPerDrain: 150 } as const\n\n/**\n * Turns the top slab into a flat roof: a screed sloped to the drains (its weight from the mean thickness `screedMin + slope * run / 2`), the\n * waterproofing membrane over it with the rain water on it (`contains` water, running down through a puncture: `outflow` [0, -1, 0], so a shot through\n * the membrane is a `leak` into the floor below) and the drains (tag `drain`). Screed and membrane load the roof slab (role partition: carried,\n * carry nothing). Part ids: `roof_screed`, `roof_membrane`, `roof_drain_<k>`.\n */\nexport function addFlatRoof(spec: DestructibleSpec, g: TowerGeometry, options: FlatRoofOptions = {}): DestructibleSpec {\n const c = { ...FLAT_ROOF_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const top = slabId(g, g.floors - 1)\n const slab = parts.find((p) => p.id === top)\n if (!slab || slab.shape.kind !== 'box') return spec\n const [sx, sy, sz] = slab.shape.size\n const area = sx * sz\n const longX = sx >= sz\n const count = c.drains ?? Math.max(2, Math.ceil(area / c.areaPerDrain))\n const long = longX ? sx : sz\n const spacing = long / count\n // the farthest point from a drain: half the spacing along the line and half the width across it\n const run = Math.hypot(spacing / 2, (longX ? sz : sx) / 2)\n const screed = c.screedMin + (c.slope * run) / 2\n const y = slab.position[1] + sy / 2\n parts.push({\n id: 'roof_screed', material: 'concrete', shape: box([sx, screed, sz]), position: [slab.position[0], y + screed / 2, slab.position[2]], mass: c.screedDensity * screed * area,\n structure: { role: 'partition' }, tags: ['roof_screed'],\n })\n rests(joints, 'roof_screed', top, 'mortar')\n const my = y + screed + c.membraneThickness / 2\n parts.push({\n id: 'roof_membrane', material: c.membrane, shape: box([sx, c.membraneThickness, sz]), position: [slab.position[0], my, slab.position[2]], thickness: c.membraneThickness,\n structure: { role: 'partition' }, contains: { fluid: 'water', liters: c.water * area * 1000, outflow: [0, -1, 0] }, tags: ['roof_membrane', 'waterproofing'],\n })\n rests(joints, 'roof_membrane', top, 'glue')\n for (let k = 0; k < count; k++) {\n const at = -long / 2 + (k + 0.5) * spacing\n const id = `roof_drain_${k}`\n parts.push({\n id, material: 'plastic', shape: { kind: 'cylinder', radius: 0.05, height: 0.1 }, position: longX ? [slab.position[0] + at, my, slab.position[2]] : [slab.position[0], my, slab.position[2] + at],\n fill: 0.2, tags: ['drain'],\n })\n rests(joints, id, top, 'glue', false)\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Mechanical floor\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface MechanicalFloorOptions {\n /** Elevator machines: one per elevator, over its shaft (default from the core; 2). */\n elevators?: number\n /** Where the shafts are, object-local `[x, z]` of each (default from the core layout). */\n shafts?: Array<[number, number]>\n /** Mass of a traction machine with its frame (default 2500 kg) and of what hangs from it: car, counterweight, rated load (default 1500 + 2000 + 1000 kg). */\n machineMass?: number\n suspendedMass?: number\n /** Water tank in litres (default: `occupants` per storey x 200 L a day x 40% stored up high, NBR 5626, plus a fire reserve of 6000 L, NBR 13714). */\n waterLiters?: number\n occupants?: number\n fireReserve?: number\n /** Chillers on the floor (default 2 of 3500 kg). */\n chillers?: number\n chillerMass?: number\n /** Material and wall thickness of the tank (default `plastic` 10 mm: a fibreglass or polyethylene reservoir). */\n tankMaterial?: string\n tankWall?: number\n /** Where the tank goes, `[x, z]` (default the middle of the bay at -x, away from the core). */\n tankAt?: [number, number]\n /**\n * Storey the equipment stands on (default the top one, under the roof). On any other storey the part ids end in `_<floor>` (`water_tank_20`,\n * `chiller_0_20`), so a tower can carry a mechanical floor every few storeys (design T10 §11).\n */\n floor?: number\n}\n\nexport const MECHANICAL_DEFAULTS = { tankMaterial: 'plastic', tankWall: 0.01, machineMass: 2500, suspendedMass: 4500, occupants: 16, litersPerPerson: 200, storedFraction: 0.4, fireReserve: 6000, chillers: 2, chillerMass: 3500 } as const\n\n/** Litres of the water tank of a building of `storeys` occupied storeys (NBR 5626 consumption, the fire reserve of NBR 13714). */\nexport const towerWater = (storeys: number, o: Pick<MechanicalFloorOptions, 'occupants' | 'fireReserve'> = {}): number =>\n Math.round((o.occupants ?? MECHANICAL_DEFAULTS.occupants) * MECHANICAL_DEFAULTS.litersPerPerson * MECHANICAL_DEFAULTS.storedFraction * storeys + (o.fireReserve ?? MECHANICAL_DEFAULTS.fireReserve))\n\n/**\n * Makes the top storey the mechanical floor: the elevator machines over the shafts, the water tank (with its water: `contains`, a shot makes it leak)\n * and the chillers, on the slab under the roof (role partition: their weight goes into the structure). Part ids: `machine_<k>`, `water_tank`,\n * `chiller_<k>`.\n */\nexport function addMechanicalFloor(spec: DestructibleSpec, g: TowerGeometry, options: MechanicalFloorOptions = {}): DestructibleSpec {\n const c = { ...MECHANICAL_DEFAULTS, ...options }\n if (g.floors < 2) return spec\n const level = options.floor ?? g.floors - 1\n if (level < 1 || level > g.floors - 1) return spec\n const sfx = level === g.floors - 1 ? '' : `_${level}`\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const floor = `slab_${level - 1}`\n const y = storeyBase(g, level)\n const shafts = options.shafts ?? []\n const put = (id: string, material: string, size: Vec3, at: [number, number], mass: number, extra: Partial<PartSpec> = {}) => {\n parts.push({ id: id + sfx, material, shape: box(size), position: [at[0], y + size[1] / 2, at[1]], mass, fill: 0.2, structure: { role: 'partition' }, tags: ['mechanical'], ...extra })\n rests(joints, id + sfx, floor, 'bolt')\n }\n shafts.forEach((at, k) => put(`machine_${k}`, 'steel', [1.2, 1.0, 0.8], at, c.machineMass + c.suspendedMass, { tags: ['mechanical', 'elevator_machine'] }))\n const liters = options.waterLiters ?? towerWater(level, options)\n const depth = 2\n const side = Math.sqrt(liters / 1000 / depth)\n const [hx] = slabHalf(g)\n const tankAt = options.tankAt ?? [-hx / 2, 0]\n const shell = 4 * side * depth + 2 * side * side\n put('water_tank', c.tankMaterial, [side, depth, side], tankAt, liters + 1100 * c.tankWall * shell, {\n fill: (shell * c.tankWall) / (side * side * depth), thickness: c.tankWall, contains: { fluid: 'water', liters }, tags: ['mechanical', 'water_tank'],\n })\n for (let k = 0; k < c.chillers; k++) put(`chiller_${k}`, 'steel', [3, 2, 1.5], [-hx + 2 + k * 3.5, -(slabHalf(g)[1] - 2)], c.chillerMass, { tags: ['mechanical', 'chiller'] })\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Tuned mass damper\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface DamperOptions {\n /** Mass of the damper in kg (default: `ratio` of the modal mass of the building, estimated as `modalShare` of its mass). */\n mass?: number\n /** Mass ratio, damper over the modal mass of the building (default 0.01: 0.5 to 2% is the usual range). */\n ratio?: number\n /** Share of the building's mass that is its modal mass in the first mode, tip at 1 (default 0.25, a uniform cantilever). */\n modalShare?: number\n /** Frequency in Hz and damping ratio of the damper (default: tuned by the world to the building, `wind.tuning`). */\n frequency?: number\n damping?: number\n /** Where it stands on the mechanical floor, object-local `[x, z]` (default on the beam end beside the column nearest to 35% of the depth at +z, clear of the machines: its weight goes straight to the beam and the column). */\n at?: [number, number]\n /** Material of the mass (default `steel`; the real ones are steel or lead-filled blocks and concrete). */\n material?: string\n /** Tallest the block may be, metres (default 2.5: it stands inside the mechanical floor). */\n maxHeight?: number\n}\n\nexport const DAMPER_DEFAULTS = { ratio: 0.01, modalShare: 0.25, material: 'steel', maxHeight: 2.5 } as const\n\n/** Mass in kg of a damper for a structure: `ratio` of `modalShare` of the mass of everything above the foundations (curtain wall, roof and equipment included). */\nexport const damperMass = (spec: DestructibleSpec, o: Pick<DamperOptions, 'ratio' | 'modalShare'> = {}): number => {\n const byId = new Map(MATERIALS.map((m) => [m.id, m]))\n let total = 0\n for (const p of spec.parts) {\n const m = byId.get(p.material)\n if (!m || p.structure?.role === 'foundation' || p.damper) continue\n total += partMass(p, m)\n }\n return total * (o.modalShare ?? DAMPER_DEFAULTS.modalShare) * (o.ratio ?? DAMPER_DEFAULTS.ratio)\n}\n\n/**\n * Adds a tuned mass damper to the mechanical floor: a block of `material` on the slab under the roof (role partition: its mass loads the slab and\n * goes down to the core and the columns like the machines), with `PartSpec.damper` so the world tunes it to the building and moves it against the\n * sway (Den Hartog). Part id: `damper`.\n */\nexport function addTunedMassDamper(spec: DestructibleSpec, g: TowerGeometry, options: DamperOptions = {}): DestructibleSpec {\n const c = { ...DAMPER_DEFAULTS, ...options }\n if (g.floors < 2) return spec\n const mat = MATERIALS.find((m) => m.id === c.material)\n if (!mat) throw new Error(`unknown material \"${c.material}\" for the damper`)\n const mass = options.mass ?? damperMass(spec, c)\n const volume = mass / mat.density\n const height = Math.min(c.maxHeight, Math.cbrt(volume))\n const side = Math.sqrt(volume / height)\n const column = (span: number, n: number | undefined, want: number) => {\n const k = Math.max(2, n ?? 0) - 1\n return n === undefined ? want : Math.round((want + span / 2) / (span / k)) * (span / k) - span / 2\n }\n const colZ = column(g.spanZ, g.columnsZ, g.spanZ * 0.35)\n // on the beam end beside the column, so the slab hands its weight straight to the beam, which hands it to the column\n const at = options.at ?? [column(g.spanX, g.columnsX, 0), colZ - Math.sign(colZ || 1) * (g.columnSize / 2 + 0.1)]\n const y = storeyBase(g, g.floors - 1)\n const floor = `slab_${g.floors - 2}`\n const part: PartSpec = {\n id: 'damper', material: c.material, shape: box([side, height, side]), position: [at[0], y + height / 2, at[1]], mass, structure: { role: 'partition' }, tags: ['mechanical', 'tuned_mass_damper'],\n damper: { ...(c.frequency !== undefined ? { frequency: c.frequency } : {}), ...(c.damping !== undefined ? { damping: c.damping } : {}) },\n }\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n rests(joints, part.id, floor, 'bolt')\n return { ...spec, parts: [...spec.parts, part], joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Tower\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface TowerMechanicalOptions {\n /**\n * Another mechanical floor every this many storeys (design T10 §11): storeys `every`, `2 * every`... below the top one, each with its own\n * relay water tank for the storeys it serves and its chillers, and without glass. Default none: only the top storey.\n */\n every?: number\n}\n\n/** Indices of the intermediate mechanical storeys of a tower of `floors` storeys with one every `every` (none below `every / 2` storeys of the top one). */\nexport const mechanicalStoreys = (floors: number, every?: number): number[] => {\n if (!every || every < 2) return []\n const out: number[] = []\n for (let k = every; k < floors - 1; k += every) if (floors - 1 - k >= every / 2) out.push(k)\n return out\n}\n\nexport interface TowerOptions extends Omit<FrameOptions, 'walls' | 'roof' | 'continuousColumns'> {\n /** The core (default on); `false` for a frame alone. */\n core?: CoreOptions | false\n /** The curtain wall (default on, without glass on the mechanical floor). */\n facade?: CurtainWallOptions | false\n /** A punched facade (infill walls with windows) instead of the curtain wall: turn the curtain wall off (`facade: false`) when you use it. Default off. */\n punched?: PunchedFacadeOptions | false\n /** The flat roof (default on). */\n flatRoof?: FlatRoofOptions | false\n /** The mechanical floor under the roof (default on). */\n mechanical?: (MechanicalFloorOptions & TowerMechanicalOptions) | false\n /** A tuned mass damper on the mechanical floor (default off: `{}` adds one of 1% of the modal mass). */\n damper?: DamperOptions | false\n /**\n * The wind the tower is made for (default none: the tower is sized for its weight only). Its `speed`, `terrain`, `class`... size the walls, columns\n * and core bars for the wind (`sizeStructure({ wind })`), and the fields of `WindExposure` (terrain, class, topography, statistical, drag, damping)\n * go into `DestructibleSpec.wind`, where the building stands. The world still needs its own `wind` for the wind to blow.\n */\n wind?: WindOptions | false\n /** Size the structure (`sizeStructure`, default `{}`); `false` keeps the material capacities. */\n sizing?: SizeStructureOptions | false\n}\n\n/** The fields of the wind options that describe the place and the shape of one building (`DestructibleSpec.wind`). */\nexport const windExposureOf = (w: WindOptions): WindExposure => {\n const out: WindExposure = {}\n if (w.terrain !== undefined) out.terrain = w.terrain\n if (w.class !== undefined) out.class = w.class\n if (w.topography !== undefined) out.topography = w.topography\n if (w.statistical !== undefined) out.statistical = w.statistical\n if (w.drag !== undefined) out.drag = w.drag\n if (w.damping !== undefined) out.damping = w.damping\n return out\n}\n\n/** Defaults of the frame of a tower: 16 x 24 m on a 8 m grid, 12 storeys of 3 m, 60 cm columns caged with 20 mm bars, 60 cm beams, continuous columns. */\nexport const TOWER_DEFAULTS = {\n spanX: 16, spanZ: 24, columnsX: 3, columnsZ: 4, floors: 12, height: 3, columnSize: 0.6, beamHeight: 0.6, slabThickness: 0.2,\n columnCage: { material: 'steel', spacing: 0.15, diameter: 0.02 },\n} as const\n\n/**\n * A multi-storey building with real structure: a frame with continuous columns, the concrete core in the bay at +x of the centre, the curtain wall,\n * the flat roof and the mechanical floor, sized as a designer would. Every system can be turned off or configured.\n */\nexport function buildTower(options: TowerOptions = {}): DestructibleSpec {\n const { core, facade, punched, flatRoof, mechanical, damper, wind, sizing, ...frame } = options\n const f = { ...TOWER_DEFAULTS, ...frame, columnCage: { ...TOWER_DEFAULTS.columnCage, ...frame.columnCage } }\n const g: TowerGeometry = { floors: f.floors, height: f.height, slab: f.slabThickness, spanX: f.spanX, spanZ: f.spanZ, columnSize: f.columnSize, columnsX: f.columnsX, columnsZ: f.columnsZ, beamHeight: f.beamHeight, roof: true }\n const { every, ...mech } = mechanical || {}\n const relays = mechanical === false ? [] : mechanicalStoreys(f.floors, every)\n const noGlass = (fl: number) => mechanical !== false && (fl === g.floors - 1 || relays.includes(fl))\n let spec = buildFrame({ roofThickness: f.slabThickness, ...f, roof: true, continuousColumns: true })\n spec = { ...spec, name: 'tower', tags: ['structure', 'tower'] }\n let shafts: Array<[number, number]> = []\n if (core !== false) {\n const bayX = f.spanX / (Math.max(2, f.columnsX) - 1)\n const center = core?.center ?? [bayX / 2, 0]\n spec = addCore(spec, g, { ...core, center })\n const c = { ...CORE_DEFAULTS, ...core }\n const [W, L] = coreSize(core || {})\n const sx = center[0] - W / 2 + c.wallThickness + c.stairWidth + c.innerThickness + c.shaftDepth / 2\n shafts = Array.from({ length: c.elevators }, (_, k) => [sx, center[1] - L / 2 + c.wallThickness + k * (c.shaft + c.innerThickness) + c.shaft / 2] as [number, number])\n }\n if (facade !== false && !punched) spec = addCurtainWall(spec, g, { skip: noGlass, ...facade })\n if (punched) spec = addPunchedFacade(spec, g, { skip: noGlass, ...punched })\n if (flatRoof !== false) spec = addFlatRoof(spec, g, flatRoof || {})\n if (mechanical !== false) {\n spec = addMechanicalFloor(spec, g, { shafts, ...mech })\n // the intermediate floors hold the plant of the zone below them: no elevator machines (they are on the top floor), a relay tank and the chillers\n for (const floor of relays) spec = addMechanicalFloor(spec, g, { ...mech, shafts: [], floor, waterLiters: mech.waterLiters ?? towerWater(every ?? floor, mech) })\n }\n if (damper) spec = addTunedMassDamper(spec, g, damper)\n if (wind) {\n const exposure = windExposureOf(wind)\n if (Object.keys(exposure).length) spec = { ...spec, wind: exposure }\n }\n if (sizing === false) return spec\n return sizeStructure(spec, wind && sizing?.wind === undefined ? { ...sizing, wind } : sizing ?? {})\n}\n","import type { DestructibleSpec, PartSpec, PileSpec, SoilProfile } from '@adatechnology/game-contracts'\nimport { GRAVITY, MATERIALS, SOILS, createDestruction, partMass, pileLength, profileOf } from '@adatechnology/game-destruction'\nimport type { SizeStructureOptions, WindOptions } from '@adatechnology/game-destruction'\n\nimport {\n CORE_DEFAULTS, TOWER_DEFAULTS, buildTower, coreSize, mechanicalStoreys,\n} from './tower'\nimport type { CoreOptions, CurtainWallOptions, DamperOptions, FlatRoofOptions, MechanicalFloorOptions, PunchedFacadeOptions, TowerMechanicalOptions, TowerOptions } from './tower'\n\n/**\n * The skyscraper as a recipe: a few numbers (storeys, bay, core ratio, facade, mechanical floors, damper, wind, soil and piles) that `skyscraperLayout`\n * turns into the sizes of a `buildTower` and `buildSkyscraper` turns into a destructible spec on deep piles. The typologies that use it\n * (`game-floorplan-commercial` office tower, `game-floorplan-residential` residential tower) bring their own defaults and the rooms of the plan; the\n * structure is the same one. Design T10-estrutura-real.md §11.\n */\n\n/** Deep foundation of a tower: bored piles under the raft, taken down to firm ground (`pileLength`) by the load each one carries. */\nexport interface PileDesign {\n /** Diameter in metres (default 1.2: the bored piles of high-rise foundations are 0.8 to 2.0 m). */\n diameter?: number\n /** Grid pitch as a multiple of the diameter (default 3.5; the usual minimum is 2.5 to 3). */\n pitch?: number\n method?: PileSpec['method']\n /** Longest pile in metres (default 60); when the load does not fit, the piles are put closer. */\n maxLength?: number\n /** Fixed length and count (default: from the load and the soil). */\n length?: number\n count?: number\n}\n\nexport const PILE_DEFAULTS = { diameter: 1.2, pitch: 3.5, method: 'bored', maxLength: 60 } as const\n\n/**\n * Most storeys a skyscraper has by default (owner decision 2026-10-25): above about 60 the drift at the top passes H/500, because the engine has no outrigger\n * or perimeter tube. A default, not a physical constant: `SkyscraperOptions.range` (or a preset with another `range`) raises it.\n */\nexport const SKYSCRAPER_MAX_STOREYS = 60\n\n/** Numbers that describe one typology of skyscraper. Every one is an option of `skyscraperLayout`. */\nexport interface SkyscraperPreset {\n /** Storeys: the default and the range the typology accepts (the top storey is the mechanical floor). */\n storeys: number\n range: readonly [number, number]\n /** Clear height of a storey in metres (the storey pitch is this plus the slab). */\n height: number\n /** Column spacing in metres along x and z. */\n bay: readonly [number, number]\n /** Bays along x and z (z always odd: the core stands in the middle bay, between two rows of beams). */\n bays: readonly [number, number]\n /** Tallest the tower may be over its narrowest side (default 9: Taipei 101 is 8.3, the Burj Khalifa 8); the bays are widened to keep it. `false` leaves them as given. */\n slenderness: number | false\n /** Target share of the floor plate taken by the concrete core (tube footprint over plate); the number of elevators follows, as far as the bay allows. */\n coreRatio: number\n facade: 'curtain' | 'punched'\n /** Another mechanical floor every this many storeys; `false` none (only the top one). */\n mechanicalEvery: number | false\n /** Total height in metres from which a tuned mass damper is added on the top mechanical floor; `false` never. */\n damperAbove: number | false\n /** The wind the tower is designed for (`buildTower({ wind })`). */\n wind: WindOptions | false\n /** The ground: a soil class id or a profile of layers; `false` leaves the tower on anchored ground. */\n soil: string | SoilProfile | false\n /** Deep piles under the raft (only with `soil`); `false` leaves a shallow raft. */\n piles: PileDesign | false\n /**\n * Sizes the lateral system by height (default on): a tower taller than `above` metres whose design drift at the requested storeys is over the limit of\n * the wind (`driftLimit`, default H/500: NBR 6118 serviceability) gets wider bays, and with them a larger plate and core, in steps of 0.5 m up to `maxBay`\n * until it passes. `false` keeps the layout as given (and then a 60-storey tower is `drift`).\n */\n sizeForWind?: boolean | { above?: number; maxBay?: number }\n /** Dead load per m² of floor besides the slab itself, kg/m² (facade, partitions, finishes, equipment), used to size the columns. */\n superimposed: number\n}\n\n/** Defaults of a generic skyscraper: a 40-storey tower on 12 m bays with a curtain wall, a plant floor every 20 storeys, a damper above 150 m, in a city wind, on piles to the sand under soft clay. */\nexport const SKYSCRAPER_DEFAULTS: SkyscraperPreset = {\n storeys: 40,\n range: [20, SKYSCRAPER_MAX_STOREYS],\n height: 3.6,\n bay: [12, 12],\n bays: [3, 3],\n slenderness: 9,\n coreRatio: 0.08,\n facade: 'curtain',\n mechanicalEvery: 20,\n damperAbove: 150,\n wind: { speed: 40, terrain: 'IV' },\n soil: { layers: [{ soil: 'clay_soft', thickness: 10 }, { soil: 'sand_dense' }] },\n piles: {},\n superimposed: 450,\n}\n\nexport interface SkyscraperOptions extends Partial<Omit<SkyscraperPreset, 'bay' | 'bays'>> {\n bay?: number | readonly [number, number]\n bays?: readonly [number, number]\n /** Sizes derived from the load and the height unless given: columns, beam depth and slab thickness in metres. */\n columnSize?: number\n beamHeight?: number\n slabThickness?: number\n /** The core (`false`: a frame alone); `wallThickness` and `elevators` are derived unless given. */\n core?: CoreOptions | false\n curtain?: CurtainWallOptions\n punchedFacade?: PunchedFacadeOptions\n flatRoof?: FlatRoofOptions | false\n mechanical?: (MechanicalFloorOptions & TowerMechanicalOptions) | false\n damper?: DamperOptions\n sizing?: SizeStructureOptions | false\n}\n\nexport interface SkyscraperLayout {\n storeys: number\n /** Clear height, slab and storey pitch in metres. */\n height: number\n slab: number\n pitch: number\n /** Height from the ground to the roof. */\n total: number\n bay: [number, number]\n /** Distance between the outer column axes. */\n span: [number, number]\n columnsX: number\n columnsZ: number\n columnSize: number\n beamHeight: number\n /** Size of the floor slab, `[x, z]`, centred on the origin of the spec. */\n plate: [number, number]\n core: { center: [number, number]; size: [number, number]; wallThickness: number; elevators: number; stairWidth: number; shaftDepth: number } | null\n /** Footprint of the core over the plate. */\n coreRatio: number\n facade: 'curtain' | 'punched'\n /** Storeys with plant (the intermediate ones and the top one), ascending. */\n mechanical: number[]\n damper: boolean\n /** The options `buildTower` is called with. */\n tower: TowerOptions\n}\n\nconst ceilTo = (v: number, step: number): number => Math.ceil(v / step - 1e-9) * step\nconst round2 = (v: number): number => Math.round(v * 100) / 100\n/** Bearing stress used to size columns: 0.85 fck of a C25 concrete, in kg/m² (the cage steel is the margin), with the 0.65 utilisation of the sizing. */\nconst COLUMN_KG_M2 = (0.85 * 25e6) / GRAVITY * 0.65\n/** Share of the gravity load the columns carry; the core and its walls take the rest. */\nconst COLUMN_SHARE = 0.5\n/** Clear space kept between the core and the columns and beams around it, metres. */\nconst CORE_CLEARANCE = 0.4\n/** A core wall is as thick as the total height over this, in metres per metre (40 cm at 80 m, 1.55 m at 312 m; real cores run 30 cm to 1.5 m). */\nconst WALL_SLENDER = 200\n\n/** Sizing by wind below this height (metres) is skipped: every tower up to 40 storeys passes H/500 as laid out. */\nexport const WIND_SIZING_DEFAULTS = { above: 180, maxBay: 20 } as const\n\nconst sizedCache = new Map<string, SkyscraperLayout>()\n\n/** The design drift (deflection over height) of the tower of a layout, in the wind it is designed for. */\nconst driftOf = (layout: SkyscraperLayout, wind: WindOptions): number => {\n const w = createDestruction({ wind })\n return w.state(w.add(buildTower(layout.tower)))?.wind?.drift ?? 0\n}\n\n/**\n * Resolves the numbers of a skyscraper from a preset and the options. Without `sizeForWind: false`, a tall tower that would drift past H/500 gets wider\n * bays (so a larger plate and core) until it does not: the way real towers thicken the core and widen the footprint with height. Memoised, because it\n * builds the tower to measure it.\n */\nexport function skyscraperLayout(options: SkyscraperOptions = {}, preset: SkyscraperPreset = SKYSCRAPER_DEFAULTS): SkyscraperLayout {\n const raw = rawLayout(options, preset)\n const o = { ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset & SkyscraperOptions\n const cfg = { ...WIND_SIZING_DEFAULTS, ...(typeof o.sizeForWind === 'object' ? o.sizeForWind : {}) }\n if (o.sizeForWind === false || !o.wind || o.core === false || raw.total < cfg.above) return raw\n const key = JSON.stringify([options, preset])\n const hit = sizedCache.get(key)\n if (hit) return hit\n const limit = o.wind.driftLimit ?? 1 / 500\n let layout = raw\n for (let i = 0; i < 6; i++) {\n const drift = driftOf(layout, o.wind)\n const widest = Math.max(...layout.bay)\n if (drift <= limit || widest >= cfg.maxBay) break\n // drift falls about with the cube of the bay (the plate, the core and the lever arm grow together)\n const k = Math.max(1.02, Math.pow(drift / limit, 1 / 3) * 1.02)\n const bay = layout.bay.map((b) => Math.min(cfg.maxBay, round2(ceilTo(b * k, 0.5)))) as [number, number]\n layout = rawLayout({ ...options, bay }, preset)\n }\n sizedCache.set(key, layout)\n return layout\n}\n\nfunction rawLayout(options: SkyscraperOptions, preset: SkyscraperPreset): SkyscraperLayout {\n const o = { ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset & SkyscraperOptions\n const range = o.range\n const storeys = Math.max(range[0], Math.min(range[1], Math.round(o.storeys)))\n const given: [number, number] = typeof o.bay === 'number' ? [o.bay, o.bay] : [o.bay[0], o.bay[1]]\n const oddZ = (n: number) => (Math.round(n) % 2 === 1 ? Math.round(n) : Math.round(n) + 1)\n const bays: [number, number] = [Math.max(1, Math.round(o.bays[0])), oddZ(Math.max(1, o.bays[1]))]\n const slabOf = (b: number) => Math.max(TOWER_DEFAULTS.slabThickness, round2(ceilTo(b / 32, 0.05)))\n // too slender for its plate: the bays grow until the narrowest side is a ninth of the height (the slab, and so the height, follow the bay)\n let bay: [number, number] = given\n for (let i = 0; i < 4 && o.slenderness !== false; i++) {\n const total = storeys * (o.height + (o.slabThickness ?? slabOf(Math.max(...bay))))\n const narrow = Math.min(bays[0] * bay[0], bays[1] * bay[1])\n if (narrow >= total / o.slenderness) break\n const k = total / o.slenderness / narrow\n bay = [round2(ceilTo(bay[0] * k, 0.5)), round2(ceilTo(bay[1] * k, 0.5))]\n }\n const span: [number, number] = [bays[0] * bay[0], bays[1] * bay[1]]\n const slab = o.slabThickness ?? slabOf(Math.max(...bay))\n const beamHeight = o.beamHeight ?? Math.max(TOWER_DEFAULTS.beamHeight, round2(ceilTo(Math.max(...bay) / 14, 0.1)))\n const pitch = o.height + slab\n const total = storeys * pitch\n const tributary = bay[0] * bay[1]\n const load = COLUMN_SHARE * tributary * storeys * (o.superimposed + slab * 2500)\n const columnSize = o.columnSize ?? Math.max(TOWER_DEFAULTS.columnSize, round2(ceilTo(Math.sqrt(load / COLUMN_KG_M2), 0.1)))\n const plate: [number, number] = [round2(span[0] + columnSize + 0.2), round2(span[1] + columnSize + 0.2)]\n const mech = o.mechanicalEvery === false ? undefined : o.mechanicalEvery\n const relays = o.mechanical === false ? [] : mechanicalStoreys(storeys, o.mechanical === undefined ? mech : o.mechanical.every ?? mech)\n const mechanical = o.mechanical === false ? [] : [...relays, storeys - 1]\n\n let coreLayout: SkyscraperLayout['core'] = null\n let coreOptions: CoreOptions | false = false\n if (o.core !== false) {\n const given = o.core ?? {}\n // a wall thicker than a third of its height is a block, not a plate, to the engine: it would hold no vertical bars (and no pull)\n const maxWall = Math.floor((o.height / 3 - 0.05) * 20) / 20\n const wallThickness = given.wallThickness ?? Math.max(CORE_DEFAULTS.wallThickness, Math.min(maxWall, round2(ceilTo(total / WALL_SLENDER, 0.05))))\n const ti = given.innerThickness ?? CORE_DEFAULTS.innerThickness\n const shaft = given.shaft ?? CORE_DEFAULTS.shaft\n // the most elevators whose row of shafts fits between the beams on each side of the middle bay\n const fit = Math.max(1, Math.floor((bay[1] - 2 * CORE_CLEARANCE - 0.2 - 2 * wallThickness + ti) / (shaft + ti)))\n const probe = coreSize({ ...given, wallThickness, elevators: 2 })\n const wanted = given.elevators ?? Math.max(2, Math.ceil((o.coreRatio * plate[0] * plate[1] / probe[0] - 2 * wallThickness + ti) / (shaft + ti)))\n const elevators = Math.max(1, Math.min(wanted, fit))\n // what the ratio asks beyond the elevators the bay holds goes into the width: deeper cars and service space beside the shafts, as far as the bay allows\n const narrow = coreSize({ ...given, wallThickness, elevators })\n const room = bay[0] - columnSize - 2 * CORE_CLEARANCE - narrow[0]\n const extra = given.shaftDepth !== undefined ? 0 : Math.max(0, Math.min(room, (o.coreRatio * plate[0] * plate[1]) / narrow[1] - narrow[0]))\n // the middle bay in z has no row of columns; in x the core stands in the middle bay too, or in the first half bay when the count is even\n const xs = Array.from({ length: bays[0] + 1 }, (_, i) => -span[0] / 2 + i * bay[0])\n const middle = Math.floor(bays[0] / 2)\n const center: [number, number] = given.center ?? [bays[0] % 2 === 1 ? (xs[middle] + xs[middle + 1]) / 2 : xs[middle] + bay[0] / 2, 0]\n // a high-rise core is caged tighter than a house wall: 10 cm between bars, 7.5 cm above 50 storeys (the pull at the top of a tall core needs the steel)\n const rebar = { spacing: storeys > 50 ? 0.075 : 0.1, ...given.rebar }\n coreOptions = { ...given, wallThickness, elevators, center, rebar, shaftDepth: (given.shaftDepth ?? CORE_DEFAULTS.shaftDepth) + round2(extra) }\n const size = coreSize(coreOptions)\n coreLayout = { center, size, wallThickness, elevators, stairWidth: given.stairWidth ?? CORE_DEFAULTS.stairWidth, shaftDepth: coreOptions.shaftDepth! }\n }\n const damperOn = o.damperAbove !== false && total >= o.damperAbove && o.mechanical !== false\n const tower: TowerOptions = {\n floors: storeys, height: o.height, spanX: span[0], spanZ: span[1], columnsX: bays[0] + 1, columnsZ: bays[1] + 1, columnSize, beamHeight, slabThickness: slab,\n roofThickness: round2(slab + 0.1), columnCage: { ...TOWER_DEFAULTS.columnCage }, core: coreOptions,\n facade: o.facade === 'curtain' ? (o.curtain ?? {}) : false, punched: o.facade === 'punched' ? (o.punchedFacade ?? {}) : false,\n flatRoof: o.flatRoof ?? {}, mechanical: o.mechanical === false ? false : { every: o.mechanicalEvery === false ? undefined : mech, ...o.mechanical },\n damper: damperOn ? (o.damper ?? {}) : false, wind: o.wind === false ? false : o.wind, sizing: o.sizing ?? {},\n raft: true,\n }\n return {\n storeys, height: o.height, slab, pitch, total, bay, span, columnsX: bays[0] + 1, columnsZ: bays[1] + 1, columnSize, beamHeight, plate, core: coreLayout,\n coreRatio: coreLayout ? (coreLayout.size[0] * coreLayout.size[1]) / (plate[0] * plate[1]) : 0, facade: o.facade, mechanical, damper: damperOn, tower,\n }\n}\n\n/** Mass in kg of everything above the raft's top face in a spec, plus the raft itself. */\nconst totalMass = (spec: DestructibleSpec): number => {\n const byId = new Map(MATERIALS.map((m) => [m.id, m]))\n return spec.parts.reduce((sum, part) => sum + (part.mass ?? partMass(part, byId.get(part.material)!)), 0)\n}\n\n/**\n * Piles under the raft, by the load: a grid of `pitch` diameters over the raft, each as long as it needs to carry its share of the tower with the\n * NBR 6122 safety (`pileLength`); when that is longer than `maxLength` the grid is closed up and tried again, down to a pitch of 2.5 diameters.\n */\nexport function pilesFor(spec: DestructibleSpec, soil: string | SoilProfile, design: PileDesign = {}): PileSpec {\n const raft = spec.parts.find((p) => p.id === 'raft')\n if (!raft || raft.shape.kind !== 'box') throw new Error('Piles go under a raft: the spec has none')\n const d = { ...PILE_DEFAULTS, ...design }\n const [sx, sy, sz] = raft.shape.size\n const profile = profileOf(soil)\n const soils = new Map(SOILS.map((s) => [s.id, s]))\n const weight = totalMass(spec) * GRAVITY\n if (design.length !== undefined || design.count !== undefined) {\n const count = design.count ?? Math.max(4, Math.ceil((sx * sz) / (d.pitch * d.diameter) ** 2))\n const length = design.length ?? pileLength(profile, { load: weight / count, diameter: d.diameter, top: sy, method: d.method, maxLength: d.maxLength, soils })\n return { length, diameter: d.diameter, count, method: d.method }\n }\n let pitch: number = d.pitch\n for (;;) {\n const count = Math.max(4, Math.ceil(sx / (pitch * d.diameter)) * Math.ceil(sz / (pitch * d.diameter)))\n const length = pileLength(profile, { load: weight / count, diameter: d.diameter, top: sy, method: d.method, maxLength: d.maxLength, soils })\n if (length < d.maxLength || pitch <= 2.5) return { length, diameter: d.diameter, count, method: d.method }\n pitch = Math.max(2.5, pitch - 0.25)\n }\n}\n\n/** The tower of a layout: `buildTower` on a raft, then the soil and, with it, the deep piles sized by the load. */\nexport function buildSkyscraper(options: SkyscraperOptions = {}, preset: SkyscraperPreset = SKYSCRAPER_DEFAULTS): DestructibleSpec {\n const layout = skyscraperLayout(options, preset)\n const o = { ...SKYSCRAPER_DEFAULTS, ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset\n const built = buildTower(layout.tower)\n const spec: DestructibleSpec = { ...built, name: 'skyscraper', tags: [...(built.tags ?? []), 'skyscraper'] }\n if (o.soil === false) return spec\n const parts: PartSpec[] = spec.parts.map((part) => {\n if (part.id !== 'raft') return part\n return o.piles === false ? { ...part, structure: { ...part.structure!, role: 'foundation' } } : { ...part, structure: { ...part.structure!, role: 'foundation', pile: pilesFor(spec, o.soil as string | SoilProfile, o.piles) } }\n })\n return { ...spec, parts, soil: o.soil }\n}\n","import type { DoorDef, FloorDef, RoomDef, WindowDef } from '@adatechnology/game-floorplan'\n\nimport type { SkyscraperLayout } from './skyscraper'\nimport enLocale from './locales/en.json'\nimport ptBrLocale from './locales/pt-BR.json'\n\n/**\n * The floor plan of a skyscraper at room level, shared by every typology: a central core (stairs, elevator shafts and a service shaft) inside a ring of\n * corridors, with the four strips of the perimeter left for the typology (office suites, apartments) to fill. The plate and the core come from the\n * same `SkyscraperLayout` as the structure (`buildSkyscraper`), so a room of the plan stands where the structure has its slab and its core. The plan is in\n * the space of `game-floorplan` (`u` to the right, `v` to the back, from the front-left corner); the structure is centred (`planToSpace`). Design\n * T10-estrutura-real.md §11.5.\n */\n\n/** `[u0, v0, u1, v1]`. */\nexport type PlateRect = [number, number, number, number]\n\nexport interface PlateOptions {\n /** Width of the corridors around the core (default 1.8 m). */\n corridor?: number\n /** Width of the elevator lobby beside the shafts (default 3 m). */\n lobby?: number\n /** Narrowest the stair room is made (default 3.4 m): the stairs need more than the tube's clear width. */\n stairWidth?: number\n}\n\nexport const PLATE_DEFAULTS = { corridor: 1.8, lobby: 3, stairWidth: 3.4 } as const\n\nexport type StripId = 'south' | 'north' | 'west' | 'east'\n\n/** One of the four bands of the perimeter, where the typology puts its rooms. */\nexport interface PlateStrip {\n id: StripId\n /** Side of the building the outer edge is on, as `game-floorplan` names it. */\n side: 'front' | 'back' | 'left' | 'right'\n rect: PlateRect\n /** The strip runs along `u` (south and north) or along `v` (west and east). */\n alongU: boolean\n /** Length along the perimeter and depth from the outer wall to the circulation, metres. */\n length: number\n depth: number\n /** Id (without the storey suffix) of the circulation room the inner edge touches: `corridor_s`, `corridor_n`, `corridor_w` or `lobby`. */\n circulation: string\n}\n\nexport interface TowerPlate {\n w: number\n d: number\n core: PlateRect\n stairs: PlateRect\n service: PlateRect | null\n shafts: PlateRect[]\n lobby: PlateRect\n corridors: { s: PlateRect; n: PlateRect; w: PlateRect }\n strips: PlateStrip[]\n}\n\nconst r2 = (v: number): number => Math.round(v * 100) / 100\n\n/** The plate of a layout: where the core, its rooms, the circulation and the four strips stand. */\nexport function towerPlate(layout: SkyscraperLayout, options: PlateOptions = {}): TowerPlate {\n const o = { ...PLATE_DEFAULTS, ...options }\n const [w, d] = layout.plate\n const core = layout.core\n if (!core) throw new Error('A tower plan needs a core (turn the core on)')\n const t = core.wallThickness\n const [W, L] = core.size\n const u = w / 2 + core.center[0], v = d / 2 + core.center[1]\n const rect: PlateRect = [r2(u - W / 2), r2(v - L / 2), r2(u + W / 2), r2(v + L / 2)]\n const [x0, z0, x1, z1] = rect\n const split = r2(Math.min(x1 - 1.8, x0 + Math.max(o.stairWidth, t + core.stairWidth + 0.1)))\n const stairEnd = r2(z0 + Math.min(L, Math.max(5.4, 2 * t + 4.8)))\n const merged = z1 - stairEnd < 1.6\n const stairs: PlateRect = [x0, z0, split, merged ? z1 : stairEnd]\n const service: PlateRect | null = merged ? null : [x0, stairEnd, split, z1]\n const n = core.elevators\n const shafts = Array.from({ length: n }, (_, k): PlateRect => [split, r2(z0 + (k * L) / n), x1, r2(z0 + ((k + 1) * L) / n)])\n const lobby: PlateRect = [x1, z0, r2(x1 + o.lobby), z1]\n const west: PlateRect = [r2(x0 - o.corridor), z0, x0, z1]\n const south: PlateRect = [0, r2(z0 - o.corridor), w, z0]\n const north: PlateRect = [0, z1, w, r2(z1 + o.corridor)]\n const strip = (id: StripId, side: PlateStrip['side'], r: PlateRect, alongU: boolean, circulation: string): PlateStrip => ({\n id, side, rect: r, alongU, length: r2(alongU ? r[2] - r[0] : r[3] - r[1]), depth: r2(alongU ? r[3] - r[1] : r[2] - r[0]), circulation,\n })\n return {\n w, d, core: rect, stairs, service, shafts, lobby, corridors: { s: south, n: north, w: west },\n strips: [\n strip('south', 'front', [0, 0, w, south[1]], true, 'corridor_s'),\n strip('north', 'back', [0, north[3], w, d], true, 'corridor_n'),\n strip('west', 'left', [0, z0, west[0], z1], false, 'corridor_w'),\n strip('east', 'right', [lobby[2], z0, w, z1], false, 'lobby'),\n ],\n }\n}\n\n/** A point of the plan (`u`, `v`) in the space of the structure (centred on the plate, `x` right, `z` back). */\nexport const planToSpace = (layout: SkyscraperLayout, [u, v]: [number, number]): [number, number] => [r2(u - layout.plate[0] / 2), r2(v - layout.plate[1] / 2)]\n\nexport type StoreyKind = 'ground' | 'typical' | 'mechanical'\n\n/** What kind each storey is: the first is the ground floor, the mechanical ones are the plant floors of the layout, the rest are typical. */\nexport const storeyKinds = (layout: SkyscraperLayout): StoreyKind[] =>\n Array.from({ length: layout.storeys }, (_, f) => (f === 0 ? 'ground' : layout.mechanical.includes(f) ? 'mechanical' : 'typical'))\n\nexport interface StoreyContext {\n floor: number\n kind: StoreyKind\n layout: SkyscraperLayout\n plate: TowerPlate\n /** Floor to floor, metres: the ceiling of the plan floor. */\n ceiling: number\n}\n\nexport interface StripFill {\n rooms: RoomDef[]\n doors: DoorDef[]\n windows: WindowDef[]\n}\n\n/** Fills one strip of a storey with rooms. Room ids must be unique in the whole tower: end them with the storey (`_${floor}`). */\nexport type StripFiller = (strip: PlateStrip, storey: StoreyContext) => StripFill\n\nexport interface TowerPlanOptions extends PlateOptions {\n /** The perimeter of the typical storeys. */\n typical: StripFiller\n /** The ground floor (default: the typical filler). */\n ground?: StripFiller\n /** The plant floors (default: one plant room per strip, no windows). */\n mechanical?: StripFiller\n}\n\n/** Cuts a strip into `count` equal parts along its length. */\nexport const splitStrip = (strip: PlateStrip, count: number): PlateRect[] => {\n const [u0, v0, u1, v1] = strip.rect\n return Array.from({ length: Math.max(1, count) }, (_, k): PlateRect => {\n const a = k / Math.max(1, count), b = (k + 1) / Math.max(1, count)\n return strip.alongU ? [r2(u0 + (u1 - u0) * a), v0, r2(u0 + (u1 - u0) * b), v1] : [u0, r2(v0 + (v1 - v0) * a), u1, r2(v0 + (v1 - v0) * b)]\n })\n}\n\nconst EDGE = 1e-6\n\n/**\n * Windows on every outside wall of a room of the plate, `spacing` metres apart (at least one a wall); `y0`, `y1` the sill and head (default 0.3 and the\n * ceiling less 0.5 m, a glass facade).\n */\nexport function exteriorWindows(id: string, rect: PlateRect, plate: TowerPlate, ceiling: number, o: { spacing?: number; width?: number; y0?: number; y1?: number } = {}): WindowDef[] {\n const [u0, v0, u1, v1] = rect\n const spacing = o.spacing ?? 3\n const out: WindowDef[] = []\n const add = (side: string, length: number) => {\n const n = Math.max(1, Math.round(length / spacing))\n out.push({ room: id, side, n, width: Math.min(o.width ?? 2.4, (length / n) * 0.8), y0: o.y0 ?? 0.3, y1: o.y1 ?? r2(ceiling - 0.5) })\n }\n if (Math.abs(v0) < EDGE) add('front', u1 - u0)\n if (Math.abs(v1 - plate.d) < EDGE) add('back', u1 - u0)\n if (Math.abs(u0) < EDGE) add('left', v1 - v0)\n if (Math.abs(u1 - plate.w) < EDGE) add('right', v1 - v0)\n return out\n}\n\n/** The door from a room of a strip to the circulation it touches. */\nexport const stripDoor = (id: string, strip: PlateStrip, floor: number, width = 1): DoorDef => ({ a: id, b: `${strip.circulation}_${floor}`, width, opensTo: id })\n\n/** The default fill of a plant floor: a plant room on each strip, with a door to the circulation and no windows (the facade has louvres there). */\nconst plantRooms: StripFiller = (strip, { floor }) => {\n const id = `plant_${floor}_${strip.id}`\n return { rooms: [{ id, type: 'storage', label: 'plant_room', rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor, 1.2)], windows: [] }\n}\n\n/** The core and the circulation of a storey: the stairs, the shafts, the service shaft, the lobby and the three corridors, with their doors. */\nfunction coreRooms(plate: TowerPlate, floor: number, storeys: number): { rooms: RoomDef[]; doors: DoorDef[]; openPairs: [string, string][] } {\n const id = (name: string) => `${name}_${floor}`\n const link = floor < storeys - 1 ? [floor, floor + 1] : [floor - 1, floor]\n const rooms: RoomDef[] = [\n { id: id('stairs'), type: 'stairs', label: 'stairs', rect: [...plate.stairs], link },\n ...(plate.service ? [{ id: id('service'), type: 'storage', label: 'service_shaft', rect: [...plate.service] }] : []),\n ...plate.shafts.map((rect, k): RoomDef => ({ id: id(`elevator_${k}`), type: 'elevator', label: 'elevator', rect: [...rect] })),\n { id: id('lobby'), type: 'hall', label: 'elevator_lobby', rect: [...plate.lobby] },\n { id: id('corridor_w'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.w] },\n { id: id('corridor_s'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.s] },\n { id: id('corridor_n'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.n] },\n ]\n const doors: DoorDef[] = [\n { a: id('stairs'), b: id('corridor_w'), width: 1, opensTo: id('corridor_w') },\n ...(plate.service ? [{ a: id('service'), b: id('corridor_w'), width: 0.8, opensTo: id('service') }] : []),\n ...plate.shafts.map((_, k): DoorDef => ({ a: id(`elevator_${k}`), b: id('lobby'), width: 1.2, opensTo: id('lobby') })),\n ]\n const openPairs: [string, string][] = [[id('lobby'), id('corridor_s')], [id('lobby'), id('corridor_n')], [id('corridor_w'), id('corridor_s')], [id('corridor_w'), id('corridor_n')]]\n return { rooms, doors, openPairs }\n}\n\n/**\n * The storeys of a tower as `FloorDef`s for `TemplateDef.floorsFn`: each has the core and the circulation, the strips filled by the typology for its\n * kind of storey (ground, typical, plant), `ceiling` the storey pitch of the structure. The template's size must be the plate (`layout.plate`).\n */\nexport function towerFloors(layout: SkyscraperLayout, plan: TowerPlanOptions): FloorDef[] {\n const plate = towerPlate(layout, plan)\n const fillers: Record<StoreyKind, StripFiller> = { ground: plan.ground ?? plan.typical, typical: plan.typical, mechanical: plan.mechanical ?? plantRooms }\n return storeyKinds(layout).map((kind, floor): FloorDef => {\n const context: StoreyContext = { floor, kind, layout, plate, ceiling: layout.pitch }\n const fills = plate.strips.map((strip) => fillers[kind](strip, context))\n const core = coreRooms(plate, floor, layout.storeys)\n return {\n label: kind === 'ground' ? 'ground_floor' : kind === 'mechanical' ? 'mechanical_floor' : 'typical_floor',\n ceiling: layout.pitch,\n openPairs: core.openPairs,\n rooms: () => [...core.rooms, ...fills.flatMap((f) => f.rooms)],\n doors: () => [...core.doors, ...fills.flatMap((f) => f.doors)],\n windows: () => fills.flatMap((f) => f.windows),\n }\n })\n}\n\n/** The names of the rooms and storeys the plan helpers make (`elevator_lobby`, `plant_room`, `typical_floor`...), for the packs that fill the strips to register with `engine.registerLocale`. */\nexport const towerLocales = { en: { labels: enLocale.labels }, 'pt-BR': { labels: ptBrLocale.labels } } as const\n","export const version = '0.1.0'\n\nexport { register } from './register'\nexport type { StructurePackOptions } from './register'\nexport { buildStructure } from './structure'\nexport { MEMBER_CAGE, PILE_AREA, cageResidualCapacity, RAFT_THICKNESS, REBAR_RATIOS, toDestructibleSpec } from './to-destructible-spec'\nexport type { DestructibleSpecOptions } from './to-destructible-spec'\nexport { SLAB_PANEL_DEFAULTS, applySlabPanels, beamDepthFor, beamSpan, resolveSlabPanels, slabPanelView, slabPanelsOf } from './slab-panels'\nexport type { SlabPanelOptions } from './slab-panels'\nexport { WALL_PILLAR_SIDE, WALL_PILLAR_SPACING, pillarStations } from './structure/wall-pillars'\nexport { GROUND_BEAM_DEPTH } from './structure/ground-beams'\nexport { SILL_BEAM_DEPTH } from './wall-detail/panels'\nexport { TANK_PILLAR_SIDE } from './water-tank'\nexport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MAX_PILLAR_SPACING, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION, countViolations, validateSpec, validateStructure } from './validate'\nexport type { StructuralViolation, StructuralViolationCode, ValidateStructureOptions } from './validate'\nexport { buildWallSpecimen } from './wall-specimen'\nexport type { WallSpecimenOptions } from './wall-specimen'\nexport { planWaterTank } from './water-tank'\nexport type { TankPlanOptions } from './water-tank'\nexport {\n CONSTRUCTION_SYSTEMS, CONSTRUCTIONS, ROOF_COVERINGS, registerConstruction, registerConstructionSystem, registerRoofCovering,\n} from './registry'\nexport type { ConstructionBuild, ConstructionBuilder, ConstructionSystemDef, RoofCoveringDef } from './registry'\nexport { campConstruction, chaletConstruction, constructionOfSystem, logCabinConstruction, masonryConstruction, shackConstruction, woodFrameConstruction } from './presets'\nexport type { ChaletOptions, ShackOptions, WoodFrameOptions } from './presets'\nexport { structureLayer } from './viewer-layer'\nexport { DENSITY } from './density'\nexport { GROUND } from './types'\nexport type * from './types'\nexport {\n CORE_DEFAULTS, CURTAIN_DEFAULTS, DAMPER_DEFAULTS, FLAT_ROOF_DEFAULTS, MECHANICAL_DEFAULTS, TOWER_DEFAULTS, addCore, addCurtainWall, addFlatRoof, addMechanicalFloor,\n addTunedMassDamper, buildTower, coreSize, damperMass, towerWater, windExposureOf,\n PUNCHED_DEFAULTS, addPunchedFacade, mechanicalStoreys,\n} from './tower'\nexport type { CoreOptions, CurtainWallOptions, DamperOptions, FlatRoofOptions, MechanicalFloorOptions, PunchedFacadeOptions, TowerGeometry, TowerMechanicalOptions, TowerOptions } from './tower'\nexport { PILE_DEFAULTS, SKYSCRAPER_DEFAULTS, SKYSCRAPER_MAX_STOREYS, buildSkyscraper, pilesFor, skyscraperLayout } from './skyscraper'\nexport type { PileDesign, SkyscraperLayout, SkyscraperOptions, SkyscraperPreset } from './skyscraper'\nexport { PLATE_DEFAULTS, exteriorWindows, planToSpace, splitStrip, storeyKinds, stripDoor, towerFloors, towerLocales, towerPlate } from './skyscraper-plan'\nexport type { PlateOptions, PlateRect, PlateStrip, StoreyContext, StoreyKind, StripFill, StripFiller, StripId, TowerPlanOptions, TowerPlate } from './skyscraper-plan'\nexport type * from './utilities/types'\nexport type { Utilities } from './utilities'\nexport type { Electrical, EnergyConfig, EnergyMode } from './utilities/electrical'\nexport type { Gas, GasMeter } from './utilities/gas'\n"],"mappings":"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","names":["onSoil","box","box","centre","box","at","centre","at","box","acrossOf","box","box","at","item","flight","TOLERANCE","alongRange","box","box","part","box","entry","entry","round2","round2","round2","round2","centre","round2","distance","box","absolute","round2","centre","round2","box","DOOR_HEIGHT","round2","box","distance","clamp","centre","distance","at","best","runsOf","EPS","at","box","runsOf","opening","at","box","LINTEL_DEPTH","LINTEL_BEARING","roleOf","opening","overlaps","box","carries","raft","alongOf","getAssembly","TOLERANCE","lineOf","getAssembly","pointOf","at","carries","TOLERANCE","LINTEL_DEPTH","opening","lineOf","EPSILON","assemblyPart","getAssembly","DOOR_WIDTH","opening","getAssembly","assemblyPart","MATERIALS","partMass","raft","at","centre","addFlatRoof","GRAVITY","MATERIALS","SOILS","partMass","pileLength","profileOf","ceilTo","round2","GRAVITY","total","given","MATERIALS","partMass","raft","profileOf","SOILS","pileLength","merged"]}
|
|
1
|
+
{"version":3,"sources":["../src/registry.ts","../src/geometry.ts","../src/presets.ts","../src/construction.ts","../src/locales/en.json","../src/locales/pt-BR.json","../src/types.ts","../src/density.ts","../src/structure/builder.ts","../src/structure/legacy-key.ts","../src/structure/context.ts","../src/structure/balconies.ts","../src/structure/canvas.ts","../src/structure/extras.ts","../src/structure/floor-deck.ts","../src/structure/foundation.ts","../src/structure/ground-beams.ts","../src/structure/wall-pillars.ts","../src/structure/plates.ts","../src/structure/porch.ts","../src/structure/porch-roof.ts","../src/structure/roof.ts","../src/structure/stairs.ts","../src/structure/openings.ts","../src/structure/steps.ts","../src/structure/tank-parts.ts","../src/structure/upper-floor.ts","../src/structure/walls.ts","../src/structure/index.ts","../src/utilities/content-tables.ts","../src/utilities/content.ts","../src/utilities/shared.ts","../src/utilities/wall-points.ts","../src/utilities/electrical-outlets.ts","../src/utilities/electrical-entrance.ts","../src/utilities/electrical-circuits.ts","../src/utilities/electrical.ts","../src/utilities/gas.ts","../src/utilities/plumbing.ts","../src/utilities/solar.ts","../src/utilities/index.ts","../src/utilities/outbuildings.ts","../src/water-tank.ts","../src/viewer-layer.ts","../src/register.ts","../src/to-destructible-spec.ts","../src/loads.ts","../src/slab-panels/layout.ts","../src/slab-panels/apply.ts","../src/slab-panels/options.ts","../src/wall-detail/index.ts","../src/wall-detail/apply.ts","../src/wall-detail/courses.ts","../src/wall-detail/panels.ts","../src/validate/codes.ts","../src/validate/load-path.ts","../src/validate/masonry.ts","../src/validate/openings.ts","../src/validate/spec.ts","../src/validate/index.ts","../src/wall-specimen.ts","../src/tower.ts","../src/skyscraper.ts","../src/skyscraper-plan.ts","../src/index.ts"],"sourcesContent":["import type { JointKind } from '@adatechnology/game-contracts'\n\nimport type { Construction, ConstructionSystem, PlanContext, StructureExtras } from './types'\n\n/** What a wall system is made of and how its parts are tied. Timber systems sit on joists, carry the roof on timber plates and have wooden porch posts. */\nexport interface ConstructionSystemDef {\n /** Wall assembly of `game-destruction` (`registerAssembly`) the detailed wall is built from. Empty: no walls (a tent). */\n walls: string\n joints: Record<'wall' | 'slab' | 'beam' | 'column' | 'truss', JointKind>\n /** Thickness of the structural floor under each storey (m). */\n slabThickness: number\n /** Height of the top plate or bond beam (m). */\n plateThickness: number\n timber: boolean\n /** `rules`: bearing when external, under another wall or beside a porch; `bearing`: every wall (logs); `partition`: none (posts carry the roof). */\n wallRole: 'rules' | 'bearing' | 'partition'\n /** Solid fraction of a bearing wall in the structure weight (studs and air). */\n wallFill: number\n studs?: { spacing: number; section: string }\n}\n\nconst uniform = (joint: JointKind): ConstructionSystemDef['joints'] => ({ wall: joint, slab: joint, beam: joint, column: joint, truss: joint })\n\nexport const CONSTRUCTION_SYSTEMS = new Map<string, ConstructionSystemDef>([\n ['masonry', { walls: 'brick_wall_plastered', joints: { wall: 'mortar', slab: 'rebar', beam: 'mortar', column: 'rebar', truss: 'bolt' }, slabThickness: 0.12, plateThickness: 0.2, timber: false, wallRole: 'rules', wallFill: 1 }],\n ['wood_frame', { walls: 'wood_frame_wall', joints: uniform('nail'), slabThickness: 0.28, plateThickness: 0.1, timber: true, wallRole: 'rules', wallFill: 0.35, studs: { spacing: 0.4, section: '38x89' } }],\n ['log', { walls: 'log_wall', joints: { wall: 'bolt', slab: 'nail', beam: 'bolt', column: 'bolt', truss: 'bolt' }, slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'bearing', wallFill: 1 }],\n ['improvised', { walls: 'sheet_metal_shack', joints: uniform('nail'), slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'partition', wallFill: 1 }],\n ['canvas', { walls: '', joints: uniform('tie'), slabThickness: 0, plateThickness: 0, timber: false, wallRole: 'partition', wallFill: 1 }],\n])\n\n/** Adds or replaces a construction system (`id` is a `ConstructionSystem` or any name a construction refers to). */\nexport function registerConstructionSystem(id: ConstructionSystem | string, def: ConstructionSystemDef): void {\n CONSTRUCTION_SYSTEMS.set(id, def)\n}\n\nexport interface RoofCoveringDef {\n material: string\n /** How the covering is fixed to the trusses. */\n joint: JointKind\n}\n\nexport const ROOF_COVERINGS = new Map<string, RoofCoveringDef>([\n ['colonial', { material: 'ceramic', joint: 'resting' }],\n ['fiber_cement', { material: 'concrete', joint: 'bolt' }],\n ['slab', { material: 'concrete', joint: 'rebar' }],\n ['asphalt', { material: 'plastic', joint: 'nail' }],\n ['zinc', { material: 'steel', joint: 'nail' }],\n ['wood', { material: 'wood_soft', joint: 'nail' }],\n ['canvas', { material: 'fabric', joint: 'tie' }],\n ['thatch', { material: 'foliage', joint: 'tie' }],\n])\n\nexport function registerRoofCovering(id: string, def: RoofCoveringDef): void {\n ROOF_COVERINGS.set(id, def)\n}\n\nexport interface ConstructionBuild {\n construction: Construction\n extras?: StructureExtras\n}\nexport type ConstructionBuilder = (context: PlanContext) => ConstructionBuild\n\nexport const CONSTRUCTIONS = new Map<string, ConstructionBuilder>()\n\n/** Registers how a template's building is made: `TemplateDef.construction` names it. A template without one gets the masonry default. */\nexport function registerConstruction(id: string, builder: ConstructionBuilder): void {\n CONSTRUCTIONS.set(id, builder)\n}\n","import type { Rect, SourceWall } from './types'\n\nexport const WALL_THICKNESS = 0.15\n\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\n\nexport function touches(a: Rect, b: Rect, tolerance: number): boolean {\n return a[0] < b[2] + tolerance && a[2] > b[0] - tolerance && a[1] < b[3] + tolerance && a[3] > b[1] - tolerance\n}\n\nexport function distanceBetween(a: Rect, b: Rect): number {\n return Math.hypot(Math.max(a[0] - b[2], b[0] - a[2], 0), Math.max(a[1] - b[3], b[1] - a[3], 0))\n}\n\nexport function unionOf(rects: readonly Rect[]): Rect {\n const out: Rect = [1e9, 1e9, -1e9, -1e9]\n for (const rect of rects) {\n out[0] = Math.min(out[0], rect[0])\n out[1] = Math.min(out[1], rect[1])\n out[2] = Math.max(out[2], rect[2])\n out[3] = Math.max(out[3], rect[3])\n }\n return out\n}\n\n/** The wall's centre line thickened to its box in the plan. */\nexport function wallBox(wall: Pick<SourceWall, 'u0' | 'v0' | 'u1' | 'v1' | 'thickness'>): Rect {\n const half = (wall.thickness ?? WALL_THICKNESS) / 2\n return [Math.min(wall.u0, wall.u1) - half, Math.min(wall.v0, wall.v1) - half, Math.max(wall.u0, wall.u1) + half, Math.max(wall.v0, wall.v1) + half]\n}\n\nexport const centreOf = (rect: Rect): [number, number] => [(rect[0] + rect[2]) / 2, (rect[1] + rect[3]) / 2]\n\n/** The nearest `count` of `candidates` to `target`, nearest first. */\nexport function nearestTo<T extends { aabb: Rect }>(target: Rect, candidates: readonly T[], count: number): T[] {\n return candidates.slice().sort((a, b) => distanceBetween(target, a.aabb) - distanceBetween(target, b.aabb)).slice(0, count)\n}\n","import type { Construction, FoundationType, StructureSource } from './types'\nimport { WALL_THICKNESS } from './geometry'\nimport { ROOF_COVERINGS } from './registry'\n\nconst SLAB_COVERING = 'slab'\nconst PLASTERED_FINISHES = ['plaster', 'partial_plaster']\n\n/** Masonry house of the engine's own templates: brick with plaster, concrete frame, tiles by facade; a unit in a building gets a flat slab roof. */\nexport function masonryConstruction(source: StructureSource): Construction {\n const unit = source.floorNumber !== undefined\n const covering = unit ? SLAB_COVERING : (source.facade.roof ?? 'colonial')\n const finish = source.facade.finish ?? 'roughcast'\n const budget = source.style === 'budget'\n const flat = unit || covering === SLAB_COVERING\n return {\n system: 'masonry',\n walls: { material: 'brick', cladding: PLASTERED_FINISHES.includes(finish) ? 'plaster' : null, finish, thickness: WALL_THICKNESS, ...(finish === 'exposed_block' ? { assembly: 'concrete_block_wall' } : {}) },\n floor: { material: budget ? 'concrete' : 'ceramic', finish: budget ? 'burnt_cement' : 'ceramic_tile' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'ceramic', covering, shape: flat ? 'slab' : 'gable', pitch: flat ? 0 : covering === 'colonial' ? 30 : 15, timber: 'wood_soft' },\n frame: { material: 'concrete', pillars: 'concrete', beams: 'concrete', slabs: 'concrete', timber: 'wood_soft', rebar: 'steel' },\n foundation: { type: unit ? 'building' : 'strip_footing', material: 'concrete', elevation: 0 },\n }\n}\n\nexport interface WoodFrameOptions {\n foundation?: 'basement' | 'crawl_space' | 'raft'\n covering?: string\n finish?: string\n /** Cladding of the outer face (default soft wood). */\n cladding?: string\n}\n\nconst FOUNDATIONS: Record<NonNullable<WoodFrameOptions['foundation']>, Construction['foundation']> = {\n basement: { type: 'basement', material: 'concrete', elevation: 0.5, depth: 2.4 },\n crawl_space: { type: 'crawl_space', material: 'concrete', elevation: 0.6 },\n raft: { type: 'raft', material: 'concrete', elevation: 0.2 },\n}\n\nconst TIMBER_FRAME: Construction['frame'] = { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'plywood', timber: 'wood_soft', rebar: null }\n\n/** American wood frame house: 38x89 studs every 40 cm, plaster inside, wood outside, asphalt shingles. */\nexport function woodFrameConstruction(options: WoodFrameOptions = {}): Construction {\n const covering = options.covering ?? 'asphalt'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'plaster', cladding: options.cladding ?? 'wood_soft', finish: options.finish ?? 'wood_siding', thickness: WALL_THICKNESS, studs: '38x89 every 40 cm', insulation: 'foam' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'plastic', covering, shape: 'gable', pitch: 28, timber: 'wood_soft', eave: 0.5 },\n frame: { ...TIMBER_FRAME },\n foundation: { ...FOUNDATIONS[options.foundation ?? 'raft'] },\n }\n}\n\nexport interface ChaletOptions {\n covering?: string\n finish?: string\n piles?: boolean\n}\n\n/** Mountain chalet: A-frame roof at 52 degrees with gables front and back, 38x140 studs. */\nexport function chaletConstruction(options: ChaletOptions = {}): Construction {\n const covering = options.covering ?? 'colonial'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'wood_soft', cladding: 'wood_hard', finish: options.finish ?? 'vertical_boards', thickness: WALL_THICKNESS, studs: '38x140 every 40 cm' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 52, timber: 'wood_soft', eave: 0.8, axis: 'v', profile: 'a_frame', gables: ['front', 'back'] },\n frame: { ...TIMBER_FRAME },\n foundation: options.piles ? { type: 'piles', material: 'stone', elevation: 0.9 } : { type: 'raft', material: 'concrete', elevation: 0.2 },\n }\n}\n\n/** Log cabin: every wall is a stack of 26 cm logs, notched at the corners, on stone piles. */\nexport function logCabinConstruction(options: { covering?: string } = {}): Construction {\n const covering = options.covering ?? 'wood'\n return {\n system: 'log',\n walls: { material: 'wood_hard', interior: 'wood_hard', cladding: null, finish: 'log', thickness: WALL_THICKNESS, logDiameter: 0.26, joint: 'notched_corners' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 32, timber: 'wood_hard', eave: 0.6 },\n frame: { material: 'wood_hard', pillars: 'wood_hard', beams: 'wood_hard', slabs: 'wood_hard', timber: 'wood_hard', rebar: null },\n foundation: { type: 'piles', material: 'stone', elevation: 0.5 },\n }\n}\n\nexport interface ShackOptions {\n material?: 'wood' | 'zinc' | 'mixed'\n floor?: 'soil' | 'concrete'\n}\n\nconst MIXED_SCRAP = ['wood_soft', 'steel', 'plywood', 'steel', 'wood_soft']\n\n/** Shack of scrap boards and zinc sheets: timber posts carry the roof, the walls only close. */\nexport function shackConstruction(options: ShackOptions = {}): Construction {\n const material = options.material === 'zinc' ? 'steel' : 'wood_soft'\n const onSoil = options.floor === 'soil'\n return {\n system: 'improvised',\n walls: { material, interior: options.material === 'zinc' ? 'plywood' : material, cladding: null, finish: 'scrap', thickness: WALL_THICKNESS, ...(options.material === 'mixed' ? { mixed: MIXED_SCRAP } : {}) },\n floor: onSoil ? { material: 'soil', finish: 'packed_earth' } : { material: 'concrete', finish: 'burnt_cement' },\n roof: { material: 'steel', covering: 'zinc', shape: 'gable', pitch: 12, timber: 'wood_soft', eave: 0.3, fastening: 'nails_and_stones' },\n frame: { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'concrete', timber: 'wood_soft', rebar: null },\n foundation: onSoil ? { type: 'ground', material: 'soil', elevation: 0 } : { type: 'raft', material: 'concrete', elevation: 0.08 },\n }\n}\n\n/** Camping: canvas over aluminium poles on the ground; there are no walls. */\nexport function campConstruction(): Construction {\n return {\n system: 'canvas',\n walls: { material: 'fabric', interior: 'fabric', cladding: null, finish: 'nylon', thickness: 0.002 },\n floor: { material: 'plastic', finish: 'waterproof_mat' },\n roof: { material: 'fabric', covering: 'canvas', shape: 'tent', pitch: 0, timber: 'aluminium', eave: 0 },\n frame: { material: 'aluminium', pillars: 'aluminium', beams: 'aluminium', slabs: 'plastic', timber: 'aluminium', rebar: null },\n foundation: { type: 'ground', material: 'soil', elevation: 0 },\n }\n}\n\n/** The construction a system gets on any plan when the options force it (`options.construction`). */\nexport function constructionOfSystem(system: string, source: StructureSource): Construction | undefined {\n const covering = source.facade.roof\n const keep = covering && covering !== SLAB_COVERING ? { covering } : {}\n switch (system) {\n case 'masonry':\n return masonryConstruction(source)\n case 'wood_frame':\n return woodFrameConstruction(keep)\n case 'log':\n return logCabinConstruction(keep)\n case 'improvised':\n return shackConstruction()\n case 'canvas':\n return campConstruction()\n default:\n return undefined\n }\n}\n\nexport type { FoundationType }\n","import { CONSTRUCTIONS } from './registry'\nimport type { ConstructionBuild } from './registry'\nimport { constructionOfSystem, masonryConstruction } from './presets'\nimport type { PlanContext, StructureSource, Tent } from './types'\n\n/** The construction of a plan: the one it already carries, else the masonry default of the engine's templates. */\nexport function resolveConstruction(source: StructureSource): ConstructionBuild {\n const extras = source.structureExtras ?? {}\n return { construction: source.construction ?? masonryConstruction(source), extras }\n}\n\nconst TENT_LABEL = /^tent_(dome|tunnel)(?:_|$)/\n\n/**\n * Tents of a plan whose template names the `canvas` construction and registers none of its own: one per room of type `tent`, standing on the room's footprint\n * (a label `tent_<kind>_<people>` names the kind, any other is a long tunnel) as high as the room's ceiling.\n */\nexport function tentsOf(source: StructureSource): Tent[] {\n const tents: Tent[] = []\n for (const room of source.rooms) {\n if (room.type !== 'tent' || room.floor !== 0 || !room.parts[0]) continue\n const { label } = room as { label?: unknown }\n tents.push({ id: room.id, kind: TENT_LABEL.exec(typeof label === 'string' ? label : '')?.[1] ?? 'tunnel', height: room.ceiling ?? source.floors[0]?.ceiling ?? 2.4, aabb: room.parts[0] })\n }\n return tents\n}\n\n/**\n * Picks the construction for a plan being generated: `options.construction` (a registered construction or a system name) wins over the template's\n * own (`TemplateDef.construction`), which wins over the masonry default.\n */\nexport function constructionFor(context: PlanContext): ConstructionBuild {\n const forced = context.options?.construction\n const named = typeof forced === 'string' ? forced : (context.template?.construction as string | undefined)\n if (named === undefined) return { construction: masonryConstruction(context.result) }\n const registered = CONSTRUCTIONS.get(named)\n if (registered) return registered(context)\n const preset = constructionOfSystem(named, context.result)\n if (preset) return { construction: preset, ...(named === 'canvas' ? { extras: { tents: tentsOf(context.result) } } : {}) }\n throw new Error(`Unknown construction \"${named}\": register it with registerConstruction`)\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Structure\",\n \"structure_column_concrete\": \"Concrete pillar\",\n \"structure_column_steel\": \"Steel post\",\n \"structure_column_masonry\": \"Masonry pillar\",\n \"structure_column_wood\": \"Wood post\",\n \"structure_beam_concrete\": \"Bond beam / beam (concrete)\",\n \"structure_beam_wood\": \"Plate / beam (wood)\",\n \"structure_roof_frame\": \"Trusses, rafters and ridge (roof view)\"\n },\n \"labels\": {\n \"elevator_lobby\": \"Elevator lobby\",\n \"service_shaft\": \"Service shaft\",\n \"plant_room\": \"Plant room\",\n \"mechanical_floor\": \"Mechanical floor\",\n \"typical_floor\": \"Typical floor\"\n }\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Estrutura\",\n \"structure_column_concrete\": \"Pilar de concreto\",\n \"structure_column_steel\": \"Poste de aço\",\n \"structure_column_masonry\": \"Pilar de alvenaria\",\n \"structure_column_wood\": \"Pilar de madeira\",\n \"structure_beam_concrete\": \"Cinta / viga (concreto)\",\n \"structure_beam_wood\": \"Prato / viga (madeira)\",\n \"structure_roof_frame\": \"Tesouras, caibros e cumeeira (vista do telhado)\"\n },\n \"labels\": {\n \"elevator_lobby\": \"Antessala dos elevadores\",\n \"service_shaft\": \"Shaft de serviço\",\n \"plant_room\": \"Casa de máquinas\",\n \"mechanical_floor\": \"Andar técnico\",\n \"typical_floor\": \"Andar tipo\"\n }\n}\n","import type { JointKind, MaterialId, StructureRole } from '@adatechnology/game-contracts'\n\n/** Axis-aligned rectangle `[u0, v0, u1, v1]` in the plan (metres). */\nexport type Rect = [number, number, number, number]\n\nexport type ConstructionSystem = 'masonry' | 'wood_frame' | 'log' | 'improvised' | 'canvas'\nexport type WallDetail = 'coarse' | 'panels' | 'units'\n/** What a structural part is called in a plan: a column is a pillar, `wall` is a bearing wall, `partition` a wall that only closes. */\nexport type PartRole = Exclude<StructureRole, 'foundation'>\n\nexport const GROUND = 'ground'\n\n/** A piece of the structure with its box in the plan, its height range and the mass it weighs. `y` is absolute: the ground floor sits at `foundation.elevation`. */\nexport interface StructurePart {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n floor: number\n mass: number\n /** Part this one is cut out of (a pier of a wall in `panels` detail). */\n host?: string\n /** Wall assembly of `game-destruction` the part is built from in the destructible spec (layers, units, rebar, breach). */\n assembly?: string\n /** A brick, block or log: the unit of a wall (`units` detail, log courses), not a piece of it. */\n unit?: true\n /** Distance between repeated members (joists, ceiling joists). */\n spacing?: number\n /** `plate` (timber top plate), `bond_beam` (masonry bond beam) or `ground_beam` (the masonry ground beam, viga baldrame, buried under a ground-floor wall). */\n beamKind?: 'plate' | 'bond_beam' | 'ground_beam'\n /** An exterior wall (it carries the bond beam and the pillars of confined masonry). */\n exterior?: true\n steps?: number\n door?: string\n /** Slab that is the roof (flat roof). */\n cover?: boolean\n /** Litres a tank holds. */\n liters?: number\n studs?: { spacing: number; section: string }\n pitch?: number\n tent?: string\n form?: string\n /** Rooms a concrete slab covers (the rectangles of the storey it carries); the slab itself is their bounding box. `toDestructibleSpec` cuts the slab into panels over it. */\n footprint?: Rect[]\n /** Slab the panel, beam or column was made for (`toDestructibleSpec` with `slabPanels`; a `StructurePart` of `buildStructure` never has it). */\n slab?: string\n}\n\n/** `part` rests on `on` (`GROUND` or another part) through `joint`. `bears: false` ties the two without carrying load. */\nexport interface Support {\n part: string\n on: string\n joint: JointKind\n bears?: false\n}\n\nexport interface RoofPane {\n id: string\n aabb: Rect\n y0: number\n y1: number\n flat?: true\n}\n\nexport type RoofShape = 'gable' | 'slab' | 'tent'\n\nexport interface Roof {\n shape: RoofShape\n covering: string\n material: MaterialId\n pitch: number\n /** Floor the roof rests on. */\n bearingFloor: number\n panes: (RoofPane | string)[]\n trusses: number\n axis?: 'u' | 'v'\n ridge?: number\n eave?: number\n y0?: number\n aabb?: Rect\n}\n\n/** A window in a wall (the doors are gaps between walls: a lintel part bridges them). Heights are absolute. */\nexport interface Opening {\n id: string\n kind: 'window' | 'door'\n wall: string\n /** Along the wall (u for a wall along u, v for one along v). */\n from: number\n to: number\n y0: number\n y1: number\n}\n\nexport interface Structure {\n parts: StructurePart[]\n supports: Support[]\n openings: Opening[]\n /** Absolute height of the floor level of each storey. */\n levels: number[]\n elevation: number\n roof: Roof\n construction: Construction\n /** A reinforced concrete frame carries the building (apartments, commercial buildings, three storeys or more); the walls are infill. */\n framed: boolean\n}\n\n/** The structure as a `generate` result carries it: the roof goes out apart, in `result.roof`. */\nexport type PlanStructure = Omit<Structure, 'roof'>\n\nexport interface WallMaterials {\n material: MaterialId\n interior?: MaterialId\n cladding?: MaterialId | null\n finish?: string\n /** Wall assembly of `game-destruction` (default by system, and by finish in masonry). */\n assembly?: string\n thickness: number\n studs?: string\n /** Materials drawn per wall by a hash of its legacy key (the improvised shack). */\n mixed?: MaterialId[]\n [extra: string]: unknown\n}\n\nexport interface Construction {\n system: ConstructionSystem\n walls: WallMaterials\n floor: { material: MaterialId; finish: string }\n roof: {\n material: MaterialId\n covering: string\n shape: RoofShape\n pitch: number\n timber: MaterialId\n eave?: number\n axis?: 'u' | 'v'\n bearingFloor?: number\n profile?: string\n gables?: string[]\n fastening?: string\n }\n frame: { material: MaterialId; pillars: MaterialId; beams: MaterialId; slabs: MaterialId; timber: MaterialId; rebar: MaterialId | null }\n foundation: { type: FoundationType; material: MaterialId; elevation: number; depth?: number }\n guard?: MaterialId\n stairs?: MaterialId\n}\n\nexport type FoundationType = 'strip_footing' | 'building' | 'raft' | 'crawl_space' | 'piles' | 'basement' | 'ground'\n\nexport interface Chimney {\n kind: 'fireplace' | 'flue'\n material: MaterialId\n aabb: Rect\n flue?: boolean\n top?: number\n height?: number\n}\n\nexport interface Tent {\n id: string\n kind: string\n height: number\n aabb: Rect\n}\n\n/** What a construction needs besides walls and roof, from the template: a chimney, a well, an attic floor, tents. */\nexport interface StructureExtras {\n chimney?: Chimney\n well?: { aabb: Rect; height?: number }\n attic?: boolean\n tents?: Tent[]\n [extra: string]: unknown\n}\n\nexport interface TankPlatform {\n aabb: Rect\n baseY: number\n height: number\n thickness: number\n topY: number\n pillars: { u: number; v: number; side: number }[]\n ladder: boolean\n}\n\nexport interface WaterTank {\n id: 'water_tank'\n kind: 'water_tank'\n itemType: string\n place: 'slab' | 'attic' | 'raised_slab' | 'trestle' | string\n floor: number\n room: string\n u: number\n v: number\n y: number\n w: number\n d: number\n h: number\n capacity: number\n material?: MaterialId\n aabb: Rect\n platform?: TankPlatform\n /** Trestle tank (a stand of its own: rural water). */\n stand?: { pillars: { u: number; v: number; side: number }[]; material: MaterialId; height: number; baseJoint?: JointKind; joint?: JointKind; tie?: JointKind; braces?: boolean }\n}\n\n/** The fields of a generated plan the structure reads. */\nexport interface StructureSource {\n floors: { y0: number; ceiling: number }[]\n rooms: { id: string; type: string; floor: number; parts: Rect[]; ceiling?: number | null }[]\n walls: SourceWall[]\n doors: SourceDoor[]\n windows?: SourceWindow[]\n items: { id?: string; type: string; category?: string; floor: number; aabb?: Rect; link?: { from: number; to: number } | string | null }[]\n facade: { roof?: string; finish?: string; [extra: string]: unknown }\n style?: string\n template?: string\n lot?: unknown\n w: number\n d: number\n floorNumber?: number\n waterTank?: WaterTank | null\n construction?: Construction\n structureExtras?: StructureExtras\n [extra: string]: unknown\n}\n\nexport interface SourceWall {\n floor: number\n axis: 'u' | 'v'\n u0: number\n v0: number\n u1: number\n v1: number\n thickness?: number\n sides: string[]\n exterior: boolean\n type: string\n h?: number\n /** Gable wall: the plate does not sit on top of it. */\n gable?: boolean\n structureHeight?: number\n}\n\nexport interface SourceWindow {\n id: string\n floor: number\n axis: 'u' | 'v'\n /** Coordinate of the wall line across its axis. */\n pos: number\n /** Centre along the wall. */\n at: number\n width: number\n y0: number\n y1: number\n}\n\nexport interface SourceDoor {\n id: string\n floor: number\n a: string\n b: string\n exterior?: boolean\n model?: string\n type?: string\n u: number\n v: number\n width: number\n side?: string | null\n axis: 'u' | 'v'\n steps?: number\n}\n\nexport interface StructureOptions {\n construction?: Construction\n extras?: StructureExtras\n tank?: WaterTank | null\n /** The porch roof is carried by its posts alone (the tie to the house wall carries nothing). Default: when the detail is not `coarse`. */\n porchRoofOnPostsOnly?: boolean\n /** Gable roofs as rafters of each side and a ridge beam (a side falls with the wall it rests on) instead of whole trusses. Default: when the detail is not `coarse`. */\n rafterRoof?: boolean\n wallDetail?: WallDetail\n /** `false`: no roof (a free-standing wall, a garden wall). Default `true`. */\n roof?: boolean\n /**\n * Concrete pillars along the exterior masonry walls besides the corner ones (at the free ends and door jambs, beside the windows, where walls meet and at\n * most every `spacing` metres, default `WALL_PILLAR_SPACING`). `false`: only the corner pillars. Default `true`.\n */\n wallPillars?: boolean | { spacing?: number }\n /** A reinforced concrete ground beam (viga baldrame) under each ground-floor wall of a masonry house on strip footings (`GROUND_BEAM_DEPTH` deep). Default `true`. */\n groundBeams?: boolean\n /** The sections the Visor de casas 3D drew below the NBR 6118 minimum (16 cm balcony pillars), for the team's golden only. Default `false`. */\n visorSections?: boolean\n}\n\n/** What a construction builder and the tank get to see: the generated plan, its seed and the template. */\nexport interface PlanContext {\n result: StructureSource\n seed: number | string\n /** The template definition (`TemplateDef`) when known: it may carry `tank` and `tankLocation` hooks. */\n template?: Record<string, unknown>\n options?: { floors?: number; [extra: string]: unknown }\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\n/** kg/m3 the plan structure weighs its parts with (the table of the Visor de casas 3D; a material outside it weighs like soft wood). */\nexport const DENSITY: Readonly<Record<string, number>> = {\n steel: 7850, cast_iron: 7200, aluminium: 2700, copper: 8900, wood_soft: 500, wood_hard: 800, plywood: 600, mdf: 750, glass: 2500,\n tempered_glass: 2500, ceramic: 2000, concrete: 2400, brick: 1800, plaster: 1000, stone: 2600, plastic: 950, rubber: 1100, fabric: 400,\n foam: 30, leather: 900, paper: 800, foliage: 100, green_wood: 900, cactus: 700, flesh_fruit: 900, wax: 900, soil: 1600,\n}\nexport const DEFAULT_DENSITY = 500\n\nexport const densityOf = (material: MaterialId): number => DENSITY[material] ?? DEFAULT_DENSITY\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { densityOf } from '../density'\nimport { round2 } from '../geometry'\nimport { GROUND } from '../types'\nimport type { PartRole, Rect, StructurePart, Support } from '../types'\n\nexport type PartExtras = Partial<Pick<StructurePart, 'host' | 'exterior' | 'spacing' | 'beamKind' | 'steps' | 'door' | 'cover' | 'studs' | 'pitch' | 'tent' | 'form' | 'liters' | 'assembly' | 'footprint'>>\nexport interface PartOptions extends PartExtras {\n floor?: number\n /** Solid fraction of the box (studs, trusses, tile roofs). */\n fill?: number\n}\n\nexport interface PartDraft {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n}\n\n/** Collects the parts and what each rests on. A part id is unique: a second one is a bug of the builder. */\nexport class StructureBuilder {\n readonly parts: StructurePart[] = []\n readonly supports: Support[] = []\n private readonly ids = new Set<string>()\n\n add(draft: PartDraft, options: PartOptions = {}): StructurePart {\n const { id, role, material, aabb, y0, y1 } = draft\n if (this.ids.has(id)) throw new Error(`Part repeated in the structure: ${id}`)\n this.ids.add(id)\n const { floor, fill, ...extras } = options\n const volume = Math.max(0, (aabb[2] - aabb[0]) * (aabb[3] - aabb[1]) * (y1 - y0)) * (fill ?? 1)\n const part: StructurePart = {\n id, role, material, aabb: aabb.map(round2) as Rect, y0: round2(y0), y1: round2(y1), floor: floor ?? 0,\n mass: Math.max(1, Math.round(volume * densityOf(material))),\n }\n for (const [key, value] of Object.entries(extras)) if (value !== undefined) (part as unknown as Record<string, unknown>)[key] = value\n this.parts.push(part)\n return part\n }\n\n rest(part: StructurePart | string, on: StructurePart | string, joint: JointKind): void {\n const id = typeof part === 'string' ? part : part.id\n const base = typeof on === 'string' ? on : on.id\n this.supports.push({ part: id, on: base === GROUND ? GROUND : base, joint })\n }\n\n has(id: string): boolean {\n return this.ids.has(id)\n }\n\n find(id: string): StructurePart | undefined {\n return this.parts.find((part) => part.id === id)\n }\n}\n","/** The string hash of the floor plan engine (`engine.hashString`), copied so that this package never imports the engine at run time. */\nexport function hashLegacyKey(key: string): number {\n let hash = 1779033703 ^ key.length\n for (let i = 0; i < key.length; i++) {\n hash = Math.imul(hash ^ key.charCodeAt(i), 3432918353)\n hash = (hash << 13) | (hash >>> 19)\n }\n hash = Math.imul(hash ^ (hash >>> 16), 2246822507)\n hash = Math.imul(hash ^ (hash >>> 13), 3266489909)\n return (hash ^ (hash >>> 16)) >>> 0\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\nimport { unionOf, wallBox, round2 } from '../geometry'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\nimport type { ConstructionSystemDef } from '../registry'\nimport { GROUND } from '../types'\nimport type { Construction, PartRole, Rect, Roof, StructureExtras, StructurePart, StructureSource, WaterTank, SourceWall } from '../types'\nimport { StructureBuilder } from './builder'\nimport { hashLegacyKey } from './legacy-key'\n\nexport const OPEN_ROOM_TYPES: readonly string[] = ['balcony', 'terrace', 'porch']\nconst GUARD_HEIGHT = 1.1\n\nexport interface BuildWall extends SourceWall {\n id: string\n /** The id the Visor de casas 3D gave the wall (`w<floor>_<index>`); seeded choices hash it so old seeds keep their draws. */\n legacyKey: string\n role: PartRole\n material: MaterialId\n box: Rect\n}\n\nexport interface PorchPosts {\n posts: StructurePart[]\n ceilingY: number\n}\n\ntype Base = StructurePart | typeof GROUND | undefined\n\n/** Everything the steps that build the structure share: the plan, the construction, the parts so far and what each storey rests on. */\nexport interface BuildContext {\n source: StructureSource\n construction: Construction\n system: ConstructionSystemDef\n extras: StructureExtras\n tank: WaterTank | null\n builder: StructureBuilder\n porchRoofOnPostsOnly: boolean\n /** Gable roofs are built as rafters of each side plus a ridge beam, so a side falls with the wall it rests on. */\n rafterRoof: boolean\n /** Most metres between the pillars along a masonry wall (`StructureOptions.wallPillars`); 0: only the corner pillars. */\n wallPillarSpacing: number\n /** `StructureOptions.visorSections`. */\n visorSections: boolean\n floorCount: number\n isUnit: boolean\n elevation: number\n isTimber: boolean\n walls: BuildWall[]\n wallParts: Map<string, StructurePart>\n /** The ground beam under each ground-floor masonry wall, by wall id (`addGroundBeams`). */\n groundBeams: Map<string, StructurePart>\n carriers: Map<number, StructurePart[]>\n plates: Map<number, StructurePart[]>\n pillars: Map<number, StructurePart[]>\n porches: Map<string, PorchPosts>\n base0: Base\n houseBox: Rect\n topBox: Rect\n hasBasement: boolean\n topSlab?: StructurePart\n ceilingJoists?: StructurePart[]\n roof: Roof\n level(floor: number): number\n ceilingOf(floor: number): number\n topOf(floor: number): number\n rectsOf(floor: number, exclude?: readonly string[]): Rect[]\n baseOf(floor: number): Base\n}\n\nexport interface ContextOptions {\n porchRoofOnPostsOnly: boolean\n rafterRoof: boolean\n wallPillarSpacing: number\n visorSections: boolean\n}\n\nexport function createContext(source: StructureSource, construction: Construction, extras: StructureExtras, tank: WaterTank | null, options: ContextOptions): BuildContext {\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)\n if (!system) throw new Error(`Unknown construction system \"${construction.system}\"`)\n const floorCount = source.floors.length\n const isUnit = source.floorNumber !== undefined\n const elevation = construction.foundation.elevation || 0\n const level = (floor: number): number => round2(elevation + (source.floors[floor]?.y0 ?? 0))\n const ceilingOf = (floor: number): number => source.floors[floor]?.ceiling ?? 0\n const topOf = (floor: number): number => (floor < floorCount - 1 && !isUnit ? level(floor + 1) - system.slabThickness : level(floor) + ceilingOf(floor))\n const rectsOf = (floor: number, exclude: readonly string[] = []): Rect[] =>\n source.rooms.filter((room) => room.floor === floor && !exclude.includes(room.type)).flatMap((room) => room.parts)\n const builder = new StructureBuilder()\n const context: BuildContext = {\n source, construction, system, extras, tank, builder, porchRoofOnPostsOnly: options.porchRoofOnPostsOnly, rafterRoof: options.rafterRoof, wallPillarSpacing: options.wallPillarSpacing, visorSections: options.visorSections, floorCount, isUnit, elevation, isTimber: system.timber,\n walls: [], wallParts: new Map(), groundBeams: new Map(), carriers: new Map(), plates: new Map(), pillars: new Map(), porches: new Map(), base0: GROUND,\n houseBox: [0, 0, 0, 0], topBox: [0, 0, 0, 0], hasBasement: false,\n roof: { shape: 'slab', covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n level, ceilingOf, topOf, rectsOf,\n baseOf: (floor) => (floor === 0 ? context.base0 : builder.find(`slab_${floor}`)),\n }\n const closed = rectsOf(0, ['balcony', 'porch'])\n context.houseBox = unionOf(closed.length ? closed : rectsOf(0))\n context.walls = classifyWalls(context)\n return context\n}\n\nconst isBearingOnTop = (wall: BuildWall, walls: readonly BuildWall[]): boolean => {\n const along = (w: SourceWall, pick: (a: number, b: number) => number): number => (w.axis === 'u' ? pick(w.u0, w.u1) : pick(w.v0, w.v1))\n const across = (w: SourceWall): number => (w.axis === 'u' ? w.v0 : w.u0)\n return walls.some(\n (other) =>\n other.floor === wall.floor + 1 && other.type === 'wall' && other.axis === wall.axis && Math.abs(across(other) - across(wall)) < 0.2 &&\n Math.min(along(wall, Math.max), along(other, Math.max)) - Math.max(along(wall, Math.min), along(other, Math.min)) > 0.3,\n )\n}\n\nfunction roleOf(context: BuildContext, wall: BuildWall, walls: readonly BuildWall[], porchIds: ReadonlySet<string>): PartRole {\n if (wall.type === 'railing') return 'partition'\n const { wallRole } = context.system\n if (wallRole === 'bearing') return 'wall'\n if (wallRole === 'partition') return 'partition'\n const bearingFloor = context.construction.roof.bearingFloor ?? context.floorCount - 1\n if (wall.floor > bearingFloor) return 'partition'\n if (wall.exterior || wall.sides.some((id) => porchIds.has(id))) return 'wall'\n return wall.floor < context.floorCount - 1 && isBearingOnTop(wall, walls) ? 'wall' : 'partition'\n}\n\nfunction materialOf(context: BuildContext, wall: BuildWall): MaterialId {\n const { walls, guard } = context.construction\n if (wall.type === 'railing') return guard ?? (context.isTimber ? 'wood_soft' : 'steel')\n if (walls.mixed?.length) return walls.mixed[hashLegacyKey(wall.legacyKey) % walls.mixed.length] as MaterialId\n return wall.exterior ? walls.material : (walls.interior ?? walls.material)\n}\n\nfunction classifyWalls(context: BuildContext): BuildWall[] {\n const countByFloor = new Map<number, number>()\n const all: BuildWall[] = context.source.walls.map((wall) => {\n const index = countByFloor.get(wall.floor) ?? 0\n countByFloor.set(wall.floor, index + 1)\n return { ...wall, id: `wall_${wall.floor}_${index}`, legacyKey: `w${wall.floor}_${index}`, role: 'wall', material: '', box: wallBox(wall) }\n })\n const built = all.filter((wall) => wall.type === 'wall' || wall.type === 'railing')\n const porchIds = new Set(context.source.rooms.filter((room) => room.type === 'porch').map((room) => room.id))\n for (const wall of built) {\n wall.role = roleOf(context, wall, built, porchIds)\n wall.material = materialOf(context, wall)\n }\n return built\n}\n\nexport const guardHeightOf = (wall: BuildWall): number => wall.h || GUARD_HEIGHT\n","import { GROUND } from '../types'\nimport { unionOf } from '../geometry'\nimport type { BuildContext } from './context'\n\n/** Cantilevered balconies: a slab tied to the floor of its storey, or on a pillar of its own when it is at ground level. */\nexport function addBalconies(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'balcony' && r.floor >= 0)) {\n const floor = room.floor\n const box = unionOf(room.parts)\n const base = floor === 0 ? undefined : context.baseOf(floor)\n const deck = builder.add({ id: `slab_${floor}_${room.id}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(floor) - system.slabThickness, y1: context.level(floor) }, { floor })\n if (base) {\n builder.rest(deck, base, system.joints.slab)\n continue\n }\n // a 20 cm pillar (NBR 6118); the Visor de casas 3D drew 16 cm\n const half = context.visorSections ? 0.08 : 0.1\n const pillar = builder.add({ id: `balcony_column_${room.id}`, role: 'column', material: construction.frame.pillars, aabb: [box[0] - half, box[1] - half, box[0] + half, box[1] + half], y0: 0, y1: context.level(floor) - system.slabThickness }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n builder.rest(deck, pillar, 'rebar')\n }\n}\n","import { GROUND } from '../types'\nimport type { Construction, Rect, Roof, Structure, StructureExtras } from '../types'\nimport { StructureBuilder } from './builder'\n\nconst GROUNDSHEET = 0.02\n\n/** Camping tents: canvas over aluminium poles, a plastic groundsheet and pegs with guy ropes; no walls. */\nexport function buildCanvasStructure(construction: Construction, extras: StructureExtras): Structure {\n const builder = new StructureBuilder()\n const panes: string[] = []\n for (const tent of extras.tents ?? []) {\n const [u0, v0, u1, v1] = tent.aabb\n const centreU = (u0 + u1) / 2\n const centreV = (v0 + v1) / 2\n const sheet = builder.add({ id: `groundsheet_${tent.id}`, role: 'slab', material: 'plastic', aabb: tent.aabb, y0: 0, y1: GROUNDSHEET }, { floor: 0, tent: tent.id })\n builder.rest(sheet, GROUND, 'resting')\n const canvas = builder.add({ id: `canvas_${tent.id}`, role: 'roof', material: 'fabric', aabb: tent.aabb, y0: GROUNDSHEET, y1: tent.height }, { floor: 0, fill: 0.04, tent: tent.id, form: tent.kind })\n panes.push(canvas.id)\n const poles: [Rect, number][] =\n tent.kind === 'tunnel'\n ? [0.25, 0.75].map((fraction, k): [Rect, number] => [[u0 + (u1 - u0) * fraction - 0.015, v0 + 0.05, u0 + (u1 - u0) * fraction + 0.015, v1 - 0.05], k])\n : [[[u0 + 0.05, centreV - 0.015, u1 - 0.05, centreV + 0.015], 0], [[centreU - 0.015, v0 + 0.05, centreU + 0.015, v1 - 0.05], 1]]\n for (const [aabb, k] of poles) {\n const pole = builder.add({ id: `pole_${tent.id}_${k}`, role: 'column', material: construction.frame.pillars, aabb, y0: GROUNDSHEET, y1: tent.height - GROUNDSHEET }, { floor: 0, fill: 0.05, tent: tent.id })\n builder.rest(pole, GROUND, 'resting')\n builder.rest(canvas, pole, 'tie')\n }\n const corners: [number, number][] = [[u0 - 0.2, v0 - 0.2], [u1 + 0.2, v0 - 0.2], [u0 - 0.2, v1 + 0.2], [u1 + 0.2, v1 + 0.2]]\n corners.forEach(([u, v], k) => {\n const peg = builder.add({ id: `peg_${tent.id}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - 0.02, v - 0.02, u + 0.02, v + 0.02], y0: 0, y1: 0.2 }, { floor: 0 })\n builder.rest(peg, GROUND, 'nail')\n builder.rest(canvas, peg, 'tie')\n })\n }\n const roof: Roof = { shape: 'tent', covering: 'canvas', material: 'fabric', pitch: 0, bearingFloor: 0, panes, trusses: 0 }\n return { parts: builder.parts, supports: builder.supports, levels: [0], elevation: 0, roof, construction, framed: false, openings: [] }\n}\n","import { GROUND } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst CHIMNEY_CLEARANCE_ABOVE_RIDGE = 0.6\n\n/** A masonry chimney or a stove flue next to the house, tied to the wall it touches, rising above the ridge. */\nexport function addChimney(context: BuildContext): void {\n const chimney = context.extras.chimney\n if (!chimney) return\n const { builder } = context\n const top = context.floorCount - 1\n const ridge = context.roof.ridge || context.level(top) + context.ceilingOf(top)\n const height = Math.max(ridge, chimney.top || 0) + CHIMNEY_CLEARANCE_ABOVE_RIDGE\n const part = builder.add({ id: 'chimney', role: 'column', material: chimney.material || 'brick', aabb: chimney.aabb, y0: chimney.flue ? context.level(0) : 0, y1: height }, { floor: 0, fill: chimney.flue ? 0.15 : 0.7 })\n if (chimney.flue) builder.rest(part, context.base0 ?? GROUND, 'resting')\n else builder.rest(part, GROUND, 'mortar')\n const walls = builder.parts.filter((wall) => wall.role === 'wall' && wall.floor === 0 && !wall.id.startsWith('basement') && touches(wall.aabb, part.aabb, 0.1))\n for (const wall of walls) builder.rest(part, wall, 'bolt')\n chimney.height = round2(height)\n}\n\n/** The stone mouth of a well. */\nexport function addWell(context: BuildContext): void {\n const well = context.extras.well\n if (!well) return\n const part = context.builder.add({ id: 'well', role: 'column', material: 'stone', aabb: well.aabb, y0: -0.5, y1: well.height || 0.9 }, { floor: 0, fill: 0.5 })\n context.builder.rest(part, GROUND, 'mortar')\n}\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, touches } from '../geometry'\nimport type { Rect, StructurePart } from '../types'\nimport type { BuildContext } from './context'\n\nexport interface JoistOptions {\n floor: number\n box: Rect\n thickness: number\n carriers: readonly StructurePart[]\n material: MaterialId\n joint: JointKind\n suffix?: string\n}\n\nconst JOIST_PITCH = 0.6\n\n/** Joists every 0.6 m under the floor of `floor`, each resting on what touches it from below (or the nearest carrier). */\nexport function addJoists(context: BuildContext, options: JoistOptions): StructurePart[] {\n const { floor, box, thickness, carriers, material, joint, suffix = '' } = options\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / JOIST_PITCH) + 1)\n const top = context.level(floor) - thickness * 0.15\n const out: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const centre = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [centre - 0.025, box[1], centre + 0.025, box[3]] : [box[0], centre - 0.025, box[2], centre + 0.025]\n const joist = context.builder.add({ id: `joist_${floor}${suffix}_${k}`, role: 'beam', material, aabb, y0: context.level(floor) - thickness, y1: top }, { floor, fill: 1, spacing: JOIST_PITCH })\n out.push(joist)\n const below = carriers.filter((carrier) => carrier.y0 <= top + 0.05)\n const touching = below.filter((carrier) => touches(aabb, carrier.aabb, 0.2))\n const pool = below.length ? below : carriers\n const chosen = touching.length ? touching : pool.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 1)\n for (const carrier of chosen) context.builder.rest(joist, carrier, joint)\n }\n return out\n}\n\n/** The deck (floor boards, slab) of `floor` on its joists. */\nexport function addDeck(context: BuildContext, id: string, material: MaterialId, options: Pick<JoistOptions, 'floor' | 'box' | 'thickness' | 'joint'>, joists: readonly StructurePart[]): StructurePart {\n const { floor, box, thickness, joint } = options\n const deck = context.builder.add({ id, role: 'slab', material, aabb: box, y0: context.level(floor) - thickness * 0.15, y1: context.level(floor) }, { floor })\n for (const joist of joists) context.builder.rest(deck, joist, joint)\n return deck\n}\n","import type { StructurePart, Rect } from '../types'\nimport { GROUND } from '../types'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\nconst raft = (context: BuildContext, thickness: number, material: string): StructurePart => {\n const [u0, v0, u1, v1] = context.houseBox\n const part = context.builder.add({ id: 'foundation_raft', role: 'slab', material, aabb: [u0 - 0.1, v0 - 0.1, u1 + 0.1, v1 + 0.1], y0: 0, y1: thickness }, { floor: 0 })\n context.builder.rest(part, GROUND, 'resting')\n return part\n}\n\n/** A unit in a building: the building's pillars go down to the ground and carry a slab under the unit. */\nfunction addBuildingBase(context: BuildContext): void {\n const { builder, construction, houseBox: box } = context\n const corners: [number, number][] = [[box[0], box[1]], [box[2], box[1]], [box[0], box[3]], [box[2], box[3]]]\n const top = context.level(0) - context.system.slabThickness\n const pillars = corners.map(([u, v], k) => {\n const pillar = builder.add({ id: `building_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: 0, y1: top }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'slab_base', role: 'slab', material: construction.frame.slabs, aabb: box, y0: top, y1: context.level(0) }, { floor: 0, footprint: [box] })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n context.base0 = slab\n}\n\nfunction addBasement(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation } = context\n const depth = context.construction.foundation.depth || 2.4\n const floor = builder.add({ id: 'basement_slab', role: 'slab', material: 'concrete', aabb: box, y0: -depth - 0.15, y1: -depth }, { floor: -1 })\n builder.rest(floor, GROUND, 'resting')\n const sides: [string, Rect][] = [\n ['front', [box[0], box[1] - 0.1, box[2], box[1] + 0.1]], ['back', [box[0], box[3] - 0.1, box[2], box[3] + 0.1]],\n ['left', [box[0] - 0.1, box[1], box[0] + 0.1, box[3]]], ['right', [box[2] - 0.1, box[1], box[2] + 0.1, box[3]]],\n ]\n const carried: StructurePart[] = []\n for (const [name, aabb] of sides) {\n const wall = builder.add({ id: `basement_wall_${name}`, role: 'wall', material: 'concrete', aabb, y0: -depth, y1: elevation }, { floor: -1 })\n builder.rest(wall, GROUND, 'rebar')\n builder.rest(wall, floor, 'rebar')\n carried.push(wall)\n }\n const count = Math.max(1, Math.floor((box[2] - box[0]) / 3.0))\n for (let k = 0; k < count; k++) {\n const u = box[0] + ((k + 0.5) * (box[2] - box[0])) / count\n const v = (box[1] + box[3]) / 2\n const column = builder.add({ id: `basement_column_${k}`, role: 'column', material: 'concrete', aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: -depth, y1: elevation - 0.3 }, { floor: -1 })\n builder.rest(column, floor, 'rebar')\n builder.rest(column, GROUND, 'rebar')\n carried.push(column)\n }\n context.hasBasement = true\n return carried\n}\n\n/** Pier footings every ~2 m with a base beam through each line of them (crawl space, piles). */\nfunction addPiers(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation, construction } = context\n const columns = Math.max(2, Math.ceil((box[2] - box[0]) / 2.0) + 1)\n const rows = Math.max(2, Math.ceil((box[3] - box[1]) / 2.0) + 1)\n const height = Math.max(0.1, elevation - context.system.slabThickness - 0.15)\n const piers: StructurePart[] = []\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < columns; i++) {\n const u = box[0] + (i * (box[2] - box[0])) / (columns - 1)\n const v = box[1] + (j * (box[3] - box[1])) / (rows - 1)\n const pier = builder.add({ id: `footing_pier_${j}_${i}`, role: 'column', material: construction.foundation.material || 'concrete', aabb: [u - 0.12, v - 0.12, u + 0.12, v + 0.12], y0: 0, y1: height }, { floor: 0 })\n builder.rest(pier, GROUND, 'resting')\n piers.push(pier)\n }\n }\n const alongU = box[2] - box[0] >= box[3] - box[1]\n const beams: StructurePart[] = []\n const lines = alongU ? rows : columns\n for (let line = 0; line < lines; line++) {\n const at = alongU ? box[1] + (line * (box[3] - box[1])) / (rows - 1) : box[0] + (line * (box[2] - box[0])) / (columns - 1)\n const aabb: Rect = alongU ? [box[0], at - 0.07, box[2], at + 0.07] : [at - 0.07, box[1], at + 0.07, box[3]]\n const beam = builder.add({ id: `base_beam_${line}`, role: 'beam', material: construction.frame.timber, aabb, y0: height, y1: elevation - context.system.slabThickness }, { floor: 0 })\n const centre = (q: StructurePart): number => (alongU ? (q.aabb[1] + q.aabb[3]) / 2 : (q.aabb[0] + q.aabb[2]) / 2)\n for (const pier of piers.filter((q) => Math.abs(centre(q) - at) < 0.05)) builder.rest(beam, pier, 'bolt')\n beams.push(beam)\n }\n return beams\n}\n\nfunction addRaisedFloor(context: BuildContext): void {\n const { construction, system, houseBox: box } = context\n const carriers = construction.foundation.type === 'basement' ? addBasement(context) : addPiers(context)\n const thickness = system.slabThickness\n const joists = addJoists(context, { floor: 0, box, thickness, carriers, material: construction.frame.timber, joint: construction.foundation.type === 'basement' ? 'bolt' : 'nail' })\n const deckMaterial = context.isTimber ? (construction.floor.material === 'wood_hard' ? 'wood_hard' : 'plywood') : construction.frame.slabs\n context.base0 = addDeck(context, 'slab_0', deckMaterial, { floor: 0, box, thickness, joint: 'nail' }, joists)\n}\n\n/** Foundation and floor of the ground storey: raft, crawl space, piles, basement, a unit's building base or nothing (strip footing). */\nexport function addFoundation(context: BuildContext): void {\n const { type, material } = context.construction.foundation\n if (context.isUnit) return addBuildingBase(context)\n if (type === 'raft') context.base0 = raft(context, Math.max(0.1, context.elevation), material || 'concrete')\n else if (type === 'crawl_space' || type === 'piles' || type === 'basement') addRaisedFloor(context)\n else if (context.isTimber && type !== 'ground') context.base0 = raft(context, Math.max(0.12, context.elevation), 'concrete')\n}\n","import { GROUND } from '../types'\nimport type { StructurePart } from '../types'\nimport type { BuildContext } from './context'\n\n/** Depth of the ground beam (viga baldrame) under a ground-floor masonry wall, metres: the usual 15 x 30 cm, as wide as the wall. */\nexport const GROUND_BEAM_DEPTH = 0.3\n\n/**\n * The ground beams of a masonry house on strip footings: one reinforced concrete beam under each ground-floor wall, buried with its top at the floor, cast\n * on the footing. The wall stands on it instead of on the soil; the pillars go down through it to the footing.\n */\nexport function addGroundBeams(context: BuildContext): void {\n const { builder, construction } = context\n if (construction.system !== 'masonry' || context.isUnit || construction.foundation.type !== 'strip_footing') return\n const top = context.level(0)\n for (const wall of context.walls) {\n if (wall.floor !== 0 || wall.type !== 'wall') continue\n const beam: StructurePart = builder.add({ id: `ground_beam_${context.groundBeams.size}`, role: 'beam', material: construction.frame.beams, aabb: wall.box, y0: top - GROUND_BEAM_DEPTH, y1: top }, { floor: 0, beamKind: 'ground_beam' })\n builder.rest(beam, GROUND, 'rebar')\n context.groundBeams.set(wall.id, beam)\n }\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext, BuildWall } from './context'\n\n/**\n * Most a masonry wall runs between two of its concrete pillars, metres. Confined masonry (alvenaria confinada / de vedação with a concrete frame) puts a pillar\n * every 3 to 5 m, at the corners, where walls meet and beside the openings; 4 m is the middle of that range.\n */\nexport const WALL_PILLAR_SPACING = 4\n/** Side of a wall pillar, metres: 0.2 x 0.2 m, as the corner pillars (NBR 6118 asks at least 19 cm for a pillar). */\nexport const WALL_PILLAR_SIDE = 0.2\n/** Two pillars closer than this along a wall are one (the corner pillar or a jamb pillar already stands there). */\nconst MERGE_DISTANCE = 0.45\nconst HALF = WALL_PILLAR_SIDE / 2\nconst TOLERANCE = 0.03\n\ninterface Stretch {\n wall: BuildWall\n from: number\n to: number\n}\n\nconst alongRange = (wall: BuildWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\nconst acrossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\n\n/** The solid stretches of a wall: the wall cut at its windows (a door is already a gap between two walls). */\nfunction stretchesOf(context: BuildContext, wall: BuildWall): Stretch[] {\n const [low, high] = alongRange(wall)\n const windows = (context.source.windows ?? [])\n .filter((w) => w.floor === wall.floor && w.axis === wall.axis && Math.abs(w.pos - acrossOf(wall)) <= TOLERANCE && w.at + w.width / 2 > low && w.at - w.width / 2 < high)\n .map((w): [number, number] => [w.at - w.width / 2, w.at + w.width / 2])\n .sort((a, b) => a[0] - b[0])\n const out: Stretch[] = []\n let cursor = low\n for (const [from, to] of windows) {\n if (from - cursor > TOLERANCE) out.push({ wall, from: cursor, to: from })\n cursor = Math.max(cursor, to)\n }\n if (high - cursor > TOLERANCE) out.push({ wall, from: cursor, to: high })\n return out\n}\n\n/** Where another wall meets this one inside its length (a T): the along coordinates of the meeting points. */\nfunction junctionsOf(context: BuildContext, wall: BuildWall): number[] {\n const [low, high] = alongRange(wall)\n const line = acrossOf(wall)\n const out: number[] = []\n for (const other of context.walls) {\n if (other === wall || other.floor !== wall.floor || other.axis === wall.axis || other.type !== 'wall') continue\n const at = acrossOf(other)\n const [a, b] = alongRange(other)\n const meets = Math.abs(a - line) <= (wall.thickness ?? 0.15) / 2 + TOLERANCE || Math.abs(b - line) <= (wall.thickness ?? 0.15) / 2 + TOLERANCE\n if (meets && at > low + HALF && at < high - HALF) out.push(at)\n }\n return out\n}\n\n/**\n * Centres of the pillars of a stretch: at each end (inside the stretch, flush with it), at the walls that meet it, and in between so that no span passes\n * `spacing`. A short pier still gets one at each end (a door jamb beside a corner keeps its own pillar; `addWallPillars` drops the one a pillar already\n * stands near); one too short for two gets one in its middle, and one too short for a pillar none.\n */\nexport function pillarStations(from: number, to: number, junctions: readonly number[], spacing: number): number[] {\n const length = to - from\n if (length < WALL_PILLAR_SIDE - 1e-6) return []\n if (length < 2 * WALL_PILLAR_SIDE) return [(from + to) / 2]\n if (length < WALL_PILLAR_SIDE + MERGE_DISTANCE) return [from + HALF, to - HALF]\n const fixed = [from + HALF, ...junctions.filter((at) => at > from + HALF + MERGE_DISTANCE && at < to - HALF - MERGE_DISTANCE), to - HALF].sort((a, b) => a - b)\n const out: number[] = []\n fixed.forEach((at, k) => {\n out.push(at)\n const next = fixed[k + 1]\n if (next === undefined) return\n const spans = Math.ceil((next - at) / spacing - 1e-6)\n for (let s = 1; s < spans; s++) out.push(at + ((next - at) * s) / spans)\n })\n return out\n}\n\n/**\n * Concrete pillars along the exterior masonry walls of a storey, besides the corner pillars: at the free ends and door jambs, beside the windows, where an\n * inner wall meets them and at most every `spacing` metres. Each is as deep as the wall's centre line (0.2 x 0.2 m, so it sits in the wall under the\n * plaster), rests on what the storey rests on and carries the bond beam over it, so the bond beam stands on the pillars when the bricks under it go.\n */\nexport function addWallPillars(context: BuildContext, walls: readonly BuildWall[], floor: number, plates: readonly StructurePart[], taken: readonly StructurePart[], spacing: number): StructurePart[] {\n const { builder } = context\n const pillars: StructurePart[] = []\n const placed: [number, number][] = taken.map((p) => [(p.aabb[0] + p.aabb[2]) / 2, (p.aabb[1] + p.aabb[3]) / 2])\n const base = context.baseOf(floor)\n for (const wall of walls) {\n if (!wall.exterior || wall.type !== 'wall') continue\n const top = context.wallParts.get(wall.id)!.y1\n const across = acrossOf(wall)\n const junctions = junctionsOf(context, wall)\n for (const stretch of stretchesOf(context, wall)) {\n // a pillar already standing at an end of the stretch (a corner, the end of the next wall) is where the spacing counts from\n const standing = (end: number): number | undefined => placed.map(([pu, pv]) => (wall.axis === 'u' ? [pu, pv] : [pv, pu]) as [number, number]).find(([a, c]) => Math.abs(c - across) <= TOLERANCE && Math.abs(a - end) < MERGE_DISTANCE + HALF)?.[0]\n const first = standing(stretch.from)\n const last = standing(stretch.to)\n const from = first === undefined ? stretch.from : Math.min(stretch.from, first - HALF)\n const to = last === undefined ? stretch.to : Math.max(stretch.to, last + HALF)\n for (const along of pillarStations(from, to, junctions, spacing)) {\n const [u, v] = wall.axis === 'u' ? [along, across] : [across, along]\n // a pillar near the end of a stretch only stands for it when it is near the end itself (a short pier keeps its jamb pillar)\n const end = Math.abs(along - stretch.from) < Math.abs(along - stretch.to) ? stretch.from : stretch.to\n const endPoint = wall.axis === 'u' ? [end, across] : [across, end]\n const isEnd = Math.abs(along - end) <= HALF + TOLERANCE\n if (placed.some(([pu, pv]) => Math.hypot(pu - u, pv - v) < MERGE_DISTANCE && (!isEnd || Math.hypot(pu - endPoint[0]!, pv - endPoint[1]!) < MERGE_DISTANCE))) continue\n placed.push([u, v])\n const box: Rect = [u - HALF, v - HALF, u + HALF, v + HALF]\n const pillar = builder.add({ id: `wall_column_${floor}_${pillars.length}`, role: 'column', material: context.construction.frame.pillars, aabb: box, y0: context.level(floor), y1: top }, { floor })\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n for (const plate of plates.filter((p) => touches(p.aabb, box, 0.01))) builder.rest(plate, pillar, 'rebar')\n pillars.push(pillar)\n }\n }\n }\n return pillars\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext, BuildWall } from './context'\nimport { addWallPillars } from './wall-pillars'\n\nconst MAX_GAP_WITHIN_RUN = 3.2\nconst POST_SPACING = 2.4\nconst POST_SIDE = 0.05\n\ninterface Run {\n from: number\n to: number\n walls: BuildWall[]\n}\n\nconst alongOf = (wall: BuildWall, pick: (a: number, b: number) => number): number => (wall.axis === 'u' ? pick(wall.u0, wall.u1) : pick(wall.v0, wall.v1))\nconst acrossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\n\n/** Continuous runs of exterior wall on one line and height: a plate or bond beam runs along each. */\nfunction runsOf(context: BuildContext, walls: readonly BuildWall[], floor: number): Run[][] {\n const lines = new Map<string, BuildWall[]>()\n for (const wall of walls) {\n if (!wall.exterior || wall.type !== 'wall') continue\n const top = round2(context.wallParts.get(wall.id)!.y1)\n const key = `${floor}|${wall.axis}|${acrossOf(wall).toFixed(2)}|${top.toFixed(2)}`\n lines.set(key, [...(lines.get(key) ?? []), wall])\n }\n return [...lines.values()].map((line) => {\n const sorted = line.slice().sort((a, b) => alongOf(a, Math.min) - alongOf(b, Math.min))\n const runs: Run[] = []\n for (const wall of sorted) {\n const from = alongOf(wall, Math.min)\n const to = alongOf(wall, Math.max)\n const last = runs[runs.length - 1]\n if (last && from - last.to <= MAX_GAP_WITHIN_RUN) {\n last.to = Math.max(last.to, to)\n last.walls.push(wall)\n } else runs.push({ from, to, walls: [wall] })\n }\n return runs\n })\n}\n\n/** Timber posts of a shack: the corner and every ~2.4 m carry the plate; the sheet walls only close. */\nfunction addShackPosts(context: BuildContext, run: Run, plate: StructurePart, floor: number, index: number): StructurePart[] {\n const first = run.walls[0]!\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const count = Math.max(1, Math.ceil((run.to - run.from) / POST_SPACING))\n const posts: StructurePart[] = []\n for (let k = 0; k <= count; k++) {\n const along = run.from + ((run.to - run.from) * k) / count\n const [u, v] = first.axis === 'u' ? [along, across] : [across, along]\n const half = 0.05 + POST_SIDE / 2\n const post = context.builder.add({ id: `post_${floor}_${index}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - half, v - half, u + half, v + half], y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n if (base === GROUND || !base) context.builder.rest(post, GROUND, 'tie')\n else context.builder.rest(post, base, 'nail')\n context.builder.rest(plate, post, 'nail')\n posts.push(post)\n }\n return posts\n}\n\nexport interface PlatesResult {\n plates: StructurePart[]\n pillars: StructurePart[]\n}\n\nfunction addPlates(context: BuildContext, walls: readonly BuildWall[], floor: number): PlatesResult {\n const { builder, system, construction } = context\n const plates: StructurePart[] = []\n const pillars: StructurePart[] = []\n let counter = 0\n for (const runs of runsOf(context, walls, floor)) {\n for (const run of runs) {\n const first = run.walls[0]!\n const half = (first.thickness ?? 0.15) / 2\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const aabb: Rect = first.axis === 'u' ? [run.from - half, across - half, run.to + half, across + half] : [across - half, run.from - half, across + half, run.to + half]\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const plate = builder.add({ id: `plate_${floor}_${counter++}`, role: 'beam', material, aabb, y0: top, y1: top + system.plateThickness }, { floor, beamKind: context.isTimber ? 'plate' : 'bond_beam' })\n if (construction.system === 'improvised') pillars.push(...addShackPosts(context, run, plate, floor, counter))\n else for (const wall of run.walls) builder.rest(plate, context.wallParts.get(wall.id)!, system.joints.beam)\n plates.push(plate)\n }\n }\n return { plates, pillars }\n}\n\nfunction cornerPoints(walls: readonly BuildWall[]): [number, number][] {\n const ends = walls\n .filter((wall) => wall.exterior && wall.type === 'wall')\n .flatMap((wall): [number, number, string][] =>\n wall.axis === 'u'\n ? [[Math.min(wall.u0, wall.u1), wall.v0, 'u'], [Math.max(wall.u0, wall.u1), wall.v0, 'u']]\n : [[wall.u0, Math.min(wall.v0, wall.v1), 'v'], [wall.u0, Math.max(wall.v0, wall.v1), 'v']],\n )\n const points: [number, number][] = []\n for (const a of ends) {\n const joinsOtherAxis = ends.some((b) => b[2] !== a[2] && Math.hypot(a[0] - b[0], a[1] - b[1]) < 0.12)\n if (joinsOtherAxis && !points.some((q) => Math.hypot(q[0] - a[0], q[1] - a[1]) < 0.12)) points.push([a[0], a[1]])\n }\n return points\n}\n\n/** Concrete corner pillars of a masonry storey where two exterior walls of different axes meet; they run up to the highest plate they touch. */\nfunction addCornerPillars(context: BuildContext, walls: readonly BuildWall[], floor: number, plates: readonly StructurePart[]): StructurePart[] {\n const { builder } = context\n const topOfFloor = context.topOf(floor)\n return cornerPoints(walls).map(([u, v], k) => {\n const box: Rect = [u - 0.1, v - 0.1, u + 0.1, v + 0.1]\n const top = Math.max(topOfFloor, ...plates.filter((plate) => touches(plate.aabb, box, 0.05)).map((plate) => plate.y0))\n const pillar = builder.add({ id: `column_${floor}_${k}`, role: 'column', material: context.construction.frame.pillars, aabb: box, y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n for (const plate of plates.filter((p) => touches(p.aabb, pillar.aabb, 0.05))) builder.rest(plate, pillar, 'rebar')\n return pillar\n })\n}\n\n/** Plates (bond beams) over the exterior walls of a storey and, in masonry, the corner pillars and the pillars along the walls (`addWallPillars`); records what carries the storey above. */\nexport function addPlatesAndPillars(context: BuildContext, floor: number): void {\n const walls = context.walls.filter((wall) => wall.floor === floor)\n const { plates, pillars } = addPlates(context, walls, floor)\n if (context.construction.system === 'masonry') {\n const corners = addCornerPillars(context, walls, floor, plates)\n pillars.push(...corners)\n if (context.wallPillarSpacing) pillars.push(...addWallPillars(context, walls, floor, plates, corners, context.wallPillarSpacing))\n }\n context.pillars.set(floor, pillars)\n context.plates.set(floor, plates)\n const innerBearing = walls.filter((wall) => wall.role === 'wall' && !wall.exterior).map((wall) => context.wallParts.get(wall.id)!)\n context.carriers.set(floor, [...plates, ...pillars, ...innerBearing])\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst POST_HALF = 0.08\nconst FOOTING_HALF = 0.12\nconst BEAM_DEPTH = 0.2\nconst BEAM_WIDTH = 0.16\n\n/** Footings and posts under the porch roof: two at the front corners and one more in the middle of a wide porch. */\nfunction addPosts(context: BuildContext, porchId: string, rect: Rect, deck: StructurePart, floor: number): StructurePart[] {\n const { builder, construction } = context\n const hasUpperFloor = floor < context.floorCount - 1\n const ceilingY = hasUpperFloor ? context.level(floor + 1) - context.system.slabThickness : context.level(floor) + context.ceilingOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const spots: [number, number][] = [[rect[0] + 0.1, rect[1] + 0.1], [rect[2] - 0.1, rect[1] + 0.1]]\n if (rect[2] - rect[0] > 4.5) spots.push([(rect[0] + rect[2]) / 2, rect[1] + 0.1])\n const posts = spots.map(([u, v], k) => {\n const footing = builder.add({ id: `porch_footing_${porchId}_${k}`, role: 'column', material: 'concrete', aabb: [u - FOOTING_HALF, v - FOOTING_HALF, u + FOOTING_HALF, v + FOOTING_HALF], y0: 0, y1: context.level(floor) - deckDepth }, { floor: 0 })\n builder.rest(footing, GROUND, 'resting')\n builder.rest(deck, footing, 'resting')\n const material = context.isTimber ? construction.frame.timber : construction.frame.pillars\n const post = builder.add({ id: `porch_post_${porchId}_${k}`, role: 'column', material, aabb: [u - POST_HALF, v - POST_HALF, u + POST_HALF, v + POST_HALF], y0: context.level(floor), y1: hasUpperFloor ? ceilingY - BEAM_DEPTH : ceilingY }, { floor })\n builder.rest(post, deck, context.isTimber ? 'nail' : 'rebar')\n return post\n })\n context.porches.set(porchId, { posts, ceilingY })\n return posts\n}\n\n/** With a storey above the porch, a head beam over the posts and two side beams carry the floor of that storey. */\nfunction addUpperBeams(context: BuildContext, porchId: string, rect: Rect, posts: StructurePart[], floor: number): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const joint = context.isTimber ? 'nail' : 'rebar'\n const ceilingY = context.porches.get(porchId)!.ceilingY\n const y0 = ceilingY - BEAM_DEPTH\n const carriers = context.carriers.get(floor)!\n const head = builder.add({ id: `porch_beam_${porchId}`, role: 'beam', material, aabb: [rect[0], rect[1], rect[2], rect[1] + BEAM_WIDTH], y0, y1: ceilingY }, { floor })\n for (const post of posts) builder.rest(head, post, joint)\n carriers.push(head)\n const sides: [string, Rect, StructurePart][] = [['e', [rect[0], rect[1], rect[0] + BEAM_WIDTH, rect[3]], posts[0]!], ['d', [rect[2] - BEAM_WIDTH, rect[1], rect[2], rect[3]], posts[1]!]]\n for (const [name, aabb, post] of sides) {\n const side = builder.add({ id: `porch_beam_${porchId}_${name}`, role: 'beam', material, aabb, y0, y1: ceilingY }, { floor })\n builder.rest(side, post, joint)\n builder.rest(side, head, joint)\n for (const wall of context.walls.filter((w) => w.floor === floor && w.role === 'wall' && touches(w.box, side.aabb, 0.3))) builder.rest(side, context.wallParts.get(wall.id)!, joint)\n carriers.push(side)\n }\n}\n\n/** Deck, footings, posts (concrete in masonry, wood in timber houses) and, with a storey above, the beams of every porch of the storey. */\nexport function addPorches(context: BuildContext, floor: number): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch' && r.floor === floor)) {\n const rect = room.parts[0]!\n const base = context.baseOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const deck = builder.add({ id: `porch_floor_${room.id}`, role: 'slab', material: context.isTimber ? 'wood_soft' : construction.frame.slabs, aabb: rect, y0: context.level(floor) - deckDepth, y1: context.level(floor) }, { floor })\n if (base && base !== GROUND) builder.rest(deck, base, context.isTimber ? 'nail' : context.system.joints.slab)\n const posts = addPosts(context, room.id, rect, deck, floor)\n if (floor < context.floorCount - 1) addUpperBeams(context, room.id, rect, posts, floor)\n }\n}\n","import { ROOF_COVERINGS } from '../registry'\nimport type { BuildContext } from './context'\n\nconst ROOF_RISE = 0.6\n\n/** A porch under the top storey has a roof of its own, resting on its posts and on the wall of the house. */\nexport function addPorchRoofs(context: BuildContext): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const floor = room.floor\n const rect = room.parts[0]!\n const posts = context.porches.get(room.id)\n if (floor !== context.floorCount - 1 || !posts) continue\n const material = ROOF_COVERINGS.get(construction.roof.covering)?.material ?? 'ceramic'\n const roof = builder.add({ id: `porch_roof_${room.id}`, role: 'roof', material, aabb: [rect[0] - 0.3, rect[1] - 0.5, rect[2] + 0.3, rect[3]], y0: posts.ceilingY, y1: posts.ceilingY + ROOF_RISE }, { floor })\n for (const post of posts.posts) builder.rest(roof, post, context.isTimber ? 'nail' : 'bolt')\n const housewalls = context.walls.filter((w) => w.floor === floor && !w.exterior && w.sides.includes(room.id) && w.type === 'wall')\n for (const wall of housewalls) {\n if (context.porchRoofOnPostsOnly) builder.supports.push({ part: roof.id, on: wall.id, joint: 'nail', bears: false })\n else builder.rest(roof, context.wallParts.get(wall.id)!, 'nail')\n }\n }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, round2, touches, unionOf } from '../geometry'\nimport { ROOF_COVERINGS } from '../registry'\nimport type { Rect, RoofPane, StructurePart } from '../types'\nimport type { BuildContext } from './context'\nimport { OPEN_ROOM_TYPES } from './context'\n\nconst TRUSS_PITCH = 1.2\nconst DEFAULT_PITCH = 20\nconst DEFAULT_EAVE = 0.4\nconst CLOSED_ONLY: readonly string[] = [...OPEN_ROOM_TYPES, 'void']\n\ninterface RoofUnit {\n suffix: string\n box: Rect\n floor: number\n annex: boolean\n}\n\n/** The main roof, plus an own roof for every room of a lower storey that the storey above does not cover (a ground floor wider than the upper one). */\nfunction roofUnits(context: BuildContext, bearing: number): RoofUnit[] {\n const units: RoofUnit[] = [{ suffix: '', box: context.topBox, floor: bearing, annex: false }]\n if (context.floorCount <= 1 || context.isUnit || bearing !== context.floorCount - 1) return units\n for (let floor = 0; floor < context.floorCount - 1; floor++) {\n const above = context.source.rooms.filter((room) => room.floor === floor + 1).flatMap((room) => room.parts)\n const rooms = context.source.rooms.filter((room) => room.floor === floor && !OPEN_ROOM_TYPES.includes(room.type) && room.type !== 'void' && room.type !== 'elevator')\n for (const room of rooms) {\n const area = room.parts.reduce((total, part) => total + (part[2] - part[0]) * (part[3] - part[1]), 0)\n const covered = room.parts.reduce((total, part) => total + above.reduce((sum, other) => sum + Math.max(0, Math.min(part[2], other[2]) - Math.max(part[0], other[0])) * Math.max(0, Math.min(part[3], other[3]) - Math.max(part[1], other[1])), 0), 0)\n if (covered < area * 0.7) units.push({ suffix: `_${room.id}`, box: unionOf(room.parts), floor, annex: true })\n }\n }\n return units\n}\n\n/** Everything that carries the roof of one unit: the plates at its height, the pillars and the inner bearing walls under it. */\nfunction roofCarriers(context: BuildContext, unit: RoofUnit): StructurePart[] {\n const platesHere = context.plates.get(unit.floor) ?? []\n const allPlates = [...context.plates.values()].flat()\n const eaveHeight = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : 0\n const plates = allPlates.filter((plate) => Math.abs(plate.y1 - eaveHeight) < 0.4 && touches(plate.aabb, unit.box, 0.3))\n const pillars = (context.pillars.get(unit.floor) ?? []).filter((pillar) => touches(pillar.aabb, unit.box, 0.3))\n const walls = context.walls.filter((wall) => wall.floor === unit.floor && wall.role === 'wall' && !wall.exterior && touches(wall.box, unit.box, 0.2)).map((wall) => context.wallParts.get(wall.id)!)\n return [...plates, ...pillars, ...walls]\n}\n\nfunction addFlatRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[]): RoofPane {\n const { builder, construction, system } = context\n const top = context.level(unit.floor) + context.ceilingOf(unit.floor)\n const [u0, v0, u1, v1] = unit.box\n const slab = builder.add({ id: `slab_top${unit.suffix}`, role: 'slab', material: construction.frame.slabs, aabb: [u0 - 0.15, v0 - 0.15, u1 + 0.15, v1 + 0.15], y0: top, y1: top + 0.12 }, { floor: unit.floor, cover: true, footprint: [unit.box] })\n for (const carrier of carriers.length ? carriers : (context.plates.get(unit.floor) ?? [])) builder.rest(slab, carrier, system.joints.slab)\n if (unit.suffix === '') context.topSlab = slab\n return { id: slab.id, aabb: slab.aabb, y0: slab.y0, y1: slab.y1, flat: true }\n}\n\nfunction addTrusses(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): StructurePart[] {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const trusses: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const aabb: Rect = axis === 'u' ? [at - 0.04, box[1] - eave * 0.5, at + 0.04, box[3] + eave * 0.5] : [box[0] - eave * 0.5, at - 0.04, box[2] + eave * 0.5, at + 0.04]\n const truss = builder.add({ id: `truss${unit.suffix}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(truss, carrier, system.joints.truss)\n trusses.push(truss)\n }\n return trusses\n}\n\ninterface GableGeometry {\n axis: 'u' | 'v'\n length: number\n eave: number\n rise: number\n eaveY: number\n}\n\nfunction geometryOf(context: BuildContext, unit: RoofUnit): GableGeometry {\n const { box } = unit\n const roof = context.construction.roof\n const platesHere = context.plates.get(unit.floor) ?? []\n const width = box[2] - box[0]\n const depth = box[3] - box[1]\n const axis = roof.axis ?? (width >= depth ? 'u' : 'v')\n const span = axis === 'u' ? depth : width\n const pitch = unit.annex ? Math.min(roof.pitch || DEFAULT_PITCH, 20) : roof.pitch || DEFAULT_PITCH\n const eaveY = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : context.level(unit.floor) + context.ceilingOf(unit.floor)\n return { axis, length: axis === 'u' ? width : depth, eave: roof.eave ?? DEFAULT_EAVE, rise: round2((span / 2) * Math.tan((pitch * Math.PI) / 180)), eaveY }\n}\n\ninterface Frames {\n all: StructurePart[]\n sideA: StructurePart[]\n sideB: StructurePart[]\n}\n\n/** Rafters of each side at the truss positions, each resting only on what is under its own side, and a ridge beam that rests on all of them. */\nfunction addRafters(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const middle = axis === 'u' ? (box[1] + box[3]) / 2 : (box[0] + box[2]) / 2\n const frames: Frames = { all: [], sideA: [], sideB: [] }\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const halves: [string, Rect][] =\n axis === 'u'\n ? [['a', [at - 0.04, box[1] - eave * 0.5, at + 0.04, middle]], ['b', [at - 0.04, middle, at + 0.04, box[3] + eave * 0.5]]]\n : [['a', [box[0] - eave * 0.5, at - 0.04, middle, at + 0.04]], ['b', [middle, at - 0.04, box[2] + eave * 0.5, at + 0.04]]]\n for (const [side, aabb] of halves) {\n const rafter = builder.add({ id: `rafter${unit.suffix}_${side}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((x, y) => distanceBetween(aabb, x.aabb) - distanceBetween(aabb, y.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(rafter, carrier, system.joints.truss)\n frames.all.push(rafter)\n if (side === 'a') frames.sideA.push(rafter)\n else frames.sideB.push(rafter)\n }\n }\n if (!unit.annex) {\n const ridgeBox: Rect = axis === 'u' ? [box[0] - eave, middle - 0.05, box[2] + eave, middle + 0.05] : [middle - 0.05, box[1] - eave, middle + 0.05, box[3] + eave]\n const ridge = builder.add({ id: `ridge${unit.suffix}`, role: 'beam', material: construction.frame.timber, aabb: ridgeBox, y0: eaveY + rise - 0.12, y1: eaveY + rise }, { floor: unit.floor })\n for (const rafter of frames.all) builder.rest(ridge, rafter, system.joints.truss)\n }\n context.roof.trusses += count\n return frames\n}\n\nfunction panesOf(unit: RoofUnit, geometry: GableGeometry): Rect[] {\n const [u0, v0, u1, v1] = unit.box\n const { eave, axis } = geometry\n if (unit.annex) return [[u0 - eave, v0 - eave, u1 + eave, v1 + eave]]\n const midV = (v0 + v1) / 2\n const midU = (u0 + u1) / 2\n return axis === 'u'\n ? [[u0 - eave, v0 - eave, u1 + eave, midV], [u0 - eave, midV, u1 + eave, v1 + eave]]\n : [[u0 - eave, v0 - eave, midU, v1 + eave], [midU, v0 - eave, u1 + eave, v1 + eave]]\n}\n\nfunction coarseFrames(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const trusses = addTrusses(context, unit, carriers, geometry)\n context.roof.trusses += trusses.length\n return { all: trusses, sideA: trusses, sideB: trusses }\n}\n\nfunction addGableRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], covering: JointKind): RoofPane[] {\n const { builder, construction } = context\n const geometry = geometryOf(context, unit)\n const frames: Frames = context.rafterRoof ? addRafters(context, unit, carriers, geometry) : coarseFrames(context, unit, carriers, geometry)\n const panes: RoofPane[] = []\n panesOf(unit, geometry).forEach((aabb, k) => {\n const name = unit.annex ? 'annex' : k === 0 ? 'a' : 'b'\n const options = { floor: unit.floor, fill: construction.roof.covering === 'colonial' ? 0.12 : 0.05, ...(construction.roof.pitch === undefined ? {} : { pitch: construction.roof.pitch }) }\n const pane = builder.add({ id: `roof${unit.suffix}_${name}`, role: 'roof', material: construction.roof.material, aabb, y0: geometry.eaveY, y1: geometry.eaveY + geometry.rise + 0.05 }, options)\n const carried = unit.annex || !context.rafterRoof ? frames.all : k === 0 ? frames.sideA : frames.sideB\n for (const frame of carried) builder.rest(pane, frame, covering)\n panes.push({ id: pane.id, aabb: pane.aabb, y0: pane.y0, y1: pane.y1 })\n })\n if (!unit.annex) {\n const roof = context.roof\n roof.axis = geometry.axis\n roof.ridge = round2(geometry.eaveY + geometry.rise)\n roof.eave = geometry.eave\n roof.y0 = round2(geometry.eaveY)\n roof.aabb = [unit.box[0] - geometry.eave, unit.box[1] - geometry.eave, unit.box[2] + geometry.eave, unit.box[3] + geometry.eave].map(round2) as Rect\n }\n return panes\n}\n\n/** Roof of a timber house: ceiling joists every 0.6 m tie the trusses and carry the attic floor. */\nfunction addCeilingJoists(context: BuildContext): void {\n const { builder, construction } = context\n const bearing = context.roof.bearingFloor\n const rects = context.rectsOf(bearing, CLOSED_ONLY)\n const box = unionOf(rects.length ? rects : [context.topBox])\n const carriers = [...(context.plates.get(bearing) ?? []), ...context.walls.filter((w) => w.floor === bearing && w.role === 'wall' && !w.exterior).map((w) => context.wallParts.get(w.id)!)]\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / 0.6) + 1)\n const beamTops = carriers.filter((carrier) => carrier.role === 'beam').map((carrier) => carrier.y0)\n const y0 = carriers.length ? Math.max(...beamTops, context.level(bearing) + 1) : context.topOf(bearing)\n const joists: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [at - 0.025, box[1], at + 0.025, box[3]] : [box[0], at - 0.025, box[2], at + 0.025]\n const joist = builder.add({ id: `ceiling_joist_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: y0 - 0.02, y1: y0 + context.system.plateThickness - 0.02 }, { floor: bearing, spacing: 0.6 })\n const beams = carriers.filter((carrier) => carrier.role === 'beam' && touches(aabb, carrier.aabb, 0.2))\n for (const carrier of beams.length ? beams : carriers.slice(0, 2)) builder.rest(joist, carrier, 'nail')\n joists.push(joist)\n }\n context.ceilingJoists = joists\n}\n\n/** The roof over the top storey: a flat slab or trusses and two panes, and the ceiling joists of a timber house. */\nexport function addRoof(context: BuildContext): void {\n const { construction } = context\n const covering = ROOF_COVERINGS.get(construction.roof.covering)\n const bearing = construction.roof.bearingFloor ?? context.floorCount - 1\n const open = context.rectsOf(context.floorCount - 1, OPEN_ROOM_TYPES)\n const topRects = context.rectsOf(context.floorCount - 1, CLOSED_ONLY)\n const body = unionOf(open.length ? open : topRects)\n context.topBox = context.floorCount - 1 === bearing ? body : unionOf(context.rectsOf(bearing, OPEN_ROOM_TYPES))\n context.roof = { shape: construction.roof.shape, covering: construction.roof.covering, material: construction.roof.material, pitch: construction.roof.pitch || 0, bearingFloor: bearing, panes: [], trusses: 0 }\n for (const unit of roofUnits(context, bearing)) {\n const carriers = roofCarriers(context, unit)\n if (construction.roof.shape === 'slab') context.roof.panes.push(addFlatRoof(context, unit, carriers))\n else context.roof.panes.push(...addGableRoof(context, unit, carriers, covering?.joint ?? 'nail'))\n }\n if (context.isTimber && construction.roof.shape !== 'slab') addCeilingJoists(context)\n}\n","import { GROUND } from '../types'\nimport type { StructureSource } from '../types'\nimport type { BuildContext } from './context'\n\ntype SourceItem = StructureSource['items'][number]\n/** A stair item: its `link` names the storeys it joins. */\ntype StairItem = SourceItem & { link: { from: number; to: number } }\n\nconst isStair = (item: SourceItem): item is StairItem => item.category === 'stairs' && typeof item.link === 'object' && item.link !== null\n\n/** One flight per pair of linked storeys, taken from the item of the lower storey when both are present. */\nfunction flightsOf(items: readonly SourceItem[]): Map<string, StairItem> {\n const flights = new Map<string, StairItem>()\n for (const item of items.filter(isStair)) {\n const key = `${item.link.from}_${item.link.to}`\n if (!flights.has(key) || item.floor === item.link.from) flights.set(key, item)\n }\n return flights\n}\n\n/** Interior stairs between storeys, resting on the floor below and tied to the one above, plus the basement stairs. */\nexport function addStairs(context: BuildContext): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : (construction.stairs ?? 'concrete')\n for (const [key, item] of flightsOf(context.source.items)) {\n const { from, to } = item.link\n const flight = builder.add({ id: `stairs_${key}`, role: 'stair', material, aabb: item.aabb!, y0: context.level(from), y1: context.level(to) }, { floor: from, steps: Math.round((context.level(to) - context.level(from)) / 0.18) })\n const base = context.baseOf(from)\n builder.rest(flight, !base || base === GROUND ? GROUND : base, !base || base === GROUND ? 'resting' : context.isTimber ? 'nail' : 'mortar')\n const upper = context.baseOf(to)\n if (upper && upper !== GROUND) builder.rest(flight, upper, context.isTimber ? 'nail' : 'bolt')\n }\n if (!context.hasBasement) return\n const item = context.source.items.find((it) => it.type === 'basement_stairs')\n if (!item?.aabb) return\n const depth = construction.foundation.depth || 2.4\n const flight = builder.add({ id: 'basement_stairs', role: 'stair', material: 'wood_soft', aabb: item.aabb, y0: -depth, y1: context.level(0) }, { floor: -1, steps: Math.round((context.level(0) + depth) / 0.18) })\n builder.rest(flight, builder.find('basement_slab')!, 'resting')\n if (context.base0 && context.base0 !== GROUND) builder.rest(flight, context.base0, 'nail')\n}\n","import { GROUND } from '../types'\nimport type { Opening, Rect, SourceDoor, StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\nimport { WALL_PILLAR_SIDE } from './wall-pillars'\n\nconst TOLERANCE = 0.02\n/** Height of a door leaf, which the plan does not store (m). */\nexport const DOOR_HEIGHT = 2.1\nconst LINTEL_DEPTH = 0.2\nconst LINTEL_BEARING = 0.2\n\nconst crossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\nconst alongRange = (wall: BuildWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** The windows of the plan, each in the wall it sits in. */\nexport function findOpenings(context: BuildContext): Opening[] {\n const openings: Opening[] = []\n for (const window of context.source.windows ?? []) {\n const from = window.at - window.width / 2\n const to = window.at + window.width / 2\n const wall = context.walls.find((w) => {\n if (w.floor !== window.floor || w.axis !== window.axis || w.type !== 'wall' || Math.abs(crossOf(w) - window.pos) > TOLERANCE) return false\n const [low, high] = alongRange(w)\n return from >= low - TOLERANCE && to <= high + TOLERANCE\n })\n if (!wall) continue\n const base = context.level(window.floor)\n openings.push({ id: window.id, kind: 'window', wall: wall.id, from, to, y0: base + window.y0, y1: base + window.y1 })\n }\n return openings\n}\n\n/**\n * A lintel over every door gap, 0.2 m deep, bearing 0.2 m on the wall at each side (a concrete beam in masonry, a header in timber houses). The bond beam or\n * plate over the door rests on it as well as on the walls beside it.\n */\nexport function addDoorLintels(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const door of context.source.doors.filter((d) => d.a !== undefined && d.type !== 'zipper')) {\n const along = door.axis === 'u' ? door.u : door.v\n const cross = door.axis === 'u' ? door.v : door.u\n const from = along - door.width / 2\n const to = along + door.width / 2\n const beside = context.walls.filter((w) => w.floor === door.floor && w.axis === door.axis && w.type === 'wall' && Math.abs(crossOf(w) - cross) <= TOLERANCE && (Math.abs(alongRange(w)[1] - from) <= 0.05 || Math.abs(alongRange(w)[0] - to) <= 0.05))\n if (!beside.length) continue\n const half = (beside[0]!.thickness ?? 0.15) / 2\n const lo = from - LINTEL_BEARING\n const hi = to + LINTEL_BEARING\n const box: Rect = door.axis === 'u' ? [lo, cross - half, hi, cross + half] : [cross - half, lo, cross + half, hi]\n const y0 = context.level(door.floor) + DOOR_HEIGHT\n // h = L/10 of reinforced concrete: a wide door (a garage) needs a deeper lintel\n const depth = Math.max(LINTEL_DEPTH, (door.width + LINTEL_BEARING) / 10)\n const lintel = builder.add({ id: `lintel_${door.id}`, role: 'beam', material: system.timber ? construction.frame.timber : 'concrete', aabb: box, y0, y1: y0 + depth }, { floor: door.floor, ...(system.timber ? {} : { assembly: 'reinforced_concrete' }) })\n for (const wall of beside) builder.rest(lintel, context.wallParts.get(wall.id) as StructurePart, system.joints.beam)\n // the pillars at the jambs carry the lintel too (confined masonry: a wide door rests on the frame, not on the bricks alone)\n const jambs = (context.pillars.get(door.floor) ?? []).filter((pillar) => pillar.material === 'concrete' && overlapsInPlan(pillar.aabb, box) && pillar.y1 >= y0)\n if (construction.system === 'masonry' && hi - lo > WIDE_DOOR) jambs.push(...addJambPillars(context, { door, beside, from, to, cross }, jambs))\n for (const pillar of jambs) builder.rest(lintel, pillar, 'rebar')\n for (const plate of context.plates.get(door.floor) ?? []) if (overlapsInPlan(plate.aabb, box)) builder.rest(plate, lintel, system.joints.beam)\n }\n}\n\n/** A lintel longer than this (metres) does not rest on masonry alone: it gets a concrete pillar at each jamb that has none (`MAX_LINTEL_ON_MASONRY` of the validator). */\nconst WIDE_DOOR = 3\nconst HALF_PILLAR = WALL_PILLAR_SIDE / 2\n\ninterface DoorGap {\n door: SourceDoor\n beside: BuildWall[]\n from: number\n to: number\n cross: number\n}\n\n/** Concrete pillars in the walls at the jambs of a wide door (an inner door has none of the exterior walls' pillars), from the floor to the top of the wall. */\nfunction addJambPillars(context: BuildContext, gap: DoorGap, standing: readonly StructurePart[]): StructurePart[] {\n const { builder, construction } = context\n const top = Math.max(...gap.beside.map((w) => context.wallParts.get(w.id)!.y1))\n const base = context.baseOf(gap.door.floor)\n const out: StructurePart[] = []\n for (const [k, along] of ([[0, gap.from - HALF_PILLAR], [1, gap.to + HALF_PILLAR]] as const)) {\n const [u, v] = gap.door.axis === 'u' ? [along, gap.cross] : [gap.cross, along]\n const box: Rect = [u - HALF_PILLAR, v - HALF_PILLAR, u + HALF_PILLAR, v + HALF_PILLAR]\n if (standing.some((p) => overlapsInPlan(p.aabb, box))) continue\n const pillar = builder.add({ id: `jamb_column_${gap.door.id}_${k}`, role: 'column', material: construction.frame.pillars, aabb: box, y0: context.level(gap.door.floor), y1: top }, { floor: gap.door.floor })\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n out.push(pillar)\n }\n return out\n}\n\nconst overlapsInPlan = (a: Rect, b: Rect): boolean => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]\n","import { GROUND } from '../types'\nimport type { Rect } from '../types'\nimport type { BuildContext } from './context'\n\nconst RISER = 0.18\nconst TREAD = 0.28\n\nconst stepCount = (elevation: number): number => Math.max(1, Math.ceil(elevation / RISER))\n\n/** Steps from each porch door down to the ground: concrete in masonry, wood otherwise, resting on the porch floor. */\nfunction addPorchSteps(context: BuildContext): void {\n const { builder } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const deck = builder.find(`porch_floor_${room.id}`)\n for (const door of context.source.doors.filter((d) => d.floor === room.floor && d.b === 'outside' && d.a === room.id)) {\n const count = stepCount(context.elevation)\n const depth = count * TREAD\n const aabb: Rect = [door.u - door.width / 2, door.v - depth, door.u + door.width / 2, door.v]\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb, y0: 0, y1: context.level(room.floor) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n if (deck) builder.rest(flight, deck, context.isTimber ? 'nail' : 'mortar')\n }\n }\n}\n\nfunction boxOfSteps(door: { u: number; v: number; width: number; axis: string; side?: string | null }, depth: number): Rect {\n const direction = door.axis === 'u' ? (door.side === 'front' ? -1 : 1) : door.side === 'left' ? -1 : 1\n if (door.axis === 'u') return [door.u - door.width / 2, Math.min(door.v, door.v + direction * depth), door.u + door.width / 2, Math.max(door.v, door.v + direction * depth)]\n return [Math.min(door.u, door.u + direction * depth), door.v - door.width / 2, Math.max(door.u, door.u + direction * depth), door.v + door.width / 2]\n}\n\n/** Steps at the other outside doors of the ground storey when the floor sits above the ground. */\nfunction addDoorSteps(context: BuildContext): void {\n if (context.elevation <= 0.1) return\n const { builder } = context\n const doors = context.source.doors.filter((d) => d.floor === 0 && d.exterior && d.model !== 'steel' && d.type !== 'steps' && d.type !== 'zipper')\n for (const door of doors) {\n const count = stepCount(context.elevation)\n const depth = Math.min(TREAD * count, 0.9)\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb: boxOfSteps(door, depth), y0: 0, y1: context.level(0) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n const base = context.base0\n if (base && base !== GROUND) builder.rest(flight, base, context.isTimber ? 'nail' : 'mortar')\n }\n}\n\nexport function addExteriorSteps(context: BuildContext): void {\n addPorchSteps(context)\n addDoorSteps(context)\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart, WaterTank } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst TANK_FILL = 0.08\n\nconst squareAround = (u: number, v: number, side: number): Rect => [u - side / 2, v - side / 2, u + side / 2, v + side / 2]\n\nfunction addTank(context: BuildContext, tank: WaterTank, floor: number, y0: number): StructurePart {\n return context.builder.add({ id: 'water_tank', role: 'none', material: tank.material ?? 'plastic', aabb: tank.aabb, y0, y1: y0 + tank.h }, { floor, fill: TANK_FILL, liters: tank.capacity })\n}\n\n/** The slab under the roof that carries a tank in the attic or on a raised platform: a ceiling slab on the top plates, pillars and bearing walls. */\nfunction ensureCeilingSlab(context: BuildContext, y: number): StructurePart {\n const { builder, construction, system } = context\n const existing = builder.find('slab_ceiling')\n if (existing) return existing\n const top = context.floorCount - 1\n const box = context.topBox\n const carriers = builder.parts.filter(\n (part) =>\n ((part.role === 'beam' && part.id.startsWith(`plate_${top}_`)) || (part.role === 'column' && part.floor === top) || (part.role === 'wall' && part.floor === top && !part.id.startsWith('basement'))) &&\n touches(box, part.aabb, 0.1),\n )\n const slab = builder.add({ id: 'slab_ceiling', role: 'slab', material: construction.frame.slabs, aabb: box, y0: y - 0.12, y1: y }, { floor: top, footprint: [box] })\n for (const carrier of carriers) builder.rest(slab, carrier, system.joints.slab)\n return slab\n}\n\nfunction addRaisedPlatform(context: BuildContext, tank: WaterTank): void {\n const { builder, construction } = context\n const platform = tank.platform!\n const top = context.floorCount - 1\n const ceiling = ensureCeilingSlab(context, platform.baseY)\n const pillars = platform.pillars.map((q, k) => {\n const pillar = builder.add({ id: `tank_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: squareAround(q.u, q.v, q.side), y0: platform.baseY, y1: platform.topY - platform.thickness }, { floor: top })\n builder.rest(pillar, ceiling, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'tank_slab', role: 'slab', material: construction.frame.slabs, aabb: platform.aabb, y0: platform.topY - platform.thickness, y1: platform.topY }, { floor: top })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n builder.rest(addTank(context, tank, top, tank.y), slab, 'resting')\n}\n\nfunction addAtticTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const top = context.floorCount - 1\n if (!context.isTimber) {\n const ceiling = ensureCeilingSlab(context, tank.y)\n builder.rest(addTank(context, tank, top, tank.y), ceiling, 'resting')\n return\n }\n const supports = context.topSlab ? [context.topSlab] : (context.ceilingJoists ?? builder.parts.filter((part) => part.role === 'beam' && part.id.startsWith(`plate_${top}_`)))\n const y0 = supports[0] ? supports[0].y1 : tank.y - 0.03\n const floor = builder.add({ id: 'attic_floor', role: 'slab', material: 'plywood', aabb: context.topBox, y0, y1: y0 + 0.03 }, { floor: top })\n for (const support of supports) if (touches(floor.aabb, support.aabb, 0.1)) builder.rest(floor, support, 'nail')\n builder.rest(addTank(context, tank, top, tank.y), floor, 'resting')\n}\n\nfunction addSlabTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const supports = builder.parts.filter((part) => part.role === 'slab' && Math.abs(part.y1 - tank.y) < 0.3 && touches(part.aabb, tank.aabb, 0.1))\n const carrier = supports.sort((a, b) => Math.abs(a.y1 - tank.y) - Math.abs(b.y1 - tank.y))[0] ?? context.topSlab\n const part = addTank(context, tank, tank.floor, tank.y)\n builder.rest(part, carrier ?? GROUND, 'resting')\n}\n\nfunction addTrestleTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const stand = tank.stand!\n const columns = stand.pillars.map((q, k) => {\n const column = builder.add({ id: `trestle_column_${k}`, role: 'column', material: stand.material, aabb: squareAround(q.u, q.v, q.side), y0: 0, y1: stand.height }, { floor: 0 })\n builder.rest(column, GROUND, stand.baseJoint ?? 'resting')\n return column\n })\n const [u0, v0, u1, v1] = tank.aabb\n const beams = ([[u0 - 0.1, v0 - 0.1, u1 + 0.1, v0 + 0.05], [u0 - 0.1, v1 - 0.05, u1 + 0.1, v1 + 0.1]] as Rect[]).map((aabb, k) => {\n const beam = builder.add({ id: `trestle_beam_${k}`, role: 'beam', material: stand.material, aabb, y0: stand.height - 0.12, y1: stand.height }, { floor: 0 })\n for (const column of columns.filter((c) => touches(beam.aabb, c.aabb, 0.15))) builder.rest(beam, column, stand.joint ?? 'nail')\n return beam\n })\n const part = addTank(context, tank, 0, stand.height)\n for (const beam of beams) builder.rest(part, beam, stand.tie ?? 'resting')\n}\n\n/** The water tank as a part (role `none`: it weighs on what holds it and carries nothing) with whatever holds it up. */\nexport function addWaterTank(context: BuildContext): void {\n const tank = context.tank\n if (!tank) return\n switch (tank.place) {\n case 'slab':\n return addSlabTank(context, tank)\n case 'raised_slab':\n return addRaisedPlatform(context, tank)\n case 'attic':\n return addAtticTank(context, tank)\n case 'trestle':\n return addTrestleTank(context, tank)\n }\n}\n","import { touches, unionOf } from '../geometry'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\n/** The floor of the storey above `floor`: a concrete slab, or joists and boards in timber, resting on what carries `floor`. */\nexport function addUpperFloor(context: BuildContext, floor: number): void {\n if (floor >= context.floorCount - 1 || context.isUnit) return\n const next = floor + 1\n const rects = context.rectsOf(next, ['balcony', 'porch', 'void'])\n const box = rects.length ? unionOf(rects) : context.houseBox\n const carriers = context.carriers.get(floor)!\n const { system, construction, builder } = context\n const thickness = system.slabThickness\n if (context.isTimber) {\n const joists = addJoists(context, { floor: next, box, thickness, carriers, material: construction.frame.timber, joint: system.joints.beam })\n addDeck(context, `slab_${next}`, construction.frame.slabs, { floor: next, box, thickness, joint: system.joints.slab }, joists)\n return\n }\n const slab = builder.add({ id: `slab_${next}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(next) - thickness, y1: context.level(next) }, { floor: next, footprint: rects.length ? rects : [context.houseBox] })\n const below = carriers.filter((carrier) => carrier.y0 <= slab.y0 + 0.05)\n const touching = below.filter((carrier) => touches(slab.aabb, carrier.aabb, 0.2))\n for (const carrier of touching.length ? touching : below) builder.rest(slab, carrier, system.joints.slab)\n}\n","import { GROUND } from '../types'\nimport type { StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\nimport { guardHeightOf, OPEN_ROOM_TYPES } from './context'\n\n/** Highest ceiling among the rooms the wall touches (a double-height room lifts its outer wall to the eave). */\nexport function wallCeiling(context: BuildContext, wall: BuildWall): number {\n const rooms = wall.sides.map((id) => context.source.rooms.find((room) => room.id === id && room.floor === wall.floor)).filter((room) => room !== undefined)\n return Math.max(context.ceilingOf(wall.floor), ...rooms.map((room) => room.ceiling || 0))\n}\n\nfunction wallTop(context: BuildContext, wall: BuildWall, floor: number): number {\n const y0 = context.level(floor)\n if (wall.type === 'railing') return y0 + guardHeightOf(wall)\n const ceiling = wallCeiling(context, wall)\n const height = wall.structureHeight || wall.h || context.ceilingOf(floor)\n if (wall.exterior && floor < context.floorCount - 1 && !context.isUnit && ceiling > context.ceilingOf(floor) + 0.01) return y0 + ceiling\n if (floor === context.floorCount - 1 || context.isUnit) return y0 + Math.max(height, ceiling)\n const top = context.topOf(floor)\n return Math.max(y0 + height, y0 + ceiling > top ? top : y0 + ceiling)\n}\n\n/** What a railing rests on: the slab of its own balcony or the floor of its porch. */\nfunction railingBase(context: BuildContext, wall: BuildWall, floor: number): StructurePart | string | undefined {\n const open = wall.sides\n .map((id) => context.source.rooms.find((room) => room.id === id && room.floor === floor))\n .find((room) => room && (room.type === 'balcony' || room.type === 'porch'))\n if (!open) return context.baseOf(floor)\n return open.type === 'porch' ? `porch_floor_${open.id}` : `slab_${floor}_${open.id}`\n}\n\nconst assemblyOf = (context: BuildContext): string | undefined => context.construction.walls.assembly ?? (context.system.walls || undefined)\n\nfunction addWallPart(context: BuildContext, wall: BuildWall, floor: number): void {\n const { system, builder } = context\n const isRailing = wall.type === 'railing'\n const y0 = context.level(floor)\n const top = wallTop(context, wall, floor)\n const y1 = isRailing ? top : wall.exterior && !wall.gable ? top - system.plateThickness : top\n const framed = system.studs !== undefined && !isRailing\n const part = builder.add(\n { id: wall.id, role: wall.role, material: wall.material, aabb: wall.box, y0, y1: Math.max(y1, y0 + 0.2) },\n { floor, fill: context.isTimber && wall.role === 'wall' ? system.wallFill : 1, ...(framed ? { studs: system.studs } : {}), ...(isRailing ? {} : { assembly: assemblyOf(context) }), ...(wall.exterior && !isRailing ? { exterior: true as const } : {}) },\n )\n context.wallParts.set(wall.id, part)\n const base = isRailing ? railingBase(context, wall, floor) : (context.groundBeams.get(wall.id) ?? context.baseOf(floor))\n const joint = isRailing ? 'nail' : system.joints.wall\n if (base === GROUND || (floor === 0 && !base)) builder.rest(part, GROUND, joint)\n else if (base) builder.rest(part, base, joint)\n}\n\n/** One part per wall of the storey, resting on the floor below it (or the ground). */\nexport function addWalls(context: BuildContext, floor: number): void {\n for (const wall of context.walls.filter((w) => w.floor === floor)) addWallPart(context, wall, floor)\n}\n\nexport const isOpenRoomType = (type: string): boolean => OPEN_ROOM_TYPES.includes(type)\n","import { createContext } from './context'\nimport type { BuildContext } from './context'\nimport { addBalconies } from './balconies'\nimport { buildCanvasStructure } from './canvas'\nimport { addChimney, addWell } from './extras'\nimport { addFoundation } from './foundation'\nimport { addGroundBeams } from './ground-beams'\nimport { addPlatesAndPillars } from './plates'\nimport { addPorches } from './porch'\nimport { addPorchRoofs } from './porch-roof'\nimport { addRoof } from './roof'\nimport { addStairs } from './stairs'\nimport { addDoorLintels, findOpenings } from './openings'\nimport { addExteriorSteps } from './steps'\nimport { addWaterTank } from './tank-parts'\nimport { addUpperFloor } from './upper-floor'\nimport { addWalls } from './walls'\nimport { WALL_PILLAR_SPACING } from './wall-pillars'\nimport { resolveConstruction } from '../construction'\nimport type { Structure, StructureOptions, StructureSource } from '../types'\n\nfunction buildFloors(context: BuildContext): void {\n for (let floor = 0; floor < context.floorCount; floor++) {\n addWalls(context, floor)\n addPlatesAndPillars(context, floor)\n addPorches(context, floor)\n addUpperFloor(context, floor)\n }\n}\n\nconst wallPillarSpacingOf = (options: StructureOptions): number => {\n const pillars = options.wallPillars ?? true\n if (pillars === false) return 0\n return pillars === true ? WALL_PILLAR_SPACING : (pillars.spacing ?? WALL_PILLAR_SPACING)\n}\n\n/**\n * The structure of a generated plan: every part that carries load (foundation, floors, walls, plates and bond beams, pillars, porch posts, trusses,\n * roof, stairs, tank) with what each rests on. The plan itself is not modified.\n */\nexport function buildStructure(source: StructureSource, options: StructureOptions = {}): Structure {\n const refined = options.wallDetail !== 'coarse'\n const built = options.construction ? { construction: options.construction, extras: options.extras ?? {} } : resolveConstruction(source)\n const construction = built.construction\n const extras = options.extras ?? built.extras ?? {}\n if (construction.system === 'canvas') return buildCanvasStructure(construction, extras)\n const tank = options.tank !== undefined ? options.tank : (source.waterTank ?? null)\n const context = createContext(source, construction, extras, tank, { porchRoofOnPostsOnly: options.porchRoofOnPostsOnly ?? refined, rafterRoof: options.rafterRoof ?? refined, wallPillarSpacing: wallPillarSpacingOf(options), visorSections: options.visorSections === true })\n addFoundation(context)\n if (options.groundBeams !== false) addGroundBeams(context)\n buildFloors(context)\n addBalconies(context)\n addPorchRoofs(context)\n addExteriorSteps(context)\n addStairs(context)\n if (options.roof !== false) addRoof(context)\n if (refined) addDoorLintels(context)\n addWaterTank(context)\n addChimney(context)\n addWell(context)\n const levels = source.floors.map((_, floor) => context.level(floor))\n const framed = construction.system === 'masonry' && (context.isUnit || source.style === 'commercial' || context.floorCount >= 3)\n return { parts: context.builder.parts, supports: context.builder.supports, levels, elevation: context.elevation, roof: context.roof, construction, framed, openings: findOpenings(context) }\n}\n","export type ContentGroup = 'food' | 'water' | 'medicine' | 'tool' | 'cleaning' | 'improvised_weapon' | 'clothes' | 'document' | 'utensil' | 'trash'\n\nexport interface ContentEntry {\n itemId: string\n min: number\n max: number\n group: ContentGroup\n pickable: boolean\n weight: number\n}\n\nconst entry = (itemId: string, min: number, max: number, group: ContentGroup, pickable: boolean, weight: number): ContentEntry => ({ itemId, min, max, group, pickable, weight })\n\nconst FRIDGE = [\n entry('water_bottle', 1, 3, 'water', true, 3), entry('milk_carton', 1, 2, 'food', true, 2), entry('eggs', 1, 1, 'food', true, 2), entry('packed_meat', 1, 2, 'food', true, 1.5), entry('fruit', 1, 4, 'food', true, 2),\n entry('yogurt', 1, 3, 'food', true, 1), entry('soda', 1, 2, 'water', true, 1), entry('cheese', 1, 1, 'food', true, 1), entry('insulin', 1, 1, 'medicine', true, 0.4), entry('leftovers', 1, 2, 'food', true, 1),\n]\nconst BEDSIDE = [entry('medicine', 1, 2, 'medicine', true, 2), entry('book', 1, 2, 'document', true, 1.5), entry('charger', 1, 1, 'tool', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('glasses', 1, 1, 'tool', true, 0.7)]\nconst WARDROBE = [\n entry('shirt', 2, 6, 'clothes', true, 3), entry('trousers', 1, 4, 'clothes', true, 3), entry('coat', 1, 2, 'clothes', true, 1.5), entry('sneakers', 1, 2, 'clothes', true, 1.5),\n entry('shoes', 1, 2, 'clothes', true, 1), entry('blanket', 1, 2, 'clothes', true, 1.5), entry('backpack', 1, 1, 'tool', true, 0.8),\n]\nconst DRESSER = [entry('underwear', 2, 6, 'clothes', true, 3), entry('socks', 2, 6, 'clothes', true, 2), entry('t_shirt', 1, 4, 'clothes', true, 2), entry('documents', 1, 2, 'document', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('batteries', 1, 2, 'tool', true, 0.7)]\nconst FILING = [entry('documents', 1, 4, 'document', true, 3), entry('pen', 1, 3, 'tool', true, 1.5), entry('keys', 1, 2, 'tool', true, 1), entry('stapler', 1, 1, 'improvised_weapon', true, 0.5)]\nconst TRASH = [entry('full_trash_bag', 1, 1, 'trash', false, 2), entry('packaging', 1, 4, 'trash', true, 3), entry('empty_can', 1, 3, 'trash', true, 2), entry('crumpled_paper', 1, 3, 'trash', true, 1)]\n\n/** What each kind of container may hold, by category (or by type when a type differs from its category). */\nexport const CONTENT_TABLES: Record<string, ContentEntry[]> = {\n fridge: FRIDGE,\n display_fridge: [entry('soda', 2, 6, 'water', true, 3), entry('water_bottle', 2, 6, 'water', true, 3), entry('yogurt', 2, 5, 'food', true, 2)],\n freezer: [entry('frozen_meat', 2, 5, 'food', true, 3), entry('ice_cream', 1, 2, 'food', true, 1)],\n kitchen_cabinet: [\n entry('pot', 1, 2, 'tool', true, 1.5), entry('kitchen_knife', 1, 2, 'improvised_weapon', true, 1.5), entry('dish_soap', 1, 2, 'cleaning', true, 2), entry('sponge', 1, 2, 'cleaning', true, 1), entry('rice', 1, 2, 'food', true, 1.5),\n entry('beans', 1, 2, 'food', true, 1.5), entry('pasta', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 1, 'food', true, 1), entry('canned_tuna', 1, 3, 'food', true, 1.5), entry('disinfectant', 1, 1, 'cleaning', true, 1), entry('trash_bag', 1, 2, 'trash', true, 0.7),\n ],\n overhead_cabinet: [entry('plates', 4, 8, 'utensil', false, 3), entry('glasses', 3, 6, 'utensil', false, 3), entry('mug', 1, 3, 'utensil', true, 1.5), entry('coffee', 1, 2, 'food', true, 1.5), entry('canned_corn', 1, 3, 'food', true, 1.5), entry('spices', 1, 3, 'food', true, 1)],\n washbasin: [\n entry('painkiller', 1, 2, 'medicine', true, 2), entry('bandages', 1, 2, 'medicine', true, 2), entry('soap', 1, 3, 'cleaning', true, 2), entry('toilet_paper', 1, 4, 'cleaning', true, 2), entry('shampoo', 1, 2, 'cleaning', true, 1),\n entry('toothbrush', 1, 2, 'cleaning', true, 1), entry('scissors', 1, 1, 'improvised_weapon', true, 0.5), entry('rubbing_alcohol', 1, 1, 'medicine', true, 1),\n ],\n wardrobe: WARDROBE,\n wardrobe_large: WARDROBE,\n dresser: DRESSER,\n console_table: DRESSER,\n nightstand: BEDSIDE,\n filing_cabinet: FILING,\n pantry: [\n entry('rice', 2, 4, 'food', true, 2), entry('beans', 2, 4, 'food', true, 2), entry('canned_tuna', 2, 5, 'food', true, 2), entry('water_jug', 1, 2, 'water', true, 2), entry('flour', 1, 2, 'food', true, 1),\n entry('sugar', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 2, 'food', true, 1), entry('biscuits', 1, 4, 'food', true, 1.5),\n ],\n tv_unit: [entry('remote_control', 1, 1, 'tool', true, 2), entry('dvds', 1, 4, 'document', true, 1), entry('cables', 1, 3, 'tool', true, 1.5), entry('batteries', 1, 2, 'tool', true, 1)],\n laundry_cabinet: [entry('washing_powder', 1, 2, 'cleaning', true, 3), entry('bleach', 1, 2, 'cleaning', true, 2), entry('disinfectant', 1, 2, 'cleaning', true, 2), entry('bucket', 1, 1, 'tool', true, 1), entry('broom', 1, 1, 'improvised_weapon', true, 1), entry('rubber_gloves', 1, 2, 'cleaning', true, 1)],\n laundry_shelf: [entry('washing_powder', 1, 1, 'cleaning', true, 2), entry('softener', 1, 2, 'cleaning', true, 2), entry('clothespins', 1, 1, 'tool', true, 1)],\n workbench: [entry('hammer', 1, 1, 'improvised_weapon', true, 2), entry('screwdriver', 1, 2, 'tool', true, 2), entry('pliers', 1, 1, 'tool', true, 1.5), entry('insulating_tape', 1, 2, 'tool', true, 1), entry('screws', 1, 2, 'tool', true, 1)],\n tool_shelf: [entry('hammer', 1, 1, 'improvised_weapon', true, 1.5), entry('hand_saw', 1, 1, 'improvised_weapon', true, 1), entry('paint_can', 1, 3, 'trash', true, 1.5), entry('rope', 1, 1, 'tool', true, 1), entry('nails', 1, 2, 'tool', true, 1.5)],\n mailbox: [entry('letter', 1, 4, 'document', true, 3), entry('bill', 1, 2, 'document', true, 2), entry('flyer', 1, 4, 'trash', true, 2)],\n trash_bin: TRASH,\n outdoor_bin: TRASH,\n china_cabinet: [entry('china_plates', 3, 6, 'utensil', false, 3), entry('wine_glasses', 2, 5, 'utensil', false, 2)],\n}\n\n/** Groups of things somebody who locked themselves in would have stocked up. */\nexport const SUPPLY_GROUPS: readonly ContentGroup[] = ['food', 'water', 'medicine', 'tool']\n","import type { FindStack } from '@adatechnology/game-floorplan'\n\nimport { CONTENT_TABLES, SUPPLY_GROUPS } from './content-tables'\nimport type { ContentEntry } from './content-tables'\nimport type { Rng } from './shared'\n\nexport interface ContentStack extends FindStack {\n group: string\n pickable: boolean\n}\n\nexport interface ContentQuery {\n /** Category or type of the container (`fridge`, `kitchen_cabinet`, `overhead_cabinet`...). */\n container: string\n state: string\n rng: Rng\n /** Footprint of the container in m2. */\n footprint: number\n}\n\n/** How a state changes what a container holds: how many kinds, how likely each is, how many of each, and what is left over. */\nexport interface ContentStateRule {\n kinds(base: number, available: number, rng: Rng): number\n weight(entry: ContentEntry): number\n extraQuantity(entry: ContentEntry): number\n leftovers?(found: ContentStack[], container: string, rng: Rng): void\n}\n\nconst FRIDGES = ['fridge', 'display_fridge', 'freezer']\nconst isSupply = (entry: ContentEntry): boolean => SUPPLY_GROUPS.includes(entry.group)\n\n/** The normal world is the base; `fortified` and `abandoned` are the genre's rules, kept here until the item catalogue and the genre pack own them. */\nexport const CONTENT_STATES: Record<string, ContentStateRule> = {\n normal: { kinds: (base) => base, weight: (entry) => entry.weight, extraQuantity: () => 0 },\n fortified: { kinds: (base, available) => Math.min(available, base + 2), weight: (entry) => (isSupply(entry) ? entry.weight * 2.5 : entry.weight), extraQuantity: (entry) => (isSupply(entry) ? 1 : 0) },\n abandoned: {\n kinds: (_base, _available, rng) => (rng() < 0.4 ? 0 : 1),\n weight: (entry) => entry.weight,\n extraQuantity: () => 0,\n leftovers(found, container, rng) {\n if (found.length === 0 && rng() < 0.5) found.push({ itemId: 'scraps_and_papers', count: 1, pickable: false, group: 'trash' })\n if (FRIDGES.includes(container)) found.push({ itemId: 'spoiled_food', count: 1, pickable: false, group: 'trash' })\n },\n },\n}\n\nexport function registerContentState(state: string, rule: ContentStateRule): void {\n CONTENT_STATES[state] = rule\n}\n\n/** Weighted draw without replacement. */\nfunction weightedOrder<T extends { weight: number }>(candidates: T[], rng: Rng): T[] {\n const pool = candidates.slice()\n const out: T[] = []\n while (pool.length) {\n let x = rng() * pool.reduce((sum, c) => sum + c.weight, 0)\n let i = 0\n for (; i < pool.length - 1; i++) {\n x -= pool[i]!.weight\n if (x < 0) break\n }\n out.push(pool.splice(i, 1)[0]!)\n }\n return out\n}\n\n/** What a container holds in a state: a few kinds of thing from the table of its category, more of the useful ones when fortified, almost nothing when abandoned. */\nexport function contentOf(query: ContentQuery): ContentStack[] {\n const pool = CONTENT_TABLES[query.container]\n if (!pool) return []\n const rule = CONTENT_STATES[query.state] ?? CONTENT_STATES.normal!\n const { rng } = query\n const base = Math.max(2, Math.min(5, Math.round(1.5 + query.footprint * 3 + rng() * 1.5)))\n const kinds = rule.kinds(base, pool.length, rng)\n const found: ContentStack[] = []\n for (const candidate of weightedOrder(pool.map((entry) => ({ entry, weight: rule.weight(entry) })), rng).slice(0, kinds)) {\n const { entry } = candidate\n const count = entry.min + Math.floor(rng() * (entry.max - entry.min + 1)) + rule.extraQuantity(entry)\n found.push({ itemId: entry.itemId, count, pickable: entry.pickable, group: entry.group })\n }\n rule.leftovers?.(found, query.container, rng)\n return found\n}\n\nexport const hasContent = (container: string): boolean => container in CONTENT_TABLES\n\n","import type { Plan, PlacedItemFields, PlanWall } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\n\nexport type Rng = () => number\n\nexport const HALF_WALL = 0.075\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\nexport const clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport const overlaps = (a: Rect, b: Rect, epsilon = 1e-6): boolean => a[0] < b[2] - epsilon && a[2] > b[0] + epsilon && a[1] < b[3] - epsilon && a[3] > b[1] + epsilon\n\nexport const inner = (rect: Rect): Rect => [rect[0] + HALF_WALL, rect[1] + HALF_WALL, rect[2] - HALF_WALL, rect[3] - HALF_WALL]\n\n/** A solid item: not a rug, not resting on something, and not decoration unless it stands on the floor. */\nexport const isSolid = (item: Pick<PlacedItemFields, 'flat' | 'on' | 'decor' | 'mount'>): boolean => !item.flat && !item.on && (!item.decor || item.mount === 'floor')\n\nexport const distanceToRect = (u: number, v: number, rect: Rect): number => Math.hypot(Math.max(rect[0] - u, 0, u - rect[2]), Math.max(rect[1] - v, 0, v - rect[3]))\n\n/** Room types without sockets, switches or circuits. */\nexport const NO_SOCKET_ROOMS: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch', 'tent']\n\n/** Unit vector pointing out of the house from a wall (`sides[0]` or `sides[1]` is `outside`). */\nexport const outwardOf = (wall: PlanWall): [number, number] => {\n const sign = wall.sides[0] === 'outside' ? -1 : 1\n return wall.axis === 'u' ? [0, sign] : [sign, 0]\n}\n\nexport const sideNameOf = (vector: [number, number]): string => (Math.abs(vector[0]) > Math.abs(vector[1]) ? (vector[0] > 0 ? 'right' : 'left') : vector[1] > 0 ? 'back' : 'front')\n\nexport const alongRange = (wall: PlanWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** Exterior ground-floor wall at least 1 m long, the front one first when there is one (a gas meter and an inverter go on them). */\nexport function groundExteriorWalls(plan: Plan): PlanWall[] {\n return plan.walls.filter((wall) => wall.exterior && wall.floor === 0 && wall.type === 'wall' && Math.hypot(wall.u1 - wall.u0, wall.v1 - wall.v0) >= 1.0)\n}\n","import type { Plan, PlanWindow, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport { HALF_WALL, isSolid, round2 } from './shared'\n\nexport interface WallPoint {\n u: number\n v: number\n /** Position along the wall. */\n c: number\n axis: 'u' | 'v'\n pos: number\n side: number\n nu: number\n nv: number\n a0: number\n a1: number\n exterior: boolean\n windows: PlanWindow[]\n /** A solid item within 12 cm of the point reaches higher than `height`. */\n blocked(height: number): boolean\n}\n\nconst STEP = 0.05\nconst SURFACE_OFFSET = 0.012\n\n/** Points on the inner face of the walls of a room, away from corners (`margin`), where sockets, switches and a panel may go. */\nexport function wallPointsOf(plan: Plan, room: Room, items: ResultItem[], margin = 0.3): WallPoint[] {\n const points: WallPoint[] = []\n const windows = plan.windows.filter((w) => w.floor === room.floor)\n const solids = items.filter((m) => m.floor === room.floor && !m.outdoor && m.room === room.id && isSolid(m))\n for (const wall of plan.walls) {\n if (wall.floor !== room.floor || wall.type !== 'wall' || !wall.sides.includes(room.id)) continue\n const side = wall.sides[1] === room.id ? 1 : -1\n const a0 = wall.axis === 'u' ? Math.min(wall.u0, wall.u1) : Math.min(wall.v0, wall.v1)\n const a1 = wall.axis === 'u' ? Math.max(wall.u0, wall.u1) : Math.max(wall.v0, wall.v1)\n const pos = wall.axis === 'u' ? wall.v0 : wall.u0\n const nearby = windows.filter((w) => w.axis === wall.axis && Math.abs(w.pos - pos) < 1e-3 && w.at + w.width / 2 > a0 && w.at - w.width / 2 < a1)\n for (let c = a0 + margin; c <= a1 - margin + 1e-9; c += STEP) {\n const u = wall.axis === 'u' ? c : pos + side * (HALF_WALL + SURFACE_OFFSET)\n const v = wall.axis === 'u' ? pos + side * (HALF_WALL + SURFACE_OFFSET) : c\n points.push({\n u: round2(u), v: round2(v), c: round2(c), axis: wall.axis, pos, side, nu: wall.axis === 'u' ? 0 : side, nv: wall.axis === 'u' ? side : 0, a0, a1, exterior: wall.exterior, windows: nearby,\n blocked: (height) => solids.some((m) => m.aabb && Math.hypot(Math.max(m.aabb[0] - u, 0, u - m.aabb[2]), Math.max(m.aabb[1] - v, 0, v - m.aabb[3])) < 0.12 && (m.y || 0) + m.h > height),\n })\n }\n }\n return points\n}\n\nexport const hasWindowAt = (point: WallPoint, y: number, clearance = 0.2): boolean =>\n point.windows.some((w) => y + 0.1 > w.y0 - 0.05 && y - 0.1 < w.y1 + 0.05 && Math.abs(point.c - w.at) < w.width / 2 + clearance)\n\nexport const atDoor = (plan: Plan, room: Room, point: WallPoint, clearance: number): boolean =>\n plan.doors.some((d) => d.floor === room.floor && d.axis === point.axis && Math.abs(d.pos - point.pos) < 1e-3 && Math.abs(d.at - point.c) < d.width / 2 + clearance)\n","import type { ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { keyOf } from './electrical'\nimport { distanceToRect } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { Outlet } from './types'\n\n/** Categories that need a socket of their own. */\nconst APPLIANCES = ['fridge', 'display_fridge', 'freezer', 'tv', 'appliance', 'washing_machine', 'air_conditioner', 'cash_register', 'table_light']\nconst COUNTERS = ['kitchen_cabinet', 'workbench', 'checkout_counter']\nconst LAMPS = ['table_light', 'lamp']\n\nconst needsSocket = (item: ResultItem): boolean => APPLIANCES.includes(item.category) || item.category === 'shower'\n\ninterface Pick {\n point: WallPoint\n y: number\n score: number\n}\n\n/** Sockets: one for each appliance (the shower heater too), then enough for the size of each room, two at counter height in a kitchen with a counter. */\nexport function addOutlets(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n let counter = 0\n const outletsOf = (room: Room): Outlet[] => electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const newOutlet = (room: Room, point: WallPoint, y: number): Outlet => {\n const outlet: Outlet = { id: `outlet${++counter}`, room: room.id, floor: room.floor, u: point.u, v: point.v, y, c: point.c, axis: point.axis, pos: point.pos, frontU: point.nu, frontV: point.nv, type: '2P+T', voltage: 127 }\n electrical.outlets.push(outlet)\n return outlet\n }\n const counters = items.filter((m) => COUNTERS.includes(m.category) && !m.outdoor)\n const heightFor = (room: Room, point: WallPoint): number =>\n room.type === 'kitchen' && counters.some((m) => m.floor === room.floor && m.room === room.id && distanceToRect(point.u, point.v, m.aabb) < 0.45) ? 1.1 : 0.3\n const valid = (room: Room, point: WallPoint, y: number): boolean =>\n !hasWindowAt(point, y, 0.25) && !atDoor(plan, room, point, 0.45) && !outletsOf(room).some((t) => Math.hypot(t.u - point.u, t.v - point.v) < 0.5 && t.y === y)\n const pick = (room: Room, score: (point: WallPoint) => number, fixedY: number | null, ignoreBlocked?: boolean): Pick | null => {\n let best: Pick | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n const y = fixedY ?? heightFor(room, point)\n if (!valid(room, point, y)) continue\n const total = score(point) + (point.blocked(y) && !ignoreBlocked ? 5 : 0)\n if (!best || total < best.score) best = { point, y, score: total }\n }\n return best\n }\n const roomOf = (item: ResultItem): Room | undefined => rooms.find((x) => x.id === item.room && x.floor === item.floor)\n const appliances = items.filter((m) => !m.outdoor && needsSocket(m) && rooms.some((c) => c.id === m.room && c.floor === m.floor) && m.category !== 'table_light')\n for (const item of appliances) connectAppliance(item)\n function connectAppliance(item: ResultItem): void {\n const room = roomOf(item)!\n const target = item.aabb\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, target) })).filter((o) => o.d <= 1.2 && o.t.y <= 1.1).sort((a, b) => a.d - b.d)[0]\n const isShower = item.category === 'shower'\n let outlet: Outlet | null = nearest && !isShower ? nearest.t : null\n if (!outlet) {\n const height = isShower ? 1.1 : item.y > 0.7 ? 1.1 : null\n const best = pick(room, (p) => { const d = distanceToRect(p.u, p.v, target); return isShower && d < 0.6 ? 50 + d : d }, height)\n let chosen = best\n if (!isShower && (!best || distanceToRect(best.point.u, best.point.v, target) > 1.4)) {\n const behind = pick(room, (p) => distanceToRect(p.u, p.v, target), item.y > 0.7 ? 1.1 : null, true)\n if (behind && (!best || distanceToRect(behind.point.u, behind.point.v, target) < distanceToRect(best.point.u, best.point.v, target))) chosen = behind\n }\n if (chosen) outlet = newOutlet(room, chosen.point, chosen.y)\n }\n if (!outlet) return\n item.outlet = outlet.id\n if (isShower) item.showerHeater = { electric: true, powerW: 5500, outlet: outlet.id }\n }\n for (const room of rooms) {\n const area = room.parts.reduce((sum: number, q: number[]) => sum + (q[2]! - q[0]!) * (q[3]! - q[1]!), 0)\n const wanted = Math.max(room.type === 'kitchen' ? 3 : 2, Math.min(6, Math.round(area / 7)))\n const farthest = (existing: Outlet[]) => (p: WallPoint) => -Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v)))\n for (let guard = 0; outletsOf(room).length < wanted && guard < 12; guard++) {\n const best = pick(room, farthest(outletsOf(room)), null)\n if (!best) break\n newOutlet(room, best.point, best.y)\n }\n if (room.type !== 'kitchen' || !counters.some((m) => m.room === room.id)) continue\n for (let guard = 0; outletsOf(room).filter((t) => t.y === 1.1).length < 2 && guard < 4; guard++) {\n const existing = outletsOf(room)\n const best = pick(room, (p) => (heightFor(room, p) === 1.1 ? 0 : 20) - Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v))), 1.1)\n if (!best) break\n newOutlet(room, best.point, 1.1)\n }\n }\n for (const item of appliances) {\n if (item.category === 'shower' || !item.outlet) continue\n const room = roomOf(item)!\n const current = outletsOf(room).find((t) => t.id === item.outlet)\n if (!current || distanceToRect(current.u, current.v, item.aabb) <= 1.2) continue\n const other = outletsOf(room).filter((t) => t.y <= 1.1).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (other && other.d < distanceToRect(current.u, current.v, item.aabb) && other.d <= 1.2) item.outlet = other.t.id\n }\n for (const item of items.filter((m) => LAMPS.includes(m.category) && !m.outdoor)) {\n const room = roomOf(item)\n if (!room) continue\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (nearest) item.outlet = nearest.t.id\n }\n}\n\n","import type { Plan, PlanDoor } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport { clamp, round2 } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { ElectricMeter } from './types'\n\nconst METER_SIZE = { w: 0.35, d: 0.2, h: 0.5 }\n\nexport const mainDoorOf = (plan: Plan): PlanDoor | undefined => plan.doors.find((p) => p.floor === 0 && p.exterior && p.side === 'front') || plan.doors.find((p) => p.floor === 0 && p.exterior)\n\n/** Pole, drop, meter and descent: the meter on the gate pillar (or the facade without a gate); an apartment or shop has it on the facade. */\nexport function placeEntrance(layout: Layout): void {\n const { plan, electrical } = layout\n const gate = plan.gates.find((g) => g.type === 'pedestrian')\n const door = mainDoorOf(plan)\n const lot = plan.lot\n if (lot && plan.style !== 'commercial') {\n const rect = lot.rect\n const poleU = clamp(gate ? gate.u + 3 : plan.w / 2, rect[0] + 0.5, rect[2] - 0.5)\n const poleV = rect[1] - 0.6\n let placed: Omit<ElectricMeter, 'id'>\n if (gate) {\n const direction = gate.u - gate.width / 2 - 0.4 >= rect[0] + 0.3 ? -1 : 1\n placed = { place: 'gate_pillar', u: round2(gate.u + direction * (gate.width / 2 + 0.25)), v: round2(gate.v), y: 1.4, side: 'front', ...METER_SIZE }\n } else placed = { place: 'facade', u: round2(door ? door.at + 1.2 : plan.w / 2), v: -0.1, y: 1.4, side: 'front', ...METER_SIZE }\n const meter: ElectricMeter = Object.assign(placed, { id: 'meter' })\n electrical.serviceEntrance = { pole: { u: round2(poleU), v: round2(poleV), h: 7.5 }, drop: [[round2(poleU), round2(poleV), 6.5], [meter.u, meter.v, 2.6]], meter, descent: [[meter.u, meter.v, 2.6], [meter.u, meter.v, 1.65]], internalRun: null }\n } else if (lot === null || plan.style === 'commercial') {\n const front = door ? { u: round2(door.at + 1.0), v: -0.1 } : { u: round2(plan.w / 2), v: -0.1 }\n electrical.serviceEntrance = {\n pole: { u: round2(front.u + 2), v: -3, h: 7.5 }, drop: [[round2(front.u + 2), -3, 6.5], [front.u, front.v, 3.2]],\n meter: { id: 'meter', place: 'facade', u: front.u, v: front.v, y: 1.4, side: 'front', ...METER_SIZE }, descent: [[front.u, front.v, 3.2], [front.u, front.v, 1.65]], internalRun: null,\n }\n }\n}\n\n/** The distribution panel in the room of the main door, on the wall nearest the meter, clear of doors and windows and of tall furniture. */\nexport function placePanel(layout: Layout): void {\n const { plan, rooms, electrical, pointsOf } = layout\n const door = mainDoorOf(plan)\n const room = (door && rooms.find((c) => c.id === door.a && c.floor === 0)) || rooms.find((c) => c.floor === 0) || rooms[0]\n if (!room) return\n const meter = electrical.serviceEntrance?.meter\n const targetU = meter ? meter.u : plan.w / 2\n const targetV = meter ? Math.max(0, meter.v) : 0\n let best: { point: WallPoint | undefined; score: number } | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n if (point.blocked(1.5) || hasWindowAt(point, 1.5, 0.3) || atDoor(plan, room, point, 0.8)) continue\n const score = Math.hypot(point.u - targetU, point.v - targetV) + (point.exterior ? 0 : 3)\n if (!best || score < best.score) best = { point, score }\n }\n if (!best) best = { point: (pointsOf.get(keyOf(room)) ?? [])[0], score: 0 }\n if (best.point) {\n const p = best.point\n electrical.panel = { id: 'panel', room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.5, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, w: 0.3, h: 0.4, breakers: 0 }\n }\n if (electrical.serviceEntrance && electrical.panel) {\n const entrance = electrical.serviceEntrance\n const meterOf = entrance.meter as ElectricMeter // placeEntrance always sets the meter; only the tap pass clears it, later\n entrance.internalRun = [[meterOf.u, meterOf.v, 0.1], [electrical.panel.u, electrical.panel.v, heightOf(plan, electrical.panel.floor, electrical.panel.y)]]\n }\n}\n","import type { PlanDoor, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport { mainDoorOf } from './electrical-entrance'\nimport { round2 } from './shared'\nimport { atDoor, hasWindowAt, wallPointsOf } from './wall-points'\nimport type { WallPoint } from './wall-points'\nimport type { Circuit, Point3, WallFixture } from './types'\n\nconst LAMP_CATEGORIES = ['ceiling_light', 'lamp', 'table_light']\n\nconst lampsOf = (layout: Layout): ResultItem[] => layout.items.filter((m) => !m.outdoor && LAMP_CATEGORIES.includes(m.category))\n\n/** A switch by the latch of the main door of each room that has a lamp (and of the room of the front door, for the outside lamp), at 1.10 m. */\nexport function addSwitches(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n const lamps = lampsOf(layout)\n const door = mainDoorOf(plan)\n let counter = 0\n const positionFor = (room: Room): { point: WallPoint; door: PlanDoor; latch: boolean } | null => {\n const doors = plan.doors\n .filter((p) => p.floor === room.floor && (p.a === room.id || p.b === room.id))\n .sort((a, b) => (a.opensTo === room.id ? 0 : 1) - (b.opensTo === room.id ? 0 : 1) || (a.width < b.width ? 1 : -1))\n const points = wallPointsOf(plan, room, items, 0.12)\n for (const tolerance of [0.16, 0.3]) {\n for (const d of doors) {\n for (const direction of [1, -1]) {\n const target = d.at + direction * (d.width / 2 + 0.18)\n const point = points.filter((q) => q.axis === d.axis && Math.abs(q.pos - d.pos) < 1e-3 && !hasWindowAt(q, 1.1, 0.2)).sort((a, b) => Math.abs(a.c - target) - Math.abs(b.c - target))[0]\n if (point && Math.abs(point.c - target) <= tolerance && !atDoor(plan, room, point, 0.0) && Math.abs(point.c - d.at) >= d.width / 2 + 0.12) return { point, door: d, latch: direction === 1 }\n }\n }\n }\n return null\n }\n for (const room of rooms.concat(plan.rooms.filter((x) => ['stairs'].includes(x.type)))) {\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n const extra = door && door.a === room.id && room.floor === 0 && plan.lot ? [`outdoor_${door.id}`] : []\n if (!roomLamps.length && !extra.length) continue\n if (!pointsOf.get(keyOf(room))) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const found = positionFor(room)\n if (!found) continue\n const p = found.point\n electrical.switches.push({ id: `switch${++counter}`, room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.1, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, door: found.door.id, latchSide: found.latch, controls: roomLamps.map((m) => m.id).concat(extra) })\n }\n if (door && plan.lot) {\n const id = `outdoor_${door.id}`\n electrical.outdoorLamps.push({ id, u: round2(door.at + door.width / 2 + 0.32), v: round2(door.pos), y: 2.15, door: door.id, switch: electrical.switches.find((s) => s.controls.includes(id))?.id ?? null })\n }\n}\n\n/** One circuit per room with sockets or switches, and the conduits: from the panel up to the ceiling, along it to the room and down to each point. */\nexport function addConduits(layout: Layout): void {\n const { plan, rooms, electrical } = layout\n const panel = electrical.panel\n const lamps = lampsOf(layout)\n for (const room of rooms) {\n const outlets = electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const switches = electrical.switches.filter((i) => i.room === room.id && i.floor === room.floor)\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n if (!outlets.length && !switches.length) continue\n const ceiling = (room.ceiling || plan.floors[room.floor].ceiling) - 0.12\n const part = room.parts[0]\n const centreU = round2((part[0] + part[2]) / 2)\n const centreV = round2((part[1] + part[3]) / 2)\n const circuit: Circuit = { id: `circuit_${room.id}_${room.floor}`, room: room.id, floor: room.floor, outlets: outlets.map((t) => t.id), switches: switches.map((i) => i.id), lamps: roomLamps.map((m) => m.id), exposed: electrical.exposed, gauge_mm2: outlets.length > 3 ? 2.5 : 1.5 }\n electrical.circuits.push(circuit)\n const base = heightOf(plan, room.floor, 0)\n const riser: Point3[] = panel ? [[panel.u, panel.v, heightOf(plan, panel.floor, panel.y)], [panel.u, panel.v, heightOf(plan, panel.floor, 0) + ceiling]] : []\n if (panel) electrical.conduits.push({ id: `conduit_${circuit.id}`, circuit: circuit.id, from: 'panel', to: room.id, exposed: electrical.exposed, diameter: 0.025, points: riser.concat([[centreU, centreV, base + ceiling]]) })\n for (const point of (outlets as WallFixture[]).concat(switches)) {\n electrical.conduits.push({ id: `conduit_${point.id}`, circuit: circuit.id, from: circuit.id, to: point.id, exposed: electrical.exposed, diameter: 0.02, points: [[centreU, centreV, base + ceiling], [point.u, point.v, base + ceiling], [point.u, point.v, base + point.y]] })\n }\n }\n if (panel) panel.breakers = electrical.circuits.length + 1\n}\n","import type { Plan, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Rng } from './shared'\nimport type { Circuit, Conduit, ElectricalPanel, LightSwitch, OutdoorLamp, Outlet, ServiceEntrance } from './types'\nimport { NO_SOCKET_ROOMS } from './shared'\nimport { addOutlets } from './electrical-outlets'\nimport { addConduits, addSwitches } from './electrical-circuits'\nimport { placeEntrance, placePanel } from './electrical-entrance'\nimport { wallPointsOf } from './wall-points'\nimport type { WallPoint } from './wall-points'\n\nexport type EnergyMode = 'grid' | 'tap' | 'offgrid'\n\n/** What a template says about its energy (a shack taps the grid without a meter, a cabin may run off-grid on solar). */\nexport interface EnergyConfig {\n mode: EnergyMode\n solar?: boolean\n}\n\nexport interface Electrical {\n mode: EnergyMode\n serviceEntrance: ServiceEntrance | null\n panel: ElectricalPanel | null\n outlets: Outlet[]\n switches: LightSwitch[]\n circuits: Circuit[]\n conduits: Conduit[]\n exposed: boolean\n outdoorLamps: OutdoorLamp[]\n source?: 'solar' | 'lamp'\n}\n\nexport interface ElectricalContext {\n plan: Plan\n items: ResultItem[]\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Shared state of the steps that lay the installation out. */\nexport interface Layout {\n plan: Plan\n items: ResultItem[]\n rooms: Room[]\n electrical: Electrical\n pointsOf: Map<string, WallPoint[]>\n}\n\nexport const keyOf = (room: Room): string => `${room.id}@${room.floor}`\n\nconst absolute = (plan: Plan, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\nexport const heightOf = absolute\n\n/**\n * The electrical installation: sockets for the appliances and by room size, the service entrance (pole, drop, meter, descent; a tap without meter for a shack),\n * the panel near the entrance, switches by the door latch, circuits and conduits. Items that plug in are annotated (`outlet`, `showerHeater`).\n */\nexport function planElectrical(context: ElectricalContext): Electrical {\n const { plan, items, rng, energy } = context\n const mode: EnergyMode = energy?.mode ?? 'grid'\n const electrical: Electrical = { mode, serviceEntrance: null, panel: null, outlets: [], switches: [], circuits: [], conduits: [], exposed: false, outdoorLamps: [] }\n electrical.exposed = plan.style === 'budget' ? rng() < 0.65 : plan.style === 'mid' ? rng() < 0.12 : false\n if (mode !== 'grid') electrical.exposed = true\n if (mode === 'offgrid') {\n electrical.source = energy?.solar ? 'solar' : 'lamp'\n return electrical\n }\n const rooms = plan.rooms.filter((room) => !NO_SOCKET_ROOMS.includes(room.type) && !room.outdoor)\n const pointsOf = new Map<string, WallPoint[]>()\n for (const room of rooms) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const layout: Layout = { plan, items, rooms, electrical, pointsOf }\n addOutlets(layout)\n placeEntrance(layout)\n placePanel(layout)\n addSwitches(layout)\n addConduits(layout)\n const entrance = electrical.serviceEntrance\n const meter = entrance?.meter\n if (mode === 'tap' && entrance && meter) {\n entrance.tap = true\n entrance.connection = { u: meter.u, v: meter.v, y: 2.6 }\n entrance.meter = null\n }\n return electrical\n}\n","import type { Plan, ResultItem, Room } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\nimport type { Rng } from './shared'\nimport { HALF_WALL, clamp, groundExteriorWalls, inner, isSolid, outwardOf, overlaps, round2, sideNameOf } from './shared'\n\nexport const CYLINDER_TYPE = 'cooking_gas_cylinder'\nconst CYLINDER = { w: 0.36, d: 0.36, h: 0.48 }\nconst CYLINDER_KG = 13\n\nexport interface GasMeter {\n id: 'gas.meter'\n u: number\n v: number\n y: number\n side: string\n w: number\n d: number\n h: number\n}\n\nexport interface Gas {\n type: 'piped' | 'cylinder'\n meter: GasMeter | null\n}\n\ninterface Spot {\n mode: 'beside' | 'niche' | 'under'\n x: number\n z: number\n rect: Rect\n outdoor?: boolean\n cabinet?: string\n}\n\n/** Gas meter on the front wall of the ground floor, 1.2 m up. */\nfunction placeMeter(plan: Plan): GasMeter | null {\n const segments = groundExteriorWalls(plan).sort((a, b) => (b.sides.includes('outside') ? 1 : 0) - (a.sides.includes('outside') ? 1 : 0) || (a.axis === 'u' && a.v0 === 0 ? -1 : 1))\n const wall = segments.find((w) => w.axis === 'u' && w.v0 === 0) || segments[0]\n if (!wall) return null\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const vector = outwardOf(wall)\n const offset = HALF_WALL + 0.1\n return {\n id: 'gas.meter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.2, side: sideNameOf(vector), w: 0.3, d: 0.15, h: 0.4,\n }\n}\n\ninterface Context {\n plan: Plan\n items: ResultItem[]\n stateItems: ResultItem[]\n rng: Rng\n}\n\nfunction besideStove(context: Context, stove: ResultItem, room: Room, solids: Rect[], doorZones: Rect[]): Spot | undefined {\n const t: [number, number] = [-(stove.frontV ?? 1), (stove.frontU ?? 0)]\n const parts = room.parts.map(inner)\n for (const s of context.rng() < 0.5 ? [1, -1] : [-1, 1]) {\n const cx = stove.x + t[0] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - ((stove.frontU ?? 0) * (stove.d - CYLINDER.d)) / 2\n const cz = stove.z + t[1] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - ((stove.frontV ?? 1) * (stove.d - CYLINDER.d)) / 2\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const inside = parts.some((q: Rect) => rect[0] >= q[0] - 0.011 && rect[2] <= q[2] + 0.011 && rect[1] >= q[1] - 0.011 && rect[3] <= q[3] + 0.011)\n if (inside && !solids.some((o) => overlaps(rect, o, 0.011)) && !doorZones.some((z) => overlaps(rect, z, 0.011))) return { mode: 'beside', x: cx, z: cz, rect }\n }\n return undefined\n}\n\nfunction inNiche(context: Context, stove: ResultItem, room: Room, doorZones: Rect[]): Spot | undefined {\n const { plan, items, stateItems } = context\n const wall = plan.walls.find(\n (p) =>\n p.exterior && p.floor === stove.floor && p.type === 'wall' && p.sides.includes(room.id) &&\n (p.axis === 'u'\n ? Math.abs(stove.x - clamp(stove.x, p.u0, p.u1)) < 1.6 && Math.abs(stove.z - p.v0) < 1.6\n : Math.abs(stove.z - clamp(stove.z, p.v0, p.v1)) < 1.6 && Math.abs(stove.x - p.u0) < 1.6),\n )\n if (!wall || stove.floor !== 0) return undefined\n const vector = outwardOf(wall)\n const cx = wall.axis === 'u' ? clamp(stove.x, wall.u0 + 0.4, wall.u1 - 0.4) : wall.u0 + vector[0] * (HALF_WALL + CYLINDER.w / 2 + 0.05)\n const cz = wall.axis === 'u' ? wall.v0 + vector[1] * (HALF_WALL + CYLINDER.d / 2 + 0.05) : clamp(stove.z, wall.v0 + 0.4, wall.v1 - 0.4)\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const blockedByItem = items.some((o) => o.outdoor && isSolid(o) && overlaps(rect, o.aabb, 0.011))\n const blockedByState = stateItems.some((o) => o.outdoor && o.aabb && !o.flat && o.mount !== 'ground' && overlaps(rect, o.aabb, 0.011))\n const blockedByPath = plan.paths.some((c) => c.rects.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByGate = plan.gates.some((g) => g.zones.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByFence = !plan.lot || plan.lot.perimeter.some((q) => overlaps(rect, [Math.min(q.u0, q.u1) - HALF_WALL, Math.min(q.v0, q.v1) - HALF_WALL, Math.max(q.u0, q.u1) + HALF_WALL, Math.max(q.v0, q.v1) + HALF_WALL], 0.011))\n if (blockedByItem || blockedByState || blockedByPath || doorZones.some((z) => overlaps(rect, z, 0.011)) || blockedByGate || blockedByFence) return undefined\n return { mode: 'niche', x: cx, z: cz, rect, outdoor: true }\n}\n\nfunction underCounter(context: Context, stove: ResultItem): Spot | undefined {\n const distance = (m: ResultItem): number => Math.hypot(m.x - stove.x, m.z - stove.z)\n const cabinets = context.items\n .filter(\n (m) => m.floor === stove.floor && m.room === stove.room && !m.outdoor && !m.on && !m.flat && ['kitchen_cabinet', 'workbench'].includes(m.category) && m.aabb && m.id !== stove.id &&\n Math.min(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.d - 0.011 && Math.max(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.w + 0.02,\n )\n .sort((a, b) => (a.category === 'kitchen_cabinet' ? 0 : 1) - (b.category === 'kitchen_cabinet' ? 0 : 1) || distance(a) - distance(b))\n for (const cabinet of cabinets) {\n if (distance(cabinet) > 3) continue\n const box = cabinet.aabb as Rect\n const hw = CYLINDER.w / 2\n const hd = CYLINDER.d / 2\n const cx = clamp(stove.x, box[0] + hw + 0.01, box[2] - hw - 0.01)\n const cz = clamp(stove.z, box[1] + hd + 0.01, box[3] - hd - 0.01)\n const rect = [cx - hw, cz - hd, cx + hw, cz + hd].map(round2) as Rect\n if (rect[0] < box[0] || rect[2] > box[2] || rect[1] < box[1] || rect[3] > box[3] || overlaps(rect, stove.aabb, 0.011)) continue\n return { mode: 'under', x: cx, z: cz, rect, cabinet: cabinet.id }\n }\n return undefined\n}\n\nconst PLACEMENT = { beside: 'beside', niche: 'external_niche', under: 'under_counter' } as const\n\nfunction cylinderItem(stove: ResultItem, spot: Spot): ResultItem {\n const item: ResultItem = {\n id: `${stove.room}.${CYLINDER_TYPE}`, type: CYLINDER_TYPE, category: CYLINDER_TYPE, x: round2(spot.x), z: round2(spot.z), ry: 0, w: CYLINDER.w, d: CYLINDER.d, h: CYLINDER.h, y: 0,\n frontU: -(stove.frontU ?? 0), frontV: -(stove.frontV ?? 1), room: stove.room, floor: stove.floor, outdoor: !!spot.outdoor, slot: 'cylinder', on: null, mode: null, clearance: 0, flat: false, low: false,\n aabb: spot.rect, link: stove.id, placement: PLACEMENT[spot.mode], hose: [[round2(spot.x), round2(spot.z), 0.3], [stove.x, stove.z, 0.5]], capacityKg: CYLINDER_KG,\n }\n if (spot.cabinet) {\n item.on = spot.cabinet\n item.hidden = true\n }\n if (spot.outdoor) item.floor = -1\n item.color = stove.color\n return item\n}\n\n/**\n * Gas for the stoves of the house: a cylinder beside the stove, in an outside niche with a hose or under the counter, or (high-end houses, or when\n * nothing fits) piped gas with a meter on the facade. The cylinders are added to `items`; the stoves are annotated (`gas`, `cylinder`, `gasMeter`).\n */\nexport function planGas(context: Context): Gas | null {\n const { plan, items, stateItems, rng } = context\n const stoves = items.filter((m) => m.category === 'stove' && !m.outdoor)\n if (!stoves.length) return null\n const high = plan.style === 'high'\n const piped = plan.style !== 'commercial' && (high ? rng() < 0.8 : plan.style === 'mid' ? rng() < 0.1 : false)\n const out: Gas = { type: piped ? 'piped' : 'cylinder', meter: null }\n const ensureMeter = (): void => {\n if (!out.meter) out.meter = placeMeter(plan)\n }\n for (const stove of stoves) {\n const room = plan.rooms.find((c) => c.id === stove.room && c.floor === stove.floor)\n if (!room) continue\n stove.gas = piped ? 'piped' : 'cylinder'\n if (piped) {\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const solids = items.filter((m) => m.floor === stove.floor && m.room === stove.room && isSolid(m) && m.id !== stove.id).map((m) => m.aabb as Rect)\n .concat(stateItems.filter((m) => m.aabb && m.room === stove.room && m.floor === stove.floor && !m.flat && !m.on && m.mount !== 'window' && m.mount !== 'ground').map((m) => m.aabb as Rect))\n const doorZones = plan.doors.filter((p) => p.floor === stove.floor).flatMap((p) => p.zones as Rect[])\n const order: Spot['mode'][] = rng() < 0.7 ? ['beside', 'niche', 'under'] : ['niche', 'beside', 'under']\n let spot: Spot | undefined\n for (const mode of order) {\n if (spot) break\n spot = mode === 'beside' ? besideStove(context, stove, room, solids, doorZones) : mode === 'niche' ? inNiche(context, stove, room, doorZones) : underCounter(context, stove)\n }\n if (!spot) {\n stove.gas = 'piped'\n out.type = 'piped'\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const cylinder = cylinderItem(stove, spot)\n items.push(cylinder)\n stove.cylinder = cylinder.id\n }\n return out\n}\n","import type { Plan, ResultItem } from '@adatechnology/game-floorplan'\nimport { round2 } from './shared'\nimport type { WaterTank } from '../types'\nimport type { Plumbing, PlumbingPoint, PlumbingRun } from './types'\n\nconst FIXTURES: Record<string, string> = { kitchen_cabinet: 'tap', washbasin: 'tap', shower: 'shower', toilet: 'flush', laundry_tub: 'tub', washing_machine: 'machine' }\nconst FLOW_LPM: Record<string, number> = { tap: 6, shower: 9, flush: 6, tub: 8, machine: 12 }\nconst POINT_HEIGHT: Record<string, number> = { shower: 2.1, flush: 0.9, machine: 0.8 }\nconst DEFAULT_CAPACITY = { budget: 500, mid: 1000 }\n\nexport interface PlumbingContext {\n plan: Plan\n items: ResultItem[]\n tank: WaterTank | null\n}\n\nconst absolute = (plan: Plan, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\n\n/**\n * Plumbing as logic: a point for every tap, shower, toilet, tub and machine, and the runs you can see: the outlet of the tank, under each sink and in the wall\n * from the tank to every wet room (hidden in the wall, it shows only where the wall breaks).\n */\nexport function planPlumbing(context: PlumbingContext): Plumbing {\n const { plan, items, tank } = context\n const fixtures = items.filter((m) => FIXTURES[m.category] && !m.decor)\n const points: PlumbingPoint[] = []\n const runs: PlumbingRun[] = []\n const capacity = tank?.capacity ?? (plan.style === 'budget' ? DEFAULT_CAPACITY.budget : plan.style === 'mid' ? DEFAULT_CAPACITY.mid : plan.tpl?.id === 'mansion' ? 3000 : 2000)\n const plumbing: Plumbing = { tank: tank ? 'water_tank' : null, capacityL: tank || !plan.tpl.noWalls ? capacity : 0, points, visibleRuns: runs }\n const top = plan.floors.length - 1\n fixtures.forEach((item, index) => {\n const kind = FIXTURES[item.category]!\n points.push({ id: `pt${index + 1}`, kind, item: item.id, room: item.room, floor: item.outdoor ? -1 : item.floor, u: item.x, v: item.z, y: POINT_HEIGHT[kind] ?? 0.9, flowLpm: FLOW_LPM[kind], run: null })\n })\n if (!tank) return plumbing\n const slabY = absolute(plan, top, plan.floors[top].ceiling)\n const tankY = tank.place === 'raised_slab' ? tank.platform!.topY : tank.place === 'attic' ? slabY + 0.5 : tank.y\n runs.push({ id: 'run_outlet', from: 'water_tank', to: 'ceiling', points: [[tank.u, tank.v, round2(tankY + 0.15)], [tank.u, tank.v, round2(slabY - 0.15)]], diameter: 0.032, exposed: 'tank_outlet' })\n for (const point of points) {\n const item = fixtures.find((x) => x.id === point.item)!\n if (point.kind !== 'tap' || item.outdoor) continue\n const front = [item.frontU || 0, item.frontV || 1]\n const behind = [item.x - front[0]! * (item.d / 2 + 0.02), item.z - front[1]! * (item.d / 2 + 0.02)]\n runs.push({ id: `run_under_${point.id}`, from: 'valve', to: point.id, points: [[round2(behind[0]!), round2(behind[1]!), absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.75)]], diameter: 0.025, exposed: 'under_sink' })\n }\n const wet: { room: string | null; floor: number; points: PlumbingPoint[] }[] = []\n for (const point of points) {\n if (!wet.some((c) => c.room === point.room && c.floor === point.floor)) wet.push({ room: point.room, floor: point.floor, points: points.filter((q) => q.room === point.room && q.floor === point.floor) })\n }\n for (const room of wet) {\n const found = plan.rooms.find((c) => c.id === room.room && c.floor === room.floor)\n const zone = plan.zones.find((z) => z.id === room.room)\n const parts = (found || zone || { parts: [[tank.u, tank.v, tank.u, tank.v]] }).parts\n const centreU = (parts[0][0] + parts[0][2]) / 2\n const centreV = (parts[0][1] + parts[0][3]) / 2\n const ceiling = found ? found.ceiling || plan.floors[found.floor].ceiling : 2.8\n const y0 = found ? absolute(plan, found.floor, 0) : 0\n const id = `run_wall_${room.room}${room.floor === -1 ? '_outside' : `_${room.floor}`}`\n runs.push({ id, from: 'water_tank', to: room.room, points: [[tank.u, tank.v, round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(y0 + ceiling - 0.15)], [round2(centreU), round2(centreV), round2(y0 + 0.6)]], diameter: 0.025, exposed: 'wall' })\n for (const point of room.points) point.run = id\n }\n return plumbing\n}\n","import type { Plan } from '@adatechnology/game-floorplan'\nimport { outwardOf, groundExteriorWalls, HALF_WALL, round2, sideNameOf } from './shared'\nimport type { Rng } from './shared'\nimport type { Inverter, Solar, SolarPanel } from './types'\nimport type { EnergyConfig } from './electrical'\n\nconst PANEL_WIDTH = 1.0\nconst PANEL_LENGTH = 1.65\nconst NO_PANELS_UNDER: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch']\n\nexport interface SolarContext {\n plan: Plan\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Inverter on a side wall of the ground floor, 1.5 m up. */\nfunction placeInverter(plan: Plan): Inverter | null {\n const wall = groundExteriorWalls(plan).filter((q) => q.sides.includes('outside')).sort((a, b) => (a.axis === 'v' ? 0 : 1) - (b.axis === 'v' ? 0 : 1))[0]\n if (!wall) return null\n const vector = outwardOf(wall)\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const offset = HALF_WALL + 0.08\n return { id: 'inverter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.5, side: sideNameOf(vector), w: 0.4, d: 0.15, h: 0.5, outdoor: true, link: 'panel' }\n}\n\n/**\n * Solar panels: about 6% of budget houses, 25% of mid and 50% of the rest; on the roof slope that faces north or on tilted racks on a flat roof, with the\n * inverter on the wall. A template with its own energy decides (`energy.solar`).\n */\nexport function planSolar(context: SolarContext): Solar | null {\n const { plan, rng, energy } = context\n if (!plan.lot || plan.style === 'commercial' || !plan.facade) return null\n const chance = plan.style === 'budget' ? 0.06 : plan.style === 'mid' ? 0.25 : 0.5\n const forced = energy ? (energy.solar ? 1 : 0) : null\n const draw = rng()\n if (forced !== null ? !forced : draw >= chance) return null\n const floor = plan.floors.length - 1\n const level = plan.floors[floor]\n const flat = plan.facade.roof === 'slab'\n const tops = plan.rooms.filter((c) => c.floor === floor && !NO_PANELS_UNDER.includes(c.type))\n if (!tops.length) return null\n const parts: number[][] = tops.flatMap((c) => c.parts)\n const box = [Math.min(...parts.map((q) => q[0]!)), Math.min(...parts.map((q) => q[1]!)), Math.max(...parts.map((q) => q[2]!)), Math.max(...parts.map((q) => q[3]!))] as [number, number, number, number]\n const north = rng() < 0.5 ? 'front' : 'back'\n const angle = flat ? 15 : 25\n const projection = round2(PANEL_LENGTH * Math.cos((angle * Math.PI) / 180))\n const margin = 0.6\n const uStart = box[0] + margin\n const uEnd = box[2] - margin\n const columns = Math.max(1, Math.floor((uEnd - uStart) / (PANEL_WIDTH + 0.05)))\n const vMiddle = (box[1] + box[3]) / 2\n const vArea = flat ? [box[1] + margin, box[3] - margin] : north === 'front' ? [box[1] + 0.4, vMiddle - 0.2] : [vMiddle + 0.2, box[3] - 0.4]\n const step = flat ? projection + 0.5 : projection + 0.05\n const rowsMax = Math.max(1, Math.floor((vArea[1]! - vArea[0]!) / step))\n const wanted = forced !== null ? 1 + Math.floor(rng() * 2) : 3 + Math.floor(rng() * (plan.style === 'high' ? 12 : 8))\n const rows = Math.max(1, Math.min(rowsMax, Math.ceil(wanted / columns)))\n const count = Math.min(wanted, rows * columns)\n const u0 = uStart + (uEnd - uStart - columns * (PANEL_WIDTH + 0.05)) / 2\n const vStart = north === 'front' ? vArea[0]! : vArea[1]! - rows * step\n const panels: SolarPanel[] = []\n for (let k = 0; k < count; k++) {\n const row = Math.floor(k / columns)\n const column = k % columns\n panels.push({ id: `pv${k + 1}`, u: round2(u0 + column * (PANEL_WIDTH + 0.05) + PANEL_WIDTH / 2), v: round2(vStart + row * step + (flat ? 0.25 : 0) + projection / 2), w: PANEL_WIDTH, d: projection, length: PANEL_LENGTH })\n }\n const area = [round2(u0), round2(vStart), round2(u0 + columns * (PANEL_WIDTH + 0.05)), round2(vStart + rows * step)]\n return { type: flat ? 'slab_rack' : 'roof', orientation: 'north', north, slopeSide: flat ? null : north, tilt: angle, area, areaM2: round2(count * PANEL_WIDTH * PANEL_LENGTH), count, floor, y: round2(level.y0 + level.ceiling), panels, inverter: placeInverter(plan) }\n}\n","import type { FindStack, FindsQuery, Plan, ResultItem } from '@adatechnology/game-floorplan'\n\nimport type { WaterTank } from '../types'\nimport { hasContent } from './content'\nimport type { EnergyConfig, Electrical } from './electrical'\nimport { planElectrical } from './electrical'\nimport { planGas } from './gas'\nimport type { Gas } from './gas'\nimport { planPlumbing } from './plumbing'\nimport type { Rng } from './shared'\nimport type { Plumbing, Solar } from './types'\nimport { planSolar } from './solar'\n\nexport interface Utilities {\n gas: Gas | null\n electrical: Electrical\n solar: Solar | null\n plumbing: Plumbing\n}\n\nexport interface UtilitiesContext {\n plan: Plan\n items: ResultItem[]\n stateItems: ResultItem[]\n tank: WaterTank | null\n energy?: EnergyConfig\n /** Seeded stream by name: `gas`, `electrical`, `solar`. */\n rngFor(key: string): Rng\n}\n\n/** Gas, electricity, solar panels and plumbing of a house, in the order that lets the later ones see the cylinders the first adds to `items`. */\nexport function planUtilities(context: UtilitiesContext): Utilities {\n const { plan, items, stateItems, tank, energy, rngFor } = context\n const gas = planGas({ plan, items, stateItems, rng: rngFor('gas') })\n const electrical = planElectrical({ plan, items, rng: rngFor('eletrica'), ...(energy ? { energy } : {}) })\n const solar = planSolar({ plan, rng: rngFor('solar'), ...(energy ? { energy } : {}) })\n const plumbing = planPlumbing({ plan, items, tank })\n return { gas, electrical, solar, plumbing }\n}\n\nconst OVERHEAD = 'overhead_cabinet'\nconst ALWAYS_HOLD: readonly string[] = ['trash_bin', 'outdoor_bin', 'mailbox']\n\nexport interface ContentsContext {\n items: ResultItem[]\n state: string\n place: string\n /** Outbreak days and region of the world, passed to the finds provider. */\n day?: number\n region?: string\n rngFor(key: string): Rng\n findsFor(query: FindsQuery): readonly FindStack[]\n}\n\n/** What every container holds, asked of the registered finds provider: by item id, and `<id>#overhead` for the wall cabinet over a sink. */\nexport function planContents(context: ContentsContext): Record<string, readonly FindStack[]> {\n const out: Record<string, readonly FindStack[]> = {}\n const ask = (item: ResultItem, container: string, key: string): readonly FindStack[] =>\n context.findsFor({ place: context.place, container, state: context.state, rng: context.rngFor(key), footprint: item.w * item.d, key: item.id, ...(context.day === undefined ? {} : { day: context.day }), ...(context.region === undefined ? {} : { region: context.region }) })\n for (const item of context.items) {\n if (item.decor && item.mount !== 'wall_top') continue\n const container = hasContent(item.type) ? item.type : item.category\n if (!hasContent(container)) continue\n if (!ALWAYS_HOLD.includes(container) && item.decor) continue\n out[item.id] = ask(item, container, `content:${item.id}`)\n if (container === 'kitchen_cabinet' && item.overhead !== false) out[`${item.id}#overhead`] = ask(item, OVERHEAD, `content:${item.id}:overhead`)\n }\n return out\n}\n","import type { FurnitureDef, Plan, ResultItem, ResultLot, Vec2 } from '@adatechnology/game-floorplan'\nimport type { Rect } from '../types'\nimport type { Rng } from './shared'\nimport type { Outbuilding, OutbuildingItem, OutbuildingOpening, OutbuildingWall } from './types'\nimport { isSolid, overlaps, round2 } from './shared'\n\nconst WALL = 0.15\nconst DOOR_WIDTH = 0.85\nconst DOOR_HEIGHT = 2.1\nconst USES: Record<string, string[]> = { guest_room: ['single_bed', 'nightstand'], office: ['desk', 'shelf_unit_small'], storage: ['tool_shelf', 'crate'], gourmet: ['dining_table_small', 'workbench'] }\nconst USE_WEIGHTS: Record<string, number> = { guest_room: 3, office: 2, storage: 2, gourmet: 2 }\nconst PATH_WIDTH = 1.0\n\nexport interface OutbuildingContext {\n plan: Plan\n items: ResultItem[]\n catalog: Record<string, FurnitureDef>\n rngFor(key: string): Rng\n}\n\n/**\n * Name of the seeded stream of an outbuilding. It is the name the Visor de casas 3D gave it (`edif:<room>.<slot>` in Portuguese: `quintal.edicula`), kept verbatim so that an\n * old seed draws the same use and furniture; it never appears in the output.\n */\nconst LEGACY_ROOMS: Record<string, string> = { backyard: 'quintal' }\nconst LEGACY_SLOTS: Record<string, string> = { outbuilding: 'edicula' }\nexport const streamOf = (itemId: string): string => {\n const [room = '', ...slot] = itemId.split('.')\n return `edif:${LEGACY_ROOMS[room] ?? room}.${slot.map((part) => LEGACY_SLOTS[part] ?? part).join('.')}`\n}\n\nfunction pickWeighted(rng: Rng, weights: Record<string, number>): string {\n const keys = Object.keys(weights)\n let x = rng() * keys.reduce((sum, key) => sum + weights[key]!, 0)\n for (const key of keys) {\n x -= weights[key]!\n if (x < 0) return key\n }\n return keys[keys.length - 1]!\n}\n\nconst sideOf = (x: number, z: number): string => (Math.abs(x) > Math.abs(z) ? (x > 0 ? 'right' : 'left') : z > 0 ? 'back' : 'front')\n\ninterface Frame {\n n: [number, number]\n t: [number, number]\n cx: number\n cz: number\n depth: number\n width: number\n horizontal: boolean\n sideToMiddle: number\n}\n\nconst at = (frame: Frame, a: number, b: number): [number, number] => [frame.cx + frame.n[0] * a + frame.t[0] * b, frame.cz + frame.n[1] * a + frame.t[1] * b]\n\nfunction opening(frame: Frame, id: string, a: number, b: number, vector: [number, number], width: number, extra: Partial<OutbuildingOpening>): OutbuildingOpening {\n const [u, v] = at(frame, a, b)\n const alongU = Math.abs(vector[0]) !== 1\n return { id, axis: alongU ? 'u' : 'v', pos: round2(alongU ? v : u), at: round2(alongU ? u : v), u: round2(u), v: round2(v), width: round2(width), side: sideOf(vector[0], vector[1]), ...extra }\n}\n\nfunction wallsOf(box: Rect, door: OutbuildingOpening, height: number): OutbuildingWall[] {\n const walls: OutbuildingWall[] = []\n const sides: { axis: 'u' | 'v'; pos: number; i0: number; i1: number; side: string }[] = [\n { axis: 'u', pos: box[1], i0: box[0], i1: box[2], side: 'front' }, { axis: 'u', pos: box[3], i0: box[0], i1: box[2], side: 'back' },\n { axis: 'v', pos: box[0], i0: box[1], i1: box[3], side: 'left' }, { axis: 'v', pos: box[2], i0: box[1], i1: box[3], side: 'right' },\n ]\n for (const w of sides) {\n const cut = w.axis === door.axis && Math.abs(w.pos - door.pos) < 0.02 ? [door.at - door.width / 2, door.at + door.width / 2] : null\n const segments = cut ? [[w.i0, cut[0]!], [cut[1]!, w.i1]] : [[w.i0, w.i1]]\n for (const [x0, x1] of segments) {\n if (x1! - x0! <= 1e-3) continue\n walls.push(w.axis === 'u' ? { axis: 'u', u0: round2(x0!), v0: round2(w.pos), u1: round2(x1!), v1: round2(w.pos), thickness: WALL, h: height, side: w.side } : { axis: 'v', u0: round2(w.pos), v0: round2(x0!), u1: round2(w.pos), v1: round2(x1!), thickness: WALL, h: height, side: w.side })\n }\n }\n return walls\n}\n\nfunction furnish(context: OutbuildingContext, frame: Frame, use: string, interior: Rect, insideDoor: Rect): OutbuildingItem[] {\n const placed: OutbuildingItem[] = []\n USES[use]!.forEach((type, k) => {\n const def = context.catalog[type]!\n const facing: [number, number] = k === 0 ? frame.n : [frame.t[0] * frame.sideToMiddle, frame.t[1] * frame.sideToMiddle]\n const [a, b] = k === 0 ? [-frame.depth / 2 + WALL + def.d / 2, frame.sideToMiddle * -0.4] : [-0.1, -frame.sideToMiddle * (frame.width / 2 - WALL - def.d / 2)]\n const [u, v] = at(frame, a, b)\n const eu = Math.abs(facing[0]) === 1 ? def.d : def.w\n const ev = Math.abs(facing[0]) === 1 ? def.w : def.d\n const box = [u - eu / 2, v - ev / 2, u + eu / 2, v + ev / 2].map(round2) as Rect\n if (box[0] < interior[0] - 0.011 || box[2] > interior[2] + 0.011 || box[1] < interior[1] - 0.011 || box[3] > interior[3] + 0.011 || overlaps(box, insideDoor) || placed.some((o) => overlaps(box, o.aabb))) return\n placed.push({ type, category: def.category, u: round2(u), v: round2(v), w: def.w, d: def.d, h: def.h, ry: Math.atan2(facing[0], facing[1]), frontU: facing[0], frontV: facing[1], aabb: box })\n })\n return placed\n}\n\n/**\n * The outbuilding at the back of the yard is a small building of its own: walls with a gap for the door, a door of 0.85 m facing the yard, two windows and the\n * furniture of a drawn use (guest room, office, storage, gourmet space).\n */\nexport function planOutbuildings(context: OutbuildingContext): Outbuilding[] {\n const { plan, items } = context\n const lot = plan.lot\n if (!lot) return []\n const out: Outbuilding[] = []\n for (const item of items.filter((m) => m.category === 'outbuilding')) {\n const rng = context.rngFor(streamOf(item.id))\n const [a0, a1, a2, a3] = item.aabb as Rect\n const frontU = item.frontU ?? 0\n const frontV = item.frontV ?? 1\n const n: [number, number] = [frontU, frontV]\n const t: [number, number] = [-frontV, frontU]\n const horizontal = Math.abs(frontU) === 1\n const cx = (a0 + a2) / 2\n const cz = (a1 + a3) / 2\n const depth = horizontal ? a2 - a0 : a3 - a1\n const width = horizontal ? a3 - a1 : a2 - a0\n const sideToMiddle = ((lot.rect[0] + lot.rect[2]) / 2 - cx) * t[0] + ((lot.rect[1] + lot.rect[3]) / 2 - cz) * t[1] >= 0 ? 1 : -1\n const frame: Frame = { n, t, cx, cz, depth, width, horizontal, sideToMiddle }\n const doorOffset = sideToMiddle * (width / 2 - 0.95)\n const door = opening(frame, `${item.id}.d0`, depth / 2, doorOffset, n, DOOR_WIDTH, { height: DOOR_HEIGHT, exterior: true })\n const windowFront = opening(frame, `${item.id}.w0`, depth / 2, -sideToMiddle * (width / 2 - 0.9), n, Math.min(1.0, width / 2 - 0.6), { y0: 1.0, y1: 2.0 })\n const windowSide = opening(frame, `${item.id}.w1`, 0, (sideToMiddle * width) / 2, [t[0] * sideToMiddle, t[1] * sideToMiddle], Math.min(1.0, depth - 0.8), { y0: 1.0, y1: 2.0 })\n const [p, q] = [at(frame, depth / 2, doorOffset), at(frame, depth / 2 - 0.9, doorOffset)]\n door.zone = (horizontal ? [Math.min(p[0], q[0]), p[1] - door.width / 2, Math.max(p[0], q[0]), p[1] + door.width / 2] : [p[0] - door.width / 2, Math.min(p[1], q[1]), p[0] + door.width / 2, Math.max(p[1], q[1])]).map(round2) as Rect\n const interior: Rect = [a0 + WALL, a1 + WALL, a2 - WALL, a3 - WALL]\n const use = pickWeighted(rng, USE_WEIGHTS)\n out.push({ id: item.id, type: 'outbuilding', use, floor: 0, aabb: item.aabb.slice() as Rect, interior: [interior.map(round2) as Rect], ceiling: item.h, thickness: WALL, front: n, walls: wallsOf(item.aabb, door, item.h), doors: [door], windows: [windowFront, windowSide], items: furnish(context, frame, use, interior, door.zone) })\n }\n return out\n}\n\n/** A pedestrian path from every door of an outbuilding: a 1 m stub out of the door and an L to the nearest existing path, away from furniture, the building and the fence. */\nexport function addOutbuildingPaths(lot: ResultLot, outbuildings: Outbuilding[], items: ResultItem[]): void {\n const half = PATH_WIDTH / 2\n const rect = lot.rect\n const solids = items.filter((m) => m.outdoor && m.aabb && isSolid(m)).map((m) => m.aabb as Rect)\n const fence = lot.perimeter.map((q) => [Math.min(q.u0, q.u1) - 0.075, Math.min(q.v0, q.v1) - 0.075, Math.max(q.u0, q.u1) + 0.075, Math.max(q.v0, q.v1) + 0.075] as Rect)\n const strip = (p: number[], q: number[]): Rect => [Math.min(p[0]!, q[0]!) - half, Math.min(p[1]!, q[1]!) - half, Math.max(p[0]!, q[0]!) + half, Math.max(p[1]!, q[1]!) + half]\n for (const building of outbuildings) {\n for (const door of building.doors) {\n if (lot.paths.some((c) => c.to === door.id)) continue\n const z = door.zone as Rect\n const zc = door.axis === 'v' ? (z[0] + z[2]) / 2 : (z[1] + z[3]) / 2\n const outside = zc > door.pos ? -1 : 1\n const A = door.axis === 'v' ? [door.pos, door.at] : [door.at, door.pos]\n const S = door.axis === 'v' ? [door.pos + outside * PATH_WIDTH, door.at] : [door.at, door.pos + outside * PATH_WIDTH]\n const stub: Rect = door.axis === 'v' ? [Math.min(A[0]!, S[0]!), A[1]! - half, Math.max(A[0]!, S[0]!), A[1]! + half] : [A[0]! - half, Math.min(A[1]!, S[1]!), A[0]! + half, Math.max(A[1]!, S[1]!)]\n const cost = (rs: Rect[]): number => {\n let n = 0\n for (const r of rs) {\n const c: Rect = [r[0] + 0.02, r[1] + 0.02, r[2] - 0.02, r[3] - 0.02]\n for (const q of solids) if (overlaps(c, q, 0.011)) n += 2\n if (overlaps(c, building.aabb, 0.011)) n += 3\n for (const q of fence) if (overlaps(c, q, 0.011)) n += 3\n if (r[0] < rect[0] || r[1] < rect[1] || r[2] > rect[2] || r[3] > rect[3]) n += 3\n }\n return n\n }\n let best: { v: number; k: { rects: Rect[]; points: number[][] }; from: string | null } | null = null\n for (const c of lot.paths.filter((p) => p.type === 'pedestrian' || p.id === 'cargo_path')) {\n for (const r of c.rects as Rect[]) {\n const T = [Math.min(Math.max(S[0]!, r[0] + half), r[2] - half), Math.min(Math.max(S[1]!, r[1] + half), r[3] - half)]\n const candidates: { rects: Rect[]; points: number[][] }[] = []\n if (Math.abs(T[0]! - S[0]!) < 1e-6 && Math.abs(T[1]! - S[1]!) < 1e-6) candidates.push({ rects: [stub], points: [A, S] })\n else for (const via of [[T[0]!, S[1]!], [S[0]!, T[1]!]]) candidates.push({ rects: [stub, strip(S, via), strip(via, T)].filter((q) => q[2] - q[0] > 1e-6), points: [A, S, via, T] })\n for (const k of candidates) {\n const distance = k.points.slice(1).reduce((sum, q, i) => sum + Math.abs(q[0]! - k.points[i]![0]!) + Math.abs(q[1]! - k.points[i]![1]!), 0)\n const value = cost(k.rects.slice(1)) * 100 + distance\n if (!best || value < best.v) best = { v: value, k, from: c.from }\n }\n }\n }\n const chosen = best ? best.k : { rects: [stub], points: [A, S] }\n lot.paths.push({ id: `path_${door.id}`, type: 'pedestrian', from: best ? best.from : null, to: door.id, width: PATH_WIDTH, rects: chosen.rects.map((q) => q.map(round2) as Rect), points: chosen.points.map((q) => q.map(round2) as Vec2) })\n }\n }\n}\n","import { round2 } from './geometry'\nimport type { Rect, StructureSource, WaterTank } from './types'\n\ntype Rng = () => number\n\nconst TANK_SIDE = 1.1\n/** Side of the concrete pillars of a raised tank slab, metres: NBR 6118 asks at least 19 cm. */\nexport const TANK_PILLAR_SIDE = 0.2\n/** The 0.12 m pillars of the Visor de casas 3D, below the NBR 6118 minimum (`visorSections`, for the team's golden only). */\nexport const VISOR_TANK_PILLAR_SIDE = 0.12\nconst NOT_UNDER_TANK = ['void', 'elevator', 'stairs', 'balcony', 'porch']\nconst WET_ROOMS = ['bathroom', 'kitchen', 'laundry']\nconst ATTIC_CHANCE = 0.12\nconst clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport interface TankPlanOptions {\n /** Litres by template id or style id (default: budget 500, mid 1000, mansion 3000, any other 2000). */\n capacities?: Record<string, number>\n /** Where the tank goes; default: on the slab of a flat roof, else on a raised platform (the attic one time in eight). */\n location?: (source: StructureSource, rng: Rng) => WaterTank['place']\n /** A template with its own tank (a trestle for the rural water) answers here instead. */\n custom?: (source: StructureSource, rng: Rng) => WaterTank | null\n /** Side of the platform's concrete pillars (default `TANK_PILLAR_SIDE`; the Visor de casas 3D drew 0.12 m). */\n pillarSide?: number\n}\n\nconst DEFAULT_CAPACITIES: Record<string, number> = { budget: 500, mid: 1000, mansion: 3000 }\n\nfunction capacityOf(source: StructureSource, capacities: Record<string, number>): number {\n return capacities[source.style ?? ''] ?? capacities[source.template ?? ''] ?? 2000\n}\n\n/** Candidate spot: the room part with the least weight (wet rooms first, terraces last, near the reference point or the middle). */\nfunction bestSpot(source: StructureSource, floor: number, reference: { u: number; v: number } | undefined): { roomType: string; roomId: string; rect: Rect } | undefined {\n const centre: [number, number] = reference ? [reference.u, reference.v] : [source.w / 2, source.d / 2]\n let best: { roomType: string; roomId: string; rect: Rect; weight: number } | undefined\n for (const room of source.rooms.filter((r) => r.floor === floor && !NOT_UNDER_TANK.includes(r.type))) {\n for (const part of room.parts) {\n const rect: Rect = [part[0] + 0.4, part[1] + 0.4, part[2] - 0.4, part[3] - 0.4]\n if (rect[2] - rect[0] < TANK_SIDE || rect[3] - rect[1] < TANK_SIDE) continue\n const base = WET_ROOMS.includes(room.type) ? 0 : room.type === 'terrace' ? 500 : 100\n const weight = base + Math.hypot((rect[0] + rect[2]) / 2 - centre[0], (rect[1] + rect[3]) / 2 - centre[1])\n if (!best || weight < best.weight) best = { roomType: room.type, roomId: room.id, rect, weight }\n }\n }\n return best\n}\n\nfunction raisedPlatform(source: StructureSource, spot: { u: number; v: number; baseY: number }, side: number): NonNullable<WaterTank['platform']> {\n const { u, v, baseY } = spot\n const margin = 0.12\n const edge = Math.max(0, Math.min(u, source.w - u, v, source.d - v))\n const rise = round2(clamp(edge * 0.35 + 0.7, 1.1, 2.4))\n const thickness = 0.12\n const reach = TANK_SIDE / 2 + margin - side / 2\n const pillars = ([[-1, -1], [1, -1], [-1, 1], [1, 1]] as const).map(([a, b]) => ({ u: round2(u + a * reach), v: round2(v + b * reach), side }))\n const half = TANK_SIDE / 2 + margin\n return { aabb: [u - half, v - half, u + half, v + half].map(round2) as Rect, baseY, height: rise, thickness, topY: round2(baseY + rise + thickness), pillars, ladder: true }\n}\n\n/**\n * The water tank of a house: on the roof slab, in the attic, or on a platform that rises out of the roof, never in the yard. Null for a plan without\n * a lot (an apartment) or a commercial building, and when no room has space.\n */\nexport function planWaterTank(source: StructureSource, rng: Rng, options: TankPlanOptions = {}): WaterTank | null {\n if (!source.lot || source.style === 'commercial') return null\n if (options.custom) return options.custom(source, rng)\n const floor = source.floors.length - 1\n const level = source.floors[floor]!\n const capacity = capacityOf(source, { ...DEFAULT_CAPACITIES, ...options.capacities })\n const height = capacity >= 2000 ? 1.4 : capacity === 1000 ? 1.0 : 0.85\n const place = options.location ? options.location(source, rng) : source.facade.roof === 'slab' ? 'slab' : rng() < ATTIC_CHANCE ? 'attic' : 'raised_slab'\n const reference = (source.facade.slab as { waterTank?: { u: number; v: number } } | undefined)?.waterTank\n const spot = bestSpot(source, floor, reference)\n if (!spot) return null\n const target = reference ? [reference.u, reference.v] : [(spot.rect[0] + spot.rect[2]) / 2, (spot.rect[1] + spot.rect[3]) / 2]\n const u = clamp(target[0]!, spot.rect[0] + TANK_SIDE / 2, spot.rect[2] - TANK_SIDE / 2)\n const v = clamp(target[1]!, spot.rect[1] + TANK_SIDE / 2, spot.rect[3] - TANK_SIDE / 2)\n const where = spot.roomType === 'terrace' ? 'slab' : place\n const slabY = round2(spot.roomType === 'terrace' ? level.y0 : level.y0 + level.ceiling)\n const tank: WaterTank = {\n id: 'water_tank', kind: 'water_tank', itemType: 'water_tank', place: where, floor, room: spot.roomId, u: round2(u), v: round2(v), y: slabY, w: TANK_SIDE, d: TANK_SIDE, h: height,\n capacity, aabb: [u - TANK_SIDE / 2, v - TANK_SIDE / 2, u + TANK_SIDE / 2, v + TANK_SIDE / 2].map(round2) as Rect,\n }\n if (where === 'raised_slab') {\n tank.platform = raisedPlatform(source, { u, v, baseY: slabY }, options.pillarSide ?? TANK_PILLAR_SIDE)\n tank.y = tank.platform.topY\n }\n return tank\n}\n","import type { ViewerLayer, ViewerLayerContext, ViewerLayerLegendEntry } from '@adatechnology/game-floorplan'\n\nimport type { Roof, Structure, StructurePart } from './types'\n\ntype MaterialGroup = 'concrete' | 'steel' | 'masonry' | 'wood'\n\nconst COLORS: Record<MaterialGroup, string> = { concrete: '#7d8590', steel: '#3d6fb0', masonry: '#b5654b', wood: '#a0693a' }\nconst BEAM_IDS = ['plate_', 'porch_beam', 'base_beam', 'trestle_beam']\n\nexport const LAYER_ID = 'structure'\n\nexport function groupOf(material: string): MaterialGroup {\n if (material === 'concrete') return 'concrete'\n if (material === 'steel' || material === 'aluminium' || material === 'cast_iron') return 'steel'\n if (material === 'brick' || material === 'stone' || material === 'ceramic') return 'masonry'\n return 'wood'\n}\n\nconst isRoofFrame = (part: StructurePart): boolean => ['truss', 'rafter', 'ridge'].some((prefix) => part.id.startsWith(prefix))\nconst isDrawnBeam = (part: StructurePart): boolean => part.role === 'beam' && BEAM_IDS.some((prefix) => part.id.startsWith(prefix))\n\nfunction drawColumns(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n for (const part of parts.filter((p) => p.role === 'column')) {\n const color = COLORS[groupOf(part.material)]\n if (groupOf(part.material) === 'wood') context.rect(part.aabb, null, color, 2)\n else context.rect(part.aabb, color, null)\n context.hit(part.aabb, `${part.id} · column · ${part.material} · ${part.mass} kg`)\n }\n}\n\nfunction drawBeams(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([6, 4])\n for (const part of parts.filter(isDrawnBeam)) {\n context.rect(part.aabb, null, COLORS[groupOf(part.material)], 1.5)\n context.hit(part.aabb, `${part.id} · beam · ${part.material} · ${part.mass} kg`)\n }\n context.g.restore()\n}\n\nfunction drawRoofFrames(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.strokeStyle = COLORS.wood\n context.g.lineWidth = 1\n for (const part of parts.filter(isRoofFrame)) {\n const [u0, v0, u1, v1] = part.aabb\n const alongV = v1 - v0 > u1 - u0\n context.g.beginPath()\n if (alongV) { context.g.moveTo(context.X((u0 + u1) / 2), context.Z(v0)); context.g.lineTo(context.X((u0 + u1) / 2), context.Z(v1)) }\n else { context.g.moveTo(context.X(u0), context.Z((v0 + v1) / 2)); context.g.lineTo(context.X(u1), context.Z((v0 + v1) / 2)) }\n context.g.stroke()\n }\n context.g.restore()\n}\n\nfunction drawPorchRoofs(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([2, 4])\n for (const part of parts.filter((p) => p.id.startsWith('porch_roof'))) context.rect(part.aabb, null, COLORS.wood, 1)\n context.g.restore()\n}\n\n/** What the viewer draws at one storey: pillars (filled for concrete, steel and masonry, hollow for wood), dashed beams, trusses on the top storey, the porch roof outline. */\nexport function drawStructure(context: ViewerLayerContext): void {\n // the structure and roof extensions of this pack wrote these into the result\n const structure = context.plan.structure as Structure | undefined\n if (!structure) return\n const floor = context.all ? 0 : context.floor\n const here = structure.parts.filter((part) => part.floor === floor)\n drawPorchRoofs(context, here)\n if (floor === ((context.plan.roof as Roof | null | undefined)?.bearingFloor ?? 0)) drawRoofFrames(context, structure.parts)\n drawBeams(context, here)\n drawColumns(context, here)\n}\n\nexport function structureLegend(plan: Readonly<Record<string, unknown>>): ViewerLayerLegendEntry[] {\n const parts = (plan.structure as Pick<Structure, 'parts'> | undefined)?.parts ?? [] // written by the structure extension\n const entries: ViewerLayerLegendEntry[] = []\n for (const group of ['concrete', 'steel', 'masonry', 'wood'] as const) {\n const columns = parts.some((p) => p.role === 'column' && groupOf(p.material) === group)\n if (columns) entries.push({ label: `structure_column_${group}`, color: COLORS[group], shape: group === 'wood' ? 'hollow' : 'filled' })\n }\n for (const group of ['concrete', 'wood'] as const) {\n if (parts.some((p) => isDrawnBeam(p) && groupOf(p.material) === group)) entries.push({ label: `structure_beam_${group}`, color: COLORS[group], shape: 'dashed' })\n }\n if (parts.some(isRoofFrame)) entries.push({ label: 'structure_roof_frame', color: COLORS.wood, shape: 'line' })\n return entries\n}\n\nexport const structureLayer: ViewerLayer = {\n id: LAYER_ID,\n label: 'structure_layer',\n defaultOn: false,\n draw: drawStructure,\n legend: structureLegend,\n}\n","import type { FloorplanEngine, FloorplanResult, ResultExtensionContext } from '@adatechnology/game-floorplan'\n\nimport { constructionFor } from './construction'\nimport enLocale from './locales/en.json'\nimport ptBrLocale from './locales/pt-BR.json'\nimport type { ConstructionBuild } from './registry'\nimport type { WaterTank } from './types'\nimport { buildStructure } from './structure'\nimport { contentOf } from './utilities/content'\nimport { planContents, planUtilities } from './utilities'\nimport { addOutbuildingPaths, planOutbuildings } from './utilities/outbuildings'\nimport type { EnergyConfig } from './utilities/electrical'\nimport type { TankPlanOptions } from './water-tank'\nimport { VISOR_TANK_PILLAR_SIDE, planWaterTank } from './water-tank'\nimport { structureLayer } from './viewer-layer'\nimport type { PlanStructure, Roof, StructureOptions, WallDetail } from './types'\n\n/**\n * A `generate` result once the structure pack is registered: the plan of `game-floorplan` with what the pack's extensions add (the construction and its extras,\n * the water tank, the structure and its roof, the contents of the furniture, the outbuildings and the utilities).\n */\nexport type StructuredResult = FloorplanResult & {\n construction: ConstructionBuild['construction']\n structureExtras: NonNullable<ConstructionBuild['extras']>\n waterTank: WaterTank | null\n structure: PlanStructure\n roof: Roof | null\n contents: ReturnType<typeof planContents>\n outbuildings: ReturnType<typeof planOutbuildings>\n utilities: ReturnType<typeof planUtilities>\n}\n\nexport interface StructurePackOptions {\n /** Litres of the tank by template id or style id. */\n tankCapacities?: Record<string, number>\n}\n\ntype Cache = { build: ConstructionBuild; roof?: Roof }\nconst CACHE = new WeakMap<object, Cache>()\n\nconst cacheOf = (result: object): Cache => {\n const cache = CACHE.get(result)\n if (!cache) throw new Error('The construction extension did not run for this plan')\n return cache\n}\n\nfunction constructionExtension(context: ResultExtensionContext): unknown {\n const build = constructionFor({ result: context.result as never, seed: context.seed, template: context.plan.tpl as never, options: context.options })\n CACHE.set(context.result, { build })\n return build.construction\n}\n\nfunction structureExtension(context: ResultExtensionContext): unknown {\n const cache = cacheOf(context.result)\n const options: StructureOptions = { construction: cache.build.construction, extras: cache.build.extras ?? {}, tank: tankOf(context), wallDetail: (context.options.wallDetail ?? 'panels') as WallDetail, ...(context.options.wallPillars !== undefined ? { wallPillars: context.options.wallPillars as StructureOptions['wallPillars'] } : {}), ...(context.options.groundBeams !== undefined ? { groundBeams: context.options.groundBeams === true } : {}), ...(context.options.visorSections === true ? { visorSections: true } : {}) }\n const { roof, ...structure } = buildStructure(context.result, options)\n cache.roof = roof\n for (const part of structure.parts) {\n if (part.door === undefined || part.steps === undefined) continue\n const door = context.result.doors.find((d: { id: string }) => d.id === part.door)\n if (door) door.steps = part.steps\n }\n return structure\n}\n\nconst COOKING_CYLINDER = { type: 'cooking_gas_cylinder', category: 'cooking_gas_cylinder', w: 0.36, d: 0.36, h: 0.48 }\n\n/** The tank the `waterTank` extension (registered here) wrote into the result. */\nconst tankOf = (context: ResultExtensionContext): WaterTank | null => (context.result.waterTank as WaterTank | null | undefined) ?? null\n\nfunction energyOf(context: ResultExtensionContext): EnergyConfig | undefined {\n const energy = context.plan.tpl.energy\n return typeof energy === 'function' ? energy(context.options, context.plan.w, context.plan.d) : undefined\n}\n\n/**\n * Registers the structure into the engine: `result.construction`, `result.structureExtras`, `result.waterTank`, `result.structure` and `result.roof` of every plan,\n * and the structure layer of the 2D viewer. Register the content packs first.\n */\nexport function register(engine: FloorplanEngine, options: StructurePackOptions = {}): void {\n engine.registerLocale('en', enLocale)\n engine.registerLocale('pt-BR', ptBrLocale)\n engine.registerResultExtension('construction', constructionExtension)\n engine.registerResultExtension('structureExtras', (context) => cacheOf(context.result).build.extras ?? {}, { after: ['construction'] })\n engine.registerResultExtension(\n 'waterTank',\n (context) => {\n const tank: TankPlanOptions = { capacities: options.tankCapacities, custom: context.plan.tpl.tank as TankPlanOptions['custom'], location: context.plan.tpl.tankLocation as TankPlanOptions['location'], ...(context.options.visorSections === true ? { pillarSide: VISOR_TANK_PILLAR_SIDE } : {}) } // templates declare their own tank hooks\n return planWaterTank(context.result as never, context.rng, tank)\n },\n { after: ['construction'], seedKey: 'caixa' },\n )\n engine.registerResultExtension('structure', structureExtension, { after: ['construction', 'structureExtras', 'waterTank'] })\n engine.registerResultExtension('roof', (context) => cacheOf(context.result).roof ?? null, { after: ['structure'] })\n engine.registerViewerLayer(structureLayer)\n engine.registerItem(COOKING_CYLINDER)\n engine.registerResultExtension('contents', (context) => planContents({ items: context.result.items, state: context.result.state, place: context.plan.tpl.place ?? 'house', ...(typeof context.options.day === 'number' ? { day: context.options.day } : {}), ...(typeof context.options.region === 'string' ? { region: context.options.region } : {}), rngFor: (key) => engine.createRng(context.seed, key), findsFor: (query) => { const answered = engine.findsAnswer(query); return answered ?? contentOf({ container: query.container, state: query.state, rng: query.rng, footprint: query.footprint ?? 0.5 }) } }))\n engine.registerResultExtension('outbuildings', (context) => {\n const outbuildings = planOutbuildings({ plan: context.plan, items: context.result.items, catalog: engine.catalog, rngFor: (key) => engine.createRng(context.seed, key) })\n if (context.result.lot) addOutbuildingPaths(context.result.lot, outbuildings, context.result.items)\n return outbuildings\n }, { after: ['contents'] })\n engine.registerResultExtension('utilities', (context) => planUtilities({ plan: context.plan, items: context.result.items, stateItems: context.result.stateItems, tank: tankOf(context), ...(energyOf(context) ? { energy: energyOf(context) } : {}), rngFor: (key) => engine.createRng(context.seed, key) }), { after: ['outbuildings', 'waterTank'] })\n}\n","import type { DestructibleSpec, JointSpec, MaterialId, PartSpec, PileSpec, SoilProfile, StructureRole } from '@adatechnology/game-contracts'\nimport { GRAVITY, MATERIALS, SOILS, assemblyPart, partMass, pileLength, profileOf, sizeRebar } from '@adatechnology/game-destruction'\nimport type { SoilDef } from '@adatechnology/game-destruction'\nimport { sizeCapacities } from './loads'\nimport { GROUND } from './types'\nimport { resolveSlabPanels } from './slab-panels'\nimport type { SlabPanelOptions } from './slab-panels'\nimport { applySlabPanels, beamDepthFor, deepenBondBeams } from './slab-panels'\nimport { applyPanels, applyUnits } from './wall-detail'\nimport type { FoundationType, PartRole, PlanStructure, StructurePart, WallDetail } from './types'\n\nexport interface DestructibleSpecOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest (default 0.65). */\n safety?: number\n /** After losing any other pillar or bearing wall, the most of its capacity one of them uses (default 0.97: the house holds one loss and falls with two). */\n redundancy?: number\n /** Fraction of capacity beams, slabs, roofs, stairs and partitions use at rest (default 0.45). */\n safetyOthers?: number\n /** Bearing walls close but do not carry: a frame of pillars and beams carries the building. Default: for a framed building unless the detail is `coarse`. */\n portico?: boolean\n /** How finely the walls are split (default `panels`; `coarse` is one part per wall as the Visor de casas 3D builds it). */\n wallDetail?: WallDetail\n /**\n * Cuts the concrete slabs into panels with a beam under each edge, and adds the pillars those beams and the bond beams need (design T10 §12): `true` for\n * `SLAB_PANEL_DEFAULTS`, options to change them, `false` for the slab as one piece, as the Visor de casas 3D describes it. Default `true`.\n */\n slabPanels?: boolean | Partial<SlabPanelOptions>\n /** Name of the spec (default `house`). */\n name?: string\n /** Leaves parts out (and what rests on them is dropped from the joints). */\n filter?: (part: StructurePart) => boolean\n /** `false` keeps the capacity of the material instead of sizing it from the load. */\n sized?: boolean\n /** Metres the anchored terrain slab reaches beyond the parts (default 6). */\n terrainMargin?: number\n /**\n * Declares the tension steel of the concrete beams, slabs, roofs and stairs of a construction with rebar (`structure.rebar.ratio`), so the destruction\n * world bends them (`structure.flexure` of game-destruction): `true` for the default ratios (`REBAR_RATIOS`), or ratios per role. When the spec is\n * sized the steel is sized too (`sizeRebar`: at rest at `safetyOthers`, after the loss of any pillar or bearing wall under `redundancy`). On by\n * default (a house of concrete is reinforced concrete, with the slab in panels on real beams, `slabPanels`); `false` leaves the concrete plain, as the\n * Visor de casas 3D describes it.\n */\n rebar?: boolean | Partial<Record<'beam' | 'slab' | 'roof' | 'stair', number>>\n /**\n * The ground the house stands on (`DestructibleSpec.soil` of game-contracts: a soil class id such as `clay_stiff`, or a profile of layers). With it\n * the foundations bear on the soil (game-destruction `soil`): the house settles, and tips over where the soil cannot carry it. A raft foundation\n * (`raft`, `basement`, `building`) becomes a concrete raft under the footprint (`RAFT_THICKNESS`) instead of the anchored terrain; any other\n * foundation keeps the terrain and every wall and pillar on it bears on a footing at least `footingWidth` wide. Off by default.\n */\n soil?: string | SoilProfile\n /** Foundation used with `soil` (default the construction's `foundation.type`). */\n foundation?: FoundationType\n /**\n * Deep concrete piles under the raft (a piled raft; with `soil` only). `length` omitted: each pile goes down to where it carries its share of the\n * house with the NBR 6122 safety (`pileLength`). Defaults: diameter 0.4 m, one pile per `PILE_AREA` m² of raft, at least 4, bored.\n */\n piles?: true | Partial<PileSpec>\n /** Soil classes beyond `SOILS` that `soil` names (the same ones given to the destruction world in `soil.soils`). */\n soils?: readonly SoilDef[]\n}\n\n/** Thickness of the raft of a house on the soil, metres (usual 0.20 to 0.30 m). */\nexport const RAFT_THICKNESS = 0.25\n/** Raft area per pile when the count is not given, m² (a 3 x 3 m grid). */\nexport const PILE_AREA = 9\n/** Metres the raft reaches beyond the walls. */\nconst RAFT_MARGIN = 0.15\nconst RAFT_FOUNDATIONS: ReadonlySet<FoundationType> = new Set(['raft', 'basement', 'building'])\n\n/**\n * Tension steel ratio a concrete member starts with before sizing, `As / (b d)`: beams 0.8%, slabs and roof slabs 0.25%, stairs 0.4% (inside the\n * usual ranges of NBR 6118; the minimum for C25 is 0.15%).\n */\nexport const REBAR_RATIOS: Readonly<Record<'beam' | 'slab' | 'roof' | 'stair', number>> = { beam: 0.008, slab: 0.0025, roof: 0.0025, stair: 0.004 }\n\nconst CONTRACT_ROLE: Record<PartRole, StructureRole> = { column: 'column', beam: 'beam', slab: 'slab', wall: 'wall', partition: 'partition', roof: 'roof', stair: 'stair', none: 'none' }\n\nconst TERRAIN_MARGIN = 6\nconst TERRAIN_THICKNESS = 0.5\n\nconst boxSpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n return {\n id: part.id, material: part.material, shape: { kind: 'box', size: [Math.max(0.01, u1 - u0), Math.max(0.01, part.y1 - part.y0), Math.max(0.01, v1 - v0)] },\n position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], mass: Math.max(0.1, part.mass || 1),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity },\n }\n}\n\n/** A wall piece as its assembly builds it (layers, rebar, units, breach), with the mass the structure gave it. A brick or log is the unit itself, so it keeps no units or breach. */\nconst assemblySpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n const alongU = u1 - u0 >= v1 - v0\n const spec = assemblyPart(part.assembly!, {\n id: part.id, width: alongU ? u1 - u0 : v1 - v0, height: part.y1 - part.y0, position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], ...(alongU ? {} : { rotation: [0, Math.PI / 2, 0] }),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity }, extra: { mass: Math.max(0.1, part.mass || 1) },\n })\n if (part.unit) {\n delete spec.units\n delete spec.breach\n }\n return spec\n}\n\n/** The cage of a concrete beam or pillar (four bars in a small section, an NBR 6118 minimum) and the blocks a shot or a blow knocks out of its concrete. */\nexport const MEMBER_CAGE = { spacing: 0.1, diameter: 0.008, unit: 0.1 }\nconst CAGED_ROLES: ReadonlySet<PartRole> = new Set(['beam', 'column'])\n/** Concrete cover to the bars of a member, metres (NBR 6118, class I of aggressiveness: 2.5 cm, plus the stirrup). */\nconst CAGE_COVER = 0.03\n/** Share of the bars' crushing load a bare cage keeps: without the concrete around them the bars buckle between the stirrups well before they yield. */\nconst CAGE_BUCKLING_SHARE = 0.5\nconst DEFAULT_RESIDUAL = 0.15\n\n/**\n * What the bare cage of a concrete pillar still carries once its concrete is blown off, as the share of the pillar's `capacity` (kg) the destruction\n * world keeps for it (`reinforcement.residualCapacity`): its perimeter bars (at most `spacing` apart, at least two a face) by the steel's crushing\n * strength, halved for buckling between the stirrups. A pillar under a light bond beam keeps standing on its cage; a loaded one still gives way.\n */\nexport function cageResidualCapacity(size: readonly number[], reinforcement: { material: string; spacing: number; diameter: number }, capacity: number | undefined): number {\n const [a = 0, b = 0] = [...size].sort((x, y) => x - y)\n const perSide = (w: number): number => Math.max(2, Math.floor(Math.max(0, w - 2 * CAGE_COVER) / reinforcement.spacing) + 1)\n const bars = 2 * perSide(a) + 2 * perSide(b) - 4\n const steel = MATERIALS.find((m) => m.id === reinforcement.material)?.compressive ?? 0\n const carries = bars * Math.PI * (reinforcement.diameter / 2) ** 2 * steel * CAGE_BUCKLING_SHARE\n if (!capacity || capacity <= 0 || carries <= 0) return DEFAULT_RESIDUAL\n return Math.min(1, Math.max(DEFAULT_RESIDUAL, carries / capacity))\n}\n\n/**\n * A concrete beam or pillar of a frame with rebar, in detail: its steel cage (`reinforcement`) and its concrete as blocks (`units`), so shots and blows\n * take out the concrete where they land, the bars show there and the cage is what is left when the concrete is gone.\n */\nconst caged = (spec: PartSpec, part: StructurePart, rebar: MaterialId | null): PartSpec => {\n if (!rebar || part.material !== 'concrete' || !CAGED_ROLES.has(part.role) || spec.reinforcement) return spec\n const size = spec.shape.kind === 'box' ? spec.shape.size : null\n if (!size) return spec\n const thin = Math.min(...size)\n const reinforcement = { material: rebar, spacing: MEMBER_CAGE.spacing, diameter: MEMBER_CAGE.diameter }\n return {\n ...spec,\n reinforcement: part.role === 'column' ? { ...reinforcement, residualCapacity: cageResidualCapacity(size, reinforcement, spec.structure?.capacity) } : reinforcement,\n units: { size: [MEMBER_CAGE.unit, MEMBER_CAGE.unit, thin], bond: 'stack', mortar: 'concrete' },\n }\n}\n\nconst partSpecOf = (part: StructurePart, capacity: number | undefined, detailed: boolean, rebar: MaterialId | null): PartSpec => {\n if (detailed && part.assembly) return assemblySpec(part, capacity)\n const spec = boxSpec(part, capacity)\n const out = detailed ? caged(spec, part, rebar) : spec\n // a ground beam is buried in the soil on its footing: part of the foundation, it holds what stands on it and never falls\n return part.beamKind === 'ground_beam' ? { ...out, anchored: true, structure: { role: 'foundation' } } : out\n}\n\n/**\n * The structure as a `DestructibleSpec` in the space of the house (x = u, y = height, z = v; the ground is y = 0), one box per part and a terrain slab\n * that anchors it. Capacities are sized from the loads at rest, as a designer would: a house stands whole, holds the loss of one pillar or bearing wall\n * and falls with two.\n */\nexport function toDestructibleSpec(structure: PlanStructure, options: DestructibleSpecOptions = {}): DestructibleSpec {\n const { safety = 0.65, redundancy = 0.97, safetyOthers = 0.45 } = options\n const kept = structure.parts.filter((part) => !options.filter || options.filter(part))\n const portico = options.portico ?? (options.wallDetail !== 'coarse' && structure.framed)\n const roled = portico ? kept.map((part): StructurePart => (part.role === 'wall' ? { ...part, role: 'partition' } : part)) : kept\n const ids = new Set(roled.map((part) => part.id))\n const filtered = structure.supports.filter((support) => !options.filter || (ids.has(support.part) && (support.on === GROUND || ids.has(support.on))))\n const detail = options.wallDetail ?? 'panels'\n const resolved = resolveSlabPanels(options.slabPanels ?? true)\n const slabOptions = resolved && structure.levels.length <= resolved.maxStoreys ? resolved : undefined\n const slabbed = slabOptions ? applySlabPanels({ parts: roled, supports: filtered }, structure, slabOptions) : { parts: roled, supports: filtered }\n const walled = applyPanels(slabbed, structure, detail, slabOptions && structure.construction.frame.rebar ? (span) => beamDepthFor(span, slabOptions) : undefined)\n const panels = slabOptions && detail !== 'coarse' ? deepenBondBeams(walled, structure, slabOptions) : walled\n const sizing = { safety, redundancy, safetyOthers }\n // a ground beam is foundation, as the anchored world sees it: what stands on it is as near the ground as what stands on the soil\n const foundation = new Set(panels.parts.filter((part) => part.beamKind === 'ground_beam').map((part) => part.id))\n const onFoundation = foundation.size ? panels.supports.filter((s) => !foundation.has(s.part)).map((s) => (foundation.has(s.on) ? { ...s, on: GROUND } : s)) : panels.supports\n const sized = { ...panels, capacities: options.sized === false ? new Map<string, number>() : sizeCapacities(panels.parts.filter((part) => !foundation.has(part.id)), onFoundation, sizing) }\n const { parts, supports, capacities } = detail === 'units' ? applyUnits(sized, structure) : sized\n const specs = parts.map((part) => partSpecOf(part, capacities.get(part.id), detail !== 'coarse', structure.construction.frame.rebar))\n const margin = options.terrainMargin ?? TERRAIN_MARGIN\n const x0 = Math.min(...parts.map((part) => part.aabb[0]))\n const z0 = Math.min(...parts.map((part) => part.aabb[1]))\n const x1 = Math.max(...parts.map((part) => part.aabb[2]))\n const z1 = Math.max(...parts.map((part) => part.aabb[3]))\n if (parts.length) specs.push({ id: GROUND, material: 'concrete', shape: { kind: 'box', size: [x1 - x0 + margin, TERRAIN_THICKNESS, z1 - z0 + margin] }, position: [(x0 + x1) / 2, -TERRAIN_THICKNESS / 2, (z0 + z1) / 2], hp: 1e12, structure: { role: 'foundation' }, anchored: true, tags: ['terrain'] })\n const present = new Set([...parts.map((part) => part.id), GROUND])\n // in a frame (`portico`) the walls only close: a beam rests on the pillars, not on the wall under it, and is sized for the span between pillars (a wall that is lost does not bring the beam down)\n const infill = new Set(portico && slabOptions ? kept.filter((part) => part.role === 'wall').map((part) => part.id) : [])\n const beams = new Set(parts.filter((part) => part.role === 'beam' && (part.beamKind === 'bond_beam' || part.slab !== undefined)).map((part) => part.id))\n const joints: JointSpec[] = supports.filter((s) => present.has(s.part) && present.has(s.on)).map((s) => ({ id: `${s.part}~${s.on}`, a: s.part, b: s.on, kind: s.joint, bears: s.bears === false || (beams.has(s.part) && infill.has(s.on)) ? false : 'a_on_b' }))\n const spec: DestructibleSpec = { name: options.name ?? 'house', parts: specs, joints, tags: ['structure', 'house'] }\n return onSoil(withRebar(spec, structure, options, portico, slabOptions !== undefined), structure, options)\n}\n\nfunction withRebar(spec: DestructibleSpec, structure: PlanStructure, options: DestructibleSpecOptions, portico: boolean, panelled: boolean): DestructibleSpec {\n const { redundancy = 0.97, safetyOthers = 0.45 } = options\n const rebar = options.rebar ?? panelled\n if (!rebar || !structure.construction.frame.rebar) return spec\n const ratios = { ...REBAR_RATIOS, ...(rebar === true ? {} : rebar) }\n for (const part of spec.parts) {\n const role = part.structure?.role\n if (!role || !(role in ratios) || part.structure!.rebar || !MATERIALS.find((m) => m.id === part.material)?.strength?.tensileMPa) continue\n part.structure = { ...part.structure!, rebar: { ratio: ratios[role as keyof typeof ratios] } }\n }\n if (options.sized === false) return spec\n return sizeRebar(spec, { safety: safetyOthers, redundancy, redundancyRoles: portico ? ['column'] : ['column', 'wall'] })\n}\n\n/** Puts the house on its soil: the raft (with its piles) in place of the terrain, or the terrain with a footing under each part on it. */\nfunction onSoil(spec: DestructibleSpec, structure: PlanStructure, options: DestructibleSpecOptions): DestructibleSpec {\n if (options.soil === undefined) return spec\n const out: DestructibleSpec = { ...spec, soil: options.soil }\n const type = options.foundation ?? structure.construction.foundation.type\n const ground = out.parts.findIndex((p) => p.id === GROUND)\n if (ground < 0 || (!RAFT_FOUNDATIONS.has(type) && !options.piles)) return out\n const house = out.parts.filter((p) => p.id !== GROUND)\n // the raft is under what stands on the ground (walls, pillars, the ground floor), not under the eaves\n const onGround = new Set((out.joints ?? []).filter((j) => j.b === GROUND).map((j) => j.a))\n const footprint = house.filter((p) => onGround.has(p.id))\n const half = (p: PartSpec, k: number) => (p.shape.kind === 'box' ? p.shape.size[k] / 2 : p.shape.kind === 'cylinder' ? (k === 1 ? p.shape.height / 2 : p.shape.radius) : p.shape.radius)\n const under = footprint.length ? footprint : house\n const x0 = Math.min(...under.map((p) => p.position[0] - half(p, 0))) - RAFT_MARGIN, x1 = Math.max(...under.map((p) => p.position[0] + half(p, 0))) + RAFT_MARGIN\n const z0 = Math.min(...under.map((p) => p.position[2] - half(p, 2))) - RAFT_MARGIN, z1 = Math.max(...under.map((p) => p.position[2] + half(p, 2))) + RAFT_MARGIN\n const raft: PartSpec = {\n id: GROUND, material: 'concrete', shape: { kind: 'box', size: [x1 - x0, RAFT_THICKNESS, z1 - z0] }, position: [(x0 + x1) / 2, -RAFT_THICKNESS / 2, (z0 + z1) / 2],\n structure: { role: 'foundation' }, tags: ['raft'],\n }\n if (options.piles) {\n const given = options.piles === true ? {} : options.piles\n const count = given.count ?? Math.max(4, Math.ceil(((x1 - x0) * (z1 - z0)) / PILE_AREA))\n const diameter = given.diameter ?? 0.4\n const method = given.method ?? 'bored'\n const materials = new Map(MATERIALS.map((m) => [m.id, m]))\n const mass = [...house, raft].reduce((sum, p) => sum + (p.mass ?? partMass(p, materials.get(p.material)!)), 0)\n const soils = new Map(SOILS.map((d) => [d.id, d]))\n for (const d of options.soils ?? []) soils.set(d.id, d)\n const length = given.length ?? pileLength(profileOf(options.soil), { load: (mass * GRAVITY) / count, diameter, top: RAFT_THICKNESS, method, soils })\n raft.structure = { role: 'foundation', pile: { length, diameter, count, method } }\n }\n out.parts = out.parts.map((p, i) => (i === ground ? raft : p))\n return out\n}\n","import { GROUND } from './types'\nimport type { StructurePart, Support } from './types'\n\n/**\n * Load each part carries at rest, by the rules of the Visor de casas 3D (which the destruction world shares): load only goes down to supports closer to\n * the ground, shared equally, and a partition wall carries nothing, so what rests only on partitions has no load. `without` leaves one part out (as if it\n * had failed). Parts that are not structural (the tank) are not loaded.\n */\nexport function loadsAtRest(parts: readonly StructurePart[], supports: readonly Support[], without?: string): Map<string, number> {\n const byId = new Map(parts.filter((part) => part.id !== without).map((part) => [part.id, part]))\n const resting = new Map<string, string[]>()\n const carrying = new Map<string, string[]>()\n const push = (map: Map<string, string[]>, key: string, value: string): void => {\n const list = map.get(key)\n if (list) list.push(value)\n else map.set(key, [value])\n }\n for (const support of supports) {\n if (support.bears === false) continue\n if (!byId.has(support.part) || (support.on !== GROUND && !byId.has(support.on))) continue\n push(resting, support.part, support.on)\n push(carrying, support.on, support.part)\n }\n const partition = (id: string): boolean => byId.get(id)?.role === 'partition'\n const structural = (id: string): boolean => byId.has(id) && byId.get(id)!.role !== 'none'\n const distance = new Map<string, number>([[GROUND, 0]])\n const queue = [GROUND]\n for (let head = 0; head < queue.length; head++) {\n const current = queue[head]!\n if (current !== GROUND && partition(current)) continue\n for (const above of carrying.get(current) ?? []) {\n if (distance.has(above) || !structural(above)) continue\n distance.set(above, distance.get(current)! + 1)\n queue.push(above)\n }\n }\n const incoming = new Map<string, number>()\n const loads = new Map<string, number>()\n for (let head = queue.length - 1; head >= 1; head--) {\n const id = queue[head]!\n const total = (byId.get(id)!.mass || 1) + (incoming.get(id) ?? 0)\n loads.set(id, total)\n const below = (resting.get(id) ?? []).filter((other) => distance.has(other) && distance.get(other)! < distance.get(id)! && !(other !== GROUND && partition(other)))\n for (const other of below) incoming.set(other, (incoming.get(other) ?? 0) + total / below.length)\n }\n return loads\n}\n\nexport interface SizingOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest. */\n safety: number\n /** The most of its capacity a pillar or bearing wall uses after any other pillar or bearing wall is lost. */\n redundancy: number\n /** Fraction of capacity every other structural part uses at rest. */\n safetyOthers: number\n}\n\nconst isBearing = (part: StructurePart): boolean => part.role === 'column' || part.role === 'wall'\n\n/**\n * Capacity of each loaded part, as a designer would size it: a pillar or bearing wall uses `safety` of it at rest and stays under `redundancy` when\n * any other pillar or bearing wall is lost (the house holds one loss and falls with two); every other part uses `safetyOthers`.\n * `sizeStructure` of game-destruction gives the same numbers except for beams of a framed building (it holds them under `redundancy` too).\n */\nexport function sizeCapacities(parts: readonly StructurePart[], supports: readonly Support[], options: SizingOptions): Map<string, number> {\n const loads = loadsAtRest(parts, supports)\n const worst = new Map<string, number>()\n for (const part of parts.filter(isBearing)) {\n for (const [id, load] of loadsAtRest(parts, supports, part.id)) {\n const before = loads.get(id)\n if (before && load / before > (worst.get(id) ?? 1)) worst.set(id, load / before)\n }\n }\n const capacities = new Map<string, number>()\n for (const part of parts) {\n const load = loads.get(part.id)\n if (load === undefined || part.role === 'none') continue\n const factor = isBearing(part) ? Math.max(1 / options.safety, (worst.get(part.id) ?? 1) / options.redundancy) : 1 / options.safetyOthers\n capacities.set(part.id, Math.max(1, load * factor))\n }\n return capacities\n}\n","import type { Rect } from '../types'\nimport type { SlabPanelOptions } from './options'\n\n/** A line of wall seen from above: it runs along `dir` at the coordinate `at` of the other axis, over `[from, to]`. */\nexport interface WallLine {\n dir: 'u' | 'v'\n at: number\n from: number\n to: number\n}\n\n/** A beam line: it runs along `dir` at `at` over `[from, to]`. A cut along `v` at `u = at` separates the panels on its two sides. */\nexport type Cut = WallLine\n\nexport interface Layout {\n leaves: Rect[]\n cuts: Cut[]\n}\n\nconst EPS = 1e-6\n\n/** The wall boxes `[u0, v0, u1, v1]` as lines. */\nexport function linesOf(boxes: readonly Rect[]): WallLine[] {\n return boxes.map(([u0, v0, u1, v1]) => (u1 - u0 >= v1 - v0 ? { dir: 'u', at: (v0 + v1) / 2, from: u0, to: u1 } : { dir: 'v', at: (u0 + u1) / 2, from: v0, to: v1 }))\n}\n\n/** Share of `[from, to]` the walls of the line `(dir, at)` cover, with gaps up to `doorGap` counted as wall. */\nfunction coverage(lines: readonly WallLine[], dir: 'u' | 'v', at: number, from: number, to: number, options: SlabPanelOptions): number {\n const spans = lines\n .filter((line) => line.dir === dir && Math.abs(line.at - at) <= options.lineTolerance)\n .map((line): [number, number] => [Math.max(from, line.from), Math.min(to, line.to)])\n .filter(([a, b]) => b > a)\n .sort((x, y) => x[0] - y[0])\n let covered = 0\n let end = from\n let start = NaN\n for (const [a, b] of spans) {\n if (Number.isNaN(start)) {\n start = a\n end = b\n } else if (a - end <= options.doorGap) end = Math.max(end, b)\n else {\n covered += end - start\n start = a\n end = b\n }\n }\n if (!Number.isNaN(start)) covered += end - start\n return to > from ? covered / (to - from) : 0\n}\n\n/** Positions of the lines of one direction, walls closer than the tolerance merged. */\nfunction positions(lines: readonly WallLine[], dir: 'u' | 'v', tolerance: number): number[] {\n const sorted = lines.filter((line) => line.dir === dir).map((line) => line.at).sort((a, b) => a - b)\n const out: number[] = []\n let group: number[] = []\n for (const at of sorted) {\n if (group.length && at - group[group.length - 1]! > tolerance) {\n out.push(group.reduce((s, x) => s + x, 0) / group.length)\n group = []\n }\n group.push(at)\n }\n if (group.length) out.push(group.reduce((s, x) => s + x, 0) / group.length)\n return out\n}\n\ninterface Candidate {\n dir: 'u' | 'v'\n at: number\n coverage: number\n /** 0 at the middle of the rectangle, 1 at its edge. */\n skew: number\n}\n\nconst round = (x: number): number => Math.round(x * 100) / 100\n\n/** The cut of `rect`: along `dir` at `at`, or none when it is already a panel. */\nfunction choose(rect: Rect, lines: readonly WallLine[], options: SlabPanelOptions): { dir: 'u' | 'v'; at: number } | null {\n const [u0, v0, u1, v1] = rect\n const width = u1 - u0\n const depth = v1 - v0\n const tooWide = width > options.maxSpan + EPS\n const tooDeep = depth > options.maxSpan + EPS\n const candidates: Candidate[] = []\n for (const at of positions(lines, 'v', options.lineTolerance)) {\n if (at < u0 + options.minPanel - EPS || at > u1 - options.minPanel + EPS) continue\n candidates.push({ dir: 'v', at, coverage: coverage(lines, 'v', at, v0, v1, options), skew: Math.abs(at - (u0 + u1) / 2) / (width / 2) })\n }\n for (const at of positions(lines, 'u', options.lineTolerance)) {\n if (at < v0 + options.minPanel - EPS || at > v1 - options.minPanel + EPS) continue\n candidates.push({ dir: 'u', at, coverage: coverage(lines, 'u', at, u0, u1, options), skew: Math.abs(at - (v0 + v1) / 2) / (depth / 2) })\n }\n const boundary = candidates.filter((c) => c.coverage >= options.lineCoverage)\n if (tooWide || tooDeep) {\n // cut across the longer side when both are too long\n const across: 'u' | 'v' = tooWide && (!tooDeep || width >= depth) ? 'v' : 'u'\n const pool = boundary.filter((c) => c.dir === across)\n if (pool.length) {\n const best = pool.reduce((a, b) => (b.skew - 0.25 * b.coverage < a.skew - 0.25 * a.coverage ? b : a))\n return { dir: best.dir, at: round(best.at) }\n }\n const length = across === 'v' ? width : depth\n const origin = across === 'v' ? u0 : v0\n return { dir: across, at: round(origin + length / Math.ceil(length / options.maxSpan - EPS)) }\n }\n if (!boundary.length) return null\n const best = boundary.reduce((a, b) => (b.coverage - 0.25 * b.skew > a.coverage - 0.25 * a.skew ? b : a))\n return { dir: best.dir, at: round(best.at) }\n}\n\n/** Cuts `rect` along the walls and into pieces no wider than `maxSpan` (the panels of a slab) and returns them with the cut lines. */\nexport function layoutPanels(rect: Rect, lines: readonly WallLine[], options: SlabPanelOptions): Layout {\n const leaves: Rect[] = []\n const cuts: Cut[] = []\n const walk = (r: Rect, depth: number): void => {\n const cut = depth < 16 ? choose(r, lines, options) : null\n if (!cut) {\n leaves.push(r)\n return\n }\n if (cut.dir === 'v') {\n cuts.push({ dir: 'v', at: cut.at, from: r[1], to: r[3] })\n walk([r[0], r[1], cut.at, r[3]], depth + 1)\n walk([cut.at, r[1], r[2], r[3]], depth + 1)\n } else {\n cuts.push({ dir: 'u', at: cut.at, from: r[0], to: r[2] })\n walk([r[0], r[1], r[2], cut.at], depth + 1)\n walk([r[0], cut.at, r[2], r[3]], depth + 1)\n }\n }\n walk(rect, 0)\n return { leaves, cuts }\n}\n\nexport const areaOf = (rect: Rect): number => Math.max(0, rect[2] - rect[0]) * Math.max(0, rect[3] - rect[1])\n\nexport function overlapArea(a: Rect, b: Rect): number {\n return Math.max(0, Math.min(a[2], b[2]) - Math.max(a[0], b[0])) * Math.max(0, Math.min(a[3], b[3]) - Math.max(a[1], b[1]))\n}\n\n/** Share of `rect` inside the union of `footprint` (the rectangles of the footprint do not overlap). */\nexport function shareInside(rect: Rect, footprint: readonly Rect[]): number {\n const area = areaOf(rect)\n return area > 0 ? Math.min(1, footprint.reduce((sum, other) => sum + overlapArea(rect, other), 0) / area) : 0\n}\n\n/** The stretches of the cut that border at least one of `panels` (the beams under the kept panels), as `[from, to]` runs. */\nexport function runsOf(cut: Cut, panels: readonly Rect[], tolerance = 0.02): [number, number][] {\n const spans: [number, number][] = []\n for (const [u0, v0, u1, v1] of panels) {\n if (cut.dir === 'v') {\n if (Math.abs(u0 - cut.at) < tolerance || Math.abs(u1 - cut.at) < tolerance) spans.push([Math.max(v0, cut.from), Math.min(v1, cut.to)])\n } else if (Math.abs(v0 - cut.at) < tolerance || Math.abs(v1 - cut.at) < tolerance) spans.push([Math.max(u0, cut.from), Math.min(u1, cut.to)])\n }\n const sorted = spans.filter(([a, b]) => b - a > tolerance).sort((x, y) => x[0] - y[0])\n const runs: [number, number][] = []\n for (const [a, b] of sorted) {\n const last = runs[runs.length - 1]\n if (last && a <= last[1] + tolerance) last[1] = Math.max(last[1], b)\n else runs.push([a, b])\n }\n return runs\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { densityOf } from '../density'\nimport { round2, touches } from '../geometry'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\nimport { GROUND } from '../types'\nimport type { Rect, PlanStructure, StructurePart, Support } from '../types'\nimport type { PartsAndSupports } from '../wall-detail/apply'\nimport { layoutPanels, linesOf, runsOf, shareInside } from './layout'\nimport type { Cut } from './layout'\nimport type { SlabPanelOptions } from './options'\n\nconst SLAB_ID = /^slab_(\\d+|top.*|ceiling|base)$/\nconst PLAN_TOLERANCE = 0.05\n/** Metres a support may end below the bottom of what it holds and still hold it (walls end under the bond beam, pillars at the slab). */\nconst BELOW = 0.35\nconst UP = 0.15\n/** A beam needs a support this close to each of its ends. */\nconst END_REACH = 0.35\nconst EPS = 1e-6\n\ntype Interval = [number, number]\n\nconst ceilTo = (value: number, step: number): number => Math.ceil(value / step - 1e-9) * step\nconst isConcreteSlab = (part: StructurePart, material: string): boolean => part.role === 'slab' && part.material === material && SLAB_ID.test(part.id)\nconst isBondBeam = (part: StructurePart, material: string): boolean => part.role === 'beam' && part.beamKind === 'bond_beam' && part.material === material\n\nfunction merged(intervals: readonly Interval[]): Interval[] {\n const out: Interval[] = []\n for (const [a, b] of intervals.slice().sort((x, y) => x[0] - y[0])) {\n const last = out[out.length - 1]\n if (last && a <= last[1] + EPS) last[1] = Math.max(last[1], b)\n else out.push([a, b])\n }\n return out\n}\n\n/**\n * The span the destruction world measures for a beam from `0` to `length` held at `supports`: twice the farthest any point is from its nearest support\n * (two supports `g` apart give `g`; a beam hanging `e` past its last support gives `2e`). `at` is where a new support helps the most.\n */\nexport function beamSpan(length: number, supports: readonly Interval[]): { span: number; at: number; lo: number; hi: number } {\n const held = merged(supports.map(([a, b]): Interval => [Math.max(0, a), Math.min(length, b)]).filter(([a, b]) => b > a))\n if (!held.length) return { span: Infinity, at: length / 2, lo: 0, hi: length }\n let span = 0\n let at = length / 2\n let lo = 0\n let hi = length\n const lead = held[0]![0]\n if (2 * lead > span) {\n span = 2 * lead\n at = 0\n lo = 0\n hi = lead\n }\n const trail = length - held[held.length - 1]![1]\n if (2 * trail > span) {\n span = 2 * trail\n at = length\n lo = length - trail\n hi = length\n }\n for (let k = 1; k < held.length; k++) {\n const gap = held[k]![0] - held[k - 1]![1]\n if (gap > span) {\n span = gap\n at = (held[k]![0] + held[k - 1]![1]) / 2\n lo = held[k - 1]![1]\n hi = held[k]![0]\n }\n }\n return { span, at, lo, hi }\n}\n\n/** A beam as a line in the plan: it runs along `dir` at the coordinate `at` of the other axis, from `from` to `to`. */\ninterface Line {\n dir: 'u' | 'v'\n at: number\n from: number\n to: number\n}\n\nconst lineOf = (aabb: Rect, dir: 'u' | 'v'): Line => (dir === 'u' ? { dir, at: (aabb[1] + aabb[3]) / 2, from: aabb[0], to: aabb[2] } : { dir, at: (aabb[0] + aabb[2]) / 2, from: aabb[1], to: aabb[3] })\nconst pointOf = (line: Line, s: number): [number, number] => (line.dir === 'u' ? [line.from + s, line.at] : [line.at, line.from + s])\n\n/** Where `box` holds a beam of `line` and `width`: the stretch of the beam (from its start), or undefined when it does not touch. */\nfunction holds(line: Line, width: number, box: Rect): Interval | undefined {\n const [across0, across1, along0, along1] = line.dir === 'u' ? [box[1], box[3], box[0], box[2]] : [box[0], box[2], box[1], box[3]]\n if (across0 >= line.at + width / 2 + PLAN_TOLERANCE || across1 <= line.at - width / 2 - PLAN_TOLERANCE) return undefined\n const a = Math.max(along0 - PLAN_TOLERANCE, line.from)\n const b = Math.min(along1 + PLAN_TOLERANCE, line.to)\n return b > a ? [a - line.from, b - line.from] : undefined\n}\n\n/** What can hold a beam from below: a pillar or a bearing wall, with how many steps it is from the ground (the destruction world only rests a part on the nearest-to-ground of its supports). */\ninterface Prop {\n box: Rect\n dist: number\n part?: StructurePart\n}\n\ninterface Spot {\n u: number\n v: number\n}\n\ninterface Context {\n structure: PlanStructure\n options: SlabPanelOptions\n beamMaterial: string\n pillarMaterial: string\n joint: JointKind\n wallThickness: number\n parts: StructurePart[]\n supports: Support[]\n panelsOf: Map<string, StructurePart[]>\n pillars: number\n groundBase: string\n /** The distances of the last call to `distancesOf`, kept while no part or support is added (a tower asks for them once per bond beam and per slab). */\n distCache?: { parts: number; supports: number; map: Map<string, number> }\n}\n\nconst boxOfSpot = (spot: Spot, side: number): Rect => [spot.u - side / 2, spot.v - side / 2, spot.u + side / 2, spot.v + side / 2]\n\n/** Steps from the ground of every part, the way the destruction world counts them: through the supports that carry, and not through a partition. */\nfunction distancesOf(context: Context): Map<string, number> {\n const cache = context.distCache\n if (cache && cache.parts === context.parts.length && cache.supports === context.supports.length) return cache.map\n const map = distances(context.parts, context.supports)\n context.distCache = { parts: context.parts.length, supports: context.supports.length, map }\n return map\n}\n\nfunction distances(parts: readonly StructurePart[], supports: readonly Support[]): Map<string, number> {\n const byId = new Map(parts.map((p) => [p.id, p]))\n const carrying = new Map<string, string[]>()\n for (const s of supports) {\n if (s.bears === false || !byId.has(s.part) || (s.on !== GROUND && !byId.has(s.on))) continue\n const list = carrying.get(s.on)\n if (list) list.push(s.part)\n else carrying.set(s.on, [s.part])\n }\n const dist = new Map<string, number>([[GROUND, 0]])\n const queue = [GROUND]\n for (let head = 0; head < queue.length; head++) {\n const current = queue[head]!\n if (current !== GROUND && byId.get(current)?.role === 'partition') continue\n for (const above of carrying.get(current) ?? []) {\n if (dist.has(above) || byId.get(above)?.role === 'none') continue\n dist.set(above, dist.get(current)! + 1)\n queue.push(above)\n }\n }\n return dist\n}\n\n/** Pillars and bearing walls that end where `y0` is (under a beam or a bond beam at that height). */\nfunction propsUnder(context: Context, dist: ReadonlyMap<string, number>, y0: number, y1: number, floor: number): Prop[] {\n return context.parts\n .filter((q) => (q.role === 'column' || q.role === 'wall') && q.floor === floor && dist.has(q.id) && q.y0 < y0 - PLAN_TOLERANCE && q.y1 >= y0 - BELOW && q.y1 <= y1 + UP)\n .map((q) => ({ box: q.aabb, dist: dist.get(q.id)!, part: q }))\n}\n\n/** What holds the beam: of the props that touch it only the ones nearest to the ground do (the world rests a part on those). */\nfunction heldBy(line: Line, width: number, props: readonly Prop[]): { intervals: Interval[]; used: Prop[] } {\n const touching = props.map((prop) => ({ prop, interval: holds(line, width, prop.box) })).filter((x): x is { prop: Prop; interval: Interval } => x.interval !== undefined)\n if (!touching.length) return { intervals: [], used: [] }\n const nearest = Math.min(...touching.map((x) => x.prop.dist))\n const used = touching.filter((x) => x.prop.dist === nearest)\n return { intervals: used.map((x) => x.interval), used: used.map((x) => x.prop) }\n}\n\n/**\n * Finds where a beam (or bond beam) needs pillars so that it never goes more than `maxSpan` without a support (and, for a beam, so that each end is\n * held). `spots` collects the pillars, which then hold the beams after it; `dist` is how far from the ground a pillar is.\n */\nfunction pillarsFor(\n line: Line, width: number, props: readonly Prop[], spots: Array<Spot & { dist: number }>, dist: number, options: SlabPanelOptions, ends: boolean, ground: readonly Rect[] = [],\n): Interval[] {\n const length = line.to - line.from\n const side = options.columnSide\n const all = (): Prop[] => [...props, ...spots.map((spot) => ({ box: boxOfSpot(spot, side), dist: spot.dist }))]\n // a pillar of a storey above the first stands on a beam or a bond beam of the slab under it, not on the middle of a panel\n const allowed = merged(ground.map((box) => holds(line, 0.02, box)).filter((x): x is Interval => x !== undefined))\n const place = (at: number, lo: number, hi: number): number => {\n if (!allowed.length) return at\n let best: number | undefined\n let gap = Infinity\n for (const [a, b] of allowed) {\n const from = Math.max(a + side / 2, lo + 0.2)\n const to = Math.min(b - side / 2, hi - 0.2)\n if (to < from) continue\n const clamped = Math.min(to, Math.max(from, at))\n if (Math.abs(clamped - at) < gap) {\n gap = Math.abs(clamped - at)\n best = clamped\n }\n }\n return best ?? at\n }\n let held = heldBy(line, width, all()).intervals\n for (let guard = 0; guard < 64; guard++) {\n let at: number | undefined\n let lo = 0\n let hi = length\n if (ends && !held.some(([a]) => a <= END_REACH)) at = 0\n else if (ends && !held.some(([, b]) => b >= length - END_REACH)) at = length\n else {\n const found = beamSpan(length, held)\n if (found.span <= options.maxSpan + 1e-3) break\n at = found.at\n lo = found.lo\n hi = found.hi\n }\n const [u, v] = pointOf(line, at === 0 || at === length ? at : place(at, lo, hi))\n const spot = { u: round2(u), v: round2(v), dist }\n if (spots.some((other) => Math.hypot(other.u - spot.u, other.v - spot.v) < 0.15)) break\n spots.push(spot)\n held = heldBy(line, width, all()).intervals\n }\n return held\n}\n\nconst make = (draft: Omit<StructurePart, 'mass'>): StructurePart => {\n const [u0, v0, u1, v1] = draft.aabb\n const volume = Math.max(0, (u1 - u0) * (v1 - v0) * (draft.y1 - draft.y0))\n return { ...draft, aabb: draft.aabb.map(round2) as Rect, y0: round2(draft.y0), y1: round2(draft.y1), mass: Math.max(1, Math.round(volume * densityOf(draft.material))) }\n}\n\nconst rest = (context: Context, on: StructurePart | string, below: StructurePart, joint: JointKind = context.joint): void => {\n context.supports.push({ part: below.id, on: typeof on === 'string' ? on : on.id, joint })\n}\n\nconst distance = (a: Rect, b: Rect): number => Math.hypot(Math.max(a[0] - b[2], b[0] - a[2], 0), Math.max(a[1] - b[3], b[1] - a[3], 0))\n\n/** The panels of `slab` that `box` touches (the nearest one when none does). */\nfunction panelsUnder(context: Context, slab: string, box: Rect): StructurePart[] {\n const panels = context.panelsOf.get(slab) ?? []\n const touching = panels.filter((panel) => touches(panel.aabb, box, PLAN_TOLERANCE))\n return touching.length ? touching : panels.slice().sort((a, b) => distance(a.aabb, box) - distance(b.aabb, box)).slice(0, 1)\n}\n\n/** The pillar at `spot` from `bottom` to `top`, on the ground or on the slab of the storey below. */\nfunction addPillar(context: Context, spot: Spot, bottom: number, top: number, floor: number, below: string | undefined, slab: string): StructurePart {\n const pillar = make({\n id: `pillar_${floor}_${context.pillars++}`, role: 'column', material: context.pillarMaterial, floor, slab, aabb: boxOfSpot(spot, context.options.columnSide), y0: bottom, y1: top,\n })\n context.parts.push(pillar)\n if (below && context.panelsOf.has(below)) for (const panel of panelsUnder(context, below, pillar.aabb)) rest(context, panel, pillar, 'rebar')\n else rest(context, context.groundBase, pillar, 'rebar')\n return pillar\n}\n\n/** The storey under a slab: its floor, the slab it stands on (none: the ground) and the height its pillars start at. */\nfunction storeyUnder(context: Context, slab: StructurePart): { floor: number; below: string | undefined; bottom: number } {\n const levels = context.structure.levels\n const match = /^slab_(\\d+)$/.exec(slab.id)\n const floor = match && Number(match[1]) >= 1 ? Number(match[1]) - 1 : slab.id === 'slab_base' ? 0 : slab.floor\n return { floor, below: slab.id === 'slab_base' || floor < 1 ? undefined : `slab_${floor}`, bottom: slab.id === 'slab_base' ? 0 : (levels[floor] ?? 0) }\n}\n\n/** Steps from the ground of a pillar that stands under `slab`. */\nfunction pillarDist(context: Context, dist: ReadonlyMap<string, number>, storey: { below: string | undefined }): number {\n if (storey.below && context.panelsOf.has(storey.below)) return Math.min(...context.panelsOf.get(storey.below)!.map((p) => dist.get(p.id) ?? 99)) + 1\n return (dist.get(context.groundBase) ?? 0) + 1\n}\n\n/** Where a pillar can stand on the slab `below`: on its beams and on the bond beams at its level. */\nfunction groundOf(context: Context, below: string): Rect[] {\n const panels = context.panelsOf.get(below) ?? []\n const level = panels[0]?.y1\n if (level === undefined) return []\n return context.parts.filter((q) => q.role === 'beam' && (q.slab === below || (q.beamKind === 'bond_beam' && Math.abs(q.y1 - level) < 0.4))).map((q) => q.aabb)\n}\n\n/** Thickness of the panels of a slab: the shortest side of the widest of them over `thicknessRatio`, not under the minimum of the use. */\nfunction thicknessOf(leaves: readonly Rect[], roof: boolean, options: SlabPanelOptions): number {\n const shortest = Math.max(...leaves.map((leaf) => Math.min(leaf[2] - leaf[0], leaf[3] - leaf[1])))\n return Math.max(roof ? options.roofMinThickness : options.floorMinThickness, ceilTo(shortest / options.thicknessRatio, 0.01))\n}\n\nconst restThickness = (slab: StructurePart, thickness: number, roof: boolean): void => {\n if (roof) slab.y1 = round2(slab.y0 + thickness)\n else slab.y0 = round2(slab.y1 - thickness)\n slab.mass = Math.max(1, Math.round((slab.aabb[2] - slab.aabb[0]) * (slab.aabb[3] - slab.aabb[1]) * (slab.y1 - slab.y0) * densityOf(slab.material)))\n}\n\n/** Cuts one slab into panels, adds the beams under their edges and the pillars those need; re-points what rested on the slab. */\nfunction cutSlab(context: Context, slab: StructurePart, wallBoxes: readonly Rect[]): void {\n const { options } = context\n const roof = slab.cover === true\n const layout = layoutPanels(slab.aabb, linesOf(wallBoxes), options)\n const footprint = slab.footprint ?? [slab.aabb]\n const kept = layout.leaves.filter((leaf) => shareInside(leaf, footprint) >= options.footprintShare)\n const leaves = kept.length ? kept : [slab.aabb]\n const thickness = thicknessOf(leaves, roof, options)\n if (leaves.length === 1 && layout.cuts.length === 0) {\n restThickness(slab, thickness, roof)\n context.panelsOf.set(slab.id, [slab])\n return\n }\n const own = context.supports.filter((s) => s.part === slab.id && s.bears !== false)\n const resting = context.supports.filter((s) => s.on === slab.id)\n context.supports = context.supports.filter((s) => s.part !== slab.id && s.on !== slab.id)\n const [y0, y1] = roof ? [slab.y0, slab.y0 + thickness] : [slab.y1 - thickness, slab.y1]\n const panels = leaves.map((leaf, k) =>\n make({\n id: `${slab.id}_p${k}`, role: 'slab', material: slab.material, aabb: leaf, y0, y1, floor: slab.floor, ...(slab.cover ? { cover: true } : {}), slab: slab.id,\n ...(slab.footprint ? { footprint: slab.footprint } : {}),\n }),\n )\n context.parts.splice(context.parts.indexOf(slab), 1, ...panels)\n context.panelsOf.set(slab.id, panels)\n\n // the beams: under the edges of the panels, on pillars and bearing walls; a bond beam that already runs there is the beam\n const top = roof ? slab.y0 : y0\n const dist = distancesOf(context)\n const storey = storeyUnder(context, slab)\n const props = propsUnder(context, dist, top, slab.y1, storey.floor)\n const near = props.length ? Math.min(...props.map((p) => p.dist)) : pillarDist(context, dist, storey)\n const spots: Array<Spot & { dist: number }> = []\n const bonds = context.parts.filter((q) => q.role === 'beam' && q.beamKind === 'bond_beam' && q.y1 >= top - BELOW && q.y0 < slab.y1)\n const ground = storey.below ? groundOf(context, storey.below) : []\n const covered = (line: Line): boolean => {\n const width = context.wallThickness\n const spans = merged(bonds.map((bond) => holds(line, width + 0.5, bond.aabb)).filter((x): x is Interval => x !== undefined))\n return spans.reduce((sum, [a, b]) => sum + Math.max(0, Math.min(b, line.to - line.from) - Math.max(a, 0)), 0) >= (line.to - line.from) * 0.9\n }\n const [su0, sv0, su1, sv1] = slab.aabb\n const borders: Cut[] = [\n { dir: 'u', at: sv0, from: su0, to: su1 }, { dir: 'u', at: sv1, from: su0, to: su1 }, { dir: 'v', at: su0, from: sv0, to: sv1 }, { dir: 'v', at: su1, from: sv0, to: sv1 },\n ]\n const beams: Array<{ part: StructurePart; line: Line; width: number }> = []\n let count = 0\n for (const cut of [...layout.cuts, ...borders]) {\n for (const [from, to] of runsOf(cut, leaves)) {\n const line: Line = { dir: cut.dir === 'v' ? 'v' : 'u', at: cut.at, from, to }\n if (covered(line)) continue\n const held = pillarsFor(line, context.wallThickness, props, spots, near, options, true, ground)\n const span = Math.min(beamSpan(to - from, held).span, options.maxSpan)\n const depth = beamDepthFor(span, options)\n const width = Math.max(context.wallThickness, round2(depth / options.beamWidthRatio))\n const aabb: Rect = line.dir === 'u' ? [from, cut.at - width / 2, to, cut.at + width / 2] : [cut.at - width / 2, from, cut.at + width / 2, to]\n beams.push({ part: make({ id: `${slab.id}_b${count++}`, role: 'beam', material: context.beamMaterial, aabb, y0: top - depth, y1: top, floor: slab.floor, slab: slab.id }), line, width })\n }\n }\n const pillars = spots.map((spot) => addPillar(context, spot, storey.bottom, top, storey.floor, storey.below, slab.id))\n context.parts.splice(context.parts.indexOf(panels[panels.length - 1]!) + 1, 0, ...beams.map((b) => b.part))\n const all: Prop[] = [...props, ...pillars.map((p, k) => ({ box: p.aabb, dist: spots[k]!.dist, part: p }))]\n for (const { part: beam, line, width } of beams) for (const used of heldBy(line, width, all).used) rest(context, used.part!, beam)\n\n // the panels rest on the beams of their edges and on the bond beams (the walls and pillars under them hold the beams)\n for (const panel of panels) {\n for (const { part: beam } of beams) if (touches(panel.aabb, beam.aabb, PLAN_TOLERANCE)) rest(context, beam, panel)\n for (const bond of bonds) if (touches(panel.aabb, bond.aabb, PLAN_TOLERANCE)) rest(context, bond, panel, own.find((s) => s.on === bond.id)?.joint ?? context.joint)\n }\n for (const panel of panels.filter((p) => !context.supports.some((s) => s.part === p.id))) {\n const nearest = [...beams.map((b) => b.part), ...bonds].sort((a, b) => distance(a.aabb, panel.aabb) - distance(b.aabb, panel.aabb))[0]\n if (nearest) rest(context, nearest, panel)\n }\n // what rested on the slab rests on the panels it touches\n for (const support of resting) {\n const upper = context.parts.find((q) => q.id === support.part)\n if (!upper) continue\n for (const panel of panelsUnder(context, slab.id, upper.aabb)) context.supports.push({ ...support, on: panel.id })\n }\n}\n\n/** Depth of a beam over `span` metres: `span / beamDepthRatio` up to a multiple of `beamStep`, not under `minimum`. */\nexport const beamDepthFor = (span: number, options: SlabPanelOptions, minimum = options.beamMinDepth): number => Math.max(minimum, ceilTo(span / options.beamDepthRatio, options.beamStep))\n\n/**\n * After the walls are cut at their windows: a bond beam over a wide opening spans it (the destruction world rests it on the piers, the nearest of its supports\n * to the ground), so it gets the depth and the width of a beam of that span. Returns copies of the parts it changes.\n */\nexport function deepenBondBeams(input: PartsAndSupports, structure: PlanStructure, options: SlabPanelOptions): PartsAndSupports {\n const frame = structure.construction.frame\n if (!frame.rebar) return input\n const dist = distances(input.parts, input.supports)\n const context = { parts: input.parts } as Context\n let changed = false\n const parts = input.parts.map((part) => {\n if (!isBondBeam(part, frame.beams) || !dist.has(part.id)) return part\n const dir: 'u' | 'v' = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1] ? 'u' : 'v'\n const line = lineOf(part.aabb, dir)\n const width = dir === 'u' ? part.aabb[3] - part.aabb[1] : part.aabb[2] - part.aabb[0]\n const span = beamSpan(line.to - line.from, heldBy(line, width, propsUnder(context, dist, part.y0, part.y1, part.floor)).intervals).span\n if (!(span > 1.5) || !Number.isFinite(span)) return part\n const depth = Math.max(part.y1 - part.y0, beamDepthFor(span, options))\n const wide = Math.max(width, round2(depth / options.beamWidthRatio))\n const grow = (wide - width) / 2\n changed = true\n const aabb: Rect = dir === 'u' ? [part.aabb[0], part.aabb[1] - grow, part.aabb[2], part.aabb[3] + grow] : [part.aabb[0] - grow, part.aabb[1], part.aabb[2] + grow, part.aabb[3]]\n return make({ ...part, aabb, y0: part.y1 - depth })\n })\n return changed ? { parts, supports: input.supports } : input\n}\n\n/** Adds the pillars a concrete bond beam needs under it (a frame whose walls only close has none between its corners) and deepens it over a wide span. */\nfunction supportBondBeam(context: Context, plate: StructurePart): void {\n const { options } = context\n const dir: 'u' | 'v' = plate.aabb[2] - plate.aabb[0] >= plate.aabb[3] - plate.aabb[1] ? 'u' : 'v'\n const line = lineOf(plate.aabb, dir)\n const width = dir === 'u' ? plate.aabb[3] - plate.aabb[1] : plate.aabb[2] - plate.aabb[0]\n const dist = distancesOf(context)\n const floor = plate.floor\n const props = propsUnder(context, dist, plate.y0, plate.y1, floor)\n const storey = { floor, below: floor >= 1 ? `slab_${floor}` : undefined, bottom: context.structure.levels[floor] ?? 0 }\n const spots: Array<Spot & { dist: number }> = []\n const near = props.length ? Math.min(...props.map((p) => p.dist)) : pillarDist(context, dist, storey)\n const held = pillarsFor(line, width, props, spots, near, options, false)\n const span = beamSpan(line.to - line.from, held).span\n if (span > 1.5) {\n const depth = Math.max(plate.y1 - plate.y0, beamDepthFor(Math.min(span, options.maxSpan), options))\n plate.y0 = round2(plate.y1 - depth)\n plate.mass = Math.max(1, Math.round((plate.aabb[2] - plate.aabb[0]) * (plate.aabb[3] - plate.aabb[1]) * depth * densityOf(plate.material)))\n }\n for (const spot of spots) {\n const pillar = addPillar(context, spot, storey.bottom, plate.y0 + PLAN_TOLERANCE, floor, storey.below, plate.id)\n rest(context, pillar, plate, 'rebar')\n }\n}\n\n/**\n * The slabs of concrete cut into panels with beams (`SlabPanelOptions`): see `T10-estrutura-real.md` §12. `input` is the structure as\n * `toDestructibleSpec` has it (walls with their roles), and the result has the panels, the beams, the pillars they need and the supports re-pointed.\n */\nexport function applySlabPanels(input: PartsAndSupports, structure: PlanStructure, options: SlabPanelOptions): PartsAndSupports {\n const frame = structure.construction.frame\n const system = CONSTRUCTION_SYSTEMS.get(structure.construction.system)\n if (!frame.rebar || !system || system.timber || structure.levels.length > options.maxStoreys) return input\n const parts = input.parts.map((p) => ({ ...p }))\n const slabs = parts.filter((p) => isConcreteSlab(p, frame.slabs))\n const bonds = parts.filter((p) => isBondBeam(p, frame.beams))\n if (!slabs.length && !bonds.length) return input\n const firstColumn = input.supports.find((s) => /^(column_0_|building_column_)/.test(s.part) && !/^(column_0_|building_column_)/.test(s.on))\n const context: Context = {\n structure, options, beamMaterial: frame.beams, pillarMaterial: frame.pillars, joint: system.joints.slab, wallThickness: (structure.construction.walls.thickness as number | undefined) ?? 0.15,\n parts, supports: input.supports.slice(), panelsOf: new Map(), pillars: 0, groundBase: firstColumn?.on ?? GROUND,\n }\n const walls = parts.filter((p) => /^wall_/.test(p.id) && (p.role === 'wall' || p.role === 'partition'))\n const jobs = [...bonds.map((part) => ({ part, bond: true })), ...slabs.map((part) => ({ part, bond: false }))].sort((a, b) => a.part.y0 - b.part.y0 || Number(b.bond) - Number(a.bond))\n for (const job of jobs) {\n if (job.bond) {\n supportBondBeam(context, job.part)\n continue\n }\n const slab = job.part\n const boxes = walls.filter((w) => (w.y0 >= slab.y1 - 0.1 && w.y0 <= slab.y1 + 0.4) || (w.y1 >= slab.y0 - 0.4 && w.y1 <= slab.y0 + 0.1 && w.y0 < slab.y0)).map((w) => w.aabb)\n cutSlab(context, slab, boxes)\n }\n if (structure.construction.foundation.type === 'building') anchorBalconies(context)\n return { parts: context.parts, supports: context.supports }\n}\n\n/**\n * A unit of a building stands high above the ground, and the balcony of its plan comes with a pillar of its own that starts at the ground floor: the\n * pillar would be five storeys of a single column under one corner. The balcony is a cantilever of the unit's slab (`slab_base`) and the pillar goes.\n */\nfunction anchorBalconies(context: Context): void {\n const base = context.panelsOf.get('slab_base')\n if (!base) return\n const decks = context.parts.filter((p) => p.role === 'slab' && /^slab_\\d+_/.test(p.id) && context.supports.some((s) => s.part === p.id && /^balcony_column_/.test(s.on)))\n for (const deck of decks) {\n const pillars = new Set(context.supports.filter((s) => s.part === deck.id && /^balcony_column_/.test(s.on)).map((s) => s.on))\n context.supports = context.supports.filter((s) => s.part !== deck.id && !pillars.has(s.part) && !pillars.has(s.on))\n context.parts = context.parts.filter((p) => !pillars.has(p.id))\n for (const panel of panelsUnder(context, 'slab_base', deck.aabb)) rest(context, panel, deck)\n }\n}\n\n/**\n * The panels `toDestructibleSpec` makes of the slabs of a structure (named as it names them), for a renderer that draws the floor of each room apart:\n * `panels` (each with `slab`, the id of the slab it was cut from), `replaced` (those slabs, which the spec no longer has) and the `supports` that touch the panels.\n */\nexport function slabPanelView(structure: PlanStructure, options: SlabPanelOptions): { panels: StructurePart[]; replaced: string[]; supports: Support[] } {\n const out = applySlabPanels({ parts: structure.parts, supports: structure.supports }, structure, options)\n const panels = out.parts.filter((p) => p.slab !== undefined && p.role === 'slab')\n const ids = new Set(panels.map((p) => p.id))\n return { panels, replaced: [...new Set(panels.map((p) => p.slab!))], supports: out.supports.filter((s) => ids.has(s.part) || ids.has(s.on)) }\n}\n\n/** The panels of `slabPanelView`, alone. */\nexport const slabPanelsOf = (structure: PlanStructure, options: SlabPanelOptions): StructurePart[] => slabPanelView(structure, options).panels\n","/**\n * How a concrete slab of a house is cut into panels with beams under their edges, and where pillars are added so that every beam spans a\n * reasonable distance (design T10-estrutura-real.md §12). Every number is a choice of the design and can be changed per call\n * (`toDestructibleSpec({ slabPanels: { maxSpan: 4 } })`).\n */\nexport interface SlabPanelOptions {\n /** Longest side of a panel and longest stretch of a beam or bond beam without a support, metres (default 5). */\n maxSpan: number\n /** A cut never leaves a piece narrower than this, metres (default 1.5). */\n minPanel: number\n /** Share of a line of the panel a wall must cover (doors included) for the line to be a room boundary the panel is cut along (default 0.6). */\n lineCoverage: number\n /** A gap in a line of walls up to this wide is a door and counts as wall, metres (default 1.3). */\n doorGap: number\n /** Walls whose lines are this close are one line, metres (default 0.2). */\n lineTolerance: number\n /** A panel with less than this share of its area inside the footprint of the slab is left out (default 0.5). */\n footprintShare: number\n /** Thickness of a panel is its short side over this (default 40: `h = L/40`). */\n thicknessRatio: number\n /** Thinnest floor slab, metres (default 0.10). */\n floorMinThickness: number\n /** Thinnest roof slab, metres (default 0.08). */\n roofMinThickness: number\n /** Depth of a beam is its span over this (default 10: `h = L/10`, a simply supported beam of NBR 6118, and deep enough for the frame to carry the loss of one pillar; continuous beams are L/12). */\n beamDepthRatio: number\n /** Shallowest beam, metres (default 0.25). */\n beamMinDepth: number\n /** Depth of beams and bond beams is rounded up to a multiple of this, metres (default 0.05). */\n beamStep: number\n /** Width of a beam is the thickness of the wall it hides in, or its depth over this when that is wider (default 3). */\n beamWidthRatio: number\n /** Side of the pillars that are added, metres (default 0.20; NBR 6118 13.2.3 asks for 19 cm). */\n columnSide: number\n /**\n * Most storeys of a building that gets panels (default 8). A tall building is a frame of its own (`buildTower`, the skyscraper presets), and cutting its 40 slabs and\n * sizing every pillar for the loss of each other one is quadratic: minutes for the 40-storey tower of the plan engine. It keeps its slabs whole, and the steel is not declared.\n */\n maxStoreys: number\n}\n\nexport const SLAB_PANEL_DEFAULTS: Readonly<SlabPanelOptions> = {\n maxSpan: 5, minPanel: 1.5, lineCoverage: 0.6, doorGap: 1.3, lineTolerance: 0.2, footprintShare: 0.5, thicknessRatio: 40, floorMinThickness: 0.1, roofMinThickness: 0.08,\n beamDepthRatio: 10, beamMinDepth: 0.25, beamStep: 0.05, beamWidthRatio: 3, columnSide: 0.2, maxStoreys: 8,\n}\n\nexport const resolveSlabPanels = (options?: boolean | Partial<SlabPanelOptions>): SlabPanelOptions | undefined => {\n if (options === false) return undefined\n const given = options === true || options === undefined ? {} : options\n const out = { ...SLAB_PANEL_DEFAULTS }\n for (const key of Object.keys(given) as (keyof SlabPanelOptions)[]) if (given[key] !== undefined) out[key] = given[key]!\n return out\n}\n","import { getAssembly } from '@adatechnology/game-destruction'\n\nimport type { Construction, Rect, PlanStructure, StructurePart, WallDetail } from '../types'\nimport { applySplits } from './apply'\nimport type { PartsAndSupports } from './apply'\nimport { splitIntoCourses } from './courses'\nimport type { CourseSpec } from './courses'\nimport { splitIntoPanels } from './panels'\nimport type { WallSplit } from './panels'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\n\nconst LOG_DIAMETER = 0.26\nconst isWall = (part: StructurePart): boolean => part.id.startsWith('wall_') && part.assembly !== undefined && (part.role === 'wall' || part.role === 'partition')\n\nfunction logSpec(construction: Construction, part: StructurePart): CourseSpec {\n const diameter = (construction.walls.logDiameter as number | undefined) ?? LOG_DIAMETER\n return { rowHeight: diameter, bond: 'stack', joint: CONSTRUCTION_SYSTEMS.get(construction.system)!.joints.wall, assembly: part.assembly! }\n}\n\n/** Walls cut at their windows (piers, sills, lintels, spandrels); the walls of logs as courses of logs. */\nfunction panelSplits(input: PartsAndSupports, structure: PlanStructure, lintelDepth?: (span: number) => number): Map<string, WallSplit> {\n const { construction } = structure\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)!\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts.filter(isWall)) {\n if (construction.system === 'log') {\n splits.set(part.id, splitIntoCourses(part, structure.openings, logSpec(construction, part)))\n continue\n }\n const split = splitIntoPanels(part, structure.openings, {\n lintelMaterial: system.timber ? construction.frame.timber : 'concrete', ...(system.timber ? {} : { lintelAssembly: 'reinforced_concrete' }), lintelJoint: system.joints.beam, wallJoint: system.joints.wall, ...(lintelDepth && !system.timber ? { lintelDepth } : {}), ...(construction.system === 'masonry' ? { sillBeam: true } : {}),\n })\n if (split.pieces.length > 1) splits.set(part.id, split)\n }\n return splits\n}\n\n/** Splits the walls the way `detail` says: `coarse` keeps one part per wall, `panels` cuts them at the windows, `units` goes on to bricks and blocks. */\nexport function applyPanels(input: PartsAndSupports, structure: PlanStructure, detail: WallDetail, lintelDepth?: (span: number) => number): PartsAndSupports {\n if (detail === 'coarse') return input\n return onJambPillars(applySplits(input, panelSplits(input, structure, lintelDepth)))\n}\n\nconst OPENING_BEAM = /_(lintel|sillbeam)_\\d+$/\nconst overlaps = (a: Rect, b: Rect): boolean => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]\n\n/** The lintels and sill beams of the windows bear on the concrete pillars at the jambs as well as on the masonry beside them. */\nfunction onJambPillars(split: PartsAndSupports): PartsAndSupports {\n const pillars = split.parts.filter((part) => part.role === 'column' && part.material === 'concrete')\n const extra: PartsAndSupports['supports'] = []\n for (const beam of split.parts) {\n if (beam.role !== 'beam' || !OPENING_BEAM.test(beam.id)) continue\n for (const pillar of pillars) if (pillar.floor === beam.floor && overlaps(pillar.aabb, beam.aabb) && pillar.y0 <= beam.y0 && pillar.y1 >= beam.y1 - 0.01) extra.push({ part: beam.id, on: pillar.id, joint: 'rebar' })\n }\n return extra.length ? { parts: split.parts, supports: [...split.supports, ...extra] } : split\n}\n\nexport interface Sized extends PartsAndSupports {\n capacities: Map<string, number>\n}\n\n/** Cuts each wall piece that its assembly lays in units (bricks, blocks, concrete panels) into those units; a unit takes the share of the piece's capacity its width has (it carries its column of the wall). */\nexport function applyUnits(input: Sized, structure: PlanStructure): Sized {\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts) {\n if (part.unit || !part.assembly || part.role === 'beam' || part.role === 'none') continue\n const units = getAssembly(part.assembly)?.units\n if (!units) continue\n const joint = CONSTRUCTION_SYSTEMS.get(structure.construction.system)!.joints.wall\n splits.set(part.id, splitIntoCourses(part, [], { rowHeight: units.size[1], unitLength: units.size[0], bond: units.bond, joint: units.mortar === 'concrete' ? 'mortar' : joint, assembly: part.assembly }))\n }\n const next = applySplits(input, splits)\n const capacities = new Map(input.capacities)\n for (const [id, split] of splits) {\n const capacity = input.capacities.get(id)\n capacities.delete(id)\n if (capacity === undefined) continue\n const along = (box: Rect): number => Math.max(box[2] - box[0], box[3] - box[1])\n const length = along(input.parts.find((part) => part.id === id)!.aabb)\n for (const piece of split.pieces) capacities.set(piece.id, Math.max(1, (capacity * along(piece.aabb)) / length))\n }\n return { ...next, capacities }\n}\n","import { touches } from '../geometry'\nimport type { Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface PartsAndSupports {\n parts: StructurePart[]\n supports: Support[]\n}\n\n/** Replaces each part that has a split by its pieces, and re-points what rested on it or what it rested on (the pieces touching the part resting on it get the load). */\nexport function applySplits(input: PartsAndSupports, splits: ReadonlyMap<string, WallSplit>): PartsAndSupports {\n if (!splits.size) return input\n const boxes = new Map<string, Rect>(input.parts.map((part) => [part.id, part.aabb]))\n const pieceBox = new Map<string, Rect>()\n for (const split of splits.values()) for (const piece of split.pieces) pieceBox.set(piece.id, piece.aabb)\n const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part])\n const supports: Support[] = []\n for (const support of input.supports) {\n const own = splits.get(support.part)\n const host = splits.get(support.on)\n const resting = boxes.get(support.part)\n const targets = host ? host.top.filter((id) => resting && touches(pieceBox.get(id)!, resting, 0.05)) : [support.on]\n const carriers = host ? (targets.length ? targets : host.top) : targets\n for (const part of own ? own.base : [support.part]) for (const on of carriers) supports.push({ ...support, part, on })\n }\n for (const split of splits.values()) supports.push(...split.internal)\n return { parts, supports }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface CourseSpec {\n rowHeight: number\n /** Length of a unit along the wall; without it a course is one piece per stretch (a log). */\n unitLength?: number\n bond: 'running' | 'stack'\n /** Joint of a unit on the units under it. */\n joint: JointKind\n assembly: string\n}\n\nconst MIN_UNIT = 0.02\n\ninterface Cell {\n from: number\n to: number\n row: number\n y0: number\n y1: number\n}\n\nfunction cutAt(from: number, to: number, openings: readonly Opening[], y0: number, y1: number): [number, number][] {\n let stretches: [number, number][] = [[from, to]]\n for (const opening of openings.filter((o) => o.y0 < y1 - MIN_UNIT && o.y1 > y0 + MIN_UNIT)) {\n stretches = stretches.flatMap(([a, b]): [number, number][] => {\n if (opening.to <= a || opening.from >= b) return [[a, b]]\n return [[a, Math.min(b, opening.from)], [Math.max(a, opening.to), b]].filter(([x, y]) => (y as number) - (x as number) > MIN_UNIT) as [number, number][]\n })\n }\n return stretches\n}\n\nfunction unitsOf(from: number, to: number, row: number, spec: CourseSpec): [number, number][] {\n const length = spec.unitLength\n if (!length) return [[from, to]]\n const offset = spec.bond === 'running' && row % 2 === 1 ? length / 2 : 0\n const cuts: number[] = [from]\n for (let at = from + (offset || length); at < to - MIN_UNIT; at += length) cuts.push(at)\n cuts.push(to)\n return cuts.slice(0, -1).map((start, k): [number, number] => [start, cuts[k + 1]!]).filter(([a, b]) => b - a > MIN_UNIT)\n}\n\n/**\n * Cuts a wall into courses of units (bricks laid in bond, or logs): each course is cut at the openings it meets, and each unit rests on the units of the course\n * below that it overlaps. A wall whose lowest course goes loses every course above it. The mass of the wall is shared among the units by volume.\n */\nexport function splitIntoCourses(wall: StructurePart, openings: readonly Opening[], spec: CourseSpec): WallSplit {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n const from = alongU ? wall.aabb[0] : wall.aabb[1]\n const to = alongU ? wall.aabb[2] : wall.aabb[3]\n const cross: [number, number] = alongU ? [wall.aabb[1], wall.aabb[3]] : [wall.aabb[0], wall.aabb[2]]\n const rows = Math.max(1, Math.round((wall.y1 - wall.y0) / spec.rowHeight))\n const rowHeight = (wall.y1 - wall.y0) / rows\n const cells: Cell[] = []\n for (let row = 0; row < rows; row++) {\n const y0 = wall.y0 + row * rowHeight\n const y1 = wall.y0 + (row + 1) * rowHeight\n for (const [a, b] of cutAt(from, to, openings.filter((o) => o.wall === wall.id), y0, y1)) for (const [x0, x1] of unitsOf(a, b, row, spec)) cells.push({ from: x0, to: x1, row, y0, y1 })\n }\n const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0)\n const box = (cell: Cell): Rect => (alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to])\n const pieces = cells.map((cell, index): StructurePart => ({\n id: `${wall.id}_${spec.unitLength ? 'u' : 'log'}${cell.row}_${index}`, role: wall.role, material: wall.material, aabb: box(cell), y0: cell.y0, y1: cell.y1, floor: wall.floor,\n mass: round2(Math.max(0.1, (wall.mass * (cell.to - cell.from) * (cell.y1 - cell.y0)) / total)), host: wall.id, assembly: spec.assembly, unit: true,\n }))\n const internal: Support[] = []\n cells.forEach((cell, index) => {\n if (cell.row === 0) return\n const below = cells.map((other, k) => ({ other, k })).filter(({ other }) => other.row === cell.row - 1 && Math.min(other.to, cell.to) - Math.max(other.from, cell.from) > MIN_UNIT)\n for (const { k } of below) internal.push({ part: pieces[index]!.id, on: pieces[k]!.id, joint: spec.joint })\n })\n return { pieces, internal, base: pieces.filter((_, i) => cells[i]!.row === 0).map((p) => p.id), top: pieces.filter((_, i) => cells[i]!.row === rows - 1).map((p) => p.id) }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\n\nexport interface PanelStyle {\n lintelMaterial: string\n lintelAssembly?: string\n /** Joint of a lintel on its piers and of the wall above it on the lintel. */\n lintelJoint: JointKind\n wallJoint: JointKind\n /** Depth of the lintel over an opening of the given width, metres (default `LINTEL_DEPTH`): a wide opening needs a deeper beam. */\n lintelDepth?: (span: number) => number\n /** A concrete sill beam (contraverga) under each window, `SILL_BEAM_DEPTH` deep and bearing `LINTEL_BEARING` on the piers: masonry walls have one. */\n sillBeam?: boolean\n}\n\nexport interface WallSplit {\n pieces: StructurePart[]\n /** What the pieces rest on among themselves (lintel on piers, spandrel on lintel). */\n internal: Support[]\n /** Pieces that rest on what the wall rests on. */\n base: string[]\n /** Pieces that carry what rests on the wall. */\n top: string[]\n}\n\nexport const LINTEL_DEPTH = 0.2\nexport const LINTEL_BEARING = 0.2\n/** Depth of the sill beam under a window of a masonry wall, metres (a contraverga is usually 10 cm). */\nexport const SILL_BEAM_DEPTH = 0.1\n/** A lintel is at least a tenth of its span deep (span: the opening plus one bearing, h = L/10). */\nconst LINTEL_SPAN_RATIO = 10\nconst MIN_PIECE = 0.05\n\ninterface Frame {\n alongU: boolean\n from: number\n to: number\n cross: [number, number]\n}\n\nconst frameOf = (wall: StructurePart): Frame => {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n return alongU ? { alongU, from: wall.aabb[0], to: wall.aabb[2], cross: [wall.aabb[1], wall.aabb[3]] } : { alongU, from: wall.aabb[1], to: wall.aabb[3], cross: [wall.aabb[0], wall.aabb[2]] }\n}\n\nconst boxOf = (frame: Frame, from: number, to: number): Rect => (frame.alongU ? [from, frame.cross[0], to, frame.cross[1]] : [frame.cross[0], from, frame.cross[1], to])\n\ninterface Draft {\n id: string\n role: StructurePart['role']\n material: string\n assembly?: string\n from: number\n to: number\n y0: number\n y1: number\n /** Volume that counts for the mass share (pieces tile the wall: a lintel keeps the bearing it shares with the piers). */\n volume: number\n}\n\n/**\n * Cuts a wall at its windows: piers between them at full height, a sill wall under each window, a lintel over it that bears 0.2 m on the piers and the wall\n * above the lintel up to the top. The mass of the wall is shared among the pieces by volume, so the total is the wall's.\n */\nexport function splitIntoPanels(wall: StructurePart, openings: readonly Opening[], style: PanelStyle): WallSplit {\n const frame = frameOf(wall)\n const own = openings.filter((o) => o.wall === wall.id && o.to > frame.from + MIN_PIECE && o.from < frame.to - MIN_PIECE).sort((a, b) => a.from - b.from)\n if (!own.length) return { pieces: [wall], internal: [], base: [wall.id], top: [wall.id] }\n const drafts: Draft[] = []\n const piers: Draft[] = []\n const lintels: Draft[] = []\n const sillBeams: Draft[] = []\n const spandrels: (Draft | undefined)[] = []\n const height = wall.y1 - wall.y0\n let cursor = frame.from\n const roleOf = wall.role\n const addPier = (to: number): void => {\n if (to - cursor < MIN_PIECE) return\n piers.push({ id: `${wall.id}_pier_${piers.length}`, role: roleOf, material: wall.material, from: cursor, to, y0: wall.y0, y1: wall.y1, volume: (to - cursor) * height })\n }\n own.forEach((opening, k) => {\n addPier(Math.max(cursor, opening.from))\n const span = opening.to - opening.from\n const lintelTop = Math.min(wall.y1, opening.y1 + Math.max(LINTEL_DEPTH, style.lintelDepth?.(span) ?? 0, (span + LINTEL_BEARING) / LINTEL_SPAN_RATIO))\n const lintelFrom = Math.max(frame.from, opening.from - LINTEL_BEARING)\n const lintelTo = Math.min(frame.to, opening.to + LINTEL_BEARING)\n const lintelHeight = lintelTop - opening.y1\n const sillTop = style.sillBeam && opening.y0 - wall.y0 > SILL_BEAM_DEPTH + MIN_PIECE ? opening.y0 - SILL_BEAM_DEPTH : opening.y0\n if (sillTop - wall.y0 > MIN_PIECE) drafts.push({ id: `${wall.id}_sill_${k}`, role: 'partition', material: wall.material, from: opening.from, to: opening.to, y0: wall.y0, y1: sillTop, volume: (opening.to - opening.from) * (sillTop - wall.y0) })\n if (sillTop < opening.y0) sillBeams.push({ id: `${wall.id}_sillbeam_${k}`, role: 'beam', material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: sillTop, y1: opening.y0, volume: (lintelTo - lintelFrom) * SILL_BEAM_DEPTH })\n lintels.push({ id: `${wall.id}_lintel_${k}`, role: 'beam', material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: opening.y1, y1: lintelTop, volume: (lintelTo - lintelFrom) * lintelHeight })\n spandrels.push(wall.y1 - lintelTop > MIN_PIECE ? { id: `${wall.id}_spandrel_${k}`, role: roleOf, material: wall.material, from: opening.from, to: opening.to, y0: lintelTop, y1: wall.y1, volume: (opening.to - opening.from) * (wall.y1 - lintelTop) } : undefined)\n cursor = opening.to\n })\n addPier(frame.to)\n // the piers give the bearing zone of each lintel and sill beam to it\n for (const pier of piers) {\n for (const lintel of [...lintels, ...sillBeams]) {\n const overlap = Math.max(0, Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from))\n pier.volume -= overlap * (lintel.y1 - lintel.y0)\n }\n }\n const all = [...piers, ...drafts, ...sillBeams, ...lintels, ...spandrels.filter((d): d is Draft => d !== undefined)]\n const total = all.reduce((sum, d) => sum + d.volume, 0)\n const pieces = all.map((d): StructurePart => ({\n id: d.id, role: d.role, material: d.material, aabb: boxOf(frame, d.from, d.to), y0: d.y0, y1: d.y1, floor: wall.floor, mass: round2(Math.max(0.1, (wall.mass * d.volume) / total)), host: wall.id,\n ...(d.role === 'beam' ? (style.lintelAssembly ? { assembly: style.lintelAssembly } : {}) : wall.assembly ? { assembly: wall.assembly } : {}),\n }))\n const internal: Support[] = []\n // a sill beam rests on the masonry under the window and bears on the piers at each side\n for (const beam of sillBeams) {\n const sill = drafts.find((d) => d.id === beam.id.replace('_sillbeam_', '_sill_'))\n if (sill) internal.push({ part: beam.id, on: sill.id, joint: style.lintelJoint })\n for (const pier of piers) if (Math.min(pier.to, beam.to) - Math.max(pier.from, beam.from) > 0) internal.push({ part: beam.id, on: pier.id, joint: style.lintelJoint })\n }\n lintels.forEach((lintel, k) => {\n for (const pier of piers) if (Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from) > 0) internal.push({ part: lintel.id, on: pier.id, joint: style.lintelJoint })\n const spandrel = spandrels[k]\n if (spandrel) internal.push({ part: spandrel.id, on: lintel.id, joint: style.wallJoint })\n })\n const base = [...piers, ...drafts.filter((d) => d.id.includes('_sill_'))].map((d) => d.id)\n const top = [...piers.map((p) => p.id), ...lintels.map((l, k) => spandrels[k]?.id ?? l.id)]\n return { pieces, internal, base, top }\n}\n","/** Stable codes of what `validateStructure` and `validateSpec` find wrong in a construction. */\nexport const STRUCTURAL_VIOLATION = {\n /** A pillar with no load path to the ground, or that starts above what it rests on. */\n PILLAR_NOT_GROUNDED: 'PILLAR_NOT_GROUNDED',\n /** A pillar of a masonry wall that stops short of the bond beam, or that the bond beam does not rest on. */\n PILLAR_DOES_NOT_REACH_BOND_BEAM: 'PILLAR_DOES_NOT_REACH_BOND_BEAM',\n /** A masonry wall that runs more than `MAX_PILLAR_SPACING` between two of its pillars. */\n WALL_SPAN_WITHOUT_PILLAR: 'WALL_SPAN_WITHOUT_PILLAR',\n /** A free end of a masonry wall (a door jamb, the end of a garden wall) with no pillar. */\n WALL_END_WITHOUT_PILLAR: 'WALL_END_WITHOUT_PILLAR',\n /** Two masonry walls meet at a corner with no pillar there. */\n CORNER_WITHOUT_PILLAR: 'CORNER_WITHOUT_PILLAR',\n /** Another wall meets a masonry wall inside its length (a T) with no pillar there. */\n WALL_JUNCTION_WITHOUT_PILLAR: 'WALL_JUNCTION_WITHOUT_PILLAR',\n /** A window or door in a masonry wall with no lintel (verga) over it. */\n OPENING_WITHOUT_LINTEL: 'OPENING_WITHOUT_LINTEL',\n /** A window in a masonry wall with no sill beam (contraverga) under it. */\n OPENING_WITHOUT_SILL: 'OPENING_WITHOUT_SILL',\n /** An exterior masonry wall with no bond beam (cinta de amarração) on top. */\n MISSING_BOND_BEAM: 'MISSING_BOND_BEAM',\n /** A ground-floor masonry wall standing on the soil with no ground beam (viga baldrame) or foundation under it. */\n MISSING_GROUND_BEAM: 'MISSING_GROUND_BEAM',\n /** A part with no load path down to the ground. */\n FLOATING_PART: 'FLOATING_PART',\n /** A concrete beam longer than a lintel that rests on masonry alone (no pillar, beam or slab carries it). */\n BEAM_ON_WEAK_MASONRY: 'BEAM_ON_WEAK_MASONRY',\n /** A concrete pillar or beam below the NBR 6118 minimum section, or a beam between point supports shallower than a tenth of its span. */\n CONCRETE_BELOW_MIN_SECTION: 'CONCRETE_BELOW_MIN_SECTION',\n /** A concrete pillar or beam with no steel (the construction has no rebar). */\n UNREINFORCED_CONCRETE: 'UNREINFORCED_CONCRETE',\n /** A brick or block wall laid in stack bond: the vertical joints line up and the wall splits along them. */\n UNBONDED_MASONRY: 'UNBONDED_MASONRY',\n /** A plastered brick wall without plaster on both faces. */\n MISSING_PLASTER: 'MISSING_PLASTER',\n} as const\n\nexport type StructuralViolationCode = (typeof STRUCTURAL_VIOLATION)[keyof typeof STRUCTURAL_VIOLATION]\n\n/** One thing a construction gets wrong: the code, the part (or opening) it is about and the rule it breaks, in words. */\nexport interface StructuralViolation {\n readonly code: StructuralViolationCode\n readonly part: string\n readonly message: string\n}\n\n/** Most metres a masonry wall runs between two pillars (confined masonry: 3 to 4 m; `WALL_PILLAR_SPACING` is 4). */\nexport const MAX_PILLAR_SPACING = 4\n/** NBR 6118 13.2.3: no side of a pillar under 19 cm, and at least 360 cm² of section. */\nexport const MIN_PILLAR_SIDE = 0.19\nexport const MIN_PILLAR_AREA = 0.036\n/** NBR 6118 13.2.2: a beam at least 12 cm wide. */\nexport const MIN_BEAM_WIDTH = 0.12\n/** A beam between point supports is at least a tenth of its span deep (pre-sizing of reinforced concrete beams, h = L/10). */\nexport const BEAM_DEPTH_RATIO = 10\n/** A concrete beam that only masonry carries may be a lintel up to this span; a longer one needs pillars. */\nexport const MAX_LINTEL_ON_MASONRY = 3\n","import { GROUND } from '../types'\nimport type { Structure, StructurePart, Support } from '../types'\nimport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\n/** A part this close above the top of what it rests on still rests on it (metres). */\nconst CONTACT = 0.05\nconst EPSILON = 0.005\n\n/** The parts with a load path down to the ground over the supports that bear. */\nexport function groundedParts(parts: readonly StructurePart[], supports: readonly Support[]): Set<string> {\n const ids = new Set(parts.map((part) => part.id))\n const grounded = new Set<string>([GROUND])\n const bearing = supports.filter((s) => s.bears !== false && ids.has(s.part))\n let grew = true\n while (grew) {\n grew = false\n for (const support of bearing) {\n if (grounded.has(support.part) || !grounded.has(support.on)) continue\n grounded.add(support.part)\n grew = true\n }\n }\n return grounded\n}\n\n/** Every part with a load path to the ground, and every pillar standing on what it rests on. */\nexport function loadPathViolations(structure: Pick<Structure, 'parts' | 'supports'>): StructuralViolation[] {\n const { parts, supports } = structure\n const grounded = groundedParts(parts, supports)\n const byId = new Map(parts.map((part) => [part.id, part]))\n const out: StructuralViolation[] = []\n for (const part of parts) {\n if (part.role === 'none') continue\n const pillar = part.role === 'column'\n if (!grounded.has(part.id)) {\n out.push({ code: pillar ? STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED : STRUCTURAL_VIOLATION.FLOATING_PART, part: part.id, message: `${part.id} has no load path to the ground` })\n continue\n }\n if (!pillar) continue\n const bases = supports.filter((s) => s.part === part.id && s.bears !== false)\n const standsOnBase = bases.some((s) => {\n if (s.on === GROUND) return part.y0 <= CONTACT\n const base = byId.get(s.on)\n return base !== undefined && part.y0 >= base.y0 - EPSILON && part.y0 <= base.y1 + CONTACT\n })\n if (!standsOnBase) out.push({ code: STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED, part: part.id, message: `${part.id} starts at ${part.y0} m, above what it rests on` })\n }\n return out\n}\n\nconst alongOf = (part: StructurePart): { alongU: boolean; from: number; to: number; width: number } => {\n const alongU = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1]\n return alongU\n ? { alongU, from: part.aabb[0], to: part.aabb[2], width: part.aabb[3] - part.aabb[1] }\n : { alongU, from: part.aabb[1], to: part.aabb[3], width: part.aabb[2] - part.aabb[0] }\n}\n\n/** The along ranges of a beam where each of its bearing supports holds it. */\nfunction bearingsOf(beam: StructurePart, supports: readonly Support[], byId: ReadonlyMap<string, StructurePart>): Bearing[] {\n const frame = alongOf(beam)\n return supports\n .filter((s) => s.part === beam.id && s.bears !== false && s.on !== GROUND)\n .map((s) => byId.get(s.on))\n .filter((on): on is StructurePart => on !== undefined)\n .map((on) => {\n const [low, high] = frame.alongU ? [on.aabb[0], on.aabb[2]] : [on.aabb[1], on.aabb[3]]\n return { on, from: Math.max(frame.from, low), to: Math.min(frame.to, high) }\n })\n .filter((bearing) => bearing.to - bearing.from > -EPSILON)\n}\n\nconst isWallLike = (part: StructurePart): boolean => part.role === 'wall' || part.role === 'partition'\n/** A plain concrete pedestal (a footing block under a post) may go without steel: no taller than three times its least side (ACI 318 14.3.3). */\nconst PEDESTAL_RATIO = 3\nconst isPedestal = (part: StructurePart): boolean => part.role === 'column' && part.y1 - part.y0 <= PEDESTAL_RATIO * Math.min(part.aabb[2] - part.aabb[0], part.aabb[3] - part.aabb[1])\n\n/**\n * Concrete pillars and beams against NBR 6118: the minimum sections (13.2.2, 13.2.3), the steel of a reinforced member, a beam between point supports at\n * least a tenth of its span deep, and no long beam that only masonry carries.\n */\nexport function concreteViolations(structure: Pick<Structure, 'parts' | 'supports' | 'construction'>, isMasonry: (part: StructurePart) => boolean): StructuralViolation[] {\n const { parts, supports } = structure\n const byId = new Map(parts.map((part) => [part.id, part]))\n const out: StructuralViolation[] = []\n for (const part of parts) {\n if (part.material !== 'concrete' || (part.role !== 'column' && part.role !== 'beam')) continue\n if (!structure.construction.frame.rebar && !isPedestal(part)) out.push({ code: STRUCTURAL_VIOLATION.UNREINFORCED_CONCRETE, part: part.id, message: `${part.id} is concrete without steel` })\n if (part.role === 'column') {\n const sides = [part.aabb[2] - part.aabb[0], part.aabb[3] - part.aabb[1]]\n if (Math.min(...sides) < MIN_PILLAR_SIDE - EPSILON || sides[0]! * sides[1]! < MIN_PILLAR_AREA - EPSILON)\n out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${sides.map((s) => s.toFixed(2)).join(' x ')} m: NBR 6118 asks at least ${MIN_PILLAR_SIDE} m a side and ${MIN_PILLAR_AREA} m²` })\n continue\n }\n const castOn = supports\n .filter((s) => s.on === part.id && s.bears !== false)\n .map((s) => byId.get(s.part))\n .filter((top): top is StructurePart => top !== undefined && top.role === 'beam' && top.material === 'concrete' && Math.abs(top.y0 - part.y1) < 0.01)\n .reduce((most, top) => Math.max(most, top.y1 - top.y0), 0)\n out.push(...beamViolations(part, bearingsOf(part, supports, byId), { isMasonry, castOn }))\n }\n return out\n}\n\n/** Longest effective span between the bearings of a beam: the clear span plus, at each end, half the bearing up to 0.3 of the depth (NBR 6118 14.6.2.4). */\nfunction effectiveSpan(bearings: readonly { from: number; to: number }[], depth: number): number {\n const sorted = [...bearings].sort((a, b) => a.from - b.from)\n let most = 0\n for (let k = 1; k < sorted.length; k++) {\n const previous = sorted.slice(0, k).reduce((a, b) => (b.to > a.to ? b : a))\n const next = sorted[k]!\n const clear = next.from - previous.to\n if (clear <= 0) continue\n most = Math.max(most, clear + Math.min((previous.to - previous.from) / 2, 0.3 * depth) + Math.min((next.to - next.from) / 2, 0.3 * depth))\n }\n return most\n}\n\ninterface Bearing {\n on: StructurePart\n from: number\n to: number\n}\n\nfunction beamViolations(beam: StructurePart, bearings: readonly Bearing[], context: { isMasonry: (part: StructurePart) => boolean; castOn: number }): StructuralViolation[] {\n const out: StructuralViolation[] = []\n const frame = alongOf(beam)\n const length = frame.to - frame.from\n // a beam cast together with the one on it (a lintel under the bond beam) works as one section\n const depth = beam.y1 - beam.y0 + context.castOn\n if (frame.width < MIN_BEAM_WIDTH - EPSILON) out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: beam.id, message: `${beam.id} is ${frame.width.toFixed(2)} m wide: NBR 6118 asks at least ${MIN_BEAM_WIDTH} m` })\n if (!bearings.length) return out\n const continuous = bearings.some((b) => isWallLike(b.on) && b.to - b.from >= length / 2)\n const span = continuous ? 0 : effectiveSpan(bearings, depth)\n if (depth < span / BEAM_DEPTH_RATIO - EPSILON) out.push({ code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: beam.id, message: `${beam.id} is ${depth.toFixed(2)} m deep over a ${span.toFixed(2)} m span: it needs at least L/${BEAM_DEPTH_RATIO} = ${(span / BEAM_DEPTH_RATIO).toFixed(2)} m` })\n if (length > MAX_LINTEL_ON_MASONRY && bearings.every((b) => context.isMasonry(b.on)))\n out.push({ code: STRUCTURAL_VIOLATION.BEAM_ON_WEAK_MASONRY, part: beam.id, message: `${beam.id} spans ${length.toFixed(2)} m on masonry alone: no pillar carries it` })\n return out\n}\n","import { getAssembly } from '@adatechnology/game-destruction'\n\nimport { GROUND } from '../types'\nimport type { Structure, StructurePart } from '../types'\nimport { MAX_PILLAR_SPACING, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\nconst TOLERANCE = 0.05\n/** A pillar this close (along the wall) to a corner, an end or a junction stands there (`WALL_PILLAR_SIDE` plus the merge distance of `addWallPillars`). */\nconst AT_POINT = 0.45\nconst EXPOSED_FINISHES: readonly string[] = ['exposed_brick', 'exposed_block']\n\n/** A wall of the plan as a line: its axis, the line across, where its centre line starts and ends, its half thickness. */\nexport interface WallLine {\n part: StructurePart\n alongU: boolean\n line: number\n from: number\n to: number\n half: number\n}\n\nexport const lineOf = (part: StructurePart): WallLine => {\n const alongU = part.aabb[2] - part.aabb[0] >= part.aabb[3] - part.aabb[1]\n const half = (alongU ? part.aabb[3] - part.aabb[1] : part.aabb[2] - part.aabb[0]) / 2\n const [from, to] = alongU ? [part.aabb[0], part.aabb[2]] : [part.aabb[1], part.aabb[3]]\n return { part, alongU, line: alongU ? part.aabb[1] + half : part.aabb[0] + half, from: from + half, to: to - half, half }\n}\n\n/** A wall laid in bricks or blocks with mortar (not a concrete wall, not timber). */\nexport function isMasonryWall(part: StructurePart): boolean {\n if (!part.id.startsWith('wall_') || !part.assembly || (part.role !== 'wall' && part.role !== 'partition')) return false\n const units = getAssembly(part.assembly)?.units\n return units !== undefined && units.mortar !== 'concrete'\n}\n\nconst pointOf = (wall: WallLine, along: number): [number, number] => (wall.alongU ? [along, wall.line] : [wall.line, along])\nconst alongOfPoint = (wall: WallLine, point: readonly [number, number]): number => (wall.alongU ? point[0] : point[1])\nconst acrossOfPoint = (wall: WallLine, point: readonly [number, number]): number => (wall.alongU ? point[1] : point[0])\nconst centre = (part: StructurePart): [number, number] => [(part.aabb[0] + part.aabb[2]) / 2, (part.aabb[1] + part.aabb[3]) / 2]\nconst onLine = (wall: WallLine, point: readonly [number, number], slack = 0): boolean =>\n Math.abs(acrossOfPoint(wall, point) - wall.line) <= wall.half + TOLERANCE && alongOfPoint(wall, point) >= wall.from - wall.half - slack && alongOfPoint(wall, point) <= wall.to + wall.half + slack\n\n/** What the end of a wall meets: another wall end at a corner, the side of another wall (a T), the next wall on the same line, or nothing (a free end, a door jamb). */\nfunction endKind(wall: WallLine, along: number, others: readonly WallLine[]): 'corner' | 'junction' | 'continued' | 'free' {\n const point = pointOf(wall, along)\n const meeting = others.filter((other) => onLine(other, point))\n const across = meeting.filter((other) => other.alongU !== wall.alongU)\n const continued = meeting.length > across.length\n if (!across.length) return continued ? 'continued' : 'free'\n // the side of a wall that the line goes on through, or that meets it in its length, is a junction; two ends alone are a corner\n const atEnd = (other: WallLine): boolean => Math.min(Math.abs(alongOfPoint(other, point) - other.from), Math.abs(alongOfPoint(other, point) - other.to)) <= other.half + wall.half + TOLERANCE\n return !continued && across.every(atEnd) ? 'corner' : 'junction'\n}\n\ninterface WallContext {\n wall: WallLine\n pillars: StructurePart[]\n stations: number[]\n /** Along ranges of the windows in the wall (no masonry to confine there). */\n windows: [number, number][]\n}\n\n/** Metres of masonry between two points along a wall: the distance less the windows between them. */\nconst masonryBetween = (from: number, to: number, windows: readonly [number, number][]): number =>\n windows.reduce((left, [a, b]) => left - Math.max(0, Math.min(to, b) - Math.max(from, a)), to - from)\n\nfunction pointViolations(context: WallContext, others: readonly WallLine[]): StructuralViolation[] {\n const { wall, stations } = context\n const out: StructuralViolation[] = []\n const covered = (along: number): boolean => stations.some((at) => Math.abs(at - along) <= AT_POINT)\n for (const along of [wall.from, wall.to]) {\n const kind = endKind(wall, along, others)\n if (kind === 'continued' || covered(along)) continue\n const code = kind === 'corner' ? STRUCTURAL_VIOLATION.CORNER_WITHOUT_PILLAR : kind === 'junction' ? STRUCTURAL_VIOLATION.WALL_JUNCTION_WITHOUT_PILLAR : STRUCTURAL_VIOLATION.WALL_END_WITHOUT_PILLAR\n out.push({ code, part: wall.part.id, message: `${wall.part.id} has no pillar at its ${kind} end (${along.toFixed(2)} m along)` })\n }\n for (const other of others) {\n if (other.alongU === wall.alongU) continue\n for (const end of [other.from, other.to]) {\n const point = pointOf(other, end)\n const at = alongOfPoint(wall, point)\n if (!onLine(wall, point) || at <= wall.from + AT_POINT || at >= wall.to - AT_POINT || covered(at)) continue\n out.push({ code: STRUCTURAL_VIOLATION.WALL_JUNCTION_WITHOUT_PILLAR, part: wall.part.id, message: `${other.part.id} meets ${wall.part.id} at ${at.toFixed(2)} m along with no pillar there` })\n }\n }\n const line = [...stations].sort((a, b) => a - b)\n for (let k = 1; k < line.length; k++) {\n const gap = masonryBetween(line[k - 1]!, line[k]!, context.windows)\n if (gap > MAX_PILLAR_SPACING + TOLERANCE) out.push({ code: STRUCTURAL_VIOLATION.WALL_SPAN_WITHOUT_PILLAR, part: wall.part.id, message: `${wall.part.id} runs ${gap.toFixed(2)} m between pillars (at most ${MAX_PILLAR_SPACING} m)` })\n }\n if (!line.length && wall.to - wall.from > MAX_PILLAR_SPACING) out.push({ code: STRUCTURAL_VIOLATION.WALL_SPAN_WITHOUT_PILLAR, part: wall.part.id, message: `${wall.part.id} runs ${(wall.to - wall.from).toFixed(2)} m with no pillar` })\n return out\n}\n\nfunction bondBeamViolations(context: WallContext, structure: Pick<Structure, 'parts' | 'supports'>): StructuralViolation[] {\n const { wall, pillars } = context\n const resting = new Set(structure.supports.filter((s) => s.on === wall.part.id).map((s) => s.part))\n const beams = structure.parts.filter((p) => p.beamKind === 'bond_beam' && resting.has(p.id))\n if (!beams.length) return [{ code: STRUCTURAL_VIOLATION.MISSING_BOND_BEAM, part: wall.part.id, message: `${wall.part.id} has no bond beam on top` }]\n const out: StructuralViolation[] = []\n for (const pillar of pillars) {\n const [u, v] = centre(pillar)\n const over = beams.filter((b) => u >= b.aabb[0] - TOLERANCE && u <= b.aabb[2] + TOLERANCE && v >= b.aabb[1] - TOLERANCE && v <= b.aabb[3] + TOLERANCE)\n const carries = over.some((b) => pillar.y1 >= b.y0 - TOLERANCE && structure.supports.some((s) => s.part === b.id && s.on === pillar.id && s.bears !== false))\n if (!carries) out.push({ code: STRUCTURAL_VIOLATION.PILLAR_DOES_NOT_REACH_BOND_BEAM, part: pillar.id, message: `${pillar.id} stops at ${pillar.y1} m and does not carry the bond beam of ${wall.part.id}` })\n }\n return out\n}\n\n/** The units and coats of a masonry wall: a running bond, and plaster on both faces of a plastered brick wall. */\nfunction assemblyViolations(part: StructurePart, finish: string | undefined): StructuralViolation[] {\n const def = getAssembly(part.assembly ?? '')\n if (!def) return []\n const out: StructuralViolation[] = []\n if (def.units && def.units.bond !== 'running') out.push({ code: STRUCTURAL_VIOLATION.UNBONDED_MASONRY, part: part.id, message: `${part.id} is laid in ${def.units.bond} bond: the joints must be staggered` })\n const plastered = (def.layers ?? []).some((layer) => layer.material === 'plaster' && layer.faces === 'both')\n if (def.core.material === 'brick' && !plastered && !EXPOSED_FINISHES.includes(finish ?? '')) out.push({ code: STRUCTURAL_VIOLATION.MISSING_PLASTER, part: part.id, message: `${part.id} is brick without plaster on both faces` })\n return out\n}\n\n/**\n * Confined masonry: every exterior masonry wall stands on a ground beam (or a foundation), has a concrete pillar at each end, corner and junction and at most\n * every `MAX_PILLAR_SPACING` metres, from the floor up to the bond beam on top, which rests on them; its bricks are bonded and plastered on both faces.\n */\nexport function masonryViolations(structure: Pick<Structure, 'parts' | 'supports' | 'construction' | 'openings'>): StructuralViolation[] {\n const walls = structure.parts.filter(isMasonryWall)\n const columns = structure.parts.filter((p) => p.role === 'column' && p.material === 'concrete')\n const out: StructuralViolation[] = []\n for (const part of walls) {\n out.push(...assemblyViolations(part, structure.construction.walls.finish))\n if (part.floor === 0 && structure.supports.some((s) => s.part === part.id && s.on === GROUND))\n out.push({ code: STRUCTURAL_VIOLATION.MISSING_GROUND_BEAM, part: part.id, message: `${part.id} stands on the soil with no ground beam under it` })\n if (!part.exterior) continue\n const wall = lineOf(part)\n // a pillar of the next wall on the line, standing just past this one's end, confines this end too\n const pillars = columns.filter((c) => c.floor === part.floor && onLine(wall, centre(c), AT_POINT) && Math.min(c.y1, part.y1) - Math.max(c.y0, part.y0) > 0.5)\n const windows = structure.openings.filter((o) => o.wall === part.id).map((o): [number, number] => [o.from, o.to])\n const context: WallContext = { wall, pillars, stations: pillars.map((p) => alongOfPoint(wall, centre(p))), windows }\n const others = walls.filter((w) => w !== part && w.floor === part.floor).map(lineOf)\n out.push(...pointViolations(context, others), ...bondBeamViolations(context, structure))\n }\n return out\n}\n","import type { Opening, SourceDoor, Structure, StructurePart } from '../types'\nimport { DOOR_HEIGHT } from '../structure/openings'\nimport { LINTEL_DEPTH, SILL_BEAM_DEPTH } from '../wall-detail/panels'\nimport { STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\nimport { isMasonryWall, lineOf } from './masonry'\nimport type { WallLine } from './masonry'\n\nconst TOLERANCE = 0.05\n/** A window this close to the floor has too little masonry under it for a sill beam (a French window). */\nconst LOW_WINDOW = SILL_BEAM_DEPTH + 0.05\n\n/**\n * A beam in the wall's line that covers `[from, to]` along it, with its underside (`side: 'y0'`) within a lintel's depth over `y` (the bond beam is the\n * lintel of a window right under it) or its top (`'y1'`) at `y`.\n */\nfunction beamAcross(parts: readonly StructurePart[], wall: WallLine, span: { from: number; to: number }, side: 'y0' | 'y1', y: number): boolean {\n return parts.some((part) => {\n const off = part[side] - y\n if (part.role !== 'beam' || off < -TOLERANCE || off > (side === 'y0' ? LINTEL_DEPTH : TOLERANCE)) return false\n const [from, to, low, high] = wall.alongU ? [part.aabb[0], part.aabb[2], part.aabb[1], part.aabb[3]] : [part.aabb[1], part.aabb[3], part.aabb[0], part.aabb[2]]\n return from <= span.from + TOLERANCE && to >= span.to - TOLERANCE && low <= wall.line + TOLERANCE && high >= wall.line - TOLERANCE\n })\n}\n\nfunction windowViolations(opening: Opening, wall: StructurePart, built: readonly StructurePart[]): StructuralViolation[] {\n const line = lineOf(wall)\n const out: StructuralViolation[] = []\n if (!beamAcross(built, line, opening, 'y0', opening.y1)) out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_LINTEL, part: opening.id, message: `window ${opening.id} in ${wall.id} has no lintel over it` })\n if (opening.y0 - wall.y0 > LOW_WINDOW && !beamAcross(built, line, opening, 'y1', opening.y0))\n out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_SILL, part: opening.id, message: `window ${opening.id} in ${wall.id} has no sill beam under it` })\n return out\n}\n\n/** The masonry walls beside a door gap (the door is the gap between two walls on one line). */\nfunction wallsBeside(door: SourceDoor, walls: readonly StructurePart[]): WallLine[] {\n const along = door.axis === 'u' ? door.u : door.v\n const across = door.axis === 'u' ? door.v : door.u\n const from = along - door.width / 2\n const to = along + door.width / 2\n return walls\n .filter((w) => w.floor === door.floor)\n .map(lineOf)\n .filter((w) => w.alongU === (door.axis === 'u') && Math.abs(w.line - across) <= TOLERANCE && (Math.abs(w.to - from) <= TOLERANCE || Math.abs(w.from - to) <= TOLERANCE))\n}\n\n/** Lintels and sill beams: a lintel over every window and door of a masonry wall, a sill beam under every window that has masonry under it. */\nexport function openingViolations(structure: Pick<Structure, 'parts' | 'openings' | 'levels'>, built: readonly StructurePart[], doors: readonly SourceDoor[]): StructuralViolation[] {\n const walls = structure.parts.filter(isMasonryWall)\n const hosts = new Map(walls.map((wall) => [wall.id, wall]))\n const out: StructuralViolation[] = []\n for (const opening of structure.openings) {\n const wall = hosts.get(opening.wall)\n if (wall) out.push(...windowViolations(opening, wall, built))\n }\n for (const door of doors) {\n const beside = wallsBeside(door, walls)\n if (!beside.length) continue\n const along = door.axis === 'u' ? door.u : door.v\n const span = { from: along - door.width / 2, to: along + door.width / 2 }\n const lintel = beamAcross(built, beside[0]!, span, 'y0', (structure.levels[door.floor] ?? 0) + DOOR_HEIGHT)\n if (!lintel) out.push({ code: STRUCTURAL_VIOLATION.OPENING_WITHOUT_LINTEL, part: door.id, message: `door ${door.id} has no lintel over it` })\n }\n return out\n}\n","import type { DestructibleSpec, JointSpec, PartSpec } from '@adatechnology/game-contracts'\n\nimport { MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\n\nconst EPSILON = 0.005\n\nconst carries = (part: PartSpec | undefined): boolean => part?.structure !== undefined && part.structure.role !== 'none'\n\n/** The directions load flows over a joint: `[from, to]` pairs (a part rests on the second). */\nfunction flows(joint: JointSpec, byId: ReadonlyMap<string, PartSpec>): [string, string][] {\n const bears = joint.bears ?? (carries(byId.get(joint.a)) && carries(byId.get(joint.b)))\n if (bears === false) return []\n if (bears === 'a_on_b') return [[joint.a, joint.b]]\n if (bears === 'b_on_a') return [[joint.b, joint.a]]\n return [[joint.a, joint.b], [joint.b, joint.a]]\n}\n\nfunction groundedOf(spec: DestructibleSpec, byId: ReadonlyMap<string, PartSpec>): Set<string> {\n const grounded = new Set(spec.parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id))\n const edges = (spec.joints ?? []).flatMap((joint) => flows(joint, byId))\n let grew = true\n while (grew) {\n grew = false\n for (const [part, on] of edges) {\n if (grounded.has(part) || !grounded.has(on)) continue\n grounded.add(part)\n grew = true\n }\n }\n return grounded\n}\n\nfunction sectionViolation(part: PartSpec): StructuralViolation | null {\n if (part.material !== 'concrete' || part.shape.kind !== 'box') return null\n const role = part.structure?.role\n const [x, y, z] = part.shape.size\n if (role === 'column' && (Math.min(x, z) < MIN_PILLAR_SIDE - EPSILON || x * z < MIN_PILLAR_AREA - EPSILON))\n return { code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${x.toFixed(2)} x ${z.toFixed(2)} m: NBR 6118 asks at least ${MIN_PILLAR_SIDE} m a side` }\n if (role === 'beam' && Math.min(x, z) < MIN_BEAM_WIDTH - EPSILON && y >= Math.min(x, z))\n return { code: STRUCTURAL_VIOLATION.CONCRETE_BELOW_MIN_SECTION, part: part.id, message: `${part.id} is ${Math.min(x, z).toFixed(2)} m wide: NBR 6118 asks at least ${MIN_BEAM_WIDTH} m` }\n return null\n}\n\n/** Every structural part of the spec reaches an anchored part over the joints that bear; every concrete pillar and beam has the NBR 6118 minimum section. */\nexport function specViolations(spec: DestructibleSpec): StructuralViolation[] {\n const byId = new Map(spec.parts.map((part) => [part.id, part]))\n const grounded = groundedOf(spec, byId)\n const out: StructuralViolation[] = []\n for (const part of spec.parts) {\n if (!carries(part)) continue\n if (!grounded.has(part.id)) {\n const pillar = part.structure!.role === 'column'\n out.push({ code: pillar ? STRUCTURAL_VIOLATION.PILLAR_NOT_GROUNDED : STRUCTURAL_VIOLATION.FLOATING_PART, part: part.id, message: `${part.id} has no load path to an anchored part` })\n }\n const section = sectionViolation(part)\n if (section) out.push(section)\n }\n return out\n}\n","import type { DestructibleSpec } from '@adatechnology/game-contracts'\n\nimport { applyPanels } from '../wall-detail'\nimport type { SourceDoor, PlanStructure, WallDetail } from '../types'\nimport { STRUCTURAL_VIOLATION } from './codes'\nimport type { StructuralViolation } from './codes'\nimport { concreteViolations, loadPathViolations } from './load-path'\nimport { isMasonryWall, masonryViolations } from './masonry'\nimport { openingViolations } from './openings'\nimport { specViolations } from './spec'\n\nexport interface ValidateStructureOptions {\n /** Detail the walls are built in for play (default `panels`, as the houses are): the lintels and sill beams of the windows come from it. */\n wallDetail?: WallDetail\n /** The doors of the plan (`plan.doors`): each door gap in a masonry wall needs a lintel. Without them only the windows are checked. */\n doors?: readonly SourceDoor[]\n}\n\n/**\n * What a structure gets wrong as a real building: load paths (every part down to the ground, every pillar on what carries it), reinforced concrete (NBR\n * 6118 sections, steel, beam depth) and, in masonry, confined masonry (ground beam, pillars at ends, corners, junctions and every 4 m up to the bond beam,\n * lintels and sill beams, bonded and plastered bricks). An empty list is a structure that a structural engineer would sign.\n */\nexport function validateStructure(structure: PlanStructure, options: ValidateStructureOptions = {}): StructuralViolation[] {\n const detail = options.wallDetail ?? 'panels'\n const built = applyPanels({ parts: structure.parts, supports: structure.supports }, structure, detail)\n const out = [...loadPathViolations(structure), ...concreteViolations({ ...built, construction: structure.construction }, isMasonryWall)]\n if (structure.construction.system !== 'masonry') return out\n return [...out, ...masonryViolations(structure), ...openingViolations(structure, built.parts, options.doors ?? [])]\n}\n\n/** What a destructible spec built straight as one (towers, skyscrapers) gets wrong: load paths and concrete sections. */\nexport function validateSpec(spec: DestructibleSpec): StructuralViolation[] {\n return specViolations(spec)\n}\n\n/** The violations counted by code (for reports and tests). */\nexport function countViolations(violations: readonly StructuralViolation[]): Partial<Record<keyof typeof STRUCTURAL_VIOLATION, number>> {\n const out: Partial<Record<keyof typeof STRUCTURAL_VIOLATION, number>> = {}\n for (const violation of violations) out[violation.code] = (out[violation.code] ?? 0) + 1\n return out\n}\n\nexport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MAX_PILLAR_SPACING, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION } from './codes'\nexport type { StructuralViolation, StructuralViolationCode } from './codes'\n","import type { DestructibleSpec } from '@adatechnology/game-contracts'\nimport { assemblyDepth, assemblyPart, getAssembly } from '@adatechnology/game-destruction'\n\nimport { GROUND } from './types'\nimport { constructionOfSystem } from './presets'\nimport { CONSTRUCTION_SYSTEMS } from './registry'\nimport { toDestructibleSpec } from './to-destructible-spec'\nimport type { Opening, StructureSource, WallDetail } from './types'\n\nexport interface WallSpecimenOptions {\n /** Wall assembly of `game-destruction` (`brick_wall_plastered`, `concrete_block_wall`, `reinforced_concrete`, `drywall`, `wood_frame_wall`, `log_wall`, `sheet_metal_shack`...). */\n assembly: string\n /** Width and height in metres (the test area uses 2.4 x 2.1). */\n w: number\n h: number\n opening?: 'door' | 'window' | null\n /** Default `panels`: piers, lintel with its 0.2 m bearing, sill, plaster and rebar; `units` also lays the bricks, blocks or concrete panels one by one. */\n detail?: WallDetail\n}\n\nconst SYSTEM_OF_ASSEMBLY: Record<string, string> = { log_wall: 'log', wood_frame_wall: 'wood_frame', sheet_metal_shack: 'improvised' }\nconst DOOR_WIDTH = 0.9\nconst WINDOW_WIDTH = 1.0\n\nfunction openingOf(kind: 'door' | 'window', height: number): Opening {\n return kind === 'door'\n ? { id: 'door', kind, wall: 'wall_specimen', from: -DOOR_WIDTH / 2, to: DOOR_WIDTH / 2, y0: 0, y1: height * 0.8 }\n : { id: 'window', kind, wall: 'wall_specimen', from: -WINDOW_WIDTH / 2, to: WINDOW_WIDTH / 2, y0: height * 0.33, y1: height * 0.8 }\n}\n\n/**\n * A test wall as its assembly builds it, standing on a plinth: in `panels` the piers beside the opening, the lintel over it (reinforced concrete bearing 0.2 m on\n * the piers; a header in timber walls), the sill under a window and the wall above; with the plaster coat and the rebar of the assembly. The mass is the\n * assembly's for the whole w x h, whatever the detail.\n */\nexport function buildWallSpecimen(options: WallSpecimenOptions): DestructibleSpec {\n const { assembly, w, h, opening = null, detail = 'panels' } = options\n const def = getAssembly(assembly)\n if (!def) throw new Error(`unknown assembly \"${assembly}\"`)\n const system = SYSTEM_OF_ASSEMBLY[assembly] ?? 'masonry'\n const depth = assemblyDepth(def)\n const mass = assemblyPart(assembly, { id: 'wall_specimen', width: w, height: h, position: [0, h / 2, 0] }).mass ?? 1\n const construction = constructionOfSystem(system, { facade: {}, floors: [], rooms: [], walls: [], doors: [], items: [], w, d: depth } as StructureSource)!\n const joint = CONSTRUCTION_SYSTEMS.get(system)!.joints.wall\n const structure = {\n parts: [{ id: 'wall_specimen', role: 'wall' as const, material: def.core.material, aabb: [-w / 2, -depth / 2, w / 2, depth / 2] as [number, number, number, number], y0: 0, y1: h, floor: 0, mass, assembly }],\n supports: [{ part: 'wall_specimen', on: GROUND, joint }],\n openings: opening ? [openingOf(opening, h)] : [],\n levels: [0], elevation: 0, construction, framed: false,\n roof: { shape: 'slab' as const, covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n }\n return toDestructibleSpec(structure, { wallDetail: detail, sized: false, terrainMargin: 0.6, name: `wall_${assembly}` })\n}\n","import type { DestructibleSpec, JointSpec, PartSpec, Vec3, WindExposure } from '@adatechnology/game-contracts'\nimport { MATERIALS, buildFrame, partMass, sizeStructure } from '@adatechnology/game-destruction'\nimport type { FrameOptions, SizeStructureOptions, WindOptions } from '@adatechnology/game-destruction'\n\n/**\n * Building systems of a multi-storey building, as parts added to a frame spec: the rigid concrete core (shear-wall tube with the stairs and the\n * elevator shafts inside), the glass curtain wall hung from the slab edges, the flat roof (screed sloped to the drains and a waterproofing\n * membrane) and the mechanical floor under it (elevator machines, the water tank, chillers). Every number is an option with a real default; see the\n * design T10-estrutura-real.md §9.\n */\n\n/** The frame the systems are added to, in metres: what `buildFrame` was given. */\nexport interface TowerGeometry {\n floors: number\n /** Clear height of a storey (`buildFrame` `height`). */\n height: number\n /** Slab thickness. */\n slab: number\n spanX: number\n spanZ: number\n columnSize: number\n /** Columns along x and z (`buildFrame` `columnsX`, `columnsZ`; default 3 and 4, as `TOWER_DEFAULTS`). */\n columnsX?: number\n columnsZ?: number\n /** Depth of the beams (`buildFrame` `beamHeight`; default 0.6 m, as `TOWER_DEFAULTS`). */\n beamHeight?: number\n /** The top slab is a roof (`roof` id) instead of `slab_<floors-1>`. */\n roof: boolean\n}\n\nconst slabId = (g: TowerGeometry, f: number): string => (f === g.floors - 1 && g.roof ? 'roof' : `slab_${f}`)\n/** Bottom of storey `f` (top of the slab under it; storey 0 starts at the ground). */\nconst storeyBase = (g: TowerGeometry, f: number): number => f * (g.height + g.slab)\n/** Half sizes of the slabs (`buildFrame` makes them the span plus a column and 0.1 m each side). */\nconst slabHalf = (g: TowerGeometry): [number, number] => [(g.spanX + g.columnSize + 0.2) / 2, (g.spanZ + g.columnSize + 0.2) / 2]\n\nconst box = (size: Vec3) => ({ kind: 'box' as const, size })\nconst rests = (joints: JointSpec[], a: string, b: string, kind: JointSpec['kind'], bears: JointSpec['bears'] = 'a_on_b') => joints.push({ id: `${a}~${b}`, a, b, kind, bears })\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Rigid core\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface CoreOptions {\n /** Centre of the core in plan, object-local `[x, z]` (default `[0, 0]`). */\n center?: [number, number]\n /** Thickness of the outer walls of the tube (default 0.35 m: 30 to 60 cm in high-rise cores; at least h/25, NBR 6118 18.5 / EN 1992-1-1 9.6). */\n wallThickness?: number\n /** Thickness of the walls inside it, between the stair and the shafts and between shafts (default 0.2 m). */\n innerThickness?: number\n /** Elevator shafts (default 2), each `shaft` wide along z and `shaftDepth` deep along x. */\n elevators?: number\n shaft?: number\n shaftDepth?: number\n /** Stair compartment: width along x (two flights of 1.2 m side by side) and length along z (default 2.6 x 4.8 m, NBR 9077). */\n stairWidth?: number\n stairLength?: number\n /** Concrete of the walls (default `concrete`). */\n material?: string\n /** Rebar cage of the walls: bars of `diameter` every `spacing` (default 12.5 mm every 0.15 m: about 0.5% of the section, above the 0.2% of EN 1992-1-1 9.6.2). */\n rebar?: { spacing?: number; diameter?: number }\n /** Thickness of the mat foundation under the core when the frame has no raft (default 1.2 m). */\n matThickness?: number\n}\n\nexport const CORE_DEFAULTS = {\n wallThickness: 0.35, innerThickness: 0.2, elevators: 2, shaft: 2.2, shaftDepth: 2.4, stairWidth: 2.6, stairLength: 4.8, material: 'concrete',\n rebar: { spacing: 0.15, diameter: 0.0125 }, matThickness: 1.2,\n} as const\n\n/** Outer size of the core in plan, `[x, z]`, from its options: the stair compartment beside the row of shafts. */\nexport const coreSize = (o: CoreOptions = {}): [number, number] => {\n const c = { ...CORE_DEFAULTS, ...o }\n const shafts = c.elevators * c.shaft + Math.max(0, c.elevators - 1) * c.innerThickness\n return [2 * c.wallThickness + c.stairWidth + c.innerThickness + c.shaftDepth, 2 * c.wallThickness + Math.max(c.stairLength, shafts)]\n}\n\n/**\n * Adds the concrete core: four shear walls per storey forming a tube, the wall between the stair and the shafts and the walls between shafts, each\n * resting on the one below (continuous from the foundation to the roof) with its rebar cage, the slab of each storey resting on the tube, two\n * flights and a landing of stairs per storey inside, and an elevator car parked at the bottom of each shaft. Part ids: `core_<f>_<n|s|e|w|stair|shaft_k>`,\n * `stair_<f>_a|b`, `landing_<f>`, `elevator_<k>`, `core_mat`.\n */\nexport function addCore(spec: DestructibleSpec, g: TowerGeometry, options: CoreOptions = {}): DestructibleSpec {\n const c = { ...CORE_DEFAULTS, ...options, rebar: { ...CORE_DEFAULTS.rebar, ...options.rebar } }\n const [cx, cz] = options.center ?? [0, 0]\n const [W, L] = coreSize(options)\n const t = c.wallThickness, ti = c.innerThickness\n const x0 = cx - W / 2, z0 = cz - L / 2\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const reinforcement = { material: 'steel', spacing: c.rebar.spacing, diameter: c.rebar.diameter }\n const raft = parts.find((p) => p.id === 'raft')\n let base = raft?.id\n if (!base) {\n base = 'core_mat'\n parts.push({ id: base, material: c.material, shape: box([W + 1, c.matThickness, L + 1]), position: [cx, -c.matThickness / 2, cz], structure: { role: 'foundation' }, anchored: true })\n }\n const innerX = x0 + t + c.stairWidth + ti / 2\n for (let f = 0; f < g.floors; f++) {\n const yb = storeyBase(g, f), H = g.height\n const wall = (name: string, size: Vec3, pos: [number, number]) => {\n const id = `core_${f}_${name}`\n parts.push({ id, material: c.material, shape: box(size), position: [pos[0], yb + H / 2, pos[1]], structure: { role: 'wall' }, reinforcement, tags: ['core'] })\n rests(joints, id, f === 0 ? base! : `core_${f - 1}_${name}`, 'rebar')\n return id\n }\n const tube = [\n wall('w', [t, H, L], [x0 + t / 2, cz]),\n wall('e', [t, H, L], [x0 + W - t / 2, cz]),\n wall('n', [W - 2 * t, H, t], [cx, z0 + L - t / 2]),\n wall('s', [W - 2 * t, H, t], [cx, z0 + t / 2]),\n ]\n wall('stair', [ti, H, L - 2 * t], [innerX, cz])\n for (let k = 1; k < c.elevators; k++) {\n wall(`shaft_${k}`, [c.shaftDepth, H, ti], [innerX + ti / 2 + c.shaftDepth / 2, z0 + t + k * c.shaft + (k - 1) * ti + ti / 2])\n }\n for (const w of tube) rests(joints, slabId(g, f), w, 'rebar')\n // the stairs: two flights of half the storey each and the landing between them, cast into the walls of the tube\n const rise = (H + g.slab) / 2\n const flightWidth = (c.stairWidth - 0.2) / 2\n const landing = 1.2\n const run = c.stairLength - 2 * landing\n const angle = Math.atan2(rise, run)\n const length = Math.hypot(rise, run)\n const sx = x0 + t\n const landingId = `landing_${f}`\n parts.push({ id: landingId, material: c.material, shape: box([c.stairWidth, 0.15, landing]), position: [sx + c.stairWidth / 2, yb + rise - 0.075, z0 + t + c.stairLength - landing / 2], structure: { role: 'stair' }, tags: ['stair'] })\n rests(joints, landingId, `core_${f}_w`, 'rebar')\n rests(joints, landingId, `core_${f}_stair`, 'rebar')\n const zMid = z0 + t + landing + run / 2\n for (const [k, side] of [['a', 0], ['b', 1]] as const) {\n const id = `stair_${f}_${k}`\n const up = side === 0 ? 1 : -1\n parts.push({\n id, material: c.material, shape: box([flightWidth, 0.15, length]), position: [sx + flightWidth / 2 + side * (flightWidth + 0.2), yb + rise / 2 + side * rise, zMid],\n rotation: [up * angle * -1, 0, 0], structure: { role: 'stair' }, tags: ['stair'],\n })\n rests(joints, id, landingId, 'rebar')\n rests(joints, id, side === 0 ? `core_${f}_w` : `core_${f}_stair`, 'rebar')\n }\n }\n // a car at the bottom of each shaft (it hangs from its machine on the mechanical floor; parked, it rests on the pit)\n for (let k = 0; k < c.elevators; k++) {\n const id = `elevator_${k}`\n parts.push({\n id, material: 'steel', shape: box([c.shaftDepth - 0.6, 2.3, c.shaft - 0.6]), position: [innerX + ti / 2 + c.shaftDepth / 2, 1.15 + 0.05, z0 + t + k * (c.shaft + ti) + c.shaft / 2],\n fill: 0.03, mass: 1500, tags: ['elevator_car'],\n })\n rests(joints, id, base, 'resting', false)\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Curtain wall\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface CurtainWallOptions {\n /** Width of a panel (default 1.5 m). */\n panel?: number\n /** Glass of the panels (default `glass`: annealed or laminated glass that breaks in large shards; `tempered_glass` breaks in small cubes). */\n material?: string\n /** Glass thickness in metres: the two panes of an insulated unit (default 0.012, 6 + 6 mm). */\n thickness?: number\n /** Mass of the aluminium frame per m² of facade (default 10 kg/m²). */\n frameKgM2?: number\n /** Size of the pieces a broken panel falls in (default 0.6 m: a laminated pane breaks in large shards held by the interlayer). */\n shard?: number\n /** Gap from the slab edge to the glass (default 0.1 m). */\n offset?: number\n /** Storeys without glass (the mechanical floor has louvres): default none. */\n skip?: (floor: number) => boolean\n}\n\nexport const CURTAIN_DEFAULTS = { panel: 1.5, material: 'glass', thickness: 0.012, frameKgM2: 10, shard: 0.6, offset: 0.1 } as const\n\n/**\n * Adds a glass curtain wall around the frame: one panel per bay and storey, floor to floor, hung from the edge of the slab above it (`bolt`, carries\n * nothing: role none). In a blast the panels shatter into `shard`-sized pieces (`units`) that fall from the facade; a panel whose slab falls goes\n * with it. Part ids: `glass_<f>_<side>_<k>` with side `n`, `s`, `e`, `w`.\n */\nexport function addCurtainWall(spec: DestructibleSpec, g: TowerGeometry, options: CurtainWallOptions = {}): DestructibleSpec {\n const c = { ...CURTAIN_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const [hx, hz] = slabHalf(g)\n const h = g.height + g.slab\n const sides = [\n { name: 'n', along: 0, length: 2 * hx, fixed: hz + c.offset, axis: 2 },\n { name: 's', along: 0, length: 2 * hx, fixed: -hz - c.offset, axis: 2 },\n { name: 'e', along: 2, length: 2 * hz, fixed: hx + c.offset, axis: 0 },\n { name: 'w', along: 2, length: 2 * hz, fixed: -hx - c.offset, axis: 0 },\n ]\n for (let f = 0; f < g.floors; f++) {\n if (c.skip?.(f)) continue\n const yb = storeyBase(g, f)\n for (const s of sides) {\n const n = Math.max(1, Math.round(s.length / c.panel))\n const w = s.length / n\n for (let k = 0; k < n; k++) {\n const id = `glass_${f}_${s.name}_${k}`\n const at = -s.length / 2 + (k + 0.5) * w\n const size: Vec3 = s.axis === 2 ? [w - 0.01, h - 0.01, c.thickness] : [c.thickness, h - 0.01, w - 0.01]\n const position: Vec3 = s.axis === 2 ? [at, yb + h / 2, s.fixed] : [s.fixed, yb + h / 2, at]\n parts.push({\n id, material: c.material, shape: box(size), position, mass: (2500 * c.thickness + c.frameKgM2) * w * h, thickness: c.thickness,\n units: { size: [c.shard, c.shard, c.thickness], bond: 'stack', mortar: 'plastic' }, tags: ['curtain_wall', 'glass'],\n })\n rests(joints, id, slabId(g, f), 'bolt', false)\n }\n }\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Punched facade\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface PunchedFacadeOptions {\n /** Material of the infill wall (default `brick`: a masonry or block wall between the columns, as the residential towers are built). */\n material?: string\n /** Thickness of the wall in metres (default 0.2). */\n thickness?: number\n /** Width of the window as a share of the clear bay (default 0.6). */\n window?: number\n /** Sill and head of the window above the floor of the storey (default 0.9 and 2.4 m; the head is kept under the beam). */\n sill?: number\n head?: number\n /** Glass of the window and its thickness (default `glass`, 12 mm: an insulated unit). */\n glass?: string\n glassThickness?: number\n /** Storeys without infill (louvres on a mechanical floor): default none. */\n skip?: (floor: number) => boolean\n}\n\nexport const PUNCHED_DEFAULTS = { material: 'brick', thickness: 0.2, window: 0.6, sill: 0.9, head: 2.4, glass: 'glass', glassThickness: 0.012 } as const\n\n/**\n * Closes the perimeter bays of every storey with an infill wall that has a window in it (the alternative to the curtain wall): a sill wall under the\n * window, a wall over it and a pier at each side, all resting on the columns of the bay (role partition: they load the columns and carry nothing, as the\n * walls of `buildFrame`), and the glass in the opening, which rests on the sill and carries nothing. Part ids: `infill_<f>_<side>_<k>_sill|head|pl|pr`,\n * `glass_<f>_<side>_<k>` with side `n`, `s`, `e`, `w` (the same ids as the curtain wall, so the two exclude each other).\n */\nexport function addPunchedFacade(spec: DestructibleSpec, g: TowerGeometry, options: PunchedFacadeOptions = {}): DestructibleSpec {\n const c = { ...PUNCHED_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const nx = Math.max(2, g.columnsX ?? 3), nz = Math.max(2, g.columnsZ ?? 4)\n const xs = Array.from({ length: nx }, (_, i) => -g.spanX / 2 + (i * g.spanX) / (nx - 1))\n const zs = Array.from({ length: nz }, (_, j) => -g.spanZ / 2 + (j * g.spanZ) / (nz - 1))\n const beamUnder = g.beamHeight ?? TOWER_DEFAULTS.beamHeight\n for (let f = 0; f < g.floors; f++) {\n if (c.skip?.(f)) continue\n const yb = storeyBase(g, f)\n const room = g.height - beamUnder\n const head = Math.min(c.head, room - 0.3), sill = Math.min(c.sill, head - 0.6)\n const wall = (id: string, size: Vec3, position: Vec3, on: string[]) => {\n parts.push({ id, material: c.material, shape: box(size), position, structure: { role: 'partition' }, tags: ['infill'] })\n for (const o of on) rests(joints, id, o, 'mortar')\n }\n const bay = (side: string, k: number, along: 0 | 2, centre: number, fixed: number, length: number, c1: string, c2: string) => {\n const clear = length - g.columnSize\n const win = clear * c.window\n const pier = (clear - win) / 2\n const at = (u: number): Vec3 => (along === 0 ? [u, 0, fixed] : [fixed, 0, u])\n const size = (u: number, h: number): Vec3 => (along === 0 ? [u, h, c.thickness] : [c.thickness, h, u])\n const put = (name: string, u: number, h: number, y: number, centreU: number, on: string[]) => {\n const p = at(centreU)\n wall(`infill_${f}_${side}_${k}_${name}`, size(u, h), [p[0], y, p[2]], on)\n }\n const id = (name: string) => `infill_${f}_${side}_${k}_${name}`\n put('sill', clear, sill, yb + sill / 2, centre, [c1, c2])\n put('pl', pier, head - sill, yb + sill + (head - sill) / 2, centre - clear / 2 + pier / 2, [c1, id('sill')])\n put('pr', pier, head - sill, yb + sill + (head - sill) / 2, centre + clear / 2 - pier / 2, [c2, id('sill')])\n put('head', clear, room - head, yb + head + (room - head) / 2, centre, [c1, c2])\n const gp = at(centre)\n const gid = `glass_${f}_${side}_${k}`\n parts.push({\n id: gid, material: c.glass, shape: box(size(win - 0.01, head - sill)), position: [gp[0], yb + sill + (head - sill) / 2, gp[2]], thickness: c.glassThickness,\n units: { size: [0.6, 0.6, c.glassThickness], bond: 'stack', mortar: 'plastic' }, tags: ['window', 'glass'],\n })\n rests(joints, gid, id('sill'), 'glue', false)\n }\n for (const [side, j] of [['s', 0], ['n', nz - 1]] as const) {\n for (let i = 0; i < nx - 1; i++) bay(side, i, 0, (xs[i] + xs[i + 1]) / 2, zs[j], xs[i + 1] - xs[i], `column_${f}_${i}_${j}`, `column_${f}_${i + 1}_${j}`)\n }\n for (const [side, i] of [['w', 0], ['e', nx - 1]] as const) {\n for (let j = 0; j < nz - 1; j++) bay(side, j, 2, (zs[j] + zs[j + 1]) / 2, xs[i], zs[j + 1] - zs[j], `column_${f}_${i}_${j}`, `column_${f}_${i}_${j + 1}`)\n }\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Flat roof\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface FlatRoofOptions {\n /** Slope of the screed to the drains (default 0.01: 1%, the minimum of NBR 9575 for flat roofs). */\n slope?: number\n /** Screed thickness at the drains (default 0.02 m). */\n screedMin?: number\n /** Density of the screed (default 2000 kg/m³, cement and sand). */\n screedDensity?: number\n /** Membrane material and thickness (default `rubber` 1.5 mm: an EPDM sheet). */\n membrane?: string\n membraneThickness?: number\n /** Drains (default one per 150 m² of roof, at least 2, on the long centre line). */\n drains?: number\n /** Water standing on the membrane in metres (default 0.005: 5 mm of a storm on its way to the drains); set it in game with `setLiters`. */\n water?: number\n}\n\nexport const FLAT_ROOF_DEFAULTS = { slope: 0.01, screedMin: 0.02, screedDensity: 2000, membrane: 'rubber', membraneThickness: 0.0015, water: 0.005, areaPerDrain: 150 } as const\n\n/**\n * Turns the top slab into a flat roof: a screed sloped to the drains (its weight from the mean thickness `screedMin + slope * run / 2`), the\n * waterproofing membrane over it with the rain water on it (`contains` water, running down through a puncture: `outflow` [0, -1, 0], so a shot through\n * the membrane is a `leak` into the floor below) and the drains (tag `drain`). Screed and membrane load the roof slab (role partition: carried,\n * carry nothing). Part ids: `roof_screed`, `roof_membrane`, `roof_drain_<k>`.\n */\nexport function addFlatRoof(spec: DestructibleSpec, g: TowerGeometry, options: FlatRoofOptions = {}): DestructibleSpec {\n const c = { ...FLAT_ROOF_DEFAULTS, ...options }\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const top = slabId(g, g.floors - 1)\n const slab = parts.find((p) => p.id === top)\n if (!slab || slab.shape.kind !== 'box') return spec\n const [sx, sy, sz] = slab.shape.size\n const area = sx * sz\n const longX = sx >= sz\n const count = c.drains ?? Math.max(2, Math.ceil(area / c.areaPerDrain))\n const long = longX ? sx : sz\n const spacing = long / count\n // the farthest point from a drain: half the spacing along the line and half the width across it\n const run = Math.hypot(spacing / 2, (longX ? sz : sx) / 2)\n const screed = c.screedMin + (c.slope * run) / 2\n const y = slab.position[1] + sy / 2\n parts.push({\n id: 'roof_screed', material: 'concrete', shape: box([sx, screed, sz]), position: [slab.position[0], y + screed / 2, slab.position[2]], mass: c.screedDensity * screed * area,\n structure: { role: 'partition' }, tags: ['roof_screed'],\n })\n rests(joints, 'roof_screed', top, 'mortar')\n const my = y + screed + c.membraneThickness / 2\n parts.push({\n id: 'roof_membrane', material: c.membrane, shape: box([sx, c.membraneThickness, sz]), position: [slab.position[0], my, slab.position[2]], thickness: c.membraneThickness,\n structure: { role: 'partition' }, contains: { fluid: 'water', liters: c.water * area * 1000, outflow: [0, -1, 0] }, tags: ['roof_membrane', 'waterproofing'],\n })\n rests(joints, 'roof_membrane', top, 'glue')\n for (let k = 0; k < count; k++) {\n const at = -long / 2 + (k + 0.5) * spacing\n const id = `roof_drain_${k}`\n parts.push({\n id, material: 'plastic', shape: { kind: 'cylinder', radius: 0.05, height: 0.1 }, position: longX ? [slab.position[0] + at, my, slab.position[2]] : [slab.position[0], my, slab.position[2] + at],\n fill: 0.2, tags: ['drain'],\n })\n rests(joints, id, top, 'glue', false)\n }\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Mechanical floor\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface MechanicalFloorOptions {\n /** Elevator machines: one per elevator, over its shaft (default from the core; 2). */\n elevators?: number\n /** Where the shafts are, object-local `[x, z]` of each (default from the core layout). */\n shafts?: Array<[number, number]>\n /** Mass of a traction machine with its frame (default 2500 kg) and of what hangs from it: car, counterweight, rated load (default 1500 + 2000 + 1000 kg). */\n machineMass?: number\n suspendedMass?: number\n /** Water tank in litres (default: `occupants` per storey x 200 L a day x 40% stored up high, NBR 5626, plus a fire reserve of 6000 L, NBR 13714). */\n waterLiters?: number\n occupants?: number\n fireReserve?: number\n /** Chillers on the floor (default 2 of 3500 kg). */\n chillers?: number\n chillerMass?: number\n /** Material and wall thickness of the tank (default `plastic` 10 mm: a fibreglass or polyethylene reservoir). */\n tankMaterial?: string\n tankWall?: number\n /** Where the tank goes, `[x, z]` (default the middle of the bay at -x, away from the core). */\n tankAt?: [number, number]\n /**\n * Storey the equipment stands on (default the top one, under the roof). On any other storey the part ids end in `_<floor>` (`water_tank_20`,\n * `chiller_0_20`), so a tower can carry a mechanical floor every few storeys (design T10 §11).\n */\n floor?: number\n}\n\nexport const MECHANICAL_DEFAULTS = { tankMaterial: 'plastic', tankWall: 0.01, machineMass: 2500, suspendedMass: 4500, occupants: 16, litersPerPerson: 200, storedFraction: 0.4, fireReserve: 6000, chillers: 2, chillerMass: 3500 } as const\n\n/** Litres of the water tank of a building of `storeys` occupied storeys (NBR 5626 consumption, the fire reserve of NBR 13714). */\nexport const towerWater = (storeys: number, o: Pick<MechanicalFloorOptions, 'occupants' | 'fireReserve'> = {}): number =>\n Math.round((o.occupants ?? MECHANICAL_DEFAULTS.occupants) * MECHANICAL_DEFAULTS.litersPerPerson * MECHANICAL_DEFAULTS.storedFraction * storeys + (o.fireReserve ?? MECHANICAL_DEFAULTS.fireReserve))\n\n/**\n * Makes the top storey the mechanical floor: the elevator machines over the shafts, the water tank (with its water: `contains`, a shot makes it leak)\n * and the chillers, on the slab under the roof (role partition: their weight goes into the structure). Part ids: `machine_<k>`, `water_tank`,\n * `chiller_<k>`.\n */\nexport function addMechanicalFloor(spec: DestructibleSpec, g: TowerGeometry, options: MechanicalFloorOptions = {}): DestructibleSpec {\n const c = { ...MECHANICAL_DEFAULTS, ...options }\n if (g.floors < 2) return spec\n const level = options.floor ?? g.floors - 1\n if (level < 1 || level > g.floors - 1) return spec\n const sfx = level === g.floors - 1 ? '' : `_${level}`\n const parts: PartSpec[] = [...spec.parts]\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n const floor = `slab_${level - 1}`\n const y = storeyBase(g, level)\n const shafts = options.shafts ?? []\n const put = (id: string, material: string, size: Vec3, at: [number, number], mass: number, extra: Partial<PartSpec> = {}) => {\n parts.push({ id: id + sfx, material, shape: box(size), position: [at[0], y + size[1] / 2, at[1]], mass, fill: 0.2, structure: { role: 'partition' }, tags: ['mechanical'], ...extra })\n rests(joints, id + sfx, floor, 'bolt')\n }\n shafts.forEach((at, k) => put(`machine_${k}`, 'steel', [1.2, 1.0, 0.8], at, c.machineMass + c.suspendedMass, { tags: ['mechanical', 'elevator_machine'] }))\n const liters = options.waterLiters ?? towerWater(level, options)\n const depth = 2\n const side = Math.sqrt(liters / 1000 / depth)\n const [hx] = slabHalf(g)\n const tankAt = options.tankAt ?? [-hx / 2, 0]\n const shell = 4 * side * depth + 2 * side * side\n put('water_tank', c.tankMaterial, [side, depth, side], tankAt, liters + 1100 * c.tankWall * shell, {\n fill: (shell * c.tankWall) / (side * side * depth), thickness: c.tankWall, contains: { fluid: 'water', liters }, tags: ['mechanical', 'water_tank'],\n })\n for (let k = 0; k < c.chillers; k++) put(`chiller_${k}`, 'steel', [3, 2, 1.5], [-hx + 2 + k * 3.5, -(slabHalf(g)[1] - 2)], c.chillerMass, { tags: ['mechanical', 'chiller'] })\n return { ...spec, parts, joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Tuned mass damper\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface DamperOptions {\n /** Mass of the damper in kg (default: `ratio` of the modal mass of the building, estimated as `modalShare` of its mass). */\n mass?: number\n /** Mass ratio, damper over the modal mass of the building (default 0.01: 0.5 to 2% is the usual range). */\n ratio?: number\n /** Share of the building's mass that is its modal mass in the first mode, tip at 1 (default 0.25, a uniform cantilever). */\n modalShare?: number\n /** Frequency in Hz and damping ratio of the damper (default: tuned by the world to the building, `wind.tuning`). */\n frequency?: number\n damping?: number\n /** Where it stands on the mechanical floor, object-local `[x, z]` (default on the beam end beside the column nearest to 35% of the depth at +z, clear of the machines: its weight goes straight to the beam and the column). */\n at?: [number, number]\n /** Material of the mass (default `steel`; the real ones are steel or lead-filled blocks and concrete). */\n material?: string\n /** Tallest the block may be, metres (default 2.5: it stands inside the mechanical floor). */\n maxHeight?: number\n}\n\nexport const DAMPER_DEFAULTS = { ratio: 0.01, modalShare: 0.25, material: 'steel', maxHeight: 2.5 } as const\n\n/** Mass in kg of a damper for a structure: `ratio` of `modalShare` of the mass of everything above the foundations (curtain wall, roof and equipment included). */\nexport const damperMass = (spec: DestructibleSpec, o: Pick<DamperOptions, 'ratio' | 'modalShare'> = {}): number => {\n const byId = new Map(MATERIALS.map((m) => [m.id, m]))\n let total = 0\n for (const p of spec.parts) {\n const m = byId.get(p.material)\n if (!m || p.structure?.role === 'foundation' || p.damper) continue\n total += partMass(p, m)\n }\n return total * (o.modalShare ?? DAMPER_DEFAULTS.modalShare) * (o.ratio ?? DAMPER_DEFAULTS.ratio)\n}\n\n/**\n * Adds a tuned mass damper to the mechanical floor: a block of `material` on the slab under the roof (role partition: its mass loads the slab and\n * goes down to the core and the columns like the machines), with `PartSpec.damper` so the world tunes it to the building and moves it against the\n * sway (Den Hartog). Part id: `damper`.\n */\nexport function addTunedMassDamper(spec: DestructibleSpec, g: TowerGeometry, options: DamperOptions = {}): DestructibleSpec {\n const c = { ...DAMPER_DEFAULTS, ...options }\n if (g.floors < 2) return spec\n const mat = MATERIALS.find((m) => m.id === c.material)\n if (!mat) throw new Error(`unknown material \"${c.material}\" for the damper`)\n const mass = options.mass ?? damperMass(spec, c)\n const volume = mass / mat.density\n const height = Math.min(c.maxHeight, Math.cbrt(volume))\n const side = Math.sqrt(volume / height)\n const column = (span: number, n: number | undefined, want: number) => {\n const k = Math.max(2, n ?? 0) - 1\n return n === undefined ? want : Math.round((want + span / 2) / (span / k)) * (span / k) - span / 2\n }\n const colZ = column(g.spanZ, g.columnsZ, g.spanZ * 0.35)\n // on the beam end beside the column, so the slab hands its weight straight to the beam, which hands it to the column\n const at = options.at ?? [column(g.spanX, g.columnsX, 0), colZ - Math.sign(colZ || 1) * (g.columnSize / 2 + 0.1)]\n const y = storeyBase(g, g.floors - 1)\n const floor = `slab_${g.floors - 2}`\n const part: PartSpec = {\n id: 'damper', material: c.material, shape: box([side, height, side]), position: [at[0], y + height / 2, at[1]], mass, structure: { role: 'partition' }, tags: ['mechanical', 'tuned_mass_damper'],\n damper: { ...(c.frequency !== undefined ? { frequency: c.frequency } : {}), ...(c.damping !== undefined ? { damping: c.damping } : {}) },\n }\n const joints: JointSpec[] = [...(spec.joints ?? [])]\n rests(joints, part.id, floor, 'bolt')\n return { ...spec, parts: [...spec.parts, part], joints }\n}\n\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n// Tower\n// -------------------------------------------------------------------------------------------------------------------------------------------------\n\nexport interface TowerMechanicalOptions {\n /**\n * Another mechanical floor every this many storeys (design T10 §11): storeys `every`, `2 * every`... below the top one, each with its own\n * relay water tank for the storeys it serves and its chillers, and without glass. Default none: only the top storey.\n */\n every?: number\n}\n\n/** Indices of the intermediate mechanical storeys of a tower of `floors` storeys with one every `every` (none below `every / 2` storeys of the top one). */\nexport const mechanicalStoreys = (floors: number, every?: number): number[] => {\n if (!every || every < 2) return []\n const out: number[] = []\n for (let k = every; k < floors - 1; k += every) if (floors - 1 - k >= every / 2) out.push(k)\n return out\n}\n\nexport interface TowerOptions extends Omit<FrameOptions, 'walls' | 'roof' | 'continuousColumns'> {\n /** The core (default on); `false` for a frame alone. */\n core?: CoreOptions | false\n /** The curtain wall (default on, without glass on the mechanical floor). */\n facade?: CurtainWallOptions | false\n /** A punched facade (infill walls with windows) instead of the curtain wall: turn the curtain wall off (`facade: false`) when you use it. Default off. */\n punched?: PunchedFacadeOptions | false\n /** The flat roof (default on). */\n flatRoof?: FlatRoofOptions | false\n /** The mechanical floor under the roof (default on). */\n mechanical?: (MechanicalFloorOptions & TowerMechanicalOptions) | false\n /** A tuned mass damper on the mechanical floor (default off: `{}` adds one of 1% of the modal mass). */\n damper?: DamperOptions | false\n /**\n * The wind the tower is made for (default none: the tower is sized for its weight only). Its `speed`, `terrain`, `class`... size the walls, columns\n * and core bars for the wind (`sizeStructure({ wind })`), and the fields of `WindExposure` (terrain, class, topography, statistical, drag, damping)\n * go into `DestructibleSpec.wind`, where the building stands. The world still needs its own `wind` for the wind to blow.\n */\n wind?: WindOptions | false\n /** Size the structure (`sizeStructure`, default `{}`); `false` keeps the material capacities. */\n sizing?: SizeStructureOptions | false\n}\n\n/** The fields of the wind options that describe the place and the shape of one building (`DestructibleSpec.wind`). */\nexport const windExposureOf = (w: WindOptions): WindExposure => {\n const out: WindExposure = {}\n if (w.terrain !== undefined) out.terrain = w.terrain\n if (w.class !== undefined) out.class = w.class\n if (w.topography !== undefined) out.topography = w.topography\n if (w.statistical !== undefined) out.statistical = w.statistical\n if (w.drag !== undefined) out.drag = w.drag\n if (w.damping !== undefined) out.damping = w.damping\n return out\n}\n\n/** Defaults of the frame of a tower: 16 x 24 m on a 8 m grid, 12 storeys of 3 m, 60 cm columns caged with 20 mm bars, 60 cm beams, continuous columns. */\nexport const TOWER_DEFAULTS = {\n spanX: 16, spanZ: 24, columnsX: 3, columnsZ: 4, floors: 12, height: 3, columnSize: 0.6, beamHeight: 0.6, slabThickness: 0.2,\n columnCage: { material: 'steel', spacing: 0.15, diameter: 0.02 },\n} as const\n\n/**\n * A multi-storey building with real structure: a frame with continuous columns, the concrete core in the bay at +x of the centre, the curtain wall,\n * the flat roof and the mechanical floor, sized as a designer would. Every system can be turned off or configured.\n */\nexport function buildTower(options: TowerOptions = {}): DestructibleSpec {\n const { core, facade, punched, flatRoof, mechanical, damper, wind, sizing, ...frame } = options\n const f = { ...TOWER_DEFAULTS, ...frame, columnCage: { ...TOWER_DEFAULTS.columnCage, ...frame.columnCage } }\n const g: TowerGeometry = { floors: f.floors, height: f.height, slab: f.slabThickness, spanX: f.spanX, spanZ: f.spanZ, columnSize: f.columnSize, columnsX: f.columnsX, columnsZ: f.columnsZ, beamHeight: f.beamHeight, roof: true }\n const { every, ...mech } = mechanical || {}\n const relays = mechanical === false ? [] : mechanicalStoreys(f.floors, every)\n const noGlass = (fl: number) => mechanical !== false && (fl === g.floors - 1 || relays.includes(fl))\n let spec = buildFrame({ roofThickness: f.slabThickness, ...f, roof: true, continuousColumns: true })\n spec = { ...spec, name: 'tower', tags: ['structure', 'tower'] }\n let shafts: Array<[number, number]> = []\n if (core !== false) {\n const bayX = f.spanX / (Math.max(2, f.columnsX) - 1)\n const center = core?.center ?? [bayX / 2, 0]\n spec = addCore(spec, g, { ...core, center })\n const c = { ...CORE_DEFAULTS, ...core }\n const [W, L] = coreSize(core || {})\n const sx = center[0] - W / 2 + c.wallThickness + c.stairWidth + c.innerThickness + c.shaftDepth / 2\n shafts = Array.from({ length: c.elevators }, (_, k) => [sx, center[1] - L / 2 + c.wallThickness + k * (c.shaft + c.innerThickness) + c.shaft / 2] as [number, number])\n }\n if (facade !== false && !punched) spec = addCurtainWall(spec, g, { skip: noGlass, ...facade })\n if (punched) spec = addPunchedFacade(spec, g, { skip: noGlass, ...punched })\n if (flatRoof !== false) spec = addFlatRoof(spec, g, flatRoof || {})\n if (mechanical !== false) {\n spec = addMechanicalFloor(spec, g, { shafts, ...mech })\n // the intermediate floors hold the plant of the zone below them: no elevator machines (they are on the top floor), a relay tank and the chillers\n for (const floor of relays) spec = addMechanicalFloor(spec, g, { ...mech, shafts: [], floor, waterLiters: mech.waterLiters ?? towerWater(every ?? floor, mech) })\n }\n if (damper) spec = addTunedMassDamper(spec, g, damper)\n if (wind) {\n const exposure = windExposureOf(wind)\n if (Object.keys(exposure).length) spec = { ...spec, wind: exposure }\n }\n if (sizing === false) return spec\n return sizeStructure(spec, wind && sizing?.wind === undefined ? { ...sizing, wind } : sizing ?? {})\n}\n","import type { DestructibleSpec, PartSpec, PileSpec, SoilProfile } from '@adatechnology/game-contracts'\nimport { GRAVITY, MATERIALS, SOILS, createDestruction, partMass, pileLength, profileOf } from '@adatechnology/game-destruction'\nimport type { SizeStructureOptions, WindOptions } from '@adatechnology/game-destruction'\n\nimport {\n CORE_DEFAULTS, TOWER_DEFAULTS, buildTower, coreSize, mechanicalStoreys,\n} from './tower'\nimport type { CoreOptions, CurtainWallOptions, DamperOptions, FlatRoofOptions, MechanicalFloorOptions, PunchedFacadeOptions, TowerMechanicalOptions, TowerOptions } from './tower'\n\n/**\n * The skyscraper as a recipe: a few numbers (storeys, bay, core ratio, facade, mechanical floors, damper, wind, soil and piles) that `skyscraperLayout`\n * turns into the sizes of a `buildTower` and `buildSkyscraper` turns into a destructible spec on deep piles. The typologies that use it\n * (`game-floorplan-commercial` office tower, `game-floorplan-residential` residential tower) bring their own defaults and the rooms of the plan; the\n * structure is the same one. Design T10-estrutura-real.md §11.\n */\n\n/** Deep foundation of a tower: bored piles under the raft, taken down to firm ground (`pileLength`) by the load each one carries. */\nexport interface PileDesign {\n /** Diameter in metres (default 1.2: the bored piles of high-rise foundations are 0.8 to 2.0 m). */\n diameter?: number\n /** Grid pitch as a multiple of the diameter (default 3.5; the usual minimum is 2.5 to 3). */\n pitch?: number\n method?: PileSpec['method']\n /** Longest pile in metres (default 60); when the load does not fit, the piles are put closer. */\n maxLength?: number\n /** Fixed length and count (default: from the load and the soil). */\n length?: number\n count?: number\n}\n\nexport const PILE_DEFAULTS = { diameter: 1.2, pitch: 3.5, method: 'bored', maxLength: 60 } as const\n\n/**\n * Most storeys a skyscraper has by default (owner decision 2026-10-25): above about 60 the drift at the top passes H/500, because the engine has no outrigger\n * or perimeter tube. A default, not a physical constant: `SkyscraperOptions.range` (or a preset with another `range`) raises it.\n */\nexport const SKYSCRAPER_MAX_STOREYS = 60\n\n/** Numbers that describe one typology of skyscraper. Every one is an option of `skyscraperLayout`. */\nexport interface SkyscraperPreset {\n /** Storeys: the default and the range the typology accepts (the top storey is the mechanical floor). */\n storeys: number\n range: readonly [number, number]\n /** Clear height of a storey in metres (the storey pitch is this plus the slab). */\n height: number\n /** Column spacing in metres along x and z. */\n bay: readonly [number, number]\n /** Bays along x and z (z always odd: the core stands in the middle bay, between two rows of beams). */\n bays: readonly [number, number]\n /** Tallest the tower may be over its narrowest side (default 9: Taipei 101 is 8.3, the Burj Khalifa 8); the bays are widened to keep it. `false` leaves them as given. */\n slenderness: number | false\n /** Target share of the floor plate taken by the concrete core (tube footprint over plate); the number of elevators follows, as far as the bay allows. */\n coreRatio: number\n facade: 'curtain' | 'punched'\n /** Another mechanical floor every this many storeys; `false` none (only the top one). */\n mechanicalEvery: number | false\n /** Total height in metres from which a tuned mass damper is added on the top mechanical floor; `false` never. */\n damperAbove: number | false\n /** The wind the tower is designed for (`buildTower({ wind })`). */\n wind: WindOptions | false\n /** The ground: a soil class id or a profile of layers; `false` leaves the tower on anchored ground. */\n soil: string | SoilProfile | false\n /** Deep piles under the raft (only with `soil`); `false` leaves a shallow raft. */\n piles: PileDesign | false\n /**\n * Sizes the lateral system by height (default on): a tower taller than `above` metres whose design drift at the requested storeys is over the limit of\n * the wind (`driftLimit`, default H/500: NBR 6118 serviceability) gets wider bays, and with them a larger plate and core, in steps of 0.5 m up to `maxBay`\n * until it passes. `false` keeps the layout as given (and then a 60-storey tower is `drift`).\n */\n sizeForWind?: boolean | { above?: number; maxBay?: number }\n /** Dead load per m² of floor besides the slab itself, kg/m² (facade, partitions, finishes, equipment), used to size the columns. */\n superimposed: number\n}\n\n/** Defaults of a generic skyscraper: a 40-storey tower on 12 m bays with a curtain wall, a plant floor every 20 storeys, a damper above 150 m, in a city wind, on piles to the sand under soft clay. */\nexport const SKYSCRAPER_DEFAULTS: SkyscraperPreset = {\n storeys: 40,\n range: [20, SKYSCRAPER_MAX_STOREYS],\n height: 3.6,\n bay: [12, 12],\n bays: [3, 3],\n slenderness: 9,\n coreRatio: 0.08,\n facade: 'curtain',\n mechanicalEvery: 20,\n damperAbove: 150,\n wind: { speed: 40, terrain: 'IV' },\n soil: { layers: [{ soil: 'clay_soft', thickness: 10 }, { soil: 'sand_dense' }] },\n piles: {},\n superimposed: 450,\n}\n\nexport interface SkyscraperOptions extends Partial<Omit<SkyscraperPreset, 'bay' | 'bays'>> {\n bay?: number | readonly [number, number]\n bays?: readonly [number, number]\n /** Sizes derived from the load and the height unless given: columns, beam depth and slab thickness in metres. */\n columnSize?: number\n beamHeight?: number\n slabThickness?: number\n /** The core (`false`: a frame alone); `wallThickness` and `elevators` are derived unless given. */\n core?: CoreOptions | false\n curtain?: CurtainWallOptions\n punchedFacade?: PunchedFacadeOptions\n flatRoof?: FlatRoofOptions | false\n mechanical?: (MechanicalFloorOptions & TowerMechanicalOptions) | false\n damper?: DamperOptions\n sizing?: SizeStructureOptions | false\n}\n\nexport interface SkyscraperLayout {\n storeys: number\n /** Clear height, slab and storey pitch in metres. */\n height: number\n slab: number\n pitch: number\n /** Height from the ground to the roof. */\n total: number\n bay: [number, number]\n /** Distance between the outer column axes. */\n span: [number, number]\n columnsX: number\n columnsZ: number\n columnSize: number\n beamHeight: number\n /** Size of the floor slab, `[x, z]`, centred on the origin of the spec. */\n plate: [number, number]\n core: { center: [number, number]; size: [number, number]; wallThickness: number; elevators: number; stairWidth: number; shaftDepth: number } | null\n /** Footprint of the core over the plate. */\n coreRatio: number\n facade: 'curtain' | 'punched'\n /** Storeys with plant (the intermediate ones and the top one), ascending. */\n mechanical: number[]\n damper: boolean\n /** The options `buildTower` is called with. */\n tower: TowerOptions\n}\n\nconst ceilTo = (v: number, step: number): number => Math.ceil(v / step - 1e-9) * step\nconst round2 = (v: number): number => Math.round(v * 100) / 100\n/** Bearing stress used to size columns: 0.85 fck of a C25 concrete, in kg/m² (the cage steel is the margin), with the 0.65 utilisation of the sizing. */\nconst COLUMN_KG_M2 = (0.85 * 25e6) / GRAVITY * 0.65\n/** Share of the gravity load the columns carry; the core and its walls take the rest. */\nconst COLUMN_SHARE = 0.5\n/** Clear space kept between the core and the columns and beams around it, metres. */\nconst CORE_CLEARANCE = 0.4\n/** A core wall is as thick as the total height over this, in metres per metre (40 cm at 80 m, 1.55 m at 312 m; real cores run 30 cm to 1.5 m). */\nconst WALL_SLENDER = 200\n\n/** Sizing by wind below this height (metres) is skipped: every tower up to 40 storeys passes H/500 as laid out. */\nexport const WIND_SIZING_DEFAULTS = { above: 180, maxBay: 20 } as const\n\nconst sizedCache = new Map<string, SkyscraperLayout>()\n\n/** The design drift (deflection over height) of the tower of a layout, in the wind it is designed for. */\nconst driftOf = (layout: SkyscraperLayout, wind: WindOptions): number => {\n const w = createDestruction({ wind })\n return w.state(w.add(buildTower(layout.tower)))?.wind?.drift ?? 0\n}\n\n/**\n * Resolves the numbers of a skyscraper from a preset and the options. Without `sizeForWind: false`, a tall tower that would drift past H/500 gets wider\n * bays (so a larger plate and core) until it does not: the way real towers thicken the core and widen the footprint with height. Memoised, because it\n * builds the tower to measure it.\n */\nexport function skyscraperLayout(options: SkyscraperOptions = {}, preset: SkyscraperPreset = SKYSCRAPER_DEFAULTS): SkyscraperLayout {\n const raw = rawLayout(options, preset)\n const o = { ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset & SkyscraperOptions\n const cfg = { ...WIND_SIZING_DEFAULTS, ...(typeof o.sizeForWind === 'object' ? o.sizeForWind : {}) }\n if (o.sizeForWind === false || !o.wind || o.core === false || raw.total < cfg.above) return raw\n const key = JSON.stringify([options, preset])\n const hit = sizedCache.get(key)\n if (hit) return hit\n const limit = o.wind.driftLimit ?? 1 / 500\n let layout = raw\n for (let i = 0; i < 6; i++) {\n const drift = driftOf(layout, o.wind)\n const widest = Math.max(...layout.bay)\n if (drift <= limit || widest >= cfg.maxBay) break\n // drift falls about with the cube of the bay (the plate, the core and the lever arm grow together)\n const k = Math.max(1.02, Math.pow(drift / limit, 1 / 3) * 1.02)\n const bay = layout.bay.map((b) => Math.min(cfg.maxBay, round2(ceilTo(b * k, 0.5)))) as [number, number]\n layout = rawLayout({ ...options, bay }, preset)\n }\n sizedCache.set(key, layout)\n return layout\n}\n\nfunction rawLayout(options: SkyscraperOptions, preset: SkyscraperPreset): SkyscraperLayout {\n const o = { ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset & SkyscraperOptions\n const range = o.range\n const storeys = Math.max(range[0], Math.min(range[1], Math.round(o.storeys)))\n const given: [number, number] = typeof o.bay === 'number' ? [o.bay, o.bay] : [o.bay[0], o.bay[1]]\n const oddZ = (n: number) => (Math.round(n) % 2 === 1 ? Math.round(n) : Math.round(n) + 1)\n const bays: [number, number] = [Math.max(1, Math.round(o.bays[0])), oddZ(Math.max(1, o.bays[1]))]\n const slabOf = (b: number) => Math.max(TOWER_DEFAULTS.slabThickness, round2(ceilTo(b / 32, 0.05)))\n // too slender for its plate: the bays grow until the narrowest side is a ninth of the height (the slab, and so the height, follow the bay)\n let bay: [number, number] = given\n for (let i = 0; i < 4 && o.slenderness !== false; i++) {\n const total = storeys * (o.height + (o.slabThickness ?? slabOf(Math.max(...bay))))\n const narrow = Math.min(bays[0] * bay[0], bays[1] * bay[1])\n if (narrow >= total / o.slenderness) break\n const k = total / o.slenderness / narrow\n bay = [round2(ceilTo(bay[0] * k, 0.5)), round2(ceilTo(bay[1] * k, 0.5))]\n }\n const span: [number, number] = [bays[0] * bay[0], bays[1] * bay[1]]\n const slab = o.slabThickness ?? slabOf(Math.max(...bay))\n const beamHeight = o.beamHeight ?? Math.max(TOWER_DEFAULTS.beamHeight, round2(ceilTo(Math.max(...bay) / 14, 0.1)))\n const pitch = o.height + slab\n const total = storeys * pitch\n const tributary = bay[0] * bay[1]\n const load = COLUMN_SHARE * tributary * storeys * (o.superimposed + slab * 2500)\n const columnSize = o.columnSize ?? Math.max(TOWER_DEFAULTS.columnSize, round2(ceilTo(Math.sqrt(load / COLUMN_KG_M2), 0.1)))\n const plate: [number, number] = [round2(span[0] + columnSize + 0.2), round2(span[1] + columnSize + 0.2)]\n const mech = o.mechanicalEvery === false ? undefined : o.mechanicalEvery\n const relays = o.mechanical === false ? [] : mechanicalStoreys(storeys, o.mechanical === undefined ? mech : o.mechanical.every ?? mech)\n const mechanical = o.mechanical === false ? [] : [...relays, storeys - 1]\n\n let coreLayout: SkyscraperLayout['core'] = null\n let coreOptions: CoreOptions | false = false\n if (o.core !== false) {\n const given = o.core ?? {}\n // a wall thicker than a third of its height is a block, not a plate, to the engine: it would hold no vertical bars (and no pull)\n const maxWall = Math.floor((o.height / 3 - 0.05) * 20) / 20\n const wallThickness = given.wallThickness ?? Math.max(CORE_DEFAULTS.wallThickness, Math.min(maxWall, round2(ceilTo(total / WALL_SLENDER, 0.05))))\n const ti = given.innerThickness ?? CORE_DEFAULTS.innerThickness\n const shaft = given.shaft ?? CORE_DEFAULTS.shaft\n // the most elevators whose row of shafts fits between the beams on each side of the middle bay\n const fit = Math.max(1, Math.floor((bay[1] - 2 * CORE_CLEARANCE - 0.2 - 2 * wallThickness + ti) / (shaft + ti)))\n const probe = coreSize({ ...given, wallThickness, elevators: 2 })\n const wanted = given.elevators ?? Math.max(2, Math.ceil((o.coreRatio * plate[0] * plate[1] / probe[0] - 2 * wallThickness + ti) / (shaft + ti)))\n const elevators = Math.max(1, Math.min(wanted, fit))\n // what the ratio asks beyond the elevators the bay holds goes into the width: deeper cars and service space beside the shafts, as far as the bay allows\n const narrow = coreSize({ ...given, wallThickness, elevators })\n const room = bay[0] - columnSize - 2 * CORE_CLEARANCE - narrow[0]\n const extra = given.shaftDepth !== undefined ? 0 : Math.max(0, Math.min(room, (o.coreRatio * plate[0] * plate[1]) / narrow[1] - narrow[0]))\n // the middle bay in z has no row of columns; in x the core stands in the middle bay too, or in the first half bay when the count is even\n const xs = Array.from({ length: bays[0] + 1 }, (_, i) => -span[0] / 2 + i * bay[0])\n const middle = Math.floor(bays[0] / 2)\n const center: [number, number] = given.center ?? [bays[0] % 2 === 1 ? (xs[middle] + xs[middle + 1]) / 2 : xs[middle] + bay[0] / 2, 0]\n // a high-rise core is caged tighter than a house wall: 10 cm between bars, 7.5 cm above 50 storeys (the pull at the top of a tall core needs the steel)\n const rebar = { spacing: storeys > 50 ? 0.075 : 0.1, ...given.rebar }\n coreOptions = { ...given, wallThickness, elevators, center, rebar, shaftDepth: (given.shaftDepth ?? CORE_DEFAULTS.shaftDepth) + round2(extra) }\n const size = coreSize(coreOptions)\n coreLayout = { center, size, wallThickness, elevators, stairWidth: given.stairWidth ?? CORE_DEFAULTS.stairWidth, shaftDepth: coreOptions.shaftDepth! }\n }\n const damperOn = o.damperAbove !== false && total >= o.damperAbove && o.mechanical !== false\n const tower: TowerOptions = {\n floors: storeys, height: o.height, spanX: span[0], spanZ: span[1], columnsX: bays[0] + 1, columnsZ: bays[1] + 1, columnSize, beamHeight, slabThickness: slab,\n roofThickness: round2(slab + 0.1), columnCage: { ...TOWER_DEFAULTS.columnCage }, core: coreOptions,\n facade: o.facade === 'curtain' ? (o.curtain ?? {}) : false, punched: o.facade === 'punched' ? (o.punchedFacade ?? {}) : false,\n flatRoof: o.flatRoof ?? {}, mechanical: o.mechanical === false ? false : { every: o.mechanicalEvery === false ? undefined : mech, ...o.mechanical },\n damper: damperOn ? (o.damper ?? {}) : false, wind: o.wind === false ? false : o.wind, sizing: o.sizing ?? {},\n raft: true,\n }\n return {\n storeys, height: o.height, slab, pitch, total, bay, span, columnsX: bays[0] + 1, columnsZ: bays[1] + 1, columnSize, beamHeight, plate, core: coreLayout,\n coreRatio: coreLayout ? (coreLayout.size[0] * coreLayout.size[1]) / (plate[0] * plate[1]) : 0, facade: o.facade, mechanical, damper: damperOn, tower,\n }\n}\n\n/** Mass in kg of everything above the raft's top face in a spec, plus the raft itself. */\nconst totalMass = (spec: DestructibleSpec): number => {\n const byId = new Map(MATERIALS.map((m) => [m.id, m]))\n return spec.parts.reduce((sum, part) => sum + (part.mass ?? partMass(part, byId.get(part.material)!)), 0)\n}\n\n/**\n * Piles under the raft, by the load: a grid of `pitch` diameters over the raft, each as long as it needs to carry its share of the tower with the\n * NBR 6122 safety (`pileLength`); when that is longer than `maxLength` the grid is closed up and tried again, down to a pitch of 2.5 diameters.\n */\nexport function pilesFor(spec: DestructibleSpec, soil: string | SoilProfile, design: PileDesign = {}): PileSpec {\n const raft = spec.parts.find((p) => p.id === 'raft')\n if (!raft || raft.shape.kind !== 'box') throw new Error('Piles go under a raft: the spec has none')\n const d = { ...PILE_DEFAULTS, ...design }\n const [sx, sy, sz] = raft.shape.size\n const profile = profileOf(soil)\n const soils = new Map(SOILS.map((s) => [s.id, s]))\n const weight = totalMass(spec) * GRAVITY\n if (design.length !== undefined || design.count !== undefined) {\n const count = design.count ?? Math.max(4, Math.ceil((sx * sz) / (d.pitch * d.diameter) ** 2))\n const length = design.length ?? pileLength(profile, { load: weight / count, diameter: d.diameter, top: sy, method: d.method, maxLength: d.maxLength, soils })\n return { length, diameter: d.diameter, count, method: d.method }\n }\n let pitch: number = d.pitch\n for (;;) {\n const count = Math.max(4, Math.ceil(sx / (pitch * d.diameter)) * Math.ceil(sz / (pitch * d.diameter)))\n const length = pileLength(profile, { load: weight / count, diameter: d.diameter, top: sy, method: d.method, maxLength: d.maxLength, soils })\n if (length < d.maxLength || pitch <= 2.5) return { length, diameter: d.diameter, count, method: d.method }\n pitch = Math.max(2.5, pitch - 0.25)\n }\n}\n\n/** The tower of a layout: `buildTower` on a raft, then the soil and, with it, the deep piles sized by the load. */\nexport function buildSkyscraper(options: SkyscraperOptions = {}, preset: SkyscraperPreset = SKYSCRAPER_DEFAULTS): DestructibleSpec {\n const layout = skyscraperLayout(options, preset)\n const o = { ...SKYSCRAPER_DEFAULTS, ...preset, ...Object.fromEntries(Object.entries(options).filter(([, v]) => v !== undefined)) } as SkyscraperPreset\n const built = buildTower(layout.tower)\n const spec: DestructibleSpec = { ...built, name: 'skyscraper', tags: [...(built.tags ?? []), 'skyscraper'] }\n if (o.soil === false) return spec\n const parts: PartSpec[] = spec.parts.map((part) => {\n if (part.id !== 'raft') return part\n return o.piles === false ? { ...part, structure: { ...part.structure!, role: 'foundation' } } : { ...part, structure: { ...part.structure!, role: 'foundation', pile: pilesFor(spec, o.soil as string | SoilProfile, o.piles) } }\n })\n return { ...spec, parts, soil: o.soil }\n}\n","import type { DoorDef, FloorDef, RoomDef, WindowDef } from '@adatechnology/game-floorplan'\n\nimport type { SkyscraperLayout } from './skyscraper'\nimport enLocale from './locales/en.json'\nimport ptBrLocale from './locales/pt-BR.json'\n\n/**\n * The floor plan of a skyscraper at room level, shared by every typology: a central core (stairs, elevator shafts and a service shaft) inside a ring of\n * corridors, with the four strips of the perimeter left for the typology (office suites, apartments) to fill. The plate and the core come from the\n * same `SkyscraperLayout` as the structure (`buildSkyscraper`), so a room of the plan stands where the structure has its slab and its core. The plan is in\n * the space of `game-floorplan` (`u` to the right, `v` to the back, from the front-left corner); the structure is centred (`planToSpace`). Design\n * T10-estrutura-real.md §11.5.\n */\n\n/** `[u0, v0, u1, v1]`. */\nexport type PlateRect = [number, number, number, number]\n\nexport interface PlateOptions {\n /** Width of the corridors around the core (default 1.8 m). */\n corridor?: number\n /** Width of the elevator lobby beside the shafts (default 3 m). */\n lobby?: number\n /** Narrowest the stair room is made (default 3.4 m): the stairs need more than the tube's clear width. */\n stairWidth?: number\n}\n\nexport const PLATE_DEFAULTS = { corridor: 1.8, lobby: 3, stairWidth: 3.4 } as const\n\nexport type StripId = 'south' | 'north' | 'west' | 'east'\n\n/** One of the four bands of the perimeter, where the typology puts its rooms. */\nexport interface PlateStrip {\n id: StripId\n /** Side of the building the outer edge is on, as `game-floorplan` names it. */\n side: 'front' | 'back' | 'left' | 'right'\n rect: PlateRect\n /** The strip runs along `u` (south and north) or along `v` (west and east). */\n alongU: boolean\n /** Length along the perimeter and depth from the outer wall to the circulation, metres. */\n length: number\n depth: number\n /** Id (without the storey suffix) of the circulation room the inner edge touches: `corridor_s`, `corridor_n`, `corridor_w` or `lobby`. */\n circulation: string\n}\n\nexport interface TowerPlate {\n w: number\n d: number\n core: PlateRect\n stairs: PlateRect\n service: PlateRect | null\n shafts: PlateRect[]\n lobby: PlateRect\n corridors: { s: PlateRect; n: PlateRect; w: PlateRect }\n strips: PlateStrip[]\n}\n\nconst r2 = (v: number): number => Math.round(v * 100) / 100\n\n/** The plate of a layout: where the core, its rooms, the circulation and the four strips stand. */\nexport function towerPlate(layout: SkyscraperLayout, options: PlateOptions = {}): TowerPlate {\n const o = { ...PLATE_DEFAULTS, ...options }\n const [w, d] = layout.plate\n const core = layout.core\n if (!core) throw new Error('A tower plan needs a core (turn the core on)')\n const t = core.wallThickness\n const [W, L] = core.size\n const u = w / 2 + core.center[0], v = d / 2 + core.center[1]\n const rect: PlateRect = [r2(u - W / 2), r2(v - L / 2), r2(u + W / 2), r2(v + L / 2)]\n const [x0, z0, x1, z1] = rect\n const split = r2(Math.min(x1 - 1.8, x0 + Math.max(o.stairWidth, t + core.stairWidth + 0.1)))\n const stairEnd = r2(z0 + Math.min(L, Math.max(5.4, 2 * t + 4.8)))\n const merged = z1 - stairEnd < 1.6\n const stairs: PlateRect = [x0, z0, split, merged ? z1 : stairEnd]\n const service: PlateRect | null = merged ? null : [x0, stairEnd, split, z1]\n const n = core.elevators\n const shafts = Array.from({ length: n }, (_, k): PlateRect => [split, r2(z0 + (k * L) / n), x1, r2(z0 + ((k + 1) * L) / n)])\n const lobby: PlateRect = [x1, z0, r2(x1 + o.lobby), z1]\n const west: PlateRect = [r2(x0 - o.corridor), z0, x0, z1]\n const south: PlateRect = [0, r2(z0 - o.corridor), w, z0]\n const north: PlateRect = [0, z1, w, r2(z1 + o.corridor)]\n const strip = (id: StripId, side: PlateStrip['side'], r: PlateRect, alongU: boolean, circulation: string): PlateStrip => ({\n id, side, rect: r, alongU, length: r2(alongU ? r[2] - r[0] : r[3] - r[1]), depth: r2(alongU ? r[3] - r[1] : r[2] - r[0]), circulation,\n })\n return {\n w, d, core: rect, stairs, service, shafts, lobby, corridors: { s: south, n: north, w: west },\n strips: [\n strip('south', 'front', [0, 0, w, south[1]], true, 'corridor_s'),\n strip('north', 'back', [0, north[3], w, d], true, 'corridor_n'),\n strip('west', 'left', [0, z0, west[0], z1], false, 'corridor_w'),\n strip('east', 'right', [lobby[2], z0, w, z1], false, 'lobby'),\n ],\n }\n}\n\n/** A point of the plan (`u`, `v`) in the space of the structure (centred on the plate, `x` right, `z` back). */\nexport const planToSpace = (layout: SkyscraperLayout, [u, v]: [number, number]): [number, number] => [r2(u - layout.plate[0] / 2), r2(v - layout.plate[1] / 2)]\n\nexport type StoreyKind = 'ground' | 'typical' | 'mechanical'\n\n/** What kind each storey is: the first is the ground floor, the mechanical ones are the plant floors of the layout, the rest are typical. */\nexport const storeyKinds = (layout: SkyscraperLayout): StoreyKind[] =>\n Array.from({ length: layout.storeys }, (_, f) => (f === 0 ? 'ground' : layout.mechanical.includes(f) ? 'mechanical' : 'typical'))\n\nexport interface StoreyContext {\n floor: number\n kind: StoreyKind\n layout: SkyscraperLayout\n plate: TowerPlate\n /** Floor to floor, metres: the ceiling of the plan floor. */\n ceiling: number\n}\n\nexport interface StripFill {\n rooms: RoomDef[]\n doors: DoorDef[]\n windows: WindowDef[]\n}\n\n/** Fills one strip of a storey with rooms. Room ids must be unique in the whole tower: end them with the storey (`_${floor}`). */\nexport type StripFiller = (strip: PlateStrip, storey: StoreyContext) => StripFill\n\nexport interface TowerPlanOptions extends PlateOptions {\n /** The perimeter of the typical storeys. */\n typical: StripFiller\n /** The ground floor (default: the typical filler). */\n ground?: StripFiller\n /** The plant floors (default: one plant room per strip, no windows). */\n mechanical?: StripFiller\n}\n\n/** Cuts a strip into `count` equal parts along its length. */\nexport const splitStrip = (strip: PlateStrip, count: number): PlateRect[] => {\n const [u0, v0, u1, v1] = strip.rect\n return Array.from({ length: Math.max(1, count) }, (_, k): PlateRect => {\n const a = k / Math.max(1, count), b = (k + 1) / Math.max(1, count)\n return strip.alongU ? [r2(u0 + (u1 - u0) * a), v0, r2(u0 + (u1 - u0) * b), v1] : [u0, r2(v0 + (v1 - v0) * a), u1, r2(v0 + (v1 - v0) * b)]\n })\n}\n\nconst EDGE = 1e-6\n\n/**\n * Windows on every outside wall of a room of the plate, `spacing` metres apart (at least one a wall); `y0`, `y1` the sill and head (default 0.3 and the\n * ceiling less 0.5 m, a glass facade).\n */\nexport function exteriorWindows(id: string, rect: PlateRect, plate: TowerPlate, ceiling: number, o: { spacing?: number; width?: number; y0?: number; y1?: number } = {}): WindowDef[] {\n const [u0, v0, u1, v1] = rect\n const spacing = o.spacing ?? 3\n const out: WindowDef[] = []\n const add = (side: string, length: number) => {\n const n = Math.max(1, Math.round(length / spacing))\n out.push({ room: id, side, n, width: Math.min(o.width ?? 2.4, (length / n) * 0.8), y0: o.y0 ?? 0.3, y1: o.y1 ?? r2(ceiling - 0.5) })\n }\n if (Math.abs(v0) < EDGE) add('front', u1 - u0)\n if (Math.abs(v1 - plate.d) < EDGE) add('back', u1 - u0)\n if (Math.abs(u0) < EDGE) add('left', v1 - v0)\n if (Math.abs(u1 - plate.w) < EDGE) add('right', v1 - v0)\n return out\n}\n\n/** The door from a room of a strip to the circulation it touches. */\nexport const stripDoor = (id: string, strip: PlateStrip, floor: number, width = 1): DoorDef => ({ a: id, b: `${strip.circulation}_${floor}`, width, opensTo: id })\n\n/** The default fill of a plant floor: a plant room on each strip, with a door to the circulation and no windows (the facade has louvres there). */\nconst plantRooms: StripFiller = (strip, { floor }) => {\n const id = `plant_${floor}_${strip.id}`\n return { rooms: [{ id, type: 'storage', label: 'plant_room', rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor, 1.2)], windows: [] }\n}\n\n/** The core and the circulation of a storey: the stairs, the shafts, the service shaft, the lobby and the three corridors, with their doors. */\nfunction coreRooms(plate: TowerPlate, floor: number, storeys: number): { rooms: RoomDef[]; doors: DoorDef[]; openPairs: [string, string][] } {\n const id = (name: string) => `${name}_${floor}`\n const link = floor < storeys - 1 ? [floor, floor + 1] : [floor - 1, floor]\n const rooms: RoomDef[] = [\n { id: id('stairs'), type: 'stairs', label: 'stairs', rect: [...plate.stairs], link },\n ...(plate.service ? [{ id: id('service'), type: 'storage', label: 'service_shaft', rect: [...plate.service] }] : []),\n ...plate.shafts.map((rect, k): RoomDef => ({ id: id(`elevator_${k}`), type: 'elevator', label: 'elevator', rect: [...rect] })),\n { id: id('lobby'), type: 'hall', label: 'elevator_lobby', rect: [...plate.lobby] },\n { id: id('corridor_w'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.w] },\n { id: id('corridor_s'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.s] },\n { id: id('corridor_n'), type: 'corridor', label: 'corridor', rect: [...plate.corridors.n] },\n ]\n const doors: DoorDef[] = [\n { a: id('stairs'), b: id('corridor_w'), width: 1, opensTo: id('corridor_w') },\n ...(plate.service ? [{ a: id('service'), b: id('corridor_w'), width: 0.8, opensTo: id('service') }] : []),\n ...plate.shafts.map((_, k): DoorDef => ({ a: id(`elevator_${k}`), b: id('lobby'), width: 1.2, opensTo: id('lobby') })),\n ]\n const openPairs: [string, string][] = [[id('lobby'), id('corridor_s')], [id('lobby'), id('corridor_n')], [id('corridor_w'), id('corridor_s')], [id('corridor_w'), id('corridor_n')]]\n return { rooms, doors, openPairs }\n}\n\n/**\n * The storeys of a tower as `FloorDef`s for `TemplateDef.floorsFn`: each has the core and the circulation, the strips filled by the typology for its\n * kind of storey (ground, typical, plant), `ceiling` the storey pitch of the structure. The template's size must be the plate (`layout.plate`).\n */\nexport function towerFloors(layout: SkyscraperLayout, plan: TowerPlanOptions): FloorDef[] {\n const plate = towerPlate(layout, plan)\n const fillers: Record<StoreyKind, StripFiller> = { ground: plan.ground ?? plan.typical, typical: plan.typical, mechanical: plan.mechanical ?? plantRooms }\n return storeyKinds(layout).map((kind, floor): FloorDef => {\n const context: StoreyContext = { floor, kind, layout, plate, ceiling: layout.pitch }\n const fills = plate.strips.map((strip) => fillers[kind](strip, context))\n const core = coreRooms(plate, floor, layout.storeys)\n return {\n label: kind === 'ground' ? 'ground_floor' : kind === 'mechanical' ? 'mechanical_floor' : 'typical_floor',\n ceiling: layout.pitch,\n openPairs: core.openPairs,\n rooms: () => [...core.rooms, ...fills.flatMap((f) => f.rooms)],\n doors: () => [...core.doors, ...fills.flatMap((f) => f.doors)],\n windows: () => fills.flatMap((f) => f.windows),\n }\n })\n}\n\n/** The names of the rooms and storeys the plan helpers make (`elevator_lobby`, `plant_room`, `typical_floor`...), for the packs that fill the strips to register with `engine.registerLocale`. */\nexport const towerLocales = { en: { labels: enLocale.labels }, 'pt-BR': { labels: ptBrLocale.labels } } as const\n","export const version = '0.1.0'\n\nexport { register } from './register'\nexport type { StructuredResult, StructurePackOptions } from './register'\nexport { buildStructure } from './structure'\nexport { MEMBER_CAGE, PILE_AREA, cageResidualCapacity, RAFT_THICKNESS, REBAR_RATIOS, toDestructibleSpec } from './to-destructible-spec'\nexport type { DestructibleSpecOptions } from './to-destructible-spec'\nexport { SLAB_PANEL_DEFAULTS, applySlabPanels, beamDepthFor, beamSpan, resolveSlabPanels, slabPanelView, slabPanelsOf } from './slab-panels'\nexport type { SlabPanelOptions } from './slab-panels'\nexport { WALL_PILLAR_SIDE, WALL_PILLAR_SPACING, pillarStations } from './structure/wall-pillars'\nexport { GROUND_BEAM_DEPTH } from './structure/ground-beams'\nexport { SILL_BEAM_DEPTH } from './wall-detail/panels'\nexport { TANK_PILLAR_SIDE } from './water-tank'\nexport { BEAM_DEPTH_RATIO, MAX_LINTEL_ON_MASONRY, MAX_PILLAR_SPACING, MIN_BEAM_WIDTH, MIN_PILLAR_AREA, MIN_PILLAR_SIDE, STRUCTURAL_VIOLATION, countViolations, validateSpec, validateStructure } from './validate'\nexport type { StructuralViolation, StructuralViolationCode, ValidateStructureOptions } from './validate'\nexport { buildWallSpecimen } from './wall-specimen'\nexport type { WallSpecimenOptions } from './wall-specimen'\nexport { planWaterTank } from './water-tank'\nexport type { TankPlanOptions } from './water-tank'\nexport {\n CONSTRUCTION_SYSTEMS, CONSTRUCTIONS, ROOF_COVERINGS, registerConstruction, registerConstructionSystem, registerRoofCovering,\n} from './registry'\nexport type { ConstructionBuild, ConstructionBuilder, ConstructionSystemDef, RoofCoveringDef } from './registry'\nexport { campConstruction, chaletConstruction, constructionOfSystem, logCabinConstruction, masonryConstruction, shackConstruction, woodFrameConstruction } from './presets'\nexport type { ChaletOptions, ShackOptions, WoodFrameOptions } from './presets'\nexport { structureLayer } from './viewer-layer'\nexport { DENSITY } from './density'\nexport { GROUND } from './types'\nexport type * from './types'\nexport {\n CORE_DEFAULTS, CURTAIN_DEFAULTS, DAMPER_DEFAULTS, FLAT_ROOF_DEFAULTS, MECHANICAL_DEFAULTS, TOWER_DEFAULTS, addCore, addCurtainWall, addFlatRoof, addMechanicalFloor,\n addTunedMassDamper, buildTower, coreSize, damperMass, towerWater, windExposureOf,\n PUNCHED_DEFAULTS, addPunchedFacade, mechanicalStoreys,\n} from './tower'\nexport type { CoreOptions, CurtainWallOptions, DamperOptions, FlatRoofOptions, MechanicalFloorOptions, PunchedFacadeOptions, TowerGeometry, TowerMechanicalOptions, TowerOptions } from './tower'\nexport { PILE_DEFAULTS, SKYSCRAPER_DEFAULTS, SKYSCRAPER_MAX_STOREYS, buildSkyscraper, pilesFor, skyscraperLayout } from './skyscraper'\nexport type { PileDesign, SkyscraperLayout, SkyscraperOptions, SkyscraperPreset } from './skyscraper'\nexport { PLATE_DEFAULTS, exteriorWindows, planToSpace, splitStrip, storeyKinds, stripDoor, towerFloors, towerLocales, towerPlate } from './skyscraper-plan'\nexport type { PlateOptions, PlateRect, PlateStrip, StoreyContext, StoreyKind, StripFill, StripFiller, StripId, TowerPlanOptions, TowerPlate } from './skyscraper-plan'\nexport type * from './utilities/types'\nexport type { Utilities } from './utilities'\nexport type { Electrical, EnergyConfig, EnergyMode } from './utilities/electrical'\nexport type { Gas, GasMeter } from './utilities/gas'\n"],"mappings":"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","names":["onSoil","box","box","centre","box","at","centre","at","box","acrossOf","box","box","at","item","flight","TOLERANCE","alongRange","box","box","part","box","entry","entry","round2","round2","round2","round2","centre","round2","distance","box","absolute","round2","centre","round2","box","DOOR_HEIGHT","round2","box","distance","clamp","centre","distance","at","best","runsOf","EPS","at","box","runsOf","opening","at","box","LINTEL_DEPTH","LINTEL_BEARING","roleOf","opening","overlaps","box","carries","raft","alongOf","getAssembly","TOLERANCE","lineOf","getAssembly","pointOf","at","carries","TOLERANCE","LINTEL_DEPTH","opening","lineOf","EPSILON","assemblyPart","getAssembly","DOOR_WIDTH","opening","getAssembly","assemblyPart","MATERIALS","partMass","raft","at","centre","addFlatRoof","GRAVITY","MATERIALS","SOILS","partMass","pileLength","profileOf","ceilTo","round2","GRAVITY","total","given","MATERIALS","partMass","raft","profileOf","SOILS","pileLength","merged"]}
|