@apocaliss92/nodedreame 1.11.3 → 1.11.4

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.cjs CHANGED
@@ -86,7 +86,7 @@ module.exports = __toCommonJS(index_exports);
86
86
 
87
87
  // src/support/version.ts
88
88
  var LIBRARY_NAME = "nodedreame";
89
- var LIBRARY_VERSION = "1.11.3";
89
+ var LIBRARY_VERSION = "1.11.4";
90
90
 
91
91
  // src/transport/errors.ts
92
92
  var DreameError = class extends Error {
@@ -2984,6 +2984,66 @@ var SCHEMES = {
2984
2984
  virtualWall: [195, 35, 35, 230],
2985
2985
  obstacle: [225, 145, 25, 255],
2986
2986
  label: [35, 42, 54, 255]
2987
+ },
2988
+ // Flat-design: soft neutral floor, bright low-saturation segment fills, thin
2989
+ // mid-grey walls, a single vivid accent for the path.
2990
+ flat: {
2991
+ floor: [236, 239, 241, 255],
2992
+ wall: [120, 132, 145, 255],
2993
+ carpet: [205, 185, 160, 200],
2994
+ segSat: 0.28,
2995
+ segVal: 0.99,
2996
+ path: [255, 138, 101, 240],
2997
+ robotBody: [38, 50, 56, 255],
2998
+ robotHeading: [255, 255, 255, 255],
2999
+ charger: [38, 166, 154, 255],
3000
+ noGoFill: [239, 83, 80, 60],
3001
+ noGoBorder: [229, 57, 53, 210],
3002
+ noMopFill: [66, 165, 245, 55],
3003
+ noMopBorder: [30, 136, 229, 200],
3004
+ virtualWall: [229, 57, 53, 225],
3005
+ obstacle: [255, 167, 38, 255],
3006
+ label: [55, 71, 79, 255]
3007
+ },
3008
+ // Dark-neon: near-black floor with high-saturation glowing segment fills, a
3009
+ // bright cyan path and magenta robot.
3010
+ "dark-neon": {
3011
+ floor: [16, 18, 27, 255],
3012
+ wall: [5, 6, 10, 255],
3013
+ carpet: [60, 50, 80, 200],
3014
+ segSat: 0.85,
3015
+ segVal: 0.95,
3016
+ path: [0, 230, 255, 240],
3017
+ robotBody: [255, 45, 170, 255],
3018
+ robotHeading: [255, 255, 255, 255],
3019
+ charger: [0, 255, 150, 255],
3020
+ noGoFill: [255, 40, 90, 80],
3021
+ noGoBorder: [255, 40, 90, 235],
3022
+ noMopFill: [40, 130, 255, 75],
3023
+ noMopBorder: [40, 160, 255, 225],
3024
+ virtualWall: [255, 40, 90, 235],
3025
+ obstacle: [255, 220, 0, 255],
3026
+ label: [230, 240, 255, 255]
3027
+ },
3028
+ // Materico (Material-design): light grey surface, Material-palette segment
3029
+ // fills, indigo/teal accents.
3030
+ materico: {
3031
+ floor: [245, 245, 245, 255],
3032
+ wall: [97, 97, 97, 255],
3033
+ carpet: [188, 170, 144, 205],
3034
+ segSat: 0.55,
3035
+ segVal: 0.93,
3036
+ path: [63, 81, 181, 235],
3037
+ robotBody: [48, 63, 159, 255],
3038
+ robotHeading: [255, 255, 255, 255],
3039
+ charger: [0, 150, 136, 255],
3040
+ noGoFill: [244, 67, 54, 65],
3041
+ noGoBorder: [211, 47, 47, 215],
3042
+ noMopFill: [33, 150, 243, 60],
3043
+ noMopBorder: [25, 118, 210, 205],
3044
+ virtualWall: [211, 47, 47, 225],
3045
+ obstacle: [255, 152, 0, 255],
3046
+ label: [33, 33, 33, 255]
2987
3047
  }
2988
3048
  };
2989
3049
  function hsvToRgba(h, s, v) {
@@ -3026,10 +3086,13 @@ function renderVacuumPng(map, opts = {}) {
3026
3086
  const h = Math.max(1, map.dimensions.height * scale);
3027
3087
  const png = new import_pngjs.PNG({ width: w, height: h });
3028
3088
  png.data.fill(0);
3089
+ const dim = map.dimensions;
3029
3090
  for (const layer of map.layers) {
3030
- paintLayer(png, layer, scale, pal);
3091
+ paintLayer(png, layer, dim.height, scale, pal);
3092
+ }
3093
+ if (opts.showCleanedArea === true && map.cleanedArea !== null) {
3094
+ paintCleanedArea(png, map.cleanedArea, dim, scale, pal.path);
3031
3095
  }
3032
- const dim = map.dimensions;
3033
3096
  if (opts.showNoGo !== false) {
3034
3097
  for (const area of map.restrictedAreas) {
3035
3098
  const fill = area.kind === "noMop" ? pal.noMopFill : pal.noGoFill;
@@ -3052,10 +3115,17 @@ function renderVacuumPng(map, opts = {}) {
3052
3115
  drawPolyline(png, path.points, dim, scale, pal.path, Math.max(1, scale));
3053
3116
  }
3054
3117
  }
3118
+ if (opts.showFurniture !== false) {
3119
+ for (const zone of map.lowLyingAreas) {
3120
+ paintFurnitureZone(png, zone.points, dim, scale);
3121
+ }
3122
+ }
3055
3123
  if (opts.showObstacles !== false) {
3124
+ const byType = opts.colorObstaclesByType !== false;
3056
3125
  for (const ob of map.obstacles) {
3057
3126
  const p = worldToPx(ob.x, ob.y, dim, scale);
3058
- drawDisk(png, p.x, p.y, Math.max(2, scale * 2), pal.obstacle);
3127
+ const color = byType ? obstacleColor(ob.type) : pal.obstacle;
3128
+ drawDiamond(png, p.x, p.y, Math.max(2, scale * 2), color);
3059
3129
  }
3060
3130
  }
3061
3131
  if (opts.showCharger !== false && map.dock !== null) {
@@ -3064,31 +3134,33 @@ function renderVacuumPng(map, opts = {}) {
3064
3134
  if (opts.showRobot !== false && map.robot !== null) {
3065
3135
  drawRobot(png, map.robot, dim, scale, pal);
3066
3136
  }
3067
- if (opts.showSegmentLabels === true) {
3137
+ if (opts.showSegmentNames === true || opts.showSegmentLabels === true) {
3068
3138
  for (const seg of map.segments) {
3069
3139
  const p = worldToPx(seg.centroid.x, seg.centroid.y, dim, scale);
3070
- drawLabel(png, p.x, p.y, String(seg.id), pal.label, Math.max(1, scale));
3140
+ const text = opts.showSegmentNames === true ? labelText(seg.name, seg.id) : String(seg.id);
3141
+ drawLabel(png, p.x, p.y, text, pal.label, Math.max(1, scale));
3071
3142
  }
3072
3143
  }
3073
3144
  return import_pngjs.PNG.sync.write(png);
3074
3145
  }
3075
3146
  function worldToPx(worldX, worldY, dim, scale) {
3147
+ const cellY = (worldY - dim.top) / dim.gridSize;
3076
3148
  return {
3077
3149
  x: Math.round((worldX - dim.left) / dim.gridSize * scale),
3078
- y: Math.round((worldY - dim.top) / dim.gridSize * scale)
3150
+ y: Math.round((dim.height - 1 - cellY) * scale)
3079
3151
  };
3080
3152
  }
3081
- function paintLayer(png, layer, scale, pal) {
3153
+ function paintLayer(png, layer, dimHeight, scale, pal) {
3082
3154
  const color = layer.type === "segment" ? segmentColor(layer.segmentId ?? 0, pal) : layer.type === "wall" ? pal.wall : layer.type === "carpet" ? pal.carpet : pal.floor;
3083
3155
  for (const run of layer.runs) {
3084
- paintRun(png, run, color, scale);
3156
+ paintRun(png, run, dimHeight, color, scale);
3085
3157
  }
3086
3158
  }
3087
- function paintRun(png, run, color, scale) {
3159
+ function paintRun(png, run, dimHeight, color, scale) {
3088
3160
  const [xPx, yPx, len] = run;
3161
+ const baseY = (dimHeight - 1 - yPx) * scale;
3089
3162
  for (let i = 0; i < len; i += 1) {
3090
3163
  const baseX = (xPx + i) * scale;
3091
- const baseY = yPx * scale;
3092
3164
  for (let dy = 0; dy < scale; dy += 1) {
3093
3165
  for (let dx = 0; dx < scale; dx += 1) {
3094
3166
  setPixel(png, baseX + dx, baseY + dy, color);
@@ -3194,7 +3266,7 @@ function drawRobot(png, robot, dim, scale, pal) {
3194
3266
  drawDisk(png, p.x, p.y, r, pal.robotBody);
3195
3267
  const rad = robot.angle * Math.PI / 180;
3196
3268
  const hx = Math.round(p.x + Math.cos(rad) * r);
3197
- const hy = Math.round(p.y + Math.sin(rad) * r);
3269
+ const hy = Math.round(p.y - Math.sin(rad) * r);
3198
3270
  drawLine(png, p.x, p.y, hx, hy, pal.robotHeading, Math.max(1, Math.trunc(scale / 2) + 1));
3199
3271
  }
3200
3272
  function drawCharger(png, dock, dim, scale, pal) {
@@ -3202,6 +3274,58 @@ function drawCharger(png, dock, dim, scale, pal) {
3202
3274
  const r = Math.max(2, scale * 2);
3203
3275
  fillRect(png, p.x - r, p.y - r, p.x + r, p.y + r, pal.charger);
3204
3276
  }
3277
+ function drawDiamond(png, cx, cy, r, color) {
3278
+ for (let dy = -r; dy <= r; dy += 1) {
3279
+ const w = r - Math.abs(dy);
3280
+ for (let dx = -w; dx <= w; dx += 1) {
3281
+ setPixel(png, cx + dx, cy + dy, color);
3282
+ }
3283
+ }
3284
+ }
3285
+ function obstacleColor(type) {
3286
+ const hue = Math.abs(Math.trunc(type)) * 47 % 360;
3287
+ return hsvToRgba(hue, 0.85, 0.95);
3288
+ }
3289
+ var FURNITURE_LINE = [150, 110, 200, 235];
3290
+ function paintFurnitureZone(png, points, dim, scale) {
3291
+ if (points.length < 2) return;
3292
+ for (let i = 0; i < points.length; i += 1) {
3293
+ const a = points[i];
3294
+ const b = points[(i + 1) % points.length];
3295
+ if (a === void 0 || b === void 0) continue;
3296
+ const pa = worldToPx(a.x, a.y, dim, scale);
3297
+ const pb = worldToPx(b.x, b.y, dim, scale);
3298
+ drawLine(png, pa.x, pa.y, pb.x, pb.y, FURNITURE_LINE, Math.max(1, scale));
3299
+ }
3300
+ }
3301
+ function paintCleanedArea(png, overlay, parentDim, scale, baseColor) {
3302
+ const tint = [baseColor[0], baseColor[1], baseColor[2], 55];
3303
+ const inner = overlay.dimensions;
3304
+ const block = Math.max(1, Math.round(inner.gridSize / parentDim.gridSize * scale));
3305
+ for (const [xPx, yPx, len] of overlay.cleaned) {
3306
+ for (let i = 0; i < len; i += 1) {
3307
+ const worldX = inner.left + (xPx + i) * inner.gridSize;
3308
+ const worldY = inner.top + yPx * inner.gridSize;
3309
+ const p = worldToPx(worldX, worldY, parentDim, scale);
3310
+ for (let dy = 0; dy < block; dy += 1) {
3311
+ for (let dx = 0; dx < block; dx += 1) {
3312
+ setPixel(png, p.x + dx, p.y + dy, tint);
3313
+ }
3314
+ }
3315
+ }
3316
+ }
3317
+ }
3318
+ function labelText(name, id) {
3319
+ const raw = (name ?? "").trim();
3320
+ const base = raw.length > 0 ? raw : `ROOM ${id}`;
3321
+ const upper = base.toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
3322
+ let out = "";
3323
+ for (const ch of upper) {
3324
+ if (GLYPHS[ch] !== void 0) out += ch;
3325
+ }
3326
+ const trimmed = out.trim().slice(0, 14);
3327
+ return trimmed.length > 0 ? trimmed : `ROOM ${id}`;
3328
+ }
3205
3329
  var GLYPHS = {
3206
3330
  "0": [7, 5, 5, 5, 7],
3207
3331
  "1": [2, 6, 2, 2, 7],
@@ -3213,7 +3337,34 @@ var GLYPHS = {
3213
3337
  "7": [7, 1, 2, 2, 2],
3214
3338
  "8": [7, 5, 7, 5, 7],
3215
3339
  "9": [7, 5, 7, 1, 7],
3216
- "-": [0, 0, 7, 0, 0]
3340
+ "-": [0, 0, 7, 0, 0],
3341
+ " ": [0, 0, 0, 0, 0],
3342
+ A: [2, 5, 7, 5, 5],
3343
+ B: [6, 5, 6, 5, 6],
3344
+ C: [3, 4, 4, 4, 3],
3345
+ D: [6, 5, 5, 5, 6],
3346
+ E: [7, 4, 6, 4, 7],
3347
+ F: [7, 4, 6, 4, 4],
3348
+ G: [3, 4, 5, 5, 3],
3349
+ H: [5, 5, 7, 5, 5],
3350
+ I: [7, 2, 2, 2, 7],
3351
+ J: [1, 1, 1, 5, 2],
3352
+ K: [5, 5, 6, 5, 5],
3353
+ L: [4, 4, 4, 4, 7],
3354
+ M: [5, 7, 7, 5, 5],
3355
+ N: [5, 7, 7, 7, 5],
3356
+ O: [2, 5, 5, 5, 2],
3357
+ P: [6, 5, 6, 4, 4],
3358
+ Q: [2, 5, 5, 6, 3],
3359
+ R: [6, 5, 6, 5, 5],
3360
+ S: [3, 4, 2, 1, 6],
3361
+ T: [7, 2, 2, 2, 2],
3362
+ U: [5, 5, 5, 5, 7],
3363
+ V: [5, 5, 5, 5, 2],
3364
+ W: [5, 5, 7, 7, 5],
3365
+ X: [5, 5, 2, 5, 5],
3366
+ Y: [5, 5, 2, 2, 2],
3367
+ Z: [7, 1, 2, 4, 7]
3217
3368
  };
3218
3369
  function drawLabel(png, cx, cy, text, color, px) {
3219
3370
  const glyphW = 3 * px;