@flamingo-stack/openframe-frontend-core 0.0.405 → 0.0.406-snapshot.20260711131925
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-3KEBI6TP.cjs → chunk-2B6773QM.cjs} +1 -1
- package/dist/chunk-2B6773QM.cjs.map +1 -0
- package/dist/{chunk-RIGB7LP7.js → chunk-43H2WOAW.js} +3 -3
- package/dist/{chunk-QYTGHN2T.js → chunk-4UZH3MT2.js} +4 -4
- package/dist/{chunk-LREN3G7R.cjs → chunk-5M5W6XDY.cjs} +7 -7
- package/dist/{chunk-LREN3G7R.cjs.map → chunk-5M5W6XDY.cjs.map} +1 -1
- package/dist/{chunk-WEZIVLCO.cjs → chunk-74FWQI73.cjs} +18 -18
- package/dist/{chunk-WEZIVLCO.cjs.map → chunk-74FWQI73.cjs.map} +1 -1
- package/dist/{chunk-E6YHDT3D.js → chunk-7Q52HP45.js} +2 -2
- package/dist/chunk-7Q52HP45.js.map +1 -0
- package/dist/{chunk-3XCNFTFV.js → chunk-7XVFSGQA.js} +3 -3
- package/dist/{chunk-QAFRLO5N.cjs → chunk-CUN4CJUN.cjs} +10 -11
- package/dist/chunk-CUN4CJUN.cjs.map +1 -0
- package/dist/{chunk-ICJRSNBM.js → chunk-CVYSW33D.js} +199 -189
- package/dist/chunk-CVYSW33D.js.map +1 -0
- package/dist/{chunk-FOJRR647.cjs → chunk-DOBNDDNE.cjs} +75 -75
- package/dist/{chunk-FOJRR647.cjs.map → chunk-DOBNDDNE.cjs.map} +1 -1
- package/dist/{chunk-FFYEDIAG.cjs → chunk-GGDM5J4B.cjs} +332 -322
- package/dist/chunk-GGDM5J4B.cjs.map +1 -0
- package/dist/{chunk-UN2BJ7XW.js → chunk-GJSLKATJ.js} +2 -2
- package/dist/{chunk-GT7AJXKH.js → chunk-GMZL4T7C.js} +3 -3
- package/dist/{chunk-BK7QCB5J.js → chunk-H66L2265.js} +6 -6
- package/dist/{chunk-F3YLM5PO.js → chunk-HB63TQQO.js} +2 -2
- package/dist/{chunk-5XZEY34X.js → chunk-HJIRG7R6.js} +4 -4
- package/dist/{chunk-NA7XJRWB.js → chunk-KFQXO7QB.js} +1 -1
- package/dist/chunk-KFQXO7QB.js.map +1 -0
- package/dist/{chunk-Q2KKEE6W.js → chunk-KLBEIJVZ.js} +7 -7
- package/dist/{chunk-M6BGJVDY.cjs → chunk-LC6RRLFA.cjs} +15 -15
- package/dist/{chunk-M6BGJVDY.cjs.map → chunk-LC6RRLFA.cjs.map} +1 -1
- package/dist/{chunk-VFWEFR3Q.cjs → chunk-LPC3C7MG.cjs} +40 -40
- package/dist/{chunk-VFWEFR3Q.cjs.map → chunk-LPC3C7MG.cjs.map} +1 -1
- package/dist/{chunk-PNJ5LMVK.js → chunk-NO2KT42M.js} +9 -10
- package/dist/{chunk-PNJ5LMVK.js.map → chunk-NO2KT42M.js.map} +1 -1
- package/dist/{chunk-RC35ITSR.js → chunk-NSF7JUXF.js} +7 -7
- package/dist/{chunk-V4MOB3AD.cjs → chunk-PRKMOF2U.cjs} +14 -14
- package/dist/{chunk-V4MOB3AD.cjs.map → chunk-PRKMOF2U.cjs.map} +1 -1
- package/dist/{chunk-DHIYBC5Z.cjs → chunk-Q2MC3CBI.cjs} +35 -35
- package/dist/{chunk-DHIYBC5Z.cjs.map → chunk-Q2MC3CBI.cjs.map} +1 -1
- package/dist/{chunk-BS6O4HLJ.cjs → chunk-R4MXLJUS.cjs} +42 -42
- package/dist/{chunk-BS6O4HLJ.cjs.map → chunk-R4MXLJUS.cjs.map} +1 -1
- package/dist/{chunk-CCIBZ7TO.cjs → chunk-STGWQFYT.cjs} +5 -5
- package/dist/chunk-STGWQFYT.cjs.map +1 -0
- package/dist/{chunk-6OQ7YOX5.cjs → chunk-SY3QS2E5.cjs} +29 -29
- package/dist/{chunk-6OQ7YOX5.cjs.map → chunk-SY3QS2E5.cjs.map} +1 -1
- package/dist/{chunk-ELLTTMPE.cjs → chunk-WCPUJA3Y.cjs} +7 -7
- package/dist/{chunk-ELLTTMPE.cjs.map → chunk-WCPUJA3Y.cjs.map} +1 -1
- package/dist/{chunk-UIAQXIA6.js → chunk-XFP43YKG.js} +6 -6
- package/dist/{chunk-ACJ4CM6H.cjs → chunk-YX7C5JD7.cjs} +77 -77
- package/dist/{chunk-ACJ4CM6H.cjs.map → chunk-YX7C5JD7.cjs.map} +1 -1
- 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 +185 -179
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +38 -32
- 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 +0 -6
- 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 +3 -0
- 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 +0 -4
- package/dist/utils/color-analysis.d.ts.map +1 -1
- package/dist/utils/index.cjs +186 -177
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +185 -176
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/ods-color-utils.d.ts +2 -1
- package/dist/utils/ods-color-utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/announcement-bar.tsx +38 -21
- package/src/components/features/video.tsx +8 -0
- package/src/contexts/endpoints-runtime-context.tsx +1 -1
- package/src/hooks/use-self-fetch.ts +10 -9
- package/src/stories/AnnouncementBar.stories.tsx +8 -14
- package/src/types/announcement.ts +0 -8
- package/src/utils/announcement-storage.ts +17 -0
- package/src/utils/app-config.ts +3 -2
- package/src/utils/color-analysis.ts +5 -2
- package/src/utils/ods-color-utils.ts +4 -7
- package/dist/chunk-3KEBI6TP.cjs.map +0 -1
- package/dist/chunk-CCIBZ7TO.cjs.map +0 -1
- package/dist/chunk-E6YHDT3D.js.map +0 -1
- package/dist/chunk-FFYEDIAG.cjs.map +0 -1
- package/dist/chunk-ICJRSNBM.js.map +0 -1
- package/dist/chunk-NA7XJRWB.js.map +0 -1
- package/dist/chunk-QAFRLO5N.cjs.map +0 -1
- /package/dist/{chunk-RIGB7LP7.js.map → chunk-43H2WOAW.js.map} +0 -0
- /package/dist/{chunk-QYTGHN2T.js.map → chunk-4UZH3MT2.js.map} +0 -0
- /package/dist/{chunk-3XCNFTFV.js.map → chunk-7XVFSGQA.js.map} +0 -0
- /package/dist/{chunk-UN2BJ7XW.js.map → chunk-GJSLKATJ.js.map} +0 -0
- /package/dist/{chunk-GT7AJXKH.js.map → chunk-GMZL4T7C.js.map} +0 -0
- /package/dist/{chunk-BK7QCB5J.js.map → chunk-H66L2265.js.map} +0 -0
- /package/dist/{chunk-F3YLM5PO.js.map → chunk-HB63TQQO.js.map} +0 -0
- /package/dist/{chunk-5XZEY34X.js.map → chunk-HJIRG7R6.js.map} +0 -0
- /package/dist/{chunk-Q2KKEE6W.js.map → chunk-KLBEIJVZ.js.map} +0 -0
- /package/dist/{chunk-RC35ITSR.js.map → chunk-NSF7JUXF.js.map} +0 -0
- /package/dist/{chunk-UIAQXIA6.js.map → chunk-XFP43YKG.js.map} +0 -0
package/dist/utils/index.js
CHANGED
|
@@ -462,6 +462,174 @@ 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
|
+
|
|
465
633
|
// src/utils/ods-color-utils.ts
|
|
466
634
|
function getPlatformAccentColor(platform) {
|
|
467
635
|
const currentPlatform = platform || getCurrentPlatform();
|
|
@@ -486,18 +654,13 @@ function getCurrentPlatform() {
|
|
|
486
654
|
return process.env.NEXT_PUBLIC_APP_TYPE || "openmsp";
|
|
487
655
|
}
|
|
488
656
|
function getReadableTextColor(hex) {
|
|
489
|
-
|
|
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";
|
|
657
|
+
return pickReadableTextColor(hex) === "dark" ? "#212121" : "#fafafa";
|
|
495
658
|
}
|
|
496
659
|
var HEX_PATTERN = /^#[0-9a-fA-F]{6}$/;
|
|
497
660
|
function clamp(n, min, max) {
|
|
498
661
|
return Math.max(min, Math.min(max, n));
|
|
499
662
|
}
|
|
500
|
-
function
|
|
663
|
+
function hexToRgb2(hex) {
|
|
501
664
|
if (!HEX_PATTERN.test(hex)) return null;
|
|
502
665
|
const n = Number.parseInt(hex.slice(1), 16);
|
|
503
666
|
return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
|
|
@@ -509,7 +672,7 @@ function rgbToHex(r, g, b) {
|
|
|
509
672
|
var HOVER_DARKEN_STEP = 10;
|
|
510
673
|
var ACTIVE_DARKEN_STEP = 20;
|
|
511
674
|
function darkenByStep(hex, step) {
|
|
512
|
-
const rgb =
|
|
675
|
+
const rgb = hexToRgb2(hex);
|
|
513
676
|
if (!rgb) return hex;
|
|
514
677
|
return rgbToHex(rgb.r - step, rgb.g - step, rgb.b - step);
|
|
515
678
|
}
|
|
@@ -2312,173 +2475,6 @@ function isGenericWebsiteDomain(website) {
|
|
|
2312
2475
|
return isGenericDomain(normalizeDomain(website));
|
|
2313
2476
|
}
|
|
2314
2477
|
|
|
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
|
-
|
|
2482
2478
|
// src/utils/announcement-storage.ts
|
|
2483
2479
|
function announcementDismissCookieName(platform) {
|
|
2484
2480
|
return `${platform}-announcement-dismissed`;
|
|
@@ -2507,6 +2503,19 @@ function isAnnouncementDismissed(platform, id) {
|
|
|
2507
2503
|
return false;
|
|
2508
2504
|
}
|
|
2509
2505
|
}
|
|
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
|
+
}
|
|
2510
2519
|
function clearLegacyAnnouncementCache(platform) {
|
|
2511
2520
|
if (typeof window === "undefined") return;
|
|
2512
2521
|
try {
|
|
@@ -4037,6 +4046,6 @@ function toFigmaOriginalUrl(url) {
|
|
|
4037
4046
|
// src/utils/page-header-constants.ts
|
|
4038
4047
|
var SECTION_HERO_ICON_CLASS = "h-10 w-10 text-ods-accent";
|
|
4039
4048
|
|
|
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,
|
|
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, clearAnnouncementDismissals, 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, 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, hexToRgb2 as 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 };
|
|
4041
4050
|
//# sourceMappingURL=index.js.map
|
|
4042
4051
|
//# sourceMappingURL=index.js.map
|