semiotic 3.5.1 → 3.5.3
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/CLAUDE.md +26 -23
- package/README.md +27 -21
- package/ai/chartSuggestions.cjs +191 -3
- package/ai/componentMetadata.cjs +3 -3
- package/ai/dist/mcp-server.js +266 -48
- package/ai/examples.md +68 -0
- package/ai/schema.json +914 -1
- package/ai/system-prompt.md +4 -1
- package/dist/components/ThemeProvider.d.ts +2 -2
- package/dist/components/Tooltip/FlippingTooltip.d.ts +16 -1
- package/dist/components/charts/geo/FlowMap.d.ts +13 -4
- package/dist/components/charts/index.d.ts +6 -0
- package/dist/components/charts/network/OrbitDiagram.d.ts +5 -5
- package/dist/components/charts/network/ProcessSankey.d.ts +163 -0
- package/dist/components/charts/network/SankeyDiagram.d.ts +5 -1
- package/dist/components/charts/network/processSankey/algorithm.d.ts +193 -0
- package/dist/components/charts/network/processSankey/buildScenes.d.ts +51 -0
- package/dist/components/charts/network/processSankey/ribbonInputs.d.ts +32 -0
- package/dist/components/charts/network/processSankey/streamingLayout.d.ts +71 -0
- package/dist/components/charts/network/processSankey/tooltipUtils.d.ts +41 -0
- package/dist/components/charts/ordinal/BarChart.d.ts +12 -0
- package/dist/components/charts/ordinal/DotPlot.d.ts +9 -0
- package/dist/components/charts/ordinal/GaugeChart.d.ts +20 -0
- package/dist/components/charts/ordinal/SwimlaneChart.d.ts +5 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +16 -11
- package/dist/components/charts/realtime/RealtimeLineChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +2 -0
- package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +19 -0
- package/dist/components/charts/shared/axisExtent.d.ts +59 -0
- package/dist/components/charts/shared/chartSpecs.d.ts +75 -0
- package/dist/components/charts/shared/colorUtils.d.ts +8 -2
- package/dist/components/charts/shared/networkUtils.d.ts +3 -5
- package/dist/components/charts/shared/radialGeometry.d.ts +99 -0
- package/dist/components/charts/shared/regressionUtils.d.ts +59 -0
- package/dist/components/charts/shared/selectionUtils.d.ts +8 -1
- package/dist/components/charts/shared/streamPropsHelpers.d.ts +5 -0
- package/dist/components/charts/shared/tooltipUtils.d.ts +11 -0
- package/dist/components/charts/shared/types.d.ts +19 -0
- package/dist/components/charts/shared/useAreaSeriesSetup.d.ts +78 -0
- package/dist/components/charts/shared/useChartSetup.d.ts +2 -0
- package/dist/components/charts/shared/useCustomChartSetup.d.ts +1 -0
- package/dist/components/charts/shared/useEncodingDomain.d.ts +48 -0
- package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +1 -1
- package/dist/components/charts/shared/useNetworkChartSetup.d.ts +150 -0
- package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +87 -0
- package/dist/components/charts/shared/useSeriesFeatures.d.ts +57 -0
- package/dist/components/charts/shared/useStreamStatus.d.ts +33 -0
- package/dist/components/charts/shared/useXYLineStyle.d.ts +69 -0
- package/dist/components/charts/shared/useXYPointStyle.d.ts +87 -0
- package/dist/components/charts/shared/withChartWrapper.d.ts +10 -3
- package/dist/components/charts/xy/AreaChart.d.ts +36 -2
- package/dist/components/charts/xy/BubbleChart.d.ts +9 -0
- package/dist/components/charts/xy/ConnectedScatterplot.d.ts +16 -0
- package/dist/components/charts/xy/DifferenceChart.d.ts +172 -0
- package/dist/components/charts/xy/LineChart.d.ts +26 -2
- package/dist/components/charts/xy/Scatterplot.d.ts +39 -1
- package/dist/components/geometry/ribbonGeometry.d.ts +76 -0
- package/dist/components/semiotic-ai.d.ts +2 -0
- package/dist/components/semiotic-network.d.ts +4 -0
- package/dist/components/semiotic-realtime.d.ts +2 -0
- package/dist/components/semiotic-utils.d.ts +4 -0
- package/dist/components/semiotic-xy.d.ts +2 -0
- package/dist/components/semiotic.d.ts +4 -4
- package/dist/components/server/renderToStaticSVG.d.ts +2 -1
- package/dist/components/server/serverChartConfigs.d.ts +3 -0
- package/dist/components/server/staticAnnotations.d.ts +1 -1
- package/dist/components/server/themeResolver.d.ts +7 -1
- package/dist/components/store/ThemeStore.d.ts +7 -1
- package/dist/components/stream/AccessibleDataTable.d.ts +2 -2
- package/dist/components/stream/GeoPipelineStore.d.ts +21 -0
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +8 -0
- package/dist/components/stream/PipelineStore.d.ts +25 -13
- package/dist/components/stream/SVGOverlay.d.ts +9 -18
- package/dist/components/stream/accessorUtils.d.ts +2 -1
- package/dist/components/stream/annotationAccessorResolver.d.ts +39 -0
- package/dist/components/stream/geoTypes.d.ts +12 -0
- package/dist/components/stream/layouts/hierarchyLayoutPlugin.d.ts +1 -1
- package/dist/components/stream/networkTypes.d.ts +11 -0
- package/dist/components/stream/ordinalTypes.d.ts +27 -1
- package/dist/components/stream/renderers/cornerRadii.d.ts +33 -0
- package/dist/components/stream/renderers/wedgePathBuilder.d.ts +56 -0
- package/dist/components/stream/types.d.ts +127 -11
- package/dist/components/stream/xySceneBuilders/areaGradient.d.ts +20 -0
- package/dist/components/stream/xySceneBuilders/barScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/heatmapScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/lineScene.d.ts +4 -3
- package/dist/components/stream/xySceneBuilders/pointScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/ribbonScene.d.ts +107 -0
- package/dist/components/stream/xySceneBuilders/swarmScene.d.ts +2 -2
- package/dist/components/stream/xySceneBuilders/types.d.ts +9 -12
- package/dist/components/stream/xySceneBuilders/waterfallScene.d.ts +2 -2
- package/dist/components/types/legendTypes.d.ts +1 -1
- package/dist/geo.min.js +1 -1
- package/dist/geo.module.min.js +1 -1
- package/dist/network.min.js +1 -1
- package/dist/network.module.min.js +1 -1
- package/dist/ordinal.min.js +1 -1
- package/dist/ordinal.module.min.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai.d.ts +2 -0
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-data.min.js +1 -1
- package/dist/semiotic-data.module.min.js +1 -1
- package/dist/semiotic-network.d.ts +4 -0
- package/dist/semiotic-realtime.d.ts +2 -0
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-themes.min.js +1 -1
- package/dist/semiotic-themes.module.min.js +1 -1
- package/dist/semiotic-utils.d.ts +4 -0
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- package/dist/semiotic-xy.d.ts +2 -0
- package/dist/semiotic.d.ts +4 -4
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/dist/server.min.js +1 -1
- package/dist/server.module.min.js +1 -1
- package/dist/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +23 -10
- package/dist/components/stream/xySceneBuilders/boundsScene.d.ts +0 -9
package/ai/dist/mcp-server.js
CHANGED
|
@@ -3106,6 +3106,9 @@ var require_utils = __commonJS({
|
|
|
3106
3106
|
"use strict";
|
|
3107
3107
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3108
3108
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
3109
|
+
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3110
|
+
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3111
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
|
|
3109
3112
|
function stringArrayToHexStripped(input) {
|
|
3110
3113
|
let acc = "";
|
|
3111
3114
|
let code = 0;
|
|
@@ -3298,27 +3301,77 @@ var require_utils = __commonJS({
|
|
|
3298
3301
|
}
|
|
3299
3302
|
return output.join("");
|
|
3300
3303
|
}
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3304
|
+
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
3305
|
+
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
3306
|
+
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
3307
|
+
function reescapeHostDelimiters(host, isIP) {
|
|
3308
|
+
const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
3309
|
+
re.lastIndex = 0;
|
|
3310
|
+
return host.replace(re, (ch) => HOST_DELIMS[ch]);
|
|
3311
|
+
}
|
|
3312
|
+
function normalizePercentEncoding(input, decodeUnreserved = false) {
|
|
3313
|
+
if (input.indexOf("%") === -1) {
|
|
3314
|
+
return input;
|
|
3311
3315
|
}
|
|
3312
|
-
|
|
3313
|
-
|
|
3316
|
+
let output = "";
|
|
3317
|
+
for (let i = 0; i < input.length; i++) {
|
|
3318
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3319
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3320
|
+
if (isHexPair(hex3)) {
|
|
3321
|
+
const normalizedHex = hex3.toUpperCase();
|
|
3322
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3323
|
+
if (decodeUnreserved && isUnreserved(decoded)) {
|
|
3324
|
+
output += decoded;
|
|
3325
|
+
} else {
|
|
3326
|
+
output += "%" + normalizedHex;
|
|
3327
|
+
}
|
|
3328
|
+
i += 2;
|
|
3329
|
+
continue;
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
output += input[i];
|
|
3314
3333
|
}
|
|
3315
|
-
|
|
3316
|
-
|
|
3334
|
+
return output;
|
|
3335
|
+
}
|
|
3336
|
+
function normalizePathEncoding(input) {
|
|
3337
|
+
let output = "";
|
|
3338
|
+
for (let i = 0; i < input.length; i++) {
|
|
3339
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3340
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3341
|
+
if (isHexPair(hex3)) {
|
|
3342
|
+
const normalizedHex = hex3.toUpperCase();
|
|
3343
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3344
|
+
if (decoded !== "." && isUnreserved(decoded)) {
|
|
3345
|
+
output += decoded;
|
|
3346
|
+
} else {
|
|
3347
|
+
output += "%" + normalizedHex;
|
|
3348
|
+
}
|
|
3349
|
+
i += 2;
|
|
3350
|
+
continue;
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
if (isPathCharacter(input[i])) {
|
|
3354
|
+
output += input[i];
|
|
3355
|
+
} else {
|
|
3356
|
+
output += escape(input[i]);
|
|
3357
|
+
}
|
|
3317
3358
|
}
|
|
3318
|
-
|
|
3319
|
-
|
|
3359
|
+
return output;
|
|
3360
|
+
}
|
|
3361
|
+
function escapePreservingEscapes(input) {
|
|
3362
|
+
let output = "";
|
|
3363
|
+
for (let i = 0; i < input.length; i++) {
|
|
3364
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
3365
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
3366
|
+
if (isHexPair(hex3)) {
|
|
3367
|
+
output += "%" + hex3.toUpperCase();
|
|
3368
|
+
i += 2;
|
|
3369
|
+
continue;
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
output += escape(input[i]);
|
|
3320
3373
|
}
|
|
3321
|
-
return
|
|
3374
|
+
return output;
|
|
3322
3375
|
}
|
|
3323
3376
|
function recomposeAuthority(component) {
|
|
3324
3377
|
const uriTokens = [];
|
|
@@ -3333,7 +3386,7 @@ var require_utils = __commonJS({
|
|
|
3333
3386
|
if (ipV6res.isIPV6 === true) {
|
|
3334
3387
|
host = `[${ipV6res.escapedHost}]`;
|
|
3335
3388
|
} else {
|
|
3336
|
-
host =
|
|
3389
|
+
host = reescapeHostDelimiters(host, false);
|
|
3337
3390
|
}
|
|
3338
3391
|
}
|
|
3339
3392
|
uriTokens.push(host);
|
|
@@ -3347,7 +3400,10 @@ var require_utils = __commonJS({
|
|
|
3347
3400
|
module2.exports = {
|
|
3348
3401
|
nonSimpleDomain,
|
|
3349
3402
|
recomposeAuthority,
|
|
3350
|
-
|
|
3403
|
+
reescapeHostDelimiters,
|
|
3404
|
+
normalizePercentEncoding,
|
|
3405
|
+
normalizePathEncoding,
|
|
3406
|
+
escapePreservingEscapes,
|
|
3351
3407
|
removeDotSegments,
|
|
3352
3408
|
isIPv4,
|
|
3353
3409
|
isUUID,
|
|
@@ -3571,12 +3627,12 @@ var require_schemes = __commonJS({
|
|
|
3571
3627
|
var require_fast_uri = __commonJS({
|
|
3572
3628
|
"node_modules/fast-uri/index.js"(exports2, module2) {
|
|
3573
3629
|
"use strict";
|
|
3574
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority,
|
|
3630
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3575
3631
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
3576
3632
|
function normalize(uri, options) {
|
|
3577
3633
|
if (typeof uri === "string") {
|
|
3578
3634
|
uri = /** @type {T} */
|
|
3579
|
-
|
|
3635
|
+
normalizeString(uri, options);
|
|
3580
3636
|
} else if (typeof uri === "object") {
|
|
3581
3637
|
uri = /** @type {T} */
|
|
3582
3638
|
parse3(serialize(uri, options), options);
|
|
@@ -3643,19 +3699,9 @@ var require_fast_uri = __commonJS({
|
|
|
3643
3699
|
return target;
|
|
3644
3700
|
}
|
|
3645
3701
|
function equal(uriA, uriB, options) {
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
} else if (typeof uriA === "object") {
|
|
3650
|
-
uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
|
|
3651
|
-
}
|
|
3652
|
-
if (typeof uriB === "string") {
|
|
3653
|
-
uriB = unescape(uriB);
|
|
3654
|
-
uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
|
|
3655
|
-
} else if (typeof uriB === "object") {
|
|
3656
|
-
uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
|
|
3657
|
-
}
|
|
3658
|
-
return uriA.toLowerCase() === uriB.toLowerCase();
|
|
3702
|
+
const normalizedA = normalizeComparableURI(uriA, options);
|
|
3703
|
+
const normalizedB = normalizeComparableURI(uriB, options);
|
|
3704
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
|
|
3659
3705
|
}
|
|
3660
3706
|
function serialize(cmpts, opts) {
|
|
3661
3707
|
const component = {
|
|
@@ -3680,12 +3726,12 @@ var require_fast_uri = __commonJS({
|
|
|
3680
3726
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
3681
3727
|
if (component.path !== void 0) {
|
|
3682
3728
|
if (!options.skipEscape) {
|
|
3683
|
-
component.path =
|
|
3729
|
+
component.path = escapePreservingEscapes(component.path);
|
|
3684
3730
|
if (component.scheme !== void 0) {
|
|
3685
3731
|
component.path = component.path.split("%3A").join(":");
|
|
3686
3732
|
}
|
|
3687
3733
|
} else {
|
|
3688
|
-
component.path =
|
|
3734
|
+
component.path = normalizePercentEncoding(component.path);
|
|
3689
3735
|
}
|
|
3690
3736
|
}
|
|
3691
3737
|
if (options.reference !== "suffix" && component.scheme) {
|
|
@@ -3720,7 +3766,16 @@ var require_fast_uri = __commonJS({
|
|
|
3720
3766
|
return uriTokens.join("");
|
|
3721
3767
|
}
|
|
3722
3768
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
3723
|
-
function
|
|
3769
|
+
function getParseError(parsed, matches) {
|
|
3770
|
+
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
3771
|
+
return 'URI path must start with "/" when authority is present.';
|
|
3772
|
+
}
|
|
3773
|
+
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
3774
|
+
return "URI port is malformed.";
|
|
3775
|
+
}
|
|
3776
|
+
return void 0;
|
|
3777
|
+
}
|
|
3778
|
+
function parseWithStatus(uri, opts) {
|
|
3724
3779
|
const options = Object.assign({}, opts);
|
|
3725
3780
|
const parsed = {
|
|
3726
3781
|
scheme: void 0,
|
|
@@ -3731,6 +3786,7 @@ var require_fast_uri = __commonJS({
|
|
|
3731
3786
|
query: void 0,
|
|
3732
3787
|
fragment: void 0
|
|
3733
3788
|
};
|
|
3789
|
+
let malformedAuthorityOrPort = false;
|
|
3734
3790
|
let isIP = false;
|
|
3735
3791
|
if (options.reference === "suffix") {
|
|
3736
3792
|
if (options.scheme) {
|
|
@@ -3751,6 +3807,11 @@ var require_fast_uri = __commonJS({
|
|
|
3751
3807
|
if (isNaN(parsed.port)) {
|
|
3752
3808
|
parsed.port = matches[5];
|
|
3753
3809
|
}
|
|
3810
|
+
const parseError = getParseError(parsed, matches);
|
|
3811
|
+
if (parseError !== void 0) {
|
|
3812
|
+
parsed.error = parsed.error || parseError;
|
|
3813
|
+
malformedAuthorityOrPort = true;
|
|
3814
|
+
}
|
|
3754
3815
|
if (parsed.host) {
|
|
3755
3816
|
const ipv4result = isIPv4(parsed.host);
|
|
3756
3817
|
if (ipv4result === false) {
|
|
@@ -3789,14 +3850,18 @@ var require_fast_uri = __commonJS({
|
|
|
3789
3850
|
parsed.scheme = unescape(parsed.scheme);
|
|
3790
3851
|
}
|
|
3791
3852
|
if (parsed.host !== void 0) {
|
|
3792
|
-
parsed.host = unescape(parsed.host);
|
|
3853
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
3793
3854
|
}
|
|
3794
3855
|
}
|
|
3795
3856
|
if (parsed.path) {
|
|
3796
|
-
parsed.path =
|
|
3857
|
+
parsed.path = normalizePathEncoding(parsed.path);
|
|
3797
3858
|
}
|
|
3798
3859
|
if (parsed.fragment) {
|
|
3799
|
-
|
|
3860
|
+
try {
|
|
3861
|
+
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
3862
|
+
} catch {
|
|
3863
|
+
parsed.error = parsed.error || "URI malformed";
|
|
3864
|
+
}
|
|
3800
3865
|
}
|
|
3801
3866
|
}
|
|
3802
3867
|
if (schemeHandler && schemeHandler.parse) {
|
|
@@ -3805,7 +3870,29 @@ var require_fast_uri = __commonJS({
|
|
|
3805
3870
|
} else {
|
|
3806
3871
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
3807
3872
|
}
|
|
3808
|
-
return parsed;
|
|
3873
|
+
return { parsed, malformedAuthorityOrPort };
|
|
3874
|
+
}
|
|
3875
|
+
function parse3(uri, opts) {
|
|
3876
|
+
return parseWithStatus(uri, opts).parsed;
|
|
3877
|
+
}
|
|
3878
|
+
function normalizeString(uri, opts) {
|
|
3879
|
+
return normalizeStringWithStatus(uri, opts).normalized;
|
|
3880
|
+
}
|
|
3881
|
+
function normalizeStringWithStatus(uri, opts) {
|
|
3882
|
+
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
3883
|
+
return {
|
|
3884
|
+
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
3885
|
+
malformedAuthorityOrPort
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
function normalizeComparableURI(uri, opts) {
|
|
3889
|
+
if (typeof uri === "string") {
|
|
3890
|
+
const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
|
|
3891
|
+
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
3892
|
+
}
|
|
3893
|
+
if (typeof uri === "object") {
|
|
3894
|
+
return serialize(uri, opts);
|
|
3895
|
+
}
|
|
3809
3896
|
}
|
|
3810
3897
|
var fastUri = {
|
|
3811
3898
|
SCHEMES,
|
|
@@ -6808,6 +6895,7 @@ var require_componentMetadata = __commonJS({
|
|
|
6808
6895
|
xy: [
|
|
6809
6896
|
"LineChart",
|
|
6810
6897
|
"AreaChart",
|
|
6898
|
+
"DifferenceChart",
|
|
6811
6899
|
"StackedAreaChart",
|
|
6812
6900
|
"Scatterplot",
|
|
6813
6901
|
"QuadrantChart",
|
|
@@ -6839,6 +6927,7 @@ var require_componentMetadata = __commonJS({
|
|
|
6839
6927
|
network: [
|
|
6840
6928
|
"ForceDirectedGraph",
|
|
6841
6929
|
"SankeyDiagram",
|
|
6930
|
+
"ProcessSankey",
|
|
6842
6931
|
"ChordDiagram",
|
|
6843
6932
|
"TreeDiagram",
|
|
6844
6933
|
"Treemap",
|
|
@@ -6934,6 +7023,7 @@ var require_componentMetadata = __commonJS({
|
|
|
6934
7023
|
var require_chartSuggestions = __commonJS({
|
|
6935
7024
|
"ai/chartSuggestions.cjs"(exports2, module2) {
|
|
6936
7025
|
"use strict";
|
|
7026
|
+
var path2 = require("path");
|
|
6937
7027
|
var VALID_INTENTS = [
|
|
6938
7028
|
"comparison",
|
|
6939
7029
|
"trend",
|
|
@@ -6945,6 +7035,69 @@ var require_chartSuggestions = __commonJS({
|
|
|
6945
7035
|
"hierarchy"
|
|
6946
7036
|
];
|
|
6947
7037
|
var MAX_SAMPLE_SIZE = 5;
|
|
7038
|
+
var _capabilityMatrix = null;
|
|
7039
|
+
var _capabilityMatrixLoaded = false;
|
|
7040
|
+
function loadCapabilityMatrix() {
|
|
7041
|
+
if (_capabilityMatrixLoaded) return _capabilityMatrix;
|
|
7042
|
+
const candidates = [
|
|
7043
|
+
path2.join(__dirname, "capabilities.json"),
|
|
7044
|
+
path2.join(__dirname, "..", "capabilities.json")
|
|
7045
|
+
];
|
|
7046
|
+
for (const candidate of candidates) {
|
|
7047
|
+
try {
|
|
7048
|
+
const json2 = require(candidate);
|
|
7049
|
+
if (json2 && json2.charts) {
|
|
7050
|
+
_capabilityMatrix = json2.charts;
|
|
7051
|
+
_capabilityMatrixLoaded = true;
|
|
7052
|
+
return _capabilityMatrix;
|
|
7053
|
+
}
|
|
7054
|
+
} catch {
|
|
7055
|
+
}
|
|
7056
|
+
}
|
|
7057
|
+
_capabilityMatrixLoaded = true;
|
|
7058
|
+
return _capabilityMatrix;
|
|
7059
|
+
}
|
|
7060
|
+
var CAPABILITY_KEY_MAP = {
|
|
7061
|
+
push: "supportsPush",
|
|
7062
|
+
linkedHover: "supportsLinkedHover",
|
|
7063
|
+
ssr: "supportsSSR",
|
|
7064
|
+
selection: "supportsSelection",
|
|
7065
|
+
legend: "supportsLegend"
|
|
7066
|
+
};
|
|
7067
|
+
var VALID_CAPABILITY_KEYS = Object.keys(CAPABILITY_KEY_MAP);
|
|
7068
|
+
function chartSatisfiesCapabilities(chartName, requirements) {
|
|
7069
|
+
if (!requirements || Object.keys(requirements).length === 0) return true;
|
|
7070
|
+
const matrix = loadCapabilityMatrix();
|
|
7071
|
+
if (matrix == null) return false;
|
|
7072
|
+
const spec = matrix[chartName];
|
|
7073
|
+
if (!spec) return false;
|
|
7074
|
+
for (const [shortKey, want] of Object.entries(requirements)) {
|
|
7075
|
+
if (want == null) continue;
|
|
7076
|
+
const matrixKey = CAPABILITY_KEY_MAP[shortKey];
|
|
7077
|
+
if (!matrixKey) continue;
|
|
7078
|
+
const has = spec[matrixKey] === true;
|
|
7079
|
+
if (has !== want) return false;
|
|
7080
|
+
}
|
|
7081
|
+
return true;
|
|
7082
|
+
}
|
|
7083
|
+
function explainCapabilityMismatch(chartName, requirements) {
|
|
7084
|
+
if (!requirements || Object.keys(requirements).length === 0) return null;
|
|
7085
|
+
const matrix = loadCapabilityMatrix();
|
|
7086
|
+
if (matrix == null) return "capability matrix unavailable (run `npm run docs:capabilities`)";
|
|
7087
|
+
const spec = matrix[chartName];
|
|
7088
|
+
if (!spec) return `${chartName} not found in capability matrix`;
|
|
7089
|
+
const mismatches = [];
|
|
7090
|
+
for (const [shortKey, want] of Object.entries(requirements)) {
|
|
7091
|
+
if (want == null) continue;
|
|
7092
|
+
const matrixKey = CAPABILITY_KEY_MAP[shortKey];
|
|
7093
|
+
if (!matrixKey) continue;
|
|
7094
|
+
const has = spec[matrixKey] === true;
|
|
7095
|
+
if (has !== want) {
|
|
7096
|
+
mismatches.push(`requires ${shortKey}=${want} but ${matrixKey}=${has}`);
|
|
7097
|
+
}
|
|
7098
|
+
}
|
|
7099
|
+
return mismatches.length > 0 ? mismatches.join("; ") : null;
|
|
7100
|
+
}
|
|
6948
7101
|
function summarizeFields(data, keys) {
|
|
6949
7102
|
const numericFields = [];
|
|
6950
7103
|
const stringFields = [];
|
|
@@ -7003,16 +7156,38 @@ var require_chartSuggestions = __commonJS({
|
|
|
7003
7156
|
function suggestCharts2(args = {}) {
|
|
7004
7157
|
const data = args.data;
|
|
7005
7158
|
const intent = args.intent;
|
|
7159
|
+
const capabilities = args.capabilities;
|
|
7006
7160
|
if (intent && !VALID_INTENTS.includes(intent)) {
|
|
7007
7161
|
return {
|
|
7008
7162
|
ok: false,
|
|
7009
7163
|
error: `Unknown intent "${intent}". Expected one of: ${VALID_INTENTS.join(", ")}.`
|
|
7010
7164
|
};
|
|
7011
7165
|
}
|
|
7166
|
+
if (capabilities) {
|
|
7167
|
+
if (typeof capabilities !== "object" || Array.isArray(capabilities)) {
|
|
7168
|
+
return {
|
|
7169
|
+
ok: false,
|
|
7170
|
+
error: "capabilities must be an object like { push: true, linkedHover: true, ssr: true, selection: true, legend: true }."
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
7173
|
+
const unknown2 = Object.keys(capabilities).filter((k) => !VALID_CAPABILITY_KEYS.includes(k));
|
|
7174
|
+
if (unknown2.length > 0) {
|
|
7175
|
+
return {
|
|
7176
|
+
ok: false,
|
|
7177
|
+
error: `Unknown capability key(s): ${unknown2.join(", ")}. Expected: ${VALID_CAPABILITY_KEYS.join(", ")}.`
|
|
7178
|
+
};
|
|
7179
|
+
}
|
|
7180
|
+
if (loadCapabilityMatrix() == null) {
|
|
7181
|
+
return {
|
|
7182
|
+
ok: false,
|
|
7183
|
+
error: "Capability matrix unavailable: ai/capabilities.json is missing. Run `npm run docs:capabilities` to generate it. (Capability filtering requires the matrix; suggestions without a `capabilities` arg still work.)"
|
|
7184
|
+
};
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7012
7187
|
if (!data || !Array.isArray(data) || data.length === 0) {
|
|
7013
7188
|
return {
|
|
7014
7189
|
ok: false,
|
|
7015
|
-
error: "Pass { data: [{ ... }, ...] } with 1-5 sample data objects. Optionally include intent: 'comparison' | 'trend' | 'distribution' | 'relationship' | 'composition' | 'geographic' | 'network' | 'hierarchy'."
|
|
7190
|
+
error: "Pass { data: [{ ... }, ...] } with 1-5 sample data objects. Optionally include intent: 'comparison' | 'trend' | 'distribution' | 'relationship' | 'composition' | 'geographic' | 'network' | 'hierarchy', or capabilities: { push, linkedHover, ssr, selection, legend }."
|
|
7016
7191
|
};
|
|
7017
7192
|
}
|
|
7018
7193
|
if (data.length > MAX_SAMPLE_SIZE) {
|
|
@@ -7169,22 +7344,44 @@ var require_chartSuggestions = __commonJS({
|
|
|
7169
7344
|
props: { data: jsxExpression("data"), xAccessor: jsxString(xField), yAccessor: jsxString(yField), valueAccessor: jsxString(valueField) }
|
|
7170
7345
|
});
|
|
7171
7346
|
}
|
|
7347
|
+
const filteredSuggestions = capabilities ? suggestions.filter((s) => chartSatisfiesCapabilities(s.component, capabilities)) : suggestions;
|
|
7172
7348
|
return {
|
|
7173
7349
|
ok: true,
|
|
7174
7350
|
intent,
|
|
7351
|
+
capabilities,
|
|
7175
7352
|
fieldSummary: `Fields: ${keys.join(", ")} (${numericFields.length} numeric, ${stringFields.length} categorical, ${dateFields.length} date)`,
|
|
7176
7353
|
fields,
|
|
7177
|
-
suggestions
|
|
7354
|
+
suggestions: filteredSuggestions,
|
|
7355
|
+
// Surface the pre-filter set when a capability constraint was
|
|
7356
|
+
// applied — caller can see which suggestions were dropped and
|
|
7357
|
+
// whether to relax the constraint.
|
|
7358
|
+
...capabilities && filteredSuggestions.length < suggestions.length && {
|
|
7359
|
+
filteredOut: suggestions.filter((s) => !chartSatisfiesCapabilities(s.component, capabilities)).map((s) => ({
|
|
7360
|
+
component: s.component,
|
|
7361
|
+
// The `reason` here is the capability mismatch (which
|
|
7362
|
+
// constraint failed), not the original data-shape rationale
|
|
7363
|
+
// — callers debugging an empty result need to know which
|
|
7364
|
+
// capability to relax, not why the chart was originally
|
|
7365
|
+
// suggested.
|
|
7366
|
+
reason: explainCapabilityMismatch(s.component, capabilities) || "did not satisfy capability constraints"
|
|
7367
|
+
}))
|
|
7368
|
+
}
|
|
7178
7369
|
};
|
|
7179
7370
|
}
|
|
7180
7371
|
function formatSuggestionReport2(result) {
|
|
7181
7372
|
if (!result.ok) return result.error;
|
|
7182
7373
|
if (result.suggestions.length === 0) {
|
|
7183
|
-
|
|
7374
|
+
const tail = result.capabilities && result.filteredOut && result.filteredOut.length > 0 ? `
|
|
7375
|
+
|
|
7376
|
+
Dropped by capability filter (${formatCapabilityConstraints(result.capabilities)}):
|
|
7377
|
+
${result.filteredOut.map((s) => `- ${s.component}: ${s.reason}`).join("\n")}
|
|
7184
7378
|
|
|
7185
|
-
|
|
7379
|
+
Relax the capability constraints, or use getSchema to browse alternatives.` : `
|
|
7186
7380
|
|
|
7187
7381
|
Try providing intent ('${VALID_INTENTS.join("', '")}') to narrow recommendations, or use getSchema to browse available components.`;
|
|
7382
|
+
return `Could not confidently recommend a chart type.
|
|
7383
|
+
|
|
7384
|
+
${result.fieldSummary}${tail}`;
|
|
7188
7385
|
}
|
|
7189
7386
|
const lines = result.suggestions.map((suggestion, i) => {
|
|
7190
7387
|
const propsStr = Object.entries(suggestion.props).map(([k, v]) => `${k}=${v}`).join(" ");
|
|
@@ -7216,10 +7413,18 @@ Or use \`<ThemeProvider theme="dark">\` / \`<ThemeProvider theme={{ colors: {...
|
|
|
7216
7413
|
For accessibility, use \`colorScheme={COLOR_BLIND_SAFE_CATEGORICAL}\` (import from \`semiotic/themes\`) - 8-color palette safe for all forms of color blindness.`;
|
|
7217
7414
|
return lines.join("\n\n") + themingTip;
|
|
7218
7415
|
}
|
|
7416
|
+
function formatCapabilityConstraints(capabilities) {
|
|
7417
|
+
return Object.entries(capabilities).filter(([, v]) => v != null).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
7418
|
+
}
|
|
7219
7419
|
module2.exports = {
|
|
7220
7420
|
VALID_INTENTS,
|
|
7421
|
+
VALID_CAPABILITY_KEYS,
|
|
7221
7422
|
formatSuggestionReport: formatSuggestionReport2,
|
|
7222
|
-
suggestCharts: suggestCharts2
|
|
7423
|
+
suggestCharts: suggestCharts2,
|
|
7424
|
+
// Exported for tests + callers that want to filter their own
|
|
7425
|
+
// chart-name set without re-running the suggestion pipeline.
|
|
7426
|
+
chartSatisfiesCapabilities,
|
|
7427
|
+
explainCapabilityMismatch
|
|
7223
7428
|
};
|
|
7224
7429
|
}
|
|
7225
7430
|
});
|
|
@@ -32147,6 +32352,7 @@ var import_geo = require("semiotic/geo");
|
|
|
32147
32352
|
var COMPONENT_REGISTRY = {
|
|
32148
32353
|
LineChart: { component: import_ai.LineChart, category: "xy" },
|
|
32149
32354
|
AreaChart: { component: import_ai.AreaChart, category: "xy" },
|
|
32355
|
+
DifferenceChart: { component: import_ai.DifferenceChart, category: "xy" },
|
|
32150
32356
|
StackedAreaChart: { component: import_ai.StackedAreaChart, category: "xy" },
|
|
32151
32357
|
Scatterplot: { component: import_ai.Scatterplot, category: "xy" },
|
|
32152
32358
|
BubbleChart: { component: import_ai.BubbleChart, category: "xy" },
|
|
@@ -32175,6 +32381,7 @@ var COMPONENT_REGISTRY = {
|
|
|
32175
32381
|
ForceDirectedGraph: { component: import_ai.ForceDirectedGraph, category: "network" },
|
|
32176
32382
|
ChordDiagram: { component: import_ai.ChordDiagram, category: "network" },
|
|
32177
32383
|
SankeyDiagram: { component: import_ai.SankeyDiagram, category: "network" },
|
|
32384
|
+
ProcessSankey: { component: import_ai.ProcessSankey, category: "network" },
|
|
32178
32385
|
TreeDiagram: { component: import_ai.TreeDiagram, category: "network" },
|
|
32179
32386
|
Treemap: { component: import_ai.Treemap, category: "network" },
|
|
32180
32387
|
CirclePack: { component: import_ai.CirclePack, category: "network" },
|
|
@@ -32660,10 +32867,21 @@ function createServer2() {
|
|
|
32660
32867
|
);
|
|
32661
32868
|
srv.tool(
|
|
32662
32869
|
"suggestChart",
|
|
32663
|
-
"Recommend Semiotic chart types for a given data sample. Pass { data: [...] } with 1-5 sample objects. Optionally pass intent to narrow suggestions. Returns ranked recommendations with example props.",
|
|
32870
|
+
"Recommend Semiotic chart types for a given data sample. Pass { data: [...] } with 1-5 sample objects. Optionally pass intent to narrow suggestions, or capabilities to require/forbid features (push API, linked hover, SSR, selection, legend). Returns ranked recommendations with example props; charts that don't satisfy the capability constraints are dropped.",
|
|
32664
32871
|
{
|
|
32665
32872
|
data: external_exports3.array(external_exports3.record(external_exports3.string(), external_exports3.unknown())).min(1).max(5).describe("1-5 sample data objects"),
|
|
32666
|
-
intent: external_exports3.enum(["comparison", "trend", "distribution", "relationship", "composition", "geographic", "network", "hierarchy"]).optional().describe("Visualization intent to narrow suggestions")
|
|
32873
|
+
intent: external_exports3.enum(["comparison", "trend", "distribution", "relationship", "composition", "geographic", "network", "hierarchy"]).optional().describe("Visualization intent to narrow suggestions"),
|
|
32874
|
+
capabilities: external_exports3.object({
|
|
32875
|
+
push: external_exports3.boolean().optional().describe("Require ref-based push API (live streaming via ref.current.push())"),
|
|
32876
|
+
linkedHover: external_exports3.boolean().optional().describe("Require cross-chart linked hover support"),
|
|
32877
|
+
ssr: external_exports3.boolean().optional().describe("Require server-side rendering via renderChart()"),
|
|
32878
|
+
selection: external_exports3.boolean().optional().describe("Require named selection / cross-filter support"),
|
|
32879
|
+
legend: external_exports3.boolean().optional().describe("Require a top-level legend")
|
|
32880
|
+
// `.strict()` so the MCP surface rejects unknown capability
|
|
32881
|
+
// keys at the schema layer rather than silently stripping
|
|
32882
|
+
// them — keeps the cjs-level "Unknown capability key(s)"
|
|
32883
|
+
// validation from being unreachable from MCP callers.
|
|
32884
|
+
}).strict().optional().describe("Capability constraints \u2014 set a key to true to require, false to forbid. Unset keys are ignored.")
|
|
32667
32885
|
},
|
|
32668
32886
|
suggestChartHandler
|
|
32669
32887
|
);
|
package/ai/examples.md
CHANGED
|
@@ -199,6 +199,42 @@ const data = [
|
|
|
199
199
|
|
|
200
200
|
Key props: `y0Accessor` defines band bottom, `yAccessor` defines band top, `showLine={false}` hides the top edge stroke. Layer a `LineChart` on top for the main metric.
|
|
201
201
|
|
|
202
|
+
### DifferenceChart
|
|
203
|
+
|
|
204
|
+
```jsx
|
|
205
|
+
import { DifferenceChart } from "semiotic/ai"
|
|
206
|
+
|
|
207
|
+
const tempData = [
|
|
208
|
+
{ month: 1, actual: 38, normal: 32 },
|
|
209
|
+
{ month: 2, actual: 41, normal: 36 },
|
|
210
|
+
{ month: 3, actual: 45, normal: 48 },
|
|
211
|
+
{ month: 4, actual: 55, normal: 57 },
|
|
212
|
+
{ month: 5, actual: 61, normal: 66 },
|
|
213
|
+
{ month: 6, actual: 70, normal: 75 },
|
|
214
|
+
{ month: 7, actual: 79, normal: 79 },
|
|
215
|
+
{ month: 8, actual: 81, normal: 78 },
|
|
216
|
+
{ month: 9, actual: 74, normal: 70 },
|
|
217
|
+
{ month: 10, actual: 64, normal: 58 },
|
|
218
|
+
{ month: 11, actual: 52, normal: 47 },
|
|
219
|
+
{ month: 12, actual: 42, normal: 37 }
|
|
220
|
+
]
|
|
221
|
+
|
|
222
|
+
<DifferenceChart
|
|
223
|
+
data={tempData}
|
|
224
|
+
xAccessor="month"
|
|
225
|
+
seriesAAccessor="actual"
|
|
226
|
+
seriesBAccessor="normal"
|
|
227
|
+
seriesALabel="Actual"
|
|
228
|
+
seriesBLabel="Normal"
|
|
229
|
+
xLabel="Month"
|
|
230
|
+
yLabel="°F"
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Fills the region between two series with a color that switches based on which series is higher at each x — `seriesAColor` where A > B, `seriesBColor` where B > A. Crossover x-values are linearly interpolated so adjacent segments meet at zero-width vertices (no jagged seams). Classic uses: temperature anomaly, forecast vs. actual, budget variance, any A/B comparison.
|
|
235
|
+
|
|
236
|
+
Key props: `seriesALabel` / `seriesBLabel` (legend + tooltip), `seriesAColor` / `seriesBColor` (defaults to `var(--semiotic-danger)` / `var(--semiotic-info)`), `showLines` (default `true` — draws both series on top of the fill), `areaOpacity` (0.6), `gradientFill` (same shape as AreaChart), `windowSize` (max raw rows in push buffer; FIFO eviction). Push API: `ref.current.push({ x, a, b })` — accessor outputs coerce through a `toNumber` helper so `Date` (time series) and numeric strings (CSV/JSON) work transparently.
|
|
237
|
+
|
|
202
238
|
### StackedAreaChart
|
|
203
239
|
|
|
204
240
|
```jsx
|
|
@@ -661,6 +697,38 @@ const edges = [
|
|
|
661
697
|
|
|
662
698
|
Key props: **`edges`** (required, nodes inferred), `valueAccessor` controls band width
|
|
663
699
|
|
|
700
|
+
### ProcessSankey
|
|
701
|
+
|
|
702
|
+
```jsx
|
|
703
|
+
import { ProcessSankey } from "semiotic/ai"
|
|
704
|
+
|
|
705
|
+
const nodes = [
|
|
706
|
+
{ id: "Alice", category: "Person", xExtent: ["2026-01-06", "2026-01-06"] },
|
|
707
|
+
{ id: "Bob", category: "Person", xExtent: ["2026-02-01", "2026-02-01"] },
|
|
708
|
+
{ id: "Eng", category: "Team" },
|
|
709
|
+
{ id: "Release", category: "Milestone", xExtent: ["2026-04-15", "2026-05-30"] },
|
|
710
|
+
]
|
|
711
|
+
|
|
712
|
+
const edges = [
|
|
713
|
+
{ id: "alice-eng", source: "Alice", target: "Eng", value: 8,
|
|
714
|
+
startTime: "2026-01-20", endTime: "2026-02-10" },
|
|
715
|
+
{ id: "bob-eng", source: "Bob", target: "Eng", value: 5,
|
|
716
|
+
startTime: "2026-02-15", endTime: "2026-03-15" },
|
|
717
|
+
{ id: "eng-rel", source: "Eng", target: "Release", value: 13,
|
|
718
|
+
startTime: "2026-04-15", endTime: "2026-05-15" },
|
|
719
|
+
]
|
|
720
|
+
|
|
721
|
+
<ProcessSankey
|
|
722
|
+
nodes={nodes}
|
|
723
|
+
edges={edges}
|
|
724
|
+
domain={["2026-01-01", "2026-05-31"]}
|
|
725
|
+
colorBy="category"
|
|
726
|
+
showLegend
|
|
727
|
+
/>
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
Key props: **`edges`** with `startTime`/`endTime`, **`domain`** (required `[t0, t1]`); nodes optionally carry `xExtent: [start, end]` to bound the lane (`min(xExtent[0], earliestEdge)` to `max(xExtent[1], latestEdge)`). Use when flow events have timestamps; use SankeyDiagram for static total-flow snapshots.
|
|
731
|
+
|
|
664
732
|
### ChordDiagram
|
|
665
733
|
|
|
666
734
|
```jsx
|