Spaces:
Sleeping
Sleeping
Download scripts/import_legacy_data.mjs from gui-sparim/mp_tpu_TESTES: direct link, hf CLI and curl.
- Browser
- Download file 10.8 kB
-
https://huggingface.co/spaces/gui-sparim/mp_tpu_TESTES/resolve/main/scripts/import_legacy_data.mjs
- Command line
-
hf download hf://spaces/gui-sparim/mp_tpu_TESTES/scripts/import_legacy_data.mjs
-
curl -L -o import_legacy_data.mjs https://huggingface.co/spaces/gui-sparim/mp_tpu_TESTES/resolve/main/scripts/import_legacy_data.mjs
10.8 kB
| import fs from "node:fs"; | |
| import path from "node:path"; | |
| import vm from "node:vm"; | |
| import { fileURLToPath } from "node:url"; | |
| const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); | |
| const html = fs.readFileSync(path.join(root, "index.html"), "utf8"); | |
| function expression(name, pattern) { | |
| const match = html.match(pattern); | |
| if (!match) throw new Error(`Não foi possível extrair ${name}.`); | |
| return vm.runInNewContext(`(${match[1]})`); | |
| } | |
| const savedDefault = expression("savedDefault", /const savedDefault=(\[[^\n]+\]);/); | |
| const areaById = expression("areaById", /const areaById=({[^\n]+});/); | |
| const savedPinPositions = expression("savedPinPositions", /const savedPinPositions=({[^\n]+});/); | |
| const upperDefault = expression("upperDefault", /const upperDefault=(\(\(\)=>\{[\s\S]*?\}\)\(\));/); | |
| const accessoryLinks = expression("TPU_ACCESSORY_LINKS", /const TPU_ACCESSORY_LINKS=({[^\n]+});/); | |
| const baseLinks = expression("TPU_BASE_LINKS", /const TPU_BASE_LINKS=({[^\n]+});/); | |
| const requiredStores = expression("REQUIRED_ACCESSORY_STORES", /const REQUIRED_ACCESSORY_STORES=(\[[\s\S]*?\n\]);/); | |
| const requiredTpus = expression("REQUIRED_TPUS", /const REQUIRED_TPUS=(\[[^\n]+\]);/); | |
| const context = { window: {} }; | |
| vm.createContext(context); | |
| vm.runInContext(fs.readFileSync(path.join(root, "tpu_mpc_v4_data.js"), "utf8"), context); | |
| vm.runInContext(fs.readFileSync(path.join(root, "tpu_area_details.js"), "utf8"), context); | |
| const imported = context.window.MP_IMPORTED_TPUS; | |
| const details = context.window.MP_TPU_DETAILS.byId; | |
| const quadrantNames = { | |
| 74: "DEP 6 (I)", 103: "BOX 1 (IV)", 120: "DEP (II)", | |
| 135: "DEP 2 (III)", 136: "DEP 3 (III)", 137: "DEP 4 (III)", | |
| 138: "DEP 5 (III)", 139: "DEP 1 (III)", | |
| }; | |
| function spaceType(name) { | |
| const normalized = String(name).normalize("NFD").replace(/[\u0300-\u036f]/g, "").toUpperCase(); | |
| const number = normalized.match(/^(?:LOJ|LOJA|LJ)\s*0*(\d+)/); | |
| if (number && ["16", "18", "20"].includes(String(Number(number[1])))) return "SUBSTACAO"; | |
| if (normalized.startsWith("LOJ")) return "LOJ"; | |
| if (normalized.startsWith("BC")) return "BC"; | |
| if (normalized.startsWith("BP")) return "BP"; | |
| if (normalized.startsWith("AM") || normalized.startsWith("MI")) return "AM"; | |
| if (normalized.startsWith("PATIO")) return "PATIO"; | |
| if (normalized.startsWith("BOX")) return "BOX"; | |
| if (normalized.startsWith("DEP")) return "DEP"; | |
| if (normalized.startsWith("LED")) return "LED"; | |
| if (normalized.startsWith("REST")) return "REST"; | |
| if (normalized.startsWith("CON")) return "CON"; | |
| return "OUTRO"; | |
| } | |
| const types = [ | |
| ["LOJ", "Loja", "#F6D5C5", 1], ["BC", "Banca", "#CDE8D6", 1], | |
| ["BP", "Banca do peixe", "#DCD5F2", 1], ["AM", "Área de mesa", "#F7E7B8", .85], | |
| ["PATIO", "Pátio", "#CFE3F4", 1], ["BOX", "Box", "#F4C7C3", 1], | |
| ["DEP", "Depósito", "#D7E1EA", .75], ["LED", "Painel LED", "#FFE08A", 1], | |
| ["REST", "Restaurante", "#F3D3E0", 1], ["CON", "Concessão", "#CDEBE7", 1], | |
| ["SUBSTACAO", "Subestação", "#D9D2E9", 1], ["OUTRO", "Outro", "#FFFFFF", 1], | |
| ].map(([code, label, color, coefficient]) => ({ code, label, color, coefficient })); | |
| function normalizeSpace(raw, floorId) { | |
| const corrected = floorId === "ground" | |
| ? (quadrantNames[Number(raw.id)] || (Number(raw.id) === 145 && raw.name.trim().toUpperCase() === "AM PIII-1" ? "AM PIII-2" : raw.name)) | |
| : raw.name; | |
| const pin = floorId === "ground" ? savedPinPositions[raw.id] : null; | |
| const x = Number.isFinite(Number(raw.pinX)) ? Number(raw.pinX) : pin?.[0] ?? ((raw.col - 1 + raw.width / 2) / 42); | |
| const y = Number.isFinite(Number(raw.pinY)) ? Number(raw.pinY) : pin?.[1] ?? ((raw.row - 1 + raw.height / 2) / 43); | |
| return { | |
| id: `${floorId}:${raw.id}`, | |
| legacy_id: Number(raw.id), | |
| floor_id: floorId, | |
| name: corrected, | |
| type: spaceType(corrected), | |
| base_area_m2: Number((floorId === "ground" ? areaById[raw.id] : raw.area) || 0), | |
| position: { x: Number(x.toFixed(7)), y: Number(y.toFixed(7)) }, | |
| grid: { col: Number(raw.col), row: Number(raw.row), width: Number(raw.width), height: Number(raw.height) }, | |
| components: { mezzanine: 0, deposit: 0, deck: 0, table: 0 }, | |
| }; | |
| } | |
| const groundById = new Map(savedDefault.map(item => [Number(item.id), item])); | |
| for (const item of requiredStores) if (!groundById.has(Number(item.id))) groundById.set(Number(item.id), item); | |
| const spaces = [ | |
| ...[...groundById.values()].map(item => normalizeSpace(item, "ground")), | |
| ...upperDefault.map(item => normalizeSpace(item, "upper")), | |
| ]; | |
| function splitBoxes(items) { | |
| const combined = items.find(t => Number(t.id) === 400115); | |
| if (!combined) return items; | |
| const boxes = [103, 147, 148, 149, 150, 151, 152, 153]; | |
| const deposits = [154, 155, 156, 157, 158, 159, 160, 161]; | |
| const tables = [162, 163, 164, 165, 166, 167, 168, 169]; | |
| const ids = [400115, 400129, 400130, 400131, 400132, 400133, 400134, 400135]; | |
| const replacements = ids.map((id, index) => ({ | |
| ...combined, | |
| id, | |
| name: `TPU_BOX_${index + 1}_IV`, | |
| storeIds: [boxes[index], deposits[index], tables[index]], | |
| baseStoreIds: [boxes[index]], | |
| accessoryStoreIds: [deposits[index], tables[index]], | |
| linkedFloor: null, | |
| linkedStoreIds: [], | |
| allocationRefs: [{ floor: "ground", id: boxes[index] }], | |
| sourceOrder: String(112 + index), sourceGrossArea: 19.62, | |
| sourceUnitAreas: [9.52], sourceMezzanine: 0, sourceDeposit: 7.4, | |
| sourceDeck: 0, sourceTableArea: 2.7, sourceWeightedArea: 17.365, | |
| sourceArea: 17.365, | |
| })); | |
| return items.filter(t => Number(t.id) !== 400115).concat(replacements); | |
| } | |
| const rawByFloor = { | |
| ground: splitBoxes(imported.ground).concat(requiredTpus), | |
| upper: imported.upper, | |
| }; | |
| const tpuMap = new Map(); | |
| for (const [floorId, items] of Object.entries(rawByFloor)) { | |
| for (const raw of items) { | |
| const merged = { ...(details[String(raw.id)] || {}), ...raw }; | |
| let target = tpuMap.get(String(raw.id)); | |
| if (!target) { | |
| const source = {}; | |
| for (const [key, value] of Object.entries(merged)) { | |
| if (key.startsWith("source")) source[key.slice(6, 7).toLowerCase() + key.slice(7)] = value; | |
| } | |
| source.allocationRefs = (merged.allocationRefs || []).map(ref => `${ref.floor}:${ref.id}`); | |
| target = { | |
| id: String(raw.id), legacy_id: Number(raw.id), name: raw.name, | |
| color: raw.color || "#5B8DB8", members: [], source, | |
| visual_links: [], | |
| }; | |
| tpuMap.set(String(raw.id), target); | |
| } | |
| const accessories = new Set(merged.accessoryStoreIds || (floorId === "ground" ? accessoryLinks[raw.id] || [] : [])); | |
| const bases = new Set(merged.baseStoreIds || [ | |
| ...(raw.storeIds || []).filter(id => !accessories.has(id)), | |
| ...(floorId === "ground" ? baseLinks[raw.id] || [] : []), | |
| ]); | |
| const localIds = new Set([...bases, ...accessories, ...(raw.storeIds || [])]); | |
| for (const id of localIds) { | |
| const member = { space_id: `${floorId}:${id}`, role: accessories.has(id) ? "accessory" : "base" }; | |
| if (!target.members.some(item => item.space_id === member.space_id)) target.members.push(member); | |
| } | |
| if (raw.linkedFloor) { | |
| for (const id of raw.linkedStoreIds || []) { | |
| const spaceId = `${raw.linkedFloor}:${id}`; | |
| if (!target.members.some(item => item.space_id === spaceId)) target.members.push({ space_id: spaceId, role: "base" }); | |
| } | |
| } | |
| } | |
| } | |
| const document = { | |
| schema_version: 1, | |
| revision: 0, | |
| updated_at: new Date().toISOString(), | |
| floors: [ | |
| { id: "ground", name: "Térreo", image: "/plants/planta_terreo_mercado_publico.png", width: 1200, height: 1189, order: 1 }, | |
| { id: "upper", name: "2º pavimento", image: "/plants/planta_segundo_pavimento_mercado_publico.png", width: 1200, height: 1184, order: 2 }, | |
| ], | |
| space_types: types, | |
| component_types: [ | |
| { code: "mezzanine", label: "Mezanino", coefficient: .75 }, | |
| { code: "deposit", label: "Depósito", coefficient: .75 }, | |
| { code: "deck", label: "Deck", coefficient: .30 }, | |
| { code: "table", label: "Área de mesa", coefficient: .85 }, | |
| ], | |
| spaces, | |
| tpus: [...tpuMap.values()], | |
| settings: { active_floor: "ground", show_tpu_links: true }, | |
| }; | |
| const spacesById = new Map(document.spaces.map(space => [space.id, space])); | |
| for (const tpu of document.tpus) { | |
| const refs = tpu.source.allocationRefs || []; | |
| if (!refs.length) continue; | |
| const units = (tpu.source.unitAreas || []).map(Number).filter(value => value > 0); | |
| let bases; | |
| if (units.length === refs.length) { | |
| bases = units; | |
| } else if (refs.length === 1) { | |
| bases = [units.reduce((sum, value) => sum + value, 0) || spacesById.get(refs[0])?.base_area_m2 || 0]; | |
| } else { | |
| const mapped = refs.map(ref => spacesById.get(ref)?.base_area_m2 || 0); | |
| const mappedTotal = mapped.reduce((sum, value) => sum + value, 0); | |
| const unitTotal = units.reduce((sum, value) => sum + value, 0); | |
| bases = mapped.map(value => mappedTotal ? unitTotal * value / mappedTotal : unitTotal / refs.length); | |
| } | |
| const memberSpaces = tpu.members.map(member => ({ ...member, space: spacesById.get(member.space_id) })).filter(item => item.space); | |
| const depositAccessories = memberSpaces.filter(item => item.role === "accessory" && item.space.type === "DEP"); | |
| const tableAccessories = memberSpaces.filter(item => item.role === "accessory" && item.space.type === "AM"); | |
| const hasDepositAccessory = depositAccessories.length > 0; | |
| const hasTableAccessory = tableAccessories.length > 0; | |
| for (const item of depositAccessories) { | |
| item.space.base_area_m2 = Number((Number(tpu.source.deposit || 0) / depositAccessories.length).toFixed(4)); | |
| item.space.components = { mezzanine: 0, deposit: 0, deck: 0, table: 0 }; | |
| } | |
| for (const item of tableAccessories) { | |
| item.space.base_area_m2 = Number((Number(tpu.source.tableArea || 0) / tableAccessories.length).toFixed(4)); | |
| item.space.components = { mezzanine: 0, deposit: 0, deck: 0, table: 0 }; | |
| } | |
| const baseTotal = bases.reduce((sum, value) => sum + value, 0) || refs.length; | |
| refs.forEach((ref, index) => { | |
| const space = spacesById.get(ref); | |
| if (!space) return; | |
| const share = baseTotal ? bases[index] / baseTotal : 1 / refs.length; | |
| space.base_area_m2 = Number((bases[index] || 0).toFixed(4)); | |
| space.components = { | |
| mezzanine: Number((Number(tpu.source.mezzanine || 0) * share).toFixed(4)), | |
| deposit: hasDepositAccessory ? 0 : Number((Number(tpu.source.deposit || 0) * share).toFixed(4)), | |
| deck: Number((Number(tpu.source.deck || 0) * share).toFixed(4)), | |
| table: hasTableAccessory ? 0 : Number((Number(tpu.source.tableArea || 0) * share).toFixed(4)), | |
| }; | |
| }); | |
| } | |
| const output = path.join(root, "seed", "default.json"); | |
| fs.writeFileSync(output, `${JSON.stringify(document, null, 2)}\n`); | |
| console.log(`Seed criado: ${spaces.length} espaços, ${document.tpus.length} TPUs.`); | |