iobroker.proscenic 0.3.0 → 0.4.0
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/build/domain/live-map.js +58 -8
- package/build/domain/live-map.js.map +2 -2
- package/build/domain/zone-cleaning.js +10 -0
- package/build/domain/zone-cleaning.js.map +2 -2
- package/build/main.js +85 -3
- package/build/main.js.map +2 -2
- package/build/objects/projector.js +2 -1
- package/build/objects/projector.js.map +2 -2
- package/io-package.json +14 -1
- package/package.json +1 -1
- package/www/map-viewer/index.html +6 -2
- package/www/map-viewer/viewer.css +11 -0
- package/www/map-viewer/viewer.js +150 -19
package/build/domain/live-map.js
CHANGED
|
@@ -84,7 +84,8 @@ function transitionLiveMapTaskState(state, mode, cleaningActivityActive) {
|
|
|
84
84
|
if (mode === "sweep") {
|
|
85
85
|
return {
|
|
86
86
|
state: { dockedSinceLastCleaning: false, returningToDock: false, cleaningTaskActive: true },
|
|
87
|
-
resetTrail: state.dockedSinceLastCleaning
|
|
87
|
+
resetTrail: state.dockedSinceLastCleaning,
|
|
88
|
+
completedTask: false
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
if (mode === "backcharge") {
|
|
@@ -94,18 +95,20 @@ function transitionLiveMapTaskState(state, mode, cleaningActivityActive) {
|
|
|
94
95
|
returningToDock: true,
|
|
95
96
|
cleaningTaskActive: state.cleaningTaskActive
|
|
96
97
|
},
|
|
97
|
-
resetTrail: false
|
|
98
|
+
resetTrail: false,
|
|
99
|
+
completedTask: false
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
102
|
if (mode === "charge" || mode === "fullcharge") {
|
|
101
103
|
if (state.returningToDock || !state.cleaningTaskActive && !cleaningActivityActive) {
|
|
102
104
|
return {
|
|
103
105
|
state: { dockedSinceLastCleaning: true, returningToDock: false, cleaningTaskActive: false },
|
|
104
|
-
resetTrail: false
|
|
106
|
+
resetTrail: false,
|
|
107
|
+
completedTask: state.cleaningTaskActive
|
|
105
108
|
};
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
|
-
return { state, resetTrail: false };
|
|
111
|
+
return { state, resetTrail: false, completedTask: false };
|
|
109
112
|
}
|
|
110
113
|
function renderLiveMapImage20002(data, poses = [], options = {}) {
|
|
111
114
|
var _a, _b, _c, _d;
|
|
@@ -141,7 +144,15 @@ function renderLiveMapImage20002(data, poses = [], options = {}) {
|
|
|
141
144
|
}
|
|
142
145
|
const fallbackPng = encodeRgbPng(sample.width, sample.height, fallbackPixels);
|
|
143
146
|
const pngDataUrl = `data:image/png;base64,${fallbackPng.toString("base64")}`;
|
|
144
|
-
const
|
|
147
|
+
const areas = summarizeRenderedAreas(sample);
|
|
148
|
+
const svg = renderLiveMapSvg(
|
|
149
|
+
sample.width,
|
|
150
|
+
sample.height,
|
|
151
|
+
basePng,
|
|
152
|
+
runtime,
|
|
153
|
+
options.animateRobot !== false,
|
|
154
|
+
options.showZoneOverlays !== false ? areas : []
|
|
155
|
+
);
|
|
145
156
|
const svgDataUrl = `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`;
|
|
146
157
|
if (Buffer.byteLength(svgDataUrl, "utf8") > MAX_LIVE_MAP_DATA_URL_BYTES || Buffer.byteLength(pngDataUrl, "utf8") > MAX_LIVE_MAP_DATA_URL_BYTES) {
|
|
147
158
|
return void 0;
|
|
@@ -153,7 +164,7 @@ function renderLiveMapImage20002(data, poses = [], options = {}) {
|
|
|
153
164
|
format: "svg",
|
|
154
165
|
width: sample.width,
|
|
155
166
|
height: sample.height,
|
|
156
|
-
areas
|
|
167
|
+
areas,
|
|
157
168
|
poseCount: runtime.projectedPoseCount,
|
|
158
169
|
rawPoseCount: poses.length,
|
|
159
170
|
pathLineSegments: runtime.pathLineSegments,
|
|
@@ -393,16 +404,31 @@ function drawRobotMarker(pixels, width, height, pose) {
|
|
|
393
404
|
const endY = Math.round(pose.point[1] - Math.sin(angle) * headingLength);
|
|
394
405
|
drawLine(pixels, width, height, pose.point[0], pose.point[1], endX, endY, COLOR_HEADING);
|
|
395
406
|
}
|
|
396
|
-
function renderLiveMapSvg(width, height, basePng, runtime, animateRobot) {
|
|
407
|
+
function renderLiveMapSvg(width, height, basePng, runtime, animateRobot, areas) {
|
|
397
408
|
const marker = runtime.latest ? renderSvgRobotMarker(runtime.latest, runtime.latestMotionPath, animateRobot) : "";
|
|
409
|
+
const zoneLabels = renderSvgZoneLabels(areas);
|
|
398
410
|
const embeddedPng = `data:image/png;base64,${basePng.toString("base64")}`;
|
|
399
411
|
return [
|
|
400
412
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" preserveAspectRatio="xMidYMid meet">`,
|
|
401
413
|
`<image href="${embeddedPng}" width="${width}" height="${height}"/>`,
|
|
414
|
+
zoneLabels,
|
|
402
415
|
marker,
|
|
403
416
|
"</svg>"
|
|
404
417
|
].join("");
|
|
405
418
|
}
|
|
419
|
+
function renderSvgZoneLabels(areas) {
|
|
420
|
+
return areas.filter(
|
|
421
|
+
(area) => area.kind === "zone" && area.label !== void 0 && area.bounds !== void 0
|
|
422
|
+
).map((area) => {
|
|
423
|
+
var _a, _b, _c, _d;
|
|
424
|
+
const x = (_b = (_a = area.center) == null ? void 0 : _a.x) != null ? _b : (area.bounds.minX + area.bounds.maxX) / 2;
|
|
425
|
+
const y = (_d = (_c = area.center) == null ? void 0 : _c.y) != null ? _d : (area.bounds.minY + area.bounds.maxY) / 2;
|
|
426
|
+
return `<text data-zone-label="true" x="${roundSvgNumber(x)}" y="${roundSvgNumber(y)}" text-anchor="middle" dominant-baseline="middle" font-family="system-ui, sans-serif" font-size="9" font-weight="600" fill="#263b4a" stroke="#ffffff" stroke-width="2" stroke-linejoin="round" paint-order="stroke">${escapeSvgText(area.label)}</text>`;
|
|
427
|
+
}).join("");
|
|
428
|
+
}
|
|
429
|
+
function escapeSvgText(value) {
|
|
430
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
431
|
+
}
|
|
406
432
|
function renderSvgRobotMarker(latest, motionPath, animateRobot) {
|
|
407
433
|
const path = animateRobot && motionPath && motionPath.length > 1 ? motionPath : [latest.point];
|
|
408
434
|
const finalRotation = latest.phi === void 0 ? 0 : -latest.phi / 1e3 / Math.PI * 180;
|
|
@@ -626,6 +652,7 @@ function summarizeRenderedAreas(sample) {
|
|
|
626
652
|
kind: area.kind,
|
|
627
653
|
...id !== void 0 ? { id } : {},
|
|
628
654
|
...label !== void 0 ? { label } : {},
|
|
655
|
+
...projected.length > 0 ? { center: polygonCenter(projected) } : {},
|
|
629
656
|
...projected.length > 0 ? { bounds: boundsFor(projected) } : {}
|
|
630
657
|
};
|
|
631
658
|
});
|
|
@@ -633,7 +660,7 @@ function summarizeRenderedAreas(sample) {
|
|
|
633
660
|
function firstUsefulLabel(...values) {
|
|
634
661
|
for (const value of values) {
|
|
635
662
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
636
|
-
return value;
|
|
663
|
+
return value.trim().replace(/[\p{Cc}\p{Cf}]/gu, " ").slice(0, 128);
|
|
637
664
|
}
|
|
638
665
|
}
|
|
639
666
|
return void 0;
|
|
@@ -648,6 +675,29 @@ function boundsFor(points) {
|
|
|
648
675
|
maxY: Math.max(...ys)
|
|
649
676
|
};
|
|
650
677
|
}
|
|
678
|
+
function polygonCenter(points) {
|
|
679
|
+
let twiceArea = 0;
|
|
680
|
+
let weightedX = 0;
|
|
681
|
+
let weightedY = 0;
|
|
682
|
+
for (let index = 0; index < points.length; index++) {
|
|
683
|
+
const [x1, y1] = points[index];
|
|
684
|
+
const [x2, y2] = points[(index + 1) % points.length];
|
|
685
|
+
const cross = x1 * y2 - x2 * y1;
|
|
686
|
+
twiceArea += cross;
|
|
687
|
+
weightedX += (x1 + x2) * cross;
|
|
688
|
+
weightedY += (y1 + y2) * cross;
|
|
689
|
+
}
|
|
690
|
+
if (Math.abs(twiceArea) > Number.EPSILON) {
|
|
691
|
+
return {
|
|
692
|
+
x: roundSvgNumber(weightedX / (3 * twiceArea)),
|
|
693
|
+
y: roundSvgNumber(weightedY / (3 * twiceArea))
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
return {
|
|
697
|
+
x: roundSvgNumber(points.reduce((sum, [x]) => sum + x, 0) / points.length),
|
|
698
|
+
y: roundSvgNumber(points.reduce((sum, [, y]) => sum + y, 0) / points.length)
|
|
699
|
+
};
|
|
700
|
+
}
|
|
651
701
|
function normalizeMapAreaMetadata(value) {
|
|
652
702
|
var _a;
|
|
653
703
|
if (!Array.isArray(value)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/domain/live-map.ts"],
|
|
4
|
-
"sourcesContent": ["import { deflateSync } from \"node:zlib\";\n\nexport interface RobotPose {\n\tpos: [number, number];\n\tphi?: number;\n}\n\nexport interface LiveMapImage {\n\tdataUrl: string;\n\tsvgDataUrl: string;\n\tpngDataUrl: string;\n\tformat: \"svg\";\n\twidth: number;\n\theight: number;\n\tareas: LiveMapRenderedArea[];\n\tposeCount: number;\n\trawPoseCount: number;\n\tpathLineSegments: number;\n\tskippedPathSegments: number;\n\trenderedForbiddenAreaCount: number;\n\trenderedZoneAreaCount: number;\n\trenderedRoomAreaCount: number;\n\torientation: \"flip-y\";\n\tdecompressedBytes: number;\n}\n\nexport interface LiveMapRenderOptions {\n\tcanvasBackgroundColor?: string;\n\tmapBackgroundColor?: string;\n\tbackgroundColor?: string;\n\tanimateRobot?: boolean;\n\tshowZoneOverlays?: boolean;\n\tselectedZoneIds?: readonly number[];\n}\n\nexport interface LiveMapTaskState {\n\tdockedSinceLastCleaning: boolean;\n\treturningToDock: boolean;\n\tcleaningTaskActive: boolean;\n}\n\nexport interface LiveMapTaskTransition {\n\tstate: LiveMapTaskState;\n\tresetTrail: boolean;\n}\n\nexport type LiveMapAreaKind = \"forbidden\" | \"zone\" | \"unknown\";\n\nexport interface LiveMapAreaMetadata {\n\tkey: string;\n\tkind: LiveMapAreaKind;\n\tsource: Record<string, unknown>;\n}\n\nexport interface LiveMapCoordinateMetadata {\n\tmapId?: number;\n\tarea?: LiveMapAreaMetadata[];\n\tchargeHandlePos?: [number, number];\n}\n\nexport interface LiveMapRenderedArea {\n\tkey: string;\n\tkind: LiveMapAreaKind;\n\tid?: number | string;\n\tlabel?: string;\n\tbounds?: {\n\t\tminX: number;\n\t\tminY: number;\n\t\tmaxX: number;\n\t\tmaxY: number;\n\t};\n}\n\ninterface MapSample {\n\tencoded: string;\n\twidth: number;\n\theight: number;\n\tresolution?: number;\n\txMin?: number;\n\tyMin?: number;\n\tareas: MapArea[];\n\tchargeHandlePos?: [number, number];\n}\n\ninterface MapArea {\n\tkey: string;\n\tvertices: Array<[number, number]>;\n\tkind: LiveMapAreaKind;\n\tsource: Record<string, unknown>;\n}\n\ntype Color = readonly [number, number, number];\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\nconst CRC_TABLE = createCrcTable();\nconst MAX_LIVE_MAP_PIXELS = 512 * 512;\nconst MAX_LIVE_MAP_DATA_URL_BYTES = 256 * 1024;\nexport const DEFAULT_LIVE_MAP_BACKGROUND_COLOR = \"#b8ccd8\";\nexport const DEFAULT_LIVE_MAP_CANVAS_BACKGROUND_COLOR = \"#d9d9d9\";\nconst COLOR_UNKNOWN: Color = [184, 204, 216];\nconst COLOR_CANVAS_BACKGROUND: Color = [217, 217, 217];\nconst COLOR_WALL: Color = [56, 130, 188];\nconst COLOR_OBSTACLE: Color = [82, 82, 82];\nconst COLOR_FORBIDDEN_AREA: Color = [209, 106, 133];\nconst COLOR_FORBIDDEN_OUTLINE: Color = [175, 68, 103];\nconst FORBIDDEN_AREA_ALPHA = 0.45;\nconst COLOR_ZONE_AREA: Color = [255, 255, 255];\nconst COLOR_ZONE_AREA_OUTLINE: Color = [72, 128, 162];\nconst COLOR_SELECTED_ZONE_AREA: Color = [126, 216, 96];\nconst COLOR_SELECTED_ZONE_AREA_OUTLINE: Color = [72, 168, 54];\nconst ZONE_AREA_ALPHA = 0.26;\nconst SELECTED_ZONE_AREA_ALPHA = 0.45;\nconst COLOR_DOCK: Color = [92, 92, 92];\nconst COLOR_ROBOT: Color = [39, 139, 61];\nconst COLOR_PATH: Color = [126, 216, 96];\nconst COLOR_HEADING: Color = [20, 20, 20];\nconst MIN_PATH_SEGMENT_DISTANCE_SQUARED = 1.5 ** 2;\nconst MAX_PATH_SEGMENT_DISTANCE_SQUARED = 90 ** 2;\nconst ROUTED_PATH_PADDING_PIXELS = 24;\nconst MAX_ROUTED_PATH_CELLS = 20_000;\nconst PATH_LINE_RADIUS = 1;\nconst ROBOT_GLIDE_DURATION_MS = 1_600;\n\ninterface ProjectedRobotPose {\n\tpoint: [number, number];\n\tphi: number | undefined;\n}\n\ninterface RobotRuntimeRenderResult {\n\tprojectedPoseCount: number;\n\tpathLineSegments: number;\n\tskippedPathSegments: number;\n\tlatest?: ProjectedRobotPose;\n\tlatestMotionPath?: Array<[number, number]>;\n}\n\nexport function extractRobotPose20001(data: unknown): RobotPose | undefined {\n\tconst record = getRecord(data);\n\tconst pos = parsePoint(record?.pos);\n\tif (!pos) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpos,\n\t\tphi: typeof record?.phi === \"number\" ? record.phi : undefined,\n\t};\n}\n\nexport function normalizeLiveMapBackgroundColor(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn /^#[0-9a-f]{6}$/iu.test(trimmed) ? trimmed.toLowerCase() : undefined;\n}\n\nexport function transitionLiveMapTaskState(\n\tstate: LiveMapTaskState,\n\tmode: string | undefined,\n\tcleaningActivityActive: boolean,\n): LiveMapTaskTransition {\n\tif (mode === \"sweep\") {\n\t\treturn {\n\t\t\tstate: { dockedSinceLastCleaning: false, returningToDock: false, cleaningTaskActive: true },\n\t\t\tresetTrail: state.dockedSinceLastCleaning,\n\t\t};\n\t}\n\n\tif (mode === \"backcharge\") {\n\t\treturn {\n\t\t\tstate: {\n\t\t\t\tdockedSinceLastCleaning: state.dockedSinceLastCleaning,\n\t\t\t\treturningToDock: true,\n\t\t\t\tcleaningTaskActive: state.cleaningTaskActive,\n\t\t\t},\n\t\t\tresetTrail: false,\n\t\t};\n\t}\n\n\tif (mode === \"charge\" || mode === \"fullcharge\") {\n\t\tif (state.returningToDock || (!state.cleaningTaskActive && !cleaningActivityActive)) {\n\t\t\treturn {\n\t\t\t\tstate: { dockedSinceLastCleaning: true, returningToDock: false, cleaningTaskActive: false },\n\t\t\t\tresetTrail: false,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { state, resetTrail: false };\n}\n\nexport function renderLiveMapImage20002(\n\tdata: unknown,\n\tposes: readonly RobotPose[] = [],\n\toptions: LiveMapRenderOptions = {},\n): LiveMapImage | undefined {\n\tconst sample = parseMapSample(data);\n\tif (!sample) {\n\t\treturn undefined;\n\t}\n\n\tconst compressed = decodeMapPayload(sample.encoded);\n\tconst occupancy = decompressLz4Block(compressed, sample.width * sample.height);\n\tif (occupancy.length !== sample.width * sample.height) {\n\t\treturn undefined;\n\t}\n\n\tconst mapBackgroundColor = colorFromHex(options.mapBackgroundColor ?? options.backgroundColor) ?? COLOR_UNKNOWN;\n\tconst canvasBackgroundColor = colorFromHex(options.canvasBackgroundColor) ?? COLOR_CANVAS_BACKGROUND;\n\tconst basePixels = renderOccupancy(\n\t\tsample.width,\n\t\tsample.height,\n\t\toccupancy,\n\t\tmapBackgroundColor,\n\t\tcanvasBackgroundColor,\n\t);\n\tconst coordinateMetadata = drawCoordinateMetadata(\n\t\tsample,\n\t\tbasePixels,\n\t\toptions.showZoneOverlays !== false,\n\t\tnew Set(options.selectedZoneIds ?? []),\n\t);\n\tconst runtime = drawRobotRuntime(sample, occupancy, basePixels, poses);\n\tconst basePng = encodeRgbPng(sample.width, sample.height, basePixels);\n\tconst fallbackPixels = Buffer.from(basePixels);\n\tif (runtime.latest) {\n\t\tdrawRobotMarker(fallbackPixels, sample.width, sample.height, runtime.latest);\n\t}\n\tconst fallbackPng = encodeRgbPng(sample.width, sample.height, fallbackPixels);\n\tconst pngDataUrl = `data:image/png;base64,${fallbackPng.toString(\"base64\")}`;\n\tconst svg = renderLiveMapSvg(sample.width, sample.height, basePng, runtime, options.animateRobot !== false);\n\tconst svgDataUrl = `data:image/svg+xml;base64,${Buffer.from(svg, \"utf8\").toString(\"base64\")}`;\n\tif (\n\t\tBuffer.byteLength(svgDataUrl, \"utf8\") > MAX_LIVE_MAP_DATA_URL_BYTES ||\n\t\tBuffer.byteLength(pngDataUrl, \"utf8\") > MAX_LIVE_MAP_DATA_URL_BYTES\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tdataUrl: svgDataUrl,\n\t\tsvgDataUrl,\n\t\tpngDataUrl,\n\t\tformat: \"svg\",\n\t\twidth: sample.width,\n\t\theight: sample.height,\n\t\tareas: summarizeRenderedAreas(sample),\n\t\tposeCount: runtime.projectedPoseCount,\n\t\trawPoseCount: poses.length,\n\t\tpathLineSegments: runtime.pathLineSegments,\n\t\tskippedPathSegments: runtime.skippedPathSegments,\n\t\trenderedForbiddenAreaCount: coordinateMetadata.renderedForbiddenAreaCount,\n\t\trenderedZoneAreaCount: coordinateMetadata.renderedZoneAreaCount,\n\t\t// Kept as a compatibility alias while consumers migrate to the accurate zone name.\n\t\trenderedRoomAreaCount: coordinateMetadata.renderedRoomAreaCount,\n\t\torientation: \"flip-y\",\n\t\tdecompressedBytes: occupancy.length,\n\t};\n}\n\nexport function extractLiveMapCoordinateMetadata20002(data: unknown): LiveMapCoordinateMetadata | undefined {\n\tconst record = getRecord(data);\n\tif (!record) {\n\t\treturn undefined;\n\t}\n\n\tconst metadata: LiveMapCoordinateMetadata = {};\n\tif (typeof record.mapId === \"number\") {\n\t\tmetadata.mapId = record.mapId;\n\t}\n\tconst chargeHandlePos = parsePoint(record.chargeHandlePos);\n\tif (chargeHandlePos) {\n\t\tmetadata.chargeHandlePos = chargeHandlePos;\n\t}\n\n\treturn metadata.mapId !== undefined || metadata.area !== undefined || metadata.chargeHandlePos !== undefined\n\t\t? metadata\n\t\t: undefined;\n}\n\nexport function extractLiveMapZoneCatalog21004(data: unknown): LiveMapCoordinateMetadata | undefined {\n\tconst record = getRecord(data);\n\tif (\n\t\t!record ||\n\t\t!Number.isSafeInteger(record.mapId) ||\n\t\t(record.mapId as number) < 0 ||\n\t\t!Array.isArray(record.value)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst areas = normalizeMapZoneCatalog(record.value);\n\tif (areas.length !== record.value.length) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tmapId: record.mapId as number,\n\t\tarea: areas,\n\t};\n}\n\nexport function replaceLiveMapZoneCatalog(\n\tprevious: LiveMapCoordinateMetadata | undefined,\n\tcatalog: LiveMapCoordinateMetadata,\n): LiveMapCoordinateMetadata {\n\tconst sameMap = previous?.mapId === undefined || previous.mapId === catalog.mapId;\n\treturn {\n\t\tmapId: catalog.mapId,\n\t\tarea: catalog.area ?? [],\n\t\tchargeHandlePos: sameMap ? previous?.chargeHandlePos : undefined,\n\t};\n}\n\nexport function mergeLiveMapCoordinateMetadata20002(\n\tdata: unknown,\n\tmetadata: LiveMapCoordinateMetadata | undefined,\n): unknown {\n\tconst record = getRecord(data);\n\tif (!record || !metadata) {\n\t\treturn data;\n\t}\n\n\tif (metadata.mapId !== undefined && typeof record.mapId === \"number\" && metadata.mapId !== record.mapId) {\n\t\treturn data;\n\t}\n\n\tconst merged = { ...record };\n\tmerged.area = (metadata.area ?? []).map(area => ({\n\t\t...area.source,\n\t\t__proscenicKind: area.kind,\n\t}));\n\tif (metadata.chargeHandlePos && !parsePoint(record.chargeHandlePos)) {\n\t\tmerged.chargeHandlePos = metadata.chargeHandlePos;\n\t}\n\treturn merged;\n}\n\nexport function countLiveMapAreas20002(data: unknown): number {\n\tconst record = getRecord(data);\n\treturn Array.isArray(record?.area) ? record.area.length : 0;\n}\n\nexport function mergeLiveMapCoordinateMetadataCache(\n\tprevious: LiveMapCoordinateMetadata | undefined,\n\tnext: LiveMapCoordinateMetadata,\n): LiveMapCoordinateMetadata {\n\tconst sameMap = previous?.mapId === undefined || next.mapId === undefined || previous.mapId === next.mapId;\n\tconst previousAreas = sameMap ? (previous?.area ?? []) : [];\n\n\treturn {\n\t\tmapId: next.mapId ?? previous?.mapId,\n\t\tarea: mergeAreaMetadata(previousAreas, next.area ?? []),\n\t\tchargeHandlePos: next.chargeHandlePos ?? (sameMap ? previous?.chargeHandlePos : undefined),\n\t};\n}\n\nfunction parseMapSample(data: unknown): MapSample | undefined {\n\tconst record = getRecord(data);\n\tif (!record) {\n\t\treturn undefined;\n\t}\n\n\tconst encoded = record.map;\n\tconst width = record.width;\n\tconst height = record.height;\n\tif (typeof encoded !== \"string\" || typeof width !== \"number\" || typeof height !== \"number\") {\n\t\treturn undefined;\n\t}\n\tif (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width <= 0 || height <= 0) {\n\t\treturn undefined;\n\t}\n\tif (width * height > MAX_LIVE_MAP_PIXELS) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tencoded,\n\t\twidth,\n\t\theight,\n\t\tresolution: typeof record.resolution === \"number\" ? record.resolution : undefined,\n\t\txMin: typeof record.x_min === \"number\" ? record.x_min : undefined,\n\t\tyMin: typeof record.y_min === \"number\" ? record.y_min : undefined,\n\t\tareas: parseMapAreas(record.area),\n\t\tchargeHandlePos: parsePoint(record.chargeHandlePos),\n\t};\n}\n\nfunction renderOccupancy(\n\twidth: number,\n\theight: number,\n\toccupancy: Buffer,\n\tmapBackgroundColor: Color,\n\tcanvasBackgroundColor: Color,\n): Buffer {\n\tconst pixels = Buffer.alloc(width * height * 3);\n\tfor (let index = 0; index < occupancy.length; index++) {\n\t\tconst sourceX = index % width;\n\t\tconst sourceY = Math.floor(index / width);\n\t\tconst targetY = height - 1 - sourceY;\n\t\tconst value = occupancy[index];\n\t\tif (value === 0) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, COLOR_WALL);\n\t\t} else if (value === 127) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, canvasBackgroundColor);\n\t\t} else if (value === 255) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, mapBackgroundColor);\n\t\t} else {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, value < 127 ? COLOR_OBSTACLE : canvasBackgroundColor);\n\t\t}\n\t}\n\treturn pixels;\n}\n\nfunction colorFromHex(value: string | undefined): Color | undefined {\n\tconst normalized = normalizeLiveMapBackgroundColor(value);\n\tif (!normalized) {\n\t\treturn undefined;\n\t}\n\treturn [\n\t\tNumber.parseInt(normalized.slice(1, 3), 16),\n\t\tNumber.parseInt(normalized.slice(3, 5), 16),\n\t\tNumber.parseInt(normalized.slice(5, 7), 16),\n\t];\n}\n\nfunction drawCoordinateMetadata(\n\tsample: MapSample,\n\tpixels: Buffer,\n\tshowZoneOverlays: boolean,\n\tselectedZoneIds: ReadonlySet<number>,\n): { renderedForbiddenAreaCount: number; renderedZoneAreaCount: number; renderedRoomAreaCount: number } {\n\tlet renderedForbiddenAreaCount = 0;\n\tlet renderedZoneAreaCount = 0;\n\tfor (const area of showZoneOverlays ? sample.areas : []) {\n\t\tconst projected = area.vertices\n\t\t\t.map(vertex => projectRobotCoordinate(sample, vertex))\n\t\t\t.filter((vertex): vertex is [number, number] => vertex !== undefined);\n\t\tif (projected.length >= 3) {\n\t\t\tif (area.kind === \"zone\") {\n\t\t\t\tconst selected = typeof area.source.id === \"number\" && selectedZoneIds.has(area.source.id);\n\t\t\t\tfillPolygon(\n\t\t\t\t\tpixels,\n\t\t\t\t\tsample.width,\n\t\t\t\t\tsample.height,\n\t\t\t\t\tprojected,\n\t\t\t\t\tselected ? COLOR_SELECTED_ZONE_AREA : COLOR_ZONE_AREA,\n\t\t\t\t\tselected ? SELECTED_ZONE_AREA_ALPHA : ZONE_AREA_ALPHA,\n\t\t\t\t);\n\t\t\t\tdrawPolygon(\n\t\t\t\t\tpixels,\n\t\t\t\t\tsample.width,\n\t\t\t\t\tsample.height,\n\t\t\t\t\tprojected,\n\t\t\t\t\tselected ? COLOR_SELECTED_ZONE_AREA_OUTLINE : COLOR_ZONE_AREA_OUTLINE,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t\trenderedZoneAreaCount += 1;\n\t\t\t} else if (area.kind === \"forbidden\") {\n\t\t\t\tfillPolygon(pixels, sample.width, sample.height, projected, COLOR_FORBIDDEN_AREA, FORBIDDEN_AREA_ALPHA);\n\t\t\t\tdrawPolygon(pixels, sample.width, sample.height, projected, COLOR_FORBIDDEN_OUTLINE);\n\t\t\t\trenderedForbiddenAreaCount += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (sample.chargeHandlePos) {\n\t\tconst charge = projectRobotCoordinate(sample, sample.chargeHandlePos);\n\t\tif (charge) {\n\t\t\tplotMarker(pixels, sample.width, sample.height, charge[0], charge[1], 5, COLOR_DOCK);\n\t\t}\n\t}\n\n\treturn {\n\t\trenderedForbiddenAreaCount,\n\t\trenderedZoneAreaCount,\n\t\trenderedRoomAreaCount: renderedZoneAreaCount,\n\t};\n}\n\nfunction drawRobotRuntime(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpixels: Buffer,\n\tposes: readonly RobotPose[],\n): RobotRuntimeRenderResult {\n\tconst projected = poses\n\t\t.map(pose => ({\n\t\t\tpoint: projectRobotCoordinate(sample, pose.pos),\n\t\t\tphi: pose.phi,\n\t\t}))\n\t\t.filter((pose): pose is { point: [number, number]; phi: number | undefined } => pose.point !== undefined);\n\n\tlet pathLineSegments = 0;\n\tlet skippedPathSegments = 0;\n\tlet latestMotionPath: Array<[number, number]> | undefined;\n\n\tfor (let index = 1; index < projected.length; index++) {\n\t\tconst previous = projected[index - 1].point;\n\t\tconst current = projected[index].point;\n\t\tconst segmentDistanceSquared = distanceSquared(previous, current);\n\t\tif (\n\t\t\tsegmentDistanceSquared >= MIN_PATH_SEGMENT_DISTANCE_SQUARED &&\n\t\t\tsegmentDistanceSquared <= MAX_PATH_SEGMENT_DISTANCE_SQUARED\n\t\t) {\n\t\t\tconst routedPath = findDrawablePath(sample, occupancy, previous, current);\n\t\t\tif (routedPath) {\n\t\t\t\tdrawAdaptivePathPolyline(sample, occupancy, pixels, sample.width, sample.height, routedPath);\n\t\t\t\tpathLineSegments += 1;\n\t\t\t\tif (index === projected.length - 1) {\n\t\t\t\t\tlatestMotionPath = routedPath;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tskippedPathSegments += 1;\n\t\t\t}\n\t\t} else {\n\t\t\tskippedPathSegments += 1;\n\t\t}\n\t}\n\n\tconst latest = projected.at(-1);\n\tif (!latest) {\n\t\treturn {\n\t\t\tprojectedPoseCount: 0,\n\t\t\tpathLineSegments,\n\t\t\tskippedPathSegments,\n\t\t};\n\t}\n\n\treturn {\n\t\tprojectedPoseCount: projected.length,\n\t\tpathLineSegments,\n\t\tskippedPathSegments,\n\t\tlatest,\n\t\tlatestMotionPath,\n\t};\n}\n\nfunction drawRobotMarker(pixels: Buffer, width: number, height: number, pose: ProjectedRobotPose): void {\n\tplotMarker(pixels, width, height, pose.point[0], pose.point[1], 5, COLOR_ROBOT);\n\tif (pose.phi === undefined) {\n\t\treturn;\n\t}\n\tconst angle = pose.phi / 1000;\n\tconst headingLength = 10;\n\tconst endX = Math.round(pose.point[0] + Math.cos(angle) * headingLength);\n\tconst endY = Math.round(pose.point[1] - Math.sin(angle) * headingLength);\n\tdrawLine(pixels, width, height, pose.point[0], pose.point[1], endX, endY, COLOR_HEADING);\n}\n\nfunction renderLiveMapSvg(\n\twidth: number,\n\theight: number,\n\tbasePng: Buffer,\n\truntime: RobotRuntimeRenderResult,\n\tanimateRobot: boolean,\n): string {\n\tconst marker = runtime.latest ? renderSvgRobotMarker(runtime.latest, runtime.latestMotionPath, animateRobot) : \"\";\n\tconst embeddedPng = `data:image/png;base64,${basePng.toString(\"base64\")}`;\n\treturn [\n\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\" preserveAspectRatio=\"xMidYMid meet\">`,\n\t\t`<image href=\"${embeddedPng}\" width=\"${width}\" height=\"${height}\"/>`,\n\t\tmarker,\n\t\t\"</svg>\",\n\t].join(\"\");\n}\n\nfunction renderSvgRobotMarker(\n\tlatest: ProjectedRobotPose,\n\tmotionPath: readonly [number, number][] | undefined,\n\tanimateRobot: boolean,\n): string {\n\tconst path = animateRobot && motionPath && motionPath.length > 1 ? motionPath : [latest.point];\n\tconst finalRotation = latest.phi === undefined ? 0 : (-latest.phi / 1000 / Math.PI) * 180;\n\tconst marker = [\n\t\t`<circle cx=\"0\" cy=\"0\" r=\"5\" fill=\"#278b3d\" stroke=\"#145f2b\" stroke-width=\"1\"/>`,\n\t\t`<line x1=\"0\" y1=\"0\" x2=\"10\" y2=\"0\" stroke=\"#141414\" stroke-width=\"2\" stroke-linecap=\"round\" transform=\"rotate(${roundSvgNumber(finalRotation)})\"/>`,\n\t].join(\"\");\n\tif (path.length === 1) {\n\t\treturn `<g transform=\"translate(${path[0][0]} ${path[0][1]})\">${marker}</g>`;\n\t}\n\tconst svgPath = path.map((point, index) => `${index === 0 ? \"M\" : \"L\"}${point[0]} ${point[1]}`).join(\" \");\n\treturn `<g>${marker}<animateMotion dur=\"${ROBOT_GLIDE_DURATION_MS}ms\" path=\"${svgPath}\" calcMode=\"paced\" fill=\"freeze\"/></g>`;\n}\n\nfunction roundSvgNumber(value: number): number {\n\treturn Math.round(value * 100) / 100;\n}\n\nfunction drawAdaptivePathLine(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcanDraw?: (x: number, y: number) => boolean,\n): void {\n\tdrawLineWithPixelColor(pixels, width, height, x1, y1, x2, y2, (x, y) =>\n\t\tcanDraw && !canDraw(x, y) ? undefined : COLOR_PATH,\n\t);\n\tdrawLineNeighbors(pixels, width, height, x1, y1, x2, y2, canDraw);\n}\n\nfunction drawAdaptivePathPolyline(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpoints: readonly [number, number][],\n): void {\n\tconst canDraw = (x: number, y: number): boolean => isTraversableMapPixel(sample, occupancy, x, y);\n\tfor (let index = 1; index < points.length; index++) {\n\t\tconst [x1, y1] = points[index - 1];\n\t\tconst [x2, y2] = points[index];\n\t\tdrawAdaptivePathLine(pixels, width, height, x1, y1, x2, y2, canDraw);\n\t}\n}\n\nfunction findDrawablePath(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): Array<[number, number]> | undefined {\n\tif (isDirectPathTraversable(sample, occupancy, start, end)) {\n\t\treturn [start, end];\n\t}\n\n\treturn findRoutedPath(sample, occupancy, start, end);\n}\n\nfunction isDirectPathTraversable(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): boolean {\n\tlet traversedCells = 0;\n\tlet blockedCells = 0;\n\tforEachLinePoint(start[0], start[1], end[0], end[1], (x, y) => {\n\t\ttraversedCells += 1;\n\t\tif (!isTraversableMapPixel(sample, occupancy, x, y)) {\n\t\t\tblockedCells += 1;\n\t\t}\n\t});\n\treturn traversedCells > 0 && blockedCells === 0;\n}\n\nfunction findRoutedPath(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): Array<[number, number]> | undefined {\n\tconst routeStart = nearestTraversablePoint(sample, occupancy, start);\n\tconst routeEnd = nearestTraversablePoint(sample, occupancy, end);\n\tif (!routeStart || !routeEnd) {\n\t\treturn undefined;\n\t}\n\n\tconst minX = Math.max(0, Math.min(routeStart[0], routeEnd[0]) - ROUTED_PATH_PADDING_PIXELS);\n\tconst maxX = Math.min(sample.width - 1, Math.max(routeStart[0], routeEnd[0]) + ROUTED_PATH_PADDING_PIXELS);\n\tconst minY = Math.max(0, Math.min(routeStart[1], routeEnd[1]) - ROUTED_PATH_PADDING_PIXELS);\n\tconst maxY = Math.min(sample.height - 1, Math.max(routeStart[1], routeEnd[1]) + ROUTED_PATH_PADDING_PIXELS);\n\tconst searchWidth = maxX - minX + 1;\n\tconst searchHeight = maxY - minY + 1;\n\tif (searchWidth * searchHeight > MAX_ROUTED_PATH_CELLS) {\n\t\treturn undefined;\n\t}\n\n\tconst distance = new Map<number, number>();\n\tconst previous = new Map<number, number>();\n\tconst queue: Array<{ key: number; score: number }> = [];\n\tconst startKey = localPointKey(routeStart[0], routeStart[1], minX, minY, searchWidth);\n\tconst endKey = localPointKey(routeEnd[0], routeEnd[1], minX, minY, searchWidth);\n\tdistance.set(startKey, 0);\n\tqueue.push({ key: startKey, score: heuristic(routeStart, routeEnd) });\n\n\twhile (queue.length > 0) {\n\t\tqueue.sort((left, right) => left.score - right.score);\n\t\tconst current = queue.shift();\n\t\tif (!current) {\n\t\t\tbreak;\n\t\t}\n\t\tif (current.key === endKey) {\n\t\t\treturn restoreRoutedPath(previous, current.key, minX, minY, searchWidth);\n\t\t}\n\n\t\tconst [currentX, currentY] = pointFromLocalKey(current.key, minX, minY, searchWidth);\n\t\tconst currentDistance = distance.get(current.key) ?? Number.POSITIVE_INFINITY;\n\t\tfor (let dy = -1; dy <= 1; dy++) {\n\t\t\tfor (let dx = -1; dx <= 1; dx++) {\n\t\t\t\tif (dx === 0 && dy === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst nextX = currentX + dx;\n\t\t\t\tconst nextY = currentY + dy;\n\t\t\t\tif (\n\t\t\t\t\tnextX < minX ||\n\t\t\t\t\tnextX > maxX ||\n\t\t\t\t\tnextY < minY ||\n\t\t\t\t\tnextY > maxY ||\n\t\t\t\t\t!isTraversableMapPixel(sample, occupancy, nextX, nextY)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst nextKey = localPointKey(nextX, nextY, minX, minY, searchWidth);\n\t\t\t\tconst nextDistance = currentDistance + (dx !== 0 && dy !== 0 ? Math.SQRT2 : 1);\n\t\t\t\tif (nextDistance >= (distance.get(nextKey) ?? Number.POSITIVE_INFINITY)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdistance.set(nextKey, nextDistance);\n\t\t\t\tprevious.set(nextKey, current.key);\n\t\t\t\tqueue.push({ key: nextKey, score: nextDistance + heuristic([nextX, nextY], routeEnd) });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction restoreRoutedPath(\n\tprevious: ReadonlyMap<number, number>,\n\tendKey: number,\n\tminX: number,\n\tminY: number,\n\twidth: number,\n): Array<[number, number]> {\n\tconst keys = [endKey];\n\tlet current = endKey;\n\twhile (previous.has(current)) {\n\t\tcurrent = previous.get(current) ?? current;\n\t\tkeys.push(current);\n\t}\n\treturn simplifyPath(keys.reverse().map(key => pointFromLocalKey(key, minX, minY, width)));\n}\n\nfunction simplifyPath(points: Array<[number, number]>): Array<[number, number]> {\n\tif (points.length <= 2) {\n\t\treturn points;\n\t}\n\tconst simplified: Array<[number, number]> = [points[0]];\n\tlet previousDirection: [number, number] | undefined;\n\tfor (let index = 1; index < points.length; index++) {\n\t\tconst direction: [number, number] = [\n\t\t\tMath.sign(points[index][0] - points[index - 1][0]),\n\t\t\tMath.sign(points[index][1] - points[index - 1][1]),\n\t\t];\n\t\tif (previousDirection && (direction[0] !== previousDirection[0] || direction[1] !== previousDirection[1])) {\n\t\t\tsimplified.push(points[index - 1]);\n\t\t}\n\t\tpreviousDirection = direction;\n\t}\n\tsimplified.push(points.at(-1) ?? points[0]);\n\treturn simplified;\n}\n\nfunction nearestTraversablePoint(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpoint: [number, number],\n): [number, number] | undefined {\n\tif (isTraversableMapPixel(sample, occupancy, point[0], point[1])) {\n\t\treturn point;\n\t}\n\tfor (let radius = 1; radius <= 3; radius++) {\n\t\tfor (let y = point[1] - radius; y <= point[1] + radius; y++) {\n\t\t\tfor (let x = point[0] - radius; x <= point[0] + radius; x++) {\n\t\t\t\tif (isTraversableMapPixel(sample, occupancy, x, y)) {\n\t\t\t\t\treturn [x, y];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isTraversableMapPixel(sample: MapSample, occupancy: Buffer, x: number, y: number): boolean {\n\tif (x < 0 || x >= sample.width || y < 0 || y >= sample.height) {\n\t\treturn false;\n\t}\n\tconst sourceY = sample.height - 1 - y;\n\tconst value = occupancy[sourceY * sample.width + x];\n\treturn value >= 127;\n}\n\nfunction localPointKey(x: number, y: number, minX: number, minY: number, width: number): number {\n\treturn (y - minY) * width + (x - minX);\n}\n\nfunction pointFromLocalKey(key: number, minX: number, minY: number, width: number): [number, number] {\n\treturn [minX + (key % width), minY + Math.floor(key / width)];\n}\n\nfunction heuristic(left: [number, number], right: [number, number]): number {\n\treturn Math.hypot(left[0] - right[0], left[1] - right[1]);\n}\n\nfunction drawLineNeighbors(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcanDraw?: (x: number, y: number) => boolean,\n): void {\n\tfor (let dy = -PATH_LINE_RADIUS; dy <= PATH_LINE_RADIUS; dy++) {\n\t\tfor (let dx = -PATH_LINE_RADIUS; dx <= PATH_LINE_RADIUS; dx++) {\n\t\t\tif ((dx === 0 && dy === 0) || dx * dx + dy * dy > PATH_LINE_RADIUS * PATH_LINE_RADIUS) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdrawLineWithPixelColor(pixels, width, height, x1 + dx, y1 + dy, x2 + dx, y2 + dy, (x, y) =>\n\t\t\t\tcanDraw && !canDraw(x, y) ? undefined : COLOR_PATH,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction projectRobotCoordinate(sample: MapSample, point: [number, number]): [number, number] | undefined {\n\tif (sample.resolution === undefined || sample.xMin === undefined || sample.yMin === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst xMeters = point[0] / 1000;\n\tconst yMeters = point[1] / 1000;\n\tconst x = Math.round((xMeters - sample.xMin) / sample.resolution);\n\tconst y = sample.height - 1 - Math.round((yMeters - sample.yMin) / sample.resolution);\n\tif (x < 0 || x >= sample.width || y < 0 || y >= sample.height) {\n\t\treturn undefined;\n\t}\n\treturn [x, y];\n}\n\nfunction parseMapAreas(value: unknown): MapArea[] {\n\treturn normalizeMapAreaMetadata(value).map(area => ({\n\t\tkey: area.key,\n\t\tvertices: parseVertices(area.source.vertexs),\n\t\tkind: area.kind,\n\t\tsource: area.source,\n\t}));\n}\n\nfunction summarizeRenderedAreas(sample: MapSample): LiveMapRenderedArea[] {\n\treturn sample.areas.map(area => {\n\t\tconst projected = area.vertices\n\t\t\t.map(point => projectRobotCoordinate(sample, point))\n\t\t\t.filter((point): point is [number, number] => point !== undefined);\n\t\tconst id =\n\t\t\ttypeof area.source.id === \"number\" || typeof area.source.id === \"string\" ? area.source.id : undefined;\n\t\tconst label = firstUsefulLabel(area.source.tag, area.source.name);\n\n\t\treturn {\n\t\t\tkey: area.key,\n\t\t\tkind: area.kind,\n\t\t\t...(id !== undefined ? { id } : {}),\n\t\t\t...(label !== undefined ? { label } : {}),\n\t\t\t...(projected.length > 0 ? { bounds: boundsFor(projected) } : {}),\n\t\t};\n\t});\n}\n\nfunction firstUsefulLabel(...values: unknown[]): string | undefined {\n\tfor (const value of values) {\n\t\tif (typeof value === \"string\" && value.trim().length > 0) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction boundsFor(points: readonly [number, number][]): LiveMapRenderedArea[\"bounds\"] {\n\tconst xs = points.map(([x]) => x);\n\tconst ys = points.map(([, y]) => y);\n\treturn {\n\t\tminX: Math.min(...xs),\n\t\tminY: Math.min(...ys),\n\t\tmaxX: Math.max(...xs),\n\t\tmaxY: Math.max(...ys),\n\t};\n}\n\nfunction normalizeMapAreaMetadata(value: unknown): LiveMapAreaMetadata[] {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\n\tconst candidates = value\n\t\t.map(entry => {\n\t\t\tconst record = getRecord(entry);\n\t\t\tif (!record) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst vertices = parseVertices(record.vertexs);\n\t\t\tif (vertices.length < 3) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst key = mapAreaKey(record, vertices);\n\t\t\tconst explicitKind = parseAreaKind(record.__proscenicKind);\n\t\t\treturn {\n\t\t\t\tkey,\n\t\t\t\texplicitKind,\n\t\t\t\tsource: record,\n\t\t\t};\n\t\t})\n\t\t.filter(\n\t\t\t(\n\t\t\t\tentry,\n\t\t\t): entry is {\n\t\t\t\tkey: string;\n\t\t\t\texplicitKind: LiveMapAreaKind | undefined;\n\t\t\t\tsource: Record<string, unknown>;\n\t\t\t} => entry !== undefined,\n\t\t);\n\n\tconst normalized = new Map<string, LiveMapAreaMetadata>();\n\tfor (const candidate of candidates) {\n\t\tconst kind = candidate.explicitKind ?? \"unknown\";\n\t\tconst existing = normalized.get(candidate.key);\n\t\tconst next = {\n\t\t\tkey: candidate.key,\n\t\t\tkind,\n\t\t\tsource: withoutInternalAreaMetadata(candidate.source),\n\t\t};\n\t\tnormalized.set(candidate.key, existing ? mergeAreaMetadataEntry(existing, next) : next);\n\t}\n\n\treturn [...normalized.values()];\n}\n\nfunction normalizeMapZoneCatalog(value: readonly unknown[]): LiveMapAreaMetadata[] {\n\tconst normalized = new Map<string, LiveMapAreaMetadata>();\n\tfor (const entry of value) {\n\t\tconst record = getRecord(entry);\n\t\tif (!record) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst vertices = parseVertices(record.vertexs);\n\t\tif (vertices.length < 3) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = record.id;\n\t\tif (!(typeof id === \"string\" || (typeof id === \"number\" && Number.isSafeInteger(id)))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst source: Record<string, unknown> = {\n\t\t\tid,\n\t\t\tvertexs: vertices,\n\t\t};\n\t\tfor (const field of [\"active\", \"mode\", \"name\", \"tag\"] as const) {\n\t\t\tif (typeof record[field] === \"string\") {\n\t\t\t\tsource[field] = record[field];\n\t\t\t}\n\t\t}\n\t\tconst key = mapAreaKey(source, vertices);\n\t\tnormalized.set(key, {\n\t\t\tkey,\n\t\t\tkind: record.active === \"forbid\" ? \"forbidden\" : \"zone\",\n\t\t\tsource,\n\t\t});\n\t}\n\treturn [...normalized.values()];\n}\n\nfunction mergeAreaMetadata(\n\tprevious: readonly LiveMapAreaMetadata[],\n\tnext: readonly LiveMapAreaMetadata[],\n): LiveMapAreaMetadata[] {\n\tconst merged = new Map<string, LiveMapAreaMetadata>();\n\tfor (const area of [...previous, ...next]) {\n\t\tconst existing = merged.get(area.key);\n\t\tmerged.set(area.key, existing ? mergeAreaMetadataEntry(existing, area) : area);\n\t}\n\treturn [...merged.values()];\n}\n\nfunction mergeAreaMetadataEntry(left: LiveMapAreaMetadata, right: LiveMapAreaMetadata): LiveMapAreaMetadata {\n\treturn {\n\t\tkey: right.key,\n\t\tkind: strongestAreaKind(left.kind, right.kind),\n\t\tsource: right.source,\n\t};\n}\n\nfunction strongestAreaKind(left: LiveMapAreaKind, right: LiveMapAreaKind): LiveMapAreaKind {\n\tif (left === \"forbidden\" || right === \"forbidden\") {\n\t\treturn \"forbidden\";\n\t}\n\tif (left === \"zone\" || right === \"zone\") {\n\t\treturn \"zone\";\n\t}\n\treturn \"unknown\";\n}\n\nfunction parseAreaKind(value: unknown): LiveMapAreaKind | undefined {\n\tif (value === \"room\") {\n\t\treturn \"zone\";\n\t}\n\treturn value === \"forbidden\" || value === \"zone\" || value === \"unknown\" ? value : undefined;\n}\n\nfunction withoutInternalAreaMetadata(record: Record<string, unknown>): Record<string, unknown> {\n\tconst clone = { ...record };\n\tdelete clone.__proscenicKind;\n\treturn clone;\n}\n\nfunction parseVertices(value: unknown): Array<[number, number]> {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\treturn value.map(vertex => parsePoint(vertex)).filter((vertex): vertex is [number, number] => vertex !== undefined);\n}\n\nfunction mapAreaKey(record: Record<string, unknown>, vertices: readonly [number, number][]): string {\n\tconst id = record.id;\n\tif (typeof id === \"number\" || typeof id === \"string\") {\n\t\treturn `id:${String(id)}`;\n\t}\n\tconst xs = vertices.map(([x]) => x);\n\tconst ys = vertices.map(([, y]) => y);\n\treturn `shape:${vertices.length}:${Math.min(...xs)}:${Math.min(...ys)}:${Math.max(...xs)}:${Math.max(...ys)}`;\n}\n\nfunction parsePoint(value: unknown): [number, number] | undefined {\n\tif (Array.isArray(value) && value.length >= 2 && typeof value[0] === \"number\" && typeof value[1] === \"number\") {\n\t\treturn [value[0], value[1]];\n\t}\n\treturn undefined;\n}\n\nfunction getRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction decodeMapPayload(encodedMap: string): Buffer {\n\treturn Buffer.from(encodedMap.replace(/\\s/gu, \"+\"), \"base64\");\n}\n\nfunction decompressLz4Block(input: Buffer, maxOutputBytes: number): Buffer {\n\tconst output = Buffer.alloc(maxOutputBytes);\n\tlet inputOffset = 0;\n\tlet outputOffset = 0;\n\n\twhile (inputOffset < input.length) {\n\t\tconst token = input[inputOffset++];\n\t\tlet literalLength = token >> 4;\n\t\tif (literalLength === 15) {\n\t\t\tlet next: number;\n\t\t\tdo {\n\t\t\t\tif (inputOffset >= input.length) {\n\t\t\t\t\tthrow new Error(\"literal length overflow\");\n\t\t\t\t}\n\t\t\t\tnext = input[inputOffset++];\n\t\t\t\tliteralLength += next;\n\t\t\t} while (next === 255);\n\t\t}\n\n\t\tif (inputOffset + literalLength > input.length || outputOffset + literalLength > output.length) {\n\t\t\tthrow new Error(\"literal overrun\");\n\t\t}\n\t\tinput.copy(output, outputOffset, inputOffset, inputOffset + literalLength);\n\t\tinputOffset += literalLength;\n\t\toutputOffset += literalLength;\n\n\t\tif (inputOffset >= input.length) {\n\t\t\tbreak;\n\t\t}\n\t\tif (inputOffset + 2 > input.length) {\n\t\t\tthrow new Error(\"offset overrun\");\n\t\t}\n\t\tconst matchOffset = input[inputOffset] | (input[inputOffset + 1] << 8);\n\t\tinputOffset += 2;\n\t\tif (matchOffset === 0 || matchOffset > outputOffset) {\n\t\t\tthrow new Error(\"bad match offset\");\n\t\t}\n\n\t\tlet matchLength = token & 0x0f;\n\t\tif (matchLength === 15) {\n\t\t\tlet next: number;\n\t\t\tdo {\n\t\t\t\tif (inputOffset >= input.length) {\n\t\t\t\t\tthrow new Error(\"match length overflow\");\n\t\t\t\t}\n\t\t\t\tnext = input[inputOffset++];\n\t\t\t\tmatchLength += next;\n\t\t\t} while (next === 255);\n\t\t}\n\t\tmatchLength += 4;\n\t\tif (outputOffset + matchLength > output.length) {\n\t\t\tthrow new Error(\"match overrun\");\n\t\t}\n\t\tfor (let index = 0; index < matchLength; index++) {\n\t\t\toutput[outputOffset + index] = output[outputOffset - matchOffset + index];\n\t\t}\n\t\toutputOffset += matchLength;\n\t}\n\n\treturn output.subarray(0, outputOffset);\n}\n\nfunction fillPolygon(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpolygon: Array<[number, number]>,\n\tcolor: Color,\n\talpha = 1,\n): void {\n\tconst minY = Math.max(0, Math.min(...polygon.map(([, y]) => y)));\n\tconst maxY = Math.min(height - 1, Math.max(...polygon.map(([, y]) => y)));\n\n\tfor (let y = minY; y <= maxY; y++) {\n\t\tconst intersections: number[] = [];\n\t\tfor (let index = 0; index < polygon.length; index++) {\n\t\t\tconst [x1, y1] = polygon[index];\n\t\t\tconst [x2, y2] = polygon[(index + 1) % polygon.length];\n\t\t\tif ((y1 <= y && y2 > y) || (y2 <= y && y1 > y)) {\n\t\t\t\tconst x = x1 + ((y - y1) * (x2 - x1)) / (y2 - y1);\n\t\t\t\tintersections.push(Math.round(x));\n\t\t\t}\n\t\t}\n\n\t\tintersections.sort((left, right) => left - right);\n\t\tfor (let index = 0; index + 1 < intersections.length; index += 2) {\n\t\t\tconst start = Math.max(0, intersections[index]);\n\t\t\tconst end = Math.min(width - 1, intersections[index + 1]);\n\t\t\tfor (let x = start; x <= end; x++) {\n\t\t\t\tblendPixel(pixels, width, height, x, y, color, alpha);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drawPolygon(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpolygon: Array<[number, number]>,\n\tcolor: Color,\n\tradius = 0,\n): void {\n\tfor (let index = 0; index < polygon.length; index++) {\n\t\tconst [x1, y1] = polygon[index];\n\t\tconst [x2, y2] = polygon[(index + 1) % polygon.length];\n\t\tfor (let offsetY = -radius; offsetY <= radius; offsetY++) {\n\t\t\tfor (let offsetX = -radius; offsetX <= radius; offsetX++) {\n\t\t\t\tdrawLine(pixels, width, height, x1 + offsetX, y1 + offsetY, x2 + offsetX, y2 + offsetY, color);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drawLine(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcolor: Color,\n): void {\n\tdrawLineWithPixelColor(pixels, width, height, x1, y1, x2, y2, () => color);\n}\n\nfunction forEachLinePoint(\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcallback: (x: number, y: number) => void,\n): void {\n\tconst dx = Math.abs(x2 - x1);\n\tconst sx = x1 < x2 ? 1 : -1;\n\tconst dy = -Math.abs(y2 - y1);\n\tconst sy = y1 < y2 ? 1 : -1;\n\tlet error = dx + dy;\n\tlet x = x1;\n\tlet y = y1;\n\n\twhile (true) {\n\t\tcallback(x, y);\n\t\tif (x === x2 && y === y2) {\n\t\t\tbreak;\n\t\t}\n\t\tconst error2 = 2 * error;\n\t\tif (error2 >= dy) {\n\t\t\terror += dy;\n\t\t\tx += sx;\n\t\t}\n\t\tif (error2 <= dx) {\n\t\t\terror += dx;\n\t\t\ty += sy;\n\t\t}\n\t}\n}\n\nfunction drawLineWithPixelColor(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tpickColor: (x: number, y: number) => Color | undefined,\n): void {\n\tconst dx = Math.abs(x2 - x1);\n\tconst sx = x1 < x2 ? 1 : -1;\n\tconst dy = -Math.abs(y2 - y1);\n\tconst sy = y1 < y2 ? 1 : -1;\n\tlet error = dx + dy;\n\tlet x = x1;\n\tlet y = y1;\n\n\twhile (true) {\n\t\tif (x >= 0 && x < width && y >= 0 && y < height) {\n\t\t\tconst color = pickColor(x, y);\n\t\t\tif (color) {\n\t\t\t\tsetPixel(pixels, width, height, x, y, color);\n\t\t\t}\n\t\t}\n\t\tif (x === x2 && y === y2) {\n\t\t\tbreak;\n\t\t}\n\t\tconst error2 = 2 * error;\n\t\tif (error2 >= dy) {\n\t\t\terror += dy;\n\t\t\tx += sx;\n\t\t}\n\t\tif (error2 <= dx) {\n\t\t\terror += dx;\n\t\t\ty += sy;\n\t\t}\n\t}\n}\n\nfunction plotMarker(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx: number,\n\ty: number,\n\tradius: number,\n\tcolor: Color,\n): void {\n\tfor (let dy = -radius; dy <= radius; dy++) {\n\t\tfor (let dx = -radius; dx <= radius; dx++) {\n\t\t\tconst px = x + dx;\n\t\t\tconst py = y + dy;\n\t\t\tif (px >= 0 && px < width && py >= 0 && py < height && dx * dx + dy * dy <= radius * radius) {\n\t\t\t\tsetPixel(pixels, width, height, px, py, color);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction setPixel(pixels: Buffer, width: number, height: number, x: number, y: number, color: Color): void {\n\tif (x < 0 || x >= width || y < 0 || y >= height) {\n\t\treturn;\n\t}\n\n\tconst offset = (y * width + x) * 3;\n\tpixels[offset] = color[0];\n\tpixels[offset + 1] = color[1];\n\tpixels[offset + 2] = color[2];\n}\n\nfunction blendPixel(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx: number,\n\ty: number,\n\tcolor: Color,\n\talpha: number,\n): void {\n\tif (alpha >= 1) {\n\t\tsetPixel(pixels, width, height, x, y, color);\n\t\treturn;\n\t}\n\tif (x < 0 || x >= width || y < 0 || y >= height) {\n\t\treturn;\n\t}\n\n\tconst offset = (y * width + x) * 3;\n\tpixels[offset] = Math.round(pixels[offset] * (1 - alpha) + color[0] * alpha);\n\tpixels[offset + 1] = Math.round(pixels[offset + 1] * (1 - alpha) + color[1] * alpha);\n\tpixels[offset + 2] = Math.round(pixels[offset + 2] * (1 - alpha) + color[2] * alpha);\n}\n\nfunction distanceSquared(left: [number, number], right: [number, number]): number {\n\treturn (left[0] - right[0]) ** 2 + (left[1] - right[1]) ** 2;\n}\n\nfunction encodeRgbPng(width: number, height: number, pixels: Buffer): Buffer {\n\tif (pixels.length !== width * height * 3) {\n\t\tthrow new Error(`Expected ${width * height * 3} RGB pixels but received ${pixels.length}`);\n\t}\n\n\tconst header = Buffer.alloc(13);\n\theader.writeUInt32BE(width, 0);\n\theader.writeUInt32BE(height, 4);\n\theader[8] = 8;\n\theader[9] = 2;\n\n\tconst rowBytes = width * 3;\n\tconst scanlines = Buffer.alloc((rowBytes + 1) * height);\n\tfor (let y = 0; y < height; y++) {\n\t\tscanlines[y * (rowBytes + 1)] = 0;\n\t\tpixels.copy(scanlines, y * (rowBytes + 1) + 1, y * rowBytes, (y + 1) * rowBytes);\n\t}\n\n\treturn Buffer.concat([\n\t\tPNG_SIGNATURE,\n\t\tpngChunk(\"IHDR\", header),\n\t\tpngChunk(\"IDAT\", deflateSync(scanlines)),\n\t\tpngChunk(\"IEND\", Buffer.alloc(0)),\n\t]);\n}\n\nfunction pngChunk(type: string, data: Buffer): Buffer {\n\tconst typeBuffer = Buffer.from(type, \"ascii\");\n\tconst length = Buffer.alloc(4);\n\tlength.writeUInt32BE(data.length, 0);\n\tconst checksum = Buffer.alloc(4);\n\tchecksum.writeUInt32BE(crc32(Buffer.concat([typeBuffer, data])), 0);\n\treturn Buffer.concat([length, typeBuffer, data, checksum]);\n}\n\nfunction crc32(data: Buffer): number {\n\tlet crc = 0xffffffff;\n\tfor (const byte of data) {\n\t\tcrc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n\t}\n\treturn (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction createCrcTable(): readonly number[] {\n\treturn Array.from({ length: 256 }, (_, index) => {\n\t\tlet value = index;\n\t\tfor (let bit = 0; bit < 8; bit++) {\n\t\t\tvalue = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;\n\t\t}\n\t\treturn value >>> 0;\n\t});\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { deflateSync } from \"node:zlib\";\n\nexport interface RobotPose {\n\tpos: [number, number];\n\tphi?: number;\n}\n\nexport interface LiveMapImage {\n\tdataUrl: string;\n\tsvgDataUrl: string;\n\tpngDataUrl: string;\n\tformat: \"svg\";\n\twidth: number;\n\theight: number;\n\tareas: LiveMapRenderedArea[];\n\tposeCount: number;\n\trawPoseCount: number;\n\tpathLineSegments: number;\n\tskippedPathSegments: number;\n\trenderedForbiddenAreaCount: number;\n\trenderedZoneAreaCount: number;\n\trenderedRoomAreaCount: number;\n\torientation: \"flip-y\";\n\tdecompressedBytes: number;\n}\n\nexport interface LiveMapRenderOptions {\n\tcanvasBackgroundColor?: string;\n\tmapBackgroundColor?: string;\n\tbackgroundColor?: string;\n\tanimateRobot?: boolean;\n\tshowZoneOverlays?: boolean;\n\tselectedZoneIds?: readonly number[];\n}\n\nexport interface LiveMapTaskState {\n\tdockedSinceLastCleaning: boolean;\n\treturningToDock: boolean;\n\tcleaningTaskActive: boolean;\n}\n\nexport interface LiveMapTaskTransition {\n\tstate: LiveMapTaskState;\n\tresetTrail: boolean;\n\tcompletedTask: boolean;\n}\n\nexport type LiveMapAreaKind = \"forbidden\" | \"zone\" | \"unknown\";\n\nexport interface LiveMapAreaMetadata {\n\tkey: string;\n\tkind: LiveMapAreaKind;\n\tsource: Record<string, unknown>;\n}\n\nexport interface LiveMapCoordinateMetadata {\n\tmapId?: number;\n\tarea?: LiveMapAreaMetadata[];\n\tchargeHandlePos?: [number, number];\n}\n\nexport interface LiveMapRenderedArea {\n\tkey: string;\n\tkind: LiveMapAreaKind;\n\tid?: number | string;\n\tlabel?: string;\n\tcenter?: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tbounds?: {\n\t\tminX: number;\n\t\tminY: number;\n\t\tmaxX: number;\n\t\tmaxY: number;\n\t};\n}\n\ninterface MapSample {\n\tencoded: string;\n\twidth: number;\n\theight: number;\n\tresolution?: number;\n\txMin?: number;\n\tyMin?: number;\n\tareas: MapArea[];\n\tchargeHandlePos?: [number, number];\n}\n\ninterface MapArea {\n\tkey: string;\n\tvertices: Array<[number, number]>;\n\tkind: LiveMapAreaKind;\n\tsource: Record<string, unknown>;\n}\n\ntype Color = readonly [number, number, number];\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\nconst CRC_TABLE = createCrcTable();\nconst MAX_LIVE_MAP_PIXELS = 512 * 512;\nconst MAX_LIVE_MAP_DATA_URL_BYTES = 256 * 1024;\nexport const DEFAULT_LIVE_MAP_BACKGROUND_COLOR = \"#b8ccd8\";\nexport const DEFAULT_LIVE_MAP_CANVAS_BACKGROUND_COLOR = \"#d9d9d9\";\nconst COLOR_UNKNOWN: Color = [184, 204, 216];\nconst COLOR_CANVAS_BACKGROUND: Color = [217, 217, 217];\nconst COLOR_WALL: Color = [56, 130, 188];\nconst COLOR_OBSTACLE: Color = [82, 82, 82];\nconst COLOR_FORBIDDEN_AREA: Color = [209, 106, 133];\nconst COLOR_FORBIDDEN_OUTLINE: Color = [175, 68, 103];\nconst FORBIDDEN_AREA_ALPHA = 0.45;\nconst COLOR_ZONE_AREA: Color = [255, 255, 255];\nconst COLOR_ZONE_AREA_OUTLINE: Color = [72, 128, 162];\nconst COLOR_SELECTED_ZONE_AREA: Color = [126, 216, 96];\nconst COLOR_SELECTED_ZONE_AREA_OUTLINE: Color = [72, 168, 54];\nconst ZONE_AREA_ALPHA = 0.26;\nconst SELECTED_ZONE_AREA_ALPHA = 0.45;\nconst COLOR_DOCK: Color = [92, 92, 92];\nconst COLOR_ROBOT: Color = [39, 139, 61];\nconst COLOR_PATH: Color = [126, 216, 96];\nconst COLOR_HEADING: Color = [20, 20, 20];\nconst MIN_PATH_SEGMENT_DISTANCE_SQUARED = 1.5 ** 2;\nconst MAX_PATH_SEGMENT_DISTANCE_SQUARED = 90 ** 2;\nconst ROUTED_PATH_PADDING_PIXELS = 24;\nconst MAX_ROUTED_PATH_CELLS = 20_000;\nconst PATH_LINE_RADIUS = 1;\nconst ROBOT_GLIDE_DURATION_MS = 1_600;\n\ninterface ProjectedRobotPose {\n\tpoint: [number, number];\n\tphi: number | undefined;\n}\n\ninterface RobotRuntimeRenderResult {\n\tprojectedPoseCount: number;\n\tpathLineSegments: number;\n\tskippedPathSegments: number;\n\tlatest?: ProjectedRobotPose;\n\tlatestMotionPath?: Array<[number, number]>;\n}\n\nexport function extractRobotPose20001(data: unknown): RobotPose | undefined {\n\tconst record = getRecord(data);\n\tconst pos = parsePoint(record?.pos);\n\tif (!pos) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpos,\n\t\tphi: typeof record?.phi === \"number\" ? record.phi : undefined,\n\t};\n}\n\nexport function normalizeLiveMapBackgroundColor(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn /^#[0-9a-f]{6}$/iu.test(trimmed) ? trimmed.toLowerCase() : undefined;\n}\n\nexport function transitionLiveMapTaskState(\n\tstate: LiveMapTaskState,\n\tmode: string | undefined,\n\tcleaningActivityActive: boolean,\n): LiveMapTaskTransition {\n\tif (mode === \"sweep\") {\n\t\treturn {\n\t\t\tstate: { dockedSinceLastCleaning: false, returningToDock: false, cleaningTaskActive: true },\n\t\t\tresetTrail: state.dockedSinceLastCleaning,\n\t\t\tcompletedTask: false,\n\t\t};\n\t}\n\n\tif (mode === \"backcharge\") {\n\t\treturn {\n\t\t\tstate: {\n\t\t\t\tdockedSinceLastCleaning: state.dockedSinceLastCleaning,\n\t\t\t\treturningToDock: true,\n\t\t\t\tcleaningTaskActive: state.cleaningTaskActive,\n\t\t\t},\n\t\t\tresetTrail: false,\n\t\t\tcompletedTask: false,\n\t\t};\n\t}\n\n\tif (mode === \"charge\" || mode === \"fullcharge\") {\n\t\tif (state.returningToDock || (!state.cleaningTaskActive && !cleaningActivityActive)) {\n\t\t\treturn {\n\t\t\t\tstate: { dockedSinceLastCleaning: true, returningToDock: false, cleaningTaskActive: false },\n\t\t\t\tresetTrail: false,\n\t\t\t\tcompletedTask: state.cleaningTaskActive,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { state, resetTrail: false, completedTask: false };\n}\n\nexport function renderLiveMapImage20002(\n\tdata: unknown,\n\tposes: readonly RobotPose[] = [],\n\toptions: LiveMapRenderOptions = {},\n): LiveMapImage | undefined {\n\tconst sample = parseMapSample(data);\n\tif (!sample) {\n\t\treturn undefined;\n\t}\n\n\tconst compressed = decodeMapPayload(sample.encoded);\n\tconst occupancy = decompressLz4Block(compressed, sample.width * sample.height);\n\tif (occupancy.length !== sample.width * sample.height) {\n\t\treturn undefined;\n\t}\n\n\tconst mapBackgroundColor = colorFromHex(options.mapBackgroundColor ?? options.backgroundColor) ?? COLOR_UNKNOWN;\n\tconst canvasBackgroundColor = colorFromHex(options.canvasBackgroundColor) ?? COLOR_CANVAS_BACKGROUND;\n\tconst basePixels = renderOccupancy(\n\t\tsample.width,\n\t\tsample.height,\n\t\toccupancy,\n\t\tmapBackgroundColor,\n\t\tcanvasBackgroundColor,\n\t);\n\tconst coordinateMetadata = drawCoordinateMetadata(\n\t\tsample,\n\t\tbasePixels,\n\t\toptions.showZoneOverlays !== false,\n\t\tnew Set(options.selectedZoneIds ?? []),\n\t);\n\tconst runtime = drawRobotRuntime(sample, occupancy, basePixels, poses);\n\tconst basePng = encodeRgbPng(sample.width, sample.height, basePixels);\n\tconst fallbackPixels = Buffer.from(basePixels);\n\tif (runtime.latest) {\n\t\tdrawRobotMarker(fallbackPixels, sample.width, sample.height, runtime.latest);\n\t}\n\tconst fallbackPng = encodeRgbPng(sample.width, sample.height, fallbackPixels);\n\tconst pngDataUrl = `data:image/png;base64,${fallbackPng.toString(\"base64\")}`;\n\tconst areas = summarizeRenderedAreas(sample);\n\tconst svg = renderLiveMapSvg(\n\t\tsample.width,\n\t\tsample.height,\n\t\tbasePng,\n\t\truntime,\n\t\toptions.animateRobot !== false,\n\t\toptions.showZoneOverlays !== false ? areas : [],\n\t);\n\tconst svgDataUrl = `data:image/svg+xml;base64,${Buffer.from(svg, \"utf8\").toString(\"base64\")}`;\n\tif (\n\t\tBuffer.byteLength(svgDataUrl, \"utf8\") > MAX_LIVE_MAP_DATA_URL_BYTES ||\n\t\tBuffer.byteLength(pngDataUrl, \"utf8\") > MAX_LIVE_MAP_DATA_URL_BYTES\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tdataUrl: svgDataUrl,\n\t\tsvgDataUrl,\n\t\tpngDataUrl,\n\t\tformat: \"svg\",\n\t\twidth: sample.width,\n\t\theight: sample.height,\n\t\tareas,\n\t\tposeCount: runtime.projectedPoseCount,\n\t\trawPoseCount: poses.length,\n\t\tpathLineSegments: runtime.pathLineSegments,\n\t\tskippedPathSegments: runtime.skippedPathSegments,\n\t\trenderedForbiddenAreaCount: coordinateMetadata.renderedForbiddenAreaCount,\n\t\trenderedZoneAreaCount: coordinateMetadata.renderedZoneAreaCount,\n\t\t// Kept as a compatibility alias while consumers migrate to the accurate zone name.\n\t\trenderedRoomAreaCount: coordinateMetadata.renderedRoomAreaCount,\n\t\torientation: \"flip-y\",\n\t\tdecompressedBytes: occupancy.length,\n\t};\n}\n\nexport function extractLiveMapCoordinateMetadata20002(data: unknown): LiveMapCoordinateMetadata | undefined {\n\tconst record = getRecord(data);\n\tif (!record) {\n\t\treturn undefined;\n\t}\n\n\tconst metadata: LiveMapCoordinateMetadata = {};\n\tif (typeof record.mapId === \"number\") {\n\t\tmetadata.mapId = record.mapId;\n\t}\n\tconst chargeHandlePos = parsePoint(record.chargeHandlePos);\n\tif (chargeHandlePos) {\n\t\tmetadata.chargeHandlePos = chargeHandlePos;\n\t}\n\n\treturn metadata.mapId !== undefined || metadata.area !== undefined || metadata.chargeHandlePos !== undefined\n\t\t? metadata\n\t\t: undefined;\n}\n\nexport function extractLiveMapZoneCatalog21004(data: unknown): LiveMapCoordinateMetadata | undefined {\n\tconst record = getRecord(data);\n\tif (\n\t\t!record ||\n\t\t!Number.isSafeInteger(record.mapId) ||\n\t\t(record.mapId as number) < 0 ||\n\t\t!Array.isArray(record.value)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst areas = normalizeMapZoneCatalog(record.value);\n\tif (areas.length !== record.value.length) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tmapId: record.mapId as number,\n\t\tarea: areas,\n\t};\n}\n\nexport function replaceLiveMapZoneCatalog(\n\tprevious: LiveMapCoordinateMetadata | undefined,\n\tcatalog: LiveMapCoordinateMetadata,\n): LiveMapCoordinateMetadata {\n\tconst sameMap = previous?.mapId === undefined || previous.mapId === catalog.mapId;\n\treturn {\n\t\tmapId: catalog.mapId,\n\t\tarea: catalog.area ?? [],\n\t\tchargeHandlePos: sameMap ? previous?.chargeHandlePos : undefined,\n\t};\n}\n\nexport function mergeLiveMapCoordinateMetadata20002(\n\tdata: unknown,\n\tmetadata: LiveMapCoordinateMetadata | undefined,\n): unknown {\n\tconst record = getRecord(data);\n\tif (!record || !metadata) {\n\t\treturn data;\n\t}\n\n\tif (metadata.mapId !== undefined && typeof record.mapId === \"number\" && metadata.mapId !== record.mapId) {\n\t\treturn data;\n\t}\n\n\tconst merged = { ...record };\n\tmerged.area = (metadata.area ?? []).map(area => ({\n\t\t...area.source,\n\t\t__proscenicKind: area.kind,\n\t}));\n\tif (metadata.chargeHandlePos && !parsePoint(record.chargeHandlePos)) {\n\t\tmerged.chargeHandlePos = metadata.chargeHandlePos;\n\t}\n\treturn merged;\n}\n\nexport function countLiveMapAreas20002(data: unknown): number {\n\tconst record = getRecord(data);\n\treturn Array.isArray(record?.area) ? record.area.length : 0;\n}\n\nexport function mergeLiveMapCoordinateMetadataCache(\n\tprevious: LiveMapCoordinateMetadata | undefined,\n\tnext: LiveMapCoordinateMetadata,\n): LiveMapCoordinateMetadata {\n\tconst sameMap = previous?.mapId === undefined || next.mapId === undefined || previous.mapId === next.mapId;\n\tconst previousAreas = sameMap ? (previous?.area ?? []) : [];\n\n\treturn {\n\t\tmapId: next.mapId ?? previous?.mapId,\n\t\tarea: mergeAreaMetadata(previousAreas, next.area ?? []),\n\t\tchargeHandlePos: next.chargeHandlePos ?? (sameMap ? previous?.chargeHandlePos : undefined),\n\t};\n}\n\nfunction parseMapSample(data: unknown): MapSample | undefined {\n\tconst record = getRecord(data);\n\tif (!record) {\n\t\treturn undefined;\n\t}\n\n\tconst encoded = record.map;\n\tconst width = record.width;\n\tconst height = record.height;\n\tif (typeof encoded !== \"string\" || typeof width !== \"number\" || typeof height !== \"number\") {\n\t\treturn undefined;\n\t}\n\tif (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width <= 0 || height <= 0) {\n\t\treturn undefined;\n\t}\n\tif (width * height > MAX_LIVE_MAP_PIXELS) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tencoded,\n\t\twidth,\n\t\theight,\n\t\tresolution: typeof record.resolution === \"number\" ? record.resolution : undefined,\n\t\txMin: typeof record.x_min === \"number\" ? record.x_min : undefined,\n\t\tyMin: typeof record.y_min === \"number\" ? record.y_min : undefined,\n\t\tareas: parseMapAreas(record.area),\n\t\tchargeHandlePos: parsePoint(record.chargeHandlePos),\n\t};\n}\n\nfunction renderOccupancy(\n\twidth: number,\n\theight: number,\n\toccupancy: Buffer,\n\tmapBackgroundColor: Color,\n\tcanvasBackgroundColor: Color,\n): Buffer {\n\tconst pixels = Buffer.alloc(width * height * 3);\n\tfor (let index = 0; index < occupancy.length; index++) {\n\t\tconst sourceX = index % width;\n\t\tconst sourceY = Math.floor(index / width);\n\t\tconst targetY = height - 1 - sourceY;\n\t\tconst value = occupancy[index];\n\t\tif (value === 0) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, COLOR_WALL);\n\t\t} else if (value === 127) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, canvasBackgroundColor);\n\t\t} else if (value === 255) {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, mapBackgroundColor);\n\t\t} else {\n\t\t\tsetPixel(pixels, width, height, sourceX, targetY, value < 127 ? COLOR_OBSTACLE : canvasBackgroundColor);\n\t\t}\n\t}\n\treturn pixels;\n}\n\nfunction colorFromHex(value: string | undefined): Color | undefined {\n\tconst normalized = normalizeLiveMapBackgroundColor(value);\n\tif (!normalized) {\n\t\treturn undefined;\n\t}\n\treturn [\n\t\tNumber.parseInt(normalized.slice(1, 3), 16),\n\t\tNumber.parseInt(normalized.slice(3, 5), 16),\n\t\tNumber.parseInt(normalized.slice(5, 7), 16),\n\t];\n}\n\nfunction drawCoordinateMetadata(\n\tsample: MapSample,\n\tpixels: Buffer,\n\tshowZoneOverlays: boolean,\n\tselectedZoneIds: ReadonlySet<number>,\n): { renderedForbiddenAreaCount: number; renderedZoneAreaCount: number; renderedRoomAreaCount: number } {\n\tlet renderedForbiddenAreaCount = 0;\n\tlet renderedZoneAreaCount = 0;\n\tfor (const area of showZoneOverlays ? sample.areas : []) {\n\t\tconst projected = area.vertices\n\t\t\t.map(vertex => projectRobotCoordinate(sample, vertex))\n\t\t\t.filter((vertex): vertex is [number, number] => vertex !== undefined);\n\t\tif (projected.length >= 3) {\n\t\t\tif (area.kind === \"zone\") {\n\t\t\t\tconst selected = typeof area.source.id === \"number\" && selectedZoneIds.has(area.source.id);\n\t\t\t\tfillPolygon(\n\t\t\t\t\tpixels,\n\t\t\t\t\tsample.width,\n\t\t\t\t\tsample.height,\n\t\t\t\t\tprojected,\n\t\t\t\t\tselected ? COLOR_SELECTED_ZONE_AREA : COLOR_ZONE_AREA,\n\t\t\t\t\tselected ? SELECTED_ZONE_AREA_ALPHA : ZONE_AREA_ALPHA,\n\t\t\t\t);\n\t\t\t\tdrawPolygon(\n\t\t\t\t\tpixels,\n\t\t\t\t\tsample.width,\n\t\t\t\t\tsample.height,\n\t\t\t\t\tprojected,\n\t\t\t\t\tselected ? COLOR_SELECTED_ZONE_AREA_OUTLINE : COLOR_ZONE_AREA_OUTLINE,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t\trenderedZoneAreaCount += 1;\n\t\t\t} else if (area.kind === \"forbidden\") {\n\t\t\t\tfillPolygon(pixels, sample.width, sample.height, projected, COLOR_FORBIDDEN_AREA, FORBIDDEN_AREA_ALPHA);\n\t\t\t\tdrawPolygon(pixels, sample.width, sample.height, projected, COLOR_FORBIDDEN_OUTLINE);\n\t\t\t\trenderedForbiddenAreaCount += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (sample.chargeHandlePos) {\n\t\tconst charge = projectRobotCoordinate(sample, sample.chargeHandlePos);\n\t\tif (charge) {\n\t\t\tplotMarker(pixels, sample.width, sample.height, charge[0], charge[1], 5, COLOR_DOCK);\n\t\t}\n\t}\n\n\treturn {\n\t\trenderedForbiddenAreaCount,\n\t\trenderedZoneAreaCount,\n\t\trenderedRoomAreaCount: renderedZoneAreaCount,\n\t};\n}\n\nfunction drawRobotRuntime(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpixels: Buffer,\n\tposes: readonly RobotPose[],\n): RobotRuntimeRenderResult {\n\tconst projected = poses\n\t\t.map(pose => ({\n\t\t\tpoint: projectRobotCoordinate(sample, pose.pos),\n\t\t\tphi: pose.phi,\n\t\t}))\n\t\t.filter((pose): pose is { point: [number, number]; phi: number | undefined } => pose.point !== undefined);\n\n\tlet pathLineSegments = 0;\n\tlet skippedPathSegments = 0;\n\tlet latestMotionPath: Array<[number, number]> | undefined;\n\n\tfor (let index = 1; index < projected.length; index++) {\n\t\tconst previous = projected[index - 1].point;\n\t\tconst current = projected[index].point;\n\t\tconst segmentDistanceSquared = distanceSquared(previous, current);\n\t\tif (\n\t\t\tsegmentDistanceSquared >= MIN_PATH_SEGMENT_DISTANCE_SQUARED &&\n\t\t\tsegmentDistanceSquared <= MAX_PATH_SEGMENT_DISTANCE_SQUARED\n\t\t) {\n\t\t\tconst routedPath = findDrawablePath(sample, occupancy, previous, current);\n\t\t\tif (routedPath) {\n\t\t\t\tdrawAdaptivePathPolyline(sample, occupancy, pixels, sample.width, sample.height, routedPath);\n\t\t\t\tpathLineSegments += 1;\n\t\t\t\tif (index === projected.length - 1) {\n\t\t\t\t\tlatestMotionPath = routedPath;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tskippedPathSegments += 1;\n\t\t\t}\n\t\t} else {\n\t\t\tskippedPathSegments += 1;\n\t\t}\n\t}\n\n\tconst latest = projected.at(-1);\n\tif (!latest) {\n\t\treturn {\n\t\t\tprojectedPoseCount: 0,\n\t\t\tpathLineSegments,\n\t\t\tskippedPathSegments,\n\t\t};\n\t}\n\n\treturn {\n\t\tprojectedPoseCount: projected.length,\n\t\tpathLineSegments,\n\t\tskippedPathSegments,\n\t\tlatest,\n\t\tlatestMotionPath,\n\t};\n}\n\nfunction drawRobotMarker(pixels: Buffer, width: number, height: number, pose: ProjectedRobotPose): void {\n\tplotMarker(pixels, width, height, pose.point[0], pose.point[1], 5, COLOR_ROBOT);\n\tif (pose.phi === undefined) {\n\t\treturn;\n\t}\n\tconst angle = pose.phi / 1000;\n\tconst headingLength = 10;\n\tconst endX = Math.round(pose.point[0] + Math.cos(angle) * headingLength);\n\tconst endY = Math.round(pose.point[1] - Math.sin(angle) * headingLength);\n\tdrawLine(pixels, width, height, pose.point[0], pose.point[1], endX, endY, COLOR_HEADING);\n}\n\nfunction renderLiveMapSvg(\n\twidth: number,\n\theight: number,\n\tbasePng: Buffer,\n\truntime: RobotRuntimeRenderResult,\n\tanimateRobot: boolean,\n\tareas: readonly LiveMapRenderedArea[],\n): string {\n\tconst marker = runtime.latest ? renderSvgRobotMarker(runtime.latest, runtime.latestMotionPath, animateRobot) : \"\";\n\tconst zoneLabels = renderSvgZoneLabels(areas);\n\tconst embeddedPng = `data:image/png;base64,${basePng.toString(\"base64\")}`;\n\treturn [\n\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\" preserveAspectRatio=\"xMidYMid meet\">`,\n\t\t`<image href=\"${embeddedPng}\" width=\"${width}\" height=\"${height}\"/>`,\n\t\tzoneLabels,\n\t\tmarker,\n\t\t\"</svg>\",\n\t].join(\"\");\n}\n\nfunction renderSvgZoneLabels(areas: readonly LiveMapRenderedArea[]): string {\n\treturn areas\n\t\t.filter(\n\t\t\t(\n\t\t\t\tarea,\n\t\t\t): area is LiveMapRenderedArea & { label: string; bounds: NonNullable<LiveMapRenderedArea[\"bounds\"]> } =>\n\t\t\t\tarea.kind === \"zone\" && area.label !== undefined && area.bounds !== undefined,\n\t\t)\n\t\t.map(area => {\n\t\t\tconst x = area.center?.x ?? (area.bounds.minX + area.bounds.maxX) / 2;\n\t\t\tconst y = area.center?.y ?? (area.bounds.minY + area.bounds.maxY) / 2;\n\t\t\treturn `<text data-zone-label=\"true\" x=\"${roundSvgNumber(x)}\" y=\"${roundSvgNumber(y)}\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"system-ui, sans-serif\" font-size=\"9\" font-weight=\"600\" fill=\"#263b4a\" stroke=\"#ffffff\" stroke-width=\"2\" stroke-linejoin=\"round\" paint-order=\"stroke\">${escapeSvgText(area.label)}</text>`;\n\t\t})\n\t\t.join(\"\");\n}\n\nfunction escapeSvgText(value: string): string {\n\treturn value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n}\n\nfunction renderSvgRobotMarker(\n\tlatest: ProjectedRobotPose,\n\tmotionPath: readonly [number, number][] | undefined,\n\tanimateRobot: boolean,\n): string {\n\tconst path = animateRobot && motionPath && motionPath.length > 1 ? motionPath : [latest.point];\n\tconst finalRotation = latest.phi === undefined ? 0 : (-latest.phi / 1000 / Math.PI) * 180;\n\tconst marker = [\n\t\t`<circle cx=\"0\" cy=\"0\" r=\"5\" fill=\"#278b3d\" stroke=\"#145f2b\" stroke-width=\"1\"/>`,\n\t\t`<line x1=\"0\" y1=\"0\" x2=\"10\" y2=\"0\" stroke=\"#141414\" stroke-width=\"2\" stroke-linecap=\"round\" transform=\"rotate(${roundSvgNumber(finalRotation)})\"/>`,\n\t].join(\"\");\n\tif (path.length === 1) {\n\t\treturn `<g transform=\"translate(${path[0][0]} ${path[0][1]})\">${marker}</g>`;\n\t}\n\tconst svgPath = path.map((point, index) => `${index === 0 ? \"M\" : \"L\"}${point[0]} ${point[1]}`).join(\" \");\n\treturn `<g>${marker}<animateMotion dur=\"${ROBOT_GLIDE_DURATION_MS}ms\" path=\"${svgPath}\" calcMode=\"paced\" fill=\"freeze\"/></g>`;\n}\n\nfunction roundSvgNumber(value: number): number {\n\treturn Math.round(value * 100) / 100;\n}\n\nfunction drawAdaptivePathLine(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcanDraw?: (x: number, y: number) => boolean,\n): void {\n\tdrawLineWithPixelColor(pixels, width, height, x1, y1, x2, y2, (x, y) =>\n\t\tcanDraw && !canDraw(x, y) ? undefined : COLOR_PATH,\n\t);\n\tdrawLineNeighbors(pixels, width, height, x1, y1, x2, y2, canDraw);\n}\n\nfunction drawAdaptivePathPolyline(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpoints: readonly [number, number][],\n): void {\n\tconst canDraw = (x: number, y: number): boolean => isTraversableMapPixel(sample, occupancy, x, y);\n\tfor (let index = 1; index < points.length; index++) {\n\t\tconst [x1, y1] = points[index - 1];\n\t\tconst [x2, y2] = points[index];\n\t\tdrawAdaptivePathLine(pixels, width, height, x1, y1, x2, y2, canDraw);\n\t}\n}\n\nfunction findDrawablePath(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): Array<[number, number]> | undefined {\n\tif (isDirectPathTraversable(sample, occupancy, start, end)) {\n\t\treturn [start, end];\n\t}\n\n\treturn findRoutedPath(sample, occupancy, start, end);\n}\n\nfunction isDirectPathTraversable(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): boolean {\n\tlet traversedCells = 0;\n\tlet blockedCells = 0;\n\tforEachLinePoint(start[0], start[1], end[0], end[1], (x, y) => {\n\t\ttraversedCells += 1;\n\t\tif (!isTraversableMapPixel(sample, occupancy, x, y)) {\n\t\t\tblockedCells += 1;\n\t\t}\n\t});\n\treturn traversedCells > 0 && blockedCells === 0;\n}\n\nfunction findRoutedPath(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tstart: [number, number],\n\tend: [number, number],\n): Array<[number, number]> | undefined {\n\tconst routeStart = nearestTraversablePoint(sample, occupancy, start);\n\tconst routeEnd = nearestTraversablePoint(sample, occupancy, end);\n\tif (!routeStart || !routeEnd) {\n\t\treturn undefined;\n\t}\n\n\tconst minX = Math.max(0, Math.min(routeStart[0], routeEnd[0]) - ROUTED_PATH_PADDING_PIXELS);\n\tconst maxX = Math.min(sample.width - 1, Math.max(routeStart[0], routeEnd[0]) + ROUTED_PATH_PADDING_PIXELS);\n\tconst minY = Math.max(0, Math.min(routeStart[1], routeEnd[1]) - ROUTED_PATH_PADDING_PIXELS);\n\tconst maxY = Math.min(sample.height - 1, Math.max(routeStart[1], routeEnd[1]) + ROUTED_PATH_PADDING_PIXELS);\n\tconst searchWidth = maxX - minX + 1;\n\tconst searchHeight = maxY - minY + 1;\n\tif (searchWidth * searchHeight > MAX_ROUTED_PATH_CELLS) {\n\t\treturn undefined;\n\t}\n\n\tconst distance = new Map<number, number>();\n\tconst previous = new Map<number, number>();\n\tconst queue: Array<{ key: number; score: number }> = [];\n\tconst startKey = localPointKey(routeStart[0], routeStart[1], minX, minY, searchWidth);\n\tconst endKey = localPointKey(routeEnd[0], routeEnd[1], minX, minY, searchWidth);\n\tdistance.set(startKey, 0);\n\tqueue.push({ key: startKey, score: heuristic(routeStart, routeEnd) });\n\n\twhile (queue.length > 0) {\n\t\tqueue.sort((left, right) => left.score - right.score);\n\t\tconst current = queue.shift();\n\t\tif (!current) {\n\t\t\tbreak;\n\t\t}\n\t\tif (current.key === endKey) {\n\t\t\treturn restoreRoutedPath(previous, current.key, minX, minY, searchWidth);\n\t\t}\n\n\t\tconst [currentX, currentY] = pointFromLocalKey(current.key, minX, minY, searchWidth);\n\t\tconst currentDistance = distance.get(current.key) ?? Number.POSITIVE_INFINITY;\n\t\tfor (let dy = -1; dy <= 1; dy++) {\n\t\t\tfor (let dx = -1; dx <= 1; dx++) {\n\t\t\t\tif (dx === 0 && dy === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst nextX = currentX + dx;\n\t\t\t\tconst nextY = currentY + dy;\n\t\t\t\tif (\n\t\t\t\t\tnextX < minX ||\n\t\t\t\t\tnextX > maxX ||\n\t\t\t\t\tnextY < minY ||\n\t\t\t\t\tnextY > maxY ||\n\t\t\t\t\t!isTraversableMapPixel(sample, occupancy, nextX, nextY)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst nextKey = localPointKey(nextX, nextY, minX, minY, searchWidth);\n\t\t\t\tconst nextDistance = currentDistance + (dx !== 0 && dy !== 0 ? Math.SQRT2 : 1);\n\t\t\t\tif (nextDistance >= (distance.get(nextKey) ?? Number.POSITIVE_INFINITY)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdistance.set(nextKey, nextDistance);\n\t\t\t\tprevious.set(nextKey, current.key);\n\t\t\t\tqueue.push({ key: nextKey, score: nextDistance + heuristic([nextX, nextY], routeEnd) });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction restoreRoutedPath(\n\tprevious: ReadonlyMap<number, number>,\n\tendKey: number,\n\tminX: number,\n\tminY: number,\n\twidth: number,\n): Array<[number, number]> {\n\tconst keys = [endKey];\n\tlet current = endKey;\n\twhile (previous.has(current)) {\n\t\tcurrent = previous.get(current) ?? current;\n\t\tkeys.push(current);\n\t}\n\treturn simplifyPath(keys.reverse().map(key => pointFromLocalKey(key, minX, minY, width)));\n}\n\nfunction simplifyPath(points: Array<[number, number]>): Array<[number, number]> {\n\tif (points.length <= 2) {\n\t\treturn points;\n\t}\n\tconst simplified: Array<[number, number]> = [points[0]];\n\tlet previousDirection: [number, number] | undefined;\n\tfor (let index = 1; index < points.length; index++) {\n\t\tconst direction: [number, number] = [\n\t\t\tMath.sign(points[index][0] - points[index - 1][0]),\n\t\t\tMath.sign(points[index][1] - points[index - 1][1]),\n\t\t];\n\t\tif (previousDirection && (direction[0] !== previousDirection[0] || direction[1] !== previousDirection[1])) {\n\t\t\tsimplified.push(points[index - 1]);\n\t\t}\n\t\tpreviousDirection = direction;\n\t}\n\tsimplified.push(points.at(-1) ?? points[0]);\n\treturn simplified;\n}\n\nfunction nearestTraversablePoint(\n\tsample: MapSample,\n\toccupancy: Buffer,\n\tpoint: [number, number],\n): [number, number] | undefined {\n\tif (isTraversableMapPixel(sample, occupancy, point[0], point[1])) {\n\t\treturn point;\n\t}\n\tfor (let radius = 1; radius <= 3; radius++) {\n\t\tfor (let y = point[1] - radius; y <= point[1] + radius; y++) {\n\t\t\tfor (let x = point[0] - radius; x <= point[0] + radius; x++) {\n\t\t\t\tif (isTraversableMapPixel(sample, occupancy, x, y)) {\n\t\t\t\t\treturn [x, y];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isTraversableMapPixel(sample: MapSample, occupancy: Buffer, x: number, y: number): boolean {\n\tif (x < 0 || x >= sample.width || y < 0 || y >= sample.height) {\n\t\treturn false;\n\t}\n\tconst sourceY = sample.height - 1 - y;\n\tconst value = occupancy[sourceY * sample.width + x];\n\treturn value >= 127;\n}\n\nfunction localPointKey(x: number, y: number, minX: number, minY: number, width: number): number {\n\treturn (y - minY) * width + (x - minX);\n}\n\nfunction pointFromLocalKey(key: number, minX: number, minY: number, width: number): [number, number] {\n\treturn [minX + (key % width), minY + Math.floor(key / width)];\n}\n\nfunction heuristic(left: [number, number], right: [number, number]): number {\n\treturn Math.hypot(left[0] - right[0], left[1] - right[1]);\n}\n\nfunction drawLineNeighbors(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcanDraw?: (x: number, y: number) => boolean,\n): void {\n\tfor (let dy = -PATH_LINE_RADIUS; dy <= PATH_LINE_RADIUS; dy++) {\n\t\tfor (let dx = -PATH_LINE_RADIUS; dx <= PATH_LINE_RADIUS; dx++) {\n\t\t\tif ((dx === 0 && dy === 0) || dx * dx + dy * dy > PATH_LINE_RADIUS * PATH_LINE_RADIUS) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdrawLineWithPixelColor(pixels, width, height, x1 + dx, y1 + dy, x2 + dx, y2 + dy, (x, y) =>\n\t\t\t\tcanDraw && !canDraw(x, y) ? undefined : COLOR_PATH,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction projectRobotCoordinate(sample: MapSample, point: [number, number]): [number, number] | undefined {\n\tif (sample.resolution === undefined || sample.xMin === undefined || sample.yMin === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst xMeters = point[0] / 1000;\n\tconst yMeters = point[1] / 1000;\n\tconst x = Math.round((xMeters - sample.xMin) / sample.resolution);\n\tconst y = sample.height - 1 - Math.round((yMeters - sample.yMin) / sample.resolution);\n\tif (x < 0 || x >= sample.width || y < 0 || y >= sample.height) {\n\t\treturn undefined;\n\t}\n\treturn [x, y];\n}\n\nfunction parseMapAreas(value: unknown): MapArea[] {\n\treturn normalizeMapAreaMetadata(value).map(area => ({\n\t\tkey: area.key,\n\t\tvertices: parseVertices(area.source.vertexs),\n\t\tkind: area.kind,\n\t\tsource: area.source,\n\t}));\n}\n\nfunction summarizeRenderedAreas(sample: MapSample): LiveMapRenderedArea[] {\n\treturn sample.areas.map(area => {\n\t\tconst projected = area.vertices\n\t\t\t.map(point => projectRobotCoordinate(sample, point))\n\t\t\t.filter((point): point is [number, number] => point !== undefined);\n\t\tconst id =\n\t\t\ttypeof area.source.id === \"number\" || typeof area.source.id === \"string\" ? area.source.id : undefined;\n\t\tconst label = firstUsefulLabel(area.source.tag, area.source.name);\n\n\t\treturn {\n\t\t\tkey: area.key,\n\t\t\tkind: area.kind,\n\t\t\t...(id !== undefined ? { id } : {}),\n\t\t\t...(label !== undefined ? { label } : {}),\n\t\t\t...(projected.length > 0 ? { center: polygonCenter(projected) } : {}),\n\t\t\t...(projected.length > 0 ? { bounds: boundsFor(projected) } : {}),\n\t\t};\n\t});\n}\n\nfunction firstUsefulLabel(...values: unknown[]): string | undefined {\n\tfor (const value of values) {\n\t\tif (typeof value === \"string\" && value.trim().length > 0) {\n\t\t\treturn value\n\t\t\t\t.trim()\n\t\t\t\t.replace(/[\\p{Cc}\\p{Cf}]/gu, \" \")\n\t\t\t\t.slice(0, 128);\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction boundsFor(points: readonly [number, number][]): LiveMapRenderedArea[\"bounds\"] {\n\tconst xs = points.map(([x]) => x);\n\tconst ys = points.map(([, y]) => y);\n\treturn {\n\t\tminX: Math.min(...xs),\n\t\tminY: Math.min(...ys),\n\t\tmaxX: Math.max(...xs),\n\t\tmaxY: Math.max(...ys),\n\t};\n}\n\nfunction polygonCenter(points: readonly [number, number][]): { x: number; y: number } {\n\tlet twiceArea = 0;\n\tlet weightedX = 0;\n\tlet weightedY = 0;\n\tfor (let index = 0; index < points.length; index++) {\n\t\tconst [x1, y1] = points[index];\n\t\tconst [x2, y2] = points[(index + 1) % points.length];\n\t\tconst cross = x1 * y2 - x2 * y1;\n\t\ttwiceArea += cross;\n\t\tweightedX += (x1 + x2) * cross;\n\t\tweightedY += (y1 + y2) * cross;\n\t}\n\n\tif (Math.abs(twiceArea) > Number.EPSILON) {\n\t\treturn {\n\t\t\tx: roundSvgNumber(weightedX / (3 * twiceArea)),\n\t\t\ty: roundSvgNumber(weightedY / (3 * twiceArea)),\n\t\t};\n\t}\n\n\treturn {\n\t\tx: roundSvgNumber(points.reduce((sum, [x]) => sum + x, 0) / points.length),\n\t\ty: roundSvgNumber(points.reduce((sum, [, y]) => sum + y, 0) / points.length),\n\t};\n}\n\nfunction normalizeMapAreaMetadata(value: unknown): LiveMapAreaMetadata[] {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\n\tconst candidates = value\n\t\t.map(entry => {\n\t\t\tconst record = getRecord(entry);\n\t\t\tif (!record) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst vertices = parseVertices(record.vertexs);\n\t\t\tif (vertices.length < 3) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst key = mapAreaKey(record, vertices);\n\t\t\tconst explicitKind = parseAreaKind(record.__proscenicKind);\n\t\t\treturn {\n\t\t\t\tkey,\n\t\t\t\texplicitKind,\n\t\t\t\tsource: record,\n\t\t\t};\n\t\t})\n\t\t.filter(\n\t\t\t(\n\t\t\t\tentry,\n\t\t\t): entry is {\n\t\t\t\tkey: string;\n\t\t\t\texplicitKind: LiveMapAreaKind | undefined;\n\t\t\t\tsource: Record<string, unknown>;\n\t\t\t} => entry !== undefined,\n\t\t);\n\n\tconst normalized = new Map<string, LiveMapAreaMetadata>();\n\tfor (const candidate of candidates) {\n\t\tconst kind = candidate.explicitKind ?? \"unknown\";\n\t\tconst existing = normalized.get(candidate.key);\n\t\tconst next = {\n\t\t\tkey: candidate.key,\n\t\t\tkind,\n\t\t\tsource: withoutInternalAreaMetadata(candidate.source),\n\t\t};\n\t\tnormalized.set(candidate.key, existing ? mergeAreaMetadataEntry(existing, next) : next);\n\t}\n\n\treturn [...normalized.values()];\n}\n\nfunction normalizeMapZoneCatalog(value: readonly unknown[]): LiveMapAreaMetadata[] {\n\tconst normalized = new Map<string, LiveMapAreaMetadata>();\n\tfor (const entry of value) {\n\t\tconst record = getRecord(entry);\n\t\tif (!record) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst vertices = parseVertices(record.vertexs);\n\t\tif (vertices.length < 3) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = record.id;\n\t\tif (!(typeof id === \"string\" || (typeof id === \"number\" && Number.isSafeInteger(id)))) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst source: Record<string, unknown> = {\n\t\t\tid,\n\t\t\tvertexs: vertices,\n\t\t};\n\t\tfor (const field of [\"active\", \"mode\", \"name\", \"tag\"] as const) {\n\t\t\tif (typeof record[field] === \"string\") {\n\t\t\t\tsource[field] = record[field];\n\t\t\t}\n\t\t}\n\t\tconst key = mapAreaKey(source, vertices);\n\t\tnormalized.set(key, {\n\t\t\tkey,\n\t\t\tkind: record.active === \"forbid\" ? \"forbidden\" : \"zone\",\n\t\t\tsource,\n\t\t});\n\t}\n\treturn [...normalized.values()];\n}\n\nfunction mergeAreaMetadata(\n\tprevious: readonly LiveMapAreaMetadata[],\n\tnext: readonly LiveMapAreaMetadata[],\n): LiveMapAreaMetadata[] {\n\tconst merged = new Map<string, LiveMapAreaMetadata>();\n\tfor (const area of [...previous, ...next]) {\n\t\tconst existing = merged.get(area.key);\n\t\tmerged.set(area.key, existing ? mergeAreaMetadataEntry(existing, area) : area);\n\t}\n\treturn [...merged.values()];\n}\n\nfunction mergeAreaMetadataEntry(left: LiveMapAreaMetadata, right: LiveMapAreaMetadata): LiveMapAreaMetadata {\n\treturn {\n\t\tkey: right.key,\n\t\tkind: strongestAreaKind(left.kind, right.kind),\n\t\tsource: right.source,\n\t};\n}\n\nfunction strongestAreaKind(left: LiveMapAreaKind, right: LiveMapAreaKind): LiveMapAreaKind {\n\tif (left === \"forbidden\" || right === \"forbidden\") {\n\t\treturn \"forbidden\";\n\t}\n\tif (left === \"zone\" || right === \"zone\") {\n\t\treturn \"zone\";\n\t}\n\treturn \"unknown\";\n}\n\nfunction parseAreaKind(value: unknown): LiveMapAreaKind | undefined {\n\tif (value === \"room\") {\n\t\treturn \"zone\";\n\t}\n\treturn value === \"forbidden\" || value === \"zone\" || value === \"unknown\" ? value : undefined;\n}\n\nfunction withoutInternalAreaMetadata(record: Record<string, unknown>): Record<string, unknown> {\n\tconst clone = { ...record };\n\tdelete clone.__proscenicKind;\n\treturn clone;\n}\n\nfunction parseVertices(value: unknown): Array<[number, number]> {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\treturn value.map(vertex => parsePoint(vertex)).filter((vertex): vertex is [number, number] => vertex !== undefined);\n}\n\nfunction mapAreaKey(record: Record<string, unknown>, vertices: readonly [number, number][]): string {\n\tconst id = record.id;\n\tif (typeof id === \"number\" || typeof id === \"string\") {\n\t\treturn `id:${String(id)}`;\n\t}\n\tconst xs = vertices.map(([x]) => x);\n\tconst ys = vertices.map(([, y]) => y);\n\treturn `shape:${vertices.length}:${Math.min(...xs)}:${Math.min(...ys)}:${Math.max(...xs)}:${Math.max(...ys)}`;\n}\n\nfunction parsePoint(value: unknown): [number, number] | undefined {\n\tif (Array.isArray(value) && value.length >= 2 && typeof value[0] === \"number\" && typeof value[1] === \"number\") {\n\t\treturn [value[0], value[1]];\n\t}\n\treturn undefined;\n}\n\nfunction getRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction decodeMapPayload(encodedMap: string): Buffer {\n\treturn Buffer.from(encodedMap.replace(/\\s/gu, \"+\"), \"base64\");\n}\n\nfunction decompressLz4Block(input: Buffer, maxOutputBytes: number): Buffer {\n\tconst output = Buffer.alloc(maxOutputBytes);\n\tlet inputOffset = 0;\n\tlet outputOffset = 0;\n\n\twhile (inputOffset < input.length) {\n\t\tconst token = input[inputOffset++];\n\t\tlet literalLength = token >> 4;\n\t\tif (literalLength === 15) {\n\t\t\tlet next: number;\n\t\t\tdo {\n\t\t\t\tif (inputOffset >= input.length) {\n\t\t\t\t\tthrow new Error(\"literal length overflow\");\n\t\t\t\t}\n\t\t\t\tnext = input[inputOffset++];\n\t\t\t\tliteralLength += next;\n\t\t\t} while (next === 255);\n\t\t}\n\n\t\tif (inputOffset + literalLength > input.length || outputOffset + literalLength > output.length) {\n\t\t\tthrow new Error(\"literal overrun\");\n\t\t}\n\t\tinput.copy(output, outputOffset, inputOffset, inputOffset + literalLength);\n\t\tinputOffset += literalLength;\n\t\toutputOffset += literalLength;\n\n\t\tif (inputOffset >= input.length) {\n\t\t\tbreak;\n\t\t}\n\t\tif (inputOffset + 2 > input.length) {\n\t\t\tthrow new Error(\"offset overrun\");\n\t\t}\n\t\tconst matchOffset = input[inputOffset] | (input[inputOffset + 1] << 8);\n\t\tinputOffset += 2;\n\t\tif (matchOffset === 0 || matchOffset > outputOffset) {\n\t\t\tthrow new Error(\"bad match offset\");\n\t\t}\n\n\t\tlet matchLength = token & 0x0f;\n\t\tif (matchLength === 15) {\n\t\t\tlet next: number;\n\t\t\tdo {\n\t\t\t\tif (inputOffset >= input.length) {\n\t\t\t\t\tthrow new Error(\"match length overflow\");\n\t\t\t\t}\n\t\t\t\tnext = input[inputOffset++];\n\t\t\t\tmatchLength += next;\n\t\t\t} while (next === 255);\n\t\t}\n\t\tmatchLength += 4;\n\t\tif (outputOffset + matchLength > output.length) {\n\t\t\tthrow new Error(\"match overrun\");\n\t\t}\n\t\tfor (let index = 0; index < matchLength; index++) {\n\t\t\toutput[outputOffset + index] = output[outputOffset - matchOffset + index];\n\t\t}\n\t\toutputOffset += matchLength;\n\t}\n\n\treturn output.subarray(0, outputOffset);\n}\n\nfunction fillPolygon(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpolygon: Array<[number, number]>,\n\tcolor: Color,\n\talpha = 1,\n): void {\n\tconst minY = Math.max(0, Math.min(...polygon.map(([, y]) => y)));\n\tconst maxY = Math.min(height - 1, Math.max(...polygon.map(([, y]) => y)));\n\n\tfor (let y = minY; y <= maxY; y++) {\n\t\tconst intersections: number[] = [];\n\t\tfor (let index = 0; index < polygon.length; index++) {\n\t\t\tconst [x1, y1] = polygon[index];\n\t\t\tconst [x2, y2] = polygon[(index + 1) % polygon.length];\n\t\t\tif ((y1 <= y && y2 > y) || (y2 <= y && y1 > y)) {\n\t\t\t\tconst x = x1 + ((y - y1) * (x2 - x1)) / (y2 - y1);\n\t\t\t\tintersections.push(Math.round(x));\n\t\t\t}\n\t\t}\n\n\t\tintersections.sort((left, right) => left - right);\n\t\tfor (let index = 0; index + 1 < intersections.length; index += 2) {\n\t\t\tconst start = Math.max(0, intersections[index]);\n\t\t\tconst end = Math.min(width - 1, intersections[index + 1]);\n\t\t\tfor (let x = start; x <= end; x++) {\n\t\t\t\tblendPixel(pixels, width, height, x, y, color, alpha);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drawPolygon(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tpolygon: Array<[number, number]>,\n\tcolor: Color,\n\tradius = 0,\n): void {\n\tfor (let index = 0; index < polygon.length; index++) {\n\t\tconst [x1, y1] = polygon[index];\n\t\tconst [x2, y2] = polygon[(index + 1) % polygon.length];\n\t\tfor (let offsetY = -radius; offsetY <= radius; offsetY++) {\n\t\t\tfor (let offsetX = -radius; offsetX <= radius; offsetX++) {\n\t\t\t\tdrawLine(pixels, width, height, x1 + offsetX, y1 + offsetY, x2 + offsetX, y2 + offsetY, color);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drawLine(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcolor: Color,\n): void {\n\tdrawLineWithPixelColor(pixels, width, height, x1, y1, x2, y2, () => color);\n}\n\nfunction forEachLinePoint(\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tcallback: (x: number, y: number) => void,\n): void {\n\tconst dx = Math.abs(x2 - x1);\n\tconst sx = x1 < x2 ? 1 : -1;\n\tconst dy = -Math.abs(y2 - y1);\n\tconst sy = y1 < y2 ? 1 : -1;\n\tlet error = dx + dy;\n\tlet x = x1;\n\tlet y = y1;\n\n\twhile (true) {\n\t\tcallback(x, y);\n\t\tif (x === x2 && y === y2) {\n\t\t\tbreak;\n\t\t}\n\t\tconst error2 = 2 * error;\n\t\tif (error2 >= dy) {\n\t\t\terror += dy;\n\t\t\tx += sx;\n\t\t}\n\t\tif (error2 <= dx) {\n\t\t\terror += dx;\n\t\t\ty += sy;\n\t\t}\n\t}\n}\n\nfunction drawLineWithPixelColor(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx1: number,\n\ty1: number,\n\tx2: number,\n\ty2: number,\n\tpickColor: (x: number, y: number) => Color | undefined,\n): void {\n\tconst dx = Math.abs(x2 - x1);\n\tconst sx = x1 < x2 ? 1 : -1;\n\tconst dy = -Math.abs(y2 - y1);\n\tconst sy = y1 < y2 ? 1 : -1;\n\tlet error = dx + dy;\n\tlet x = x1;\n\tlet y = y1;\n\n\twhile (true) {\n\t\tif (x >= 0 && x < width && y >= 0 && y < height) {\n\t\t\tconst color = pickColor(x, y);\n\t\t\tif (color) {\n\t\t\t\tsetPixel(pixels, width, height, x, y, color);\n\t\t\t}\n\t\t}\n\t\tif (x === x2 && y === y2) {\n\t\t\tbreak;\n\t\t}\n\t\tconst error2 = 2 * error;\n\t\tif (error2 >= dy) {\n\t\t\terror += dy;\n\t\t\tx += sx;\n\t\t}\n\t\tif (error2 <= dx) {\n\t\t\terror += dx;\n\t\t\ty += sy;\n\t\t}\n\t}\n}\n\nfunction plotMarker(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx: number,\n\ty: number,\n\tradius: number,\n\tcolor: Color,\n): void {\n\tfor (let dy = -radius; dy <= radius; dy++) {\n\t\tfor (let dx = -radius; dx <= radius; dx++) {\n\t\t\tconst px = x + dx;\n\t\t\tconst py = y + dy;\n\t\t\tif (px >= 0 && px < width && py >= 0 && py < height && dx * dx + dy * dy <= radius * radius) {\n\t\t\t\tsetPixel(pixels, width, height, px, py, color);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction setPixel(pixels: Buffer, width: number, height: number, x: number, y: number, color: Color): void {\n\tif (x < 0 || x >= width || y < 0 || y >= height) {\n\t\treturn;\n\t}\n\n\tconst offset = (y * width + x) * 3;\n\tpixels[offset] = color[0];\n\tpixels[offset + 1] = color[1];\n\tpixels[offset + 2] = color[2];\n}\n\nfunction blendPixel(\n\tpixels: Buffer,\n\twidth: number,\n\theight: number,\n\tx: number,\n\ty: number,\n\tcolor: Color,\n\talpha: number,\n): void {\n\tif (alpha >= 1) {\n\t\tsetPixel(pixels, width, height, x, y, color);\n\t\treturn;\n\t}\n\tif (x < 0 || x >= width || y < 0 || y >= height) {\n\t\treturn;\n\t}\n\n\tconst offset = (y * width + x) * 3;\n\tpixels[offset] = Math.round(pixels[offset] * (1 - alpha) + color[0] * alpha);\n\tpixels[offset + 1] = Math.round(pixels[offset + 1] * (1 - alpha) + color[1] * alpha);\n\tpixels[offset + 2] = Math.round(pixels[offset + 2] * (1 - alpha) + color[2] * alpha);\n}\n\nfunction distanceSquared(left: [number, number], right: [number, number]): number {\n\treturn (left[0] - right[0]) ** 2 + (left[1] - right[1]) ** 2;\n}\n\nfunction encodeRgbPng(width: number, height: number, pixels: Buffer): Buffer {\n\tif (pixels.length !== width * height * 3) {\n\t\tthrow new Error(`Expected ${width * height * 3} RGB pixels but received ${pixels.length}`);\n\t}\n\n\tconst header = Buffer.alloc(13);\n\theader.writeUInt32BE(width, 0);\n\theader.writeUInt32BE(height, 4);\n\theader[8] = 8;\n\theader[9] = 2;\n\n\tconst rowBytes = width * 3;\n\tconst scanlines = Buffer.alloc((rowBytes + 1) * height);\n\tfor (let y = 0; y < height; y++) {\n\t\tscanlines[y * (rowBytes + 1)] = 0;\n\t\tpixels.copy(scanlines, y * (rowBytes + 1) + 1, y * rowBytes, (y + 1) * rowBytes);\n\t}\n\n\treturn Buffer.concat([\n\t\tPNG_SIGNATURE,\n\t\tpngChunk(\"IHDR\", header),\n\t\tpngChunk(\"IDAT\", deflateSync(scanlines)),\n\t\tpngChunk(\"IEND\", Buffer.alloc(0)),\n\t]);\n}\n\nfunction pngChunk(type: string, data: Buffer): Buffer {\n\tconst typeBuffer = Buffer.from(type, \"ascii\");\n\tconst length = Buffer.alloc(4);\n\tlength.writeUInt32BE(data.length, 0);\n\tconst checksum = Buffer.alloc(4);\n\tchecksum.writeUInt32BE(crc32(Buffer.concat([typeBuffer, data])), 0);\n\treturn Buffer.concat([length, typeBuffer, data, checksum]);\n}\n\nfunction crc32(data: Buffer): number {\n\tlet crc = 0xffffffff;\n\tfor (const byte of data) {\n\t\tcrc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n\t}\n\treturn (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction createCrcTable(): readonly number[] {\n\treturn Array.from({ length: 256 }, (_, index) => {\n\t\tlet value = index;\n\t\tfor (let bit = 0; bit < 8; bit++) {\n\t\t\tvalue = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;\n\t\t}\n\t\treturn value >>> 0;\n\t});\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -20,12 +20,21 @@ var zone_cleaning_exports = {};
|
|
|
20
20
|
__export(zone_cleaning_exports, {
|
|
21
21
|
buildZoneCleaningRequest: () => buildZoneCleaningRequest,
|
|
22
22
|
normalizeZoneSelection: () => normalizeZoneSelection,
|
|
23
|
+
shouldRecoverPendingZoneCleaningSelection: () => shouldRecoverPendingZoneCleaningSelection,
|
|
23
24
|
validateZoneCleaningSelection: () => validateZoneCleaningSelection,
|
|
24
25
|
zoneCleaningOptions: () => zoneCleaningOptions
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(zone_cleaning_exports);
|
|
27
28
|
const MAX_SELECTED_ZONES = 20;
|
|
28
29
|
const MAX_ZONE_LABEL_LENGTH = 128;
|
|
30
|
+
const ACCEPTED_ZONE_CLEANING_RESULTS = /* @__PURE__ */ new Set(["api-accepted", "api-accepted-unconfirmed", "status-confirmed"]);
|
|
31
|
+
function shouldRecoverPendingZoneCleaningSelection(selectedZoneCount, selectionChangedAtMs, lastCommand, lastResult, lastExecution) {
|
|
32
|
+
if (selectedZoneCount <= 0 || selectionChangedAtMs === void 0 || lastCommand !== "zoneCleaning" || typeof lastResult !== "string" || !ACCEPTED_ZONE_CLEANING_RESULTS.has(lastResult) || typeof lastExecution !== "string") {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const executionAtMs = Date.parse(lastExecution);
|
|
36
|
+
return Number.isFinite(executionAtMs) && executionAtMs >= selectionChangedAtMs;
|
|
37
|
+
}
|
|
29
38
|
function normalizeZoneSelection(value) {
|
|
30
39
|
if (value === null || value === void 0) {
|
|
31
40
|
return [];
|
|
@@ -109,6 +118,7 @@ function firstLabel(...values) {
|
|
|
109
118
|
0 && (module.exports = {
|
|
110
119
|
buildZoneCleaningRequest,
|
|
111
120
|
normalizeZoneSelection,
|
|
121
|
+
shouldRecoverPendingZoneCleaningSelection,
|
|
112
122
|
validateZoneCleaningSelection,
|
|
113
123
|
zoneCleaningOptions
|
|
114
124
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/domain/zone-cleaning.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CommandRequest } from \"./commands\";\nimport type { LiveMapCoordinateMetadata } from \"./live-map\";\n\nconst MAX_SELECTED_ZONES = 20;\nconst MAX_ZONE_LABEL_LENGTH = 128;\n\nexport interface ZoneCleaningSelection {\n\tmapId: number;\n\tzoneIds: number[];\n}\n\nexport interface ZoneCleaningOption {\n\tid: number;\n\tlabel?: string;\n}\n\nexport function normalizeZoneSelection(value: ioBroker.StateValue | undefined): number[] | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn [];\n\t}\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\tconst trimmed = value.trim();\n\tif (trimmed === \"\") {\n\t\treturn [];\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = trimmed.startsWith(\"[\") ? JSON.parse(trimmed) : trimmed.split(\",\").map(entry => entry.trim());\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (!Array.isArray(parsed) || parsed.length > MAX_SELECTED_ZONES) {\n\t\treturn undefined;\n\t}\n\n\tconst ids: number[] = [];\n\tfor (const candidate of parsed) {\n\t\tconst id = typeof candidate === \"number\" ? candidate : Number(candidate);\n\t\tif (!Number.isSafeInteger(id) || id < 0 || ids.includes(id)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tids.push(id);\n\t}\n\treturn ids;\n}\n\nexport function zoneCleaningOptions(catalog: LiveMapCoordinateMetadata | undefined): ZoneCleaningOption[] {\n\treturn (catalog?.area ?? []).flatMap(area => {\n\t\tif (area.kind !== \"zone\") {\n\t\t\treturn [];\n\t\t}\n\t\tconst id = normalizeZoneId(area.source.id);\n\t\tif (id === undefined) {\n\t\t\treturn [];\n\t\t}\n\t\tconst label = firstLabel(area.source.name, area.source.tag);\n\t\treturn [{ id, ...(label ? { label } : {}) }];\n\t});\n}\n\nexport function validateZoneCleaningSelection(\n\tzoneIds: readonly number[],\n\tmapId: number | undefined,\n\tcatalog: LiveMapCoordinateMetadata | undefined,\n): ZoneCleaningSelection {\n\tif (zoneIds.length === 0) {\n\t\tthrow new Error(\"No map zones are selected\");\n\t}\n\tif (!Number.isSafeInteger(mapId) || (mapId as number) < 0) {\n\t\tthrow new Error(\"No active map is available for zone cleaning\");\n\t}\n\tif (catalog?.mapId !== mapId) {\n\t\tthrow new Error(\"The map zone catalog does not match the active map\");\n\t}\n\n\tconst available = new Set(zoneCleaningOptions(catalog).map(option => option.id));\n\tif (zoneIds.some(id => !available.has(id))) {\n\t\tthrow new Error(\"The selected map zones are no longer available\");\n\t}\n\n\treturn { mapId: mapId as number, zoneIds: [...zoneIds] };\n}\n\nexport function buildZoneCleaningRequest(\n\tselection: ZoneCleaningSelection,\n\tserial: string,\n\tusername: string,\n): CommandRequest {\n\treturn {\n\t\tpath: `/instructions/cmd30000/${encodeURIComponent(serial)}/${selection.mapId}?username=${encodeURIComponent(username)}&part=true`,\n\t\tcontentType: \"application/json;charset=UTF-8\",\n\t\tbody: JSON.stringify(selection.zoneIds),\n\t};\n}\n\nfunction normalizeZoneId(value: unknown): number | undefined {\n\tconst id = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : Number.NaN;\n\treturn Number.isSafeInteger(id) && id >= 0 ? id : undefined;\n}\n\nfunction firstLabel(...values: unknown[]): string | undefined {\n\tfor (const value of values) {\n\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\treturn value\n\t\t\t\t.trim()\n\t\t\t\t.replace(/[\\p{Cc}\\p{Cf}]/gu, \" \")\n\t\t\t\t.slice(0, MAX_ZONE_LABEL_LENGTH);\n\t\t}\n\t}\n\treturn undefined;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,MAAM,qBAAqB;AAC3B,MAAM,wBAAwB;
|
|
4
|
+
"sourcesContent": ["import type { CommandRequest } from \"./commands\";\nimport type { LiveMapCoordinateMetadata } from \"./live-map\";\n\nconst MAX_SELECTED_ZONES = 20;\nconst MAX_ZONE_LABEL_LENGTH = 128;\n\nexport interface ZoneCleaningSelection {\n\tmapId: number;\n\tzoneIds: number[];\n}\n\nexport interface ZoneCleaningOption {\n\tid: number;\n\tlabel?: string;\n}\n\nconst ACCEPTED_ZONE_CLEANING_RESULTS = new Set([\"api-accepted\", \"api-accepted-unconfirmed\", \"status-confirmed\"]);\n\nexport function shouldRecoverPendingZoneCleaningSelection(\n\tselectedZoneCount: number,\n\tselectionChangedAtMs: number | undefined,\n\tlastCommand: unknown,\n\tlastResult: unknown,\n\tlastExecution: unknown,\n): boolean {\n\tif (\n\t\tselectedZoneCount <= 0 ||\n\t\tselectionChangedAtMs === undefined ||\n\t\tlastCommand !== \"zoneCleaning\" ||\n\t\ttypeof lastResult !== \"string\" ||\n\t\t!ACCEPTED_ZONE_CLEANING_RESULTS.has(lastResult) ||\n\t\ttypeof lastExecution !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\n\tconst executionAtMs = Date.parse(lastExecution);\n\treturn Number.isFinite(executionAtMs) && executionAtMs >= selectionChangedAtMs;\n}\n\nexport function normalizeZoneSelection(value: ioBroker.StateValue | undefined): number[] | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn [];\n\t}\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\tconst trimmed = value.trim();\n\tif (trimmed === \"\") {\n\t\treturn [];\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = trimmed.startsWith(\"[\") ? JSON.parse(trimmed) : trimmed.split(\",\").map(entry => entry.trim());\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (!Array.isArray(parsed) || parsed.length > MAX_SELECTED_ZONES) {\n\t\treturn undefined;\n\t}\n\n\tconst ids: number[] = [];\n\tfor (const candidate of parsed) {\n\t\tconst id = typeof candidate === \"number\" ? candidate : Number(candidate);\n\t\tif (!Number.isSafeInteger(id) || id < 0 || ids.includes(id)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tids.push(id);\n\t}\n\treturn ids;\n}\n\nexport function zoneCleaningOptions(catalog: LiveMapCoordinateMetadata | undefined): ZoneCleaningOption[] {\n\treturn (catalog?.area ?? []).flatMap(area => {\n\t\tif (area.kind !== \"zone\") {\n\t\t\treturn [];\n\t\t}\n\t\tconst id = normalizeZoneId(area.source.id);\n\t\tif (id === undefined) {\n\t\t\treturn [];\n\t\t}\n\t\tconst label = firstLabel(area.source.name, area.source.tag);\n\t\treturn [{ id, ...(label ? { label } : {}) }];\n\t});\n}\n\nexport function validateZoneCleaningSelection(\n\tzoneIds: readonly number[],\n\tmapId: number | undefined,\n\tcatalog: LiveMapCoordinateMetadata | undefined,\n): ZoneCleaningSelection {\n\tif (zoneIds.length === 0) {\n\t\tthrow new Error(\"No map zones are selected\");\n\t}\n\tif (!Number.isSafeInteger(mapId) || (mapId as number) < 0) {\n\t\tthrow new Error(\"No active map is available for zone cleaning\");\n\t}\n\tif (catalog?.mapId !== mapId) {\n\t\tthrow new Error(\"The map zone catalog does not match the active map\");\n\t}\n\n\tconst available = new Set(zoneCleaningOptions(catalog).map(option => option.id));\n\tif (zoneIds.some(id => !available.has(id))) {\n\t\tthrow new Error(\"The selected map zones are no longer available\");\n\t}\n\n\treturn { mapId: mapId as number, zoneIds: [...zoneIds] };\n}\n\nexport function buildZoneCleaningRequest(\n\tselection: ZoneCleaningSelection,\n\tserial: string,\n\tusername: string,\n): CommandRequest {\n\treturn {\n\t\tpath: `/instructions/cmd30000/${encodeURIComponent(serial)}/${selection.mapId}?username=${encodeURIComponent(username)}&part=true`,\n\t\tcontentType: \"application/json;charset=UTF-8\",\n\t\tbody: JSON.stringify(selection.zoneIds),\n\t};\n}\n\nfunction normalizeZoneId(value: unknown): number | undefined {\n\tconst id = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : Number.NaN;\n\treturn Number.isSafeInteger(id) && id >= 0 ? id : undefined;\n}\n\nfunction firstLabel(...values: unknown[]): string | undefined {\n\tfor (const value of values) {\n\t\tif (typeof value === \"string\" && value.trim() !== \"\") {\n\t\t\treturn value\n\t\t\t\t.trim()\n\t\t\t\t.replace(/[\\p{Cc}\\p{Cf}]/gu, \" \")\n\t\t\t\t.slice(0, MAX_ZONE_LABEL_LENGTH);\n\t\t}\n\t}\n\treturn undefined;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|