@flamingo-stack/openframe-frontend-core 0.0.406-snapshot.20260711131925 → 0.0.406
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/{chunk-2B6773QM.cjs → chunk-3KEBI6TP.cjs} +1 -1
- package/dist/chunk-3KEBI6TP.cjs.map +1 -0
- package/dist/{chunk-HJIRG7R6.js → chunk-3KZXOLFK.js} +4 -4
- package/dist/{chunk-43H2WOAW.js → chunk-6WMVBCNA.js} +3 -3
- package/dist/{chunk-XFP43YKG.js → chunk-7RVSGGO6.js} +6 -6
- package/dist/{chunk-KLBEIJVZ.js → chunk-AYFWYOL6.js} +7 -7
- package/dist/{chunk-GMZL4T7C.js → chunk-C3NPMZBI.js} +3 -3
- package/dist/{chunk-STGWQFYT.cjs → chunk-CCIBZ7TO.cjs} +5 -5
- package/dist/chunk-CCIBZ7TO.cjs.map +1 -0
- package/dist/{chunk-Q2MC3CBI.cjs → chunk-CF3LBCNI.cjs} +35 -35
- package/dist/{chunk-Q2MC3CBI.cjs.map → chunk-CF3LBCNI.cjs.map} +1 -1
- package/dist/{chunk-DOBNDDNE.cjs → chunk-COERBDG4.cjs} +75 -75
- package/dist/{chunk-DOBNDDNE.cjs.map → chunk-COERBDG4.cjs.map} +1 -1
- package/dist/{chunk-7Q52HP45.js → chunk-E6YHDT3D.js} +2 -2
- package/dist/chunk-E6YHDT3D.js.map +1 -0
- package/dist/{chunk-74FWQI73.cjs → chunk-GNS65HNC.cjs} +18 -18
- package/dist/{chunk-74FWQI73.cjs.map → chunk-GNS65HNC.cjs.map} +1 -1
- package/dist/{chunk-WCPUJA3Y.cjs → chunk-HJJXNMM7.cjs} +7 -7
- package/dist/{chunk-WCPUJA3Y.cjs.map → chunk-HJJXNMM7.cjs.map} +1 -1
- package/dist/{chunk-R4MXLJUS.cjs → chunk-ISYVNPRT.cjs} +42 -42
- package/dist/{chunk-R4MXLJUS.cjs.map → chunk-ISYVNPRT.cjs.map} +1 -1
- package/dist/{chunk-YX7C5JD7.cjs → chunk-JAPP2F4M.cjs} +77 -77
- package/dist/{chunk-YX7C5JD7.cjs.map → chunk-JAPP2F4M.cjs.map} +1 -1
- package/dist/{chunk-GGDM5J4B.cjs → chunk-LL4QQSAD.cjs} +322 -331
- package/dist/chunk-LL4QQSAD.cjs.map +1 -0
- package/dist/{chunk-GJSLKATJ.js → chunk-LSPBPUQM.js} +2 -2
- package/dist/{chunk-KFQXO7QB.js → chunk-NA7XJRWB.js} +1 -1
- package/dist/chunk-NA7XJRWB.js.map +1 -0
- package/dist/{chunk-H66L2265.js → chunk-OATWTTCI.js} +6 -6
- package/dist/{chunk-LPC3C7MG.cjs → chunk-P43ZHPM6.cjs} +40 -40
- package/dist/{chunk-LPC3C7MG.cjs.map → chunk-P43ZHPM6.cjs.map} +1 -1
- package/dist/{chunk-NO2KT42M.js → chunk-PNJ5LMVK.js} +10 -9
- package/dist/{chunk-NO2KT42M.js.map → chunk-PNJ5LMVK.js.map} +1 -1
- package/dist/{chunk-NSF7JUXF.js → chunk-PQN5R5II.js} +7 -7
- package/dist/{chunk-CUN4CJUN.cjs → chunk-QAFRLO5N.cjs} +11 -10
- package/dist/chunk-QAFRLO5N.cjs.map +1 -0
- package/dist/{chunk-LC6RRLFA.cjs → chunk-SF4G7M6U.cjs} +15 -15
- package/dist/{chunk-LC6RRLFA.cjs.map → chunk-SF4G7M6U.cjs.map} +1 -1
- package/dist/{chunk-CVYSW33D.js → chunk-SOK32D6C.js} +189 -198
- package/dist/chunk-SOK32D6C.js.map +1 -0
- package/dist/{chunk-4UZH3MT2.js → chunk-TFDNJTBX.js} +4 -4
- package/dist/{chunk-5M5W6XDY.cjs → chunk-VANFD4FX.cjs} +7 -7
- package/dist/{chunk-5M5W6XDY.cjs.map → chunk-VANFD4FX.cjs.map} +1 -1
- package/dist/{chunk-PRKMOF2U.cjs → chunk-VIB4SGCD.cjs} +14 -14
- package/dist/{chunk-PRKMOF2U.cjs.map → chunk-VIB4SGCD.cjs.map} +1 -1
- package/dist/{chunk-SY3QS2E5.cjs → chunk-VZGU4BV6.cjs} +29 -29
- package/dist/{chunk-SY3QS2E5.cjs.map → chunk-VZGU4BV6.cjs.map} +1 -1
- package/dist/{chunk-7XVFSGQA.js → chunk-XXG2Z2JT.js} +3 -3
- package/dist/{chunk-HB63TQQO.js → chunk-ZVUR3A33.js} +2 -2
- package/dist/components/announcement-bar.d.ts.map +1 -1
- package/dist/components/case-studies/index.cjs +10 -10
- package/dist/components/case-studies/index.js +4 -4
- package/dist/components/chat/index.cjs +4 -4
- package/dist/components/chat/index.js +3 -3
- package/dist/components/contact/index.cjs +5 -5
- package/dist/components/contact/index.js +4 -4
- package/dist/components/docs/index.cjs +7 -7
- package/dist/components/docs/index.js +6 -6
- package/dist/components/embeds/index.cjs +5 -5
- package/dist/components/embeds/index.js +4 -4
- package/dist/components/faq/index.cjs +6 -6
- package/dist/components/faq/index.js +5 -5
- package/dist/components/features/index.cjs +4 -4
- package/dist/components/features/index.js +3 -3
- package/dist/components/help-center-pages/index.cjs +23 -23
- package/dist/components/help-center-pages/index.js +14 -14
- package/dist/components/index.cjs +179 -185
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +32 -38
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +4 -4
- package/dist/components/navigation/index.js +3 -3
- package/dist/components/onboarding-guides/index.cjs +8 -8
- package/dist/components/onboarding-guides/index.js +7 -7
- package/dist/components/related-content/index.cjs +6 -6
- package/dist/components/related-content/index.js +5 -5
- package/dist/components/tickets/index.cjs +7 -7
- package/dist/components/tickets/index.js +6 -6
- package/dist/components/ui/index.cjs +4 -4
- package/dist/components/ui/index.js +3 -3
- package/dist/contexts/endpoints-runtime-context.d.ts +1 -1
- package/dist/contexts/endpoints-runtime-context.d.ts.map +1 -1
- package/dist/contexts/index.cjs +2 -2
- package/dist/contexts/index.js +1 -1
- package/dist/hooks/index.cjs +3 -3
- package/dist/hooks/index.js +2 -2
- package/dist/hooks/use-self-fetch.d.ts.map +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/types/announcement.cjs.map +1 -1
- package/dist/types/announcement.d.ts +6 -0
- package/dist/types/announcement.d.ts.map +1 -1
- package/dist/types/announcement.js.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/announcement-storage.d.ts +0 -3
- package/dist/utils/announcement-storage.d.ts.map +1 -1
- package/dist/utils/app-config.d.ts.map +1 -1
- package/dist/utils/color-analysis.d.ts +4 -0
- package/dist/utils/color-analysis.d.ts.map +1 -1
- package/dist/utils/index.cjs +177 -186
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +176 -185
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/ods-color-utils.d.ts +1 -2
- package/dist/utils/ods-color-utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/announcement-bar.tsx +21 -38
- package/src/contexts/endpoints-runtime-context.tsx +1 -1
- package/src/hooks/use-self-fetch.ts +9 -10
- package/src/stories/AnnouncementBar.stories.tsx +14 -8
- package/src/types/announcement.ts +8 -0
- package/src/utils/announcement-storage.ts +0 -17
- package/src/utils/app-config.ts +2 -3
- package/src/utils/color-analysis.ts +2 -5
- package/src/utils/ods-color-utils.ts +7 -4
- package/dist/chunk-2B6773QM.cjs.map +0 -1
- package/dist/chunk-7Q52HP45.js.map +0 -1
- package/dist/chunk-CUN4CJUN.cjs.map +0 -1
- package/dist/chunk-CVYSW33D.js.map +0 -1
- package/dist/chunk-GGDM5J4B.cjs.map +0 -1
- package/dist/chunk-KFQXO7QB.js.map +0 -1
- package/dist/chunk-STGWQFYT.cjs.map +0 -1
- /package/dist/{chunk-HJIRG7R6.js.map → chunk-3KZXOLFK.js.map} +0 -0
- /package/dist/{chunk-43H2WOAW.js.map → chunk-6WMVBCNA.js.map} +0 -0
- /package/dist/{chunk-XFP43YKG.js.map → chunk-7RVSGGO6.js.map} +0 -0
- /package/dist/{chunk-KLBEIJVZ.js.map → chunk-AYFWYOL6.js.map} +0 -0
- /package/dist/{chunk-GMZL4T7C.js.map → chunk-C3NPMZBI.js.map} +0 -0
- /package/dist/{chunk-GJSLKATJ.js.map → chunk-LSPBPUQM.js.map} +0 -0
- /package/dist/{chunk-H66L2265.js.map → chunk-OATWTTCI.js.map} +0 -0
- /package/dist/{chunk-NSF7JUXF.js.map → chunk-PQN5R5II.js.map} +0 -0
- /package/dist/{chunk-4UZH3MT2.js.map → chunk-TFDNJTBX.js.map} +0 -0
- /package/dist/{chunk-7XVFSGQA.js.map → chunk-XXG2Z2JT.js.map} +0 -0
- /package/dist/{chunk-HB63TQQO.js.map → chunk-ZVUR3A33.js.map} +0 -0
package/dist/utils/index.js
CHANGED
|
@@ -462,174 +462,6 @@ function formatBioText(aboutHtml, fallback = "") {
|
|
|
462
462
|
}
|
|
463
463
|
var PLAY_ICON_PATH = "M4.875 5.006c0-2.501 2.793-3.989 4.87-2.592l9.78 6.578c2.135 1.437 2.135 4.58 0 6.016l-9.78 6.579c-2.077 1.396-4.87-.091-4.87-2.593zm2.25 13.988c0 .7.783 1.118 1.364.727l9.78-6.58c.81-.545.81-1.738 0-2.283L8.488 4.28a.875.875 0 0 0-1.364.726v13.988Z";
|
|
464
464
|
|
|
465
|
-
// src/utils/color-analysis.ts
|
|
466
|
-
var DESIGN_PALETTE = [
|
|
467
|
-
{ name: "yellow", hex: "#FFC008", rgb: [255, 192, 8] },
|
|
468
|
-
{ name: "black", hex: "#161616", rgb: [22, 22, 22] },
|
|
469
|
-
{ name: "gray", hex: "#888888", rgb: [136, 136, 136] }
|
|
470
|
-
];
|
|
471
|
-
function hexToRgb(hex) {
|
|
472
|
-
const normalized = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) => `${r}${r}${g}${g}${b}${b}`);
|
|
473
|
-
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(normalized);
|
|
474
|
-
return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [0, 0, 0];
|
|
475
|
-
}
|
|
476
|
-
function getLuminance(rgb) {
|
|
477
|
-
const [r, g, b] = rgb.map((c) => {
|
|
478
|
-
c = c / 255;
|
|
479
|
-
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
480
|
-
});
|
|
481
|
-
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
482
|
-
}
|
|
483
|
-
function getContrastRatio(color1, color2) {
|
|
484
|
-
const lum1 = getLuminance(color1);
|
|
485
|
-
const lum2 = getLuminance(color2);
|
|
486
|
-
const brightest = Math.max(lum1, lum2);
|
|
487
|
-
const darkest = Math.min(lum1, lum2);
|
|
488
|
-
return (brightest + 0.05) / (darkest + 0.05);
|
|
489
|
-
}
|
|
490
|
-
function pickReadableTextColor(bgHex) {
|
|
491
|
-
const bg = hexToRgb(bgHex);
|
|
492
|
-
const darkContrast = getContrastRatio(bg, [26, 26, 26]);
|
|
493
|
-
const lightContrast = getContrastRatio(bg, [250, 250, 250]);
|
|
494
|
-
return darkContrast >= lightContrast ? "dark" : "light";
|
|
495
|
-
}
|
|
496
|
-
function extractDominantColor(canvas) {
|
|
497
|
-
const ctx = canvas.getContext("2d");
|
|
498
|
-
if (!ctx) return [128, 128, 128];
|
|
499
|
-
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
500
|
-
const data = imageData.data;
|
|
501
|
-
const sampleSize = Math.max(1, Math.floor(data.length / (4 * 1e3)));
|
|
502
|
-
const colorCounts = {};
|
|
503
|
-
for (let i = 0; i < data.length; i += 4 * sampleSize) {
|
|
504
|
-
const r = data[i];
|
|
505
|
-
const g = data[i + 1];
|
|
506
|
-
const b = data[i + 2];
|
|
507
|
-
const alpha = data[i + 3];
|
|
508
|
-
if (alpha < 128) continue;
|
|
509
|
-
const bucketR = Math.round(r / 32) * 32;
|
|
510
|
-
const bucketG = Math.round(g / 32) * 32;
|
|
511
|
-
const bucketB = Math.round(b / 32) * 32;
|
|
512
|
-
const key = `${bucketR},${bucketG},${bucketB}`;
|
|
513
|
-
colorCounts[key] = (colorCounts[key] || 0) + 1;
|
|
514
|
-
}
|
|
515
|
-
let maxCount = 0;
|
|
516
|
-
let dominantColor = [128, 128, 128];
|
|
517
|
-
for (const [colorKey, count] of Object.entries(colorCounts)) {
|
|
518
|
-
if (count > maxCount) {
|
|
519
|
-
maxCount = count;
|
|
520
|
-
const [r, g, b] = colorKey.split(",").map(Number);
|
|
521
|
-
dominantColor = [r, g, b];
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
return dominantColor;
|
|
525
|
-
}
|
|
526
|
-
function getBestContrastColor(imageColor) {
|
|
527
|
-
let bestColor = DESIGN_PALETTE[0];
|
|
528
|
-
let bestContrast = 0;
|
|
529
|
-
for (const color of DESIGN_PALETTE) {
|
|
530
|
-
const contrast = getContrastRatio(imageColor, color.rgb);
|
|
531
|
-
if (contrast > bestContrast) {
|
|
532
|
-
bestContrast = contrast;
|
|
533
|
-
bestColor = color;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return bestContrast >= 3 ? bestColor : DESIGN_PALETTE.find((c) => c.name === "black") || bestColor;
|
|
537
|
-
}
|
|
538
|
-
function analyzeImageColor(imageSrc) {
|
|
539
|
-
return new Promise((resolve, reject) => {
|
|
540
|
-
const img = new Image();
|
|
541
|
-
img.crossOrigin = "anonymous";
|
|
542
|
-
img.onload = () => {
|
|
543
|
-
try {
|
|
544
|
-
const canvas = document.createElement("canvas");
|
|
545
|
-
const ctx = canvas.getContext("2d");
|
|
546
|
-
if (!ctx) {
|
|
547
|
-
reject(new Error("Could not get canvas context"));
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
const maxSize = 100;
|
|
551
|
-
const scale = Math.min(maxSize / img.width, maxSize / img.height);
|
|
552
|
-
canvas.width = img.width * scale;
|
|
553
|
-
canvas.height = img.height * scale;
|
|
554
|
-
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
555
|
-
const dominantColor = extractDominantColor(canvas);
|
|
556
|
-
const bestContrastColor = getBestContrastColor(dominantColor);
|
|
557
|
-
resolve(bestContrastColor);
|
|
558
|
-
} catch (error) {
|
|
559
|
-
reject(error);
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
img.onerror = () => reject(new Error("Failed to load image"));
|
|
563
|
-
img.src = imageSrc;
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
async function extractImageEdgeColorAsync(imageUrl) {
|
|
567
|
-
return new Promise((resolve) => {
|
|
568
|
-
if (typeof window === "undefined") {
|
|
569
|
-
resolve("#000000");
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
const img = new Image();
|
|
573
|
-
img.crossOrigin = "anonymous";
|
|
574
|
-
img.onload = () => {
|
|
575
|
-
try {
|
|
576
|
-
const canvas = document.createElement("canvas");
|
|
577
|
-
const ctx = canvas.getContext("2d");
|
|
578
|
-
if (!ctx) {
|
|
579
|
-
resolve("#000000");
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
582
|
-
const maxSize = 50;
|
|
583
|
-
const scale = Math.min(maxSize / img.naturalWidth, maxSize / img.naturalHeight);
|
|
584
|
-
const w = Math.round(img.naturalWidth * scale);
|
|
585
|
-
const h = Math.round(img.naturalHeight * scale);
|
|
586
|
-
canvas.width = w;
|
|
587
|
-
canvas.height = h;
|
|
588
|
-
ctx.drawImage(img, 0, 0, w, h);
|
|
589
|
-
const data = ctx.getImageData(0, 0, w, h).data;
|
|
590
|
-
const edgeW = Math.max(2, Math.round(w * 0.15));
|
|
591
|
-
const edgeH = Math.max(2, Math.round(h * 0.15));
|
|
592
|
-
const bucketSize = 32;
|
|
593
|
-
const buckets = /* @__PURE__ */ new Map();
|
|
594
|
-
for (let y = 0; y < h; y++) {
|
|
595
|
-
for (let x = 0; x < w; x++) {
|
|
596
|
-
if (!(x < edgeW || x >= w - edgeW || y < edgeH || y >= h - edgeH)) continue;
|
|
597
|
-
const i = (y * w + x) * 4;
|
|
598
|
-
if (data[i + 3] < 128) continue;
|
|
599
|
-
const br = Math.floor(data[i] / bucketSize) * bucketSize;
|
|
600
|
-
const bg = Math.floor(data[i + 1] / bucketSize) * bucketSize;
|
|
601
|
-
const bb = Math.floor(data[i + 2] / bucketSize) * bucketSize;
|
|
602
|
-
const key = `${br},${bg},${bb}`;
|
|
603
|
-
const existing = buckets.get(key);
|
|
604
|
-
if (existing) {
|
|
605
|
-
existing.r += data[i];
|
|
606
|
-
existing.g += data[i + 1];
|
|
607
|
-
existing.b += data[i + 2];
|
|
608
|
-
existing.count++;
|
|
609
|
-
} else {
|
|
610
|
-
buckets.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], count: 1 });
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
let best = { r: 0, g: 0, b: 0, count: 0 };
|
|
615
|
-
for (const b2 of buckets.values()) {
|
|
616
|
-
if (b2.count > best.count) best = b2;
|
|
617
|
-
}
|
|
618
|
-
if (best.count === 0) {
|
|
619
|
-
resolve("#000000");
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
const r = Math.round(best.r / best.count), g = Math.round(best.g / best.count), b = Math.round(best.b / best.count);
|
|
623
|
-
resolve(`#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`);
|
|
624
|
-
} catch {
|
|
625
|
-
resolve("#000000");
|
|
626
|
-
}
|
|
627
|
-
};
|
|
628
|
-
img.onerror = () => resolve("#000000");
|
|
629
|
-
img.src = imageUrl;
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
|
|
633
465
|
// src/utils/ods-color-utils.ts
|
|
634
466
|
function getPlatformAccentColor(platform) {
|
|
635
467
|
const currentPlatform = platform || getCurrentPlatform();
|
|
@@ -654,13 +486,18 @@ function getCurrentPlatform() {
|
|
|
654
486
|
return process.env.NEXT_PUBLIC_APP_TYPE || "openmsp";
|
|
655
487
|
}
|
|
656
488
|
function getReadableTextColor(hex) {
|
|
657
|
-
|
|
489
|
+
const n = parseInt(hex.replace("#", ""), 16);
|
|
490
|
+
const r = n >> 16 & 255;
|
|
491
|
+
const g = n >> 8 & 255;
|
|
492
|
+
const b = n & 255;
|
|
493
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
494
|
+
return luminance > 0.5 ? "#212121" : "#fafafa";
|
|
658
495
|
}
|
|
659
496
|
var HEX_PATTERN = /^#[0-9a-fA-F]{6}$/;
|
|
660
497
|
function clamp(n, min, max) {
|
|
661
498
|
return Math.max(min, Math.min(max, n));
|
|
662
499
|
}
|
|
663
|
-
function
|
|
500
|
+
function hexToRgb(hex) {
|
|
664
501
|
if (!HEX_PATTERN.test(hex)) return null;
|
|
665
502
|
const n = Number.parseInt(hex.slice(1), 16);
|
|
666
503
|
return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
|
|
@@ -672,7 +509,7 @@ function rgbToHex(r, g, b) {
|
|
|
672
509
|
var HOVER_DARKEN_STEP = 10;
|
|
673
510
|
var ACTIVE_DARKEN_STEP = 20;
|
|
674
511
|
function darkenByStep(hex, step) {
|
|
675
|
-
const rgb =
|
|
512
|
+
const rgb = hexToRgb(hex);
|
|
676
513
|
if (!rgb) return hex;
|
|
677
514
|
return rgbToHex(rgb.r - step, rgb.g - step, rgb.b - step);
|
|
678
515
|
}
|
|
@@ -2475,6 +2312,173 @@ function isGenericWebsiteDomain(website) {
|
|
|
2475
2312
|
return isGenericDomain(normalizeDomain(website));
|
|
2476
2313
|
}
|
|
2477
2314
|
|
|
2315
|
+
// src/utils/color-analysis.ts
|
|
2316
|
+
var DESIGN_PALETTE = [
|
|
2317
|
+
{ name: "yellow", hex: "#FFC008", rgb: [255, 192, 8] },
|
|
2318
|
+
{ name: "black", hex: "#161616", rgb: [22, 22, 22] },
|
|
2319
|
+
{ name: "gray", hex: "#888888", rgb: [136, 136, 136] }
|
|
2320
|
+
];
|
|
2321
|
+
function hexToRgb2(hex) {
|
|
2322
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
2323
|
+
return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [0, 0, 0];
|
|
2324
|
+
}
|
|
2325
|
+
function getLuminance(rgb) {
|
|
2326
|
+
const [r, g, b] = rgb.map((c) => {
|
|
2327
|
+
c = c / 255;
|
|
2328
|
+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
2329
|
+
});
|
|
2330
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
2331
|
+
}
|
|
2332
|
+
function getContrastRatio(color1, color2) {
|
|
2333
|
+
const lum1 = getLuminance(color1);
|
|
2334
|
+
const lum2 = getLuminance(color2);
|
|
2335
|
+
const brightest = Math.max(lum1, lum2);
|
|
2336
|
+
const darkest = Math.min(lum1, lum2);
|
|
2337
|
+
return (brightest + 0.05) / (darkest + 0.05);
|
|
2338
|
+
}
|
|
2339
|
+
function pickReadableTextColor(bgHex) {
|
|
2340
|
+
const bg = hexToRgb2(bgHex);
|
|
2341
|
+
const darkContrast = getContrastRatio(bg, [26, 26, 26]);
|
|
2342
|
+
const lightContrast = getContrastRatio(bg, [250, 250, 250]);
|
|
2343
|
+
return darkContrast >= lightContrast ? "dark" : "light";
|
|
2344
|
+
}
|
|
2345
|
+
function extractDominantColor(canvas) {
|
|
2346
|
+
const ctx = canvas.getContext("2d");
|
|
2347
|
+
if (!ctx) return [128, 128, 128];
|
|
2348
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
2349
|
+
const data = imageData.data;
|
|
2350
|
+
const sampleSize = Math.max(1, Math.floor(data.length / (4 * 1e3)));
|
|
2351
|
+
const colorCounts = {};
|
|
2352
|
+
for (let i = 0; i < data.length; i += 4 * sampleSize) {
|
|
2353
|
+
const r = data[i];
|
|
2354
|
+
const g = data[i + 1];
|
|
2355
|
+
const b = data[i + 2];
|
|
2356
|
+
const alpha = data[i + 3];
|
|
2357
|
+
if (alpha < 128) continue;
|
|
2358
|
+
const bucketR = Math.round(r / 32) * 32;
|
|
2359
|
+
const bucketG = Math.round(g / 32) * 32;
|
|
2360
|
+
const bucketB = Math.round(b / 32) * 32;
|
|
2361
|
+
const key = `${bucketR},${bucketG},${bucketB}`;
|
|
2362
|
+
colorCounts[key] = (colorCounts[key] || 0) + 1;
|
|
2363
|
+
}
|
|
2364
|
+
let maxCount = 0;
|
|
2365
|
+
let dominantColor = [128, 128, 128];
|
|
2366
|
+
for (const [colorKey, count] of Object.entries(colorCounts)) {
|
|
2367
|
+
if (count > maxCount) {
|
|
2368
|
+
maxCount = count;
|
|
2369
|
+
const [r, g, b] = colorKey.split(",").map(Number);
|
|
2370
|
+
dominantColor = [r, g, b];
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
return dominantColor;
|
|
2374
|
+
}
|
|
2375
|
+
function getBestContrastColor(imageColor) {
|
|
2376
|
+
let bestColor = DESIGN_PALETTE[0];
|
|
2377
|
+
let bestContrast = 0;
|
|
2378
|
+
for (const color of DESIGN_PALETTE) {
|
|
2379
|
+
const contrast = getContrastRatio(imageColor, color.rgb);
|
|
2380
|
+
if (contrast > bestContrast) {
|
|
2381
|
+
bestContrast = contrast;
|
|
2382
|
+
bestColor = color;
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
return bestContrast >= 3 ? bestColor : DESIGN_PALETTE.find((c) => c.name === "black") || bestColor;
|
|
2386
|
+
}
|
|
2387
|
+
function analyzeImageColor(imageSrc) {
|
|
2388
|
+
return new Promise((resolve, reject) => {
|
|
2389
|
+
const img = new Image();
|
|
2390
|
+
img.crossOrigin = "anonymous";
|
|
2391
|
+
img.onload = () => {
|
|
2392
|
+
try {
|
|
2393
|
+
const canvas = document.createElement("canvas");
|
|
2394
|
+
const ctx = canvas.getContext("2d");
|
|
2395
|
+
if (!ctx) {
|
|
2396
|
+
reject(new Error("Could not get canvas context"));
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
const maxSize = 100;
|
|
2400
|
+
const scale = Math.min(maxSize / img.width, maxSize / img.height);
|
|
2401
|
+
canvas.width = img.width * scale;
|
|
2402
|
+
canvas.height = img.height * scale;
|
|
2403
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
2404
|
+
const dominantColor = extractDominantColor(canvas);
|
|
2405
|
+
const bestContrastColor = getBestContrastColor(dominantColor);
|
|
2406
|
+
resolve(bestContrastColor);
|
|
2407
|
+
} catch (error) {
|
|
2408
|
+
reject(error);
|
|
2409
|
+
}
|
|
2410
|
+
};
|
|
2411
|
+
img.onerror = () => reject(new Error("Failed to load image"));
|
|
2412
|
+
img.src = imageSrc;
|
|
2413
|
+
});
|
|
2414
|
+
}
|
|
2415
|
+
async function extractImageEdgeColorAsync(imageUrl) {
|
|
2416
|
+
return new Promise((resolve) => {
|
|
2417
|
+
if (typeof window === "undefined") {
|
|
2418
|
+
resolve("#000000");
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
const img = new Image();
|
|
2422
|
+
img.crossOrigin = "anonymous";
|
|
2423
|
+
img.onload = () => {
|
|
2424
|
+
try {
|
|
2425
|
+
const canvas = document.createElement("canvas");
|
|
2426
|
+
const ctx = canvas.getContext("2d");
|
|
2427
|
+
if (!ctx) {
|
|
2428
|
+
resolve("#000000");
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
const maxSize = 50;
|
|
2432
|
+
const scale = Math.min(maxSize / img.naturalWidth, maxSize / img.naturalHeight);
|
|
2433
|
+
const w = Math.round(img.naturalWidth * scale);
|
|
2434
|
+
const h = Math.round(img.naturalHeight * scale);
|
|
2435
|
+
canvas.width = w;
|
|
2436
|
+
canvas.height = h;
|
|
2437
|
+
ctx.drawImage(img, 0, 0, w, h);
|
|
2438
|
+
const data = ctx.getImageData(0, 0, w, h).data;
|
|
2439
|
+
const edgeW = Math.max(2, Math.round(w * 0.15));
|
|
2440
|
+
const edgeH = Math.max(2, Math.round(h * 0.15));
|
|
2441
|
+
const bucketSize = 32;
|
|
2442
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
2443
|
+
for (let y = 0; y < h; y++) {
|
|
2444
|
+
for (let x = 0; x < w; x++) {
|
|
2445
|
+
if (!(x < edgeW || x >= w - edgeW || y < edgeH || y >= h - edgeH)) continue;
|
|
2446
|
+
const i = (y * w + x) * 4;
|
|
2447
|
+
if (data[i + 3] < 128) continue;
|
|
2448
|
+
const br = Math.floor(data[i] / bucketSize) * bucketSize;
|
|
2449
|
+
const bg = Math.floor(data[i + 1] / bucketSize) * bucketSize;
|
|
2450
|
+
const bb = Math.floor(data[i + 2] / bucketSize) * bucketSize;
|
|
2451
|
+
const key = `${br},${bg},${bb}`;
|
|
2452
|
+
const existing = buckets.get(key);
|
|
2453
|
+
if (existing) {
|
|
2454
|
+
existing.r += data[i];
|
|
2455
|
+
existing.g += data[i + 1];
|
|
2456
|
+
existing.b += data[i + 2];
|
|
2457
|
+
existing.count++;
|
|
2458
|
+
} else {
|
|
2459
|
+
buckets.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], count: 1 });
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
let best = { r: 0, g: 0, b: 0, count: 0 };
|
|
2464
|
+
for (const b2 of buckets.values()) {
|
|
2465
|
+
if (b2.count > best.count) best = b2;
|
|
2466
|
+
}
|
|
2467
|
+
if (best.count === 0) {
|
|
2468
|
+
resolve("#000000");
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
const r = Math.round(best.r / best.count), g = Math.round(best.g / best.count), b = Math.round(best.b / best.count);
|
|
2472
|
+
resolve(`#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`);
|
|
2473
|
+
} catch {
|
|
2474
|
+
resolve("#000000");
|
|
2475
|
+
}
|
|
2476
|
+
};
|
|
2477
|
+
img.onerror = () => resolve("#000000");
|
|
2478
|
+
img.src = imageUrl;
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2478
2482
|
// src/utils/announcement-storage.ts
|
|
2479
2483
|
function announcementDismissCookieName(platform) {
|
|
2480
2484
|
return `${platform}-announcement-dismissed`;
|
|
@@ -2503,19 +2507,6 @@ function isAnnouncementDismissed(platform, id) {
|
|
|
2503
2507
|
return false;
|
|
2504
2508
|
}
|
|
2505
2509
|
}
|
|
2506
|
-
function clearAnnouncementDismissals(platform) {
|
|
2507
|
-
if (typeof document === "undefined") return;
|
|
2508
|
-
document.cookie = `${announcementDismissCookieName(platform)}=; path=/; max-age=0`;
|
|
2509
|
-
try {
|
|
2510
|
-
const prefix = `${platform}-announcement-`;
|
|
2511
|
-
Object.keys(localStorage).forEach((key) => {
|
|
2512
|
-
if (key.startsWith(prefix) && key.endsWith("-dismissed")) {
|
|
2513
|
-
localStorage.removeItem(key);
|
|
2514
|
-
}
|
|
2515
|
-
});
|
|
2516
|
-
} catch {
|
|
2517
|
-
}
|
|
2518
|
-
}
|
|
2519
2510
|
function clearLegacyAnnouncementCache(platform) {
|
|
2520
2511
|
if (typeof window === "undefined") return;
|
|
2521
2512
|
try {
|
|
@@ -4046,6 +4037,6 @@ function toFigmaOriginalUrl(url) {
|
|
|
4046
4037
|
// src/utils/page-header-constants.ts
|
|
4047
4038
|
var SECTION_HERO_ICON_CLASS = "h-10 w-10 text-ods-accent";
|
|
4048
4039
|
|
|
4049
|
-
export { ANTHROPIC_SUPPORTED_IMAGE_MIME, AUTO_CONTINUATION_DIRECTIVE_PREFIX, BRAND_MARK_SVGS, CHAT_ATTACHMENT_MARKDOWN_PATTERN, CHAT_ATTACHMENT_VIEW_TOKEN_QUERY_PARAM, CHAT_ATTACHMENT_VIEW_URL_PREFIX, CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED, CONTENT_REF_GROUPS, CUSTOM_ITEM_ID, DEFAULT_CONTENT_SUFFIXES, DEFAULT_FOLDER_INDEX_FILE, DEFAULT_MIN_FILL_MS, DEFAULT_OS_PLATFORM, DELIVERY_TASK_TYPE_OPTIONS, DESIGN_PALETTE, DEV_SECTION_PARAM_KEYS, ELAPSED_MS_FIELD, GENERIC_EMAIL_DOMAINS, HEX_PATTERN, HONEYPOT_FIELD, HUB_HEADER_OFFSET_PX, ICON_REGISTRY, OPENFRAME_DEV_SECTIONS, OS_PLATFORMS, PLAY_ICON_PATH, ROADMAP_STATUS_OPTIONS, SCROLL_ANCHOR, SCROLL_ANCHOR_WIRE_KEY, SECTION_HERO_ICON_CLASS, SEO_TITLE_MAX_LENGTH, SOURCE_ICON_NAMES, SOURCE_LABELS_BY_TABLE, STICKY_HEADER_OFFSET_PX, TICKET_STATUS_OPTIONS, analyzeImageColor, announcementDismissCookieName, applyProxyAuth, brandMarkDataUri, buildAutoContinuationDirective, buildChatAttachmentViewUrl, buildDefaultHref, buildDiscussAddendum, buildDocumentTree, buildListUrl, buildOgPlaceholderUrl, buildSuggestionUrl, canonicalContentRefType, cleanEmailDomain,
|
|
4040
|
+
export { ANTHROPIC_SUPPORTED_IMAGE_MIME, AUTO_CONTINUATION_DIRECTIVE_PREFIX, BRAND_MARK_SVGS, CHAT_ATTACHMENT_MARKDOWN_PATTERN, CHAT_ATTACHMENT_VIEW_TOKEN_QUERY_PARAM, CHAT_ATTACHMENT_VIEW_URL_PREFIX, CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED, CONTENT_REF_GROUPS, CUSTOM_ITEM_ID, DEFAULT_CONTENT_SUFFIXES, DEFAULT_FOLDER_INDEX_FILE, DEFAULT_MIN_FILL_MS, DEFAULT_OS_PLATFORM, DELIVERY_TASK_TYPE_OPTIONS, DESIGN_PALETTE, DEV_SECTION_PARAM_KEYS, ELAPSED_MS_FIELD, GENERIC_EMAIL_DOMAINS, HEX_PATTERN, HONEYPOT_FIELD, HUB_HEADER_OFFSET_PX, ICON_REGISTRY, OPENFRAME_DEV_SECTIONS, OS_PLATFORMS, PLAY_ICON_PATH, ROADMAP_STATUS_OPTIONS, SCROLL_ANCHOR, SCROLL_ANCHOR_WIRE_KEY, SECTION_HERO_ICON_CLASS, SEO_TITLE_MAX_LENGTH, SOURCE_ICON_NAMES, SOURCE_LABELS_BY_TABLE, STICKY_HEADER_OFFSET_PX, TICKET_STATUS_OPTIONS, analyzeImageColor, announcementDismissCookieName, applyProxyAuth, brandMarkDataUri, buildAutoContinuationDirective, buildChatAttachmentViewUrl, buildDefaultHref, buildDiscussAddendum, buildDocumentTree, buildListUrl, buildOgPlaceholderUrl, buildSuggestionUrl, canonicalContentRefType, cleanEmailDomain, clearEmbedProxyAuth, clearLegacyAnnouncementCache, clickupTaskUrl, cn, consumeAccessCode, createUTCTimestamp, deepClone, delay, deriveActiveColor, deriveHoverColor, devSectionAnchorId, dismissAnnouncement, embedAuthedFetch, escapeMarkdownInline, evaluateHumanitySignals, extractDomainFromEmail, extractDominantColor, extractEntityIdFilter, extractHumanitySignals, extractImageEdgeColorAsync, extractItemId, extractItems, extractSections, faqItemAnchor, faqSectionSlug, fetchPriorityProp, findDocNodeByPath, flattenAssistantContent, formatAbbreviatedNumber, formatAbsoluteDate, formatBioText, formatBytes, formatBytesShort, formatChatAttachmentMarkdownForBubble, formatClassification, formatCompactMetric, formatCurrency, formatDate, formatDateRange, formatDateShort, formatDateSlashUTC, formatDateTime, formatDateTimeAt, formatDateUTC, formatDocName, formatDuration, formatDurationCompact, formatDurationFromMs, formatDurationFromRange, formatDurationMMSS, formatEntryMonthUTC, formatFileSize, formatLargeNumber, formatLegalDate, formatNumber, formatPercent, formatPhoneE164, formatPrice, formatPricingModel, formatRelativeTime, formatReleaseDate, formatSingularLookupInvocation, formatTicketFullTimestamp, formatTicketRelativeTime, formatTimeWithTimezone, formatUnderscoreText, formatWholeDollars, generateImageSizes, generateRandomString, getAllPlatformBaseDomains, getBaseUrl, getBestContrastColor, getConfidenceBgClass, getConfidenceBorderClass, getConfidenceColorClass, getConfidenceLabel, getConfidenceLevel, getConfidenceTextClass, getContentRefLabel, getContentRefLabelOrTitleCase, getContrastRatio, getCountryByCode, getCountryPhoneData, getCurrentPlatform, getDefaultColorForPlatform, getDefaultIconForPlatform, getDetailedTimeDifference, getDocAncestorNodeIds, getDocSourceDefaultPath, getDynamicIcon, getEmbedProxyAuth, getFirstLastInitials, getIconComponent, getInitialExpandedNodeIds, getLuminance, getOSIcon, getOSLabel, getOSPlatformId, getOSTypeDefinition, getPersistedProxyEmail, getPlatformAccentColor, getPlatformColor, getPlatformDescription, getPlatformDisplayName, getPlatformIcon, getPlatformIconComponent, getPlatformIconComponent as getPlatformLogo, getPlatformProductionUrl, getPlatformSlogan, getProxiedImageUrl, getReadableTextColor, getShellIcon, getShellLabel, getSlackCommunityJoinUrl, getSmallPlatformIcon, getSourceIconName, getSourceLabel, getStatusColorScheme, getTaskTypeLabel, getToolLabel, getToolTypeAliases, getTrendColors, hasGenericEmailDomain, hexToRgb, isAnnouncementDismissed, isCrossOriginUrl, isDismissedCookieValue, isFigmaSlidesUrl, isGenericDomain, isGenericWebsiteDomain, isOSPlatform, isToday, isValidEmailDomain, isValidToolType, isWithinMinutes, makeComposeContentUrl, markdownToPlainText, nameInitials, navigateSamePageHash, normalizeDocPath, normalizeDomain, normalizeHashFragment, normalizeIconKey, normalizeOSType, normalizeToolType, normalizeToolTypeWithFallback, orderContentRefTypes, parseFaqHash, parseScrollAnchor, parseWireCommandOverride, pathToNodeId, pickReadableTextColor, platformColors, platformDescriptions, platformDisplayNames, platformHexColors, platformIconNames, platformIcons, platformSlogans, readLeadingDecisionFrame, releaseTypeToBadgeColor, resolveContentFetchPath, resolveReleaseCover, rgbToHex, sanitizeTitleForChat, scrollElementIntoView, serializeJsonLd, setEmbedAuthAdapter, setEmbedProxyAuth, shouldProxyImage, sortTreeChildren, splitCsvEnv, stripChatAttachmentMarkdown, stripFolderIndexFromPath, stripHtml, stripInlineMarkdown, toDocSlug, toFigmaEmbedUrl, toFigmaOriginalUrl, toGoogleSheetsEmbedUrl, toGoogleSheetsOriginalUrl, toToolLabel, transformPlatformConfigsToOptions, truncateString, urlPathLooksLikeSvg, validateAccessCode, validateAndConsumeAccessCode, validateEmailDomain, validateEmailDomainList, validatePhoneNumber };
|
|
4050
4041
|
//# sourceMappingURL=index.js.map
|
|
4051
4042
|
//# sourceMappingURL=index.js.map
|