perf: aggressive webp re-compression + max-width 1920 resize
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions

- recompress every webp at q=70-82 depending on size band
- resize anything wider than 1920px to 1920 max
- convert remaining png/jpg holdouts (mine, thermal, dex3-1 etc) to webp
- restore apple-touch-icon.png (iOS requires png)
- 86 files recompressed, saved 4.36 MB
- public/ images: 11.7 MB -> 6.69 MB (-43%)
- total trajectory: 23.3 MB -> 6.69 MB (-71%)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Najjar\NajjarV02 2026-05-21 17:31:56 +04:00
parent dda358b59d
commit 5a40f6b733
99 changed files with 107 additions and 7 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 KiB

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 KiB

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -0,0 +1,85 @@
import { promises as fs } from 'node:fs';
import path from 'node:path';
import sharp from 'sharp';
const ROOT = path.resolve('public');
const SKIP = new Set(['favicon.ico']);
const MAX_W = 1920; // cap any image wider than this
const exts = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
let convertedCount = 0;
let savedBytes = 0;
let skippedCount = 0;
async function walk(dir) {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const e of entries) {
const p = path.join(dir, e.name);
if (e.isDirectory()) await walk(p);
else if (exts.has(path.extname(p).toLowerCase())) await compress(p);
}
}
function qualityFor(bytes) {
if (bytes > 700 * 1024) return 70;
if (bytes > 300 * 1024) return 75;
if (bytes > 120 * 1024) return 78;
return 82;
}
async function compress(input) {
const base = path.basename(input);
if (SKIP.has(base)) return;
const ext = path.extname(input).toLowerCase();
const isGif = ext === '.gif';
const relRoot = path.relative(process.cwd(), input).split(path.sep).join('/');
try {
const stIn = await fs.stat(input);
if (stIn.size < 8 * 1024) {
// tiny: leave
return;
}
const target = input.slice(0, -ext.length) + '.webp';
// Read into memory first, then close handle
const srcBuf = await fs.readFile(input);
const meta = await sharp(srcBuf, { animated: isGif }).metadata();
let pipeline = sharp(srcBuf, { animated: isGif });
if (meta.width && meta.width > MAX_W) {
pipeline = pipeline.resize({ width: MAX_W, withoutEnlargement: true });
}
const q = qualityFor(stIn.size);
pipeline = pipeline.webp({
quality: q,
alphaQuality: 88,
effort: 6,
smartSubsample: true,
...(isGif ? { loop: 0 } : {}),
});
const buf = await pipeline.toBuffer();
if (buf.length >= stIn.size && ext === '.webp') {
skippedCount++;
return;
}
// write via temp file then rename for atomicity
const tmp = target + '.tmp';
await fs.writeFile(tmp, buf);
if (target !== input) {
try { await fs.unlink(input); } catch {}
}
await fs.rename(tmp, target);
convertedCount++;
savedBytes += stIn.size - buf.length;
const inKB = (stIn.size / 1024).toFixed(0);
const outKB = (buf.length / 1024).toFixed(0);
console.log(`OK q=${q} ${relRoot} ${inKB}KB -> ${outKB}KB${meta.width && meta.width > MAX_W ? ' (resized)' : ''}`);
} catch (err) {
console.log(`FAIL ${relRoot}: ${err.message}`);
}
}
await walk(ROOT);
const savedMB = (savedBytes / 1024 / 1024).toFixed(2);
console.log('\n---');
console.log(`compressed: ${convertedCount} skipped: ${skippedCount}`);
console.log(`saved: ${savedMB} MB`);

View File

@ -529,6 +529,21 @@ html {
/* === Layout helpers === */ /* === Layout helpers === */
.container-wide { max-width: 1320px; margin: 0 auto; padding-left: clamp(1rem, 4vw, 2rem); padding-right: clamp(1rem, 4vw, 2rem); } .container-wide { max-width: 1320px; margin: 0 auto; padding-left: clamp(1rem, 4vw, 2rem); padding-right: clamp(1rem, 4vw, 2rem); }
/* === Navbar responsive === */
.nav-desktop { display: none; }
.nav-desktop-cta { display: inline-flex; }
.nav-mobile-toggle { display: none !important; }
@media (min-width: 900px) {
.nav-desktop { display: flex !important; }
.nav-desktop-cta { display: inline-flex !important; }
.nav-mobile-toggle { display: none !important; }
}
@media (max-width: 899px) {
.nav-desktop { display: none !important; }
.nav-desktop-cta { display: none !important; }
.nav-mobile-toggle { display: inline-flex !important; }
}
.eyebrow { .eyebrow {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;

View File

@ -315,7 +315,7 @@ export const ACCESSORIES: Accessory[] = [
'1258 V operating voltage', '1258 V operating voltage',
'1 kHz communication rate', '1 kHz communication rate',
], ],
image: '/images/accessories/unitree-dex3-1.jpg', image: '/images/accessories/unitree-dex3-1.webp',
accent: GOLD_BRONZE, accent: GOLD_BRONZE,
officialUrl: 'https://www.unitree.com/Dex3-1', officialUrl: 'https://www.unitree.com/Dex3-1',
compatibility: ['Unitree G1'], compatibility: ['Unitree G1'],
@ -402,7 +402,7 @@ export const ACCESSORIES: Accessory[] = [
], ],
}, },
], ],
paramsImage: '/images/accessories/unitree-dex3-1/diagram.png', paramsImage: '/images/accessories/unitree-dex3-1/diagram.webp',
footnotes: [ footnotes: [
'Size refers to the dexterous hand in flat state.', 'Size refers to the dexterous hand in flat state.',
'Pressure data refers to force exerted by the dexterous hand when pressed by a vertical 1 cm diameter cylinder. Varies in different application scenarios.', 'Pressure data refers to force exerted by the dexterous hand when pressed by a vertical 1 cm diameter cylinder. Varies in different application scenarios.',
@ -718,7 +718,7 @@ export const ACCESSORIES: Accessory[] = [
'ENET UDP / TTL UART communication', 'ENET UDP / TTL UART communication',
'Open POINT-LIO SLAM solution', 'Open POINT-LIO SLAM solution',
], ],
image: '/images/accessories/unitree-l2.jpg', image: '/images/accessories/unitree-l2.webp',
accent: GOLD_CHAMPAGNE, accent: GOLD_CHAMPAGNE,
officialUrl: 'https://www.unitree.com/L2', officialUrl: 'https://www.unitree.com/L2',
compatibility: ['Unitree Go2', 'Unitree quadrupeds', 'Third-party robots'], compatibility: ['Unitree Go2', 'Unitree quadrupeds', 'Third-party robots'],

View File

@ -329,7 +329,7 @@ export const INDUSTRY_PAGES: Record<string, IndustryPageContent> = {
{ src: '/images/robots/pudu-cc1.webp', alt: 'PUDU CC1 auto-scrubber', caption: 'PUDU CC1 — auto-scrubber for large floors.', credit: 'Pudu' }, { src: '/images/robots/pudu-cc1.webp', alt: 'PUDU CC1 auto-scrubber', caption: 'PUDU CC1 — auto-scrubber for large floors.', credit: 'Pudu' },
{ src: '/images/robots/pudu-kettybot.webp', alt: 'KettyBot wayfinding and ad display', caption: 'KettyBot Pro — wayfinding and promo runs.', credit: 'Pudu' }, { src: '/images/robots/pudu-kettybot.webp', alt: 'KettyBot wayfinding and ad display', caption: 'KettyBot Pro — wayfinding and promo runs.', credit: 'Pudu' },
{ src: '/images/robots/unitree-go2.webp', alt: 'Unitree Go2 night patrol', caption: 'Unitree Go2 — night patrol across decks.', credit: 'Unitree' }, { src: '/images/robots/unitree-go2.webp', alt: 'Unitree Go2 night patrol', caption: 'Unitree Go2 — night patrol across decks.', credit: 'Unitree' },
{ src: '/industries/unitree/thermal.jpg', alt: 'Thermal + LiDAR patrol sensors', caption: 'Thermal + LiDAR sensors for after-hours rounds.', credit: 'Unitree' }, { src: '/industries/unitree/thermal.webp', alt: 'Thermal + LiDAR patrol sensors', caption: 'Thermal + LiDAR sensors for after-hours rounds.', credit: 'Unitree' },
], ],
problemPoints: [ problemPoints: [
'Large floor areas are hard to clean and patrol consistently.', 'Large floor areas are hard to clean and patrol consistently.',
@ -606,12 +606,12 @@ export const INDUSTRY_PAGES: Record<string, IndustryPageContent> = {
], ],
gallery: [ gallery: [
{ src: '/industries/unitree/terrain.webp', alt: 'Quadruped robot on mixed industrial terrain', caption: 'Stairs, gullies, and uneven ground handled on one platform.', credit: 'Unitree' }, { src: '/industries/unitree/terrain.webp', alt: 'Quadruped robot on mixed industrial terrain', caption: 'Stairs, gullies, and uneven ground handled on one platform.', credit: 'Unitree' },
{ src: '/industries/unitree/thermal.jpg', alt: 'Thermal imaging and laser-radar detection', caption: 'Thermal, laser-radar, and AI imaging for routine monitoring.', credit: 'Unitree' }, { src: '/industries/unitree/thermal.webp', alt: 'Thermal imaging and laser-radar detection', caption: 'Thermal, laser-radar, and AI imaging for routine monitoring.', credit: 'Unitree' },
{ src: '/industries/unitree/substation.webp', alt: 'Power substation patrol', caption: 'Substation patrol — switchgear and transformer scans.', credit: 'Unitree' }, { src: '/industries/unitree/substation.webp', alt: 'Power substation patrol', caption: 'Substation patrol — switchgear and transformer scans.', credit: 'Unitree' },
{ src: '/industries/unitree/pipeline.webp', alt: 'Pipeline corridor patrol', caption: 'Pipeline and refinery corridor inspection rounds.', credit: 'Unitree' }, { src: '/industries/unitree/pipeline.webp', alt: 'Pipeline corridor patrol', caption: 'Pipeline and refinery corridor inspection rounds.', credit: 'Unitree' },
{ src: '/industries/unitree/industrial-park.webp', alt: 'Industrial park perimeter coverage', caption: 'Industrial park and large-compound perimeter coverage.', credit: 'Unitree' }, { src: '/industries/unitree/industrial-park.webp', alt: 'Industrial park perimeter coverage', caption: 'Industrial park and large-compound perimeter coverage.', credit: 'Unitree' },
{ src: '/industries/unitree/utility-room.webp', alt: 'Utility plant room inspection', caption: 'Utility and plant-room routine checks.', credit: 'Unitree' }, { src: '/industries/unitree/utility-room.webp', alt: 'Utility plant room inspection', caption: 'Utility and plant-room routine checks.', credit: 'Unitree' },
{ src: '/industries/unitree/mine.jpg', alt: 'Tunnel inspection', caption: 'Tunnel and confined-zone inspection.', credit: 'Unitree' }, { src: '/industries/unitree/mine.webp', alt: 'Tunnel inspection', caption: 'Tunnel and confined-zone inspection.', credit: 'Unitree' },
{ src: '/industries/unitree/terrain-night.webp', alt: 'Quadruped robot on night patrol', caption: 'After-hours rounds with consistent route timing.', credit: 'Unitree' }, { src: '/industries/unitree/terrain-night.webp', alt: 'Quadruped robot on night patrol', caption: 'After-hours rounds with consistent route timing.', credit: 'Unitree' },
{ src: '/industries/unitree/b2-render.webp', alt: 'Unitree B2 industrial quadruped render', caption: 'B2 — industrial-grade quadruped platform.', credit: 'Unitree' }, { src: '/industries/unitree/b2-render.webp', alt: 'Unitree B2 industrial quadruped render', caption: 'B2 — industrial-grade quadruped platform.', credit: 'Unitree' },
], ],

View File

@ -288,7 +288,7 @@ export const ROBOTS: Robot[] = [
{ label: 'Battery', value: '1.53 h' }, { label: 'Battery', value: '1.53 h' },
SPEC_CONSULT, SPEC_CONSULT,
], ],
image: '/images/robots/unitree-go2-w.png', image: '/images/robots/unitree-go2-w.webp',
imageType: 'photo', imageType: 'photo',
accent: GOLD_BRAND, accent: GOLD_BRAND,
officialUrl: 'https://www.unitree.com/go2-w', officialUrl: 'https://www.unitree.com/go2-w',