@7365admin1/core 3.83.0 → 3.85.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/dist/index.js CHANGED
@@ -77,6 +77,7 @@ __export(src_exports, {
77
77
  ConsoleAuditAction: () => ConsoleAuditAction,
78
78
  ConsoleAuditTarget: () => ConsoleAuditTarget,
79
79
  DEFAULT_RING_SECONDS: () => DEFAULT_RING_SECONDS,
80
+ DEFAULT_SCALE_M_PER_PX: () => DEFAULT_SCALE_M_PER_PX,
80
81
  DEFAULT_SITE_TIMEZONE: () => DEFAULT_SITE_TIMEZONE,
81
82
  DEVICE_STATUS: () => DEVICE_STATUS,
82
83
  DOBStatus: () => DOBStatus,
@@ -247,6 +248,7 @@ __export(src_exports, {
247
248
  ROBOT_CAPABILITIES: () => ROBOT_CAPABILITIES,
248
249
  ROBOT_CLOUD_DOC_CONFIRMATIONS: () => ROBOT_CLOUD_DOC_CONFIRMATIONS,
249
250
  ROBOT_CLOUD_PATHS: () => ROBOT_CLOUD_PATHS,
251
+ ROBOT_CLOUD_TIMEOUT_MS: () => ROBOT_CLOUD_TIMEOUT_MS,
250
252
  ROBOT_MODULE: () => ROBOT_MODULE,
251
253
  ROBOT_PERMISSIONS: () => ROBOT_PERMISSIONS,
252
254
  ROBOT_STATUS_NAMES: () => ROBOT_STATUS_NAMES,
@@ -296,6 +298,8 @@ __export(src_exports, {
296
298
  VerificationType: () => VerificationType,
297
299
  VisitorSort: () => VisitorSort,
298
300
  VisitorStatus: () => VisitorStatus,
301
+ WALL_HEIGHT_M: () => WALL_HEIGHT_M,
302
+ WALL_THICKNESS_M: () => WALL_THICKNESS_M,
299
303
  addressSchema: () => addressSchema,
300
304
  allowedFieldsSite: () => allowedFieldsSite,
301
305
  allowedNatures: () => allowedNatures,
@@ -307,6 +311,8 @@ __export(src_exports, {
307
311
  attendanceSchema: () => attendanceSchema,
308
312
  attendanceSettingsSchema: () => attendanceSettingsSchema,
309
313
  buildSelfServiceEmailContext: () => buildSelfServiceEmailContext,
314
+ buildingMapFromRobotMaps: () => buildingMapFromRobotMaps,
315
+ buildingSolids: () => buildingSolids,
310
316
  building_level_namespace_collection: () => building_level_namespace_collection,
311
317
  building_units_namespace_collection: () => building_units_namespace_collection,
312
318
  buildings_namespace_collection: () => buildings_namespace_collection,
@@ -413,6 +419,9 @@ __export(src_exports, {
413
419
  isTermsCurrent: () => isTermsCurrent,
414
420
  isTrackingStale: () => isTrackingStale,
415
421
  isValidTimezone: () => isValidTimezone,
422
+ levelPixelToMetres: () => levelPixelToMetres,
423
+ levelScale: () => levelScale,
424
+ levelSolids: () => levelSolids,
416
425
  listStaffUserIds: () => listStaffUserIds,
417
426
  liveStatusFor: () => liveStatusFor,
418
427
  manpowerDesignationsSchema: () => manpowerDesignationsSchema,
@@ -511,6 +520,7 @@ __export(src_exports, {
511
520
  robotTier: () => robotTier,
512
521
  robotTypesVisibleTo: () => robotTypesVisibleTo,
513
522
  rtspUrl: () => rtspUrl,
523
+ scaleFromMeasurement: () => scaleFromMeasurement,
514
524
  schema: () => schema,
515
525
  schemaAppSlugNotification: () => schemaAppSlugNotification,
516
526
  schemaApprovedBy: () => schemaApprovedBy,
@@ -677,6 +687,7 @@ __export(src_exports, {
677
687
  snapshotEndpoint: () => snapshotEndpoint,
678
688
  snapshotRefusalReason: () => snapshotRefusalReason,
679
689
  staffMayBypass: () => staffMayBypass,
690
+ startRobotTracking: () => startRobotTracking,
680
691
  startTodaysBookForSite: () => startTodaysBookForSite,
681
692
  stringifyHidJson: () => stringifyHidJson,
682
693
  stripFacialImageMetadata: () => stripFacialImageMetadata,
@@ -928,8 +939,10 @@ __export(src_exports, {
928
939
  vehicleSchema: () => vehicleSchema,
929
940
  vehicleViewOf: () => vehicleViewOf,
930
941
  vehicles_namespace_collection: () => vehicles_namespace_collection,
942
+ vertexDistancePx: () => vertexDistancePx,
931
943
  visitors_namespace_collection: () => visitors_namespace_collection,
932
944
  wallConfig: () => wallConfig,
945
+ wallsFromOccupancyGrid: () => wallsFromOccupancyGrid,
933
946
  withLiveLink: () => withLiveLink,
934
947
  workOrderSchema: () => workOrderSchema,
935
948
  work_orders2_namespace_collection: () => work_orders2_namespace_collection,
@@ -60127,6 +60140,179 @@ function createLiftSimulator(options) {
60127
60140
  };
60128
60141
  }
60129
60142
 
60143
+ // src/utils/building-map.util.ts
60144
+ var WALL_HEIGHT_M = 2.5;
60145
+ var WALL_THICKNESS_M = 0.1;
60146
+ var DEFAULT_SCALE_M_PER_PX = 0.05;
60147
+ function scaleFromMeasurement(pixelDistance, realDistanceM) {
60148
+ if (!Number.isFinite(pixelDistance) || pixelDistance <= 0) {
60149
+ throw new Error("A measurement needs a positive pixel distance.");
60150
+ }
60151
+ if (!Number.isFinite(realDistanceM) || realDistanceM <= 0) {
60152
+ throw new Error("A measurement needs a positive real distance in metres.");
60153
+ }
60154
+ return realDistanceM / pixelDistance;
60155
+ }
60156
+ function vertexDistancePx(a, b) {
60157
+ return Math.hypot(b.x - a.x, b.y - a.y);
60158
+ }
60159
+ function levelScale(level) {
60160
+ const measurement = level.measurements?.find((m) => {
60161
+ const a = level.vertices[m.start];
60162
+ const b = level.vertices[m.end];
60163
+ return a && b && m.distanceM > 0 && vertexDistancePx(a, b) > 0;
60164
+ });
60165
+ if (measurement) {
60166
+ return scaleFromMeasurement(
60167
+ vertexDistancePx(level.vertices[measurement.start], level.vertices[measurement.end]),
60168
+ measurement.distanceM
60169
+ );
60170
+ }
60171
+ return level.scaleMPerPx > 0 ? level.scaleMPerPx : DEFAULT_SCALE_M_PER_PX;
60172
+ }
60173
+ function levelPixelToMetres(level, px, py, imageHeightPx) {
60174
+ const scale = levelScale(level);
60175
+ return {
60176
+ x: level.originXM + px * scale,
60177
+ y: level.originYM + (imageHeightPx - py) * scale
60178
+ };
60179
+ }
60180
+ function levelSolids(level, imageHeightPx) {
60181
+ const toM = (v) => levelPixelToMetres(level, v.x, v.y, imageHeightPx);
60182
+ const walls = [];
60183
+ for (const wall of level.walls ?? []) {
60184
+ const a = level.vertices[wall.start];
60185
+ const b = level.vertices[wall.end];
60186
+ if (!a || !b)
60187
+ continue;
60188
+ const pa = toM(a);
60189
+ const pb = toM(b);
60190
+ const lengthM = Math.hypot(pb.x - pa.x, pb.y - pa.y);
60191
+ if (lengthM <= 0)
60192
+ continue;
60193
+ const heightM = wall.heightM ?? WALL_HEIGHT_M;
60194
+ walls.push({
60195
+ centre: {
60196
+ x: (pa.x + pb.x) / 2,
60197
+ y: (pa.y + pb.y) / 2,
60198
+ // Boxes are centred, so a wall standing ON the floor sits at half its
60199
+ // own height above the level's elevation.
60200
+ z: level.elevationM + heightM / 2
60201
+ },
60202
+ lengthM,
60203
+ thicknessM: wall.thicknessM ?? WALL_THICKNESS_M,
60204
+ heightM,
60205
+ yaw: Math.atan2(pb.y - pa.y, pb.x - pa.x)
60206
+ });
60207
+ }
60208
+ const floors = [];
60209
+ for (const floor of level.floors ?? []) {
60210
+ const points = (floor.vertices ?? []).map((i) => level.vertices[i]).filter(Boolean).map(toM);
60211
+ if (points.length < 3)
60212
+ continue;
60213
+ floors.push({ points, elevationM: level.elevationM, hole: floor.hole === true });
60214
+ }
60215
+ return { level: level.name, elevationM: level.elevationM, walls, floors };
60216
+ }
60217
+ function buildingSolids(map, imageHeightFor) {
60218
+ return (map.levels ?? []).map((level) => levelSolids(level, imageHeightFor(level)));
60219
+ }
60220
+ function wallsFromOccupancyGrid(grid, options) {
60221
+ const threshold = options?.threshold ?? 100;
60222
+ const minRun = Math.max(2, options?.minRunPx ?? 6);
60223
+ const { data, width, height } = grid;
60224
+ if (!width || !height || !data || data.length < width * height) {
60225
+ return { vertices: [], walls: [] };
60226
+ }
60227
+ const occupied = (x, y) => Number(data[y * width + x]) <= threshold;
60228
+ const consumed = new Uint8Array(width * height);
60229
+ const vertices = [];
60230
+ const walls = [];
60231
+ const index = /* @__PURE__ */ new Map();
60232
+ const vertexAt = (x, y) => {
60233
+ const key = `${x}:${y}`;
60234
+ const found = index.get(key);
60235
+ if (found !== void 0)
60236
+ return found;
60237
+ vertices.push({ x, y, z: 0 });
60238
+ index.set(key, vertices.length - 1);
60239
+ return vertices.length - 1;
60240
+ };
60241
+ const addRun = (x1, y1, x2, y2) => {
60242
+ walls.push({ start: vertexAt(x1, y1), end: vertexAt(x2, y2) });
60243
+ };
60244
+ for (let y = 0; y < height; y++) {
60245
+ let run = 0;
60246
+ for (let x = 0; x <= width; x++) {
60247
+ const on = x < width && occupied(x, y);
60248
+ if (on) {
60249
+ run++;
60250
+ continue;
60251
+ }
60252
+ if (run >= minRun) {
60253
+ const startX = x - run;
60254
+ addRun(startX, y, x - 1, y);
60255
+ for (let i = startX; i < x; i++)
60256
+ consumed[y * width + i] = 1;
60257
+ }
60258
+ run = 0;
60259
+ }
60260
+ }
60261
+ for (let x = 0; x < width; x++) {
60262
+ let run = 0;
60263
+ for (let y = 0; y <= height; y++) {
60264
+ const on = y < height && occupied(x, y) && !consumed[y * width + x];
60265
+ if (on) {
60266
+ run++;
60267
+ continue;
60268
+ }
60269
+ if (run >= minRun) {
60270
+ addRun(x, y - run, x, y - 1);
60271
+ }
60272
+ run = 0;
60273
+ }
60274
+ }
60275
+ return { vertices, walls };
60276
+ }
60277
+ function buildingMapFromRobotMaps(name, maps, floorHeightM = 3) {
60278
+ const levels = [...maps ?? []].sort((a, b) => a.floorNo - b.floorNo).map((map) => {
60279
+ const vertices = [];
60280
+ if (map.baseX || map.baseY) {
60281
+ vertices.push({
60282
+ x: map.baseX ?? 0,
60283
+ y: map.baseY ?? 0,
60284
+ z: 0,
60285
+ name: `L${map.floorNo}_charger`,
60286
+ isCharger: true,
60287
+ theta: map.baseTheta ?? 0
60288
+ });
60289
+ }
60290
+ for (const area of map.areaList ?? []) {
60291
+ vertices.push({
60292
+ x: area.x,
60293
+ y: area.y,
60294
+ z: 0,
60295
+ name: area.areaName,
60296
+ isCleaningZone: true
60297
+ });
60298
+ }
60299
+ return {
60300
+ name: map.mapName?.trim() || `L${map.floorNo}`,
60301
+ elevationM: (map.floorNo - 1) * floorHeightM,
60302
+ drawing: { fileKey: map.backgroundFileKey },
60303
+ scaleMPerPx: map.resolution && map.resolution > 0 ? map.resolution : DEFAULT_SCALE_M_PER_PX,
60304
+ originXM: map.originX ?? 0,
60305
+ originYM: map.originY ?? 0,
60306
+ vertices,
60307
+ walls: [],
60308
+ floors: [],
60309
+ doors: [],
60310
+ measurements: []
60311
+ };
60312
+ });
60313
+ return { name, levels, lifts: [] };
60314
+ }
60315
+
60130
60316
  // src/services/robot-fleet.service.ts
60131
60317
  var import_node_server_utils157 = require("@7365admin1/node-server-utils");
60132
60318
 
@@ -60507,6 +60693,145 @@ function registerOunitechBrand() {
60507
60693
  });
60508
60694
  }
60509
60695
 
60696
+ // src/services/robot-tracking.service.ts
60697
+ var import_axios4 = __toESM(require("axios"));
60698
+ async function openWithAxios(url, body) {
60699
+ const response = await import_axios4.default.post(url, body, {
60700
+ responseType: "stream",
60701
+ // No read timeout: this connection is SUPPOSED to stay open and mostly
60702
+ // silent. A request timeout here would sever a healthy stream on a quiet
60703
+ // robot. The idle watchdog is what decides a stream is dead, because it can
60704
+ // tell silence from a closed socket.
60705
+ timeout: 0,
60706
+ headers: { "Content-Type": "application/json", Accept: "text/event-stream" }
60707
+ });
60708
+ return response.data;
60709
+ }
60710
+ function startRobotTracking(options) {
60711
+ const {
60712
+ credentials,
60713
+ robotSn,
60714
+ onEvent,
60715
+ baseUrl = ROBOT_CLOUD_BASE_URL,
60716
+ idleTimeoutMs = TRACKING_IDLE_TIMEOUT_MS,
60717
+ openStream = openWithAxios,
60718
+ now = Date.now
60719
+ } = options;
60720
+ if (!baseUrl)
60721
+ throw new Error("Robot cloud: ROBOT_CLOUD_BASE_URL is not configured.");
60722
+ let stopped = false;
60723
+ let attempt = 0;
60724
+ let current = null;
60725
+ let watchdog = null;
60726
+ let retry = null;
60727
+ let lastActivityAt = now();
60728
+ let everConnected = false;
60729
+ const parser = createSseParser();
60730
+ function clearTimers() {
60731
+ if (watchdog) {
60732
+ clearInterval(watchdog);
60733
+ watchdog = null;
60734
+ }
60735
+ if (retry) {
60736
+ clearTimeout(retry);
60737
+ retry = null;
60738
+ }
60739
+ }
60740
+ function dropUpstream() {
60741
+ if (!current)
60742
+ return;
60743
+ try {
60744
+ current.destroy();
60745
+ } catch {
60746
+ }
60747
+ current = null;
60748
+ }
60749
+ function lose(reason) {
60750
+ if (stopped)
60751
+ return;
60752
+ onEvent({ type: "lost", reason, at: now() });
60753
+ dropUpstream();
60754
+ scheduleReconnect();
60755
+ }
60756
+ function scheduleReconnect() {
60757
+ if (stopped)
60758
+ return;
60759
+ clearTimers();
60760
+ const delay2 = trackingBackoffMs(attempt++);
60761
+ retry = setTimeout(connect2, delay2);
60762
+ }
60763
+ async function connect2() {
60764
+ if (stopped)
60765
+ return;
60766
+ const body = robotCloudBody(
60767
+ credentials.appid,
60768
+ credentials.secret,
60769
+ ROBOT_CLOUD_PATHS.tracking,
60770
+ { robotSn }
60771
+ );
60772
+ let stream;
60773
+ try {
60774
+ stream = await openStream(
60775
+ `${baseUrl.replace(/\/+$/, "")}${ROBOT_CLOUD_PATHS.tracking}`,
60776
+ body
60777
+ );
60778
+ } catch (error) {
60779
+ lose(error?.message ?? "Could not open the robot's tracking stream.");
60780
+ return;
60781
+ }
60782
+ if (stopped) {
60783
+ try {
60784
+ stream.destroy();
60785
+ } catch {
60786
+ }
60787
+ return;
60788
+ }
60789
+ parser.reset();
60790
+ current = stream;
60791
+ lastActivityAt = now();
60792
+ if (everConnected)
60793
+ onEvent({ type: "reconnected", at: now() });
60794
+ everConnected = true;
60795
+ attempt = 0;
60796
+ stream.on("data", (chunk) => {
60797
+ if (stopped)
60798
+ return;
60799
+ const { events, sawActivity } = parser.push(chunk.toString("utf8"));
60800
+ if (sawActivity)
60801
+ lastActivityAt = now();
60802
+ for (const event of events) {
60803
+ const pose = decodeTrackingFrame(event.data);
60804
+ if (pose)
60805
+ onEvent({ type: "pose", pose, at: now() });
60806
+ }
60807
+ });
60808
+ stream.on("error", (error) => lose(error?.message ?? "The tracking stream failed."));
60809
+ stream.on("end", () => lose("The robot cloud closed the tracking stream."));
60810
+ stream.on("close", () => {
60811
+ if (!stopped && current === stream)
60812
+ lose("The tracking stream closed.");
60813
+ });
60814
+ clearTimers();
60815
+ watchdog = setInterval(() => {
60816
+ if (stopped)
60817
+ return;
60818
+ if (now() - lastActivityAt >= idleTimeoutMs) {
60819
+ lose("The robot stopped reporting.");
60820
+ }
60821
+ }, Math.max(1e3, Math.floor(idleTimeoutMs / 3)));
60822
+ }
60823
+ void connect2();
60824
+ return {
60825
+ stop() {
60826
+ if (stopped)
60827
+ return;
60828
+ stopped = true;
60829
+ clearTimers();
60830
+ dropUpstream();
60831
+ }
60832
+ };
60833
+ }
60834
+
60510
60835
  // src/controllers/robot-fleet.controller.ts
60511
60836
  var import_joi76 = __toESM(require("joi"));
60512
60837
  var import_node_server_utils158 = require("@7365admin1/node-server-utils");
@@ -60585,7 +60910,55 @@ function useRobotFleetController(deps) {
60585
60910
  fail(next, error);
60586
60911
  }
60587
60912
  }
60588
- return { getState, getMaps, getMapImages, getPlans, sendCommand: sendCommand2 };
60913
+ async function trackRobot(req, res, next) {
60914
+ let robot;
60915
+ let robotSn;
60916
+ try {
60917
+ robot = await entitleRobot(req, req.params.id);
60918
+ robotSn = await getFleet().resolveRobotSn(robot);
60919
+ } catch (error) {
60920
+ fail(next, error);
60921
+ return;
60922
+ }
60923
+ res.writeHead(200, {
60924
+ "Content-Type": "text/event-stream",
60925
+ "Cache-Control": "no-cache, no-transform",
60926
+ Connection: "keep-alive",
60927
+ // Nginx buffers proxied responses by default, which holds an SSE stream
60928
+ // until the buffer fills - the stream appears dead for minutes.
60929
+ "X-Accel-Buffering": "no"
60930
+ });
60931
+ res.flushHeaders?.();
60932
+ const send2 = (event) => {
60933
+ if (res.writableEnded)
60934
+ return;
60935
+ res.write(`data: ${JSON.stringify(event)}
60936
+
60937
+ `);
60938
+ };
60939
+ const handle = startRobotTracking({
60940
+ credentials: {
60941
+ appid: (robot.appKey ?? "").trim(),
60942
+ secret: (robot.appToken ?? "").trim()
60943
+ },
60944
+ robotSn,
60945
+ onEvent: send2
60946
+ });
60947
+ const keepAlive = setInterval(() => {
60948
+ if (!res.writableEnded)
60949
+ res.write(": keep-alive\n\n");
60950
+ }, 15e3);
60951
+ const close = () => {
60952
+ clearInterval(keepAlive);
60953
+ handle.stop();
60954
+ if (!res.writableEnded)
60955
+ res.end();
60956
+ };
60957
+ req.on("close", close);
60958
+ req.on("aborted", close);
60959
+ res.on("error", close);
60960
+ }
60961
+ return { getState, getMaps, getMapImages, getPlans, sendCommand: sendCommand2, trackRobot };
60589
60962
  }
60590
60963
 
60591
60964
  // src/models/patrol-question.model.ts
@@ -80902,7 +81275,7 @@ var MManpowerMonitoring = class {
80902
81275
  var import_node_server_utils248 = require("@7365admin1/node-server-utils");
80903
81276
 
80904
81277
  // src/utils/hrmlabs-attendance.util.ts
80905
- var import_axios4 = __toESM(require("axios"));
81278
+ var import_axios5 = __toESM(require("axios"));
80906
81279
  var import_moment_timezone7 = __toESM(require("moment-timezone"));
80907
81280
  var default_early_checkIn = 4;
80908
81281
  async function hrmLabsAuthentication({
@@ -80911,7 +81284,7 @@ async function hrmLabsAuthentication({
80911
81284
  password,
80912
81285
  domain
80913
81286
  }) {
80914
- const res = await import_axios4.default.post(
81287
+ const res = await import_axios5.default.post(
80915
81288
  authUrl,
80916
81289
  {
80917
81290
  grant_type: "password",
@@ -80941,7 +81314,7 @@ async function fetchAttendanceData({
80941
81314
  search
80942
81315
  }) {
80943
81316
  try {
80944
- const res = await import_axios4.default.post(
81317
+ const res = await import_axios5.default.post(
80945
81318
  attendanceUrl,
80946
81319
  {
80947
81320
  start: startDate,
@@ -81141,7 +81514,7 @@ async function fetchSites({ siteUrl, token }) {
81141
81514
  do {
81142
81515
  try {
81143
81516
  attempt++;
81144
- const res = await import_axios4.default.get(siteUrl, {
81517
+ const res = await import_axios5.default.get(siteUrl, {
81145
81518
  headers: { Authorization: `Bearer ${token}` },
81146
81519
  timeout: 15e3
81147
81520
  });
@@ -84739,7 +85112,7 @@ async function manpowerEvents(io) {
84739
85112
  }
84740
85113
 
84741
85114
  // src/services/reddot-payment.service.ts
84742
- var import_axios5 = __toESM(require("axios"));
85115
+ var import_axios6 = __toESM(require("axios"));
84743
85116
 
84744
85117
  // src/utils/payment-signature.util.ts
84745
85118
  var crypto9 = __toESM(require("crypto"));
@@ -85373,7 +85746,7 @@ var useRedDotPaymentSvc = () => {
85373
85746
  );
85374
85747
  }
85375
85748
  const url = process.env.MERCHANT_PAYMENT;
85376
- const response = await import_axios5.default.post(url, dataString, { headers });
85749
+ const response = await import_axios6.default.post(url, dataString, { headers });
85377
85750
  const result = response.data;
85378
85751
  return result;
85379
85752
  } catch (error) {
@@ -85407,7 +85780,7 @@ var useRedDotPaymentSvc = () => {
85407
85780
  );
85408
85781
  }
85409
85782
  const url = process.env.MERCHANT_ENQUIRY;
85410
- const response = await import_axios5.default.post(url, dataString, { headers });
85783
+ const response = await import_axios6.default.post(url, dataString, { headers });
85411
85784
  const result = response.data;
85412
85785
  const transactionId = result.transaction_id;
85413
85786
  const amount = result.request_amount || 0;
@@ -93944,6 +94317,7 @@ function usePersonalEmergencyChainController() {
93944
94317
  ConsoleAuditAction,
93945
94318
  ConsoleAuditTarget,
93946
94319
  DEFAULT_RING_SECONDS,
94320
+ DEFAULT_SCALE_M_PER_PX,
93947
94321
  DEFAULT_SITE_TIMEZONE,
93948
94322
  DEVICE_STATUS,
93949
94323
  DOBStatus,
@@ -94114,6 +94488,7 @@ function usePersonalEmergencyChainController() {
94114
94488
  ROBOT_CAPABILITIES,
94115
94489
  ROBOT_CLOUD_DOC_CONFIRMATIONS,
94116
94490
  ROBOT_CLOUD_PATHS,
94491
+ ROBOT_CLOUD_TIMEOUT_MS,
94117
94492
  ROBOT_MODULE,
94118
94493
  ROBOT_PERMISSIONS,
94119
94494
  ROBOT_STATUS_NAMES,
@@ -94163,6 +94538,8 @@ function usePersonalEmergencyChainController() {
94163
94538
  VerificationType,
94164
94539
  VisitorSort,
94165
94540
  VisitorStatus,
94541
+ WALL_HEIGHT_M,
94542
+ WALL_THICKNESS_M,
94166
94543
  addressSchema,
94167
94544
  allowedFieldsSite,
94168
94545
  allowedNatures,
@@ -94174,6 +94551,8 @@ function usePersonalEmergencyChainController() {
94174
94551
  attendanceSchema,
94175
94552
  attendanceSettingsSchema,
94176
94553
  buildSelfServiceEmailContext,
94554
+ buildingMapFromRobotMaps,
94555
+ buildingSolids,
94177
94556
  building_level_namespace_collection,
94178
94557
  building_units_namespace_collection,
94179
94558
  buildings_namespace_collection,
@@ -94280,6 +94659,9 @@ function usePersonalEmergencyChainController() {
94280
94659
  isTermsCurrent,
94281
94660
  isTrackingStale,
94282
94661
  isValidTimezone,
94662
+ levelPixelToMetres,
94663
+ levelScale,
94664
+ levelSolids,
94283
94665
  listStaffUserIds,
94284
94666
  liveStatusFor,
94285
94667
  manpowerDesignationsSchema,
@@ -94378,6 +94760,7 @@ function usePersonalEmergencyChainController() {
94378
94760
  robotTier,
94379
94761
  robotTypesVisibleTo,
94380
94762
  rtspUrl,
94763
+ scaleFromMeasurement,
94381
94764
  schema,
94382
94765
  schemaAppSlugNotification,
94383
94766
  schemaApprovedBy,
@@ -94544,6 +94927,7 @@ function usePersonalEmergencyChainController() {
94544
94927
  snapshotEndpoint,
94545
94928
  snapshotRefusalReason,
94546
94929
  staffMayBypass,
94930
+ startRobotTracking,
94547
94931
  startTodaysBookForSite,
94548
94932
  stringifyHidJson,
94549
94933
  stripFacialImageMetadata,
@@ -94795,8 +95179,10 @@ function usePersonalEmergencyChainController() {
94795
95179
  vehicleSchema,
94796
95180
  vehicleViewOf,
94797
95181
  vehicles_namespace_collection,
95182
+ vertexDistancePx,
94798
95183
  visitors_namespace_collection,
94799
95184
  wallConfig,
95185
+ wallsFromOccupancyGrid,
94800
95186
  withLiveLink,
94801
95187
  workOrderSchema,
94802
95188
  work_orders2_namespace_collection,