| 527 | }; |
| 528 | |
| 529 | const normalizeDensityColormap = ( |
| 530 | value: unknown |
| 531 | ): NonNullable<ScatterSeriesConfig['densityColormap']> | undefined => { |
| 532 | if (typeof value === 'string') { |
| 533 | const v = value.trim().toLowerCase(); |
| 534 | return v === 'viridis' || v === 'plasma' || v === 'inferno' |
| 535 | ? (v as NonNullable<ScatterSeriesConfig['densityColormap']>) |
| 536 | : undefined; |
| 537 | } |
| 538 | |
| 539 | if (!Array.isArray(value)) return undefined; |
| 540 | |
| 541 | const isAlreadyCleanStringArray = |
| 542 | value.length > 0 && value.every((c) => typeof c === 'string' && c.length > 0 && c === c.trim()); |
| 543 | |
| 544 | if (isAlreadyCleanStringArray) { |
| 545 | const arr = value as string[]; |
| 546 | if (!Object.isFrozen(arr)) Object.freeze(arr); |
| 547 | return arr as readonly string[]; |
| 548 | } |
| 549 | |
| 550 | const sanitized = value |
| 551 | .filter((c): c is string => typeof c === 'string') |
| 552 | .map((c) => c.trim()) |
| 553 | .filter((c) => c.length > 0); |
| 554 | |
| 555 | if (sanitized.length === 0) return undefined; |
| 556 | Object.freeze(sanitized); |
| 557 | return sanitized as readonly string[]; |
| 558 | }; |
| 559 | |
| 560 | const normalizeCandlestickSampling = (value: unknown): 'none' | 'ohlc' | undefined => { |
| 561 | if (typeof value !== 'string') return undefined; |