cbrowser 18.76.0 → 18.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/audit-tools.js +32 -2
- package/dist/mcp-tools/base/audit-tools.js.map +1 -1
- package/dist/visual/attention-ai-layer.d.ts +93 -0
- package/dist/visual/attention-ai-layer.d.ts.map +1 -0
- package/dist/visual/attention-ai-layer.js +233 -0
- package/dist/visual/attention-ai-layer.js.map +1 -0
- package/dist/visual/fixation-corpus.d.ts +132 -0
- package/dist/visual/fixation-corpus.d.ts.map +1 -0
- package/dist/visual/fixation-corpus.js +212 -0
- package/dist/visual/fixation-corpus.js.map +1 -0
- package/dist/visual/saliency-metrics.d.ts +111 -0
- package/dist/visual/saliency-metrics.d.ts.map +1 -0
- package/dist/visual/saliency-metrics.js +225 -0
- package/dist/visual/saliency-metrics.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saliency evaluation metrics against human fixation ground truth.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS IS IN src/ AND NOT research/
|
|
5
|
+
*
|
|
6
|
+
* The Study 1 benchmark (UEyes, Jiang et al. CHI 2023 — 495 web pages, 62
|
|
7
|
+
* participants) reported AUC-Judd 0.663 / NSS 0.544 / CC 0.216 for the COT
|
|
8
|
+
* saliency model. Those numbers were produced by a *Python reimplementation*
|
|
9
|
+
* whose own docstring calls it a "vectorized Python port of CBrowser's
|
|
10
|
+
* computeLabSaliency()" — and the port had already drifted from the shipped
|
|
11
|
+
* code on the day the results were written: the TypeScript weights chrominance
|
|
12
|
+
* 3x over luminance (wA = wB = 3.0), the Python summed all three Lab channels
|
|
13
|
+
* unweighted.
|
|
14
|
+
*
|
|
15
|
+
* So the published accuracy claim did not describe the shipped model. Not
|
|
16
|
+
* because anyone was careless — because two implementations of one concept with
|
|
17
|
+
* nothing binding them will always drift, and a number is the last place that
|
|
18
|
+
* shows up.
|
|
19
|
+
*
|
|
20
|
+
* Putting the metrics here means the benchmark scores the code that ships, by
|
|
21
|
+
* construction. There is one saliency implementation and the evaluator calls it.
|
|
22
|
+
*
|
|
23
|
+
* THE METRICS
|
|
24
|
+
*
|
|
25
|
+
* Standard in the saliency literature (Bylinskii et al., "What do different
|
|
26
|
+
* evaluation metrics tell us about saliency models?", TPAMI 2019). They
|
|
27
|
+
* disagree with each other on purpose, and reporting one alone is how models
|
|
28
|
+
* get oversold:
|
|
29
|
+
*
|
|
30
|
+
* - AUC-Judd — location-based, ranks fixated pixels against all others.
|
|
31
|
+
* Invariant to monotonic rescaling, so it says nothing about calibration.
|
|
32
|
+
* Chance = 0.5.
|
|
33
|
+
* - NSS — value-based, mean normalized saliency at fixated points. Sensitive to
|
|
34
|
+
* false positives in a way AUC is not. Chance = 0.
|
|
35
|
+
* - CC — distribution-based, linear correlation with the full fixation map.
|
|
36
|
+
* Penalises both misses and false alarms symmetrically. Range [-1, 1].
|
|
37
|
+
*
|
|
38
|
+
* @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
|
|
39
|
+
* @license MIT
|
|
40
|
+
*/
|
|
41
|
+
/** A grid of saliency values. Row-major, any scale. */
|
|
42
|
+
export interface SaliencyGrid {
|
|
43
|
+
values: Float64Array | number[];
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
}
|
|
47
|
+
/** A single human fixation, in the grid's coordinate space. */
|
|
48
|
+
export interface Fixation {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
/** Dwell in ms, if known. Unused by these metrics but carried for weighting. */
|
|
52
|
+
duration?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface SaliencyScores {
|
|
55
|
+
/** Ranks fixated pixels against all pixels. Chance 0.5. */
|
|
56
|
+
aucJudd: number;
|
|
57
|
+
/** Mean normalized saliency at fixations. Chance 0. */
|
|
58
|
+
nss: number;
|
|
59
|
+
/** Pearson correlation with the ground-truth map. Range [-1, 1]. */
|
|
60
|
+
cc: number;
|
|
61
|
+
/** How many fixations landed inside the grid and were scored. */
|
|
62
|
+
fixationsScored: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Normalized Scanpath Saliency: the mean of the standardized saliency map at
|
|
66
|
+
* fixated locations.
|
|
67
|
+
*
|
|
68
|
+
* Unlike AUC this punishes a map that is salient everywhere — standardizing
|
|
69
|
+
* first means a model cannot buy score by raising the whole map.
|
|
70
|
+
*/
|
|
71
|
+
export declare function computeNSS(grid: SaliencyGrid, fixations: Fixation[]): {
|
|
72
|
+
nss: number;
|
|
73
|
+
scored: number;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* AUC-Judd: sweep a threshold over the saliency map; at each level the true
|
|
77
|
+
* positive rate is the share of fixations above it and the false positive rate
|
|
78
|
+
* is the share of ALL pixels above it. Area under that curve.
|
|
79
|
+
*
|
|
80
|
+
* Thresholds are the saliency values AT the fixations, which is what makes this
|
|
81
|
+
* Judd's variant rather than Borji's — no random negative sampling, so it is
|
|
82
|
+
* deterministic. That matters here: a metric used to compare model revisions
|
|
83
|
+
* must not itself introduce variance between runs.
|
|
84
|
+
*/
|
|
85
|
+
export declare function computeAUCJudd(grid: SaliencyGrid, fixations: Fixation[]): {
|
|
86
|
+
auc: number;
|
|
87
|
+
scored: number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Pearson correlation between the predicted map and a ground-truth fixation
|
|
91
|
+
* density map. Both are standardized, so this is scale-invariant.
|
|
92
|
+
*/
|
|
93
|
+
export declare function computeCC(grid: SaliencyGrid, groundTruth: SaliencyGrid): number;
|
|
94
|
+
/**
|
|
95
|
+
* Score a predicted saliency map against human fixations.
|
|
96
|
+
*
|
|
97
|
+
* `groundTruth` (a fixation density map) is optional because CC needs one while
|
|
98
|
+
* AUC and NSS need only the fixation points. Reporting CC as 0 when it was
|
|
99
|
+
* never computable would be indistinguishable from a genuinely uncorrelated
|
|
100
|
+
* model, so it is omitted from the average rather than faked.
|
|
101
|
+
*/
|
|
102
|
+
export declare function scoreSaliency(predicted: SaliencyGrid, fixations: Fixation[], groundTruth?: SaliencyGrid): SaliencyScores;
|
|
103
|
+
/**
|
|
104
|
+
* Resample a grid to a target size by area-averaging.
|
|
105
|
+
*
|
|
106
|
+
* Ground-truth fixation maps and predicted grids rarely share dimensions, and
|
|
107
|
+
* comparing them at different resolutions is the mistake `computeCC` refuses to
|
|
108
|
+
* make silently. This is the explicit way to reconcile them.
|
|
109
|
+
*/
|
|
110
|
+
export declare function resampleGrid(grid: SaliencyGrid, width: number, height: number): SaliencyGrid;
|
|
111
|
+
//# sourceMappingURL=saliency-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saliency-metrics.d.ts","sourceRoot":"","sources":["../../src/visual/saliency-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+DAA+D;AAC/D,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;CACzB;AAmBD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAYrG;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgEzG;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,GAAG,MAAM,CAa/E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,QAAQ,EAAE,EACrB,WAAW,CAAC,EAAE,YAAY,GACzB,cAAc,CAShB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAsB5F"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saliency evaluation metrics against human fixation ground truth.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS IS IN src/ AND NOT research/
|
|
5
|
+
*
|
|
6
|
+
* The Study 1 benchmark (UEyes, Jiang et al. CHI 2023 — 495 web pages, 62
|
|
7
|
+
* participants) reported AUC-Judd 0.663 / NSS 0.544 / CC 0.216 for the COT
|
|
8
|
+
* saliency model. Those numbers were produced by a *Python reimplementation*
|
|
9
|
+
* whose own docstring calls it a "vectorized Python port of CBrowser's
|
|
10
|
+
* computeLabSaliency()" — and the port had already drifted from the shipped
|
|
11
|
+
* code on the day the results were written: the TypeScript weights chrominance
|
|
12
|
+
* 3x over luminance (wA = wB = 3.0), the Python summed all three Lab channels
|
|
13
|
+
* unweighted.
|
|
14
|
+
*
|
|
15
|
+
* So the published accuracy claim did not describe the shipped model. Not
|
|
16
|
+
* because anyone was careless — because two implementations of one concept with
|
|
17
|
+
* nothing binding them will always drift, and a number is the last place that
|
|
18
|
+
* shows up.
|
|
19
|
+
*
|
|
20
|
+
* Putting the metrics here means the benchmark scores the code that ships, by
|
|
21
|
+
* construction. There is one saliency implementation and the evaluator calls it.
|
|
22
|
+
*
|
|
23
|
+
* THE METRICS
|
|
24
|
+
*
|
|
25
|
+
* Standard in the saliency literature (Bylinskii et al., "What do different
|
|
26
|
+
* evaluation metrics tell us about saliency models?", TPAMI 2019). They
|
|
27
|
+
* disagree with each other on purpose, and reporting one alone is how models
|
|
28
|
+
* get oversold:
|
|
29
|
+
*
|
|
30
|
+
* - AUC-Judd — location-based, ranks fixated pixels against all others.
|
|
31
|
+
* Invariant to monotonic rescaling, so it says nothing about calibration.
|
|
32
|
+
* Chance = 0.5.
|
|
33
|
+
* - NSS — value-based, mean normalized saliency at fixated points. Sensitive to
|
|
34
|
+
* false positives in a way AUC is not. Chance = 0.
|
|
35
|
+
* - CC — distribution-based, linear correlation with the full fixation map.
|
|
36
|
+
* Penalises both misses and false alarms symmetrically. Range [-1, 1].
|
|
37
|
+
*
|
|
38
|
+
* @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
|
|
39
|
+
* @license MIT
|
|
40
|
+
*/
|
|
41
|
+
/** Normalize to zero mean, unit standard deviation. */
|
|
42
|
+
function standardize(values) {
|
|
43
|
+
const n = values.length;
|
|
44
|
+
const out = new Float64Array(n);
|
|
45
|
+
if (n === 0)
|
|
46
|
+
return out;
|
|
47
|
+
let mean = 0;
|
|
48
|
+
for (let i = 0; i < n; i++)
|
|
49
|
+
mean += values[i];
|
|
50
|
+
mean /= n;
|
|
51
|
+
let variance = 0;
|
|
52
|
+
for (let i = 0; i < n; i++)
|
|
53
|
+
variance += (values[i] - mean) ** 2;
|
|
54
|
+
variance /= n;
|
|
55
|
+
const sd = Math.sqrt(variance);
|
|
56
|
+
if (sd === 0)
|
|
57
|
+
return out; // A flat map carries no signal; NSS is 0, not NaN.
|
|
58
|
+
for (let i = 0; i < n; i++)
|
|
59
|
+
out[i] = (values[i] - mean) / sd;
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Normalized Scanpath Saliency: the mean of the standardized saliency map at
|
|
64
|
+
* fixated locations.
|
|
65
|
+
*
|
|
66
|
+
* Unlike AUC this punishes a map that is salient everywhere — standardizing
|
|
67
|
+
* first means a model cannot buy score by raising the whole map.
|
|
68
|
+
*/
|
|
69
|
+
export function computeNSS(grid, fixations) {
|
|
70
|
+
const z = standardize(grid.values);
|
|
71
|
+
let sum = 0;
|
|
72
|
+
let scored = 0;
|
|
73
|
+
for (const f of fixations) {
|
|
74
|
+
const x = Math.floor(f.x);
|
|
75
|
+
const y = Math.floor(f.y);
|
|
76
|
+
if (x < 0 || y < 0 || x >= grid.width || y >= grid.height)
|
|
77
|
+
continue;
|
|
78
|
+
sum += z[y * grid.width + x];
|
|
79
|
+
scored++;
|
|
80
|
+
}
|
|
81
|
+
return { nss: scored > 0 ? sum / scored : 0, scored };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* AUC-Judd: sweep a threshold over the saliency map; at each level the true
|
|
85
|
+
* positive rate is the share of fixations above it and the false positive rate
|
|
86
|
+
* is the share of ALL pixels above it. Area under that curve.
|
|
87
|
+
*
|
|
88
|
+
* Thresholds are the saliency values AT the fixations, which is what makes this
|
|
89
|
+
* Judd's variant rather than Borji's — no random negative sampling, so it is
|
|
90
|
+
* deterministic. That matters here: a metric used to compare model revisions
|
|
91
|
+
* must not itself introduce variance between runs.
|
|
92
|
+
*/
|
|
93
|
+
export function computeAUCJudd(grid, fixations) {
|
|
94
|
+
const n = grid.values.length;
|
|
95
|
+
const inBounds = [];
|
|
96
|
+
for (const f of fixations) {
|
|
97
|
+
const x = Math.floor(f.x);
|
|
98
|
+
const y = Math.floor(f.y);
|
|
99
|
+
if (x < 0 || y < 0 || x >= grid.width || y >= grid.height)
|
|
100
|
+
continue;
|
|
101
|
+
inBounds.push(grid.values[y * grid.width + x]);
|
|
102
|
+
}
|
|
103
|
+
if (inBounds.length === 0 || n === 0)
|
|
104
|
+
return { auc: 0.5, scored: 0 };
|
|
105
|
+
// Sorted copy of the whole map, so each threshold's false-positive rate is a
|
|
106
|
+
// binary search rather than a scan — O(n log n) once instead of O(n) per
|
|
107
|
+
// fixation, which is the difference between usable and not on 1980 images.
|
|
108
|
+
const sorted = Float64Array.from(grid.values).sort();
|
|
109
|
+
const countAbove = (t) => {
|
|
110
|
+
let lo = 0;
|
|
111
|
+
let hi = sorted.length;
|
|
112
|
+
while (lo < hi) {
|
|
113
|
+
const mid = (lo + hi) >>> 1;
|
|
114
|
+
if (sorted[mid] < t)
|
|
115
|
+
lo = mid + 1;
|
|
116
|
+
else
|
|
117
|
+
hi = mid;
|
|
118
|
+
}
|
|
119
|
+
return sorted.length - lo;
|
|
120
|
+
};
|
|
121
|
+
const nFix = inBounds.length;
|
|
122
|
+
// UNIQUE thresholds, and TPR counted rather than assumed.
|
|
123
|
+
//
|
|
124
|
+
// Using (i+1)/nFix as the true-positive rate assumes every fixation sits at a
|
|
125
|
+
// distinct saliency value. Ties break it badly, and ties are the normal case:
|
|
126
|
+
// on a flat map every threshold is identical, so FPR jumped straight to 1
|
|
127
|
+
// while TPR was still 1/nFix — which scored a flat map 0.25 instead of the
|
|
128
|
+
// 0.5 that "carries no information" must produce, and pinned the WORST
|
|
129
|
+
// possible predictor at exactly 0.5. Both are the same arithmetic slip.
|
|
130
|
+
// Counting both rates at each distinct threshold is Judd's formulation.
|
|
131
|
+
// (2026-07-29)
|
|
132
|
+
const uniqueThresholds = [...new Set(inBounds)].sort((a, b) => b - a);
|
|
133
|
+
const fixSorted = [...inBounds].sort((a, b) => a - b);
|
|
134
|
+
const fixAtOrAbove = (t) => {
|
|
135
|
+
let lo = 0;
|
|
136
|
+
let hi = fixSorted.length;
|
|
137
|
+
while (lo < hi) {
|
|
138
|
+
const mid = (lo + hi) >>> 1;
|
|
139
|
+
if (fixSorted[mid] < t)
|
|
140
|
+
lo = mid + 1;
|
|
141
|
+
else
|
|
142
|
+
hi = mid;
|
|
143
|
+
}
|
|
144
|
+
return fixSorted.length - lo;
|
|
145
|
+
};
|
|
146
|
+
// Curve from (0,0) through each threshold to (1,1), trapezoidal integration.
|
|
147
|
+
let auc = 0;
|
|
148
|
+
let prevFpr = 0;
|
|
149
|
+
let prevTpr = 0;
|
|
150
|
+
for (const t of uniqueThresholds) {
|
|
151
|
+
const tpr = fixAtOrAbove(t) / nFix;
|
|
152
|
+
const fpr = countAbove(t) / n;
|
|
153
|
+
auc += ((fpr - prevFpr) * (tpr + prevTpr)) / 2;
|
|
154
|
+
prevFpr = fpr;
|
|
155
|
+
prevTpr = tpr;
|
|
156
|
+
}
|
|
157
|
+
auc += ((1 - prevFpr) * (1 + prevTpr)) / 2;
|
|
158
|
+
return { auc: Math.min(1, Math.max(0, auc)), scored: nFix };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Pearson correlation between the predicted map and a ground-truth fixation
|
|
162
|
+
* density map. Both are standardized, so this is scale-invariant.
|
|
163
|
+
*/
|
|
164
|
+
export function computeCC(grid, groundTruth) {
|
|
165
|
+
if (grid.values.length !== groundTruth.values.length) {
|
|
166
|
+
throw new Error(`CC needs matching grids: predicted ${grid.width}x${grid.height} vs ground truth ${groundTruth.width}x${groundTruth.height}. ` +
|
|
167
|
+
`Resample one before comparing — silently reshaping here would compare unrelated regions.`);
|
|
168
|
+
}
|
|
169
|
+
const a = standardize(grid.values);
|
|
170
|
+
const b = standardize(groundTruth.values);
|
|
171
|
+
let num = 0;
|
|
172
|
+
for (let i = 0; i < a.length; i++)
|
|
173
|
+
num += a[i] * b[i];
|
|
174
|
+
// Both are unit-variance, so the denominator is n.
|
|
175
|
+
return a.length > 0 ? num / a.length : 0;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Score a predicted saliency map against human fixations.
|
|
179
|
+
*
|
|
180
|
+
* `groundTruth` (a fixation density map) is optional because CC needs one while
|
|
181
|
+
* AUC and NSS need only the fixation points. Reporting CC as 0 when it was
|
|
182
|
+
* never computable would be indistinguishable from a genuinely uncorrelated
|
|
183
|
+
* model, so it is omitted from the average rather than faked.
|
|
184
|
+
*/
|
|
185
|
+
export function scoreSaliency(predicted, fixations, groundTruth) {
|
|
186
|
+
const { auc, scored } = computeAUCJudd(predicted, fixations);
|
|
187
|
+
const { nss } = computeNSS(predicted, fixations);
|
|
188
|
+
return {
|
|
189
|
+
aucJudd: auc,
|
|
190
|
+
nss,
|
|
191
|
+
cc: groundTruth ? computeCC(predicted, groundTruth) : Number.NaN,
|
|
192
|
+
fixationsScored: scored,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Resample a grid to a target size by area-averaging.
|
|
197
|
+
*
|
|
198
|
+
* Ground-truth fixation maps and predicted grids rarely share dimensions, and
|
|
199
|
+
* comparing them at different resolutions is the mistake `computeCC` refuses to
|
|
200
|
+
* make silently. This is the explicit way to reconcile them.
|
|
201
|
+
*/
|
|
202
|
+
export function resampleGrid(grid, width, height) {
|
|
203
|
+
const out = new Float64Array(width * height);
|
|
204
|
+
const xScale = grid.width / width;
|
|
205
|
+
const yScale = grid.height / height;
|
|
206
|
+
for (let y = 0; y < height; y++) {
|
|
207
|
+
const y0 = Math.floor(y * yScale);
|
|
208
|
+
const y1 = Math.min(grid.height, Math.max(y0 + 1, Math.ceil((y + 1) * yScale)));
|
|
209
|
+
for (let x = 0; x < width; x++) {
|
|
210
|
+
const x0 = Math.floor(x * xScale);
|
|
211
|
+
const x1 = Math.min(grid.width, Math.max(x0 + 1, Math.ceil((x + 1) * xScale)));
|
|
212
|
+
let sum = 0;
|
|
213
|
+
let count = 0;
|
|
214
|
+
for (let yy = y0; yy < y1; yy++) {
|
|
215
|
+
for (let xx = x0; xx < x1; xx++) {
|
|
216
|
+
sum += grid.values[yy * grid.width + xx];
|
|
217
|
+
count++;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
out[y * width + x] = count > 0 ? sum / count : 0;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return { values: out, width, height };
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=saliency-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saliency-metrics.js","sourceRoot":"","sources":["../../src/visual/saliency-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AA4BH,uDAAuD;AACvD,SAAS,WAAW,CAAC,MAAyB;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,CAAC;IACV,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,IAAI,CAAC,CAAC;IACd,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC,mDAAmD;IAC7E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7D,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAkB,EAAE,SAAqB;IAClE,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,SAAS;QACpE,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7B,MAAM,EAAE,CAAC;IACX,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAkB,EAAE,SAAqB;IACtE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,SAAS;QACpE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAErE,6EAA6E;IAC7E,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAA2B,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE;QACvC,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;;gBAC7B,EAAE,GAAG,GAAG,CAAC;QAChB,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE7B,0DAA0D;IAC1D,EAAE;IACF,8EAA8E;IAC9E,8EAA8E;IAC9E,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,wEAAwE;IACxE,wEAAwE;IACxE,eAAe;IACf,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,CAAC,CAAS,EAAU,EAAE;QACzC,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,IAAI,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;;gBAChC,EAAE,GAAG,GAAG,CAAC;QAChB,CAAC;QACD,OAAO,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC;IAC/B,CAAC,CAAC;IAEF,6EAA6E;IAC7E,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACnC,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9B,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,GAAG,GAAG,CAAC;QACd,OAAO,GAAG,GAAG,CAAC;IAChB,CAAC;IACD,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAkB,EAAE,WAAyB;IACrE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,sCAAsC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,oBAAoB,WAAW,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,IAAI;YAC5H,0FAA0F,CAC7F,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,mDAAmD;IACnD,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAuB,EACvB,SAAqB,EACrB,WAA0B;IAE1B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjD,OAAO;QACL,OAAO,EAAE,GAAG;QACZ,GAAG;QACH,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;QAChE,eAAe,EAAE,MAAM;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,KAAa,EAAE,MAAc;IAC5E,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAChF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAClC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/E,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;gBAChC,KAAK,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;oBAChC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;oBACzC,KAAK,EAAE,CAAC;gBACV,CAAC;YACH,CAAC;YACD,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cbrowser",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.78.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cognitive browser automation that thinks like your users—and helps AI agents navigate too. Simulate real user cognition with abandonment detection, constitutional safety, chaos engineering, and UX friction discovery. Sites that pass CBrowser's cognitive tests are easier for both humans and AI agents to navigate.",
|
|
6
6
|
"main": "dist/index.js",
|