diff --git a/crates/labcolors-core/src/agnostic_gates.rs b/crates/labcolors-core/src/agnostic_gates.rs index 376cc5bd..7130def7 100644 --- a/crates/labcolors-core/src/agnostic_gates.rs +++ b/crates/labcolors-core/src/agnostic_gates.rs @@ -321,7 +321,9 @@ fn acme_config() -> ThemeConfig { ), ( "brand-fill".to_string(), - brand_ladder(LadderPosition::FillPrimary), + RoleRecipe::PairFill { + source: LadderSource::Brand, + }, ), ( "brand-label".to_string(), @@ -331,8 +333,8 @@ fn acme_config() -> ThemeConfig { hue: Some(LadderSource::Brand), }, ), - // Лейбл тинт-бейджа: любой клиент получает жёсткий контраст - // label↔tinted-fill через тот же движок, без правок ядра. + // Лейбл пары: любой клиент получает жёсткий контраст против + // фактически emitted PairFill Surface через общий joint engine. ( "badge-label".to_string(), RoleRecipe::PairLabel { @@ -418,9 +420,9 @@ fn a_second_company_config_compiles_and_emits_a_valid_system() { "hued brand-label must resolve to a solved colour on {bg_hex}" ); - // Лейбл тинт-бейджа — агностичный жёсткий контраст: решается цветом и - // держит свой UI-пол (3:1) ПРОТИВ тинт-поверхности бренда (композит - // brand-fill), а не против фона страницы. Тот же движок, чужой конфиг. + // PairLabel — агностичный жёсткий контраст: решается цветом и держит + // UI-пол (3:1) против фактически emitted PairFill Surface, а не + // страницы или скрытой синтетической подложки. let badge_label = set.iter().find(|(n, _)| n == "badge-label").unwrap(); let Resolved::Color { solved, .. } = &badge_label.1 else { panic!("badge-label must resolve to a solved colour on {bg_hex}"); @@ -429,13 +431,13 @@ fn a_second_company_config_compiles_and_emits_a_valid_system() { let surface_hex = brand_fill .1 .translucent() - .expect("brand-fill is a translucent tinted surface") + .expect("brand-fill is the emitted PairFill surface") .composite_hex(); let enc = |h: &str| crate::spaces::srgb::srgb_encoded_from_hex(h).unwrap(); let ratio = crate::wcag::contrast_ratio(enc(solved.hex()), enc(surface_hex)); assert!( ratio >= 3.0 - 1e-9, - "badge-label must clear 3:1 against its tinted surface on {bg_hex}: got {ratio:.2}:1" + "badge-label must clear 3:1 against emitted PairFill on {bg_hex}: got {ratio:.2}:1" ); } } diff --git a/crates/labcolors-core/src/appearance.rs b/crates/labcolors-core/src/appearance.rs index 23143b23..97e134bd 100644 --- a/crates/labcolors-core/src/appearance.rs +++ b/crates/labcolors-core/src/appearance.rs @@ -1162,13 +1162,6 @@ impl ModeledSrgb8PointOccurrence { self.visible } - #[cfg_attr( - not(test), - expect( - dead_code, - reason = "shipped exact evaluator reads visible; backdrop is consumed by the test-private WCAG adapter" - ) - )] pub(crate) fn backdrop(self) -> [u8; 3] { self.backdrop } diff --git a/crates/labcolors-core/src/config.rs b/crates/labcolors-core/src/config.rs index a7797f24..31d5e8d7 100644 --- a/crates/labcolors-core/src/config.rs +++ b/crates/labcolors-core/src/config.rs @@ -435,28 +435,24 @@ pub enum RoleRecipe { /// Обязательный numerical-decision profile; implicit legacy запрещён. decision_profile: crate::glow::GlowDecisionProfileV1, }, - /// Переходная solid-эмиссия пары (внутренний модуль `pair`). Текущий heuristic - /// выбирает сторону и при необходимости сдвигает светлоту источника; это не - /// валидированный перцептивный закон. Результат не является поверхностью - /// [`PairLabel`](Self::PairLabel) и удаляется вместе с pair façade. + /// Frozen PairFill frontend до C7c. Источник эмитится opaque Paint через + /// общий point occurrence; отдельной Pair-эвристики и скрытой роли нет. PairFill { /// Источник якоря: бренд, семейство или нейтраль. source: LadderSource, }, - /// Переходный foreground пары. Он решается против внутренне синтезированной - /// tint-поверхности с alpha закрытой позиции `FillPrimary`, а не против - /// страницы и не против эмитированного [`PairFill`](Self::PairFill). - /// Наличие двух несвязанных поверхностей является известным разрывом SSOT; - /// target occurrence-граф заменяет оба варианта одной композицией. + /// Frozen PairLabel frontend до C7c. Label-кандидаты проверяются против + /// фактически emitted opaque [`PairFill`](Self::PairFill) Surface общим + /// joint hard-report и fresh recheck. PairLabel { /// Источник физической цветовой идентичности: бренд, семейство или нейтраль. source: LadderSource, - /// Доля максимума контраста тинт-поверхности `(0, 1]` (как у + /// Доля максимума контраста PairFill Surface `(0, 1]` (как у /// [`TextAnchor`](Self::TextAnchor)): низкая доля оставляет больше места /// для хромы источника у пола, высокая тянет к контрастному пределу. /// Точный серый source при любой доле остаётся нейтральным. fraction: f64, - /// WCAG-пол, энфорсимый ПРОТИВ тинт-поверхности (а не фона страницы). + /// WCAG-пол против emitted PairFill Surface, не страницы. floor: Floor, }, /// Альфа-аналог solid-источника через точечную композит-инверсию @@ -952,7 +948,7 @@ impl ThemeConfig { *fraction, FRACTION_MIN_EXCLUSIVE, FRACTION_MAX_INCLUSIVE, - "0 < fraction ≤ 1 (доля максимального контраста тинт-поверхности бейджа)", + "0 < fraction ≤ 1 (доля максимального контраста PairFill Surface)", ) } RoleRecipe::AlphaAnalog { of, alpha } => { @@ -1186,14 +1182,10 @@ impl ThemeConfig { fraction, floor, } => { - // Поверхность бейджа = семейный тинт при альфе `fill-*-primary` - // (@12) над фоном резолва. Альфа берётся из ЗАКРЫТОГО меню позиции - // (не литерал), поэтому tinted-badge лейбл и `fill-*-tinted` - // заливка всегда садятся на одну и ту же подложку по построению. - // `FillPrimary` здесь — ТОЛЬКО источник client-calibrated alpha - // на этапе lowering; физика и appearance-граф это имя не знают. - let (surface_alpha_light, surface_alpha_dark) = - crate::ladder::LadderPosition::FillPrimary.alpha_pair(); + // P1 унифицирует PairFill/PairLabel на единственной поверхности, + // которую публичный PairFill уже эмитил: opaque source Paint. + // Representation не выводится из клиентского имени позиции. + let (surface_alpha_light, surface_alpha_dark) = (1.0, 1.0); Ok(RoleSpec::PairLabel { tint: self.compile_ladder_tint(role, source)?, fraction: *fraction, diff --git a/crates/labcolors-core/src/config/preset.rs b/crates/labcolors-core/src/config/preset.rs index c8661367..3a315f7b 100644 --- a/crates/labcolors-core/src/config/preset.rs +++ b/crates/labcolors-core/src/config/preset.rs @@ -341,10 +341,9 @@ pub fn labui_preset_roles() -> Vec<(String, RoleRecipe)> { brand_pos(LadderPosition::FocusRing), )); - // Пары «заливка × лейбл» бейджа (crate::pair): якорь источника, минимально - // сдвинутый до выбранной ветви переходной pair-эвристики; - // лейбл на такой заливке — обычный nested resolve потребителя. Статики - // покрываются тем же законом (белый/чёрный якоря нейтрали). + // Frozen Pair frontend: PairFill эмитит exact source как opaque occurrence; + // PairLabel строит конечный candidate domain на фактически emitted Surface + // и проверяет его общим joint evaluator/recheck. Статики проходят тот же путь. let pair = |source| RoleRecipe::PairFill { source }; roles.push(("badge-fill-brand".to_string(), pair(LadderSource::Brand))); for (client_name, family_key) in [ diff --git a/crates/labcolors-core/src/config/tests.rs b/crates/labcolors-core/src/config/tests.rs index 5c752af9..3270bcca 100644 --- a/crates/labcolors-core/src/config/tests.rs +++ b/crates/labcolors-core/src/config/tests.rs @@ -659,7 +659,7 @@ const LABUI_CONSUMED_ROLES: &[&str] = &[ "border-neutral", "border-danger", "border-focus", - // Пары бейджа: заливка законом пары, лейбл — nested resolve потребителя. + // Пары бейджа: exact opaque fill и joint-verified label на emitted Surface. "badge-fill-brand", "badge-fill-danger", "badge-fill-warning", @@ -717,12 +717,12 @@ const COLLAPSED_ROLES: &[(&str, &str)] = &[ "оверлеи → alpha.rs-роли (вне поглощаемого GAP)", ), // Компонентные алиасы — конфиг-алиасы, не рецепты. Бейдж сузился законом - // пары: badge-fill-* стали первоклассной эмиссией (RoleRecipe::PairFill, - // crate::pair), коллапс остаётся только за лейблами бейджа — те решаются - // nested resolve потребителя от выведенной заливки. + // пары: badge-fill-* — первоклассная эмиссия RoleRecipe::PairFill; + // label frontend использует фактически emitted fill Surface без зависимости + // по имени токена. ( "badge-label-*", - "лейбл бейджа — nested resolve от заливки пары", + "лейбл бейджа — joint-verified foreground на emitted PairFill Surface", ), ("control-bg", "компонентный алиас, не рецепт эмиссии"), ]; @@ -1312,43 +1312,40 @@ fn value_test_bites_on_alpha_mutation() { ); } -/// Сторона пары — идентичность семьи НА РЕЗОЛВ-УРОВНЕ. Носитель класса — -/// БРЕНД под dark-IC: источник Brand несёт сырые якоря, и его dark-ic -/// (#409CFF, Y = 0.321) пересекает кроссовер 0.30. Семейные якоря (включая -/// info) разведены солвером и порог не straddle-ят — на них мутация -/// «сторона от vc» поведенчески неразличима (выживший мутант M3 -/// верификатора). Мутация semantic.rs srgb→vc обязана уронить ЭТОТ тест. +/// P1 не выводит representation из client-owned имени позиции и не двигает +/// authored source скрытой Pair-эвристикой. Во всех VC PairFill эмитит точный +/// выбранный source как opaque Paint; смена темы меняет только authored anchor. #[test] -fn pair_side_is_family_stable_across_themes_at_resolve_level() { +fn pair_fill_is_exact_opaque_source_across_viewing_conditions() { let table = labui_reference().compile_named_role_table().unwrap(); - let bg_dark = BgInput::solid("#101012").unwrap(); - let set = resolve_named_set( - &bg_dark, - &table, - &ViewingConditions::dim_surround_high_contrast(), - ) - .expect("валидная pair-side fixture обязана резолвиться"); - let (_, res) = set - .iter() - .find(|(n, _)| n == "badge-fill-brand") - .expect("паспорт несёт badge-fill-brand"); - let fill = res - .translucent() - .expect("заливка пары эмитится лестничной сантехникой"); - // Светлая сторона семьи: тёмная заливка (белый строго выигрывает - // штатную полярность — Y ниже выведенной границы WCAG). - let enc = - crate::spaces::srgb::srgb_encoded_from_hex(fill.tint_hex()).expect("эмиссия валидный hex"); - let lin = [ - crate::spaces::srgb::srgb_gamma_inv(enc[0]), - crate::spaces::srgb::srgb_gamma_inv(enc[1]), - crate::spaces::srgb::srgb_gamma_inv(enc[2]), + let cases = [ + (ViewingConditions::srgb(), "#FFFFFF", "#007AFF"), + (ViewingConditions::dim_surround(), "#101012", "#4A8FFF"), + ( + ViewingConditions::srgb_high_contrast(), + "#FFFFFF", + "#0040DD", + ), + ( + ViewingConditions::dim_surround_high_contrast(), + "#101012", + "#409CFF", + ), ]; - let y = 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2]; - assert!( - y < 0.17913, - "badge-fill-brand в dark-IC обязан быть утемнён под светлую сторону семьи (Y={y:.4})" - ); + + for (vc, background, expected_source) in cases { + let set = resolve_named_set(&BgInput::solid(background).unwrap(), &table, &vc) + .expect("валидная PairFill fixture обязана резолвиться"); + let (_, resolved) = set + .iter() + .find(|(name, _)| name == "badge-fill-brand") + .expect("паспорт несёт badge-fill-brand"); + let fill = resolved + .translucent() + .expect("PairFill эмитится общей rgba-формой"); + assert_eq!(fill.tint_hex(), expected_source); + assert_eq!(fill.alpha().to_bits(), 1.0_f64.to_bits()); + } } /// Дубликаты ключей всех словарей отвергаются (повтор имени = неоднозначный diff --git a/crates/labcolors-core/src/constraints/exact.rs b/crates/labcolors-core/src/constraints/exact.rs index 4675d9ab..c3e06d59 100644 --- a/crates/labcolors-core/src/constraints/exact.rs +++ b/crates/labcolors-core/src/constraints/exact.rs @@ -38,6 +38,7 @@ pub(crate) struct ExactIdentityViolationV1(()); pub(crate) type ExactPassEvidenceV1 = VisiblePointPassEvidence; pub(crate) type ExactViolationEvidenceV1 = VisiblePointViolationEvidence; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) struct ExactSrgb8IdentityV1; impl ExactSrgb8IdentityV1 { diff --git a/crates/labcolors-core/src/constraints/mod.rs b/crates/labcolors-core/src/constraints/mod.rs index 83e39ec3..fdcaf610 100644 --- a/crates/labcolors-core/src/constraints/mod.rs +++ b/crates/labcolors-core/src/constraints/mod.rs @@ -17,12 +17,13 @@ pub(crate) use exact::{ #[cfg(test)] pub(crate) use exact::ExactIdentityPassV1; -#[cfg(test)] mod wcag22; +pub(crate) use wcag22::Wcag22Srgb8V1; + #[cfg(test)] pub(crate) use wcag22::{ - ApplicableWcag22EvaluationErrorV1, ApplicableWcag22MeasurementV1, Wcag22PassV1, Wcag22Srgb8V1, + ApplicableWcag22EvaluationErrorV1, ApplicableWcag22MeasurementV1, Wcag22PassV1, Wcag22ViolationV1, }; @@ -142,13 +143,13 @@ pub(crate) trait HardClassifier: ) -> HardDecision; } -type PointInvocation = +pub(crate) type PointInvocation = >::Invocation; -type PointMeasurement = +pub(crate) type PointMeasurement = >::Measurement; -type PointPass = +pub(crate) type PointPass = , PointMeasurement>>::Pass; -type PointViolation = = , PointMeasurement, >>::Violation; diff --git a/crates/labcolors-core/src/constraints/wcag22.rs b/crates/labcolors-core/src/constraints/wcag22.rs index f866eef4..347014ce 100644 --- a/crates/labcolors-core/src/constraints/wcag22.rs +++ b/crates/labcolors-core/src/constraints/wcag22.rs @@ -7,6 +7,7 @@ use crate::wcag22::{ evaluate_wcag22_srgb8, wcag22_profile_v1, }; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) struct Wcag22Srgb8V1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -26,6 +27,7 @@ pub(crate) struct ApplicableWcag22MeasurementV1 { evidence: NumericalDecisionEvidenceV1, } +#[cfg(test)] impl ApplicableWcag22MeasurementV1 { pub(crate) const fn profile_id(&self) -> Wcag22ProfileIdV1 { self.profile_id diff --git a/crates/labcolors-core/src/exposure_support.rs b/crates/labcolors-core/src/exposure_support.rs index 8a5e7e74..4bd8ea58 100644 --- a/crates/labcolors-core/src/exposure_support.rs +++ b/crates/labcolors-core/src/exposure_support.rs @@ -50,21 +50,6 @@ pub(crate) fn grid_size() -> usize { n * n * n } -/// WCAG-люминанс (Rec.709) кодированного 8-битного цвета. -pub(crate) fn wcag_y(rgb: [u8; 3]) -> f64 { - let e = [ - rgb[0] as f64 / 255.0, - rgb[1] as f64 / 255.0, - rgb[2] as f64 / 255.0, - ]; - let l = [ - srgb_gamma_inv(e[0]), - srgb_gamma_inv(e[1]), - srgb_gamma_inv(e[2]), - ]; - 0.2126 * l[0] + 0.7152 * l[1] + 0.0722 * l[2] -} - /// 8-битные каналы hex-якоря. pub(crate) fn enc_of(hex: &str) -> [u8; 3] { let s = srgb_encoded_from_hex(hex).expect("passport hex valid"); diff --git a/crates/labcolors-core/src/joint.rs b/crates/labcolors-core/src/joint.rs index 324583dd..546e5289 100644 --- a/crates/labcolors-core/src/joint.rs +++ b/crates/labcolors-core/src/joint.rs @@ -3,19 +3,65 @@ //! Один code-owned program связывает две Paint-переменные через реальный //! `lower occurrence -> visible surface -> upper occurrence`. Candidate domain, //! полный hard-report, declared policy и fresh recheck являются разными типами. -//! Модуль не знает клиентских recipes, role taxonomy или legacy solver state и +//! Модуль не знает клиентских recipes, role taxonomy или evaluator families и //! не минтит terminal output certificate. +use core::fmt::Debug; + use crate::Srgb8; use crate::appearance::{ - EncodedPointPaintV1, PaintId, PointOpacityOverSurfaceV1, ResolvedOccurrence, SurfaceInputPortId, + EncodedPointPaintV1, ModeledSrgb8PointOccurrence, PaintId, PointOpacityOverSurfaceV1, + ResolvedOccurrence, SurfaceInputPortId, }; use crate::constraints::{ - ExactPassEvidenceV1, ExactSrgb8IdentityV1, ExactViolationEvidenceV1, HardDecision, + Evaluator, ExactSrgb8IdentityV1, HardClassifier, HardDecision, PointInvocation, + PointMeasurement, VisiblePointPassEvidence, VisiblePointViolationEvidence, assess_visible_point_hard, }; use crate::observation::{RevisionBoundObservationV1, ScenarioId}; +/// Sealed evaluator family, которую joint-program вызывает одинаково для +/// каждого target occurrence. Конкретные Exact/WCAG/readability payload-и +/// остаются в evaluator-модулях и не образуют центральный enum. +pub(crate) trait JointPointEvaluatorV1: Clone + Debug + PartialEq { + type Invocation: Clone + Debug + PartialEq; + type PassEvidence: Clone + Debug + PartialEq; + type ViolationEvidence: Clone + Debug + PartialEq; + type Error: Clone + Debug + PartialEq; + + fn assess( + &self, + occurrence: &ResolvedOccurrence, + invocation: Self::Invocation, + ) -> Result, Self::Error>; +} + +impl JointPointEvaluatorV1 for Evaluation +where + Evaluation: Clone + + Debug + + PartialEq + + Evaluator + + HardClassifier, PointMeasurement>, + PointInvocation: Clone + Debug + PartialEq, + VisiblePointPassEvidence: Clone + Debug + PartialEq, + VisiblePointViolationEvidence: Clone + Debug + PartialEq, + >::Error: Clone + Debug + PartialEq, +{ + type Invocation = PointInvocation; + type PassEvidence = VisiblePointPassEvidence; + type ViolationEvidence = VisiblePointViolationEvidence; + type Error = >::Error; + + fn assess( + &self, + occurrence: &ResolvedOccurrence, + invocation: Self::Invocation, + ) -> Result, Self::Error> { + assess_visible_point_hard(occurrence, self, invocation) + } +} + /// Canonical identity одного joint candidate. Число не является declaration /// order, расстоянием или скрытым приоритетом. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] @@ -108,25 +154,33 @@ impl JointConstraintIdV1 { } } -/// Physical occurrence, к которому относится exact hard predicate. +/// Physical occurrence, к которому относится hard predicate. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum JointVisibleTargetV1 { Lower, Upper, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) struct JointHardConstraintV1 { +/// Один constraint конкретного evaluator family. Invocation типизирована самим +/// evaluator-ом; family-specific enum в joint engine отсутствует. +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseJointHardConstraintV1 +where + Evaluation: JointPointEvaluatorV1, +{ id: JointConstraintIdV1, target: JointVisibleTargetV1, - invocation: Srgb8, + invocation: Evaluation::Invocation, } -impl JointHardConstraintV1 { - pub(crate) const fn exact( +impl PointwiseJointHardConstraintV1 +where + Evaluation: JointPointEvaluatorV1, +{ + pub(crate) fn new( id: JointConstraintIdV1, target: JointVisibleTargetV1, - invocation: Srgb8, + invocation: Evaluation::Invocation, ) -> Self { Self { id, @@ -136,41 +190,142 @@ impl JointHardConstraintV1 { } } -/// Identity первой private joint topology. Она не является public Program ID. +pub(crate) type JointHardConstraintV1 = PointwiseJointHardConstraintV1; + +impl PointwiseJointHardConstraintV1 { + pub(crate) fn exact( + id: JointConstraintIdV1, + target: JointVisibleTargetV1, + invocation: Srgb8, + ) -> Self { + Self::new(id, target, invocation) + } +} + +/// Identity первой private joint topology. Она не является public Program ID и +/// не кодирует evaluator family. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum JointPointProgramIdentityV1 { - TwoPaintDerivedSurfaceExactPointV1, + TwoPaintDerivedSurfacePointV1, } -/// Две связанные occurrences над одним observed root backdrop. +/// Наблюдение, пригодное для одного и того же execution/recheck kernel-а. +/// Runtime revision и статическая compiler binding остаются разными типами. +pub(crate) trait JointObservationV1: Clone + Debug + PartialEq { + fn root_index(&self, root: SurfaceInputPortId) -> Option; + fn case_count(&self) -> usize; + fn root_at(&self, case_index: usize, root_index: usize) -> Srgb8; + fn provenance(&self, case_index: usize) -> Option<&[ScenarioId]>; +} + +impl JointObservationV1 for RevisionBoundObservationV1 { + fn root_index(&self, root: SurfaceInputPortId) -> Option { + self.schema().binary_search(&root).ok() + } + + fn case_count(&self) -> usize { + self.set().cases().len() + } + + fn root_at(&self, case_index: usize, root_index: usize) -> Srgb8 { + self.set().cases()[case_index].bindings()[root_index] + } + + fn provenance(&self, case_index: usize) -> Option<&[ScenarioId]> { + self.set() + .cases() + .get(case_index) + .map(|case| case.provenance()) + } +} + +/// Один статический point case для build/synchronous resolver path. Тип не +/// содержит runtime stream/revision и не изобретает provenance, которой у +/// синхронного вызова нет. #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct JointPointProgramV1 { +pub(crate) struct StaticJointObservationV1 { + root_surface: SurfaceInputPortId, + root: Srgb8, +} + +impl StaticJointObservationV1 { + pub(crate) const fn one_case(root_surface: SurfaceInputPortId, root: Srgb8) -> Self { + Self { root_surface, root } + } +} + +impl JointObservationV1 for StaticJointObservationV1 { + fn root_index(&self, root: SurfaceInputPortId) -> Option { + (root == self.root_surface).then_some(0) + } + + fn case_count(&self) -> usize { + 1 + } + + fn root_at(&self, case_index: usize, root_index: usize) -> Srgb8 { + debug_assert_eq!(case_index, 0); + debug_assert_eq!(root_index, 0); + self.root + } + + fn provenance(&self, _case_index: usize) -> Option<&[ScenarioId]> { + None + } +} + +/// Две связанные occurrences над одним observed root backdrop. +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseJointPointProgramV1 +where + Evaluation: JointPointEvaluatorV1, +{ + evaluator: Evaluation, root_surface: SurfaceInputPortId, lower_paint: PaintId, upper_paint: PaintId, - constraints: Box<[JointHardConstraintV1]>, + constraints: Box<[PointwiseJointHardConstraintV1]>, } +pub(crate) type JointPointProgramV1 = PointwiseJointPointProgramV1; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum JointProgramErrorV1 { SamePaintIdentity(PaintId), - EmptyHardConstraintSet, DuplicateConstraint(JointConstraintIdV1), } -impl JointPointProgramV1 { +impl PointwiseJointPointProgramV1 { pub(crate) fn new( root_surface: SurfaceInputPortId, lower_paint: PaintId, upper_paint: PaintId, - mut constraints: Vec, + constraints: Vec, + ) -> Result { + Self::with_evaluator( + ExactSrgb8IdentityV1, + root_surface, + lower_paint, + upper_paint, + constraints, + ) + } +} + +impl PointwiseJointPointProgramV1 +where + Evaluation: JointPointEvaluatorV1, +{ + pub(crate) fn with_evaluator( + evaluator: Evaluation, + root_surface: SurfaceInputPortId, + lower_paint: PaintId, + upper_paint: PaintId, + mut constraints: Vec>, ) -> Result { if lower_paint == upper_paint { return Err(JointProgramErrorV1::SamePaintIdentity(lower_paint)); } - if constraints.is_empty() { - return Err(JointProgramErrorV1::EmptyHardConstraintSet); - } constraints.sort_unstable_by_key(|constraint| constraint.id); for pair in constraints.windows(2) { if pair[0].id == pair[1].id { @@ -178,6 +333,7 @@ impl JointPointProgramV1 { } } Ok(Self { + evaluator, root_surface, lower_paint, upper_paint, @@ -186,24 +342,30 @@ impl JointPointProgramV1 { } const fn identity(&self) -> JointPointProgramIdentityV1 { - JointPointProgramIdentityV1::TwoPaintDerivedSurfaceExactPointV1 + JointPointProgramIdentityV1::TwoPaintDerivedSurfacePointV1 } - pub(crate) fn evaluate( + pub(crate) fn evaluate( &self, candidates: JointCandidateSetV1, - observation: RevisionBoundObservationV1, - ) -> Result { + observation: Observation, + ) -> Result< + PointwiseFullHardReportV1, + PointwiseJointReportErrorV1, + > + where + Observation: JointObservationV1, + { self.validate_candidates(&candidates)?; - let root_index = observation - .schema() - .binary_search(&self.root_surface) - .map_err(|_| JointReportErrorV1::MissingRootSurface(self.root_surface))?; - let (execution_count, cell_count) = checked_joint_cardinality( + let root_index = observation.root_index(self.root_surface).ok_or( + PointwiseJointReportErrorV1::MissingRootSurface(self.root_surface), + )?; + let (execution_count, cell_count) = checked_joint_cardinality_raw( candidates.candidates.len(), - observation.set().cases().len(), + observation.case_count(), self.constraints.len(), - )?; + ) + .map_err(|_| PointwiseJointReportErrorV1::ResourceExhausted)?; let matrices = self.execute( candidates.candidates(), &observation, @@ -211,7 +373,7 @@ impl JointPointProgramV1 { execution_count, cell_count, )?; - Ok(FullHardReportV1 { + Ok(PointwiseFullHardReportV1 { program_identity: self.identity(), program: self.clone(), candidates, @@ -224,10 +386,10 @@ impl JointPointProgramV1 { fn validate_candidates( &self, candidates: &JointCandidateSetV1, - ) -> Result<(), JointReportErrorV1> { + ) -> Result<(), PointwiseJointReportErrorV1> { for candidate in candidates.candidates() { if candidate.lower.id() != self.lower_paint { - return Err(JointReportErrorV1::CandidatePaintMismatch { + return Err(PointwiseJointReportErrorV1::CandidatePaintMismatch { ordinal: candidate.ordinal, stage: JointVisibleTargetV1::Lower, expected: self.lower_paint, @@ -235,7 +397,7 @@ impl JointPointProgramV1 { }); } if candidate.upper.id() != self.upper_paint { - return Err(JointReportErrorV1::CandidatePaintMismatch { + return Err(PointwiseJointReportErrorV1::CandidatePaintMismatch { ordinal: candidate.ordinal, stage: JointVisibleTargetV1::Upper, expected: self.upper_paint, @@ -246,26 +408,32 @@ impl JointPointProgramV1 { Ok(()) } - fn execute( + fn execute( &self, candidates: &[JointCandidateTupleV1], - observation: &RevisionBoundObservationV1, + observation: &Observation, root_index: usize, execution_count: usize, cell_count: usize, - ) -> Result { + ) -> Result< + PointwiseJointEvaluationMatricesV1, + PointwiseJointReportErrorV1, + > + where + Observation: JointObservationV1, + { let mut executions = Vec::new(); executions .try_reserve_exact(execution_count) - .map_err(|_| JointReportErrorV1::ResourceExhausted)?; + .map_err(|_| PointwiseJointReportErrorV1::ResourceExhausted)?; let mut cells = Vec::new(); cells .try_reserve_exact(cell_count) - .map_err(|_| JointReportErrorV1::ResourceExhausted)?; + .map_err(|_| PointwiseJointReportErrorV1::ResourceExhausted)?; for candidate in candidates { - for (case_index, case) in observation.set().cases().iter().enumerate() { - let root = case.bindings()[root_index]; + for case_index in 0..observation.case_count() { + let root = observation.root_at(case_index, root_index); let lower = PointOpacityOverSurfaceV1::evaluate_admitted( candidate.lower.source().bytes(), candidate.lower.opacity(), @@ -287,25 +455,26 @@ impl JointPointProgramV1 { upper, }); - for constraint in self.constraints.iter().copied() { + for constraint in self.constraints.iter().cloned() { let occurrence = match constraint.target { JointVisibleTargetV1::Lower => &lower, JointVisibleTargetV1::Upper => &upper, }; - let decision = match assess_visible_point_hard( - occurrence, - &ExactSrgb8IdentityV1, - constraint.invocation, - ) { - Ok(HardDecision::Pass(evidence)) => { - JointConstraintDecisionV1::Pass(evidence) + // Evaluator `Err` означает отсутствие валидного hard verdict, + // поэтому частичная матрица не называется FullHardReport. + let decision = match self + .evaluator + .assess(occurrence, constraint.invocation.clone()) + .map_err(PointwiseJointReportErrorV1::Evaluator)? + { + HardDecision::Pass(evidence) => { + PointwiseJointConstraintDecisionV1::Pass(evidence) } - Ok(HardDecision::Violation(evidence)) => { - JointConstraintDecisionV1::Violation(evidence) + HardDecision::Violation(evidence) => { + PointwiseJointConstraintDecisionV1::Violation(evidence) } - Err(error) => match error {}, }; - cells.push(JointConstraintCellV1 { + cells.push(PointwiseJointConstraintCellV1 { ordinal: candidate.ordinal, constraint: constraint.id, target: constraint.target, @@ -318,15 +487,18 @@ impl JointPointProgramV1 { debug_assert_eq!(executions.len(), execution_count); debug_assert_eq!(cells.len(), cell_count); - Ok(JointEvaluationMatricesV1 { + Ok(PointwiseJointEvaluationMatricesV1 { executions: executions.into_boxed_slice(), cells: cells.into_boxed_slice(), }) } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum JointReportErrorV1 { +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum PointwiseJointReportErrorV1 +where + Evaluation: JointPointEvaluatorV1, +{ MissingRootSurface(SurfaceInputPortId), CandidatePaintMismatch { ordinal: CandidateOrdinalV1, @@ -334,31 +506,51 @@ pub(crate) enum JointReportErrorV1 { expected: PaintId, actual: PaintId, }, + Evaluator(Evaluation::Error), ResourceExhausted, } -pub(crate) fn checked_joint_cardinality( +pub(crate) type JointReportErrorV1 = PointwiseJointReportErrorV1; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum JointCapacityErrorV1 { + ResourceExhausted, +} + +fn checked_joint_cardinality_raw( candidates: usize, cases: usize, constraints: usize, -) -> Result<(usize, usize), JointReportErrorV1> { +) -> Result<(usize, usize), JointCapacityErrorV1> { let executions = candidates .checked_mul(cases) - .ok_or(JointReportErrorV1::ResourceExhausted)?; + .ok_or(JointCapacityErrorV1::ResourceExhausted)?; let cells = executions .checked_mul(constraints) - .ok_or(JointReportErrorV1::ResourceExhausted)?; + .ok_or(JointCapacityErrorV1::ResourceExhausted)?; Ok((executions, cells)) } -#[derive(Debug, Clone, PartialEq, Eq)] -struct JointEvaluationMatricesV1 { +pub(crate) fn checked_joint_cardinality( + candidates: usize, + cases: usize, + constraints: usize, +) -> Result<(usize, usize), JointReportErrorV1> { + checked_joint_cardinality_raw(candidates, cases, constraints) + .map_err(|_| JointReportErrorV1::ResourceExhausted) +} + +#[derive(Debug, Clone, PartialEq)] +struct PointwiseJointEvaluationMatricesV1 +where + Evaluation: JointPointEvaluatorV1, +{ executions: Box<[JointExecutionRecordV1]>, - cells: Box<[JointConstraintCellV1]>, + cells: Box<[PointwiseJointConstraintCellV1]>, } /// Один execution record существует независимо от наличия constraint на lower. -/// Поэтому связь derived surface доказана даже при единственном upper predicate. +/// Поэтому связь derived surface доказана даже при пустом constraint set. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) struct JointExecutionRecordV1 { ordinal: CandidateOrdinalV1, @@ -386,6 +578,14 @@ impl JointExecutionRecordV1 { self.upper_paint } + pub(crate) const fn lower_occurrence(&self) -> &ResolvedOccurrence { + &self.lower + } + + pub(crate) const fn upper_occurrence(&self) -> &ResolvedOccurrence { + &self.upper + } + pub(crate) fn lower_visible(&self) -> Srgb8 { Srgb8::new(self.lower.visible()) } @@ -399,17 +599,28 @@ impl JointExecutionRecordV1 { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum JointConstraintDecisionV1 { - Pass(ExactPassEvidenceV1), - Violation(ExactViolationEvidenceV1), +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum PointwiseJointConstraintDecisionV1 +where + Evaluation: JointPointEvaluatorV1, +{ + Pass(Evaluation::PassEvidence), + Violation(Evaluation::ViolationEvidence), } -impl JointConstraintDecisionV1 { +pub(crate) type JointConstraintDecisionV1 = + PointwiseJointConstraintDecisionV1; + +impl PointwiseJointConstraintDecisionV1 +where + Evaluation: JointPointEvaluatorV1, +{ pub(crate) const fn is_pass(&self) -> bool { matches!(self, Self::Pass(_)) } +} +impl PointwiseJointConstraintDecisionV1 { pub(crate) fn actual(&self) -> Srgb8 { match self { Self::Pass(evidence) => evidence.actual(), @@ -425,16 +636,22 @@ impl JointConstraintDecisionV1 { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) struct JointConstraintCellV1 { +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseJointConstraintCellV1 +where + Evaluation: JointPointEvaluatorV1, +{ ordinal: CandidateOrdinalV1, constraint: JointConstraintIdV1, target: JointVisibleTargetV1, case_index: usize, - decision: JointConstraintDecisionV1, + decision: PointwiseJointConstraintDecisionV1, } -impl JointConstraintCellV1 { +impl PointwiseJointConstraintCellV1 +where + Evaluation: JointPointEvaluatorV1, +{ pub(crate) const fn ordinal(&self) -> CandidateOrdinalV1 { self.ordinal } @@ -451,24 +668,32 @@ impl JointConstraintCellV1 { self.case_index } - pub(crate) const fn decision(&self) -> &JointConstraintDecisionV1 { + pub(crate) const fn decision(&self) -> &PointwiseJointConstraintDecisionV1 { &self.decision } } /// Полная матрица candidate x constraint x unique physical case плюс отдельная /// joint execution matrix candidate x case. Report не знает selection policy. -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct FullHardReportV1 { +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseFullHardReportV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ program_identity: JointPointProgramIdentityV1, - program: JointPointProgramV1, + program: PointwiseJointPointProgramV1, candidates: JointCandidateSetV1, - observation: RevisionBoundObservationV1, + observation: Observation, executions: Box<[JointExecutionRecordV1]>, - cells: Box<[JointConstraintCellV1]>, + cells: Box<[PointwiseJointConstraintCellV1]>, } -impl FullHardReportV1 { +impl PointwiseFullHardReportV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ pub(crate) const fn program_identity(&self) -> JointPointProgramIdentityV1 { self.program_identity } @@ -481,23 +706,19 @@ impl FullHardReportV1 { &self.executions } - pub(crate) fn cells(&self) -> &[JointConstraintCellV1] { + pub(crate) fn cells(&self) -> &[PointwiseJointConstraintCellV1] { &self.cells } - pub(crate) const fn observation(&self) -> &RevisionBoundObservationV1 { + pub(crate) const fn observation(&self) -> &Observation { &self.observation } pub(crate) fn provenance(&self, case_index: usize) -> Option<&[ScenarioId]> { - self.observation - .set() - .cases() - .get(case_index) - .map(|case| case.provenance()) + self.observation.provenance(case_index) } - pub(crate) fn classify(self) -> HardFeasibilityV1 { + pub(crate) fn classify(self) -> PointwiseHardFeasibilityV1 { let mut feasible = Vec::new(); for candidate in self.candidates.candidates() { if self @@ -510,9 +731,9 @@ impl FullHardReportV1 { } } if feasible.is_empty() { - HardFeasibilityV1::Infeasible(self) + PointwiseHardFeasibilityV1::Infeasible(self) } else { - HardFeasibilityV1::NonEmpty(NonEmptyFeasibleJointTuplesV1 { + PointwiseHardFeasibilityV1::NonEmpty(PointwiseNonEmptyFeasibleJointTuplesV1 { report: self, feasible: feasible.into_boxed_slice(), }) @@ -520,19 +741,34 @@ impl FullHardReportV1 { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum HardFeasibilityV1 { - Infeasible(FullHardReportV1), - NonEmpty(NonEmptyFeasibleJointTuplesV1), +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum PointwiseHardFeasibilityV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ + Infeasible(PointwiseFullHardReportV1), + NonEmpty(PointwiseNonEmptyFeasibleJointTuplesV1), } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct NonEmptyFeasibleJointTuplesV1 { - report: FullHardReportV1, +pub(crate) type HardFeasibilityV1 = + PointwiseHardFeasibilityV1; + +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseNonEmptyFeasibleJointTuplesV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ + report: PointwiseFullHardReportV1, feasible: Box<[CandidateOrdinalV1]>, } -impl NonEmptyFeasibleJointTuplesV1 { +impl PointwiseNonEmptyFeasibleJointTuplesV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ pub(crate) fn feasible(&self) -> &[CandidateOrdinalV1] { &self.feasible } @@ -541,7 +777,10 @@ impl NonEmptyFeasibleJointTuplesV1 { self.report.candidate_set() } - pub(crate) fn select(self, policy: DeclaredTotalOrderV1) -> SelectedJointTupleV1 { + pub(crate) fn select( + self, + policy: DeclaredTotalOrderV1, + ) -> PointwiseSelectedJointTupleV1 { let ordinal = policy .order .iter() @@ -555,7 +794,7 @@ impl NonEmptyFeasibleJointTuplesV1 { .iter() .find(|candidate| candidate.ordinal == ordinal) .unwrap_or_else(|| unreachable!("validated ordinal belongs to candidate set")); - SelectedJointTupleV1 { + PointwiseSelectedJointTupleV1 { report: self.report, policy, candidate, @@ -603,31 +842,41 @@ pub(crate) enum SelectionPolicyErrorV1 { NotATotalOrder, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct SelectedJointTupleV1 { - report: FullHardReportV1, +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseSelectedJointTupleV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ + report: PointwiseFullHardReportV1, policy: DeclaredTotalOrderV1, candidate: JointCandidateTupleV1, } -impl SelectedJointTupleV1 { +impl PointwiseSelectedJointTupleV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ pub(crate) const fn ordinal(&self) -> CandidateOrdinalV1 { self.candidate.ordinal } pub(crate) fn recheck( self, - ) -> Result { + ) -> Result< + PointwiseVerifiedSelectionV1, + PointwiseSelectedRecheckErrorV1, + > { let root_index = self .report .observation - .schema() - .binary_search(&self.report.program.root_surface) - .map_err(|_| SelectedRecheckErrorV1::InvariantDrift)?; - let cases = self.report.observation.set().cases().len(); + .root_index(self.report.program.root_surface) + .ok_or(PointwiseSelectedRecheckErrorV1::InvariantDrift)?; + let cases = self.report.observation.case_count(); let (execution_count, cell_count) = - checked_joint_cardinality(1, cases, self.report.program.constraints.len()) - .map_err(|_| SelectedRecheckErrorV1::ResourceExhausted)?; + checked_joint_cardinality_raw(1, cases, self.report.program.constraints.len()) + .map_err(|_| PointwiseSelectedRecheckErrorV1::ResourceExhausted)?; let matrices = self .report .program @@ -639,23 +888,30 @@ impl SelectedJointTupleV1 { cell_count, ) .map_err(|error| match error { - JointReportErrorV1::ResourceExhausted => SelectedRecheckErrorV1::ResourceExhausted, - JointReportErrorV1::MissingRootSurface(_) - | JointReportErrorV1::CandidatePaintMismatch { .. } => { - SelectedRecheckErrorV1::InvariantDrift + PointwiseJointReportErrorV1::ResourceExhausted => { + PointwiseSelectedRecheckErrorV1::ResourceExhausted + } + PointwiseJointReportErrorV1::Evaluator(error) => { + PointwiseSelectedRecheckErrorV1::Evaluator(error) + } + PointwiseJointReportErrorV1::MissingRootSurface(_) + | PointwiseJointReportErrorV1::CandidatePaintMismatch { .. } => { + PointwiseSelectedRecheckErrorV1::InvariantDrift } })?; if let Some(violation) = matrices .cells .iter() - .copied() .find(|cell| !cell.decision.is_pass()) + .cloned() { - return Err(SelectedRecheckErrorV1::Violation(violation)); + return Err(PointwiseSelectedRecheckErrorV1::Violation(Box::new( + violation, + ))); } - Ok(RevisionBoundVerifiedSelectionV1 { + Ok(PointwiseVerifiedSelectionV1 { selected: self, - recheck: FreshJointRecheckV1 { + recheck: PointwiseFreshJointRecheckV1 { executions: matrices.executions, cells: matrices.cells, }, @@ -663,31 +919,46 @@ impl SelectedJointTupleV1 { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum SelectedRecheckErrorV1 { +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum PointwiseSelectedRecheckErrorV1 +where + Evaluation: JointPointEvaluatorV1, +{ ResourceExhausted, InvariantDrift, - Violation(JointConstraintCellV1), + Evaluator(Evaluation::Error), + Violation(Box>), } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct FreshJointRecheckV1 { +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseFreshJointRecheckV1 +where + Evaluation: JointPointEvaluatorV1, +{ executions: Box<[JointExecutionRecordV1]>, - cells: Box<[JointConstraintCellV1]>, + cells: Box<[PointwiseJointConstraintCellV1]>, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct RevisionBoundVerifiedSelectionV1 { - selected: SelectedJointTupleV1, - recheck: FreshJointRecheckV1, +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct PointwiseVerifiedSelectionV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ + selected: PointwiseSelectedJointTupleV1, + recheck: PointwiseFreshJointRecheckV1, } -impl RevisionBoundVerifiedSelectionV1 { +impl PointwiseVerifiedSelectionV1 +where + Evaluation: JointPointEvaluatorV1, + Observation: JointObservationV1, +{ pub(crate) const fn ordinal(&self) -> CandidateOrdinalV1 { self.selected.candidate.ordinal } - pub(crate) const fn report(&self) -> &FullHardReportV1 { + pub(crate) const fn report(&self) -> &PointwiseFullHardReportV1 { &self.selected.report } @@ -699,7 +970,7 @@ impl RevisionBoundVerifiedSelectionV1 { &self.recheck.executions } - pub(crate) fn fresh_cells(&self) -> &[JointConstraintCellV1] { + pub(crate) fn fresh_cells(&self) -> &[PointwiseJointConstraintCellV1] { &self.recheck.cells } } diff --git a/crates/labcolors-core/src/joint_tests.rs b/crates/labcolors-core/src/joint_tests.rs index 0537d263..877a670b 100644 --- a/crates/labcolors-core/src/joint_tests.rs +++ b/crates/labcolors-core/src/joint_tests.rs @@ -1,17 +1,23 @@ use crate::Srgb8; use crate::appearance::{EncodedPointPaintV1, PaintId, SurfaceInputPortId}; use crate::composition::AdmittedOpacityV1; +use crate::constraints::{HardDecision, Wcag22Srgb8V1}; use crate::joint::{ CandidateOrdinalV1, CandidateSetErrorV1, DeclaredTotalOrderV1, HardFeasibilityV1, JointCandidateSetV1, JointCandidateTupleV1, JointConstraintDecisionV1, JointConstraintIdV1, - JointHardConstraintV1, JointPointProgramIdentityV1, JointPointProgramV1, JointProgramErrorV1, - JointReportErrorV1, JointVisibleTargetV1, SelectionPolicyErrorV1, checked_joint_cardinality, + JointHardConstraintV1, JointPointEvaluatorV1, JointPointProgramIdentityV1, JointPointProgramV1, + JointProgramErrorV1, JointReportErrorV1, JointVisibleTargetV1, PointwiseHardFeasibilityV1, + PointwiseJointHardConstraintV1, PointwiseJointPointProgramV1, PointwiseJointReportErrorV1, + PointwiseSelectedRecheckErrorV1, SelectionPolicyErrorV1, checked_joint_cardinality, }; use crate::observation::{ ObservationPayloadInput, ObservationState, ObservationStreamId, ObservationUpdateInput, ObservedScenarioSetInput, Revision, RevisionBoundObservationV1, ScenarioId, ScenarioInput, SurfaceInputBinding, }; +use crate::wcag22::Wcag22CriterionV1; +use std::cell::Cell; +use std::rc::Rc; const ROOT: SurfaceInputPortId = SurfaceInputPortId::new(7); const LOWER: PaintId = PaintId::new(11); @@ -96,7 +102,7 @@ fn linked_candidate_is_selected_only_after_upper_sees_lower_visible_surface() { assert_eq!( report.program_identity(), - JointPointProgramIdentityV1::TwoPaintDerivedSurfaceExactPointV1 + JointPointProgramIdentityV1::TwoPaintDerivedSurfacePointV1 ); assert_eq!(report.executions().len(), 2); assert!( @@ -330,6 +336,149 @@ fn fresh_recheck_executes_the_selected_joint_program_again_on_the_same_revision( assert_eq!(verified.policy(), &[CandidateOrdinalV1::new(0)]); } +#[test] +fn empty_hard_constraint_set_is_non_vacuously_feasible() { + let observed = observation(10, vec![(1, [13, 17, 19])]); + let domain = candidates(vec![candidate(0, ([20, 30, 40], 0.5), ([50, 60, 70], 1.0))]); + let report = program(vec![]).evaluate(domain, observed).unwrap(); + + assert_eq!(report.executions().len(), 1); + assert!(report.cells().is_empty()); + let HardFeasibilityV1::NonEmpty(feasible) = report.classify() else { + panic!("a tuple with no hard violations must be feasible"); + }; + assert_eq!(feasible.feasible(), &[CandidateOrdinalV1::new(0)]); + let policy = + DeclaredTotalOrderV1::new(feasible.candidate_set(), vec![CandidateOrdinalV1::new(0)]) + .unwrap(); + let verified = feasible.select(policy).recheck().unwrap(); + assert_eq!(verified.fresh_executions().len(), 1); + assert!(verified.fresh_cells().is_empty()); +} + +#[test] +fn generic_wcag_evaluator_can_constrain_the_derived_lower_occurrence() { + let observed = observation(11, vec![(1, [255; 3])]); + let domain = candidates(vec![ + candidate(1, ([255; 3], 1.0), ([0; 3], 1.0)), + candidate(2, ([0; 3], 1.0), ([0; 3], 1.0)), + ]); + let constraint = PointwiseJointHardConstraintV1::new( + JointConstraintIdV1::new(1), + JointVisibleTargetV1::Lower, + Wcag22CriterionV1::Sc1411UiComponentOrState, + ); + let program = PointwiseJointPointProgramV1::with_evaluator( + Wcag22Srgb8V1, + ROOT, + LOWER, + UPPER, + vec![constraint], + ) + .unwrap(); + let report = program.evaluate(domain, observed).unwrap(); + + assert_eq!(report.cells().len(), 2); + assert!(!report.cells()[0].decision().is_pass()); + assert!(report.cells()[1].decision().is_pass()); + let PointwiseHardFeasibilityV1::NonEmpty(feasible) = report.classify() else { + panic!("black lower occurrence must be WCAG-feasible over white"); + }; + assert_eq!(feasible.feasible(), &[CandidateOrdinalV1::new(2)]); + let policy = DeclaredTotalOrderV1::new( + feasible.candidate_set(), + vec![CandidateOrdinalV1::new(1), CandidateOrdinalV1::new(2)], + ) + .unwrap(); + let verified = feasible.select(policy).recheck().unwrap(); + assert_eq!(verified.ordinal(), CandidateOrdinalV1::new(2)); + assert_eq!(verified.fresh_cells().len(), 1); + assert!(verified.fresh_cells()[0].decision().is_pass()); +} + +#[derive(Clone, Debug)] +struct FailOnCallEvaluatorV1 { + calls: Rc>, + fail_on: u32, +} + +impl PartialEq for FailOnCallEvaluatorV1 { + fn eq(&self, other: &Self) -> bool { + Rc::ptr_eq(&self.calls, &other.calls) && self.fail_on == other.fail_on + } +} + +impl JointPointEvaluatorV1 for FailOnCallEvaluatorV1 { + type Invocation = (); + type PassEvidence = (); + type ViolationEvidence = (); + type Error = &'static str; + + fn assess( + &self, + _occurrence: &crate::appearance::ResolvedOccurrence, + _invocation: Self::Invocation, + ) -> Result, Self::Error> { + let call = self.calls.get(); + self.calls.set(call + 1); + if call == self.fail_on { + Err("evaluator-fault") + } else { + Ok(HardDecision::Pass(())) + } + } +} + +fn fallible_program( + evaluator: FailOnCallEvaluatorV1, +) -> PointwiseJointPointProgramV1 { + PointwiseJointPointProgramV1::with_evaluator( + evaluator, + ROOT, + LOWER, + UPPER, + vec![PointwiseJointHardConstraintV1::new( + JointConstraintIdV1::new(1), + JointVisibleTargetV1::Upper, + (), + )], + ) + .unwrap() +} + +#[test] +fn evaluator_error_invalidates_the_full_report_and_fresh_recheck() { + let domain = || candidates(vec![candidate(0, ([0; 3], 1.0), ([255; 3], 1.0))]); + let observed = || observation(12, vec![(1, [0; 3])]); + + let immediate = fallible_program(FailOnCallEvaluatorV1 { + calls: Rc::new(Cell::new(0)), + fail_on: 0, + }); + assert!(matches!( + immediate.evaluate(domain(), observed()), + Err(PointwiseJointReportErrorV1::Evaluator("evaluator-fault")) + )); + + let delayed = fallible_program(FailOnCallEvaluatorV1 { + calls: Rc::new(Cell::new(0)), + fail_on: 1, + }); + let report = delayed.evaluate(domain(), observed()).unwrap(); + let PointwiseHardFeasibilityV1::NonEmpty(feasible) = report.classify() else { + panic!("first evaluation must pass"); + }; + let policy = + DeclaredTotalOrderV1::new(feasible.candidate_set(), vec![CandidateOrdinalV1::new(0)]) + .unwrap(); + assert!(matches!( + feasible.select(policy).recheck(), + Err(PointwiseSelectedRecheckErrorV1::Evaluator( + "evaluator-fault" + )) + )); +} + #[test] fn invalid_domains_and_policies_fail_before_compositing() { assert_eq!( @@ -359,11 +508,6 @@ fn invalid_domains_and_policies_fail_before_compositing() { JointPointProgramV1::new(ROOT, LOWER, LOWER, vec![exact_upper(1, [0; 3])]), Err(JointProgramErrorV1::SamePaintIdentity(LOWER)) ); - assert_eq!( - JointPointProgramV1::new(ROOT, LOWER, UPPER, vec![]), - Err(JointProgramErrorV1::EmptyHardConstraintSet) - ); - let observed = observation(9, vec![(1, [0; 3])]); let wrong = JointCandidateSetV1::new(vec![JointCandidateTupleV1::new( CandidateOrdinalV1::new(0), diff --git a/crates/labcolors-core/src/lib.rs b/crates/labcolors-core/src/lib.rs index 7db7ba23..aa7792b9 100644 --- a/crates/labcolors-core/src/lib.rs +++ b/crates/labcolors-core/src/lib.rs @@ -308,8 +308,8 @@ pub struct NoHybridLpcSurfaceMetric; #[cfg(doctest)] pub struct NoPrematureScalarLpcApi; -/// Полярность и pair-механика закрыты внутри resolver-а, а не образуют -/// публичный extension point. +/// Frozen Pair frontend не публикует собственную физику или solver extension +/// point; Pair lowering остаётся private до общего Program cutover. /// /// ```compile_fail /// use labcolors_core::pair::pair_side; diff --git a/crates/labcolors-core/src/lpc.rs b/crates/labcolors-core/src/lpc.rs index 32034d5c..1ad6667f 100644 --- a/crates/labcolors-core/src/lpc.rs +++ b/crates/labcolors-core/src/lpc.rs @@ -25,6 +25,7 @@ pub(crate) fn cam16_jch_from_xyz(xyz: [f64; 3], vc: &ViewingConditions) -> (f64, /// Chroma exponent in the Hellwig 2022 H-K lightness term /// `J_HK = J + f(h) * C^0.587` (source: see [`hk_coeff`]). +#[cfg(test)] const HK_CHROMA_EXPONENT: f64 = 0.587; /// Hue-dependent Helmholtz-Kohlrausch coefficient `f(h)`, `h_cam_deg` in degrees. @@ -38,6 +39,7 @@ const HK_CHROMA_EXPONENT: f64 = 0.587; /// `pub(crate)` so the external-reference-vector suite (`reference_vectors_deep`) /// can pin the RHS coefficients directly to the Hellwig 2022 publication; not /// part of the public API. +#[cfg(test)] pub(crate) fn hk_coeff(h_cam_deg: f64) -> f64 { let h_cam = h_cam_deg.to_radians(); -0.160 * h_cam.cos() + 0.132 * (2.0 * h_cam).cos() - 0.405 * h_cam.sin() @@ -49,6 +51,7 @@ pub(crate) fn hk_coeff(h_cam_deg: f64) -> f64 { /// /// LPC supplies an H-K-adjusted `J` target; the physical inversion itself is /// shared appearance geometry in [`cam16::gray_y`]. +#[cfg(test)] pub(crate) fn y_hk(j_hk: f64, vc: &ViewingConditions) -> f64 { cam16::gray_y(j_hk, vc) } @@ -236,6 +239,7 @@ pub(crate) fn contrast_core(y_fg: f64, y_bg: f64) -> f64 { /// Hellwig 2022 H-K-corrected lightness for an XYZ stimulus: /// `J_HK = J + f(h) * C^0.587`, with the chroma correlate `C = M / F_L^0.25`. +#[cfg(test)] pub(crate) fn j_hk_from_xyz(xyz: [f64; 3], vc: &ViewingConditions) -> f64 { let (j, m, h) = cam16_jch_from_xyz(xyz, vc); j_hk_from_cam16(j, m, h, vc) @@ -246,6 +250,7 @@ pub(crate) fn j_hk_from_xyz(xyz: [f64; 3], vc: &ViewingConditions) -> f64 { /// that already ran [`cam16::forward`] (e.g. [`crate::solve`]'s `finish`, which /// also needs the `LcsColor`) derive `J_HK` from the same forward pass instead /// of running a second identical one on the same stimulus. +#[cfg(test)] pub(crate) fn j_hk_from_cam16(j: f64, m: f64, h: f64, vc: &ViewingConditions) -> f64 { // `vc.fl_pow_025` == инлайновый `vc.fl.powf(0.25)` (пер-VC константа, // вынесенная в `ViewingConditions::build`), так что `chroma` байт-идентична. @@ -337,9 +342,9 @@ pub(crate) fn apparent_contrast_candidate_hex_with_vc_for_test( /// /// ADR-0003: Ys candidate score движка /// считает именно в этом домене — `solve::finish`/`meets_floor`, интервал фона, -/// recheck-примитивы (`semantic::measure_contrast`, `recheck_against*`) и белая -/// сторона кроссовера пары (`pair::pair_side`). Сам движок зовёт -/// [`contrast_core`] + [`crate::wcag::relative_luminance`] напрямую на уже +/// recheck-примитивы (`semantic::measure_contrast`, `recheck_against*`) и +/// pointwise hard evaluators. Сам движок зовёт [`contrast_core`] + +/// [`crate::wcag::relative_luminance`] напрямую на уже /// готовых скалярах; эта функция — только test-reference той же формулы (те же /// функции, ноль новых констант). `Y_hk` остаётся отдельной appearance- /// координатой, но не публичным scalar-LPC API. diff --git a/crates/labcolors-core/src/pair.rs b/crates/labcolors-core/src/pair.rs index d91c5027..60ba1c89 100644 --- a/crates/labcolors-core/src/pair.rs +++ b/crates/labcolors-core/src/pair.rs @@ -1,822 +1,237 @@ -//! Пара «заливка × лейбл» — выводимая поверхность с перцептивной полярностью. +//! P1: frozen Pair frontend поверх общей point graph algebra. //! -//! # Класс, который закрывает модуль -//! -//! На статичном фоне полярность текста обязана следовать достижимости -//! WCAG-пола ([`crate::semantic`], `choose_polarity`) — иначе система эмитит -//! нечитаемое по закону. Но у ВЫВОДИМОЙ поверхности (заливка бейджа, кнопки) -//! есть степень свободы, которой нет у фона страницы: заливку можно двинуть. -//! Зона конфликта — фоны с Y ∈ (0.183, ~0.30): перцептивно они ТЁМНЫЕ (белый -//! текст читается лучше — полярностная асимметрия чтения, класс исследований, -//! на которых построен APCA), но белый физически не достигает пола 4.5. -//! Фирменные заливки (синий #007AFF Y≈0.21, красный Y≈0.25) живут ровно там: -//! буква WCAG требовала чернил, глаз и Figma — белого. -//! -//! Закон пары: сторона лейбла выбирается ПЕРЦЕПТИВНЫМ кроссовером по якорю, -//! а непрерывный кандидат заливки минимально двигается по светлоте вдоль -//! фиксированных Oklab `a,b`, пока выбранная сторона не начнёт выигрывать штатный -//! `choose_polarity`. Дальше лейбл решается ОБЫЧНЫМ nested resolve на -//! выведенной заливке — пара не изобретает второй текстовый закон, она -//! готовит поверхность, на которой существующий закон даёт перцептивно -//! правильную сторону с легальным полом. Гамут и sRGB8-квантование могут изменить -//! координаты; рецепт не выдаёт это за гарантию сохранения идентичности. -//! -//! # Кроссовер (level-3) -//! -//! Сторона пары — свойство ИДЕНТИЧНОСТИ СЕМЬИ: решается ОДИН РАЗ по -//! каноническому светлому якорю ([`pair_side`], смешанное доменное сравнение -//! достижимого контраста двух архетипов лейбла) и не флипается между -//! темами/IC — иначе «Brand» носил бы белый лейбл в light и чернильный в -//! dark (тёмные якоря labui осветлены и перелезают порог: info dark -//! #5696FF Y=0.31). Пер-режимная заливка двигается ПОД выбранную сторону: -//! светлая сторона — утемнение до строгой победы белого; чернильная — -//! осветление до строгой победы чёрного (IC-якоря warning/success -//! проваливаются под границу: #C93400 Y=0.149 — без осветления штатная -//! полярность отдала бы белый и сторона флипнулась бы в IC). -//! -//! Белая сторона требует строгой победы белого в `choose_polarity`: -//! `(Y + 0.05)² < 1.05 · 0.05`, т.е. Y < 0.17913 (белый ≥ 4.58:1) — граница -//! выведена из самой формулы WCAG, не подобрана. Сдвиг для фирменных якорей -//! мал: #007AFF (0.211 → 0.179) — едва заметное утемнение при том же оттенке. - -use crate::spaces::oklab::{neutral_srgb_linear, oklab_to_srgb_linear, srgb_linear_to_oklab}; -use crate::spaces::srgb::srgb_gamma_inv; -use crate::spaces::vc::ViewingConditions; - -/// Y-порог кроссовера стороны пары «заливка × лейбл» — решается ОДИН РАЗ по -/// каноническому светлому якорю семьи. -/// -/// Терминал **(a) DERIVED** внутри замороженной численной эвристики. -/// -/// # Что этот порог решает -/// Ахроматический терминал решения стороны. С главы #64 (level-3) [`pair_side`] -/// не сравнивает люминанс с порогом напрямую — он сравнивает |Lc| обоих -/// архетипов лейбла той же кривой; на серой оси H-K-член ≈ 0 и правило -/// редуцируется ровно к этому порогу (лок -/// `achromatic_reduction_matches_derived_crossover`). Порог обязан стоять там, -/// где обе ветви frozen Ys candidate-кривой равны по модулю. -/// -/// # Почему именно это число (вывод, не выбор) -/// Используется внутреннее `contrast_core` с замороженным набором SAPC-8 -/// `0.0.98G-4g`. -/// Кроссовер = фон, на котором |Lc| ЧЁРНОГО лейбла догоняет |Lc| БЕЛОГО. Он -/// найден бисекцией (корень единственный на [0.2, 0.6], проверено сменой знака): -/// **Y = 0.341955**. Это математическое свойство текущих экспонент, но не -/// LPC/readability optimum; дрейф любой из них ломает лок -/// `pair_crossover_equals_measured_core_polarity_flip` (пиннинг деривации). -/// -/// # Почему не соседние кандидаты -/// - НЕ `0.179` (`WHITE_WINS_Y`) — это отдельная граница двойной законности WCAG. -/// - НЕ `0.325` (test-only H-K appearance-candidate, байт 155 серой оси) — тот -/// использует другой входной домен, чужой для Ys-решения `pair_side`. -/// -/// # Согласованность и почему это ещё и ЛУЧШЕ прежнего 0.30 -/// 0.341955 лежит ВНУТРИ интервала 10 Figma-якорей labui (0.246, 0.423) — вывод -/// не спорит с палитрой, а совпадает с ней (экспозиция 21.69%, -/// `exposure_pair_crossover`). Прежнее 0.30 было дизайн-тюнингом НИЖЕ модели: при -/// Y ∈ [0.30, 0.342) оно выбирало ink-ветвь там, где frozen curve даёт больший -/// модуль white-ветви. Это согласование одной эвристики, не claim читаемости. -// С главы #64 (level-3) `pair_side` не потребляет этот порог в РАНТАЙМЕ — он -// выводит кроссовер из достижимого |Lc| обоих архетипов лейбла той же кривой. -// Порог остаётся АХРОМАТИЧЕСКИМ ТЕРМИНАЛОМ правила: на серой оси H-K-член ≈ 0 и -// level-3 редуцируется ровно к нему (лок `achromatic_reduction_matches_derived_crossover`), -// а его деривация пиннится `pair_crossover_equals_measured_core_polarity_flip`. -// Константа СОХРАНЕНА живой (не удалена, не test-only): её отслеживает -// docs/empirical-inventory.md (строка 52, (a) DERIVED) и валидируют локи -// `exposure_locks`; `#[allow(dead_code)]` — честная декларация «намеренно не -// рантайм-вход при level-3», не заглушка ошибки. -// SSOT-TRACKED — Y-порог кроссовера, терминал (a) DERIVED (перелом contrast_core, бисекция), см. docs/empirical-inventory.md. -#[allow(dead_code)] -pub(crate) const PAIR_CROSSOVER_Y: f64 = 0.341955; - -/// Строгая граница победы белой стороны в `choose_polarity`: -/// `(Y + 0.05)² < 1.05 · 0.05` ⇒ Y < 0.17913. Выведена из формулы WCAG (не -/// настройка); округлена ВНИЗ (консервативно): ниже неё белый и по ратио, и -/// по tie-break выигрывает штатную полярность. -pub(crate) const WHITE_WINS_Y: f64 = 0.179; - -/// Строгая граница победы чернильной стороны — та же формула с другой -/// стороны: `(Y + 0.05)² > 1.05 · 0.05` ⇒ Y > 0.17913; округлена ВВЕРХ. -pub(crate) const BLACK_WINS_Y: f64 = 0.1795; - -/// Итераций бисекции минимального сдвига: 48 делений пополам ≫ шага 8-битной -/// решётки, на которой квантуется каждый кандидат — сходимость до кванта. -const BISECTION_STEPS: usize = 48; - -// Коэффициенты относительной яркости ITU-R BT.709 / WCAG 2.x (Rec.709 luma). -// Стандарт, не тюнинг: исключены из POLICY-инвентаря by-construction -// (`NUMERIC_METHOD_ALLOWLIST`, INV-3). Извлечены из inline-литералов, чтобы -// pair.rs прошёл GATE-5 без незадекларированных голых чисел (значения целы). -const WCAG_LUMA_R: f64 = 0.2126; -const WCAG_LUMA_G: f64 = 0.7152; -const WCAG_LUMA_B: f64 = 0.0722; - -/// WCAG-люминанс кодированного (byte/255) sRGB. -fn wcag_y_encoded(rgb: [f64; 3]) -> f64 { - let lin = [ - srgb_gamma_inv(rgb[0]), - srgb_gamma_inv(rgb[1]), - srgb_gamma_inv(rgb[2]), - ]; - WCAG_LUMA_R * lin[0] + WCAG_LUMA_G * lin[1] + WCAG_LUMA_B * lin[2] -} - -/// Сторона лейбла пары по перцептивному кроссоверу якоря. +//! Модуль не выбирает «сторону пары», не двигает цвет по Oklab и не содержит +//! собственного compositor-а или evaluator switch. Он только лоуверит +//! замороженный authoring tag в одну физическую цепочку и передаёт конечный +//! candidate domain общему joint engine. + +use crate::Srgb8; +use crate::appearance::{ + EncodedPointPaintV1, PaintId, PointOpacityOverSurfaceV1, ResolvedOccurrence, SurfaceInputPortId, +}; +use crate::composition::AdmittedOpacityV1; +use crate::constraints::{ExactSrgb8IdentityV1, Wcag22Srgb8V1}; +use crate::joint::{ + CandidateOrdinalV1, CandidateSetErrorV1, DeclaredTotalOrderV1, JointCandidateSetV1, + JointCandidateTupleV1, JointConstraintIdV1, JointExecutionRecordV1, JointProgramErrorV1, + JointVisibleTargetV1, PointwiseFullHardReportV1, PointwiseHardFeasibilityV1, + PointwiseJointHardConstraintV1, PointwiseJointPointProgramV1, PointwiseJointReportErrorV1, + PointwiseSelectedRecheckErrorV1, PointwiseVerifiedSelectionV1, SelectionPolicyErrorV1, + StaticJointObservationV1, +}; +use crate::wcag22::Wcag22CriterionV1; + +const ROOT_SURFACE: SurfaceInputPortId = SurfaceInputPortId::new(1); +const FILL_PAINT: PaintId = PaintId::new(1); +const LABEL_PAINT: PaintId = PaintId::new(2); +const LABEL_CONSTRAINT: JointConstraintIdV1 = JointConstraintIdV1::new(1); + +/// Один канонический fill Paint, действительно применённый к page Surface. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum PairSide { - /// Якорь перцептивно тёмный — лейбл светлый, заливка двигается до - /// строгой победы белого в штатной полярности. - Light, - /// Якорь перцептивно светлый — лейбл чернильный, заливка не двигается - /// (тёмная сторона уже выигрывает штатную полярность). - Ink, +pub(crate) struct LoweredPairFillV1 { + paint: EncodedPointPaintV1, + occurrence: ResolvedOccurrence, } -/// Выбрать сторону пары для кодированного якоря — level-3: смешанное доменное -/// сравнение достижимого контраста двух архетипов лейбла. -/// -/// `Ink ⇔ |Lc(чёрный, Y_eff)| > |Lc(белый, Ys)|`, -/// -/// где `Lc` — контраст-кривая SAPC-8 ([`crate::lpc`], `contrast_core`), `Ys` — -/// WCAG-люминанс display-байтов якоря, `Y_eff` — воспринимаемая яркость якоря -/// (Гельмгольц–Кольрауш: `solve::bg_luma`, серый эквивалент J_HK по -/// Hellwig 2022 под каноническим sRGB-окружением). -/// -/// Декомпозиция доменов — следствие ADR-0003, не его обход: -/// -/// - читаемость СВЕТЛОГО лейбла — люминансная величина (Mullen 1985: детальную -/// разборчивость несёт ахроматический канал): белая сторона меряется в Ys, -/// H-K к ней не допущен — класс «H-K топит белый» (15:0, отчёт V3) исключён -/// конструкцией; -/// - «поверхность выглядит светлой → ей место нести чернила» — суждение о -/// ЯРКОСТИ поверхности, законный дом H-K по тому же ADR: чернильная сторона -/// меряется от Y_eff. -/// -/// На ахроматической оси Y_eff ≈ Ys (H-K-член ≈ 0), и правило редуцируется к -/// РАВНО-|Lc| кроссоверу самой кривой Y* ≈ 0.342 — порог не задаётся, а -/// выводится (лок `achromatic_reduction_matches_derived_crossover`). Насыщенные -/// фоны флипают в чернила РАНЬШЕ по Ys — hue-каверна полнотекстов таска #62; -/// величина сдвига следует hue-зависимости H-K (Hellwig f(h)·C^0.587), новых -/// констант нет: обе стороны — существующие функции движка. -/// -/// Тай (равенство скоров) отдан свету: полярностная асимметрия чтения — белый -/// предпочтителен, пока чернила строго не выиграли. -pub(crate) fn pair_side(anchor_encoded: [f64; 3]) -> PairSide { - let ys = wcag_y_encoded(anchor_encoded); - let lin = [ - srgb_gamma_inv(anchor_encoded[0]), - srgb_gamma_inv(anchor_encoded[1]), - srgb_gamma_inv(anchor_encoded[2]), - ]; - let y_eff = crate::solve::bg_luma(lin, &ViewingConditions::srgb()); - let ink_score = crate::lpc::contrast_core(0.0, y_eff).abs(); - let white_score = crate::lpc::contrast_core(1.0, ys).abs(); - if ink_score > white_score { - PairSide::Ink - } else { - PairSide::Light +impl LoweredPairFillV1 { + pub(crate) const fn paint(self) -> EncodedPointPaintV1 { + self.paint } -} -/// Заливка пары: пер-режимный якорь, минимально сдвинутый по L Oklab до -/// строгой победы СТОРОНЫ СЕМЬИ. Непрерывный хроматический кандидат держит -/// исходные Oklab `a,b`; ахроматический идёт по точной neutral ray, чтобы шум -/// матрицы не изобрёл hue. Затем каналы клампятся и квантуются, поэтому -/// финальные байты не несут отдельной гарантии сохранения оттенка. -/// -/// Сторона приходит от канонического светлого якоря семьи ([`pair_side`]) и -/// одна на все режимы; движение пер-режимное: светлая сторона — утемнение до -/// `Y < WHITE_WINS_Y`, чернильная — осветление до `Y > BLACK_WINS_Y` -/// (IC-якоря проваливаются под границу). Якорь, уже дающий победу, не -/// двигается вовсе. -pub(crate) fn pair_fill(anchor_encoded: [f64; 3], side: PairSide) -> [f64; 3] { - let y = wcag_y_encoded(anchor_encoded); - let (needs_move, target_dark) = match side { - PairSide::Light => (y >= WHITE_WINS_Y, true), - PairSide::Ink => (y <= BLACK_WINS_Y, false), - }; - if !needs_move { - return anchor_encoded; + pub(crate) const fn occurrence(&self) -> &ResolvedOccurrence { + &self.occurrence } - let lin = [ - srgb_gamma_inv(anchor_encoded[0]), - srgb_gamma_inv(anchor_encoded[1]), - srgb_gamma_inv(anchor_encoded[2]), - ]; - let lab = srgb_linear_to_oklab(lin); - let source = crate::Srgb8::new( - anchor_encoded.map(|channel| (channel.clamp(0.0, 1.0) * 255.0).round() as u8), - ); - let linear_at = |l: f64| { - if source.is_achromatic() { - neutral_srgb_linear(l) - } else { - oklab_to_srgb_linear([l, lab[1], lab[2]]) - } - }; - let wins = |l: f64| { - let cand = encode_clamped(linear_at(l)); - if target_dark { - wcag_y_encoded(cand) < WHITE_WINS_Y - } else { - wcag_y_encoded(cand) > BLACK_WINS_Y - } - }; - // Бисекция минимального сдвига: инвариант — lo выигрывает, hi нет; - // сходимся к ближайшей к якорю светлоте с победой стороны. - let (mut lo, mut hi) = if target_dark { - (0.0_f64, lab[0]) - } else { - (1.0_f64, lab[0]) - }; - for _ in 0..BISECTION_STEPS { - let mid = 0.5 * (lo + hi); - if wins(mid) { - lo = mid; - } else { - hi = mid; - } + + pub(crate) fn visible(self) -> Srgb8 { + Srgb8::new(self.occurrence.visible()) } - encode_clamped(linear_at(lo)) } -/// Линейный sRGB → кодированный, КВАНТОВАННЫЙ в 8-битную решётку с клампом -/// в куб. Квантование обязательно: `choose_polarity` меряет display-байты, -/// и бисекция обязана сходиться на той же решётке — неквантованный кандидат -/// у границы после округления в hex выталкивался на грань tie-break -/// (красный #FF3B30 давал #E81A17 с Y ровно на границе → чернила). -fn encode_clamped(lin: [f64; 3]) -> [f64; 3] { - let g = |v: f64| (crate::spaces::srgb::srgb_gamma(v).clamp(0.0, 1.0) * 255.0).round() / 255.0; - [g(lin[0]), g(lin[1]), g(lin[2])] +/// Один frontend-proposed label Paint. Ordinal задаёт только identity; порядок +/// предпочтения приходит отдельным declared total order. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct PairLabelCandidateV1 { + ordinal: CandidateOrdinalV1, + source: Srgb8, } -#[cfg(test)] -mod tests { - use super::*; - use crate::spaces::srgb::{hex_from_srgb_encoded, srgb_encoded_from_hex}; - - fn enc(hex: &str) -> [f64; 3] { - srgb_encoded_from_hex(hex).expect("тестовые hex-литералы валидны") - } - - /// Калибровка кроссовера консенсус-сетом якорей labui: перцептивно тёмные - /// семьи получают белую сторону, светлые — чернильную. Красный и зелёный — - /// зажимы интервала (0.246 < порог < 0.423). - #[test] - fn crossover_matches_palette_consensus() { - for hex in ["#007AFF", "#FF3B30", "#3E87FF", "#101012", "#5856D6"] { - assert_eq!(pair_side(enc(hex)), PairSide::Light, "{hex}: белая сторона"); - } - for hex in ["#FFA100", "#34C759", "#FFD000", "#FFFFFF", "#5AC8FA"] { - assert_eq!( - pair_side(enc(hex)), - PairSide::Ink, - "{hex}: чернильная сторона" - ); - } - } - - /// (а) Тёмные/IC-якоря Figma носят чернильный лейбл СТЭНДАЛОН: их Ys - /// (0.31–0.32) чуть выше, но воспринимаемая яркость (0.43–0.47, H-K) - /// далеко за кроссовером — перцептивно это светлая пастель (полнотексты - /// таска #62). Семейные стороны это не трогает (канон решает светлый якорь). - #[test] - fn figma_dark_anchors_take_ink_side() { - for hex in ["#FF6161", "#5696FF", "#FF6482", "#409CFF"] { - assert_eq!( - pair_side(enc(hex)), - PairSide::Ink, - "{hex}: чернильная сторона стэндалон" - ); - } - } - - /// Минимальность сдвига: заливка тёмной стороны кроссовера двигается до - /// строгой победы белого и ни шагом дальше. - #[test] - fn light_side_nudges_minimally() { - for hex in ["#007AFF", "#FF3B30", "#3E87FF"] { - let anchor = enc(hex); - let fill = pair_fill(anchor, PairSide::Light); - let y = wcag_y_encoded(fill); - assert!( - y < WHITE_WINS_Y, - "{hex}: белый выигрывает строго (Y={y:.4})" - ); - assert!( - y > WHITE_WINS_Y - 0.004, - "{hex}: сдвиг минимален (Y={y:.4}, граница {WHITE_WINS_Y})" - ); - } - } - - /// Якоря, уже дающие победу своей стороны, не двигаются вовсе. - #[test] - fn winning_anchors_stay_put() { - for hex in ["#FFA100", "#34C759", "#FFFFFF"] { - let anchor = enc(hex); - assert_eq!( - hex_from_srgb_encoded(pair_fill(anchor, PairSide::Ink)), - hex_from_srgb_encoded(anchor), - "{hex}: чернильная сторона, заливка не тронута" - ); - } - let dark = enc("#101012"); - assert_eq!( - hex_from_srgb_encoded(pair_fill(dark, PairSide::Light)), - hex_from_srgb_encoded(dark), - "тёмный якорь светлой стороны не тронут" - ); - } - - #[test] - fn every_exact_gray_pair_fill_stays_on_the_encoded_gray_axis() { - for byte in 0_u8..=255 { - let channel = f64::from(byte) / 255.0; - let anchor = [channel; 3]; - let fill = pair_fill(anchor, pair_side(anchor)); - let [red, green, blue] = crate::srgb8::hex_bytes(&hex_from_srgb_encoded(fill)).unwrap(); - assert_eq!(red, green, "gray {byte}: red/green direction invented"); - assert_eq!(green, blue, "gray {byte}: green/blue direction invented"); - } - } - - #[test] - fn nearest_chromatic_pair_fill_keeps_a_chromatic_direction() { - let anchor = enc("#808081"); - let fill = pair_fill(anchor, pair_side(anchor)); - let [red, green, blue] = crate::srgb8::hex_bytes(&hex_from_srgb_encoded(fill)).unwrap(); - assert!( - red != green || green != blue, - "one-byte chromatic source was collapsed onto the gray axis" - ); - } - - /// Сторона — идентичность семьи: канонический светлый якорь решает один - /// раз, тёмные/IC-варианты семьи НЕ флипают её (info dark #5696FF Y=0.31 - /// перелезает кроссовер — контрпример оси A). - #[test] - fn side_is_family_canonical_not_per_vc() { - // Канон info (light) — светлая сторона... - assert_eq!(pair_side(enc("#3E87FF")), PairSide::Light); - // ...а его тёмный якорь сам по себе ушёл бы в чернила: фиксируем, - // что при семейной стороне заливка двигается, лейбл остаётся белым. - let fill = pair_fill(enc("#5696FF"), PairSide::Light); - assert!( - wcag_y_encoded(fill) < WHITE_WINS_Y, - "тёмный якорь info утемнён под светлую сторону семьи" - ); - } - - /// Чернильная сторона осветляет провалившиеся под границу IC-якоря - /// (warning light-ic #C93400 Y=0.149): без осветления штатная полярность - /// отдала бы белый и сторона флипнулась бы в IC. - #[test] - fn ink_side_lightens_sunken_ic_anchors() { - let fill = pair_fill(enc("#C93400"), PairSide::Ink); - let y = wcag_y_encoded(fill); - assert!( - y > BLACK_WINS_Y, - "IC-якорь осветлён до победы чернил (Y={y:.4})" - ); - assert!(y < BLACK_WINS_Y + 0.006, "сдвиг минимален (Y={y:.4})"); +impl PairLabelCandidateV1 { + pub(crate) const fn new(ordinal: CandidateOrdinalV1, source: Srgb8) -> Self { + Self { ordinal, source } } - /// Сквозной закон: на выведенной заливке ШТАТНАЯ полярность отдаёт - /// светлый лейбл (мост к nested resolve — пара не изобретает второй - /// текстовый закон). - #[test] - fn nudged_fill_wins_light_polarity_in_standard_law() { - use crate::BgInput; - use crate::semantic::{Resolved, Role, RoleTable, resolve}; - use crate::spaces::vc::ViewingConditions; - for hex in ["#007AFF", "#FF3B30"] { - let fill = pair_fill(enc(hex), PairSide::Light); - let fill_hex = hex_from_srgb_encoded(fill); - let bg = BgInput::solid(&fill_hex).unwrap(); - let table = RoleTable::default(); - let label = match resolve(&bg, Role::LabelPrimary, &table, &ViewingConditions::srgb()) { - Ok(Resolved::Color { solved, .. }) => solved, - other => panic!("{hex}: лейбл обязан решиться цветом, получено {other:?}"), - }; - // Светлая полярность: лейбл светлее заливки. - let label_y = wcag_y_encoded(enc(label.hex())); - assert!( - label_y > wcag_y_encoded(fill), - "{hex}: лейбл светлый на выведенной заливке ({} на {fill_hex})", - label.hex() - ); - } + pub(crate) const fn source(self) -> Srgb8 { + self.source } } -// ───────────────────────────────────────────────────────────────────────────── -// Научные локи главы #64 (level-3, `level3_locks`): валидация выведенного -// кроссовера и H-K-сдвига стороны (Hellwig f(h)·C^0.587). Ниже — локи -// терминала (a) DERIVED `PAIR_CROSSOVER_Y` (`exposure_locks`): деривация -// пиннится замером, консенсус-сет держит чистый зазор, экспозиция зоны -// флипа замерена. -// ───────────────────────────────────────────────────────────────────────────── -#[cfg(test)] -mod level3_locks { - use super::{PairSide, encode_clamped, pair_side, wcag_y_encoded}; - use crate::exposure_support::LABUI_ANCHORS; - use crate::spaces::oklab::oklab_to_srgb_linear; - use crate::spaces::srgb::srgb_encoded_from_hex; - - /// Отставленный порог level-2 — нужен тестам как БАЗА СРАВНЕНИЯ (карта - /// флипов корпуса против прежнего поведения), не как правило. - const LEVEL2_CROSSOVER_Y_RETIRED: f64 = 0.30; +/// Hard requirement PairLabel. Отсутствие пола означает пустой hard-set, а не +/// тождественный `Exact(candidate, candidate)`. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum PairLabelRequirementV1 { + None, + Wcag22(Wcag22CriterionV1), +} - fn enc(hex: &str) -> [f64; 3] { - srgb_encoded_from_hex(hex).expect("тестовые hex-литералы валидны") - } +#[derive(Debug, Clone, PartialEq)] +enum PairSelectionEvidenceV1 { + Unconstrained(PointwiseVerifiedSelectionV1), + Wcag22(PointwiseVerifiedSelectionV1), +} - /// Равно-|Lc| кроссовер контраст-кривой для архетипов белого (1.0) и - /// чёрного (0.0) — бисекция самой кривой, не константа. - fn derived_equal_lc_crossover() -> f64 { - let (mut lo, mut hi) = (0.05_f64, 0.95_f64); - for _ in 0..80 { - let mid = 0.5 * (lo + hi); - let white = crate::lpc::contrast_core(1.0, mid).abs(); - let black = crate::lpc::contrast_core(0.0, mid).abs(); - if white > black { - lo = mid; - } else { - hi = mid; - } - } - 0.5 * (lo + hi) - } +/// Полное fresh evidence одной выбранной Pair-кандидатуры. +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct VerifiedPairV1 { + evidence: PairSelectionEvidenceV1, +} - /// Максимальная хрома Oklch внутри sRGB-куба для (L, h) — бисекция по C. - fn max_chroma(l: f64, h_rad: f64) -> f64 { - let inside = |c: f64| { - let lin = oklab_to_srgb_linear([l, c * h_rad.cos(), c * h_rad.sin()]); - lin.iter().all(|&v| (-1e-9..=1.0 + 1e-9).contains(&v)) +impl VerifiedPairV1 { + fn execution(&self) -> &JointExecutionRecordV1 { + let executions = match &self.evidence { + PairSelectionEvidenceV1::Unconstrained(evidence) => evidence.fresh_executions(), + PairSelectionEvidenceV1::Wcag22(evidence) => evidence.fresh_executions(), }; - let (mut lo, mut hi) = (0.0_f64, 0.5_f64); - for _ in 0..48 { - let mid = 0.5 * (lo + hi); - if inside(mid) { - lo = mid; - } else { - hi = mid; - } - } - lo - } - - /// Насыщенная ячейка: (L, h, доля максимальной хромы) → display-байты. - fn swatch(l: f64, h_rad: f64, rel_c: f64) -> [f64; 3] { - let c = rel_c * max_chroma(l, h_rad); - encode_clamped(oklab_to_srgb_linear([l, c * h_rad.cos(), c * h_rad.sin()])) + executions.first().unwrap_or_else(|| { + unreachable!("one selected Pair tuple over one case has one execution") + }) } - /// (в) Ахроматическая редукция: на серой оси H-K-член ≈ 0, и флип - /// pair_side обязан совпасть с выведенным равно-|Lc| кроссовером Y* самой - /// кривой (Y* = 0.3420) с точностью остаточной колоримости CAM16 на - /// нейтралях (неполная хроматическая адаптация; задекларированный резидуй - /// `lpc`). Резидуй строго ОДНОнаправлен: C ≥ 0 ⇒ Y_eff ≥ Ys ⇒ флип может - /// лечь только НИЖЕ Y* — измерено 0.3340 (сдвиг 0.008 < 0.01). Обе точки - /// заметно выше отставленного level-2 порога 0.30 — сам подъём кроссовера - /// от резидуя не зависит. - #[test] - fn achromatic_reduction_matches_derived_crossover() { - let y_star = derived_equal_lc_crossover(); - eprintln!("выведенный равно-|Lc| кроссовер Y* = {y_star:.6}"); - let side_at = |g: f64| pair_side([g, g, g]); - assert_eq!(side_at(0.0), PairSide::Light, "чёрный фон — светлый лейбл"); - assert_eq!(side_at(1.0), PairSide::Ink, "белый фон — чернила"); - let (mut lo, mut hi) = (0.0_f64, 1.0_f64); - for _ in 0..48 { - let mid = 0.5 * (lo + hi); - if side_at(mid) == PairSide::Light { - lo = mid; - } else { - hi = mid; - } + pub(crate) fn ordinal(&self) -> CandidateOrdinalV1 { + match &self.evidence { + PairSelectionEvidenceV1::Unconstrained(evidence) => evidence.ordinal(), + PairSelectionEvidenceV1::Wcag22(evidence) => evidence.ordinal(), } - let flip_ys = crate::spaces::srgb::srgb_gamma_inv(0.5 * (lo + hi)); - eprintln!("флип pair_side на серой оси: Ys = {flip_ys:.6}"); - let residual = y_star - flip_ys; - assert!( - (0.0..0.01).contains(&residual), - "ахроматическая редукция: флип {flip_ys:.4} против Y* {y_star:.4} \ - (резидуй {residual:.4} обязан быть в [0, 0.01))" - ); - assert!( - flip_ys > LEVEL2_CROSSOVER_Y_RETIRED, - "подъём кроссовера против level-2 реален (флип {flip_ys:.4} > 0.30)" - ); } - /// (г) Корпус 49 якорей labui: ЕДИНСТВЕННОЕ расхождение с level-2 — - /// #4A8FFF (Brand dark): Ys=0.283, воспринимаемая яркость 0.42 — - /// перцептивно светлая пастель, чернила стэндалон. Семейная сторона - /// Brand не затронута: её решает канонический светлый #007AFF (Light, - /// пин консенсус-теста). Консенсус-10 и якоря (а) закреплены отдельно. - #[test] - fn corpus_flips_vs_level2_are_named_and_explained() { - let mut flips: Vec<&str> = Vec::new(); - for &hex in LABUI_ANCHORS { - let e = enc(hex); - let old = if wcag_y_encoded(e) < LEVEL2_CROSSOVER_Y_RETIRED { - PairSide::Light - } else { - PairSide::Ink - }; - if old != pair_side(e) { - flips.push(hex); - } - } - eprintln!("флипы корпуса против level-2: {flips:?}"); - assert_eq!( - flips, - vec!["#4A8FFF"], - "ровно один поимённо объяснённый флип" - ); - assert_eq!(pair_side(enc("#4A8FFF")), PairSide::Ink); + pub(crate) fn fill_paint(&self) -> EncodedPointPaintV1 { + self.execution().lower_paint() } - /// (д) Свип класса этюда V3 (10 оттенков × 24 средне-светлых тона, - /// максимальная хрома): H-K-сдвиг стороны против чистой Ys-модели идёт - /// ТОЛЬКО в направлении Light→Ink (насыщенная поверхность выглядит - /// светлее — раньше готова нести чернила; f(h) Хеллвига всюду > 0) и не - /// топит ни одну ячейку с ИЗВЕСТНОЙ белой конвенцией — пины V3 #007AFF, - /// #0082FF, #FF0000. Контр-конвенционный класс «H-K топит белый» пуст. - #[test] - fn v3_sweep_hk_shift_never_sinks_conventional_white() { - let y_star = derived_equal_lc_crossover(); - let (mut light_to_ink, mut ink_to_light) = (0usize, 0usize); - for hue_step in 0..10 { - let h = f64::from(hue_step) * std::f64::consts::TAU / 10.0; - for tone in 0..24 { - let l = 0.30 + 0.60 * f64::from(tone) / 23.0; - let cell = swatch(l, h, 1.0); - let pure = if wcag_y_encoded(cell) < y_star { - PairSide::Light - } else { - PairSide::Ink - }; - match (pure, pair_side(cell)) { - (PairSide::Light, PairSide::Ink) => light_to_ink += 1, - (PairSide::Ink, PairSide::Light) => ink_to_light += 1, - _ => {} - } - } - } - eprintln!("свип 240: сдвигов white→ink {light_to_ink}, обратных {ink_to_light}"); - assert_eq!( - ink_to_light, 0, - "H-K не имеет права «затемнять» поверхность" - ); - assert!( - light_to_ink > 0, - "hue-каверна обязана существовать (таск #62)" - ); - for hex in ["#007AFF", "#0082FF", "#FF0000"] { - assert_eq!( - pair_side(enc(hex)), - PairSide::Light, - "{hex}: известная конвенция — белый лейбл" - ); - } + pub(crate) fn label_paint(&self) -> EncodedPointPaintV1 { + self.execution().upper_paint() } - /// (е) Монотонность стороны: вдоль линии одного hue по возрастанию - /// светлоты — не более одного переключения, и только Light→Ink. Три - /// уровня относительной хромы, включая гамут-границу (каспы). - #[test] - fn at_most_one_switch_along_hue_lightness_lines() { - for hue_step in 0..12 { - let h = f64::from(hue_step) * std::f64::consts::TAU / 12.0; - for rel_c in [0.35, 0.70, 1.0] { - let mut prev = None; - let mut switches = 0usize; - for step in 0..=120 { - let l = 0.02 + 0.96 * f64::from(step) / 120.0; - let side = pair_side(swatch(l, h, rel_c)); - if let Some(p) = prev { - if side != p { - switches += 1; - assert_eq!( - (p, side), - (PairSide::Light, PairSide::Ink), - "hue {hue_step}, C_rel {rel_c}: только Light→Ink" - ); - } - } - prev = Some(side); - } - assert!( - switches <= 1, - "hue {hue_step}, C_rel {rel_c}: {switches} переключений стороны" - ); - } - } + pub(crate) fn fill_occurrence(&self) -> &ResolvedOccurrence { + self.execution().lower_occurrence() } -} - -// ───────────────────────────────────────────────────────────────────────────── -// Локи терминала (a) DERIVED `PAIR_CROSSOVER_Y` (после #180: (e)→(a), значение = -// измеренный перелом ядра `contrast_core`). Статус и деривация НЕ трогаются -// главой #64: тесты предъявляют (1) чистый зазор консенсус-сета вокруг порога -// (робастность деривации — сторона инвариантна к точному значению в интервале), -// (2) пиннинг деривации замером (константа РАВНА перелому ядра, не цитата), (3) -// экспозицию зоны флипа; петля консистентности с продакшн-решением учитывает -// level-3 (H-K может только ПОДНЯТЬ якорь в чернила, поимённо). -#[cfg(test)] -mod exposure_locks { - use super::{PAIR_CROSSOVER_Y, PairSide, pair_side, wcag_y_encoded}; - use crate::exposure_support::{LABUI_ANCHORS, band_exposure, enc_of, wcag_y}; - use crate::spaces::srgb::srgb_encoded_from_hex; - fn y_of(hex: &str) -> f64 { - wcag_y_encoded(srgb_encoded_from_hex(hex).unwrap()) + pub(crate) fn label_occurrence(&self) -> &ResolvedOccurrence { + self.execution().upper_occurrence() } +} - /// Sensitivity (робастность деривации): на консенсус-сете labui сторона пары - /// ИНВАРИАНТНА для любого порога в задекларированном интервале. Доказ.: max Y светлой стороны СТРОГО - /// ниже min Y чернильной (чистый зазор), и PAIR_CROSSOVER_Y лежит в нём — значит - /// точное значение внутри зазора нематериально для этой палитры. - #[test] - fn crossover_side_is_invariant_across_palette_gap() { - let light = ["#007AFF", "#FF3B30", "#3E87FF", "#101012", "#5856D6"]; - let ink = ["#FFA100", "#34C759", "#FFD000", "#FFFFFF", "#5AC8FA"]; - let light_max = light.iter().map(|h| y_of(h)).fold(0.0f64, f64::max); - let ink_min = ink.iter().map(|h| y_of(h)).fold(f64::INFINITY, f64::min); - assert!( - light_max < ink_min, - "консенсус-сет должен иметь чистый зазор Y (light_max={light_max:.4} < ink_min={ink_min:.4})" - ); - assert!( - light_max < PAIR_CROSSOVER_Y && PAIR_CROSSOVER_Y < ink_min, - "PAIR_CROSSOVER_Y={PAIR_CROSSOVER_Y} должен лежать в зазоре ({light_max:.4}, {ink_min:.4})" - ); - // Любой порог в зазоре даёт то же разбиение — проверяем на границах зазора. - for theta in [light_max + 1e-6, ink_min - 1e-6, PAIR_CROSSOVER_Y] { - for h in light { - assert!(y_of(h) < theta, "{h}: светлая сторона при θ={theta:.4}"); - } - for h in ink { - assert!(y_of(h) >= theta, "{h}: чернильная сторона при θ={theta:.4}"); - } - } - } +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum PairLoweringErrorV1 { + Candidate(CandidateSetErrorV1), + Program(JointProgramErrorV1), + ExactReport(PointwiseJointReportErrorV1), + WcagReport(PointwiseJointReportErrorV1), + Policy(SelectionPolicyErrorV1), + ExactInfeasible(Box>), + WcagInfeasible(Box>), + ExactRecheck(PointwiseSelectedRecheckErrorV1), + WcagRecheck(PointwiseSelectedRecheckErrorV1), +} - /// (a)-ЯКОРЬ ИЗМЕРЯЕТСЯ И ПИННИТ КОНСТАНТУ: перелом полярности модели — фон, на - /// котором чёрный лейбл догоняет белый по |Lc|. Два домена: - /// 1. Чистое люминансное ядро ([`crate::lpc::contrast_core`], вход — сырой Y): - /// бисекция. Это домен ахроматического терминала, к которому level-3 - /// `pair_side` редуцируется на серой оси, — потому его перелом = якорь - /// `PAIR_CROSSOVER_Y`. - /// 2. Test-only H-K appearance-candidate на серой оси sRGB8 с - /// CAM16-реконструкцией: вторичная численная характеризация (byte 155, - /// Y≈0.325) — печатается для сравнения, но решению pair.rs чужд, не якорь. - /// - /// Числа печатаются и пиннятся снапшотом: дрейф любой замороженной константы - /// ядра сдвинет перелом и СЛОМАЕТ лок — значит `PAIR_CROSSOVER_Y` не может молча - /// разойтись с деривацией (это и есть пиннинг (a) DERIVED). Перелом лежит внутри - /// интервала 10 якорей (0.246, 0.423) — вывод согласован с палитрой. Провенанс — - /// docs/empirical-inventory.md (строка 52). - #[test] - fn pair_crossover_equals_measured_core_polarity_flip() { - use crate::lpc::{apparent_contrast_candidate_hex_for_test, contrast_core}; - use crate::spaces::srgb::srgb_gamma_inv; - // 1. Ядро: f(Y) = |Lc белого| − |Lc чёрного| меняет знак на [0.2, 0.6]. - let f = |y: f64| contrast_core(1.0, y).abs() - contrast_core(0.0, y).abs(); - assert!( - f(0.2) > 0.0 && f(0.6) < 0.0, - "предпосылка бисекции: белый выигрывает на 0.2, чёрный на 0.6" - ); - // Единственность корня: знак f меняется РОВНО один раз на сетке - // интервала — без этого бисекция могла бы сойтись к одному из - // нескольких пересечений (замечание CodeRabbit, PR #177). - let mut sign_changes = 0u32; - let mut prev_positive = true; - let mut y = 0.2_f64; - while y <= 0.6 { - let cur_positive = f(y) > 0.0; - if cur_positive != prev_positive { - sign_changes += 1; - prev_positive = cur_positive; - } - y += 0.002; - } - assert_eq!( - sign_changes, 1, - "f обязана пересекать ноль ровно один раз на [0.2, 0.6]" - ); - let (mut lo, mut hi) = (0.2_f64, 0.6_f64); - for _ in 0..60 { - let mid = 0.5 * (lo + hi); - if f(mid) > 0.0 { - lo = mid; - } else { - hi = mid; - } - } - let core_x = 0.5 * (lo + hi); - // 2. Test-only H-K appearance-candidate: первый серый байт, где - // black-ветвь обгоняет white-ветвь. - let mut flip_byte = None; - for v in 1..=255u32 { - let hex = format!("#{v:02X}{v:02X}{v:02X}"); - if apparent_contrast_candidate_hex_for_test("#000000", &hex) - .expect("generated grey is valid") - .abs() - >= apparent_contrast_candidate_hex_for_test("#FFFFFF", &hex) - .expect("generated grey is valid") - .abs() - { - flip_byte = Some(v); - break; - } - } - let v = flip_byte.expect("на серой оси перелом обязан существовать"); - let y_at = |b: u32| srgb_gamma_inv(f64::from(b) / 255.0); - let (y_below, y_flip) = (y_at(v - 1), y_at(v)); - eprintln!( - "MODEL CROSSOVER: core Y={core_x:.6}; H-K candidate grey axis: byte {v} (Y in ({y_below:.4}, {y_flip:.4}])" - ); - // Снапшоты замера — регрессионный якорь (a)-деривации (прежний - // rustdoc-клейм «перелом ≈ 0.36» опровергнут этим замером 2026-07-07). - assert!( - (core_x - 0.341955).abs() < 5e-4, - "ядро: перелом ушёл от снапшота 0.3420: {core_x:.6}" - ); - assert_eq!( - v, 155, - "H-K candidate: перелом серой оси ушёл от снапшота (byte {v}, Y={y_flip:.4})" - ); - // (a) DERIVED: константа РАВНА измеренному перелому ядра — якорь = ядро - // `contrast_core`, а не H-K candidate (byte 155, Y≈0.325 несёт - // CAM16/Y_hk-реконструкцию; она остаётся вторичным замером, не якорем). - assert!( - (PAIR_CROSSOVER_Y - core_x).abs() < 1e-5, - "PAIR_CROSSOVER_Y={PAIR_CROSSOVER_Y} обязан РАВНЯТЬСЯ измеренному перелому ядра {core_x:.6}" - ); - // И вывод согласован с палитрой: перелом лежит внутри интервала 10 якорей. - assert!( - (0.246..0.423).contains(&core_x) && (0.246..0.423).contains(&y_flip), - "модельные предсказания обязаны лежать внутри интервала якорей" - ); - } +/// Материализовать fill occurrence без role-specific эвристики. +pub(crate) fn lower_fill( + source: Srgb8, + opacity: AdmittedOpacityV1, + backdrop: Srgb8, +) -> LoweredPairFillV1 { + let paint = EncodedPointPaintV1::from_admitted(FILL_PAINT, source, opacity); + let occurrence = + PointOpacityOverSurfaceV1::evaluate_admitted(source.bytes(), opacity, backdrop.bytes()); + LoweredPairFillV1 { paint, occurrence } +} - /// EXPOSURE: доля гаммы в зоне флипа PAIR_CROSSOVER_Y = доля цветов с Y в - /// задекларированном интервале (0.246, 0.423) [красный/зелёный якоря labui]. - /// Инвариант: 12 якорей 49-якорного паспорта лежат в зоне - /// (тёмные/IC-варианты семей, напр. info dark #5696FF - /// Y=0.31) — это НЕ флип-риск: сторона решается ОДИН РАЗ по каноническому - /// СВЕТЛОМУ якорю семьи, а консенсус-сет канонических якорей имеет чистый - /// зазор (`crossover_side_is_invariant_across_palette_gap`). - #[test] - fn exposure_pair_crossover() { - let (lo, hi) = (0.246, 0.423); - let (grid_pct, labui_hits) = band_exposure(wcag_y, lo, hi); - eprintln!( - "EXPOSURE PAIR_CROSSOVER_Y interval=({lo},{hi}) grid_flip={grid_pct:.2}% labui_in_zone={} {:?}", - labui_hits.len(), - labui_hits - ); - assert_eq!( - labui_hits.len(), - 12, - "в зоне перелома должны оставаться ровно 12 из 49 якорей" - ); - // Консистентность с продакшн-решением при level-3 (глава #64): H-K - // строго однонаправлен — против порога якорь может только ПОДНЯТЬСЯ в - // чернила (цветная поверхность выглядит светлее), никогда — утонуть в - // свет. Промоции поимённые и пиннятся снапшотом. - let mut promoted: Vec<&str> = Vec::new(); - for &h in LABUI_ANCHORS { - let enc = srgb_encoded_from_hex(h).unwrap(); - let prod = pair_side(enc); - let reimpl = if wcag_y(enc_of(h)) < PAIR_CROSSOVER_Y { - PairSide::Light - } else { - PairSide::Ink +/// Выбрать один label Paint из полного frontend candidate domain. Fill Paint +/// фиксирован authoring representation-ом, но каждый tuple исполняет обе +/// linked occurrences; hard report и fresh recheck используют тот же kernel. +pub(crate) fn select_label_candidates( + fill_source: Srgb8, + fill_opacity: AdmittedOpacityV1, + candidates: Vec, + declared_order: Vec, + backdrop: Srgb8, + requirement: PairLabelRequirementV1, +) -> Result { + let tuples = candidates + .into_iter() + .map(|candidate| { + JointCandidateTupleV1::new( + candidate.ordinal, + EncodedPointPaintV1::from_admitted(FILL_PAINT, fill_source, fill_opacity), + EncodedPointPaintV1::from_admitted( + LABEL_PAINT, + candidate.source, + AdmittedOpacityV1::OPAQUE, + ), + ) + }) + .collect(); + let candidates = JointCandidateSetV1::new(tuples).map_err(PairLoweringErrorV1::Candidate)?; + let policy = DeclaredTotalOrderV1::new(&candidates, declared_order) + .map_err(PairLoweringErrorV1::Policy)?; + let observation = StaticJointObservationV1::one_case(ROOT_SURFACE, backdrop); + + match requirement { + PairLabelRequirementV1::None => { + let program = PointwiseJointPointProgramV1::with_evaluator( + ExactSrgb8IdentityV1, + ROOT_SURFACE, + FILL_PAINT, + LABEL_PAINT, + Vec::new(), + ) + .map_err(PairLoweringErrorV1::Program)?; + let report = program + .evaluate(candidates, observation) + .map_err(PairLoweringErrorV1::ExactReport)?; + let feasible = match report.classify() { + PointwiseHardFeasibilityV1::NonEmpty(feasible) => feasible, + PointwiseHardFeasibilityV1::Infeasible(report) => { + return Err(PairLoweringErrorV1::ExactInfeasible(Box::new(report))); + } }; - match (reimpl, prod) { - (PairSide::Ink, PairSide::Light) => { - panic!("{h}: level-3 утопил чернильный якорь в свет — H-K однонаправлен") + let verified = feasible + .select(policy) + .recheck() + .map_err(PairLoweringErrorV1::ExactRecheck)?; + Ok(VerifiedPairV1 { + evidence: PairSelectionEvidenceV1::Unconstrained(verified), + }) + } + PairLabelRequirementV1::Wcag22(criterion) => { + let constraints = vec![PointwiseJointHardConstraintV1::new( + LABEL_CONSTRAINT, + JointVisibleTargetV1::Upper, + criterion, + )]; + let program = PointwiseJointPointProgramV1::with_evaluator( + Wcag22Srgb8V1, + ROOT_SURFACE, + FILL_PAINT, + LABEL_PAINT, + constraints, + ) + .map_err(PairLoweringErrorV1::Program)?; + let report = program + .evaluate(candidates, observation) + .map_err(PairLoweringErrorV1::WcagReport)?; + let feasible = match report.classify() { + PointwiseHardFeasibilityV1::NonEmpty(feasible) => feasible, + PointwiseHardFeasibilityV1::Infeasible(report) => { + return Err(PairLoweringErrorV1::WcagInfeasible(Box::new(report))); } - (PairSide::Light, PairSide::Ink) => promoted.push(h), - _ => {} - } + }; + let verified = feasible + .select(policy) + .recheck() + .map_err(PairLoweringErrorV1::WcagRecheck)?; + Ok(VerifiedPairV1 { + evidence: PairSelectionEvidenceV1::Wcag22(verified), + }) } - eprintln!("level-3 промоции против порога: {promoted:?}"); - // Снапшот измеренных промоций level-3 (H-K, глава #64): насыщенные - // средне-светлые фоны, у которых чистый Ys < порога, но воспринимаемая - // яркость (H-K) поднимает их над кроссовером → чернильный лейбл. Все - // пять — блю/красно-розовые пастели; ни одна «известная конвенция» - // (#007AFF и т.п.) не затронута (пин `v3_sweep_...`). H-K строго - // однонаправлен: панику «утопил чернила в свет» выше ни один не вызвал. - assert_eq!( - promoted, - vec!["#409CFF", "#4A8FFF", "#5696FF", "#FF6161", "#FF6482"], - "промоции level-3 против ахроматического терминала — поимённый снапшот" - ); } } diff --git a/crates/labcolors-core/src/pair_label_tests.rs b/crates/labcolors-core/src/pair_label_tests.rs index b9441b30..b3371a2b 100644 --- a/crates/labcolors-core/src/pair_label_tests.rs +++ b/crates/labcolors-core/src/pair_label_tests.rs @@ -1,456 +1,174 @@ -//! Характеризация boundary-адаптера `RoleSpec::PairLabel`. -//! -//! Класс, который закрывают эти тесты: контраст `label ↔ tinted-fill` у бейджа -//! на тинт-фоне был ЭМЕРДЖЕНТНЫМ, не гарантированным. Обычные `label-*` роли -//! решаются против ФОНА СТРАНИЦЫ и достигают своего WCAG-пола там; тинт-бейдж -//! (`labui/lab-badge.ts`, `type=tinted`) кладёт их на `fill-*-primary` (@12 -//! семейный тинт) — на этой подложке контраст ниже, и для warning/success -//! «цветной» лейбл (доля 0.4757, как `label-*-tertiary`) оседает к ~2.9:1 < 3:1. -//! `PairLabel` решает оттеночный лейбл ПРОТИВ тинт-поверхности, поэтому пол -//! гарантирован по построению; при недостижимости тон клампится (флаг -//! `compressed`), а не молча выдаётся за точное выполнение контракта. -//! -//! Appearance-граф описывает только физическую цепочку заливки: -//! solid paint → opacity paint → occurrence на контексте → derived surface. -//! Downstream-солвер -//! лейбла получает эту подложку без изменения своей математики. Тесты -//! доказывают точность этой границы подложки, но не заявляют наличие -//! финального label paint/occurrence или публичного recipe-контракта. -//! -//! Четыре группы: -//! 1. `shipped_*` — реальный контракт labui (`label--primary` на -//! `fill--primary`) держит UI-пол на тинте во всех темах (гвардит то, -//! что уже отгружено, — near-black лейбл сейчас даёт 13–18:1). -//! 2. `pair_label_*` — новая роль держит пол против тинт-поверхности во всех -//! client-defined families × light/dark (± IC). -//! 3. `pair_label_beats_page_resolved_label` — дифференциальный RED-proof: -//! ТОТ ЖЕ контракт (доля 0.4757, `AaUi`), решённый против страницы -//! (`label--tertiary`), проваливает 3:1 на тинте у warning/success, -//! а `PairLabel` (против поверхности) — держит. Разница ТОЛЬКО в подложке -//! резолва: если бы `resolve_pair_label` целил фон страницы, тест бы упал. -//! 4. `fill_occurrence_backdrop_*` / `pair_fill_output_*` — appearance-путь -//! подложки байт-идентичен замороженному -//! ручному composite-oracle (матрица 5 семей × 4 режима × 6 фонов + property), включая -//! типизированный отказ выбранной alpha-ветви; поверхность PairLabel НЕ является -//! эмитированным PairFill (санитарный witness против ложного ребра). - -use proptest::prelude::*; +//! P1 Pair frontend: emitted fill Surface, joint hard selection and anti-vacuum. +use crate::Srgb8; +use crate::composition::AdmittedOpacityV1; use crate::config::fixture::labui_reference; -use crate::semantic::{resolve_pair_label, resolve_pair_label_manual_composite_oracle}; -use crate::solve::Floor; -use crate::{ - BgInput, LadderSource, LadderTint, Resolved, RoleRecipe, RoleSpec, SolveFailure, - ViewingConditions, resolve_named_set, +use crate::config::{LadderSource, RoleRecipe}; +use crate::joint::CandidateOrdinalV1; +use crate::pair::{ + PairLabelCandidateV1, PairLabelRequirementV1, lower_fill, select_label_candidates, }; - -/// (имя семьи, источник лестницы) — 5 цветных семей тинт-бейджа labui -/// (нейтраль/статики используют `label-primary`/семейный примитив, покрыты -/// отдельно) . -fn families() -> [(&'static str, LadderSource); 5] { - [ - ("brand", LadderSource::Brand), - ("danger", LadderSource::Family("red".to_string())), - ("warning", LadderSource::Family("orange".to_string())), - ("success", LadderSource::Family("green".to_string())), - ("info", LadderSource::Family("blue".to_string())), - ] -} - -/// Четыре режима labui: тема (фон) × VC-пресет. -fn themes() -> [(&'static str, &'static str, ViewingConditions); 4] { - [ - ("light", "#FFFFFF", ViewingConditions::srgb()), - ( - "light-ic", - "#FFFFFF", - ViewingConditions::srgb_high_contrast(), - ), - ("dark", "#101012", ViewingConditions::dim_surround()), - ( - "dark-ic", - "#101012", - ViewingConditions::dim_surround_high_contrast(), - ), - ] -} - -/// Объявленный UI-пол из SSOT-контракта [`Floor::AaUi`]. Локальная -/// копия числа запрещена: тест проверяет тот же пол, который энфорсит -/// резолвер, и не дублирует его политику в фикстуре. -fn ui_floor() -> f64 { - Floor::AaUi - .min_ratio() - .expect("AaUi несёт числовой юр. пол") -} +use crate::semantic::{NamedRoleTable, RoleChroma, RoleSpec, resolve_named_set}; +use crate::solve::{BgInput, Floor, SolveFailure}; +use crate::spaces::vc::ViewingConditions; +use crate::wcag22::Wcag22CriterionV1; fn enc(hex: &str) -> [f64; 3] { - crate::spaces::srgb::srgb_encoded_from_hex(hex).expect("тестовый hex валиден") -} - -/// Тинт-поверхность семьи = композит `fill--primary` (то, во что складывается -/// `fill-*-tinted`). -fn surface_hex(set: &[(String, Resolved)], fam: &str) -> String { - set.iter() - .find(|(n, _)| n == &format!("fill-{fam}-primary")) - .and_then(|(_, r)| r.translucent()) - .map(|t| t.composite_hex().to_string()) - .unwrap_or_else(|| panic!("fill-{fam}-primary — тинт-поверхность")) -} - -/// Solved-hex цветной роли (лейбл). -fn solid_hex(set: &[(String, Resolved)], role: &str) -> String { - set.iter() - .find(|(n, _)| n == role) - .and_then(|(_, r)| r.solved()) - .map(|s| s.hex().to_string()) - .unwrap_or_else(|| panic!("роль `{role}` обязана решиться цветом")) -} - -/// WCAG-контраст роли против тинт-поверхности своей семьи. -fn ratio_on_tint(set: &[(String, Resolved)], role: &str, fam: &str) -> f64 { - crate::wcag::contrast_ratio(enc(&solid_hex(set, role)), enc(&surface_hex(set, fam))) -} - -/// Конфиг labui + добавленные роли `badge-label-` (`PairLabel`, доля -/// 0.47572199 «цветного» уровня = `label-*-tertiary`, пол `AaUi`) — форма, -/// которую тинт-бейдж должен потреблять. -fn labui_with_badge_labels() -> crate::NamedRoleTable { - let mut cfg = labui_reference(); - for (fam, source) in families() { - cfg.roles.push(( - format!("badge-label-{fam}"), - RoleRecipe::PairLabel { - source, - fraction: 0.47572199, - floor: Floor::AaUi, - }, - )); - } - cfg.compile_named_role_table() - .expect("labui + badge-label компилируется") + crate::spaces::srgb::srgb_encoded_from_hex(hex).unwrap() } -// ── 1. Отгруженный контракт: label--primary на fill--primary ──────── - #[test] -fn shipped_tinted_badge_label_clears_ui_floor_on_tint_all_families_and_themes() { - let floor = ui_floor(); - let table = labui_reference().compile_named_role_table().unwrap(); - for (tname, bg_hex, vc) in themes() { - let bg = BgInput::solid(bg_hex).unwrap(); - let set = resolve_named_set(&bg, &table, &vc) - .expect("валидный labui-контракт обязан резолвиться"); - for (fam, _) in families() { - let r = ratio_on_tint(&set, &format!("label-{fam}-primary"), fam); - assert!( - r >= floor, - "[{tname}] отгруженный тинт-бейдж `label-{fam}-primary` на \ - `fill-{fam}-primary` обязан держать {floor}:1, получено {r:.2}:1" - ); - } - } +fn fill_is_one_exact_opaque_occurrence_without_pair_heuristic() { + let source = Srgb8::new([0x00, 0x7A, 0xFF]); + let backdrop = Srgb8::new([0xFF; 3]); + let fill = lower_fill(source, AdmittedOpacityV1::OPAQUE, backdrop); + + assert_eq!(fill.paint().source(), source); + assert_eq!(fill.paint().opacity(), AdmittedOpacityV1::OPAQUE); + assert_eq!(fill.visible(), source); + assert_eq!( + fill.occurrence().certificate().backdrop_rgb(), + backdrop.bytes() + ); } -// ── 2. PairLabel: жёсткий пол против тинт-поверхности, все семьи × темы ──────── - #[test] -fn pair_label_clears_ui_floor_against_tinted_surface_all_families_and_themes() { - let floor = ui_floor(); - let table = labui_with_badge_labels(); - for (tname, bg_hex, vc) in themes() { - let bg = BgInput::solid(bg_hex).unwrap(); - let set = resolve_named_set(&bg, &table, &vc) - .expect("валидный PairLabel-контракт обязан резолвиться"); - for (fam, _) in families() { - let role = format!("badge-label-{fam}"); - // Решается цветом (не SolveFailure/None) и держит пол на тинте. - let r = ratio_on_tint(&set, &role, fam); - assert!( - r >= floor, - "[{tname}] `{role}` обязан держать {floor}:1 против тинт-поверхности \ - `fill-{fam}-primary`, получено {r:.2}:1" - ); - } - } +fn wcag_joint_selection_rejects_preferred_tuple_and_selects_legal_tuple() { + let dark_fill = Srgb8::new([0x10; 3]); + let preferred_dark = Srgb8::new([0x20; 3]); + let legal_light = Srgb8::new([0xFF; 3]); + let verified = select_label_candidates( + dark_fill, + AdmittedOpacityV1::OPAQUE, + vec![ + PairLabelCandidateV1::new(CandidateOrdinalV1::new(1), preferred_dark), + PairLabelCandidateV1::new(CandidateOrdinalV1::new(2), legal_light), + ], + vec![CandidateOrdinalV1::new(1), CandidateOrdinalV1::new(2)], + Srgb8::new([0xEE; 3]), + PairLabelRequirementV1::Wcag22(Wcag22CriterionV1::Sc143TextDefault), + ) + .unwrap(); + + assert_eq!(verified.ordinal(), CandidateOrdinalV1::new(2)); + assert_eq!(verified.fill_occurrence().visible(), dark_fill.bytes()); + assert_eq!(verified.label_occurrence().visible(), legal_light.bytes()); + assert_eq!( + verified.label_occurrence().certificate().backdrop_rgb(), + dark_fill.bytes() + ); } -/// Лейбл тинт-бейджа эмитит другой байтовый цвет, чем основной label семьи. #[test] -fn pair_label_bytes_differ_from_primary_label() { - let table = labui_with_badge_labels(); - let bg = BgInput::solid("#FFFFFF").unwrap(); - let set = resolve_named_set(&bg, &table, &ViewingConditions::srgb()) - .expect("валидный PairLabel-контракт обязан резолвиться"); - for (fam, _) in families() { - let role = format!("badge-label-{fam}"); - let res = &set.iter().find(|(n, _)| n == &role).unwrap().1; - let Resolved::Color { solved, .. } = res else { - panic!("`{role}` обязан решиться цветом"); - }; - // Здесь проверяется только различие представления; перцептивный порог из - // одного `assert_ne!` не выводится. - let primary = solid_hex(&set, &format!("label-{fam}-primary")); - assert_ne!( - solved.hex(), - primary, - "`{role}` не должен совпасть байт-в-байт с `label-{fam}-primary`" - ); +fn pair_fill_and_pair_label_share_the_same_emitted_surface() { + let mut config = labui_reference(); + config.roles.push(( + "badge-label-brand".into(), + RoleRecipe::PairLabel { + source: LadderSource::Brand, + fraction: 0.461, + floor: Floor::AaUi, + }, + )); + let table = config.compile_named_role_table().unwrap(); + + for (background, vc) in [ + ("#FFFFFF", ViewingConditions::srgb()), + ("#101012", ViewingConditions::dim_surround()), + ] { + let set = resolve_named_set(&BgInput::solid(background).unwrap(), &table, &vc).unwrap(); + let fill = set + .iter() + .find(|(name, _)| name == "badge-fill-brand") + .unwrap() + .1 + .translucent() + .unwrap(); + let label = set + .iter() + .find(|(name, _)| name == "badge-label-brand") + .unwrap() + .1 + .solved() + .unwrap(); + + assert_eq!(fill.alpha().to_bits(), 1.0_f64.to_bits()); + assert_eq!(fill.tint_hex(), fill.composite_hex()); + let ratio = crate::wcag::contrast_ratio(enc(label.hex()), enc(fill.composite_hex())); + assert!(ratio >= 3.0, "{background}: got {ratio}"); } } -// ── 3. Дифференциальный RED-proof: подложка резолва — и есть констрейнт ──────── - -/// ТОТ ЖЕ контракт (доля 0.4757, `AaUi`), решённый против СТРАНИЦЫ -/// (`label--tertiary`), проваливает 3:1 на тинте у warning/success в light; -/// `PairLabel` (против ПОВЕРХНОСТИ) — держит. Единственная разница — подложка -/// резолва: если `resolve_pair_label` целил бы фон страницы, «after» совпал бы с -/// «before» и упал. Кусающийся тест, не green-from-birth. #[test] -fn pair_label_beats_page_resolved_label_on_failing_families() { - let floor = ui_floor(); - let table = labui_with_badge_labels(); +fn pair_result_is_independent_of_client_role_names() { + let blue = [0.0, 0.47843137254901963, 1.0]; + let tint = crate::ladder::LadderTint::new([blue; 4]).unwrap(); + let entries = |fill: &str, label: &str| { + vec![ + (fill.into(), RoleSpec::PairFill { tint }), + ( + label.into(), + RoleSpec::PairLabel { + tint, + fraction: 0.461, + floor: Floor::AaUi, + surface_alpha_light: 1.0, + surface_alpha_dark: 1.0, + }, + ), + ] + }; + let left = NamedRoleTable::new(entries("x", "y"), Vec::new(), RoleChroma::Neutral).unwrap(); + let right = NamedRoleTable::new( + entries("danger-primary", "surface-hover"), + Vec::new(), + RoleChroma::Neutral, + ) + .unwrap(); let bg = BgInput::solid("#FFFFFF").unwrap(); - let set = resolve_named_set(&bg, &table, &ViewingConditions::srgb()) - .expect("валидный PairLabel-контракт обязан резолвиться"); - - // warning/success — семьи, где предпосылку о провале страничного - // `label-*-tertiary` на собственном тинте проверяет первый assert ниже. - for fam in ["warning", "success"] { - let before = ratio_on_tint(&set, &format!("label-{fam}-tertiary"), fam); - let after = ratio_on_tint(&set, &format!("badge-label-{fam}"), fam); - assert!( - before < floor, - "предпосылка класса: страничный `label-{fam}-tertiary` обязан \ - проваливать {floor}:1 на тинте (иначе тест не о том), получено {before:.2}:1" - ); - assert!( - after >= floor, - "`badge-label-{fam}` (тот же контракт, но против поверхности) обязан \ - держать {floor}:1, получено {after:.2}:1" - ); - assert!( - after > before, - "резолв против поверхности обязан ПОДНЯТЬ контраст на тинте: \ - {fam} before={before:.2} after={after:.2}" - ); - } -} - -// ── 4. Fill occurrence-derived backdrop == замороженный oracle ── + let a = resolve_named_set(&bg, &left, &ViewingConditions::srgb()).unwrap(); + let b = resolve_named_set(&bg, &right, &ViewingConditions::srgb()).unwrap(); -/// Скомпилированные параметры `RoleSpec::PairLabel` конкретной роли таблицы — -/// вход обоих путей differential-а (appearance-путь и ручной oracle получают -/// РОВНО одни аргументы, различие только в реализации). -fn pair_label_spec( - table: &crate::NamedRoleTable, - role: &str, -) -> (LadderTint, f64, Floor, f64, f64) { - let spec = table - .entries() - .iter() - .find(|(name, _)| name == role) - .map(|(_, spec)| spec) - .unwrap_or_else(|| panic!("роль `{role}` обязана существовать в таблице")); - match spec { - RoleSpec::PairLabel { - tint, - fraction, - floor, - surface_alpha_light, - surface_alpha_dark, - } => ( - *tint, - *fraction, - *floor, - *surface_alpha_light, - *surface_alpha_dark, - ), - other => panic!("`{role}` обязан компилироваться в PairLabel, получено {other:?}"), - } -} - -/// Шесть контекстных фонов differential-матрицы — coverage-выборка с -/// подписанным происхождением каждой точки, НЕ production-правило: -/// -/// * `#000000` / `#FFFFFF` — границы sRGB-куба; белый одновременно является -/// отгруженным фоном светлых labui-тем (классы совпадают в этой дизайн- -/// системе по факту фикстуры); -/// * `#101012` — отгруженный фон тёмных labui-тем (фикстура); -/// * `#767676` — опубликованная WCAG-граница серого (≈4.54:1 к белому), -/// напрямую закреплённая -/// `tests/reference_vectors.rs::wcag_published_ratios_via_public_api`; -/// * `#FFF4E0` — хроматический светлый witness: точная warning-поверхность -/// из graph-тестов (`appearance_graph_tests`); -/// * `#0000FF` — насыщенный хроматический угол куба (sRGB primary). -fn differential_backgrounds() -> [&'static str; 6] { - [ - "#000000", "#101012", "#767676", "#FFF4E0", "#0000FF", "#FFFFFF", - ] + assert_eq!(a[0].1, b[0].1); + assert_eq!(a[1].1, b[1].1); } -/// Appearance-путь вычисляет fill occurrence и derived backdrop, после чего -/// неизменённый downstream-солвер обязан дать тот же `Resolved`, что и -/// замороженный oracle: вариант, -/// финальные байты, флаги, unreachable-причины. Никакого approximate equality: -/// `assert_eq!` по `PartialEq` сравнивает и все числовые поля (одинаковые биты -/// по построению одного downstream-солвера), а hex сверяется отдельно, чтобы -/// байтовая эмиссия оставалась закреплённой даже при эволюции `PartialEq`. -/// Это differential-доказательство границы подложки, а не наличия финального -/// label occurrence в appearance-графе. #[test] -fn fill_occurrence_backdrop_matrix_matches_frozen_pair_label_oracle_exactly() { - let table = labui_with_badge_labels(); - let mut resolved_hits = 0usize; - for (tname, _, vc) in themes() { - for bg_hex in differential_backgrounds() { - let bg = BgInput::solid(bg_hex).unwrap(); - for (fam, _) in families() { - let role = format!("badge-label-{fam}"); - let (tint, fraction, floor, alpha_light, alpha_dark) = - pair_label_spec(&table, &role); - let production = - resolve_pair_label(&bg, tint, fraction, floor, alpha_light, alpha_dark, &vc); - let oracle = resolve_pair_label_manual_composite_oracle( - &bg, - tint, - fraction, - floor, - alpha_light, - alpha_dark, - &vc, - ); - assert_eq!( - production, oracle, - "[{tname}/{bg_hex}] `{role}`: production-граф обязан быть \ - идентичен замороженному ручному composite-oracle по всем полям" - ); - for outcome in [&production, &oracle] { - assert!( - !matches!( - outcome, - Err(SolveFailure::InvalidInput(_) - | SolveFailure::GamutUnsupported - | SolveFailure::InternalInvariant(_)) - ), - "[{tname}/{bg_hex}] `{role}`: a valid sRGB fixture produced a non-physical error: {outcome:?}" - ); - } - if let ( - Ok(Resolved::Color { solved: p, .. }), - Ok(Resolved::Color { solved: o, .. }), - ) = (&production, &oracle) - { - resolved_hits += 1; - assert_eq!( - p.hex(), - o.hex(), - "[{tname}/{bg_hex}] `{role}`: финальные байты эмиссии" - ); - } - } - } - } - assert!( - resolved_hits > 0, - "differential matrix must exercise successful colour resolution" - ); -} +fn nonopaque_pairlabel_transport_is_rejected_before_execution() { + let tint = crate::ladder::LadderTint::new([[0.0, 0.0, 0.0]; 4]).unwrap(); + let error = NamedRoleTable::new( + vec![( + "label".into(), + RoleSpec::PairLabel { + tint, + fraction: 0.5, + floor: Floor::AaUi, + surface_alpha_light: 0.122, + surface_alpha_dark: 0.122, + }, + )], + Vec::new(), + RoleChroma::Neutral, + ) + .unwrap_err(); -/// Внутренний resolver обязан типизированно отклонять невалидную выбранную -/// альфу до начала физического поиска. Публичный `NamedRoleTable` дополнительно -/// валидирует обе theme-ветви при компиляции конфига. -#[test] -fn fill_occurrence_backdrop_path_rejects_selected_invalid_alpha_exactly() { - let table = labui_with_badge_labels(); - let (tint, fraction, floor, _, _) = pair_label_spec(&table, "badge-label-warning"); - for bad_alpha in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY, -0.1, 1.5] { - for (bg_hex, vc, light, dark) in [ - ("#FFFFFF", ViewingConditions::srgb(), bad_alpha, 0.122), - ( - "#101012", - ViewingConditions::dim_surround(), - 0.122, - bad_alpha, - ), - ] { - let bg = BgInput::solid(bg_hex).unwrap(); - let production = resolve_pair_label(&bg, tint, fraction, floor, light, dark, &vc); - let oracle = resolve_pair_label_manual_composite_oracle( - &bg, tint, fraction, floor, light, dark, &vc, - ); - assert_eq!( - production, oracle, - "theme-selected alpha branch must stay exact for alpha={bad_alpha}" - ); - assert!(matches!(production, Err(SolveFailure::InvalidInput(_)))); - } - } + assert!(matches!(error, SolveFailure::InvalidInput(message) if message.contains("opaque"))); } -/// Санитарный witness против ложного ребра `PairFill → PairLabel`: эмитированный -/// `PairFill` — отдельно -/// сдвинутый солид, он НЕ равен тинт-поверхности (композиту `fill-*-primary`), -/// против которой решается `PairLabel`. Подмена derived backdrop эмитированным -/// PairFill разойдётся с differential-матрицей именно потому, что эти значения -/// различны. #[test] -fn pair_fill_output_differs_from_fill_occurrence_derived_backdrop() { - let mut cfg = labui_reference(); - for (fam, source) in families() { - cfg.roles - .push((format!("pair-fill-{fam}"), RoleRecipe::PairFill { source })); - } - let table = cfg - .compile_named_role_table() - .expect("labui + pair-fill компилируется"); - let bg = BgInput::solid("#FFFFFF").unwrap(); - let set = resolve_named_set(&bg, &table, &ViewingConditions::srgb()) - .expect("валидный PairFill-контракт обязан резолвиться"); - for (fam, _) in families() { - let pair_fill_composite = set - .iter() - .find(|(name, _)| name == &format!("pair-fill-{fam}")) - .and_then(|(_, resolved)| resolved.translucent()) - .map(|t| t.composite_hex().to_string()) - .unwrap_or_else(|| panic!("pair-fill-{fam} обязан решиться")); - let surface = surface_hex(&set, fam); - assert_ne!( - pair_fill_composite, surface, - "{fam}: эмитированный PairFill не является поверхностью PairLabel" - ); - } -} - -// Property-differential: произвольные источник/контекст/альфы/доля/пол/режим -// проверяют точную замену пути подложки. Downstream-солвер в обоих путях -// один и тот же. -proptest! { - #[test] - fn fill_occurrence_backdrop_property_matches_frozen_pair_label_oracle( - source in any::<[u8; 3]>(), - context in any::<[u8; 3]>(), - alpha_light in 0.0f64..=1.0, - alpha_dark in 0.0f64..=1.0, - fraction in 0.01f64..1.0, - floor_pick in 0usize..3, - theme_pick in 0usize..4, - ) { - let encoded = source.map(|channel| f64::from(channel) / 255.0); - let tint = LadderTint::new([encoded; 4]).expect("byte/255 всегда в домене"); - let context_hex = format!( - "#{:02X}{:02X}{:02X}", - context[0], context[1], context[2] - ); - let bg = BgInput::solid(&context_hex).expect("байтовый hex валиден"); - let floor = [Floor::AaText, Floor::AaUi, Floor::None][floor_pick]; - let (_, _, vc) = themes()[theme_pick]; - let production = resolve_pair_label( - &bg, tint, fraction, floor, alpha_light, alpha_dark, &vc, - ); - let oracle = resolve_pair_label_manual_composite_oracle( - &bg, tint, fraction, floor, alpha_light, alpha_dark, &vc, - ); - prop_assert_eq!(production, oracle); - } +fn floor_none_has_no_tautological_exact_constraint() { + let verified = select_label_candidates( + Srgb8::new([0x80; 3]), + AdmittedOpacityV1::OPAQUE, + vec![PairLabelCandidateV1::new( + CandidateOrdinalV1::new(1), + Srgb8::new([0x81; 3]), + )], + vec![CandidateOrdinalV1::new(1)], + Srgb8::new([0x00; 3]), + PairLabelRequirementV1::None, + ) + .unwrap(); + + assert_eq!(verified.ordinal(), CandidateOrdinalV1::new(1)); } diff --git a/crates/labcolors-core/src/scale.rs b/crates/labcolors-core/src/scale.rs index 741cc4fa..6e2b3fb6 100644 --- a/crates/labcolors-core/src/scale.rs +++ b/crates/labcolors-core/src/scale.rs @@ -15,10 +15,9 @@ use crate::spaces::vc::ViewingConditions; /// кандидат-вывод (хорда Oklab, `penalty_scale = C·π/180 ≈ 0.0026–0.0035/°`) /// ИЗМЕРЕН и ОТКЛОНЁН — вырождает интерьерный оптимум в клип по ребру окна /// ±30° на 12/43 якорях, флипает оптимум на 27/43 (лок -/// `chord_derived_slope_rejected_degenerates_to_window_edge`). В отличие от -/// [`crate::pair::PAIR_CROSSOVER_Y`] (где модельный якорь существует и -/// ждёт решения владельца), здесь единственный строгий кандидат уже -/// ПРОВЕРЕН и признан ХУЖЕ текущего значения — вопрос закрыт замером, не +/// `chord_derived_slope_rejected_degenerates_to_window_edge`). Единственный +/// строгий кандидат уже ПРОВЕРЕН и признан ХУЖЕ текущего значения — вопрос +/// закрыт замером, не /// открыт для владельца: свободная ручка с отклонённым кандидатом честнее /// подгонки — реестр docs/empirical-inventory.md. /// diff --git a/crates/labcolors-core/src/semantic.rs b/crates/labcolors-core/src/semantic.rs index e5e4d8be..dfe7e8e9 100644 --- a/crates/labcolors-core/src/semantic.rs +++ b/crates/labcolors-core/src/semantic.rs @@ -546,35 +546,27 @@ pub enum RoleSpec { /// path. Wire-ключ — его boundary-проекция, а не декоративный metadata. mode: crate::numerical_plan::NumericalExecutionModeV1, }, - /// Заливка пары (внутренний модуль `pair`): якорь источника, сдвинутый до победы - /// выбранной ветви переходной pair-эвристики; солид-эмиссия. + /// Frozen PairFill frontend до C7c. Источник становится opaque Paint; + /// единственный source-over occurrence создаёт фактически emitted Surface. + /// Отдельной Pair-эвристики, собственного compositor-а и выбора стороны нет. PairFill { /// Пер-темный кодированный якорь источника. tint: LadderTint, }, - /// Лейбл ТИНТ-бейджа (внутренний модуль `pair`, лейбл-сторона). Семейно-оттеночный - /// лейбл, чей WCAG-пол энфорсится ПРОТИВ объявленной тинт-поверхности - /// (exact source-over композит declared `tint` при compatibility-альфе - /// позиции `fill-*-primary` над фоном резолва), а НЕ против фона страницы - /// и НЕ против эмитированного [`PairFill`](Self::PairFill) — у того своя, - /// отдельно сдвинутая солид-эмиссия; ребра `PairFill → PairLabel` не - /// существует. Приватный appearance-граф материализует tint Paint, применяет - /// его к локальной поверхности ровно в одном fill occurrence и отдаёт - /// `surfaceFrom` как фактический фон. Последующий label solve находится вне - /// графа: этот recipe не создаёт итоговые label Paint/occurrence или их - /// доказательный статус. Дифференциальный тест доказывает только точность - /// границы подложки, а не математику label-resolver-а. - /// Тон клампится (флаг `compressed`) при недостижимости на кривой семьи. + /// Frozen PairLabel frontend до C7c. Кандидаты label Paint проверяются на + /// фактически emitted opaque PairFill Surface общим joint evaluator/recheck. + /// Поля alpha сохраняют замороженную форму публичного RoleSpec, но после P1 + /// обязаны быть opaque: представление не выводится из client role names. PairLabel { - /// Пер-темный кодированный тинт-якорь семьи (как у лестницы). + /// Пер-темный кодированный якорь источника fill и hue-направления label. tint: LadderTint, - /// Доля максимума контраста тинт-поверхности `(0, 1]`. + /// Доля максимума контраста PairFill Surface `(0, 1]`. fraction: f64, - /// WCAG-пол против тинт-поверхности. + /// Hard floor против emitted PairFill Surface. floor: Floor, - /// Альфа поверхности (светлая тема) — из позиции `fill-*-primary`. + /// Замороженное поле representation light; P1 принимает только `1.0`. surface_alpha_light: f64, - /// Альфа поверхности (тёмная тема) — из позиции `fill-*-primary`. + /// Замороженное поле representation dark; P1 принимает только `1.0`. surface_alpha_dark: f64, }, Ladder { @@ -2162,15 +2154,7 @@ fn resolve_spec_in( } RoleSpec::Decorative { magnitude } => ctx.decorative_contract(magnitude), RoleSpec::PairFill { tint } => { - // Сторона пары — идентичность СЕМЬИ: решается по каноническому - // светлому якорю и не флипается между темами/IC (тёмные якоря - // labui осветлены и перелезали бы кроссовер). Пер-режимный якорь - // затем двигается ПОД эту сторону; солид — лестничной сантехникой - // (α = 1; композит на фоне резолва замеряется честно). - let side = - crate::pair::pair_side(tint.for_vc(&crate::spaces::vc::ViewingConditions::srgb())); - let fill = crate::pair::pair_fill(tint.for_vc(vc), side); - return resolve_rgba_direct(fill, 1.0, bg, vc); + return lower_pair_fill_frontend(bg, tint, vc); } RoleSpec::PairLabel { tint, @@ -2179,7 +2163,7 @@ fn resolve_spec_in( surface_alpha_light, surface_alpha_dark, } => { - return resolve_pair_label( + return lower_pair_label_frontend( bg, tint, fraction, @@ -2606,140 +2590,194 @@ fn resolve_solid_with_ui_floor( } } -/// Public PairLabel opacity rejected by the graph's SSOT validator. -fn pair_label_opacity_input_error(error: &str) -> PendingResolution { - Err(SolveFailure::InvalidInput(format!( - "тинт-поверхность бейджа вне encoded-sRGB8 reference-домена: {error}" - ))) +/// Exact page background as the root Surface of the Pair point graph. +fn pair_root_surface(bg: &BgInput) -> Result { + crate::alpha::encoded_to_srgb8(bg.encoded_display(), "pair page background") + .map(Srgb8::new) + .map_err(|error| { + SolveFailure::InternalInvariant(format!( + "validated Pair background left encoded-sRGB8 domain: {error}" + )) + }) } -/// Резолв лейбла ТИНТ-бейджа — жёсткий контраст `label ↔ tinted-surface` -/// ([`crate::pair`], лейбл-сторона; родственен [`resolve_solid_with_ui_floor`], -/// но пол энфорсится против ВЫВОДИМОЙ подложки, а не против фона страницы). -/// -/// Sealed [`PointOpacityOverSurfaceV1`] материализует tint Paint, применяет его -/// к локальному фону в единственном exact source-over occurrence и проецирует -/// видимый результат в derived Surface. -/// Поверхность НЕ является эмитированным [`RoleSpec::PairFill`] — у того своя, -/// отдельно сдвинутая солид-эмиссия; никакого ребра `PairFill → PairLabel` нет. -/// -/// Затем [`resolve_hued_anchor_from_srgb8`] решает label НА ЭТОЙ ПОВЕРХНОСТИ, -/// вне point-графа. Этот контракт не создаёт label Paint/occurrence или -/// constraint evidence. Собственный [`ResolveContext`] поверхности задаёт -/// полярность/макс-контраст, поэтому -/// WCAG-пол лейбла -/// гарантирован против той подложки, на которой foreground реально стоит -/// (обычные `label-*` роли решаются против страницы, и на тинт-подложке их -/// контраст проседает — класс, который закрывает эта роль). Недостижимость пола -/// на кривой семьи клампит тон (`floor_override` → `compressed`), как у любой -/// контраст-роли; флаг не позволяет выдать нестрогий исход за точное выполнение. -/// Занимаемые графом typed handles структурны; клиентские -/// имена в граф не передаются. -#[allow(clippy::too_many_arguments)] -pub(crate) fn resolve_pair_label( +/// Frozen Pair representation is opaque. The old PairSide/Oklab adjustment and +/// the hidden FillPrimary opacity are both absent: representation no longer +/// depends on a client vocabulary term. +fn lower_pair_fill_occurrence( bg: &BgInput, - tint: crate::ladder::LadderTint, - fraction: f64, - floor: Floor, - surface_alpha_light: f64, - surface_alpha_dark: f64, + tint: LadderTint, + vc: &ViewingConditions, +) -> Result { + let source = tint.srgb8_for_vc(vc); + let backdrop = pair_root_surface(bg)?; + Ok(crate::pair::lower_fill( + source, + crate::composition::AdmittedOpacityV1::OPAQUE, + backdrop, + )) +} + +fn lower_pair_fill_frontend( + bg: &BgInput, + tint: LadderTint, vc: &ViewingConditions, ) -> PendingResolution { - let alpha = if vc.is_dark_theme() { - surface_alpha_dark - } else { - surface_alpha_light - }; - // Тинт квантуется ДО композита: подложка обязана считаться из отдаваемого - // значения в едином encoded-sRGB8 reference-домене. Источник и локальный - // фон проходят один quantization SSOT; порядок проверок — tint → bg → α. - let tint_q = quantise_encoded(tint.for_vc(vc)); - let source_rgb = match crate::alpha::encoded_to_srgb8(tint_q, "tint") { - Ok(bytes) => bytes, - Err(error) => { - return Err(SolveFailure::InternalInvariant(format!( - "validated PairLabel tint left encoded sRGB domain: {error}" - ))); - } - }; - let context_rgb = match crate::alpha::encoded_to_srgb8(bg.encoded_display(), "bg") { - Ok(bytes) => bytes, - Err(error) => { - return Err(SolveFailure::InternalInvariant(format!( - "validated background left encoded sRGB domain: {error}" - ))); - } - }; - let surface_occurrence = - match PointOpacityOverSurfaceV1::evaluate(source_rgb, alpha, context_rgb) { - Ok(occurrence) => occurrence, - Err(error) => { - return pair_label_opacity_input_error(error.message()); - } - }; - // Финальные байты реально собранной surface становятся контекстом solve. - let surface_rgb = surface_occurrence.visible(); - let surface_hex = crate::alpha::hex_from_srgb8(surface_rgb); - let Ok(surface_bg) = BgInput::solid(&surface_hex) else { - // Композит 8-битных каналов всегда в кубе — недостижимо, но честнее - // отказ, чем правдоподобный мусор (RoleSpec публичен). + let fill = lower_pair_fill_occurrence(bg, tint, vc)?; + finish_rgba_from_certificate( + fill.paint().source(), + crate::composition::AdmittedOpacityV1::OPAQUE.value(), + fill.occurrence().certificate(), + vc, + false, + false, + ) +} + +fn pair_requirement(floor: Floor) -> crate::pair::PairLabelRequirementV1 { + match floor { + Floor::AaText => crate::pair::PairLabelRequirementV1::Wcag22( + crate::wcag22::Wcag22CriterionV1::Sc143TextDefault, + ), + Floor::AaUi => crate::pair::PairLabelRequirementV1::Wcag22( + crate::wcag22::Wcag22CriterionV1::Sc1411UiComponentOrState, + ), + Floor::None => crate::pair::PairLabelRequirementV1::None, + } +} + +fn resolved_label_bytes(resolved: &Resolved) -> Result { + let Resolved::Color { solved, .. } = resolved else { return Err(SolveFailure::InternalInvariant( - "тинт-поверхность бейджа вне кодированного домена sRGB".into(), + "Pair label proposal did not produce a Color".into(), )); }; - // Свежий контекст ПОВЕРХНОСТИ: полярность/интервал/макс-контраст берутся от - // тинт-подложки, не от фона страницы — потому пол энфорсится против неё. - let surface_ctx = ResolveContext::new(&surface_bg, vc); - let anchor = TextAnchor::new(fraction, floor)?; - // Hue anchor остаётся отдельным входом label-solver. Fill occurrence - // вычисляет только surface и не притворяется зависимостью финального label. - resolve_hued_anchor_from_srgb8( - &surface_bg, - anchor, - Srgb8::new(source_rgb), + crate::srgb8::hex_bytes(solved.hex()) + .map(Srgb8::new) + .map_err(|error| { + SolveFailure::InternalInvariant(format!( + "Pair label solver emitted invalid sRGB8: {error}" + )) + }) +} + +fn pair_candidate( + surface_bg: &BgInput, + fraction: f64, + floor: Floor, + source: Srgb8, + vc: &ViewingConditions, + surface_ctx: &ResolveContext, +) -> Result<(Resolved, Srgb8), SolveFailure> { + let resolved = resolve_hued_anchor_from_srgb8( + surface_bg, + TextAnchor::new(fraction, floor)?, + source, vc, - &surface_ctx, - ) + surface_ctx, + )?; + let bytes = resolved_label_bytes(&resolved)?; + Ok((resolved, bytes)) } -/// Ручной differential oracle: композит tint-surface идёт независимым от графа -/// `composite_hex_from_encoded`-маршрутом, а label — через -/// [`resolve_hued_anchor`] по исходному tint. Он изолирует корректность -/// физической композиции, но не является независимым эталоном solver-а. -#[cfg(test)] +/// PairLabel proposes the exact authored fraction first, then a floor-aware +/// fallback. The common joint engine—not the proposal stage—forms the feasible +/// set, applies the declared order and performs fresh final-occurrence recheck. #[allow(clippy::too_many_arguments)] -pub(crate) fn resolve_pair_label_manual_composite_oracle( +fn lower_pair_label_frontend( bg: &BgInput, - tint: crate::ladder::LadderTint, + tint: LadderTint, fraction: f64, floor: Floor, surface_alpha_light: f64, surface_alpha_dark: f64, vc: &ViewingConditions, ) -> PendingResolution { - let alpha = if vc.is_dark_theme() { - surface_alpha_dark - } else { - surface_alpha_light - }; - let tint_q = quantise_encoded(tint.for_vc(vc)); - let surface_hex = - match crate::alpha::composite_hex_from_encoded(tint_q, alpha, bg.encoded_display()) { - Ok(hex) => hex, - Err(error) => { - return Err(SolveFailure::InvalidInput(format!( - "тинт-поверхность бейджа вне encoded-sRGB8 reference-домена: {error}" - ))); - } - }; - let Ok(surface_bg) = BgInput::solid(&surface_hex) else { - return Err(SolveFailure::InternalInvariant( - "тинт-поверхность бейджа вне кодированного домена sRGB".into(), + if surface_alpha_light.to_bits() != 1.0_f64.to_bits() + || surface_alpha_dark.to_bits() != 1.0_f64.to_bits() + { + return Err(SolveFailure::InvalidInput( + "PairLabel surface representation must be opaque after P1".into(), )); - }; + } + + let source = tint.srgb8_for_vc(vc); + let backdrop = pair_root_surface(bg)?; + let fill = lower_pair_fill_occurrence(bg, tint, vc)?; + let surface = fill.visible(); + let surface_bg = BgInput::solid(&surface.to_hex()).map_err(|error| { + SolveFailure::InternalInvariant(format!("generated PairFill Surface was rejected: {error}")) + })?; let surface_ctx = ResolveContext::new(&surface_bg, vc); - let anchor = TextAnchor::new(fraction, floor)?; - resolve_hued_anchor(&surface_bg, anchor, tint, vc, &surface_ctx) + + let mut resolved_candidates = Vec::new(); + let mut physical_candidates = Vec::new(); + let mut order = Vec::new(); + + match pair_candidate(&surface_bg, fraction, Floor::None, source, vc, &surface_ctx) { + Ok((resolved, bytes)) => { + let ordinal = crate::joint::CandidateOrdinalV1::new(1); + resolved_candidates.push((ordinal, resolved)); + physical_candidates.push(crate::pair::PairLabelCandidateV1::new(ordinal, bytes)); + order.push(ordinal); + } + Err(error) if matches!(floor, Floor::None) => return Err(error), + Err(error) if error.boundary().is_none() => return Err(error), + Err(_) => {} + } + + if !matches!(floor, Floor::None) { + let (resolved, bytes) = + pair_candidate(&surface_bg, fraction, floor, source, vc, &surface_ctx)?; + if physical_candidates + .iter() + .all(|candidate| candidate.source() != bytes) + { + let ordinal = crate::joint::CandidateOrdinalV1::new(2); + resolved_candidates.push((ordinal, resolved)); + physical_candidates.push(crate::pair::PairLabelCandidateV1::new(ordinal, bytes)); + order.push(ordinal); + } + } + + if physical_candidates.is_empty() { + return Err(SolveFailure::InternalInvariant( + "Pair frontend produced an empty candidate domain".into(), + )); + } + + let verified = crate::pair::select_label_candidates( + source, + crate::composition::AdmittedOpacityV1::OPAQUE, + physical_candidates, + order, + backdrop, + pair_requirement(floor), + ) + .map_err(|error| { + SolveFailure::InternalInvariant(format!( + "Pair joint selection failed after typed proposal admission: {error:?}" + )) + })?; + + if verified.fill_occurrence() != fill.occurrence() + || verified.fill_paint() != fill.paint() + || verified.label_occurrence().visible() != verified.label_paint().source().bytes() + { + return Err(SolveFailure::InternalInvariant( + "Pair joint evidence drifted from the selected physical chain".into(), + )); + } + + resolved_candidates + .into_iter() + .find(|(ordinal, _)| *ordinal == verified.ordinal()) + .map(|(_, resolved)| resolved) + .ok_or_else(|| { + SolveFailure::InternalInvariant( + "Pair selection returned an ordinal outside the proposal domain".into(), + ) + }) } /// Альфа-аналог: солид-цель `solid` (кодированный, по теме) на фоне резолва @@ -3299,7 +3337,13 @@ impl RoleSpec { )); } alpha("pair-label light surface alpha", surface_alpha_light)?; - alpha("pair-label dark surface alpha", surface_alpha_dark) + alpha("pair-label dark surface alpha", surface_alpha_dark)?; + if surface_alpha_light.to_bits() != 1.0_f64.to_bits() + || surface_alpha_dark.to_bits() != 1.0_f64.to_bits() + { + return Err("pair-label surface representation must be opaque after P1".into()); + } + Ok(()) } RoleSpec::Ladder { alpha_light, @@ -4496,6 +4540,7 @@ mod tests { pair(f64::NAN, 0.5, 0.5), pair(0.5, 0.0, 0.5), pair(0.5, 0.5, f64::INFINITY), + pair(0.5, 0.25, 1.0), ladder(0.0, 0.5), ladder(0.5, f64::NAN), ladder_with_floor(1.0, 1.0, Some(Floor::None)), @@ -4523,7 +4568,7 @@ mod tests { RoleSpec::DecorativeDj { magnitude_dj: DjMagnitude::new(1.0, 2.0), }, - pair(0.5, 0.25, 1.0), + pair(0.5, 1.0, 1.0), ladder(0.25, 1.0), ladder_with_floor(1.0, 1.0, Some(Floor::AaUi)), RoleSpec::AlphaAnalog { diff --git a/crates/labcolors-core/src/solve.rs b/crates/labcolors-core/src/solve.rs index 60e7c18b..ceaf0b2f 100644 --- a/crates/labcolors-core/src/solve.rs +++ b/crates/labcolors-core/src/solve.rs @@ -1340,18 +1340,6 @@ fn meets_floor(solved: &Solved, y_bg: f64, target: f64, _vc: &ViewingConditions) meets_floor_lc(lc, target) } -/// H-K-corrected luminance (`Y_hk`) of a linear-sRGB stimulus — воспринимаемая -/// ЯРКОСТЬ поверхности (Гельмгольц–Кольрауш, серый эквивалент `J_HK`). -/// -/// После ADR-0003 Ys candidate-score путь это НЕ читает: контракт -/// контраста, полы и recheck меряются в `Ys`. Потребители — яркостная ось: -/// выбор стороны внутренней pair-эвристики (`pair_side` — H-K-сдвиг кроссовера на -/// насыщенных фонах) и яркостные подсистемы. -pub(crate) fn bg_luma(rgb: [f64; 3], vc: &ViewingConditions) -> f64 { - let j_hk = lpc::j_hk_from_xyz(srgb_to_xyz(rgb), vc).max(0.0); - lpc::y_hk(j_hk, vc) -} - /// Test-only examined-candidate log (#297 local-search truth): both local /// searches (`solve`'s quantisation walk and `solve_dj`'s separation walk) /// record every on-grid candidate they actually materialize, so tests can diff --git a/crates/labcolors-core/tests/agnostic_production_surface.rs b/crates/labcolors-core/tests/agnostic_production_surface.rs index 1da80a09..bbf9d4bf 100644 --- a/crates/labcolors-core/tests/agnostic_production_surface.rs +++ b/crates/labcolors-core/tests/agnostic_production_surface.rs @@ -702,7 +702,7 @@ fn cfg_test_module_exclusion_covers_the_relocated_oracles() { // // WHY THE SIGNATURE, NOT BARE `DECLARED-CALIBRATION`: a `DECLARED-CALIBRATION` // marker alone is legitimate — a design-choice knob carries it (e.g. -// `PAIR_CROSSOVER_Y`), and a RETIRED threshold is still CITED in comments (the +// `HUE_DRIFT_PENALTY_SLOPE`), and a RETIRED threshold is still CITED in comments (the // removed M-03 light-escape). The forbidden class is specifically the // SINGLE-OBSERVER fit, whose provenance always carries `N=1` / // `single-observer` / `однонаблюдательск`. Keying on that signature makes the @@ -810,7 +810,7 @@ fn red_proof_observer_fit_scanner_is_silent_on_cfg_test_bare_calibration_and_loo // A bare DECLARED-CALIBRATION marker WITHOUT the single-observer signature is a // legitimate design-choice knob or a historical citation — must stay silent. - let bare = "// PAIR_CROSSOVER_Y is a DECLARED-CALIBRATION design choice\n\ + let bare = "// HUE_DRIFT_PENALTY_SLOPE is a DECLARED-CALIBRATION design choice\n\ // the former M-03 light-escape threshold (DECLARED-CALIBRATION) was removed\n"; assert!( single_observer_calibration_sites("probe.rs", bare).is_empty(), diff --git a/crates/labcolors-core/tests/data/labui_emission_golden.txt b/crates/labcolors-core/tests/data/labui_emission_golden.txt index 77cfafd1..30d0a3c3 100644 --- a/crates/labcolors-core/tests/data/labui_emission_golden.txt +++ b/crates/labcolors-core/tests/data/labui_emission_golden.txt @@ -91,11 +91,11 @@ srgb|#FFFFFF|label-danger=rgba(#FF3B30,1) srgb|#FFFFFF|border-accent=rgba(#007AFF,0.2) srgb|#FFFFFF|border-danger=rgba(#FF3B30,0.2) srgb|#FFFFFF|border-focus=rgba(#007AFF,1) -srgb|#FFFFFF|badge-fill-brand=rgba(#006FF3,1) -srgb|#FFFFFF|badge-fill-danger=rgba(#E71A16,1) +srgb|#FFFFFF|badge-fill-brand=rgba(#007AFF,1) +srgb|#FFFFFF|badge-fill-danger=rgba(#FF3B30,1) srgb|#FFFFFF|badge-fill-warning=rgba(#FFA100,1) srgb|#FFFFFF|badge-fill-success=rgba(#34C759,1) -srgb|#FFFFFF|badge-fill-info=rgba(#2770E6,1) +srgb|#FFFFFF|badge-fill-info=rgba(#3E87FF,1) srgb|#FFFFFF|badge-fill-static-dark=rgba(#101012,1) srgb|#FFFFFF|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#FFFFFF|fill-neutral-tinted->fill-primary @@ -198,11 +198,11 @@ srgb|#F2F2F7|label-danger=rgba(#FF3B30,1) srgb|#F2F2F7|border-accent=rgba(#007AFF,0.2) srgb|#F2F2F7|border-danger=rgba(#FF3B30,0.2) srgb|#F2F2F7|border-focus=rgba(#007AFF,1) -srgb|#F2F2F7|badge-fill-brand=rgba(#006FF3,1) -srgb|#F2F2F7|badge-fill-danger=rgba(#E71A16,1) +srgb|#F2F2F7|badge-fill-brand=rgba(#007AFF,1) +srgb|#F2F2F7|badge-fill-danger=rgba(#FF3B30,1) srgb|#F2F2F7|badge-fill-warning=rgba(#FFA100,1) srgb|#F2F2F7|badge-fill-success=rgba(#34C759,1) -srgb|#F2F2F7|badge-fill-info=rgba(#2770E6,1) +srgb|#F2F2F7|badge-fill-info=rgba(#3E87FF,1) srgb|#F2F2F7|badge-fill-static-dark=rgba(#101012,1) srgb|#F2F2F7|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#F2F2F7|fill-neutral-tinted->fill-primary @@ -305,11 +305,11 @@ srgb|#7F7F7F|label-danger=rgba(#FF3B30,1) srgb|#7F7F7F|border-accent=rgba(#007AFF,0.2) srgb|#7F7F7F|border-danger=rgba(#FF3B30,0.2) srgb|#7F7F7F|border-focus=rgba(#007AFF,1) -srgb|#7F7F7F|badge-fill-brand=rgba(#006FF3,1) -srgb|#7F7F7F|badge-fill-danger=rgba(#E71A16,1) +srgb|#7F7F7F|badge-fill-brand=rgba(#007AFF,1) +srgb|#7F7F7F|badge-fill-danger=rgba(#FF3B30,1) srgb|#7F7F7F|badge-fill-warning=rgba(#FFA100,1) srgb|#7F7F7F|badge-fill-success=rgba(#34C759,1) -srgb|#7F7F7F|badge-fill-info=rgba(#2770E6,1) +srgb|#7F7F7F|badge-fill-info=rgba(#3E87FF,1) srgb|#7F7F7F|badge-fill-static-dark=rgba(#101012,1) srgb|#7F7F7F|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#7F7F7F|fill-neutral-tinted->fill-primary @@ -412,11 +412,11 @@ srgb|#1C1C1E|label-danger=rgba(#FF3B30,1) srgb|#1C1C1E|border-accent=rgba(#007AFF,0.2) srgb|#1C1C1E|border-danger=rgba(#FF3B30,0.2) srgb|#1C1C1E|border-focus=rgba(#007AFF,1) -srgb|#1C1C1E|badge-fill-brand=rgba(#006FF3,1) -srgb|#1C1C1E|badge-fill-danger=rgba(#E71A16,1) +srgb|#1C1C1E|badge-fill-brand=rgba(#007AFF,1) +srgb|#1C1C1E|badge-fill-danger=rgba(#FF3B30,1) srgb|#1C1C1E|badge-fill-warning=rgba(#FFA100,1) srgb|#1C1C1E|badge-fill-success=rgba(#34C759,1) -srgb|#1C1C1E|badge-fill-info=rgba(#2770E6,1) +srgb|#1C1C1E|badge-fill-info=rgba(#3E87FF,1) srgb|#1C1C1E|badge-fill-static-dark=rgba(#101012,1) srgb|#1C1C1E|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#1C1C1E|fill-neutral-tinted->fill-primary @@ -519,11 +519,11 @@ srgb|#101012|label-danger=rgba(#FF3B30,1) srgb|#101012|border-accent=rgba(#007AFF,0.2) srgb|#101012|border-danger=rgba(#FF3B30,0.2) srgb|#101012|border-focus=rgba(#007AFF,1) -srgb|#101012|badge-fill-brand=rgba(#006FF3,1) -srgb|#101012|badge-fill-danger=rgba(#E71A16,1) +srgb|#101012|badge-fill-brand=rgba(#007AFF,1) +srgb|#101012|badge-fill-danger=rgba(#FF3B30,1) srgb|#101012|badge-fill-warning=rgba(#FFA100,1) srgb|#101012|badge-fill-success=rgba(#34C759,1) -srgb|#101012|badge-fill-info=rgba(#2770E6,1) +srgb|#101012|badge-fill-info=rgba(#3E87FF,1) srgb|#101012|badge-fill-static-dark=rgba(#101012,1) srgb|#101012|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#101012|fill-neutral-tinted->fill-primary @@ -626,11 +626,11 @@ srgb|#3478F6|label-danger=rgba(#FF3B30,1) srgb|#3478F6|border-accent=rgba(#007AFF,0.2) srgb|#3478F6|border-danger=rgba(#FF3B30,0.2) srgb|#3478F6|border-focus=rgba(#007AFF,1) -srgb|#3478F6|badge-fill-brand=rgba(#006FF3,1) -srgb|#3478F6|badge-fill-danger=rgba(#E71A16,1) +srgb|#3478F6|badge-fill-brand=rgba(#007AFF,1) +srgb|#3478F6|badge-fill-danger=rgba(#FF3B30,1) srgb|#3478F6|badge-fill-warning=rgba(#FFA100,1) srgb|#3478F6|badge-fill-success=rgba(#34C759,1) -srgb|#3478F6|badge-fill-info=rgba(#2770E6,1) +srgb|#3478F6|badge-fill-info=rgba(#3E87FF,1) srgb|#3478F6|badge-fill-static-dark=rgba(#101012,1) srgb|#3478F6|badge-fill-static-light=rgba(#FFFFFF,1) srgb|#3478F6|fill-neutral-tinted->fill-primary @@ -733,11 +733,11 @@ dim|#FFFFFF|label-danger=rgba(#FF3A3A,1) dim|#FFFFFF|border-accent=rgba(#4A8FFF,0.2) dim|#FFFFFF|border-danger=rgba(#FF3A3A,0.2) dim|#FFFFFF|border-focus=rgba(#4A8FFF,1) -dim|#FFFFFF|badge-fill-brand=rgba(#2D71DF,1) -dim|#FFFFFF|badge-fill-danger=rgba(#E71824,1) +dim|#FFFFFF|badge-fill-brand=rgba(#4A8FFF,1) +dim|#FFFFFF|badge-fill-danger=rgba(#FF3A3A,1) dim|#FFFFFF|badge-fill-warning=rgba(#FF9008,1) dim|#FFFFFF|badge-fill-success=rgba(#30D158,1) -dim|#FFFFFF|badge-fill-info=rgba(#3472D8,1) +dim|#FFFFFF|badge-fill-info=rgba(#5696FF,1) dim|#FFFFFF|badge-fill-static-dark=rgba(#101012,1) dim|#FFFFFF|badge-fill-static-light=rgba(#FFFFFF,1) dim|#FFFFFF|fill-neutral-tinted->fill-primary @@ -840,11 +840,11 @@ dim|#F2F2F7|label-danger=rgba(#FF3A3A,1) dim|#F2F2F7|border-accent=rgba(#4A8FFF,0.2) dim|#F2F2F7|border-danger=rgba(#FF3A3A,0.2) dim|#F2F2F7|border-focus=rgba(#4A8FFF,1) -dim|#F2F2F7|badge-fill-brand=rgba(#2D71DF,1) -dim|#F2F2F7|badge-fill-danger=rgba(#E71824,1) +dim|#F2F2F7|badge-fill-brand=rgba(#4A8FFF,1) +dim|#F2F2F7|badge-fill-danger=rgba(#FF3A3A,1) dim|#F2F2F7|badge-fill-warning=rgba(#FF9008,1) dim|#F2F2F7|badge-fill-success=rgba(#30D158,1) -dim|#F2F2F7|badge-fill-info=rgba(#3472D8,1) +dim|#F2F2F7|badge-fill-info=rgba(#5696FF,1) dim|#F2F2F7|badge-fill-static-dark=rgba(#101012,1) dim|#F2F2F7|badge-fill-static-light=rgba(#FFFFFF,1) dim|#F2F2F7|fill-neutral-tinted->fill-primary @@ -947,11 +947,11 @@ dim|#7F7F7F|label-danger=rgba(#FF3A3A,1) dim|#7F7F7F|border-accent=rgba(#4A8FFF,0.2) dim|#7F7F7F|border-danger=rgba(#FF3A3A,0.2) dim|#7F7F7F|border-focus=rgba(#4A8FFF,1) -dim|#7F7F7F|badge-fill-brand=rgba(#2D71DF,1) -dim|#7F7F7F|badge-fill-danger=rgba(#E71824,1) +dim|#7F7F7F|badge-fill-brand=rgba(#4A8FFF,1) +dim|#7F7F7F|badge-fill-danger=rgba(#FF3A3A,1) dim|#7F7F7F|badge-fill-warning=rgba(#FF9008,1) dim|#7F7F7F|badge-fill-success=rgba(#30D158,1) -dim|#7F7F7F|badge-fill-info=rgba(#3472D8,1) +dim|#7F7F7F|badge-fill-info=rgba(#5696FF,1) dim|#7F7F7F|badge-fill-static-dark=rgba(#101012,1) dim|#7F7F7F|badge-fill-static-light=rgba(#FFFFFF,1) dim|#7F7F7F|fill-neutral-tinted->fill-primary @@ -1054,11 +1054,11 @@ dim|#1C1C1E|label-danger=rgba(#FF3A3A,1) dim|#1C1C1E|border-accent=rgba(#4A8FFF,0.2) dim|#1C1C1E|border-danger=rgba(#FF3A3A,0.2) dim|#1C1C1E|border-focus=rgba(#4A8FFF,1) -dim|#1C1C1E|badge-fill-brand=rgba(#2D71DF,1) -dim|#1C1C1E|badge-fill-danger=rgba(#E71824,1) +dim|#1C1C1E|badge-fill-brand=rgba(#4A8FFF,1) +dim|#1C1C1E|badge-fill-danger=rgba(#FF3A3A,1) dim|#1C1C1E|badge-fill-warning=rgba(#FF9008,1) dim|#1C1C1E|badge-fill-success=rgba(#30D158,1) -dim|#1C1C1E|badge-fill-info=rgba(#3472D8,1) +dim|#1C1C1E|badge-fill-info=rgba(#5696FF,1) dim|#1C1C1E|badge-fill-static-dark=rgba(#101012,1) dim|#1C1C1E|badge-fill-static-light=rgba(#FFFFFF,1) dim|#1C1C1E|fill-neutral-tinted->fill-primary @@ -1161,11 +1161,11 @@ dim|#101012|label-danger=rgba(#FF3A3A,1) dim|#101012|border-accent=rgba(#4A8FFF,0.2) dim|#101012|border-danger=rgba(#FF3A3A,0.2) dim|#101012|border-focus=rgba(#4A8FFF,1) -dim|#101012|badge-fill-brand=rgba(#2D71DF,1) -dim|#101012|badge-fill-danger=rgba(#E71824,1) +dim|#101012|badge-fill-brand=rgba(#4A8FFF,1) +dim|#101012|badge-fill-danger=rgba(#FF3A3A,1) dim|#101012|badge-fill-warning=rgba(#FF9008,1) dim|#101012|badge-fill-success=rgba(#30D158,1) -dim|#101012|badge-fill-info=rgba(#3472D8,1) +dim|#101012|badge-fill-info=rgba(#5696FF,1) dim|#101012|badge-fill-static-dark=rgba(#101012,1) dim|#101012|badge-fill-static-light=rgba(#FFFFFF,1) dim|#101012|fill-neutral-tinted->fill-primary @@ -1268,11 +1268,11 @@ dim|#3478F6|label-danger=rgba(#FF3A3A,1) dim|#3478F6|border-accent=rgba(#4A8FFF,0.2) dim|#3478F6|border-danger=rgba(#FF3A3A,0.2) dim|#3478F6|border-focus=rgba(#4A8FFF,1) -dim|#3478F6|badge-fill-brand=rgba(#2D71DF,1) -dim|#3478F6|badge-fill-danger=rgba(#E71824,1) +dim|#3478F6|badge-fill-brand=rgba(#4A8FFF,1) +dim|#3478F6|badge-fill-danger=rgba(#FF3A3A,1) dim|#3478F6|badge-fill-warning=rgba(#FF9008,1) dim|#3478F6|badge-fill-success=rgba(#30D158,1) -dim|#3478F6|badge-fill-info=rgba(#3472D8,1) +dim|#3478F6|badge-fill-info=rgba(#5696FF,1) dim|#3478F6|badge-fill-static-dark=rgba(#101012,1) dim|#3478F6|badge-fill-static-light=rgba(#FFFFFF,1) dim|#3478F6|fill-neutral-tinted->fill-primary diff --git a/crates/labcolors-core/tests/empirical_inventory.rs b/crates/labcolors-core/tests/empirical_inventory.rs index 491b1589..9ea9deba 100644 --- a/crates/labcolors-core/tests/empirical_inventory.rs +++ b/crates/labcolors-core/tests/empirical_inventory.rs @@ -36,7 +36,7 @@ use common::source::{ProductionLine, production_records, production_syntax_lines // Audit surface — the perceptual modules the detector scans. // ───────────────────────────────────────────────────────────────────────────── -const PERCEPTUAL_MODULES: [&str; 8] = [ +const PERCEPTUAL_MODULES: [&str; 7] = [ "semantic.rs", "scale.rs", "spaces/oklab.rs", @@ -44,9 +44,6 @@ const PERCEPTUAL_MODULES: [&str; 8] = [ "lpc.rs", "lcs.rs", "solve.rs", - // Added for the honest-reclassification wave: `pair.rs` carries the tunable - // policy const `PAIR_CROSSOVER_Y` (row 52) — now under GATE-1/2/3. - "pair.rs", ]; // ───────────────────────────────────────────────────────────────────────────── @@ -58,27 +55,12 @@ const PERCEPTUAL_MODULES: [&str; 8] = [ // (0.968/0.627/0.461/0.276) and the Separator Lc (8.0) evaded GATE-1 until they // were extracted. The const-only detector (GATE-1/2/3) is blind to inline literals. // -// Why a SUBSET: the three modules below are POLICY modules — their magnitudes are -// tunable perceptual policy (role fractions and curve thresholds). The remaining -// modules (`scale.rs`, `spaces/oklab.rs`, `lpc.rs`, `lcs.rs`, `solve.rs`) are -// STANDARD-MODEL -// transform modules: their inline coefficients implement cited colour-appearance -// models verbatim — CIECAM16 (`460/451/288/6300/1403…` in `lcs.rs`), the Hellwig -// 2022 H-K first-harmonic (`0.080/0.132/0.160/0.405/0.792` in `lpc.rs`), the CAM16 -// non-linearity (`27.13/400.0/0.42`), and the J′ compression / cubic solver in -// `scale.rs`. Those are NOT tunable policy; flagging them as "magic numbers" would -// be a false claim (their tunable policy already lives in NAMED consts: -// `HUE_SEARCH_HALF_WINDOW`, `HUE_DRIFT_PENALTY_SLOPE`, the APCA `SOFT_CLAMP_*`/`EXP_*` -// set — all GATE-1/2 covered). `solve.rs` (added to `PERCEPTUAL_MODULES` for its -// const budgets) is likewise a quantisation-search transform, so it too stays out -// of the bare-literal surface. `pair.rs` IS scanned for inline literals: it carries a -// genuine tunable policy const (`PAIR_CROSSOVER_Y`), so it is a POLICY module. Its only -// non-policy inline floats were the ITU-R BT.709 / WCAG relative-luminance coefficients -// (`0.2126/0.7152/0.0722`), now extracted into the `WCAG_LUMA_{R,G,B}` consts on -// `NUMERIC_METHOD_ALLOWLIST` (a cited standard, excluded by construction — INV-3). -// Every module in `PERCEPTUAL_MODULES` remains under the const-marker gate; the three -// POLICY modules below are additionally scanned for inline bare literals. -const POLICY_LITERAL_MODULES: &[&str] = &["semantic.rs", "neutral.rs", "pair.rs"]; +// Why a SUBSET: the two modules below are POLICY modules — their magnitudes are +// tunable perceptual policy (role fractions and neutral thresholds). The remaining +// modules are STANDARD-MODEL or bounded numeric-search transforms. Pair after P1 +// contains only typed topology/lowering and no perceptual policy constants, so it +// is intentionally outside both inventory scan surfaces. +const POLICY_LITERAL_MODULES: &[&str] = &["semantic.rs", "neutral.rs"]; /// Bare float literal VALUES that are NOT tunable perceptual policy — universal /// domain/normalisation/degenerate/sentinel/numerical arithmetic, plus cited @@ -135,18 +117,6 @@ const NUMERIC_METHOD_ALLOWLIST: &[&str] = &[ "PROBE", // Derived from a WCAG standard ratio, not an independent policy literal. "POLARITY_FLOOR_RATIO", - // Derivation-identity from the WCAG strict-win contrast formula - // ((Y+0.05)² vs 1.05·0.05 ⇒ Y = 0.17913), rounded conservatively — the pair - // polarity crossover BOUNDARY, not an independent tunable policy literal - // (same class as `POLARITY_FLOOR_RATIO`). Provenance in pair.rs rustdoc (pair.rs). - "WHITE_WINS_Y", - "BLACK_WINS_Y", - // ITU-R BT.709 / WCAG 2.x relative-luminance coefficients (Rec.709 luma) — - // a cited standard, extracted from inline literals in `wcag_y_encoded` so - // pair.rs passes GATE-5 with no undeclared bare numbers (pair.rs; values unchanged). - "WCAG_LUMA_R", - "WCAG_LUMA_G", - "WCAG_LUMA_B", ]; /// Known standard *names* that must NEVER appear as an inventory row — the diff --git a/docs/decisions/0003-hk-scope.md b/docs/decisions/0003-hk-scope.md index fd4a589f..7486fb14 100644 --- a/docs/decisions/0003-hk-scope.md +++ b/docs/decisions/0003-hk-scope.md @@ -16,9 +16,8 @@ LPC/readability verdict; - H-K сохраняется во внутренней appearance-математике и её характеризации; - brightness-matching семейных цветов сохраняет H-K; -- внутренний `pair_side` использует `Ys`-кривую и H-K appearance-координату в - разных членах своей переходной эвристики. Ни одна из них не выдаётся за - универсальную модель разборчивости. +- Pair после P1 не имеет собственного brightness/readability закона: его + occurrences проверяются общими evaluator-ами в их объявленных доменах. ## Почему diff --git a/docs/empirical-inventory.md b/docs/empirical-inventory.md index 75f934a2..f9a46eff 100644 --- a/docs/empirical-inventory.md +++ b/docs/empirical-inventory.md @@ -36,13 +36,12 @@ Terminal classes описывают, почему число может нахо | 34 | `LO_WOB_OFFSET` | `0.027` | `lpc.rs` | GROUNDED | APCA SAPC-8 `0.0.98G-4g` published set. | | 35 | `IC_DECORATIVE_FLOOR_MIN` | `15.0` | `semantic.rs` | GROUNDED | **(b) GROUNDED** — опубликованный APCA-уровень **Lc 15**: «absolute minimum for any non-text that needs to be discernible», точка невидимости ниже неё (APCA project docs, Somers/Myndex: git.apcacontrast.com `WhyAPCA` + `APCA_in_a_Nutshell`). ⚠️ Провенанс честен: DRAFT/beta, single-origin (apca-w3 0.1.9 beta) — черновиковый дизайн-уровень, **НЕ норматив WCAG 3** и не независимое психофизическое измерение. Наш декоративный `-ic`-пол — ровно этот случай: минимальный различимый не-текстовый контраст. Применяется порядкосохраняющим равномерным сдвигом `+7.5` (= 15 − 7.5) поверх обычного пола, НЕ как `max`: max(m, 15.0) схлопывал весь стек теней (8/9.5/11.5/14) и сепаратор в один идентичный цвет под `-ic`, нарушая строго-возрастающий контракт стека и молча мутируя измеренные Lc-зазоры. Локи: `ic_floor_is_apca_lc15_with_order_preserving_shift`, `shadow_stack_is_strictly_ascending_under_increased_contrast`. | | 36 | `HUE_SEARCH_HALF_WINDOW` | `30.0` | `scale.rs` | SSOT-TRACKED | **(c) INTERVAL-INSENSITIVE** (ре-аудит `science/reclassify-e-buckets`, 2026-07-07; ранее (e)) — Half-width (degrees) of the hue search window in `find_optimal_hue`; 30° spans the typical sRGB gamut ridge width around the canonical hue. **Доказательство:** при продакшн-наклоне интерьерный оптимум НЕ касается ребра окна ни на одном из 43 хроматических якорей 49-якорного паспорта labui (см. замер строки 37 / `derivation_rejection_locks::chord_derived_slope_rejected_degenerates_to_window_edge`, база-наклон 0 прижатий) — окно нежёсткая нижняя граница, не связывающий кап. **Экспозиция:** 0.93% (l,hue)-сетки, где точное окно (свип [25°,45°]) меняет выбранный оттенок (`scale::exposure_locks::exposure_hue_search_window`). Сравни с `CUSP_HALF_WINDOW_DEG` (строка 17, семантически похожая ручка, но ДОКАЗАННО связывающая — там (c) не применим). | -| 37 | `HUE_DRIFT_PENALTY_SLOPE` | `0.15` | `scale.rs` | SSOT-TRACKED | **(e) DESIGN-CHOICE** — наклон штрафа дрейфа оттенка в `find_optimal_hue` (`penalty_scale = slope/half_window`, `score = c − penalty_scale·drift`): баланс «максимум хромы против ухода от канонического оттенка». Ранее жил незадекларированным поле-литералом (найден инвентарём конфиг-границы 2026-07-02). **Строгий кандидат-вывод:** перцептивная цена дрейфа = длина хорды Oklab `2·C·sin(Δh/2) ≈ C·Δh·π/180` при малых Δh, откуда теоретический `penalty_scale = C·π/180 ≈ 0.0026–0.0035/°` при C≈0.15–0.20 — против текущего `slope/half_window = 0.15/30 = 0.005/°`. **Разрешение (2026-07-06): хордовый кандидат ОТКЛОНЁН по замеру.** На 49-якорном замороженном паспорте labui (l-сетка 0.05–0.95, шаг 0.01) прод-наклон держит интерьерный оптимум на всех 43 хроматических якорях (0 прижатий к ребру), а `penalty_scale = C·π/180` прижимает оптимум к ребру окна ±30° на 12/43 якорях (флип >0.5° на 27/43, ΔE_ok до 0.077) — т.е. передаёт решение произвольной границе `HUE_SEARCH_HALF_WINDOW`, делая интервально-нечувствительную константу окна чувствительной: анти-объективизация. Терминал (e) DESIGN-CHOICE (терминальная таксономия 2026-07-07): свободная ручка, якорь — ИЗМЕРЕННОЕ отклонение строгого кандидата (выше); интервал свипа [0.10, 0.20], экспозиция 14.29% гаммы (`exposure_hue_drift_penalty_slope`); значение 0.15 не меняется (INV-1). Замок: `derivation_rejection_locks::chord_derived_slope_rejected_degenerates_to_window_edge`. **MODEL-CONFLICT: ИЗМЕРЕН И ОТКЛОНЁН** (ре-аудит 2026-07-07) — единственный строгий кандидат-вывод уже проверен и признан хуже shipped 0.15 (вырождение в клип по ребру окна); вопрос закрыт замером, владельцу решать нечего (как и `PAIR_CROSSOVER_Y`, строка 52, разрешён деривацией → (a)). | +| 37 | `HUE_DRIFT_PENALTY_SLOPE` | `0.15` | `scale.rs` | SSOT-TRACKED | **(e) DESIGN-CHOICE** — наклон штрафа дрейфа оттенка в `find_optimal_hue` (`penalty_scale = slope/half_window`, `score = c − penalty_scale·drift`): баланс «максимум хромы против ухода от канонического оттенка». Ранее жил незадекларированным поле-литералом (найден инвентарём конфиг-границы 2026-07-02). **Строгий кандидат-вывод:** перцептивная цена дрейфа = длина хорды Oklab `2·C·sin(Δh/2) ≈ C·Δh·π/180` при малых Δh, откуда теоретический `penalty_scale = C·π/180 ≈ 0.0026–0.0035/°` при C≈0.15–0.20 — против текущего `slope/half_window = 0.15/30 = 0.005/°`. **Разрешение (2026-07-06): хордовый кандидат ОТКЛОНЁН по замеру.** На 49-якорном замороженном паспорте labui (l-сетка 0.05–0.95, шаг 0.01) прод-наклон держит интерьерный оптимум на всех 43 хроматических якорях (0 прижатий к ребру), а `penalty_scale = C·π/180` прижимает оптимум к ребру окна ±30° на 12/43 якорях (флип >0.5° на 27/43, ΔE_ok до 0.077) — т.е. передаёт решение произвольной границе `HUE_SEARCH_HALF_WINDOW`, делая интервально-нечувствительную константу окна чувствительной: анти-объективизация. Терминал (e) DESIGN-CHOICE (терминальная таксономия 2026-07-07): свободная ручка, якорь — ИЗМЕРЕННОЕ отклонение строгого кандидата (выше); интервал свипа [0.10, 0.20], экспозиция 14.29% гаммы (`exposure_hue_drift_penalty_slope`); значение 0.15 не меняется (INV-1). Замок: `derivation_rejection_locks::chord_derived_slope_rejected_degenerates_to_window_edge`. **MODEL-CONFLICT: ИЗМЕРЕН И ОТКЛОНЁН** (ре-аудит 2026-07-07) — единственный строгий кандидат-вывод уже проверен и признан хуже shipped 0.15 (вырождение в клип по ребру окна); вопрос закрыт замером, владельцу решать нечего. | | 47 | `ACHROMATIC_MP_THRESHOLD` | `5.0` | `neutral.rs` | SSOT-TRACKED | **(c) INTERVAL-INSENSITIVE** (ре-аудит `science/reclassify-e-buckets`, 2026-07-07; ранее (e)) — Порог M' (CAM16-UCS) ахроматичности якоря: CAM16 даёт ненулевой M' даже для номинально ахроматических стимулов (≈1.5 белый, ≈2.3 near-black); 5.0 ловит модельный шум, сохраняя хроматические якоря. **Доказательство:** порог сидит в ШИРОКОМ пустом зазоре между потолком ахроматического M'-шума серых и полом хромы подлинно цветных якорей — партиция achromatic↔chromatic ИНВАРИАНТНА для любого θ в этом зазоре (`neutral::exposure_locks::achromatic_threshold_sits_in_empty_noise_to_chroma_gap`). **Экспозиция:** 1.99% гаммы (`exposure_achromatic_mp_threshold`); 4 нейтрали labui (3C3C43, 787880, B0B0B9, F6F8FA) — подстановка штатна, не флип-риск. | | 48 | `HUE_PURITY_MP_REF_RATIO` | `1.5` | `neutral.rs` | SSOT-TRACKED | **(e) DESIGN-CHOICE** — множитель опорной хромы (`mp_ref = 1.5 × M'` базы) для нормировки чистоты оттенка. Магнитуда — свободная ручка (опубликованного значения не существует; фит к данным Abney дал бы ДРУГУЮ кривую, поэтому выдавать её за (b) запрещает научная таксономия репозитория). Робастность доказана: хроматические якоря (mp ≥ mp_ref) дают purity = 1 при ЛЮБОМ значении (инвариантны), константа двигает лишь оттенок near-нейтралей, который и так atan2-шум. Терминал закрыт декларацией (решение владельца 2026-07-07, таксономия (a)/(b)/(e)); конфиг-экспорт ручки — вне зоны миссии (flagged follow-up). Пара к строке 49; провенанс ФОРМЫ — там же. Локи: `hue_purity_curve_shape_is_pinned`, `exposure_hue_purity_curve`. | | 49 | `HUE_PURITY_EXPONENT` | `0.6` | `neutral.rs` | SSOT-TRACKED | **(e) DESIGN-CHOICE** — показатель кривой чистоты `(mp/mp_ref)^0.6`. Магнитуда — свободная ручка. ПРОВЕНАНС ФОРМЫ (не значения): «не доверяй тону у нейтрали» мотивировано двумя сходящимися причинами — численной (atan2 ill-conditioned у серой оси, оттенок near-серых из шума) и перцептивной (эффект Abney: тон монохроматического стимула сдвигается при разбавлении белым — Abney 1909 Proc. R. Soc. Lond. A 83, 120–127, DOI 10.1098/rspa.1909.0085; сдвиг растёт с падением колориметрической чистоты — Kurtenbach-Sternheim-Spillmann 1984 JOSA A 1(4), 365–372, DOI 10.1364/JOSAA.1.000365; обе цитаты перепроверены живьём 2026-07-07: DOI резолвятся, реквизиты совпадают). ⚠️ Перцептивный Abney ОТДЕЛЕН от численного atan2-шума; 0.6/1.5 НЕ выведены из данных Abney (эта кривая эффект Abney не моделирует, issue #27) — поэтому честный терминал (e), не (b). Робастность: хроматические якоря инвариантны (purity = 1 при mp ≥ mp_ref); свип показателя [0.4, 0.9] — max\|Δpurity\| = 0.148 только у near-нейтралей (непрерывный дрейф, не флип). Терминал закрыт декларацией (2026-07-07). Локи: `hue_purity_curve_shape_is_pinned`, `exposure_hue_purity_curve`. | | 50 | `QUANT_BUDGET` | `1.0` | `solve.rs` | SSOT-TRACKED | **(c) INTERVAL-INSENSITIVE** (ре-аудит `science/reclassify-e-buckets`, 2026-07-07; ранее (e)) — Допуск приёмки Lc квант-солвера в единицах шага выходной сетки: цвет принят, когда измеренный Lc в пределах ±QUANT_BUDGET от цели. Замер: медианный Lc-шаг одного 8-бит кванта серых ≈0.44 (максимум ≈7.85 — обрыв мягкого клампа APCA, не шаг сетки); 1.0 Lc ≈ 2.3× типичного шага — контракт «±1 Lc» (`quant_budget_is_a_couple_of_grid_steps`). **Экспозиция:** 1.84% целей флипают приёмку при свипе ±50% (`exposure_quant_and_dj_budgets`) — дискретность 8-бит сетки поглощает почти весь свип. | | 51 | `DJ_BUDGET` | `0.6` | `solve.rs` | SSOT-TRACKED | **(c) INTERVAL-INSENSITIVE** (ре-аудит `science/reclassify-e-buckets`, 2026-07-07; ранее (e)) — Допуск приёмки dJ' декоративного солвера (J'-единицы CAM16-UCS), dJ'-аналог `QUANT_BUDGET`. Замер: медианный dJ'-шаг 8-бит кванта серых ≈0.39; 0.6 J' ≈ 1.5× типичного шага — чуть больше одного шага сетки (`dj_budget_tracks_grid_step`). **Экспозиция:** 1.55% (`exposure_quant_and_dj_budgets`). | -| 52 | `PAIR_CROSSOVER_Y` | `0.341955` | `pair.rs` | SSOT-TRACKED | **(a) DERIVED** — Y-порог кроссовера переходной pair-эвристики. **Вывод:** корень равенства модулей двух ветвей замороженной SAPC-shaped кривой для чёрного и белого foreground; бисекция на `[0.2, 0.6]` даёт **0.341955**. Это математическое свойство frozen Ys candidate-score функции, не LPC/readability optimum и не психофизический закон. Пиннится ре-деривацией `pair_crossover_equals_measured_core_polarity_flip`. Значение лежит внутри пустого интервала 10 Figma-якорей `(0.246, 0.423)`, поэтому смена прежнего 0.30 байт-идентична на этом наборе; экспозиция вне набора — 21.69% (`exposure_pair_crossover`). H-K в этот порог не входит (ADR-0003). Сосед `WHITE_WINS_Y = 0.179` — отдельная граница двойной законности WCAG. | | 53 | `QUANT_GUARD` | `0.2` | `semantic.rs` | SSOT-TRACKED | **(c) INTERVAL-INSENSITIVE** (ре-аудит `science/reclassify-e-buckets`, 2026-07-07; ранее (e)) — квант-guard над `MODEL_LC_FLOOR` (7.3): зазор `DECORATIVE_FLOOR_MIN − MODEL_LC_FLOOR`, держащий декоративный пол строго выше 7.3, чтобы решатель не садился на инфимум клипа и не возвращал нулевой контраст (issue #44). **Доказательство сильнее обычного (c):** `QUANT_GUARD` НЕ используется в продакшене НЕЗАВИСИМО — единственная величина, которую видит решатель, это байт-идентичный литерал `DECORATIVE_FLOOR_MIN` (7.5); guard существует только как провенанс-разложение этого литерала на DERIVED-член (7.3) и задекларированный запас (лок `decorative_floor_is_model_floor_plus_guard`, компайл-тайм `const _`). Замер (`no_pair_emits_contrast_below_model_floor`, скан квантованных пар): фактический минимальный ненулевой контраст = **7.3005** (сидит 0.0005 над модельным инфимумом 7.3, а не у номинальной цели 7.5) — скачок |Lc| одного 8-бит шага у клипа = **7.85** (жёсткий разрыв, guard не покрывает и не должен). Пока guard положителен и цель остаётся достижимой в пределах `QUANT_BUDGET` = 1.0, точная магнитуда 0.2 не меняет ни одного реального эмитируемого контраста; доминантный член 7.3 остаётся DERIVED. | | 54 | `MODEL_LC_FLOOR` | `7.3` | `lpc.rs` | SSOT-TRACKED | **(a) DERIVED** = (LO_CLIP − LO_BOW_OFFSET) × LC_SCALE = (0.1 − 0.027) × 100 = 7.3 — минимальный ненулевой контраст модели (за низкоконтрастным клипом `contrast_core` стартует ровно с него, внутри клипа — ноль; полярности симметричны, `LO_WOB_OFFSET == LO_BOW_OFFSET`). Алгебраическая идентичность из GROUNDED APCA `0.0.98G-4g` набора; хранится литералом 7.3 (чистое число для инвентаря), тождество с формулой пиннится `model_lc_floor_is_the_published_clip_minimum` (дрейф любого из трёх APCA-входов или правка литерала ломает лок). Опора `DECORATIVE_FLOOR_MIN` (строка 1), issue #44. | diff --git a/docs/whitepaper.md b/docs/whitepaper.md index 0f846eed..63eeedd3 100644 --- a/docs/whitepaper.md +++ b/docs/whitepaper.md @@ -79,8 +79,8 @@ fingerprint считается по распарсенной поддержив | `DecorativeLc` | декоративная контрастная величина без нормативного текстового смысла | | `Ladder` | якорь источника при alpha закрытой позиции | | `AlphaAnalog` | прозрачная форма объявленной solid-цели на локальном фоне | -| `PairFill` | solid-поверхность, сдвинутая до выбранной стороны foreground | -| `PairLabel` | foreground против объявленной derived tint-поверхности | +| `PairFill` | frozen frontend: exact authored source как opaque Paint/Occurrence | +| `PairLabel` | finite label candidate domain против фактически emitted PairFill Surface | | `Material` | точечная двухслойная композиция с выведенной alpha | | `Glow` | точечные screen-слои с явным numerical profile | | `Zero` | явное отсутствие цветового значения | @@ -108,9 +108,11 @@ point-пути scratch принадлежит caller-у и размещён на compiler-а проверяется тестом. Compiler принадлежит proof-поверхности и отсутствует в production-артефакте. -`PairLabel` использует эту поверхность как фон; role-resolver возвращает цвет -метки как `Resolved::Color`. Этот контракт не содержит label Paint/occurrence, -client-authored topology или скрытых зависимостей по имени токена. +`PairLabel` использует фактически emitted `PairFill` occurrence как derived +Surface. Frontend формирует конечный label candidate domain; общий joint engine +исполняет `fill → surfaceFrom → label`, строит полный hard-report, выбирает по +явному total order и повторяет fresh recheck. Имена клиентских токенов и +`FillPrimary` в physical lowering не участвуют. Публичный API не принимает произвольный client-authored graph. `NamedRoleTable` остаётся boundary-представлением и не служит extension point для новых доменных diff --git a/packages/colors/bench/wasm.json b/packages/colors/bench/wasm.json index a86a8338..39bea3e9 100644 --- a/packages/colors/bench/wasm.json +++ b/packages/colors/bench/wasm.json @@ -19,13 +19,13 @@ "command": "CARGO_ENCODED_RUSTFLAGS= wasm-pack build crates/labcolors-wasm --release --target web --out-dir ../../packages/colors/pkg --out-name labcolors --locked" }, "measurement": { - "source": "github-actions-run-29716449361", + "source": "github-actions-run-29797754817", "platform": "linux-x64", - "rawBytes": 386547 + "rawBytes": 421876 }, "policy": { - "maxRawBytes": 386547, - "basis": "v1b-after-docs-exact-head", + "maxRawBytes": 421876, + "basis": "p1-pair-joint-lowering", "gzip": "diagnostic-only" } } diff --git a/packages/colors/test/wasm-boundary.golden.json b/packages/colors/test/wasm-boundary.golden.json index ec0f7408..40188b7d 100644 --- a/packages/colors/test/wasm-boundary.golden.json +++ b/packages/colors/test/wasm-boundary.golden.json @@ -1 +1 @@ -{"_meta":{"purpose":"Байт-точный golden границы JS↔WASM: recheckContrast/_recheckContrastMulti и полный snapshot resolveTheme.vars.","regenerated":"2026-07-10","regen_reason":"ADR-0004: point-glow решается по конечным encoded-sRGB8 screen-state; alpha эмитируется кратчайшей decimal-записью без повторного округления.","drift_scope":"Относительно origin/main изменены ровно 24 листа resolveVars: только --lab-fx-glow-{brand,danger,warning,neutral}-alpha на 6 фонах. Ни один base/core, label, border, fill, background или другой var не изменён.","recheck_unchanged":"Секция recheck: 2752/2752 числовых значений, то есть 1376/1376 пар (lc, wcag), байт-идентичны origin/main; ни одно значение recheckContrast не изменено.","numeric_provenance":{"glow_alpha":"Старый fixed-48 bisection + 4-decimal alpha заменён перебором конечных sRGB8-state, внутренней alpha выбранного интервала и shortest-roundtrip binary64 CSS.","scope_check":"Фактический структурный diff вычислен по каждому листу resolveVars; 4 alpha-ключа × 6 записей = 24."},"wcag_floors_not_weakened":"Glow — декоративная роль без WCAG-пола. Отдельно подтверждено: все 1376 пар (2752 числовых значения) recheck неизменны, поэтому измеренный контраст ни одной проверяемой роли не ослаблен.","isolated_verification_required":"Регенерация принимается только после независимой проверки scope, recheck-инварианта и полного Rust/npm/browser gate.","partition_correction":{"regenerated":"2026-07-11","reason":"Коррекция канонической binary64 alpha по фактическому midpoint encoded-sRGB8 partition без дополнительного округления.","drift_scope":"Ровно 17 alpha leaves: light/#000000 danger и четыре Glow alpha на каждом из #808080, #3A3A3C, #007AFF, #FF3B30; остальные resolveVars-листья неизменны.","recheck_unchanged":"2752/2752 числовых значений, то есть 1376/1376 пар (lc, wcag), побитно неизменны.","numeric_provenance":{"halo":"#FF3B30","background":"#000000","state":"#030101","lower_bits":"0x3f85555555555555","upper_bits":"0x3f8c1c1c1c1c1c1c","midpoint_bits":"0x3f88b8b8b8b8b8b8","midpoint":"0.012071078431372548","previous_bits":"0x3f88b8b8b8b8b8b9","previous_relation":"1 ULP выше, внутри той же partition"},"exhaustive_proof":"65 536 channel partitions и seam: state/composite outputs неизменны.","performance":"Full-range → bracketed exact search: base 19.7→4.37 µs, bloom 74.1→16.2 µs, long 656→139 µs."},"history":{"previous_regenerated":"2026-07-10","previous_regen_reason":"Глава #64 (ADR-0003): ось читаемости активирована в домене Ys — реактивный recheck (measure_contrast/recheck_against) и solver-вывод считаются в Ys. recheck flat и resolveVars регенерированы против пересобранного движка; inputs (theme/bg/fgs) сохранены. semver-major по ADR.","previous_drift_scope":"resolveVars: exactly 24 leaves changed, all --lab-fx-glow-{brand,danger,warning,neutral}-core (glow-centre colour, background-independent → 4 distinct values). No other var moved. glow base/alpha, labels, borders, fills, backgrounds all byte-identical.","previous_recheck_unchanged":"Исторический regen также не менял recheck; прежний текст ошибочно называл 2752 числа парами. Фактический объём: 1376 пар (lc, wcag).","previous_numeric_provenance":{"glow-brand-core":"oklch(78.84894% 0.062240 265.472) -> oklch(78.76611% 0.108476 257.256): chroma rises to the blue gamut wall at the functional lightness (fixed-fraction under-saturated it); L ±0.08pp, hue shifts to the cusp.","glow-danger-core":"oklch(81.62208% 0.103545 27.533) -> oklch(81.77103% 0.102764 29.025): near-identical (red already sat near its wall).","glow-warning-core":"oklch(88.80612% 0.081204 68.866) -> oklch(88.88181% 0.082838 68.777): near-identical.","glow-neutral-core":"oklch(99.97226% 0.001314 106.423) -> oklch(100.00000% 0.000000 89.876): neutral hue is achromatic → gamut wall chroma is 0 (was fixed-fraction residue noise); exact achromatic source stays on the neutral ray."},"previous_wave1_scope":"resolveVars: 69 info-* leaves changed across 6 theme×bg entries. Zero non-info drift (scope-checked). recheck untouched."},"endpoint_recovery":{"regenerated":"2026-07-17","reason":"Acceptance is checked before low-contrast dead-zone and physical-endpoint rejection, so previously false-failed opaque border endpoints now resolve.","drift_scope":"Exactly 9 resolveVars leaves added: border-{brand,danger,info}-strong on light #808080, #007AFF and #FF3B30. No existing leaf changed or disappeared.","recheck_unchanged":"Every committed recheck value remains bit-identical; the parity test compares all 2752 numbers before resolveVars.","proof":"agnostic_gates::accepted_endpoint_recovery_keeps_previously_false_failed_borders_legal plus full Rust workspace and WASM boundary parity."}},"recheck":[{"theme":"light","bg":"#FFFFFF","fgs":["#F7F7FF","#F7F7FF","#0A0A10","#71717A","#94949E","#BDBDC7","#94949E","#0A0A10","#00030E","#0057BB","#037BFF","#78AFFF","#150000","#BE0005","#FF070E","#FF9A8C","#1B0D00","#A06300","#D28300","#FFAA3A","#000B01","#007C2D","#00A73F","#00D452","#020013","#4D00F9","#6D6EFF","#9FA9FF"],"flat":[0,1.0658201232723763,0,1.0658201232723763,104.65963437608701,19.74046779866239,70.1623092547118,4.832895561154151,53.96706418364319,3.004779237664955,33.34341874861831,1.8637664731545371,53.96706418364319,3.004779237664955,104.65963437608701,19.74046779866239,105.59876563358553,20.60103636973117,79.91552226990729,6.816302360996974,63.95198968935827,3.97647793086433,41.89234722606997,2.2400949113548063,105.32470288110206,20.35108757719671,78.97384099389187,6.579727828852003,63.90360859563009,3.970705427078051,37.83221395673913,2.048194921340976,103.87315757816087,19.018778265876662,70.62528347734393,4.90716956443272,53.97808064225952,3.0056474129326713,34.232350404909745,1.8982213760304238,104.97702200816887,20.032297013031588,73.2226464627747,5.355840815772706,56.123729301186145,3.182173571701684,36.54497093010938,1.9925549350335838,105.76444562516849,20.751302844974063,83.48658341134008,7.825697912025839,63.67798680778349,3.9439477616440737,40.86459333479343,2.1890112231357013]},{"theme":"light","bg":"#000000","fgs":["#010103","#010103","#F1F1FC","#B3B3BC","#909099","#65656D","#909099","#F1F1FC","#E6F0FF","#60A1FF","#0074F3","#004CA4","#FFF4F2","#FF8273","#F40009","#A80004","#FFF7EE","#F79C00","#C97E00","#8F5800","#C2FFC9","#00C84D","#00A03C","#006E26","#EEF0FF","#9099FF","#6662FF","#4300DB"],"flat":[0,1.0069471255994658,0,1.0069471255994658,-99.67218963360757,18.727928195985914,-63.80513707672789,10.090949031745104,-45.863656882792206,6.635143500688325,-26.33477890397734,3.635637824948841,-45.863656882792206,6.635143500688325,-99.67218963360757,18.727928195985914,-97.97941453819666,18.27263411531394,-53.55180732861014,8.039306941172763,-34.54692380627581,4.792369408161928,-17.418806999279397,2.56984376276454,-102.41236835704379,19.474434420712562,-56.92703132210305,8.692613650917824,-34.93266406694178,4.850563950189369,-18.308962222075785,2.6667193472488013,-103.5613239139708,19.790915044333452,-61.97487030298502,9.71021814570805,-44.901407836051874,6.467843223430967,-25.783665577412222,3.5638173443979557,-98.60837652742211,18.44127602271432,-60.30793382928855,9.368875012646658,-42.707239087904505,6.093571182387199,-23.370874926227668,3.2583602660985775,-98.9883689300502,18.54346384276384,-54.32153113615954,8.18635152260471,-34.304902287955215,4.756029101219059,-14.435475219756622,2.261552965854495]},{"theme":"light","bg":"#808080","fgs":["#7A7A82","#7A7A82","#010103","#18171E","#37363E","#5B5B64","#37363E","#010103","#000002","#00163A","#003272","#004494","#040000","#3A0000","#760002","#990003","#0B0400","#261300","#512F00","#845100","#000200","#001D05","#004114","#006322","#000002","#160059","#2B0097","#3B00C5"],"flat":[0,1.0777393702545288,0,1.0777393702545288,40.18994509287661,5.280525528202377,36.81932911616927,4.505560397043893,27.93898600302036,3.0217055248761144,13.845788611978202,1.7013528597992067,27.93898600302036,3.0217055248761144,40.18994509287661,5.280525528202377,40.3306726916817,5.312553092992316,36.89312592554248,4.521969910173767,28.754774555141132,3.1292028976206594,22.090354756391577,2.35851620111828,40.23106479600237,5.289901483963394,36.823385380889306,4.5064610721321205,27.786796188195932,3.002060282138028,21.02583740042693,2.2570951143110336,39.64148780057383,5.154352713354357,36.89828467875601,4.523118840482662,27.981450040156208,3.027209986332121,13.567318350507929,1.6836851754208233,40.150141663678234,5.271436537678366,36.85731353296706,4.514000513189092,27.852320260403722,3.0105025419148825,16.643886294769857,1.8937047658181707,40.3306726916817,5.312553092992316,36.84988795298528,4.512349526507044,30.916517468784825,3.4313626667845316,25.033605894158644,2.6690076358452903]},{"theme":"light","bg":"#3A3A3C","fgs":["#3E3E45","#3E3E45","#F2F2FD","#BBBBC5","#9E9EA7","#7A7A82","#9E9EA7","#F2F2FD","#E7F1FF","#73ADFF","#2985FF","#0060CB","#FFF5F4","#FF9687","#FF4336","#CD0006","#FFF8F0","#FFA62C","#DC8A00","#AC6B00","#C7FFCC","#00D251","#00B043","#008631","#EFF1FF","#9CA6FF","#767AFF","#532BFF"],"flat":[0,1.0699484563148034,0,1.0699484563148034,-89.06520303275792,10.211241554507897,-56.964055924386784,5.959497869408446,-41.60773958742316,4.2707825803649335,-24.25691832785775,2.6663016206717356,-41.60773958742316,4.2707825803649335,-89.06520303275792,10.211241554507897,-87.32090210121694,9.956824779623638,-48.0046310941281,4.945145596338778,-30.285195552724065,3.1849116126306156,-14.342034884792934,1.9106934427040745,-91.71639880150975,10.602849175762582,-51.97724928251108,5.385053682831725,-31.570923815646545,3.301015045785777,-14.82740446463819,1.94471301206827,-92.86717481243348,10.774663089384916,-55.64998948221256,5.805759082702303,-40.41406674606042,4.149700467279057,-23.7537806706175,2.6249801387527425,-87.99158651504085,10.054343074329001,-53.75183524673264,5.586666992924044,-38.313874917805634,3.940371955014153,-21.037647044419426,2.407284189061088,-88.33220875070053,10.104016013712561,-48.80525652513833,5.032519885671211,-30.915189659062865,3.2415642790980215,-11.323318014385267,1.7063261265170042]},{"theme":"light","bg":"#007AFF","fgs":["#797981","#797981","#020205","#16151C","#36353D","#72727A","#36353D","#020205","#000103","#001536","#003374","#0058BC","#070000","#360000","#730002","#BE0005","#0F0500","#241200","#4F2F00","#A16400","#000400","#001B05","#003F13","#007C2D","#000005","#140055","#3300AC","#4E00FA"],"flat":[0,1.0745907693903731,0,1.0745907693903731,39.47891404105317,5.158402202047827,36.63906407938327,4.513939148043301,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.47891404105317,5.158402202047827,39.65687576920386,5.198408498908002,36.59714090951085,4.504660010775197,27.83078380746869,3.029349552004155,13.31049770996219,1.6744770124926043,39.57933742278427,5.181007308853048,36.66186584356392,4.51899176883356,27.77510172821011,3.0221297438766705,12.721590912296357,1.6379804580418844,38.8564182220264,5.016999835671664,36.579572970042136,4.500775701626332,27.65113132417139,3.006116231224861,0,1.205042331050678,39.39108202991847,5.138573889881769,36.624715730830154,4.510761781161014,27.902773646365304,3.038708829709556,0,1.3333017445114326,39.737197591996,5.216381929144518,36.59037871155487,4.5031645842195545,27.68585404738298,3.010592990868115,17.038043883395044,1.933101474636693]},{"theme":"light","bg":"#FF3B30","fgs":["#8A8A92","#8A8A92","#030306","#212129","#3E3D45","#76767F","#3E3D45","#030306","#000104","#00204D","#003B83","#005CC4","#080000","#4C0001","#830002","#C70006","#0F0600","#331C00","#5B3600","#A76800","#000400","#002809","#004917","#00822F","#000005","#1F0075","#3A00C3","#511AFF"],"flat":[0,1.0356140935636031,0,1.0356140935636031,43.57584669970237,5.806877937534237,38.3004661979112,4.504747008392574,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.57584669970237,5.806877937534237,43.87966672163739,5.884401548408216,38.30767260595269,4.50632138120243,29.16726657041677,3.0308664461202253,15.823096179531001,1.7789458759332724,43.782795788734404,5.8597651770218455,38.402450836988166,4.527103297945568,29.016037258963053,3.011424325654164,14.9864556348382,1.7254955647131072,42.99821792375369,5.657954629703501,38.41622407485322,4.5301350068404425,28.93769973409828,3.0014083479801514,0,1.28054929135364,43.62397616937584,5.819206103341516,38.406807106466914,4.528061863682665,29.022563392947294,3.012260432085235,8.92751562582044,1.3982348229239339,43.970091731453365,5.907320242919889,38.28628402517786,4.501651045763603,28.99214635836292,3.0083657301901288,19.11088367642911,2.0125842767555064]},{"theme":"light","bg":"#101012","fgs":["#15151B","#15151B","#F2F2FC","#B4B4BE","#93939C","#696972","#93939C","#F2F2FC","#E6F0FF","#64A4FF","#0077F9","#0050AC","#FFF4F3","#FF8777","#F9000A","#B00005","#FFF7EF","#FA9E00","#CD8000","#955C00","#C3FFC9","#00CA4E","#00A33D","#007329","#EEF0FF","#939CFF","#6967FF","#4600E6"],"flat":[0,1.045340264415452,0,1.045340264415452,-98.5838326466521,17.08955684747884,-62.72698384194396,9.243246994613658,-45.67498009680545,6.239717532288448,-26.395025771311026,3.4974414103185016,-45.67498009680545,6.239717532288448,-98.5838326466521,17.08955684747884,-96.3221346483494,16.53807546575917,-53.23458352949761,7.5085332653696355,-34.299151794570456,4.531377660721796,-17.34040000814869,2.4827755446650244,-100.79897840003042,17.636700891614694,-56.73966900010428,8.131153426700068,-34.4661942600266,4.554628420782135,-18.26813498707333,2.5778416349364046,-101.94670279716274,17.922901715066683,-61.50032492399525,9.010497025774457,-44.48245067627942,6.049054371037485,-25.983086445749187,3.447217107352778,-97.04991927160123,16.714741751700544,-59.578454823729174,8.650894122604043,-42.30409033566848,5.707629679225331,-23.50941826359813,3.1535587190594883,-97.33108904020293,16.783196253636362,-53.9780650339559,7.638815670143083,-34.15649094558268,4.511565332868746,-14.178333309149869,2.174938899863266]},{"theme":"light","bg":"#F6F8FA","fgs":["#F0F0FA","#F0F0FA","#0A0910","#707079","#8F8F99","#BCBCC5","#8F8F99","#0A0910","#00030D","#0057B9","#0079FD","#74ADFF","#150000","#BC0005","#FD000A","#FF9788","#1B0D00","#9F6200","#CB7F00","#FFA730","#000B01","#007B2C","#00A63E","#00D251","#020013","#4C00F7","#6C6CFF","#9DA6FF"],"flat":[0,1.0634215248159875,0,1.0634215248159875,100.62201386979996,18.61882254505944,66.47667620763235,4.605948460093869,52.23653324893716,3.0084294463712395,29.780700684603257,1.7710808257265196,52.23653324893716,3.0084294463712395,100.62201386979996,18.61882254505944,101.48497819102282,19.361251289328656,75.9364891028185,6.438321694919453,60.636932359482174,3.8278153397206016,38.76699274290234,2.152541489746932,101.19913515757631,19.11640864166299,75.28055256994783,6.281220843840182,60.46094873358925,3.807428346232839,34.70184973776556,1.9658801332164664,99.74758985463511,17.864929125608796,66.9127104243937,4.673002507305443,52.13428535623209,3.0001216660302674,31.16352525448906,1.8227359456035261,100.85145428464311,18.816958763489637,69.48045983543288,5.0977335979175304,52.421867335088024,3.0235758695027473,33.32486172802245,1.9082022515525083,101.63887790164272,19.492343272893066,79.67393134344084,7.442688338927282,60.17031912503092,3.7741072518393395,37.967753096619255,2.113772626279229]},{"theme":"light","bg":"#1C1C1E","fgs":["#202028","#202028","#F1F1FD","#B6B6BF","#95959E","#6D6C75","#95959E","#F1F1FD","#E6F1FF","#67A5FF","#0079FD","#0053B2","#FFF5F3","#FF8A7A","#FD000A","#B60005","#FFF7EF","#FC9F00","#D08200","#9A5F00","#C4FFCA","#00CB4E","#00A53E","#00772A","#EEF1FF","#949EFF","#6B6BFF","#4900EE"],"flat":[0,1.0522076023272475,0,1.0522076023272475,-96.27140987076255,15.184146579953019,-61.97466067394124,8.452688508186561,-44.87094637123084,5.728792540137694,-25.977188885961883,3.283145241842075,-44.87094637123084,5.728792540137694,-96.27140987076255,15.184146579953019,-94.97224440690107,14.900628115594163,-51.99577035710509,6.808135431331698,-33.457001357615106,4.175350120738554,-16.755883343489252,2.3335896778079332,-99.44736446714371,15.886233758087014,-55.869159717403925,7.428487313030341,-33.63398343987836,4.1977071628099685,-17.709012021143003,2.4235530906296177,-100.15616825242344,16.04465607216319,-60.39258141645385,8.181935837052826,-43.77686148964125,5.57032618168592,-25.67861999448382,3.2497240951569792,-95.39392806862337,14.992417327878547,-58.246405974587134,7.820609198173194,-41.3596549106396,5.227261702394524,-23.16505433719768,2.9752806858720673,-95.97861011098902,15.120061263203354,-52.9765437482588,6.963016139185695,-33.57839540296167,4.190679013723035,-13.485138200601865,2.040069034387161]},{"theme":"light","bg":"#7C3AED","fgs":["#707078","#707078","#F4F4FE","#E3E4ED","#BDBDC6","#A6A6B0","#BDBDC6","#F4F4FE","#EBF3FF","#D5E6FF","#92BFFF","#4291FF","#FFF8F7","#FFDDD8","#FFA597","#FF6253","#FFFAF5","#FFE0BE","#FFAA39","#E79100","#D0FFD4","#7DFF93","#00DA54","#00B947","#F1F4FF","#DFE4FF","#AEB8FF","#8087FF"],"flat":[0,1.1608373681184396,0,1.1608373681184396,-73.98396246220521,5.215032461901156,-64.0643931275358,4.500912896664839,-41.75099800228171,3.055051474145459,-29.486682699107686,2.3616035737730514,-41.75099800228171,3.055051474145459,-73.98396246220521,5.215032461901156,-72.43421936609613,5.100687932363686,-64.08586870464498,4.502412953317652,-41.11294430990105,3.017135229848019,-18.888486914529935,1.8251241221961068,-76.90365537296871,5.4332059719499135,-64.06334225320066,4.50083949888721,-40.940708789235714,3.0069340578770496,-21.122834074579163,1.9331720160112165,-77.70409895709017,5.493642615376888,-64.34147182620212,4.520282197700913,-40.849183913847796,3.0015190917179395,-28.18413111501551,2.292444746213784,-72.9506558335481,5.138679113149092,-64.10668565953954,4.5038671985064,-41.2870784084647,3.027463512408998,-26.013778316259767,2.1791858289450103,-73.64084437140687,5.1896286230945075,-64.42349258712335,4.5260223420377566,-41.02780633656069,3.0120908713744514,-19.464187683477977,1.8526993919522168]},{"theme":"light","bg":"#123456","fgs":["#36363D","#36363D","#F2F2FD","#BEBEC8","#A2A2AC","#808089","#A2A2AC","#F2F2FD","#E8F1FF","#79B0FF","#368BFF","#0065D6","#FFF6F4","#FF9B8D","#FF5446","#D80007","#FFF8F1","#FFAB3F","#E18E00","#B47000","#C8FFCD","#00D552","#00B545","#008D34","#EFF1FF","#A0AAFF","#7B81FF","#573FFF"],"flat":[0,1.0609289970892934,0,1.0609289970892934,-91.39519035537737,11.4423466076867,-60.94367397154904,6.896920022598847,-46.020165423777584,5.026435795944436,-29.36949737122932,3.250019698594834,-46.020165423777584,5.026435795944436,-91.39519035537737,11.4423466076867,-89.77514075602531,11.177468536043195,-51.89752791553575,5.733156384550998,-34.996215684604906,3.8114980409485155,-18.92394323577027,2.320895932067837,-94.48648764812391,11.954651961610136,-56.02375667309079,6.252768618847473,-36.81873931987068,4.002056146272223,-19.591172380553846,2.375625103310219,-95.24016771148194,12.080915286992608,-59.85145182180837,6.751641124414219,-44.82390104707481,4.887508677146329,-28.683175933367217,3.184369254481423,-90.45906258458693,11.288985892577246,-57.499124974387314,6.443154991463433,-42.83495757582209,4.660276446547384,-26.099142978345885,2.9428672820648862,-90.66219607331998,11.322193559065964,-52.9772743130274,5.867283737103295,-35.76790053375578,3.8916727925995533,-16.863337707955058,2.1560372721390864]},{"theme":"light","bg":"#ABCDEF","fgs":["#C2C2CB","#C2C2CB","#06060C","#55545D","#706F78","#A1A1AA","#706F78","#06060C","#000209","#00479B","#0065D5","#3289FF","#100000","#9F0004","#D70007","#FF4F41","#170A00","#7A4A00","#9F6200","#DF8C00","#000801","#006322","#00822F","#00B344","#01000D","#3E00CE","#573EFF","#797EFF"],"flat":[0,1.0705446339746656,0,1.0705446339746656,75.64582413051765,12.232204997602986,52.76667497081496,4.519371986307913,41.423484798334584,3.0020546798073307,18.127484103049046,1.5512322351556214,41.423484798334584,3.0020546798073307,75.64582413051765,12.232204997602986,76.22533906008685,12.552007092013115,56.99670466281028,5.352680994694784,44.43662180236468,3.3253647200326193,29.122033451491582,2.0641033245604916,76.01516726706762,12.436514137733148,55.97147975339624,5.133613537650522,43.91010121645754,3.2654000659595037,27.461071919951625,1.9716236837030474,74.81611736383091,11.770648316029503,52.816193854903005,4.528105409994289,41.51373908005361,3.011071841176318,19.679891349505557,1.6112041351931181,75.72958089661125,12.278654436624837,52.80881394476793,4.526802423347816,41.42233250009274,3.001939806510638,21.536768417458934,1.687644517337887,76.3513076320574,12.62087594492386,59.99704797613187,6.063965240585196,46.62694808670478,3.592268428661898,28.6381619838115,2.036506690369533]},{"theme":"light","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"dark","bg":"#FFFFFF","fgs":["#E7E7F1","#D9D9E2","#0D0D12","#707079","#94949D","#BCBCC6","#94949D","#0D0D12","#000414","#0053C4","#1F78FF","#79ACFF","#190000","#BC0016","#FD0021","#FF978D","#1D0B00","#A65B00","#DA7A00","#FFA658","#000E02","#007C2A","#00A63C","#00D24E","#04001A","#5900F2","#7867FF","#A4A4FF"],"flat":[10.564452802176923,1.2281904700369508,18.372353597432387,1.402460683906872,104.27090588423802,19.38311547953439,70.6022439311581,4.903434648448188,54.00450766949271,3.0077315832596954,33.86624309585679,1.8839141891835494,54.00450766949271,3.0077315832596954,104.27090588423802,19.38311547953439,105.42046624663428,20.43859328774187,80.31672424485741,6.9206271592755195,64.53598724808649,4.047139863973963,42.92136358171458,2.2930773168482466,105.12312344447312,20.1664284240786,79.32640956847692,6.666965706057784,64.47466861031803,4.0396342482899685,38.694434835096864,2.0867987099188317,103.94997559222902,19.08898290736351,71.78028267942507,5.099770465607366,55.19920557284124,3.104259347966041,35.17783363962355,1.9359471784913758,104.66191026229393,19.742561272328775,73.25578885512941,5.361938351796974,56.57179613789485,3.2209892436744982,37.49012931672191,2.03317973864909,105.58294145619523,20.58664787402852,83.26627791326895,7.757864847967472,64.57504887916579,4.051931818616954,42.090577540190225,2.2501559682241092]},{"theme":"dark","bg":"#000000","fgs":["#030205","#08080D","#F0F0FA","#B1B1BB","#8F8F98","#64646D","#8F8F98","#F0F0FA","#E3EEFF","#639EFF","#006DFE","#0048AD","#FFF4F3","#FF7F74","#F1001F","#A80012","#FFF7F1","#FF921B","#D17400","#955100","#B8FFBE","#00C649","#009F39","#006E25","#EDEEFF","#9794FF","#725BFF","#4E00D6"],"flat":[0,1.0147465549687367,0,1.0508696650285665,-99.01083964835996,18.549513785944853,-62.774763175831374,9.875849762659984,-45.37711439886134,6.5503119047070335,-25.95111170367181,3.5855589616463144,-45.37711439886134,6.5503119047070335,-99.01083964835996,18.549513785944853,-96.73192161780433,17.93999294470544,-52.63286661912575,7.865273702162647,-33.381528921151094,4.618607106385301,-17.0501576858861,2.5303719690800346,-102.4562582898777,19.486486384763445,-56.148341062851905,8.53993960492931,-34.330992536827104,4.759940239487347,-18.37234103122508,2.6737006902768288,-103.68997976483836,19.82648045930809,-60.35961607275431,9.379380118591195,-43.39157032733722,6.209218370112115,-24.93643207012505,3.4548840566407524,-97.27916136850891,18.085610527348415,-59.34389647192141,9.173841233004914,-42.25887199411116,6.018336366435839,-23.360562325895305,3.2570864547421428,-97.9872053947921,18.274719246988955,-53.323021296304695,7.99582368531923,-33.63351308594995,4.6559156780457185,-14.771084781300106,2.2949481607054216]},{"theme":"dark","bg":"#808080","fgs":["#707078","#66666E","#030305","#18171D","#37363E","#5D5D64","#37363E","#030305","#000104","#00153F","#00317C","#00429F","#070000","#3A0002","#750009","#9B0010","#0C0300","#291200","#562D00","#8B4B00","#000300","#001D05","#004112","#006521","#010005","#1A0057","#350098","#4700C4"],"flat":[0,1.24296889833444,9.274501031402123,1.4407196981948422,39.91548097777799,5.217615096019717,36.836632862345205,4.5094036578339445,27.93898600302036,3.0217055248761144,13.086665786299626,1.6537770693375544,27.93898600302036,3.0217055248761144,39.91548097777799,5.217615096019717,40.20955594591163,5.284998875760269,36.83828085440759,4.509769828130583,28.330761142327287,3.0728704517581886,21.819504217645104,2.3321848000622474,40.142120786515875,5.269603471071473,36.80831529061993,4.503115584720142,27.930310922781615,3.0205822411426944,20.559717681283935,2.214401964672886,39.70511745091868,5.169077378914306,36.80795164205375,4.503034882134433,27.78871707797606,3.002307432697674,14.025581970431295,1.7128949100718707,40.051433392362526,5.248844071123953,36.85731353296706,4.514000513189092,27.870384117529113,3.0128341396537346,15.95953035602916,1.844055168824021,40.26997047853993,5.298759395894901,36.795231110735635,4.500212645278562,30.09285126953815,3.3133648365325183,24.185949678819867,2.5748913454036786]},{"theme":"dark","bg":"#3A3A3C","fgs":["#46464E","#4F4F57","#F1F1FA","#BABAC4","#9D9DA6","#797982","#9D9DA6","#F1F1FA","#E4EFFF","#75AAFF","#3482FF","#005AD5","#FFF6F4","#FF9389","#FF3C3B","#CC0019","#FFF8F2","#FFA350","#E58000","#B36300","#BCFFC2","#00D04D","#00AF3F","#00862E","#EEEFFF","#A2A1FF","#7F74FF","#601DFF"],"flat":[0,1.2140718035663858,0,1.3988859584097761,-88.35603271482154,10.107493939375463,-56.41682578047019,5.8952705955406675,-41.10063170437542,4.219157833086703,-23.840055313660137,2.6320437618590202,-41.10063170437542,4.219157833086703,-88.35603271482154,10.107493939375463,-86.07057705487603,9.776047393674569,-47.005198509651805,4.836992692850337,-29.617188814986996,3.125340410912816,-13.465221764046625,1.8500449052652255,-92.15650032550448,10.66842694645063,-51.122226750198095,5.289032001141636,-30.69564720892069,3.221769980092269,-14.697188723997265,1.9355550836437716,-92.95341233620333,10.787583067801071,-55.01595924446716,5.732183607436098,-39.01368610071904,4.00959458617392,-22.717127042375882,2.5408179478715844,-86.56463892830851,9.847321829129962,-52.766100540364825,5.474290510931042,-37.83315401910713,3.893128667535661,-21.00389596511428,2.404636707585164,-87.32881842479753,9.957973594755346,-47.6452882768299,4.906141960838558,-29.99057738527554,3.1585747205458907,-10.990631160230787,1.6845762464445797]},{"theme":"dark","bg":"#007AFF","fgs":["#6F6F77","#65656D","#040408","#16151B","#36353D","#72727A","#36353D","#040408","#000107","#00133B","#00317C","#0054C7","#0B0000","#360002","#730009","#BF0016","#100500","#261000","#542C00","#A85D00","#000501","#001B04","#004012","#007D2B","#010009","#180052","#3B00A6","#5A00F5"],"flat":[0,1.2399763057879079,9.137153276370956,1.4379357071162235,39.199487305374596,5.095159290353486,36.655643103420836,4.517612479062309,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.199487305374596,5.095159290353486,39.616537893860624,5.189361828546554,36.671589094740156,4.521147554384925,27.767977778595686,3.0212072610618272,13.560368041515986,1.6902988819780091,39.46146930028483,5.1544680971312,36.646426655727396,4.515570174173857,27.733751845040576,3.016779185756929,12.426352071081123,1.6200937148513173,38.82022467282525,5.008731246970903,36.66757146424993,4.520256699490143,27.6755983348751,3.009270049666561,0,1.2356833222737893,39.28492308543262,5.114543979353608,36.632422880871374,4.512468289727634,27.610461383700073,3.00088106913278,0,1.3173837917708568,39.666598999480925,5.200587158978297,36.5946359240296,4.504106003407952,27.684199915070796,3.0103795763779906,16.582944142840912,1.898781610023956]},{"theme":"dark","bg":"#FF3B30","fgs":["#7F7F87","#74747D","#040408","#212128","#3E3D45","#76767F","#3E3D45","#040408","#000107","#001E53","#00398D","#0058CF","#0C0000","#4C0004","#83000C","#C60018","#110500","#371A00","#603300","#AE6000","#000601","#002808","#004916","#00822D","#01000A","#250070","#4400BC","#5E01FF"],"flat":[0,1.119564506502328,0,1.304916965157494,43.43238144483196,5.770041002680692,38.322111022898454,4.5094781825179275,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.43238144483196,5.770041002680692,43.84943203331798,5.876721182230661,38.357196991852035,4.517162998132957,28.969046969390032,3.0054117916551304,16.078397205708793,1.7957132708136676,43.66281217184597,5.829141814712315,38.38176722933373,4.522556047220382,28.96308732518828,3.004650205577566,15.121014183458136,1.7339400568635355,43.01534021323247,5.66238735865634,38.36369120360285,4.518587529333456,28.956857085057415,3.003854272405285,0,1.32359073643957,43.42248485866928,5.7674953973596095,38.41370496023468,4.529580289565808,29.031977011275746,3.0134669332394415,8.949958172317846,1.3992774406692907,43.88937786124038,5.8868666342953615,38.32550423955951,4.510220548286027,28.94413025668513,3.002229117722787,19.264807559936084,2.024522036885816]},{"theme":"dark","bg":"#101012","fgs":["#1C1C22","#24242A","#F0F0FA","#B3B3BD","#92929B","#686871","#92929B","#F0F0FA","#E3EEFF","#66A0FF","#0E71FF","#004CB5","#FFF5F3","#FF8378","#F60020","#AF0013","#FFF7F1","#FF962A","#D57700","#9B5500","#B9FFBF","#00C849","#00A23A","#007226","#EDEEFF","#9997FF","#7460FF","#5200DF"],"flat":[0,1.1210017368042908,0,1.2316217101091165,-97.35355975851269,16.788671896406843,-62.18912907483276,9.1408846014785,-45.183954583215964,6.160892481462449,-25.971291980892453,3.445784610130369,-45.183954583215964,6.160892481462449,-97.35355975851269,16.788671896406843,-95.07464172795706,16.23701078357789,-51.883866319617056,7.27432706128743,-33.10437599843017,4.366728841176053,-16.962076325331164,2.444617555127284,-101.23789901188303,17.745933910216884,-55.660852739640006,7.937252290960222,-33.86013630190819,4.470540437936136,-18.127983335051407,2.5633448249431416,-102.03269987499108,17.94442049171427,-60.01549050114797,8.732123022916136,-43.24478677485694,5.853976070416037,-25.11442835418257,3.342537791539289,-95.74776769254933,16.399183837627458,-58.596724506079966,8.469603286006345,-41.852118066322895,5.637910373772879,-23.122294138224145,3.108849028833141,-96.32992550494482,16.539962663017093,-52.86610846158114,7.444323350911882,-33.336065162067605,4.398429825394501,-14.383943910910213,2.194178799785328]},{"theme":"dark","bg":"#F6F8FA","fgs":["#E0E0EA","#D2D2DC","#0D0D12","#717179","#8F8F98","#BCBCC6","#8F8F98","#0D0D12","#000414","#0053C4","#1F78FF","#79ACFF","#190000","#BC0016","#FD0021","#FF978D","#1D0B00","#A65B00","#D67800","#FFA658","#000E02","#007C2A","#00A63C","#00D24E","#04001A","#5900F2","#7867FF","#A4A4FF"],"flat":[10.34292311627503,1.2313464424988367,18.024461551245693,1.4097592283337514,100.14533816071224,18.207162386274927,66.07133001527934,4.544848448940367,52.273633182943,3.011452358576948,29.740675372331037,1.769619110018133,52.273633182943,3.011452358576948,100.14533816071224,18.207162386274927,101.29489852310851,19.198605473400605,76.19115652133168,6.500760037097026,60.41041952456072,3.801604173546957,38.795795858188825,2.153958743950203,100.99755572094737,18.94295256384705,75.20084184495119,6.262487955668726,60.349100886792264,3.7945539156195487,34.56886711157111,1.9601948416949677,99.82440786870325,17.93087452582946,67.65471495589931,4.7903727911067815,52.29898260017819,3.0135204434714913,31.0522659160978,1.8184953129572932,100.53634253876818,18.544800983402446,69.13022113160365,5.036635229225181,52.44622841436909,3.025575236651027,33.364561593196164,1.9098288766402804,101.45737373266948,19.337677744697757,79.14071018974319,7.287203401685083,60.44948115564005,3.8061054053754897,37.96500981666448,2.1136413881018767]},{"theme":"dark","bg":"#1C1C1E","fgs":["#28282E","#303036","#F0F1FA","#B5B5BE","#94949D","#6C6C74","#94949D","#F0F1FA","#E3EEFF","#69A2FF","#1975FF","#004FBB","#FFF5F3","#FF877C","#FA0021","#B50014","#FFF7F1","#FF9833","#D87900","#A05800","#B9FFC0","#00CA4A","#00A43B","#007628","#EDEEFF","#9B99FF","#7664FF","#5500E7"],"flat":[0,1.1612081374032734,0,1.2977584057597347,-96.00102363023473,15.124963081358866,-61.434200333395395,8.359778481952823,-44.37695589123639,5.656999216809453,-25.852207004995158,3.269134017520218,-44.37695589123639,5.656999216809453,-96.00102363023473,15.124963081358866,-93.28410718321774,14.535439506623602,-51.011442228336165,6.654206660130301,-32.65955270222981,4.075313081844305,-16.370466566638967,2.297770413224217,-99.44736446714371,15.886233758087014,-55.07262883280597,7.299026812522581,-33.02825162884881,4.121422426501604,-17.569909707299868,2.4103015359642868,-100.24216533025177,16.063919770413232,-58.9183675206033,7.932997007393653,-42.52780974275247,5.391835753982905,-24.79898612463087,3.1522681596337323,-93.99035989085725,14.687777164248876,-57.733604751916815,7.735299184328377,-40.905085629416114,5.1638402024196015,-22.782862127638978,2.93464773079297,-94.53939096020551,14.80664328764592,-51.95162400089297,6.801199303451522,-32.707141977036414,4.081250761977603,-13.69412377461175,2.0581050526656677]},{"theme":"dark","bg":"#7C3AED","fgs":["#7A7A83","#85858D","#F2F2FD","#E3E4ED","#BBBCC5","#A6A6AF","#BBBCC5","#F2F2FD","#E8F1FF","#D5E6FF","#95BEFF","#498FFF","#FFF9F8","#FFDDD8","#FFA59B","#FF5F57","#FFFAF6","#FFDFC5","#FFA95E","#F18700","#C6FFCB","#7DFF91","#00DA51","#00B943","#F0F1FF","#E1E3FF","#B4B6FF","#8982FF"],"flat":[-8.022975593833932,1.3402714370624624,-13.06659651622355,1.5567826841029107,-72.79588351600884,5.127281558149197,-64.0643931275358,4.500912896664839,-41.08533982136385,3.0154992993085026,-29.446612137967147,2.3594628663401775,-41.08533982136385,3.0154992993085026,-72.79588351600884,5.127281558149197,-71.17583391665679,5.008590480308264,-64.08586870464498,4.502412953317652,-40.969901639859465,3.0086620775128243,-18.492326685553408,1.8062558438836862,-77.39176152066469,5.470028106981068,-64.06334225320066,4.50083949888721,-41.06186552000793,3.0141084284175577,-20.58109958398818,1.9067218663179524,-77.74802214310357,5.496966722090798,-64.16882972322054,4.508209630901898,-40.97688137217631,3.00907529195687,-26.93048349706687,2.2267208299060117,-71.5855645088526,5.038503428518723,-64.0583201718401,4.500488740880354,-41.24499881268402,3.0249663274797034,-25.961518214862377,2.176489332337808,-72.19208007215988,5.082914152992658,-64.24580556994597,4.513590807561596,-40.91738125342747,3.005553523356943,-18.74578210381434,1.818317299241165]},{"theme":"dark","bg":"#123456","fgs":["#3E3E45","#47474E","#F0F0FC","#BDBDC6","#A1A1AA","#7F7F88","#A1A1AA","#F0F0FC","#E5EFFF","#7AADFF","#3D87FF","#005FDF","#FFF6F5","#FF988E","#FF4D48","#D5001A","#FFF8F3","#FFA75A","#EA8300","#BA6700","#BDFFC3","#00D34E","#00B341","#008C31","#EEEFFF","#A5A5FF","#837AFF","#6433FF"],"flat":[0,1.1989453999458657,0,1.3802668927515667,-90.21171279539291,11.248602775503162,-60.350304841650235,6.81783465078813,-45.467647083484636,4.962060105853706,-28.90763677945104,3.2057711392885686,-45.467647083484636,4.962060105853706,-90.21171279539291,11.248602775503162,-88.52359832003891,10.974551054175622,-50.82334067294272,5.601029591424501,-33.90019185783247,3.6989242542195706,-17.94937633357589,2.2421371448335408,-94.53061684959366,11.962030249162733,-55.11693338695639,6.136943021617957,-35.65662848796355,3.880065704029081,-19.010500723408704,2.3279588656978594,-95.32685818617963,12.095472485308715,-58.832789738116276,6.617312123916825,-43.099834270009964,4.690265818580579,-27.202021451205145,3.0448373808729228,-89.02366089613628,11.055448870118658,-56.507119659393844,6.314879036055816,-41.91393002442956,4.556652813501584,-25.675484951698337,2.9041378624661793,-89.65880574741696,11.158543725868578,-51.69548126800453,5.708204299589472,-34.40239467659594,3.750316223165759,-16.078998268001875,2.0949612264666513]},{"theme":"dark","bg":"#ABCDEF","fgs":["#B4B4BE","#A8A8B1","#09090F","#55545C","#706F78","#A1A1AB","#706F78","#09090F","#00020F","#0045A5","#0060E2","#3F88FF","#140000","#A10011","#D7001B","#FF4F49","#190900","#814600","#A85D00","#EA8300","#000A01","#006320","#00822D","#00B341","#030014","#4A00CC","#6537FF","#847BFF"],"flat":[8.489900665165298,1.2445786124510558,14.633674840112363,1.428005718026211,75.26124671135368,12.018395958758797,52.798813706484495,4.5250375920814765,41.423484798334584,3.0020546798073307,18.08917030758312,1.5497949541740348,41.423484798334584,3.0020546798073307,75.26124671135368,12.018395958758797,76.15878035868923,12.51550617725489,56.792209524954714,5.308053794065892,44.82231091099692,3.370285744389143,29.010809014184062,2.057710850183084,75.84645644595844,12.343365988484052,55.500674792931,5.036843578382145,43.81499067450534,3.25473208522667,27.348178994525146,1.9655632934834584,74.80511978941351,11.764533211175078,52.793708756474935,4.52413702940673,41.44647230556496,3.0043476386355414,20.422200521634597,1.6411239547419576,75.54552640875083,12.176514522007174,52.82929323710673,4.530419449281277,41.44477504659015,3.004178254346042,21.57431352051131,1.6892460110571705,76.19495675605003,12.535354496536943,59.24767070343283,5.876074797996776,46.58341111523108,3.5866744685580465,28.54022915013225,2.030988108287992]},{"theme":"dark","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"light-ic","bg":"#FFFFFF","fgs":["#F7F7FF","#F7F7FF","#0A0A10","#71717A","#94949E","#BDBDC7","#94949E","#0A0A10","#000110","#0042E2","#3B78FF","#85AEFF","#150000","#BD0011","#FF001B","#FF998D","#1A0500","#B04A00","#E96400","#FFA174","#000B01","#007C2D","#00A73F","#00D452","#00040B","#00639C","#0089D6","#4DB3FF"],"flat":[0,1.0658201232723763,0,1.0658201232723763,104.65963437608701,19.74046779866239,70.1623092547118,4.832895561154151,53.96706418364319,3.004779237664955,33.34341874861831,1.8637664731545371,53.96706418364319,3.004779237664955,104.65963437608701,19.74046779866239,105.76809306682351,20.754602558566376,81.70242596755779,7.298044196933449,63.72862579130605,3.9499301799077116,41.321899652634976,2.211520376313395,105.32470288110206,20.35108757719671,79.14032751842986,6.6207260543602775,64.03544238362204,3.986463961054262,38.10332212672181,2.0602150617562085,104.62285904737456,19.706640245810163,73.93672186564804,5.489431142391079,57.895853978119064,3.3399091341000195,36.26437665881752,1.9807324696579875,104.97702200816887,20.032297013031588,73.2226464627747,5.355840815772706,56.123729301186145,3.182173571701684,36.54497093010938,1.9925549350335838,105.53601527934143,20.543945015271454,78.36297683006073,6.432254688155311,62.2832355663668,3.784280156272109,42.68471757482252,2.28072562681704]},{"theme":"light-ic","bg":"#000000","fgs":["#010103","#010103","#F1F1FC","#B3B3BC","#909099","#65656D","#909099","#F1F1FC","#E8F0FF","#709FFF","#2D6DFF","#0038C6","#FFF4F3","#FF8275","#F30019","#A7000E","#FFF6F1","#FF8C52","#DF5F00","#9D4100","#C2FFC9","#00C84D","#009F3C","#006E27","#DFF0FF","#10A5FF","#0082CB","#005689"],"flat":[0,1.0069471255994658,0,1.0069471255994658,-99.67218963360757,18.727928195985914,-63.80513707672789,10.090949031745104,-45.863656882792206,6.635143500688325,-26.33477890397734,3.635637824948841,-45.863656882792206,6.635143500688325,-99.67218963360757,18.727928195985914,-98.22794037003116,18.339196272629252,-53.8293996799751,8.092203727319841,-34.21813658812841,4.7430333536498335,-15.622162303180753,2.381112763636304,-102.4562582898777,19.486486384763445,-56.97432424245902,8.701923574139988,-34.76332175899368,4.824974728357804,-18.151652148372637,2.6494391947645526,-103.24826961310278,19.70448161329645,-59.10147589327934,9.125072654774526,-40.787696351505694,5.7744786453226835,-22.81212855995232,3.1897383862050708,-98.60837652742211,18.44127602271432,-60.30793382928855,9.368875012646658,-42.29572232514961,6.0245037012352585,-23.381466511664765,3.259668821930569,-97.12909045511768,18.04563033112125,-52.54162933208091,7.848085216280267,-36.273216344700636,5.055412083856902,-18.54110013749204,2.69234396770907]},{"theme":"light-ic","bg":"#808080","fgs":["#7A7A82","#7A7A82","#010103","#18171E","#37363E","#5B5B64","#37363E","#010103","#000002","#00104D","#002488","#0032B2","#040000","#3A0002","#750007","#98000B","#080100","#2E0E00","#602500","#8F3B00","#000200","#001D05","#004114","#006322","#000102","#00192E","#003A5F","#004D7C"],"flat":[0,1.0777393702545288,0,1.0777393702545288,40.18994509287661,5.280525528202377,36.81932911616927,4.505560397043893,27.93898600302036,3.0217055248761144,13.845788611978202,1.7013528597992067,27.93898600302036,3.0217055248761144,40.18994509287661,5.280525528202377,40.3306726916817,5.312553092992316,36.799792142283025,4.501224406456354,30.04772679653348,3.3069997994324063,23.797727835383583,2.533076638038498,40.23106479600237,5.289901483963394,36.80831529061993,4.503115584720142,27.941932493369514,3.022087143525339,21.190215752118235,2.2723970292907865,40.01441400964806,5.240352767492206,36.83929336929951,4.509994812829007,27.908315541084118,3.0177360720288915,16.77490328531677,1.9034128352995776,40.150141663678234,5.271436537678366,36.85731353296706,4.514000513189092,27.852320260403722,3.0105025419148825,16.643886294769857,1.8937047658181707,40.22977489962569,5.289607582090012,36.84755783504637,4.511831555904809,27.796281383025352,3.0032808914145437,21.058698283639867,2.260143784790762]},{"theme":"light-ic","bg":"#3A3A3C","fgs":["#3E3E45","#3E3E45","#F2F2FD","#BBBBC5","#9E9EA7","#7A7A82","#9E9EA7","#F2F2FD","#EAF1FF","#81ABFF","#4982FF","#0048F5","#FFF5F4","#FF9589","#FF403B","#CC0013","#FFF7F3","#FF9E6E","#F46900","#BD5000","#C6FFCC","#00D251","#00B043","#008631","#E1F1FF","#45B0FF","#0090E1","#006CA9"],"flat":[0,1.0699484563148034,0,1.0699484563148034,-89.06520303275792,10.211241554507897,-56.964055924386784,5.959497869408446,-41.60773958742316,4.2707825803649335,-24.25691832785775,2.6663016206717356,-41.60773958742316,4.2707825803649335,-89.06520303275792,10.211241554507897,-87.69551010135778,10.011246151186945,-48.263751486481056,4.97335266465752,-30.44825366943375,3.199530942583609,-12.043546933756078,1.753943193668956,-91.71639880150975,10.602849175762582,-51.72679347557047,5.3568510977778265,-31.21621892784593,3.268795397886287,-14.661523244642579,1.9330507439017046,-92.55409442667087,10.727809933310253,-53.89547122979923,5.603122076267749,-35.95806640240085,3.7112655792375078,-20.04367187639212,2.329915503818876,-87.89039906251095,10.039605852107476,-53.75183524673264,5.586666992924044,-38.313874917805634,3.940371955014153,-21.037647044419426,2.407284189061088,-86.58838125370931,9.850752189993974,-46.78872683576137,4.81370216625391,-31.383244337404896,3.2839492580871354,-15.736559790538532,2.009284883552937]},{"theme":"light-ic","bg":"#007AFF","fgs":["#797981","#797981","#020205","#16151C","#36353D","#72727A","#36353D","#020205","#000004","#000E48","#002895","#0042E3","#070000","#360001","#730006","#BE0011","#0C0200","#2B0D00","#5F2400","#B04A00","#000400","#001B05","#003F13","#007C2D","#000103","#00172B","#00395C","#00639D"],"flat":[0,1.0745907693903731,0,1.0745907693903731,39.47891404105317,5.158402202047827,36.63906407938327,4.513939148043301,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.47891404105317,5.158402202047827,39.74741500641279,5.218664231374835,36.670023859840576,4.5208004701163915,27.672031623266886,3.008810094200282,15.351341296852958,1.8098737923818007,39.57933742278427,5.181007308853048,36.654144364688555,4.517280323585742,27.751464091733354,3.019069960427185,12.671992881770905,1.6349566993987985,39.23716411822194,5.10371254671437,36.601471319299684,4.505617849545331,27.652865692456807,3.006339685224649,7.684471784052528,1.3665581876464832,39.39108202991847,5.138573889881769,36.624715730830154,4.510761781161014,27.902773646365304,3.038708829709556,0,1.3333017445114326,39.65687576920386,5.198408498908002,36.65150522712613,4.5166954713046765,27.64129393913477,3.0048491045091428,12.054359140378313,1.5979376774972005]},{"theme":"light-ic","bg":"#FF3B30","fgs":["#8A8A92","#8A8A92","#030306","#212129","#3E3D45","#76767F","#3E3D45","#030306","#000004","#001864","#002FA8","#0045ED","#080000","#4C0003","#830008","#C60012","#0D0200","#3E1500","#6C2A00","#B84D00","#000401","#002809","#004917","#00822F","#000103","#00233D","#00416A","#0068A4"],"flat":[0,1.0356140935636031,0,1.0356140935636031,43.57584669970237,5.806877937534237,38.3004661979112,4.504747008392574,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.57584669970237,5.806877937534237,43.98030914587015,5.909904848562026,38.293478372508915,4.503221171740978,28.94317626341717,3.002107337321695,17.95394033246701,1.9258322867444517,43.782795788734404,5.8597651770218455,38.38866051296957,4.524070782124866,28.984608537472,3.0074014381148784,15.156957289606964,1.7362054736619685,43.437607341847624,5.771384990646562,38.33399448678559,4.512078832150148,28.981628167432756,3.007020263830111,9.892674202630067,1.4441010369850493,43.614187977218386,5.816700203526642,38.406807106466914,4.528061863682665,29.022563392947294,3.012260432085235,8.92751562582044,1.3982348229239339,43.88976990866122,5.886966133555759,38.401524303038336,4.526899458852529,29.03631728859714,3.0140233900654434,14.306925700285792,1.683714708917422]},{"theme":"light-ic","bg":"#101012","fgs":["#15151B","#15151B","#F2F2FC","#B4B4BE","#93939C","#696972","#93939C","#F2F2FC","#E9F0FF","#74A2FF","#3371FF","#003CD0","#FFF4F3","#FF8679","#F8001A","#AF000F","#FFF6F2","#FF9058","#E36100","#A44400","#C3FFC9","#00CA4E","#00A33D","#007329","#E0F0FF","#21A8FF","#0085D0","#005B90"],"flat":[0,1.045340264415452,0,1.045340264415452,-98.5838326466521,17.08955684747884,-62.72698384194396,9.243246994613658,-45.67498009680545,6.239717532288448,-26.395025771311026,3.4974414103185016,-45.67498009680545,6.239717532288448,-98.5838326466521,17.08955684747884,-96.69585202312288,16.62869936569993,-53.53835262595417,7.561646720391368,-33.90853669724825,4.477228400656394,-15.643424374972522,2.314414627530853,-100.79897840003042,17.636700891614694,-56.5097869254783,8.089667628698802,-34.29633291417122,4.530985783372177,-18.10601775891745,2.56107712884258,-101.63443561648342,17.844851007069916,-58.71630179001587,8.4915976550775,-40.34850051574898,5.4087697654311055,-22.889197327723014,3.0820931228283226,-97.04991927160123,16.714741751700544,-59.578454823729174,8.650894122604043,-42.30409033566848,5.707629679225331,-23.50941826359813,3.1535587190594883,-95.5914257275877,16.361459308701495,-52.26386479821355,7.339891411251783,-35.96637326948896,4.765958094131511,-18.710865986535588,2.6239504003951875]},{"theme":"light-ic","bg":"#F6F8FA","fgs":["#F0F0FA","#F0F0FA","#0A0910","#707079","#8F8F99","#BCBCC5","#8F8F99","#0A0910","#000110","#0041DF","#3876FF","#82ACFF","#140000","#BB0011","#FC001B","#FF968A","#1A0500","#AE4900","#E76300","#FF9F70","#000B01","#007B2C","#00A63F","#00D252","#00040B","#00629B","#0088D4","#47B1FF"],"flat":[0,1.0634215248159875,0,1.0634215248159875,100.62201386979996,18.61882254505944,66.47667620763235,4.605948460093869,52.23653324893716,3.0084294463712395,29.780700684603257,1.7710808257265196,52.23653324893716,3.0084294463712395,100.62201386979996,18.61882254505944,101.64252534329776,19.49544279635548,78.08171358923367,6.990900026896573,60.31711036263554,3.7908833425501425,38.14751646036453,2.122399526754989,101.24542779029852,19.156162076239593,75.44574141529571,6.3202869230281635,60.62673294996029,3.82662941345977,34.94277926170305,1.9762445240799382,100.4972913238488,18.51105924752946,70.36281029021609,5.256397052662421,54.37780741212484,3.1906001595018556,32.840214506002376,1.8885138214456323,100.85145428464311,18.816958763489637,69.48045983543288,5.0977335979175304,52.4093478352768,3.0225491335598114,33.31123457222728,1.9076443919396007,101.41044755581565,19.297565623167603,74.60712675826916,6.125340559948453,58.63177587043786,3.604653750954651,39.55009522975671,2.1915837971666887]},{"theme":"light-ic","bg":"#1C1C1E","fgs":["#202028","#202028","#F1F1FD","#B6B6BF","#95959E","#6D6C75","#95959E","#F1F1FD","#E9F1FF","#76A4FF","#3875FF","#003ED7","#FFF4F3","#FF897C","#FC001B","#B50010","#FFF6F2","#FF935D","#E66300","#A94600","#C4FFCA","#00CB4F","#00A53F","#00772B","#E0F0FF","#2BA9FF","#0087D3","#005E95"],"flat":[0,1.0522076023272475,0,1.0522076023272475,-96.27140987076255,15.184146579953019,-61.97466067394124,8.452688508186561,-44.87094637123084,5.728792540137694,-25.977188885961883,3.283145241842075,-44.87094637123084,5.728792540137694,-96.27140987076255,15.184146579953019,-95.34499825068502,14.98175500729861,-52.621417231568934,6.906762415988252,-33.47849770408375,4.178062617945301,-14.893749254597887,2.163552488849563,-99.00844385529109,15.788447906049281,-55.63494162352738,7.390318911682041,-33.467257033822236,4.176644120449875,-17.547592326855693,2.408179342981014,-99.84390107174409,15.974784754119627,-57.911424929350886,7.764836527735112,-39.59013024218227,4.982347876116714,-22.33006111099907,2.8868875311347497,-95.39392806862337,14.992417327878547,-58.26045217149408,7.822951516486187,-41.372488477704024,5.229057297458628,-23.176065198031452,2.976455642863797,-93.8008911828484,14.646846343308852,-51.05892490110174,6.66159703590636,-35.06283530237813,4.380256350040106,-18.07990151348513,2.4590883821528062]},{"theme":"light-ic","bg":"#7C3AED","fgs":["#707078","#707078","#F4F4FE","#E3E4ED","#BDBDC6","#A6A6B0","#BDBDC6","#F4F4FE","#EDF3FF","#D8E6FF","#9ABDFF","#598FFF","#FFF8F7","#FFDDD8","#FFA59A","#FF6156","#FFF9F7","#FFDECE","#FFA77C","#FF7112","#D0FFD4","#7DFF93","#00D955","#00B947","#E5F3FF","#CEE8FF","#79C3FF","#0099EE"],"flat":[0,1.1608373681184396,0,1.1608373681184396,-73.98396246220521,5.215032461901156,-64.0643931275358,4.500912896664839,-41.75099800228171,3.055051474145459,-29.486682699107686,2.3616035737730514,-41.75099800228171,3.055051474145459,-73.98396246220521,5.215032461901156,-72.68698719753608,5.119268434409956,-64.43727527190525,4.526987198998707,-41.01457995095163,3.0113075347043563,-19.296469937711088,1.8446469211142276,-76.90365537296871,5.4332059719499135,-64.06334225320066,4.50083949888721,-41.0312066106476,3.012292267380192,-20.969079339398604,1.925648566411713,-77.34727635116013,5.466668081501757,-64.08510797117285,4.502359813071005,-40.89305028080999,3.004113887137535,-23.84545366268376,2.068528569757355,-72.9506558335481,5.138679113149092,-64.10668565953954,4.5038671985064,-40.827825177303865,3.0002560129496776,-26.013778316259767,2.1791858289450103,-71.69069599862902,5.046190228559761,-64.15987367011111,4.5075837056249375,-40.85863800181002,3.0020782433474276,-19.258832894479415,1.8428420367238694]},{"theme":"light-ic","bg":"#123456","fgs":["#36363D","#36363D","#F2F2FD","#BEBEC8","#A2A2AC","#808089","#A2A2AC","#F2F2FD","#EAF1FF","#86AEFF","#5189FF","#0650FF","#FFF6F4","#FF9B8F","#FF5349","#D70015","#FFF7F3","#FFA376","#FA6C00","#C75400","#C8FFCD","#00D553","#00B445","#008D34","#E2F1FF","#50B4FF","#0094E7","#0072B3"],"flat":[0,1.0609289970892934,0,1.0609289970892934,-91.39519035537737,11.4423466076867,-60.94367397154904,6.896920022598847,-46.020165423777584,5.026435795944436,-29.36949737122932,3.250019698594834,-46.020165423777584,5.026435795944436,-91.39519035537737,11.4423466076867,-90.02549742397721,11.218239018758677,-52.117590678997175,5.760385990810306,-35.453068631322715,3.8588722418561026,-17.16315496591595,2.1796295803105563,-94.48648764812391,11.954651961610136,-56.08049309972586,6.260045669338659,-36.68653001054492,3.9880923379680597,-19.42498133620683,2.3619323117143227,-94.88408174929032,12.021194381023134,-58.024655972390946,6.511549338355004,-40.19653971715428,4.366167533936967,-25.014063203920518,2.8441658803090872,-90.45906258458693,11.288985892577246,-57.51342916294683,6.44501257640493,-42.39985031117064,4.611196053798779,-26.099142978345885,2.9428672820648862,-89.03890865199516,11.05791933389335,-51.142776043878534,5.640183677550314,-35.55629387962385,3.86961291577043,-20.57349953874105,2.4573829383449617]},{"theme":"light-ic","bg":"#ABCDEF","fgs":["#C2C2CB","#C2C2CB","#06060C","#55545D","#706F78","#A1A1AA","#706F78","#06060C","#00010B","#0035BB","#044EFF","#4E86FF","#0F0000","#9F000C","#D60015","#FF4D45","#150400","#903B00","#BB4F00","#F86B00","#000801","#006322","#008230","#00B344","#000307","#005182","#0071B2","#0093E5"],"flat":[0,1.0705446339746656,0,1.0705446339746656,75.64582413051765,12.232204997602986,52.76667497081496,4.519371986307913,41.423484798334584,3.0020546798073307,18.127484103049046,1.5512322351556214,41.423484798334584,3.0020546798073307,75.64582413051765,12.232204997602986,76.30385323493446,12.594966222228084,58.55230095328762,5.70794052541694,46.62204712410211,3.5916381056717506,29.005214449343097,2.0573900879913625,76.05323451380515,12.457481581934719,55.93606418979168,5.126251708978212,44.077718465236906,3.284322001440957,27.730078776096413,1.986177453897667,75.43283879959024,12.113874624281086,52.77586207835023,4.520990578468311,41.44187963136357,3.003889327255304,23.868980516769618,1.7916338607346896,75.72958089661125,12.278654436624837,52.80881394476793,4.526802423347816,41.41072061989075,3.0007825637465393,21.536768417458934,1.687644517337887,76.14729893560808,12.509202438867769,55.739334564053664,5.085602713702602,43.07798550292857,3.173723442083943,28.271676351762963,2.015968674447834]},{"theme":"light-ic","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"dark-ic","bg":"#FFFFFF","fgs":["#E7E7F1","#D9D9E2","#0D0D12","#707079","#94949D","#BCBCC6","#94949D","#0D0D12","#000511","#005DAD","#0080EB","#67AEFF","#180001","#BB0023","#FB0032","#FF9690","#1D0D00","#A16200","#D38200","#FFA93F","#000E02","#007C2A","#00A63B","#00D24D","#060018","#6E00E2","#8F5BFF","#B49FFF"],"flat":[10.564452802176923,1.2281904700369508,18.372353597432387,1.402460683906872,104.27090588423802,19.38311547953439,70.6022439311581,4.903434648448188,54.00450766949271,3.0077315832596954,33.86624309585679,1.8839141891835494,54.00450766949271,3.0077315832596954,104.27090588423802,19.38311547953439,105.36973966240839,20.39226096069594,79.16304803673168,6.626348275559002,63.912632944603466,3.971781216419874,43.318131952880584,2.3140155027501375,105.16667360757414,20.20636839933495,79.43361118518992,6.693805381831162,64.79709340122825,4.079330310903514,38.90470830731088,2.096381256670562,103.76723276112338,18.92212884965907,70.7453629185683,4.926701923645705,54.109273202798526,3.0160152686700097,34.512224892089854,1.9092708836328856,104.66191026229393,19.742561272328775,73.25578885512941,5.361938351796974,56.58363991444959,3.2220248289870597,37.502971296697396,2.0337403797475795,105.5639998705614,20.569417077144905,82.76169093861434,7.605398027541734,65.05029978451972,4.11090668779679,42.03743585537794,2.2474520733771812]},{"theme":"dark-ic","bg":"#000000","fgs":["#030205","#08080D","#F0F0FA","#B1B1BB","#8F8F98","#64646D","#8F8F98","#F0F0FA","#DFEEFF","#4AA0FF","#007AE0","#005198","#FFF4F3","#FF7D79","#EF0030","#A6001E","#FFF7EF","#F99A00","#CA7D00","#915800","#B8FFBE","#00C648","#009F38","#006E24","#F0EDFF","#A98DFF","#894CFF","#6000C7"],"flat":[0,1.0147465549687367,0,1.0508696650285665,-99.01083964835996,18.549513785944853,-62.774763175831374,9.875849762659984,-45.37711439886134,6.5503119047070335,-25.95111170367181,3.5855589616463144,-45.37711439886134,6.5503119047070335,-99.01083964835996,18.549513785944853,-96.24720863865953,17.81140932471069,-52.09132740819334,7.763491481432673,-34.99617079306692,4.860177125212619,-17.977340963301042,2.6303715448994067,-102.4562582898777,19.486486384763445,-55.7461567674855,8.461541475204797,-34.016004840410574,4.712824540535038,-18.066789785866806,2.6401456993132153,-103.60398268701002,19.802704734429785,-61.68353878496926,9.650187857341214,-44.76775468944945,6.444757556916112,-26.060791619056427,3.599837857825526,-97.27916136850891,18.085610527348415,-59.33082759509665,9.171209294707863,-42.24705692654848,6.016359585841944,-23.350526713793172,3.2558471191579894,-97.94239544297146,18.262727694350296,-53.03355221198167,7.94095381214551,-32.857248309508414,4.541449578831631,-15.041171256747345,2.322063533056465]},{"theme":"dark-ic","bg":"#808080","fgs":["#707078","#66666E","#030305","#18171D","#37363E","#5D5D64","#37363E","#030305","#000103","#001834","#00376B","#004A8C","#070000","#390005","#750012","#99001B","#0D0400","#261300","#522F00","#865100","#000300","#001D05","#004112","#006521","#010005","#22004F","#43008F","#5800B7"],"flat":[0,1.24296889833444,9.274501031402123,1.4407196981948422,39.91548097777799,5.217615096019717,36.836632862345205,4.5094036578339445,27.93898600302036,3.0217055248761144,13.086665786299626,1.6537770693375544,27.93898600302036,3.0217055248761144,39.91548097777799,5.217615096019717,40.21965913293546,5.287302224624218,36.81767378273908,4.505192880903515,27.950777846769416,3.023233051937069,21.000772856623527,2.25477321245894,40.142120786515875,5.269603471071473,36.88792093057972,4.5208109211231795,27.866909320024153,3.0123854877509646,20.876190217747006,2.243276608438576,39.57947058767665,5.139984882718895,36.89828467875601,4.523118840482662,27.8635036155662,3.011945822214043,13.292640012092916,1.6665035199669143,40.051433392362526,5.248844071123953,36.85731353296706,4.514000513189092,27.870384117529113,3.0128341396537346,15.95953035602916,1.844055168824021,40.26997047853993,5.298759395894901,36.80600977189143,4.502603953746083,29.651273965169533,3.2515347547731954,23.802145579236715,2.533547958530533]},{"theme":"dark-ic","bg":"#3A3A3C","fgs":["#46464E","#4F4F57","#F1F1FA","#BABAC4","#9D9DA6","#797982","#9D9DA6","#F1F1FA","#E1EFFF","#62ACFF","#0087F7","#0065BB","#FFF5F4","#FF928C","#FF3644","#CA0027","#FFF8F1","#FFA533","#DD8900","#AD6A00","#BCFFC2","#00D04C","#00AF3F","#00862E","#F1EFFF","#B29CFF","#956AFF","#7700F5"],"flat":[0,1.2140718035663858,0,1.3988859584097761,-88.35603271482154,10.107493939375463,-56.41682578047019,5.8952705955406675,-41.10063170437542,4.219157833086703,-23.840055313660137,2.6320437618590202,-41.10063170437542,4.219157833086703,-88.35603271482154,10.107493939375463,-85.70519954500536,9.72347127561709,-46.57313915269262,4.790554592637207,-29.772868283167547,3.1391774083572677,-14.678197720495364,1.9342213705917548,-91.71639880150975,10.602849175762582,-50.907190680193835,5.264997878479995,-30.103011927821978,3.1686137953283313,-14.381529067368087,1.9134497328938256,-92.9101803888625,10.781105347058572,-55.36632323767275,5.772792653136124,-40.27550194757439,4.135743433221995,-23.629833528615176,2.614848030728214,-86.56463892830851,9.847321829129962,-52.75275099572737,5.472775232316544,-37.83315401910713,3.893128667535661,-21.00389596511428,2.404636707585164,-87.71836703917482,10.014570561299498,-47.715877818006604,4.91379345402092,-29.619990398118716,3.125589171245837,-10.872649839108671,1.6769004806806627]},{"theme":"dark-ic","bg":"#007AFF","fgs":["#6F6F77","#65656D","#040408","#16151B","#36353D","#72727A","#36353D","#040408","#000106","#001632","#00366A","#005EAF","#0B0000","#360004","#730011","#BD0023","#100600","#241200","#502E00","#A36300","#000501","#001B04","#004012","#007D2B","#020009","#20004A","#48009A","#6F00E5"],"flat":[0,1.2399763057879079,9.137153276370956,1.4379357071162235,39.199487305374596,5.095159290353486,36.655643103420836,4.517612479062309,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.199487305374596,5.095159290353486,39.62660370456575,5.191620542906115,36.592103069401674,4.503545882983851,27.695057695096033,3.0117807086970667,12.482735608358766,1.623488823202914,39.46146930028483,5.1544680971312,36.631002505660305,4.512153756975423,27.677944212691237,3.0095726068531357,12.751768680957815,1.6398240151911772,38.729462058672325,4.987982714010286,36.579572970042136,4.500775701626332,27.747483785710887,3.0185550274007946,0,1.2039987886628472,39.28492308543262,5.114543979353608,36.632422880871374,4.512468289727634,27.610461383700073,3.00088106913278,0,1.3173837917708568,39.63684952401951,5.1939188146581685,36.601297620325695,4.505579426399357,27.609531401873983,3.0007614645527125,16.085712499624492,1.86220122646402]},{"theme":"dark-ic","bg":"#FF3B30","fgs":["#7F7F87","#74747D","#040408","#212128","#3E3D45","#76767F","#3E3D45","#040408","#000206","#002245","#003E78","#0062B6","#0B0000","#4C0008","#820015","#C50025","#110600","#341C00","#5B3600","#A96700","#000601","#002808","#004916","#00822D","#02000A","#2E0067","#5300AD","#7400EE"],"flat":[0,1.119564506502328,0,1.304916965157494,43.43238144483196,5.770041002680692,38.322111022898454,4.5094781825179275,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.43238144483196,5.770041002680692,43.7603252928922,5.854038847974277,38.29235457140463,4.502975854531618,29.083956028514045,3.020138635078335,15.054852030501879,1.729780743830801,43.694363439742204,5.837205585263101,38.354206470247746,4.516507237210082,29.087182234169767,3.020553277003921,15.230546565278194,1.740856512459411,42.92491991360228,5.63897133999608,38.33365423714702,4.512004338988724,28.93769973409828,3.0014083479801514,0,1.2794758858630608,43.42248485866928,5.7674953973596095,38.41370496023468,4.529580289565808,29.031977011275746,3.0134669332394415,8.949958172317846,1.3992774406692907,43.85966524740055,5.879321607935794,38.335090707081115,4.512318847459295,28.952846517354917,3.003342035233188,18.7969313728254,1.9885281036480773]},{"theme":"dark-ic","bg":"#101012","fgs":["#1C1C22","#24242A","#F0F0FA","#B3B3BD","#92929B","#686871","#92929B","#F0F0FA","#E0EEFF","#4FA3FF","#007DE4","#00559F","#FFF4F3","#FF817D","#F40031","#AD001F","#FFF7EF","#FB9C00","#CE7F00","#965B00","#B9FFBF","#00C849","#00A239","#007226","#F0EEFF","#AA90FF","#8C52FF","#6500D0"],"flat":[0,1.1210017368042908,0,1.2316217101091165,-97.35355975851269,16.788671896406843,-62.18912907483276,9.1408846014785,-45.183954583215964,6.160892481462449,-25.971291980892453,3.445784610130369,-45.183954583215964,6.160892481462449,-97.35355975851269,16.788671896406843,-94.7101738760577,16.149472101206463,-51.76844025191021,7.254462182627787,-34.605057818633654,4.573999892517157,-17.84521283217997,2.534242228411278,-100.79897840003042,17.636700891614694,-55.24750846744172,7.863491890193123,-33.54190885081095,4.42668652015819,-17.815136446883052,2.5311583129351276,-101.94670279716274,17.922901715066683,-61.02785966423507,8.921519321161206,-44.34904450398409,6.02788949767693,-25.86724540779468,3.4331609270477186,-95.74776769254933,16.399183837627458,-58.596724506079966,8.469603286006345,-41.840254848173814,5.636085625741139,-23.122294138224145,3.108849028833141,-96.71860922522349,16.634224259107555,-52.4354046324141,7.369572153296626,-32.71416296796099,4.3135863728502315,-14.766203746026353,2.2302399315399106]},{"theme":"dark-ic","bg":"#F6F8FA","fgs":["#E0E0EA","#D2D2DC","#0D0D12","#717179","#8F8F98","#BCBCC6","#8F8F98","#0D0D12","#000511","#005DAD","#0080EB","#67AEFF","#180001","#BB0023","#FB0032","#FF9690","#1D0D00","#A16200","#CC7E00","#FFA93F","#000E02","#007C2A","#00A63B","#00D24D","#060018","#6E00E1","#8F5BFF","#B49FFF"],"flat":[10.34292311627503,1.2313464424988367,18.024461551245693,1.4097592283337514,100.14533816071224,18.207162386274927,66.07133001527934,4.544848448940367,52.273633182943,3.011452358576948,29.740675372331037,1.769619110018133,52.273633182943,3.011452358576948,100.14533816071224,18.207162386274927,101.24417193888262,19.155084079579783,75.03748031320593,6.224334741672483,59.78706522107772,3.730817455350078,39.19256422935483,2.1736266322828217,101.04110588404839,18.980469423093126,75.30804346166417,6.287699296730837,60.6715256777025,3.8318416601446055,34.77914058378512,1.9691960254812915,99.64166503759763,17.774143327140518,66.61979519504256,4.627804134340593,52.265155427331,3.010761189364384,30.386657168564103,1.79343744066295,100.53634253876818,18.544800983402446,69.13022113160365,5.036635229225181,52.45807219092383,3.026547994099155,33.37740357317164,1.9103555042369325,101.43843214703563,19.321492322017065,78.73738474892319,7.17242701812758,60.92473206099399,3.861502331684902,37.91186813185219,2.111101535692422]},{"theme":"dark-ic","bg":"#1C1C1E","fgs":["#28282E","#303036","#F0F1FA","#B5B5BE","#94949D","#6C6C74","#94949D","#F0F1FA","#E0EEFF","#53A4FF","#007FE8","#0058A5","#FFF4F3","#FF8580","#F80032","#B30021","#FFF7F0","#FD9D00","#D18100","#9B5E00","#B9FFC0","#00CA4A","#00A43A","#007628","#F0EEFF","#AC93FF","#8D57FF","#6800D8"],"flat":[0,1.1612081374032734,0,1.2977584057597347,-96.00102363023473,15.124963081358866,-61.434200333395395,8.359778481952823,-44.37695589123639,5.656999216809453,-25.852207004995158,3.269134017520218,-44.37695589123639,5.656999216809453,-96.00102363023473,15.124963081358866,-92.91963933131836,14.457074514504098,-50.53751898728166,6.580638229837842,-33.762466759799054,4.213972880586457,-17.265259153354464,2.3814244063048684,-99.00844385529109,15.788447906049281,-54.621704682580784,7.2261694596451385,-32.708249696736004,4.081389020198301,-17.26088719592284,2.381011454094406,-100.19905346524207,16.054261379481122,-59.919533209261445,8.101702037099825,-43.64240726631874,5.55098822531801,-25.561703474916055,3.236683846808585,-93.99035989085725,14.687777164248876,-57.733604751916815,7.735299184328377,-40.893113879964474,5.162174617584753,-22.782862127638978,2.93464773079297,-94.92807468048419,14.891026660055605,-51.83505302329671,6.7828987244211,-32.07221654016657,4.002369709649521,-14.066989001346808,2.090531498955086]},{"theme":"dark-ic","bg":"#7C3AED","fgs":["#7A7A83","#85858D","#F2F2FD","#E3E4ED","#BBBCC5","#A6A6AF","#BBBCC5","#F2F2FD","#E5F1FF","#D2E7FF","#8AC0FF","#2091FF","#FFF9F8","#FFDDDA","#FFA49E","#FF5C5D","#FFFAF5","#FFE0C0","#FFAA42","#E99000","#C6FFCB","#7DFF91","#00DA50","#00B943","#F3F1FF","#E6E2FF","#C1B2FF","#9D7AFF"],"flat":[-8.022975593833932,1.3402714370624624,-13.06659651622355,1.5567826841029107,-72.79588351600884,5.127281558149197,-64.0643931275358,4.500912896664839,-41.08533982136385,3.0154992993085026,-29.446612137967147,2.3594628663401775,-41.08533982136385,3.0154992993085026,-72.79588351600884,5.127281558149197,-70.80493468751378,4.981574213000164,-64.1741844582375,4.5085838821814495,-40.86541522684489,3.0024791016401666,-17.915271666932362,1.7789289638170434,-77.39176152066469,5.470028106981068,-64.14420274941838,4.506488572747314,-40.82594869447877,3.0001450551263997,-20.102672577261966,1.8834970356793017,-77.70409895709017,5.493642615376888,-64.40976920815079,4.525061719384059,-40.93902681557826,3.00683450902807,-28.2154352545988,2.2940964528512438,-71.5855645088526,5.038503428518723,-64.0583201718401,4.500488740880354,-41.23137463469248,3.02415799426954,-25.961518214862377,2.176489332337808,-72.5833510184408,5.111647048756453,-64.45521953810703,4.528243512077896,-40.9348520371047,3.006587427640115,-18.521762858381592,1.807654812879132]},{"theme":"dark-ic","bg":"#123456","fgs":["#3E3E45","#47474E","#F0F0FC","#BDBDC6","#A1A1AA","#7F7F88","#A1A1AA","#F0F0FC","#E1EFFF","#68AEFF","#008BFD","#006AC4","#FFF6F5","#FF9791","#FF494F","#D30029","#FFF8F1","#FFA941","#E28C00","#B46E00","#BEFFC3","#00D34D","#00B340","#008C31","#F1EFFF","#B49FFF","#9971FF","#7D09FF"],"flat":[0,1.1989453999458657,0,1.3802668927515667,-90.21171279539291,11.248602775503162,-60.350304841650235,6.81783465078813,-45.467647083484636,4.962060105853706,-28.90763677945104,3.2057711392885686,-45.467647083484636,4.962060105853706,-90.21171279539291,11.248602775503162,-88.0351868676248,10.895768939711282,-50.01919534416472,5.502978516969682,-33.92042169291382,3.7009882121251625,-19.118481017052428,2.3367853131295435,-94.53061684959366,11.962030249162733,-54.89593536437227,6.108854061876529,-35.13675470036395,3.8260433618990066,-18.695569008603144,2.3023140000481574,-95.24016771148194,12.080915286992608,-59.18458546592085,6.6635751999987605,-44.37309985295556,4.8355935478331284,-28.125674388660414,3.1315039953558483,-89.11957165172129,11.070992163190612,-56.49372778683512,6.313154752438012,-41.901500594929324,4.555261373045625,-25.675484951698337,2.9041378624661793,-90.04835436179425,11.221964232051386,-51.2922333885473,5.658542947646642,-34.21126239038315,3.7307191421666435,-15.254686874750304,2.03178289437105]},{"theme":"dark-ic","bg":"#ABCDEF","fgs":["#B4B4BE","#A8A8B1","#09090F","#55545C","#706F78","#A1A1AB","#706F78","#09090F","#00030D","#004D92","#006CC7","#008BFE","#130001","#9F001C","#D60029","#FF4B50","#190B00","#7B4A00","#A06100","#E38C00","#000A01","#006320","#00822D","#00B341","#040013","#5B00BE","#7E16FF","#9971FF"],"flat":[8.489900665165298,1.2445786124510558,14.633674840112363,1.428005718026211,75.26124671135368,12.018395958758797,52.798813706484495,4.5250375920814765,41.423484798334584,3.0020546798073307,18.08917030758312,1.5497949541740348,41.423484798334584,3.0020546798073307,75.26124671135368,12.018395958758797,76.08600684668272,12.475516218126787,55.96473752983635,5.13221099097022,43.3369682989835,3.2018590596167122,29.318326289650187,2.0754572365320043,75.88156299830736,12.362776535253154,55.82217638546274,5.102669267083783,43.91931922104849,3.266436635421996,27.87409429449102,1.9940348577564484,74.63415754799017,11.66954886455628,52.68236753448497,4.504554642142053,41.632593181405234,3.023005829909607,19.021862742942993,1.5853635699211195,75.54552640875083,12.176514522007174,52.82929323710673,4.530419449281277,41.44477504659015,3.004178254346042,21.57431352051131,1.6892460110571705,76.18160530883091,12.528031661692317,58.96992438550627,5.808209180198148,47.36214126331064,3.68860336114861,29.106756402593504,2.0632235490419992]},{"theme":"dark-ic","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]}],"resolveVars":[{"theme":"light","bg":"#FFFFFF","vars":{"--lab-bg-tone-2":"oklch(97.84197% 0.010603 286.202)","--lab-bg-tone-3":"oklch(97.84197% 0.010603 286.202)","--lab-label-primary":"oklch(19.12257% 0.014100 291.556)","--lab-label-secondary":"oklch(56.54196% 0.013721 285.953)","--lab-label-tertiary":"oklch(66.97448% 0.014606 285.999)","--lab-label-quaternary":"oklch(81.39504% 0.013897 286.087)","--lab-border-strong":"oklch(19.12257% 0.014100 291.556)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(19.39430% 0.069681 257.297)","--lab-label-brand-secondary":"oklch(57.33316% 0.205939 257.291)","--lab-label-brand-tertiary":"oklch(67.12978% 0.175419 257.690)","--lab-label-brand-quaternary":"oklch(81.31388% 0.094313 257.967)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(20.16318% 0.082740 29.234)","--lab-label-danger-secondary":"oklch(59.62536% 0.244212 28.655)","--lab-label-danger-tertiary":"oklch(69.12968% 0.198650 28.574)","--lab-label-danger-quaternary":"oklch(82.55135% 0.097676 29.389)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(19.32631% 0.042728 66.944)","--lab-label-warning-secondary":"oklch(57.27465% 0.125021 68.799)","--lab-label-warning-tertiary":"oklch(67.73500% 0.148484 68.161)","--lab-label-warning-quaternary":"oklch(82.04043% 0.139600 68.374)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(67.73500% 0.148484 68.161 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(18.59864% 0.054816 147.311)","--lab-label-success-secondary":"oklch(54.91588% 0.161394 147.418)","--lab-label-success-tertiary":"oklch(64.88263% 0.190555 147.443)","--lab-label-success-quaternary":"oklch(79.02491% 0.232159 147.432)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(64.96409% 0.172888 147.450 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(19.54489% 0.077696 259.509)","--lab-label-info-secondary":"oklch(57.68997% 0.232691 259.838)","--lab-label-info-tertiary":"oklch(67.26428% 0.173598 259.980)","--lab-label-info-quaternary":"oklch(81.49851% 0.092914 259.576)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.5","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.5","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.5","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.5","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(66.97448% 0.014606 285.999)"}},{"theme":"light","bg":"#000000","vars":{"--lab-bg-tone-2":"oklch(7.11623% 0.013707 282.350)","--lab-bg-tone-3":"oklch(7.11623% 0.013707 282.350)","--lab-label-primary":"oklch(98.65156% 0.006606 286.278)","--lab-label-secondary":"oklch(80.14049% 0.013952 286.081)","--lab-label-tertiary":"oklch(69.23260% 0.013029 286.055)","--lab-label-quaternary":"oklch(55.16643% 0.013808 285.938)","--lab-border-strong":"oklch(98.65156% 0.006606 286.278)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(98.69528% 0.006207 255.474)","--lab-label-brand-secondary":"oklch(80.06451% 0.101154 257.822)","--lab-label-brand-tertiary":"oklch(69.35433% 0.162198 257.610)","--lab-label-brand-quaternary":"oklch(55.96293% 0.201872 257.393)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(98.64532% 0.006567 28.833)","--lab-label-danger-secondary":"oklch(81.38408% 0.105319 28.863)","--lab-label-danger-tertiary":"oklch(71.19739% 0.181099 28.350)","--lab-label-danger-quaternary":"oklch(58.10538% 0.238004 28.677)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(98.72985% 0.009577 72.664)","--lab-label-warning-secondary":"oklch(80.98123% 0.149940 68.750)","--lab-label-warning-tertiary":"oklch(70.11346% 0.152989 68.857)","--lab-label-warning-quaternary":"oklch(55.86543% 0.122417 68.219)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(98.31403% 0.027558 147.033)","--lab-label-success-secondary":"oklch(77.69544% 0.228159 147.448)","--lab-label-success-tertiary":"oklch(67.10085% 0.197388 147.383)","--lab-label-success-quaternary":"oklch(53.45797% 0.157009 147.442)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(98.69528% 0.006207 255.474)","--lab-label-info-secondary":"oklch(80.30515% 0.099317 259.806)","--lab-label-info-tertiary":"oklch(69.49027% 0.160387 260.058)","--lab-label-info-quaternary":"oklch(56.23879% 0.227606 259.853)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.013010286081645773","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.012071078431372548","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.009560345877481427","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.00784313725490196","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(69.23260% 0.013029 286.055)"}},{"theme":"light","bg":"#808080","vars":{"--lab-bg-tone-2":"oklch(58.21536% 0.012099 286.018)","--lab-bg-tone-3":"oklch(58.21536% 0.012099 286.018)","--lab-label-primary":"oklch(13.77177% 0.013406 284.503)","--lab-label-secondary":"oklch(20.89710% 0.013787 291.711)","--lab-label-tertiary":"oklch(33.70211% 0.013945 291.371)","--lab-label-quaternary":"oklch(49.18380% 0.012632 285.926)","--lab-border-strong":"oklch(13.77177% 0.013406 284.503)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(13.49058% 0.050205 258.119)","--lab-label-brand-secondary":"oklch(20.89968% 0.076454 257.725)","--lab-label-brand-tertiary":"oklch(34.17043% 0.122830 257.309)","--lab-label-brand-quaternary":"oklch(49.70427% 0.178878 257.337)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.22004% 0.058352 29.234)","--lab-label-danger-secondary":"oklch(21.88171% 0.089792 29.234)","--lab-label-danger-tertiary":"oklch(35.54757% 0.145582 28.627)","--lab-label-danger-quaternary":"oklch(51.73054% 0.211869 28.643)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(13.56514% 0.029751 68.088)","--lab-label-warning-secondary":"oklch(20.90753% 0.046395 66.438)","--lab-label-warning-tertiary":"oklch(34.00266% 0.074904 67.452)","--lab-label-warning-quaternary":"oklch(49.79045% 0.108745 68.715)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(91.20808% 0.064865 69.118 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.01439% 0.039836 145.937)","--lab-label-success-secondary":"oklch(20.10741% 0.059351 147.255)","--lab-label-success-tertiary":"oklch(32.71649% 0.095649 147.616)","--lab-label-success-quaternary":"oklch(47.52181% 0.139141 147.559)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(88.67895% 0.198079 147.416 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(13.83602% 0.055501 259.684)","--lab-label-info-secondary":"oklch(21.26627% 0.087439 260.146)","--lab-label-info-tertiary":"oklch(34.39884% 0.140838 260.069)","--lab-label-info-quaternary":"oklch(50.11242% 0.202893 259.861)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.11057506131405687","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.11023622047244083","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.07169755954418727","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.04724409448818886","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(33.70211% 0.013945 291.371)","--lab-border-brand-strong":"oklch(34.17043% 0.122830 257.309 / 1)","--lab-border-danger-strong":"oklch(35.54757% 0.145582 28.627 / 1)","--lab-border-info-strong":"oklch(34.39884% 0.140838 260.069 / 1)"}},{"theme":"light","bg":"#3A3A3C","vars":{"--lab-bg-tone-2":"oklch(36.65084% 0.011912 285.797)","--lab-bg-tone-3":"oklch(36.65084% 0.011912 285.797)","--lab-label-primary":"oklch(98.92134% 0.005280 286.303)","--lab-label-secondary":"oklch(82.53513% 0.012530 281.039)","--lab-label-tertiary":"oklch(72.82755% 0.014297 286.039)","--lab-label-quaternary":"oklch(61.25907% 0.011943 286.042)","--lab-border-strong":"oklch(98.92134% 0.005280 286.303)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(98.77036% 0.005722 264.533)","--lab-label-brand-secondary":"oklch(82.44675% 0.088464 257.008)","--lab-label-brand-tertiary":"oklch(73.08383% 0.140495 257.442)","--lab-label-brand-quaternary":"oklch(61.77245% 0.208353 257.413)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(61.75781% 0.208491 257.338 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(98.86605% 0.005516 31.054)","--lab-label-danger-secondary":"oklch(83.38591% 0.092088 28.223)","--lab-label-danger-tertiary":"oklch(74.63167% 0.153784 28.842)","--lab-label-danger-quaternary":"oklch(64.10554% 0.244701 28.706)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(98.75683% 0.008520 67.727)","--lab-label-warning-secondary":"oklch(83.08426% 0.131366 68.787)","--lab-label-warning-tertiary":"oklch(73.86147% 0.161425 68.614)","--lab-label-warning-quaternary":"oklch(61.96370% 0.135496 68.532)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(98.51065% 0.024195 147.300)","--lab-label-success-secondary":"oklch(80.08887% 0.235054 147.469)","--lab-label-success-tertiary":"oklch(70.67977% 0.207519 147.455)","--lab-label-success-quaternary":"oklch(59.24524% 0.173588 147.533)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(98.77036% 0.005722 264.533)","--lab-label-info-secondary":"oklch(82.42821% 0.087905 259.666)","--lab-label-info-tertiary":"oklch(73.17409% 0.139071 259.898)","--lab-label-info-quaternary":"oklch(61.97090% 0.205878 259.740)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.06909778454881221","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.060913705583756306","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.040609137055837526","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.028061954965508236","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(72.82755% 0.014297 286.039)"}},{"theme":"light","bg":"#007AFF","vars":{"--lab-bg-tone-2":"oklch(57.87475% 0.012117 286.015)","--lab-bg-tone-3":"oklch(57.87475% 0.012117 286.015)","--lab-label-primary":"oklch(13.41536% 0.016099 291.497)","--lab-label-secondary":"oklch(20.01464% 0.013939 291.638)","--lab-label-tertiary":"oklch(33.31157% 0.013986 291.359)","--lab-label-quaternary":"oklch(48.82850% 0.012656 285.922)","--lab-border-strong":"oklch(13.41536% 0.016099 291.497)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(13.49058% 0.050205 258.119)","--lab-label-brand-secondary":"oklch(20.23588% 0.071518 256.892)","--lab-label-brand-tertiary":"oklch(33.52307% 0.122654 257.729)","--lab-label-brand-quaternary":"oklch(49.33014% 0.177503 257.333)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.22004% 0.058352 29.234)","--lab-label-danger-secondary":"oklch(20.90400% 0.085780 29.234)","--lab-label-danger-tertiary":"oklch(34.90075% 0.142917 28.593)","--lab-label-danger-quaternary":"oklch(51.33845% 0.210254 28.629)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(13.56514% 0.029751 68.088)","--lab-label-warning-secondary":"oklch(20.32691% 0.044866 67.175)","--lab-label-warning-tertiary":"oklch(33.70499% 0.073308 69.356)","--lab-label-warning-quaternary":"oklch(49.32505% 0.107532 68.994)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(90.50991% 0.070001 68.839 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.01439% 0.039836 145.937)","--lab-label-success-secondary":"oklch(19.36939% 0.056254 147.869)","--lab-label-success-tertiary":"oklch(32.05045% 0.093836 147.561)","--lab-label-success-quaternary":"oklch(47.21271% 0.138736 147.423)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(87.96697% 0.214930 147.350 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(13.83602% 0.055501 259.684)","--lab-label-info-secondary":"oklch(20.33878% 0.084139 260.257)","--lab-label-info-tertiary":"oklch(33.98919% 0.139378 260.097)","--lab-label-info-quaternary":"oklch(49.73960% 0.201561 259.877)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.1414396647356093","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.1805418331471749","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.09073588245366788","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.06430782839451565","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(33.31157% 0.013986 291.359)","--lab-border-brand-strong":"oklch(33.52307% 0.122654 257.729 / 1)","--lab-border-danger-strong":"oklch(34.90075% 0.142917 28.593 / 1)","--lab-border-info-strong":"oklch(33.98919% 0.139378 260.097 / 1)"}},{"theme":"light","bg":"#FF3B30","vars":{"--lab-bg-tone-2":"oklch(63.60048% 0.011829 286.059)","--lab-bg-tone-3":"oklch(63.60048% 0.011829 286.059)","--lab-label-primary":"oklch(13.83495% 0.015576 284.180)","--lab-label-secondary":"oklch(25.12484% 0.015017 285.269)","--lab-label-tertiary":"oklch(36.40556% 0.013673 291.446)","--lab-label-quaternary":"oklch(51.30243% 0.012497 285.951)","--lab-border-strong":"oklch(13.83495% 0.015576 284.180)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(14.05977% 0.051776 257.879)","--lab-label-brand-secondary":"oklch(25.33060% 0.091490 257.423)","--lab-label-brand-tertiary":"oklch(36.69778% 0.133197 257.540)","--lab-label-brand-quaternary":"oklch(51.93456% 0.187074 257.359)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.49010% 0.059461 29.234)","--lab-label-danger-secondary":"oklch(26.17120% 0.107130 28.474)","--lab-label-danger-tertiary":"oklch(38.31782% 0.156989 28.748)","--lab-label-danger-quaternary":"oklch(53.87750% 0.220648 28.624)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(14.09840% 0.030367 70.955)","--lab-label-warning-secondary":"oklch(25.16306% 0.055216 68.014)","--lab-label-warning-tertiary":"oklch(36.95716% 0.080989 68.209)","--lab-label-warning-quaternary":"oklch(51.83499% 0.113346 68.533)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(94.55166% 0.039779 69.746 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.47470% 0.038038 148.984)","--lab-label-success-secondary":"oklch(24.13011% 0.070822 147.468)","--lab-label-success-tertiary":"oklch(35.33425% 0.103721 147.463)","--lab-label-success-quaternary":"oklch(49.62199% 0.145290 147.559)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(93.08890% 0.111383 147.112 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(14.07469% 0.058967 260.480)","--lab-label-info-secondary":"oklch(25.53067% 0.104920 260.137)","--lab-label-info-tertiary":"oklch(37.14168% 0.149591 259.762)","--lab-label-info-quaternary":"oklch(52.13660% 0.212021 259.943)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.1835748792270531","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.4395613333149519","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.1777791862086449","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.1016772651089421","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-badge-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(56.86744% 0.193154 259.910 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(57.10674% 0.215668 258.445 / 1)","--lab-fill-danger":"oklch(59.02521% 0.231590 28.749 / 1)","--lab-icon":"oklch(36.40556% 0.013673 291.446)","--lab-border-brand-strong":"oklch(36.69778% 0.133197 257.540 / 1)","--lab-border-danger-strong":"oklch(38.31782% 0.156989 28.748 / 1)","--lab-border-info-strong":"oklch(37.14168% 0.149591 259.762 / 1)"}}]} +{"_meta":{"purpose":"Байт-точный golden границы JS↔WASM: recheckContrast/_recheckContrastMulti и полный snapshot resolveTheme.vars.","regenerated":"2026-07-10","regen_reason":"ADR-0004: point-glow решается по конечным encoded-sRGB8 screen-state; alpha эмитируется кратчайшей decimal-записью без повторного округления.","drift_scope":"Относительно origin/main изменены ровно 24 листа resolveVars: только --lab-fx-glow-{brand,danger,warning,neutral}-alpha на 6 фонах. P1 (2026-07-21) дополнительно изменил 30 fill-leaves: fill-accent, fill-danger, badge-fill-{brand,danger,info} на 6 light-фонах — старый pair_fill притемняющий nudge удалён, эмиссия fill теперь identity-якорь бренда; recheck по-прежнему 0/2752 drift (замерено).","recheck_unchanged":"Секция recheck: 2752/2752 числовых значений, то есть 1376/1376 пар (lc, wcag), байт-идентичны origin/main; ни одно значение recheckContrast не изменено.","numeric_provenance":{"glow_alpha":"Старый fixed-48 bisection + 4-decimal alpha заменён перебором конечных sRGB8-state, внутренней alpha выбранного интервала и shortest-roundtrip binary64 CSS.","scope_check":"Фактический структурный diff вычислен по каждому листу resolveVars; 4 alpha-ключа × 6 записей = 24."},"wcag_floors_not_weakened":"Glow — декоративная роль без WCAG-пола. Отдельно подтверждено: все 1376 пар (2752 числовых значения) recheck неизменны, поэтому измеренный контраст ни одной проверяемой роли не ослаблен.","isolated_verification_required":"Регенерация принимается только после независимой проверки scope, recheck-инварианта и полного Rust/npm/browser gate.","partition_correction":{"regenerated":"2026-07-11","reason":"Коррекция канонической binary64 alpha по фактическому midpoint encoded-sRGB8 partition без дополнительного округления.","drift_scope":"Ровно 17 alpha leaves: light/#000000 danger и четыре Glow alpha на каждом из #808080, #3A3A3C, #007AFF, #FF3B30; остальные resolveVars-листья неизменны.","recheck_unchanged":"2752/2752 числовых значений, то есть 1376/1376 пар (lc, wcag), побитно неизменны.","numeric_provenance":{"halo":"#FF3B30","background":"#000000","state":"#030101","lower_bits":"0x3f85555555555555","upper_bits":"0x3f8c1c1c1c1c1c1c","midpoint_bits":"0x3f88b8b8b8b8b8b8","midpoint":"0.012071078431372548","previous_bits":"0x3f88b8b8b8b8b8b9","previous_relation":"1 ULP выше, внутри той же partition"},"exhaustive_proof":"65 536 channel partitions и seam: state/composite outputs неизменны.","performance":"Full-range → bracketed exact search: base 19.7→4.37 µs, bloom 74.1→16.2 µs, long 656→139 µs."},"history":{"previous_regenerated":"2026-07-10","previous_regen_reason":"Глава #64 (ADR-0003): ось читаемости активирована в домене Ys — реактивный recheck (measure_contrast/recheck_against) и solver-вывод считаются в Ys. recheck flat и resolveVars регенерированы против пересобранного движка; inputs (theme/bg/fgs) сохранены. semver-major по ADR.","previous_drift_scope":"resolveVars: exactly 24 leaves changed, all --lab-fx-glow-{brand,danger,warning,neutral}-core (glow-centre colour, background-independent → 4 distinct values). No other var moved. glow base/alpha, labels, borders, fills, backgrounds all byte-identical.","previous_recheck_unchanged":"Исторический regen также не менял recheck; прежний текст ошибочно называл 2752 числа парами. Фактический объём: 1376 пар (lc, wcag).","previous_numeric_provenance":{"glow-brand-core":"oklch(78.84894% 0.062240 265.472) -> oklch(78.76611% 0.108476 257.256): chroma rises to the blue gamut wall at the functional lightness (fixed-fraction under-saturated it); L ±0.08pp, hue shifts to the cusp.","glow-danger-core":"oklch(81.62208% 0.103545 27.533) -> oklch(81.77103% 0.102764 29.025): near-identical (red already sat near its wall).","glow-warning-core":"oklch(88.80612% 0.081204 68.866) -> oklch(88.88181% 0.082838 68.777): near-identical.","glow-neutral-core":"oklch(99.97226% 0.001314 106.423) -> oklch(100.00000% 0.000000 89.876): neutral hue is achromatic → gamut wall chroma is 0 (was fixed-fraction residue noise); exact achromatic source stays on the neutral ray."},"previous_wave1_scope":"resolveVars: 69 info-* leaves changed across 6 theme×bg entries. Zero non-info drift (scope-checked). recheck untouched."},"endpoint_recovery":{"regenerated":"2026-07-17","reason":"Acceptance is checked before low-contrast dead-zone and physical-endpoint rejection, so previously false-failed opaque border endpoints now resolve.","drift_scope":"Exactly 9 resolveVars leaves added: border-{brand,danger,info}-strong on light #808080, #007AFF and #FF3B30. No existing leaf changed or disappeared.","recheck_unchanged":"Every committed recheck value remains bit-identical; the parity test compares all 2752 numbers before resolveVars.","proof":"agnostic_gates::accepted_endpoint_recovery_keeps_previously_false_failed_borders_legal plus full Rust workspace and WASM boundary parity."}},"recheck":[{"theme":"light","bg":"#FFFFFF","fgs":["#F7F7FF","#F7F7FF","#0A0A10","#71717A","#94949E","#BDBDC7","#94949E","#0A0A10","#00030E","#0057BB","#037BFF","#78AFFF","#150000","#BE0005","#FF070E","#FF9A8C","#1B0D00","#A06300","#D28300","#FFAA3A","#000B01","#007C2D","#00A73F","#00D452","#020013","#4D00F9","#6D6EFF","#9FA9FF"],"flat":[0,1.0658201232723763,0,1.0658201232723763,104.65963437608701,19.74046779866239,70.1623092547118,4.832895561154151,53.96706418364319,3.004779237664955,33.34341874861831,1.8637664731545371,53.96706418364319,3.004779237664955,104.65963437608701,19.74046779866239,105.59876563358553,20.60103636973117,79.91552226990729,6.816302360996974,63.95198968935827,3.97647793086433,41.89234722606997,2.2400949113548063,105.32470288110206,20.35108757719671,78.97384099389187,6.579727828852003,63.90360859563009,3.970705427078051,37.83221395673913,2.048194921340976,103.87315757816087,19.018778265876662,70.62528347734393,4.90716956443272,53.97808064225952,3.0056474129326713,34.232350404909745,1.8982213760304238,104.97702200816887,20.032297013031588,73.2226464627747,5.355840815772706,56.123729301186145,3.182173571701684,36.54497093010938,1.9925549350335838,105.76444562516849,20.751302844974063,83.48658341134008,7.825697912025839,63.67798680778349,3.9439477616440737,40.86459333479343,2.1890112231357013]},{"theme":"light","bg":"#000000","fgs":["#010103","#010103","#F1F1FC","#B3B3BC","#909099","#65656D","#909099","#F1F1FC","#E6F0FF","#60A1FF","#0074F3","#004CA4","#FFF4F2","#FF8273","#F40009","#A80004","#FFF7EE","#F79C00","#C97E00","#8F5800","#C2FFC9","#00C84D","#00A03C","#006E26","#EEF0FF","#9099FF","#6662FF","#4300DB"],"flat":[0,1.0069471255994658,0,1.0069471255994658,-99.67218963360757,18.727928195985914,-63.80513707672789,10.090949031745104,-45.863656882792206,6.635143500688325,-26.33477890397734,3.635637824948841,-45.863656882792206,6.635143500688325,-99.67218963360757,18.727928195985914,-97.97941453819666,18.27263411531394,-53.55180732861014,8.039306941172763,-34.54692380627581,4.792369408161928,-17.418806999279397,2.56984376276454,-102.41236835704379,19.474434420712562,-56.92703132210305,8.692613650917824,-34.93266406694178,4.850563950189369,-18.308962222075785,2.6667193472488013,-103.5613239139708,19.790915044333452,-61.97487030298502,9.71021814570805,-44.901407836051874,6.467843223430967,-25.783665577412222,3.5638173443979557,-98.60837652742211,18.44127602271432,-60.30793382928855,9.368875012646658,-42.707239087904505,6.093571182387199,-23.370874926227668,3.2583602660985775,-98.9883689300502,18.54346384276384,-54.32153113615954,8.18635152260471,-34.304902287955215,4.756029101219059,-14.435475219756622,2.261552965854495]},{"theme":"light","bg":"#808080","fgs":["#7A7A82","#7A7A82","#010103","#18171E","#37363E","#5B5B64","#37363E","#010103","#000002","#00163A","#003272","#004494","#040000","#3A0000","#760002","#990003","#0B0400","#261300","#512F00","#845100","#000200","#001D05","#004114","#006322","#000002","#160059","#2B0097","#3B00C5"],"flat":[0,1.0777393702545288,0,1.0777393702545288,40.18994509287661,5.280525528202377,36.81932911616927,4.505560397043893,27.93898600302036,3.0217055248761144,13.845788611978202,1.7013528597992067,27.93898600302036,3.0217055248761144,40.18994509287661,5.280525528202377,40.3306726916817,5.312553092992316,36.89312592554248,4.521969910173767,28.754774555141132,3.1292028976206594,22.090354756391577,2.35851620111828,40.23106479600237,5.289901483963394,36.823385380889306,4.5064610721321205,27.786796188195932,3.002060282138028,21.02583740042693,2.2570951143110336,39.64148780057383,5.154352713354357,36.89828467875601,4.523118840482662,27.981450040156208,3.027209986332121,13.567318350507929,1.6836851754208233,40.150141663678234,5.271436537678366,36.85731353296706,4.514000513189092,27.852320260403722,3.0105025419148825,16.643886294769857,1.8937047658181707,40.3306726916817,5.312553092992316,36.84988795298528,4.512349526507044,30.916517468784825,3.4313626667845316,25.033605894158644,2.6690076358452903]},{"theme":"light","bg":"#3A3A3C","fgs":["#3E3E45","#3E3E45","#F2F2FD","#BBBBC5","#9E9EA7","#7A7A82","#9E9EA7","#F2F2FD","#E7F1FF","#73ADFF","#2985FF","#0060CB","#FFF5F4","#FF9687","#FF4336","#CD0006","#FFF8F0","#FFA62C","#DC8A00","#AC6B00","#C7FFCC","#00D251","#00B043","#008631","#EFF1FF","#9CA6FF","#767AFF","#532BFF"],"flat":[0,1.0699484563148034,0,1.0699484563148034,-89.06520303275792,10.211241554507897,-56.964055924386784,5.959497869408446,-41.60773958742316,4.2707825803649335,-24.25691832785775,2.6663016206717356,-41.60773958742316,4.2707825803649335,-89.06520303275792,10.211241554507897,-87.32090210121694,9.956824779623638,-48.0046310941281,4.945145596338778,-30.285195552724065,3.1849116126306156,-14.342034884792934,1.9106934427040745,-91.71639880150975,10.602849175762582,-51.97724928251108,5.385053682831725,-31.570923815646545,3.301015045785777,-14.82740446463819,1.94471301206827,-92.86717481243348,10.774663089384916,-55.64998948221256,5.805759082702303,-40.41406674606042,4.149700467279057,-23.7537806706175,2.6249801387527425,-87.99158651504085,10.054343074329001,-53.75183524673264,5.586666992924044,-38.313874917805634,3.940371955014153,-21.037647044419426,2.407284189061088,-88.33220875070053,10.104016013712561,-48.80525652513833,5.032519885671211,-30.915189659062865,3.2415642790980215,-11.323318014385267,1.7063261265170042]},{"theme":"light","bg":"#007AFF","fgs":["#797981","#797981","#020205","#16151C","#36353D","#72727A","#36353D","#020205","#000103","#001536","#003374","#0058BC","#070000","#360000","#730002","#BE0005","#0F0500","#241200","#4F2F00","#A16400","#000400","#001B05","#003F13","#007C2D","#000005","#140055","#3300AC","#4E00FA"],"flat":[0,1.0745907693903731,0,1.0745907693903731,39.47891404105317,5.158402202047827,36.63906407938327,4.513939148043301,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.47891404105317,5.158402202047827,39.65687576920386,5.198408498908002,36.59714090951085,4.504660010775197,27.83078380746869,3.029349552004155,13.31049770996219,1.6744770124926043,39.57933742278427,5.181007308853048,36.66186584356392,4.51899176883356,27.77510172821011,3.0221297438766705,12.721590912296357,1.6379804580418844,38.8564182220264,5.016999835671664,36.579572970042136,4.500775701626332,27.65113132417139,3.006116231224861,0,1.205042331050678,39.39108202991847,5.138573889881769,36.624715730830154,4.510761781161014,27.902773646365304,3.038708829709556,0,1.3333017445114326,39.737197591996,5.216381929144518,36.59037871155487,4.5031645842195545,27.68585404738298,3.010592990868115,17.038043883395044,1.933101474636693]},{"theme":"light","bg":"#FF3B30","fgs":["#8A8A92","#8A8A92","#030306","#212129","#3E3D45","#76767F","#3E3D45","#030306","#000104","#00204D","#003B83","#005CC4","#080000","#4C0001","#830002","#C70006","#0F0600","#331C00","#5B3600","#A76800","#000400","#002809","#004917","#00822F","#000005","#1F0075","#3A00C3","#511AFF"],"flat":[0,1.0356140935636031,0,1.0356140935636031,43.57584669970237,5.806877937534237,38.3004661979112,4.504747008392574,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.57584669970237,5.806877937534237,43.87966672163739,5.884401548408216,38.30767260595269,4.50632138120243,29.16726657041677,3.0308664461202253,15.823096179531001,1.7789458759332724,43.782795788734404,5.8597651770218455,38.402450836988166,4.527103297945568,29.016037258963053,3.011424325654164,14.9864556348382,1.7254955647131072,42.99821792375369,5.657954629703501,38.41622407485322,4.5301350068404425,28.93769973409828,3.0014083479801514,0,1.28054929135364,43.62397616937584,5.819206103341516,38.406807106466914,4.528061863682665,29.022563392947294,3.012260432085235,8.92751562582044,1.3982348229239339,43.970091731453365,5.907320242919889,38.28628402517786,4.501651045763603,28.99214635836292,3.0083657301901288,19.11088367642911,2.0125842767555064]},{"theme":"light","bg":"#101012","fgs":["#15151B","#15151B","#F2F2FC","#B4B4BE","#93939C","#696972","#93939C","#F2F2FC","#E6F0FF","#64A4FF","#0077F9","#0050AC","#FFF4F3","#FF8777","#F9000A","#B00005","#FFF7EF","#FA9E00","#CD8000","#955C00","#C3FFC9","#00CA4E","#00A33D","#007329","#EEF0FF","#939CFF","#6967FF","#4600E6"],"flat":[0,1.045340264415452,0,1.045340264415452,-98.5838326466521,17.08955684747884,-62.72698384194396,9.243246994613658,-45.67498009680545,6.239717532288448,-26.395025771311026,3.4974414103185016,-45.67498009680545,6.239717532288448,-98.5838326466521,17.08955684747884,-96.3221346483494,16.53807546575917,-53.23458352949761,7.5085332653696355,-34.299151794570456,4.531377660721796,-17.34040000814869,2.4827755446650244,-100.79897840003042,17.636700891614694,-56.73966900010428,8.131153426700068,-34.4661942600266,4.554628420782135,-18.26813498707333,2.5778416349364046,-101.94670279716274,17.922901715066683,-61.50032492399525,9.010497025774457,-44.48245067627942,6.049054371037485,-25.983086445749187,3.447217107352778,-97.04991927160123,16.714741751700544,-59.578454823729174,8.650894122604043,-42.30409033566848,5.707629679225331,-23.50941826359813,3.1535587190594883,-97.33108904020293,16.783196253636362,-53.9780650339559,7.638815670143083,-34.15649094558268,4.511565332868746,-14.178333309149869,2.174938899863266]},{"theme":"light","bg":"#F6F8FA","fgs":["#F0F0FA","#F0F0FA","#0A0910","#707079","#8F8F99","#BCBCC5","#8F8F99","#0A0910","#00030D","#0057B9","#0079FD","#74ADFF","#150000","#BC0005","#FD000A","#FF9788","#1B0D00","#9F6200","#CB7F00","#FFA730","#000B01","#007B2C","#00A63E","#00D251","#020013","#4C00F7","#6C6CFF","#9DA6FF"],"flat":[0,1.0634215248159875,0,1.0634215248159875,100.62201386979996,18.61882254505944,66.47667620763235,4.605948460093869,52.23653324893716,3.0084294463712395,29.780700684603257,1.7710808257265196,52.23653324893716,3.0084294463712395,100.62201386979996,18.61882254505944,101.48497819102282,19.361251289328656,75.9364891028185,6.438321694919453,60.636932359482174,3.8278153397206016,38.76699274290234,2.152541489746932,101.19913515757631,19.11640864166299,75.28055256994783,6.281220843840182,60.46094873358925,3.807428346232839,34.70184973776556,1.9658801332164664,99.74758985463511,17.864929125608796,66.9127104243937,4.673002507305443,52.13428535623209,3.0001216660302674,31.16352525448906,1.8227359456035261,100.85145428464311,18.816958763489637,69.48045983543288,5.0977335979175304,52.421867335088024,3.0235758695027473,33.32486172802245,1.9082022515525083,101.63887790164272,19.492343272893066,79.67393134344084,7.442688338927282,60.17031912503092,3.7741072518393395,37.967753096619255,2.113772626279229]},{"theme":"light","bg":"#1C1C1E","fgs":["#202028","#202028","#F1F1FD","#B6B6BF","#95959E","#6D6C75","#95959E","#F1F1FD","#E6F1FF","#67A5FF","#0079FD","#0053B2","#FFF5F3","#FF8A7A","#FD000A","#B60005","#FFF7EF","#FC9F00","#D08200","#9A5F00","#C4FFCA","#00CB4E","#00A53E","#00772A","#EEF1FF","#949EFF","#6B6BFF","#4900EE"],"flat":[0,1.0522076023272475,0,1.0522076023272475,-96.27140987076255,15.184146579953019,-61.97466067394124,8.452688508186561,-44.87094637123084,5.728792540137694,-25.977188885961883,3.283145241842075,-44.87094637123084,5.728792540137694,-96.27140987076255,15.184146579953019,-94.97224440690107,14.900628115594163,-51.99577035710509,6.808135431331698,-33.457001357615106,4.175350120738554,-16.755883343489252,2.3335896778079332,-99.44736446714371,15.886233758087014,-55.869159717403925,7.428487313030341,-33.63398343987836,4.1977071628099685,-17.709012021143003,2.4235530906296177,-100.15616825242344,16.04465607216319,-60.39258141645385,8.181935837052826,-43.77686148964125,5.57032618168592,-25.67861999448382,3.2497240951569792,-95.39392806862337,14.992417327878547,-58.246405974587134,7.820609198173194,-41.3596549106396,5.227261702394524,-23.16505433719768,2.9752806858720673,-95.97861011098902,15.120061263203354,-52.9765437482588,6.963016139185695,-33.57839540296167,4.190679013723035,-13.485138200601865,2.040069034387161]},{"theme":"light","bg":"#7C3AED","fgs":["#707078","#707078","#F4F4FE","#E3E4ED","#BDBDC6","#A6A6B0","#BDBDC6","#F4F4FE","#EBF3FF","#D5E6FF","#92BFFF","#4291FF","#FFF8F7","#FFDDD8","#FFA597","#FF6253","#FFFAF5","#FFE0BE","#FFAA39","#E79100","#D0FFD4","#7DFF93","#00DA54","#00B947","#F1F4FF","#DFE4FF","#AEB8FF","#8087FF"],"flat":[0,1.1608373681184396,0,1.1608373681184396,-73.98396246220521,5.215032461901156,-64.0643931275358,4.500912896664839,-41.75099800228171,3.055051474145459,-29.486682699107686,2.3616035737730514,-41.75099800228171,3.055051474145459,-73.98396246220521,5.215032461901156,-72.43421936609613,5.100687932363686,-64.08586870464498,4.502412953317652,-41.11294430990105,3.017135229848019,-18.888486914529935,1.8251241221961068,-76.90365537296871,5.4332059719499135,-64.06334225320066,4.50083949888721,-40.940708789235714,3.0069340578770496,-21.122834074579163,1.9331720160112165,-77.70409895709017,5.493642615376888,-64.34147182620212,4.520282197700913,-40.849183913847796,3.0015190917179395,-28.18413111501551,2.292444746213784,-72.9506558335481,5.138679113149092,-64.10668565953954,4.5038671985064,-41.2870784084647,3.027463512408998,-26.013778316259767,2.1791858289450103,-73.64084437140687,5.1896286230945075,-64.42349258712335,4.5260223420377566,-41.02780633656069,3.0120908713744514,-19.464187683477977,1.8526993919522168]},{"theme":"light","bg":"#123456","fgs":["#36363D","#36363D","#F2F2FD","#BEBEC8","#A2A2AC","#808089","#A2A2AC","#F2F2FD","#E8F1FF","#79B0FF","#368BFF","#0065D6","#FFF6F4","#FF9B8D","#FF5446","#D80007","#FFF8F1","#FFAB3F","#E18E00","#B47000","#C8FFCD","#00D552","#00B545","#008D34","#EFF1FF","#A0AAFF","#7B81FF","#573FFF"],"flat":[0,1.0609289970892934,0,1.0609289970892934,-91.39519035537737,11.4423466076867,-60.94367397154904,6.896920022598847,-46.020165423777584,5.026435795944436,-29.36949737122932,3.250019698594834,-46.020165423777584,5.026435795944436,-91.39519035537737,11.4423466076867,-89.77514075602531,11.177468536043195,-51.89752791553575,5.733156384550998,-34.996215684604906,3.8114980409485155,-18.92394323577027,2.320895932067837,-94.48648764812391,11.954651961610136,-56.02375667309079,6.252768618847473,-36.81873931987068,4.002056146272223,-19.591172380553846,2.375625103310219,-95.24016771148194,12.080915286992608,-59.85145182180837,6.751641124414219,-44.82390104707481,4.887508677146329,-28.683175933367217,3.184369254481423,-90.45906258458693,11.288985892577246,-57.499124974387314,6.443154991463433,-42.83495757582209,4.660276446547384,-26.099142978345885,2.9428672820648862,-90.66219607331998,11.322193559065964,-52.9772743130274,5.867283737103295,-35.76790053375578,3.8916727925995533,-16.863337707955058,2.1560372721390864]},{"theme":"light","bg":"#ABCDEF","fgs":["#C2C2CB","#C2C2CB","#06060C","#55545D","#706F78","#A1A1AA","#706F78","#06060C","#000209","#00479B","#0065D5","#3289FF","#100000","#9F0004","#D70007","#FF4F41","#170A00","#7A4A00","#9F6200","#DF8C00","#000801","#006322","#00822F","#00B344","#01000D","#3E00CE","#573EFF","#797EFF"],"flat":[0,1.0705446339746656,0,1.0705446339746656,75.64582413051765,12.232204997602986,52.76667497081496,4.519371986307913,41.423484798334584,3.0020546798073307,18.127484103049046,1.5512322351556214,41.423484798334584,3.0020546798073307,75.64582413051765,12.232204997602986,76.22533906008685,12.552007092013115,56.99670466281028,5.352680994694784,44.43662180236468,3.3253647200326193,29.122033451491582,2.0641033245604916,76.01516726706762,12.436514137733148,55.97147975339624,5.133613537650522,43.91010121645754,3.2654000659595037,27.461071919951625,1.9716236837030474,74.81611736383091,11.770648316029503,52.816193854903005,4.528105409994289,41.51373908005361,3.011071841176318,19.679891349505557,1.6112041351931181,75.72958089661125,12.278654436624837,52.80881394476793,4.526802423347816,41.42233250009274,3.001939806510638,21.536768417458934,1.687644517337887,76.3513076320574,12.62087594492386,59.99704797613187,6.063965240585196,46.62694808670478,3.592268428661898,28.6381619838115,2.036506690369533]},{"theme":"light","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"dark","bg":"#FFFFFF","fgs":["#E7E7F1","#D9D9E2","#0D0D12","#707079","#94949D","#BCBCC6","#94949D","#0D0D12","#000414","#0053C4","#1F78FF","#79ACFF","#190000","#BC0016","#FD0021","#FF978D","#1D0B00","#A65B00","#DA7A00","#FFA658","#000E02","#007C2A","#00A63C","#00D24E","#04001A","#5900F2","#7867FF","#A4A4FF"],"flat":[10.564452802176923,1.2281904700369508,18.372353597432387,1.402460683906872,104.27090588423802,19.38311547953439,70.6022439311581,4.903434648448188,54.00450766949271,3.0077315832596954,33.86624309585679,1.8839141891835494,54.00450766949271,3.0077315832596954,104.27090588423802,19.38311547953439,105.42046624663428,20.43859328774187,80.31672424485741,6.9206271592755195,64.53598724808649,4.047139863973963,42.92136358171458,2.2930773168482466,105.12312344447312,20.1664284240786,79.32640956847692,6.666965706057784,64.47466861031803,4.0396342482899685,38.694434835096864,2.0867987099188317,103.94997559222902,19.08898290736351,71.78028267942507,5.099770465607366,55.19920557284124,3.104259347966041,35.17783363962355,1.9359471784913758,104.66191026229393,19.742561272328775,73.25578885512941,5.361938351796974,56.57179613789485,3.2209892436744982,37.49012931672191,2.03317973864909,105.58294145619523,20.58664787402852,83.26627791326895,7.757864847967472,64.57504887916579,4.051931818616954,42.090577540190225,2.2501559682241092]},{"theme":"dark","bg":"#000000","fgs":["#030205","#08080D","#F0F0FA","#B1B1BB","#8F8F98","#64646D","#8F8F98","#F0F0FA","#E3EEFF","#639EFF","#006DFE","#0048AD","#FFF4F3","#FF7F74","#F1001F","#A80012","#FFF7F1","#FF921B","#D17400","#955100","#B8FFBE","#00C649","#009F39","#006E25","#EDEEFF","#9794FF","#725BFF","#4E00D6"],"flat":[0,1.0147465549687367,0,1.0508696650285665,-99.01083964835996,18.549513785944853,-62.774763175831374,9.875849762659984,-45.37711439886134,6.5503119047070335,-25.95111170367181,3.5855589616463144,-45.37711439886134,6.5503119047070335,-99.01083964835996,18.549513785944853,-96.73192161780433,17.93999294470544,-52.63286661912575,7.865273702162647,-33.381528921151094,4.618607106385301,-17.0501576858861,2.5303719690800346,-102.4562582898777,19.486486384763445,-56.148341062851905,8.53993960492931,-34.330992536827104,4.759940239487347,-18.37234103122508,2.6737006902768288,-103.68997976483836,19.82648045930809,-60.35961607275431,9.379380118591195,-43.39157032733722,6.209218370112115,-24.93643207012505,3.4548840566407524,-97.27916136850891,18.085610527348415,-59.34389647192141,9.173841233004914,-42.25887199411116,6.018336366435839,-23.360562325895305,3.2570864547421428,-97.9872053947921,18.274719246988955,-53.323021296304695,7.99582368531923,-33.63351308594995,4.6559156780457185,-14.771084781300106,2.2949481607054216]},{"theme":"dark","bg":"#808080","fgs":["#707078","#66666E","#030305","#18171D","#37363E","#5D5D64","#37363E","#030305","#000104","#00153F","#00317C","#00429F","#070000","#3A0002","#750009","#9B0010","#0C0300","#291200","#562D00","#8B4B00","#000300","#001D05","#004112","#006521","#010005","#1A0057","#350098","#4700C4"],"flat":[0,1.24296889833444,9.274501031402123,1.4407196981948422,39.91548097777799,5.217615096019717,36.836632862345205,4.5094036578339445,27.93898600302036,3.0217055248761144,13.086665786299626,1.6537770693375544,27.93898600302036,3.0217055248761144,39.91548097777799,5.217615096019717,40.20955594591163,5.284998875760269,36.83828085440759,4.509769828130583,28.330761142327287,3.0728704517581886,21.819504217645104,2.3321848000622474,40.142120786515875,5.269603471071473,36.80831529061993,4.503115584720142,27.930310922781615,3.0205822411426944,20.559717681283935,2.214401964672886,39.70511745091868,5.169077378914306,36.80795164205375,4.503034882134433,27.78871707797606,3.002307432697674,14.025581970431295,1.7128949100718707,40.051433392362526,5.248844071123953,36.85731353296706,4.514000513189092,27.870384117529113,3.0128341396537346,15.95953035602916,1.844055168824021,40.26997047853993,5.298759395894901,36.795231110735635,4.500212645278562,30.09285126953815,3.3133648365325183,24.185949678819867,2.5748913454036786]},{"theme":"dark","bg":"#3A3A3C","fgs":["#46464E","#4F4F57","#F1F1FA","#BABAC4","#9D9DA6","#797982","#9D9DA6","#F1F1FA","#E4EFFF","#75AAFF","#3482FF","#005AD5","#FFF6F4","#FF9389","#FF3C3B","#CC0019","#FFF8F2","#FFA350","#E58000","#B36300","#BCFFC2","#00D04D","#00AF3F","#00862E","#EEEFFF","#A2A1FF","#7F74FF","#601DFF"],"flat":[0,1.2140718035663858,0,1.3988859584097761,-88.35603271482154,10.107493939375463,-56.41682578047019,5.8952705955406675,-41.10063170437542,4.219157833086703,-23.840055313660137,2.6320437618590202,-41.10063170437542,4.219157833086703,-88.35603271482154,10.107493939375463,-86.07057705487603,9.776047393674569,-47.005198509651805,4.836992692850337,-29.617188814986996,3.125340410912816,-13.465221764046625,1.8500449052652255,-92.15650032550448,10.66842694645063,-51.122226750198095,5.289032001141636,-30.69564720892069,3.221769980092269,-14.697188723997265,1.9355550836437716,-92.95341233620333,10.787583067801071,-55.01595924446716,5.732183607436098,-39.01368610071904,4.00959458617392,-22.717127042375882,2.5408179478715844,-86.56463892830851,9.847321829129962,-52.766100540364825,5.474290510931042,-37.83315401910713,3.893128667535661,-21.00389596511428,2.404636707585164,-87.32881842479753,9.957973594755346,-47.6452882768299,4.906141960838558,-29.99057738527554,3.1585747205458907,-10.990631160230787,1.6845762464445797]},{"theme":"dark","bg":"#007AFF","fgs":["#6F6F77","#65656D","#040408","#16151B","#36353D","#72727A","#36353D","#040408","#000107","#00133B","#00317C","#0054C7","#0B0000","#360002","#730009","#BF0016","#100500","#261000","#542C00","#A85D00","#000501","#001B04","#004012","#007D2B","#010009","#180052","#3B00A6","#5A00F5"],"flat":[0,1.2399763057879079,9.137153276370956,1.4379357071162235,39.199487305374596,5.095159290353486,36.655643103420836,4.517612479062309,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.199487305374596,5.095159290353486,39.616537893860624,5.189361828546554,36.671589094740156,4.521147554384925,27.767977778595686,3.0212072610618272,13.560368041515986,1.6902988819780091,39.46146930028483,5.1544680971312,36.646426655727396,4.515570174173857,27.733751845040576,3.016779185756929,12.426352071081123,1.6200937148513173,38.82022467282525,5.008731246970903,36.66757146424993,4.520256699490143,27.6755983348751,3.009270049666561,0,1.2356833222737893,39.28492308543262,5.114543979353608,36.632422880871374,4.512468289727634,27.610461383700073,3.00088106913278,0,1.3173837917708568,39.666598999480925,5.200587158978297,36.5946359240296,4.504106003407952,27.684199915070796,3.0103795763779906,16.582944142840912,1.898781610023956]},{"theme":"dark","bg":"#FF3B30","fgs":["#7F7F87","#74747D","#040408","#212128","#3E3D45","#76767F","#3E3D45","#040408","#000107","#001E53","#00398D","#0058CF","#0C0000","#4C0004","#83000C","#C60018","#110500","#371A00","#603300","#AE6000","#000601","#002808","#004916","#00822D","#01000A","#250070","#4400BC","#5E01FF"],"flat":[0,1.119564506502328,0,1.304916965157494,43.43238144483196,5.770041002680692,38.322111022898454,4.5094781825179275,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.43238144483196,5.770041002680692,43.84943203331798,5.876721182230661,38.357196991852035,4.517162998132957,28.969046969390032,3.0054117916551304,16.078397205708793,1.7957132708136676,43.66281217184597,5.829141814712315,38.38176722933373,4.522556047220382,28.96308732518828,3.004650205577566,15.121014183458136,1.7339400568635355,43.01534021323247,5.66238735865634,38.36369120360285,4.518587529333456,28.956857085057415,3.003854272405285,0,1.32359073643957,43.42248485866928,5.7674953973596095,38.41370496023468,4.529580289565808,29.031977011275746,3.0134669332394415,8.949958172317846,1.3992774406692907,43.88937786124038,5.8868666342953615,38.32550423955951,4.510220548286027,28.94413025668513,3.002229117722787,19.264807559936084,2.024522036885816]},{"theme":"dark","bg":"#101012","fgs":["#1C1C22","#24242A","#F0F0FA","#B3B3BD","#92929B","#686871","#92929B","#F0F0FA","#E3EEFF","#66A0FF","#0E71FF","#004CB5","#FFF5F3","#FF8378","#F60020","#AF0013","#FFF7F1","#FF962A","#D57700","#9B5500","#B9FFBF","#00C849","#00A23A","#007226","#EDEEFF","#9997FF","#7460FF","#5200DF"],"flat":[0,1.1210017368042908,0,1.2316217101091165,-97.35355975851269,16.788671896406843,-62.18912907483276,9.1408846014785,-45.183954583215964,6.160892481462449,-25.971291980892453,3.445784610130369,-45.183954583215964,6.160892481462449,-97.35355975851269,16.788671896406843,-95.07464172795706,16.23701078357789,-51.883866319617056,7.27432706128743,-33.10437599843017,4.366728841176053,-16.962076325331164,2.444617555127284,-101.23789901188303,17.745933910216884,-55.660852739640006,7.937252290960222,-33.86013630190819,4.470540437936136,-18.127983335051407,2.5633448249431416,-102.03269987499108,17.94442049171427,-60.01549050114797,8.732123022916136,-43.24478677485694,5.853976070416037,-25.11442835418257,3.342537791539289,-95.74776769254933,16.399183837627458,-58.596724506079966,8.469603286006345,-41.852118066322895,5.637910373772879,-23.122294138224145,3.108849028833141,-96.32992550494482,16.539962663017093,-52.86610846158114,7.444323350911882,-33.336065162067605,4.398429825394501,-14.383943910910213,2.194178799785328]},{"theme":"dark","bg":"#F6F8FA","fgs":["#E0E0EA","#D2D2DC","#0D0D12","#717179","#8F8F98","#BCBCC6","#8F8F98","#0D0D12","#000414","#0053C4","#1F78FF","#79ACFF","#190000","#BC0016","#FD0021","#FF978D","#1D0B00","#A65B00","#D67800","#FFA658","#000E02","#007C2A","#00A63C","#00D24E","#04001A","#5900F2","#7867FF","#A4A4FF"],"flat":[10.34292311627503,1.2313464424988367,18.024461551245693,1.4097592283337514,100.14533816071224,18.207162386274927,66.07133001527934,4.544848448940367,52.273633182943,3.011452358576948,29.740675372331037,1.769619110018133,52.273633182943,3.011452358576948,100.14533816071224,18.207162386274927,101.29489852310851,19.198605473400605,76.19115652133168,6.500760037097026,60.41041952456072,3.801604173546957,38.795795858188825,2.153958743950203,100.99755572094737,18.94295256384705,75.20084184495119,6.262487955668726,60.349100886792264,3.7945539156195487,34.56886711157111,1.9601948416949677,99.82440786870325,17.93087452582946,67.65471495589931,4.7903727911067815,52.29898260017819,3.0135204434714913,31.0522659160978,1.8184953129572932,100.53634253876818,18.544800983402446,69.13022113160365,5.036635229225181,52.44622841436909,3.025575236651027,33.364561593196164,1.9098288766402804,101.45737373266948,19.337677744697757,79.14071018974319,7.287203401685083,60.44948115564005,3.8061054053754897,37.96500981666448,2.1136413881018767]},{"theme":"dark","bg":"#1C1C1E","fgs":["#28282E","#303036","#F0F1FA","#B5B5BE","#94949D","#6C6C74","#94949D","#F0F1FA","#E3EEFF","#69A2FF","#1975FF","#004FBB","#FFF5F3","#FF877C","#FA0021","#B50014","#FFF7F1","#FF9833","#D87900","#A05800","#B9FFC0","#00CA4A","#00A43B","#007628","#EDEEFF","#9B99FF","#7664FF","#5500E7"],"flat":[0,1.1612081374032734,0,1.2977584057597347,-96.00102363023473,15.124963081358866,-61.434200333395395,8.359778481952823,-44.37695589123639,5.656999216809453,-25.852207004995158,3.269134017520218,-44.37695589123639,5.656999216809453,-96.00102363023473,15.124963081358866,-93.28410718321774,14.535439506623602,-51.011442228336165,6.654206660130301,-32.65955270222981,4.075313081844305,-16.370466566638967,2.297770413224217,-99.44736446714371,15.886233758087014,-55.07262883280597,7.299026812522581,-33.02825162884881,4.121422426501604,-17.569909707299868,2.4103015359642868,-100.24216533025177,16.063919770413232,-58.9183675206033,7.932997007393653,-42.52780974275247,5.391835753982905,-24.79898612463087,3.1522681596337323,-93.99035989085725,14.687777164248876,-57.733604751916815,7.735299184328377,-40.905085629416114,5.1638402024196015,-22.782862127638978,2.93464773079297,-94.53939096020551,14.80664328764592,-51.95162400089297,6.801199303451522,-32.707141977036414,4.081250761977603,-13.69412377461175,2.0581050526656677]},{"theme":"dark","bg":"#7C3AED","fgs":["#7A7A83","#85858D","#F2F2FD","#E3E4ED","#BBBCC5","#A6A6AF","#BBBCC5","#F2F2FD","#E8F1FF","#D5E6FF","#95BEFF","#498FFF","#FFF9F8","#FFDDD8","#FFA59B","#FF5F57","#FFFAF6","#FFDFC5","#FFA95E","#F18700","#C6FFCB","#7DFF91","#00DA51","#00B943","#F0F1FF","#E1E3FF","#B4B6FF","#8982FF"],"flat":[-8.022975593833932,1.3402714370624624,-13.06659651622355,1.5567826841029107,-72.79588351600884,5.127281558149197,-64.0643931275358,4.500912896664839,-41.08533982136385,3.0154992993085026,-29.446612137967147,2.3594628663401775,-41.08533982136385,3.0154992993085026,-72.79588351600884,5.127281558149197,-71.17583391665679,5.008590480308264,-64.08586870464498,4.502412953317652,-40.969901639859465,3.0086620775128243,-18.492326685553408,1.8062558438836862,-77.39176152066469,5.470028106981068,-64.06334225320066,4.50083949888721,-41.06186552000793,3.0141084284175577,-20.58109958398818,1.9067218663179524,-77.74802214310357,5.496966722090798,-64.16882972322054,4.508209630901898,-40.97688137217631,3.00907529195687,-26.93048349706687,2.2267208299060117,-71.5855645088526,5.038503428518723,-64.0583201718401,4.500488740880354,-41.24499881268402,3.0249663274797034,-25.961518214862377,2.176489332337808,-72.19208007215988,5.082914152992658,-64.24580556994597,4.513590807561596,-40.91738125342747,3.005553523356943,-18.74578210381434,1.818317299241165]},{"theme":"dark","bg":"#123456","fgs":["#3E3E45","#47474E","#F0F0FC","#BDBDC6","#A1A1AA","#7F7F88","#A1A1AA","#F0F0FC","#E5EFFF","#7AADFF","#3D87FF","#005FDF","#FFF6F5","#FF988E","#FF4D48","#D5001A","#FFF8F3","#FFA75A","#EA8300","#BA6700","#BDFFC3","#00D34E","#00B341","#008C31","#EEEFFF","#A5A5FF","#837AFF","#6433FF"],"flat":[0,1.1989453999458657,0,1.3802668927515667,-90.21171279539291,11.248602775503162,-60.350304841650235,6.81783465078813,-45.467647083484636,4.962060105853706,-28.90763677945104,3.2057711392885686,-45.467647083484636,4.962060105853706,-90.21171279539291,11.248602775503162,-88.52359832003891,10.974551054175622,-50.82334067294272,5.601029591424501,-33.90019185783247,3.6989242542195706,-17.94937633357589,2.2421371448335408,-94.53061684959366,11.962030249162733,-55.11693338695639,6.136943021617957,-35.65662848796355,3.880065704029081,-19.010500723408704,2.3279588656978594,-95.32685818617963,12.095472485308715,-58.832789738116276,6.617312123916825,-43.099834270009964,4.690265818580579,-27.202021451205145,3.0448373808729228,-89.02366089613628,11.055448870118658,-56.507119659393844,6.314879036055816,-41.91393002442956,4.556652813501584,-25.675484951698337,2.9041378624661793,-89.65880574741696,11.158543725868578,-51.69548126800453,5.708204299589472,-34.40239467659594,3.750316223165759,-16.078998268001875,2.0949612264666513]},{"theme":"dark","bg":"#ABCDEF","fgs":["#B4B4BE","#A8A8B1","#09090F","#55545C","#706F78","#A1A1AB","#706F78","#09090F","#00020F","#0045A5","#0060E2","#3F88FF","#140000","#A10011","#D7001B","#FF4F49","#190900","#814600","#A85D00","#EA8300","#000A01","#006320","#00822D","#00B341","#030014","#4A00CC","#6537FF","#847BFF"],"flat":[8.489900665165298,1.2445786124510558,14.633674840112363,1.428005718026211,75.26124671135368,12.018395958758797,52.798813706484495,4.5250375920814765,41.423484798334584,3.0020546798073307,18.08917030758312,1.5497949541740348,41.423484798334584,3.0020546798073307,75.26124671135368,12.018395958758797,76.15878035868923,12.51550617725489,56.792209524954714,5.308053794065892,44.82231091099692,3.370285744389143,29.010809014184062,2.057710850183084,75.84645644595844,12.343365988484052,55.500674792931,5.036843578382145,43.81499067450534,3.25473208522667,27.348178994525146,1.9655632934834584,74.80511978941351,11.764533211175078,52.793708756474935,4.52413702940673,41.44647230556496,3.0043476386355414,20.422200521634597,1.6411239547419576,75.54552640875083,12.176514522007174,52.82929323710673,4.530419449281277,41.44477504659015,3.004178254346042,21.57431352051131,1.6892460110571705,76.19495675605003,12.535354496536943,59.24767070343283,5.876074797996776,46.58341111523108,3.5866744685580465,28.54022915013225,2.030988108287992]},{"theme":"dark","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"light-ic","bg":"#FFFFFF","fgs":["#F7F7FF","#F7F7FF","#0A0A10","#71717A","#94949E","#BDBDC7","#94949E","#0A0A10","#000110","#0042E2","#3B78FF","#85AEFF","#150000","#BD0011","#FF001B","#FF998D","#1A0500","#B04A00","#E96400","#FFA174","#000B01","#007C2D","#00A73F","#00D452","#00040B","#00639C","#0089D6","#4DB3FF"],"flat":[0,1.0658201232723763,0,1.0658201232723763,104.65963437608701,19.74046779866239,70.1623092547118,4.832895561154151,53.96706418364319,3.004779237664955,33.34341874861831,1.8637664731545371,53.96706418364319,3.004779237664955,104.65963437608701,19.74046779866239,105.76809306682351,20.754602558566376,81.70242596755779,7.298044196933449,63.72862579130605,3.9499301799077116,41.321899652634976,2.211520376313395,105.32470288110206,20.35108757719671,79.14032751842986,6.6207260543602775,64.03544238362204,3.986463961054262,38.10332212672181,2.0602150617562085,104.62285904737456,19.706640245810163,73.93672186564804,5.489431142391079,57.895853978119064,3.3399091341000195,36.26437665881752,1.9807324696579875,104.97702200816887,20.032297013031588,73.2226464627747,5.355840815772706,56.123729301186145,3.182173571701684,36.54497093010938,1.9925549350335838,105.53601527934143,20.543945015271454,78.36297683006073,6.432254688155311,62.2832355663668,3.784280156272109,42.68471757482252,2.28072562681704]},{"theme":"light-ic","bg":"#000000","fgs":["#010103","#010103","#F1F1FC","#B3B3BC","#909099","#65656D","#909099","#F1F1FC","#E8F0FF","#709FFF","#2D6DFF","#0038C6","#FFF4F3","#FF8275","#F30019","#A7000E","#FFF6F1","#FF8C52","#DF5F00","#9D4100","#C2FFC9","#00C84D","#009F3C","#006E27","#DFF0FF","#10A5FF","#0082CB","#005689"],"flat":[0,1.0069471255994658,0,1.0069471255994658,-99.67218963360757,18.727928195985914,-63.80513707672789,10.090949031745104,-45.863656882792206,6.635143500688325,-26.33477890397734,3.635637824948841,-45.863656882792206,6.635143500688325,-99.67218963360757,18.727928195985914,-98.22794037003116,18.339196272629252,-53.8293996799751,8.092203727319841,-34.21813658812841,4.7430333536498335,-15.622162303180753,2.381112763636304,-102.4562582898777,19.486486384763445,-56.97432424245902,8.701923574139988,-34.76332175899368,4.824974728357804,-18.151652148372637,2.6494391947645526,-103.24826961310278,19.70448161329645,-59.10147589327934,9.125072654774526,-40.787696351505694,5.7744786453226835,-22.81212855995232,3.1897383862050708,-98.60837652742211,18.44127602271432,-60.30793382928855,9.368875012646658,-42.29572232514961,6.0245037012352585,-23.381466511664765,3.259668821930569,-97.12909045511768,18.04563033112125,-52.54162933208091,7.848085216280267,-36.273216344700636,5.055412083856902,-18.54110013749204,2.69234396770907]},{"theme":"light-ic","bg":"#808080","fgs":["#7A7A82","#7A7A82","#010103","#18171E","#37363E","#5B5B64","#37363E","#010103","#000002","#00104D","#002488","#0032B2","#040000","#3A0002","#750007","#98000B","#080100","#2E0E00","#602500","#8F3B00","#000200","#001D05","#004114","#006322","#000102","#00192E","#003A5F","#004D7C"],"flat":[0,1.0777393702545288,0,1.0777393702545288,40.18994509287661,5.280525528202377,36.81932911616927,4.505560397043893,27.93898600302036,3.0217055248761144,13.845788611978202,1.7013528597992067,27.93898600302036,3.0217055248761144,40.18994509287661,5.280525528202377,40.3306726916817,5.312553092992316,36.799792142283025,4.501224406456354,30.04772679653348,3.3069997994324063,23.797727835383583,2.533076638038498,40.23106479600237,5.289901483963394,36.80831529061993,4.503115584720142,27.941932493369514,3.022087143525339,21.190215752118235,2.2723970292907865,40.01441400964806,5.240352767492206,36.83929336929951,4.509994812829007,27.908315541084118,3.0177360720288915,16.77490328531677,1.9034128352995776,40.150141663678234,5.271436537678366,36.85731353296706,4.514000513189092,27.852320260403722,3.0105025419148825,16.643886294769857,1.8937047658181707,40.22977489962569,5.289607582090012,36.84755783504637,4.511831555904809,27.796281383025352,3.0032808914145437,21.058698283639867,2.260143784790762]},{"theme":"light-ic","bg":"#3A3A3C","fgs":["#3E3E45","#3E3E45","#F2F2FD","#BBBBC5","#9E9EA7","#7A7A82","#9E9EA7","#F2F2FD","#EAF1FF","#81ABFF","#4982FF","#0048F5","#FFF5F4","#FF9589","#FF403B","#CC0013","#FFF7F3","#FF9E6E","#F46900","#BD5000","#C6FFCC","#00D251","#00B043","#008631","#E1F1FF","#45B0FF","#0090E1","#006CA9"],"flat":[0,1.0699484563148034,0,1.0699484563148034,-89.06520303275792,10.211241554507897,-56.964055924386784,5.959497869408446,-41.60773958742316,4.2707825803649335,-24.25691832785775,2.6663016206717356,-41.60773958742316,4.2707825803649335,-89.06520303275792,10.211241554507897,-87.69551010135778,10.011246151186945,-48.263751486481056,4.97335266465752,-30.44825366943375,3.199530942583609,-12.043546933756078,1.753943193668956,-91.71639880150975,10.602849175762582,-51.72679347557047,5.3568510977778265,-31.21621892784593,3.268795397886287,-14.661523244642579,1.9330507439017046,-92.55409442667087,10.727809933310253,-53.89547122979923,5.603122076267749,-35.95806640240085,3.7112655792375078,-20.04367187639212,2.329915503818876,-87.89039906251095,10.039605852107476,-53.75183524673264,5.586666992924044,-38.313874917805634,3.940371955014153,-21.037647044419426,2.407284189061088,-86.58838125370931,9.850752189993974,-46.78872683576137,4.81370216625391,-31.383244337404896,3.2839492580871354,-15.736559790538532,2.009284883552937]},{"theme":"light-ic","bg":"#007AFF","fgs":["#797981","#797981","#020205","#16151C","#36353D","#72727A","#36353D","#020205","#000004","#000E48","#002895","#0042E3","#070000","#360001","#730006","#BE0011","#0C0200","#2B0D00","#5F2400","#B04A00","#000400","#001B05","#003F13","#007C2D","#000103","#00172B","#00395C","#00639D"],"flat":[0,1.0745907693903731,0,1.0745907693903731,39.47891404105317,5.158402202047827,36.63906407938327,4.513939148043301,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.47891404105317,5.158402202047827,39.74741500641279,5.218664231374835,36.670023859840576,4.5208004701163915,27.672031623266886,3.008810094200282,15.351341296852958,1.8098737923818007,39.57933742278427,5.181007308853048,36.654144364688555,4.517280323585742,27.751464091733354,3.019069960427185,12.671992881770905,1.6349566993987985,39.23716411822194,5.10371254671437,36.601471319299684,4.505617849545331,27.652865692456807,3.006339685224649,7.684471784052528,1.3665581876464832,39.39108202991847,5.138573889881769,36.624715730830154,4.510761781161014,27.902773646365304,3.038708829709556,0,1.3333017445114326,39.65687576920386,5.198408498908002,36.65150522712613,4.5166954713046765,27.64129393913477,3.0048491045091428,12.054359140378313,1.5979376774972005]},{"theme":"light-ic","bg":"#FF3B30","fgs":["#8A8A92","#8A8A92","#030306","#212129","#3E3D45","#76767F","#3E3D45","#030306","#000004","#001864","#002FA8","#0045ED","#080000","#4C0003","#830008","#C60012","#0D0200","#3E1500","#6C2A00","#B84D00","#000401","#002809","#004917","#00822F","#000103","#00233D","#00416A","#0068A4"],"flat":[0,1.0356140935636031,0,1.0356140935636031,43.57584669970237,5.806877937534237,38.3004661979112,4.504747008392574,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.57584669970237,5.806877937534237,43.98030914587015,5.909904848562026,38.293478372508915,4.503221171740978,28.94317626341717,3.002107337321695,17.95394033246701,1.9258322867444517,43.782795788734404,5.8597651770218455,38.38866051296957,4.524070782124866,28.984608537472,3.0074014381148784,15.156957289606964,1.7362054736619685,43.437607341847624,5.771384990646562,38.33399448678559,4.512078832150148,28.981628167432756,3.007020263830111,9.892674202630067,1.4441010369850493,43.614187977218386,5.816700203526642,38.406807106466914,4.528061863682665,29.022563392947294,3.012260432085235,8.92751562582044,1.3982348229239339,43.88976990866122,5.886966133555759,38.401524303038336,4.526899458852529,29.03631728859714,3.0140233900654434,14.306925700285792,1.683714708917422]},{"theme":"light-ic","bg":"#101012","fgs":["#15151B","#15151B","#F2F2FC","#B4B4BE","#93939C","#696972","#93939C","#F2F2FC","#E9F0FF","#74A2FF","#3371FF","#003CD0","#FFF4F3","#FF8679","#F8001A","#AF000F","#FFF6F2","#FF9058","#E36100","#A44400","#C3FFC9","#00CA4E","#00A33D","#007329","#E0F0FF","#21A8FF","#0085D0","#005B90"],"flat":[0,1.045340264415452,0,1.045340264415452,-98.5838326466521,17.08955684747884,-62.72698384194396,9.243246994613658,-45.67498009680545,6.239717532288448,-26.395025771311026,3.4974414103185016,-45.67498009680545,6.239717532288448,-98.5838326466521,17.08955684747884,-96.69585202312288,16.62869936569993,-53.53835262595417,7.561646720391368,-33.90853669724825,4.477228400656394,-15.643424374972522,2.314414627530853,-100.79897840003042,17.636700891614694,-56.5097869254783,8.089667628698802,-34.29633291417122,4.530985783372177,-18.10601775891745,2.56107712884258,-101.63443561648342,17.844851007069916,-58.71630179001587,8.4915976550775,-40.34850051574898,5.4087697654311055,-22.889197327723014,3.0820931228283226,-97.04991927160123,16.714741751700544,-59.578454823729174,8.650894122604043,-42.30409033566848,5.707629679225331,-23.50941826359813,3.1535587190594883,-95.5914257275877,16.361459308701495,-52.26386479821355,7.339891411251783,-35.96637326948896,4.765958094131511,-18.710865986535588,2.6239504003951875]},{"theme":"light-ic","bg":"#F6F8FA","fgs":["#F0F0FA","#F0F0FA","#0A0910","#707079","#8F8F99","#BCBCC5","#8F8F99","#0A0910","#000110","#0041DF","#3876FF","#82ACFF","#140000","#BB0011","#FC001B","#FF968A","#1A0500","#AE4900","#E76300","#FF9F70","#000B01","#007B2C","#00A63F","#00D252","#00040B","#00629B","#0088D4","#47B1FF"],"flat":[0,1.0634215248159875,0,1.0634215248159875,100.62201386979996,18.61882254505944,66.47667620763235,4.605948460093869,52.23653324893716,3.0084294463712395,29.780700684603257,1.7710808257265196,52.23653324893716,3.0084294463712395,100.62201386979996,18.61882254505944,101.64252534329776,19.49544279635548,78.08171358923367,6.990900026896573,60.31711036263554,3.7908833425501425,38.14751646036453,2.122399526754989,101.24542779029852,19.156162076239593,75.44574141529571,6.3202869230281635,60.62673294996029,3.82662941345977,34.94277926170305,1.9762445240799382,100.4972913238488,18.51105924752946,70.36281029021609,5.256397052662421,54.37780741212484,3.1906001595018556,32.840214506002376,1.8885138214456323,100.85145428464311,18.816958763489637,69.48045983543288,5.0977335979175304,52.4093478352768,3.0225491335598114,33.31123457222728,1.9076443919396007,101.41044755581565,19.297565623167603,74.60712675826916,6.125340559948453,58.63177587043786,3.604653750954651,39.55009522975671,2.1915837971666887]},{"theme":"light-ic","bg":"#1C1C1E","fgs":["#202028","#202028","#F1F1FD","#B6B6BF","#95959E","#6D6C75","#95959E","#F1F1FD","#E9F1FF","#76A4FF","#3875FF","#003ED7","#FFF4F3","#FF897C","#FC001B","#B50010","#FFF6F2","#FF935D","#E66300","#A94600","#C4FFCA","#00CB4F","#00A53F","#00772B","#E0F0FF","#2BA9FF","#0087D3","#005E95"],"flat":[0,1.0522076023272475,0,1.0522076023272475,-96.27140987076255,15.184146579953019,-61.97466067394124,8.452688508186561,-44.87094637123084,5.728792540137694,-25.977188885961883,3.283145241842075,-44.87094637123084,5.728792540137694,-96.27140987076255,15.184146579953019,-95.34499825068502,14.98175500729861,-52.621417231568934,6.906762415988252,-33.47849770408375,4.178062617945301,-14.893749254597887,2.163552488849563,-99.00844385529109,15.788447906049281,-55.63494162352738,7.390318911682041,-33.467257033822236,4.176644120449875,-17.547592326855693,2.408179342981014,-99.84390107174409,15.974784754119627,-57.911424929350886,7.764836527735112,-39.59013024218227,4.982347876116714,-22.33006111099907,2.8868875311347497,-95.39392806862337,14.992417327878547,-58.26045217149408,7.822951516486187,-41.372488477704024,5.229057297458628,-23.176065198031452,2.976455642863797,-93.8008911828484,14.646846343308852,-51.05892490110174,6.66159703590636,-35.06283530237813,4.380256350040106,-18.07990151348513,2.4590883821528062]},{"theme":"light-ic","bg":"#7C3AED","fgs":["#707078","#707078","#F4F4FE","#E3E4ED","#BDBDC6","#A6A6B0","#BDBDC6","#F4F4FE","#EDF3FF","#D8E6FF","#9ABDFF","#598FFF","#FFF8F7","#FFDDD8","#FFA59A","#FF6156","#FFF9F7","#FFDECE","#FFA77C","#FF7112","#D0FFD4","#7DFF93","#00D955","#00B947","#E5F3FF","#CEE8FF","#79C3FF","#0099EE"],"flat":[0,1.1608373681184396,0,1.1608373681184396,-73.98396246220521,5.215032461901156,-64.0643931275358,4.500912896664839,-41.75099800228171,3.055051474145459,-29.486682699107686,2.3616035737730514,-41.75099800228171,3.055051474145459,-73.98396246220521,5.215032461901156,-72.68698719753608,5.119268434409956,-64.43727527190525,4.526987198998707,-41.01457995095163,3.0113075347043563,-19.296469937711088,1.8446469211142276,-76.90365537296871,5.4332059719499135,-64.06334225320066,4.50083949888721,-41.0312066106476,3.012292267380192,-20.969079339398604,1.925648566411713,-77.34727635116013,5.466668081501757,-64.08510797117285,4.502359813071005,-40.89305028080999,3.004113887137535,-23.84545366268376,2.068528569757355,-72.9506558335481,5.138679113149092,-64.10668565953954,4.5038671985064,-40.827825177303865,3.0002560129496776,-26.013778316259767,2.1791858289450103,-71.69069599862902,5.046190228559761,-64.15987367011111,4.5075837056249375,-40.85863800181002,3.0020782433474276,-19.258832894479415,1.8428420367238694]},{"theme":"light-ic","bg":"#123456","fgs":["#36363D","#36363D","#F2F2FD","#BEBEC8","#A2A2AC","#808089","#A2A2AC","#F2F2FD","#EAF1FF","#86AEFF","#5189FF","#0650FF","#FFF6F4","#FF9B8F","#FF5349","#D70015","#FFF7F3","#FFA376","#FA6C00","#C75400","#C8FFCD","#00D553","#00B445","#008D34","#E2F1FF","#50B4FF","#0094E7","#0072B3"],"flat":[0,1.0609289970892934,0,1.0609289970892934,-91.39519035537737,11.4423466076867,-60.94367397154904,6.896920022598847,-46.020165423777584,5.026435795944436,-29.36949737122932,3.250019698594834,-46.020165423777584,5.026435795944436,-91.39519035537737,11.4423466076867,-90.02549742397721,11.218239018758677,-52.117590678997175,5.760385990810306,-35.453068631322715,3.8588722418561026,-17.16315496591595,2.1796295803105563,-94.48648764812391,11.954651961610136,-56.08049309972586,6.260045669338659,-36.68653001054492,3.9880923379680597,-19.42498133620683,2.3619323117143227,-94.88408174929032,12.021194381023134,-58.024655972390946,6.511549338355004,-40.19653971715428,4.366167533936967,-25.014063203920518,2.8441658803090872,-90.45906258458693,11.288985892577246,-57.51342916294683,6.44501257640493,-42.39985031117064,4.611196053798779,-26.099142978345885,2.9428672820648862,-89.03890865199516,11.05791933389335,-51.142776043878534,5.640183677550314,-35.55629387962385,3.86961291577043,-20.57349953874105,2.4573829383449617]},{"theme":"light-ic","bg":"#ABCDEF","fgs":["#C2C2CB","#C2C2CB","#06060C","#55545D","#706F78","#A1A1AA","#706F78","#06060C","#00010B","#0035BB","#044EFF","#4E86FF","#0F0000","#9F000C","#D60015","#FF4D45","#150400","#903B00","#BB4F00","#F86B00","#000801","#006322","#008230","#00B344","#000307","#005182","#0071B2","#0093E5"],"flat":[0,1.0705446339746656,0,1.0705446339746656,75.64582413051765,12.232204997602986,52.76667497081496,4.519371986307913,41.423484798334584,3.0020546798073307,18.127484103049046,1.5512322351556214,41.423484798334584,3.0020546798073307,75.64582413051765,12.232204997602986,76.30385323493446,12.594966222228084,58.55230095328762,5.70794052541694,46.62204712410211,3.5916381056717506,29.005214449343097,2.0573900879913625,76.05323451380515,12.457481581934719,55.93606418979168,5.126251708978212,44.077718465236906,3.284322001440957,27.730078776096413,1.986177453897667,75.43283879959024,12.113874624281086,52.77586207835023,4.520990578468311,41.44187963136357,3.003889327255304,23.868980516769618,1.7916338607346896,75.72958089661125,12.278654436624837,52.80881394476793,4.526802423347816,41.41072061989075,3.0007825637465393,21.536768417458934,1.687644517337887,76.14729893560808,12.509202438867769,55.739334564053664,5.085602713702602,43.07798550292857,3.173723442083943,28.271676351762963,2.015968674447834]},{"theme":"light-ic","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]},{"theme":"dark-ic","bg":"#FFFFFF","fgs":["#E7E7F1","#D9D9E2","#0D0D12","#707079","#94949D","#BCBCC6","#94949D","#0D0D12","#000511","#005DAD","#0080EB","#67AEFF","#180001","#BB0023","#FB0032","#FF9690","#1D0D00","#A16200","#D38200","#FFA93F","#000E02","#007C2A","#00A63B","#00D24D","#060018","#6E00E2","#8F5BFF","#B49FFF"],"flat":[10.564452802176923,1.2281904700369508,18.372353597432387,1.402460683906872,104.27090588423802,19.38311547953439,70.6022439311581,4.903434648448188,54.00450766949271,3.0077315832596954,33.86624309585679,1.8839141891835494,54.00450766949271,3.0077315832596954,104.27090588423802,19.38311547953439,105.36973966240839,20.39226096069594,79.16304803673168,6.626348275559002,63.912632944603466,3.971781216419874,43.318131952880584,2.3140155027501375,105.16667360757414,20.20636839933495,79.43361118518992,6.693805381831162,64.79709340122825,4.079330310903514,38.90470830731088,2.096381256670562,103.76723276112338,18.92212884965907,70.7453629185683,4.926701923645705,54.109273202798526,3.0160152686700097,34.512224892089854,1.9092708836328856,104.66191026229393,19.742561272328775,73.25578885512941,5.361938351796974,56.58363991444959,3.2220248289870597,37.502971296697396,2.0337403797475795,105.5639998705614,20.569417077144905,82.76169093861434,7.605398027541734,65.05029978451972,4.11090668779679,42.03743585537794,2.2474520733771812]},{"theme":"dark-ic","bg":"#000000","fgs":["#030205","#08080D","#F0F0FA","#B1B1BB","#8F8F98","#64646D","#8F8F98","#F0F0FA","#DFEEFF","#4AA0FF","#007AE0","#005198","#FFF4F3","#FF7D79","#EF0030","#A6001E","#FFF7EF","#F99A00","#CA7D00","#915800","#B8FFBE","#00C648","#009F38","#006E24","#F0EDFF","#A98DFF","#894CFF","#6000C7"],"flat":[0,1.0147465549687367,0,1.0508696650285665,-99.01083964835996,18.549513785944853,-62.774763175831374,9.875849762659984,-45.37711439886134,6.5503119047070335,-25.95111170367181,3.5855589616463144,-45.37711439886134,6.5503119047070335,-99.01083964835996,18.549513785944853,-96.24720863865953,17.81140932471069,-52.09132740819334,7.763491481432673,-34.99617079306692,4.860177125212619,-17.977340963301042,2.6303715448994067,-102.4562582898777,19.486486384763445,-55.7461567674855,8.461541475204797,-34.016004840410574,4.712824540535038,-18.066789785866806,2.6401456993132153,-103.60398268701002,19.802704734429785,-61.68353878496926,9.650187857341214,-44.76775468944945,6.444757556916112,-26.060791619056427,3.599837857825526,-97.27916136850891,18.085610527348415,-59.33082759509665,9.171209294707863,-42.24705692654848,6.016359585841944,-23.350526713793172,3.2558471191579894,-97.94239544297146,18.262727694350296,-53.03355221198167,7.94095381214551,-32.857248309508414,4.541449578831631,-15.041171256747345,2.322063533056465]},{"theme":"dark-ic","bg":"#808080","fgs":["#707078","#66666E","#030305","#18171D","#37363E","#5D5D64","#37363E","#030305","#000103","#001834","#00376B","#004A8C","#070000","#390005","#750012","#99001B","#0D0400","#261300","#522F00","#865100","#000300","#001D05","#004112","#006521","#010005","#22004F","#43008F","#5800B7"],"flat":[0,1.24296889833444,9.274501031402123,1.4407196981948422,39.91548097777799,5.217615096019717,36.836632862345205,4.5094036578339445,27.93898600302036,3.0217055248761144,13.086665786299626,1.6537770693375544,27.93898600302036,3.0217055248761144,39.91548097777799,5.217615096019717,40.21965913293546,5.287302224624218,36.81767378273908,4.505192880903515,27.950777846769416,3.023233051937069,21.000772856623527,2.25477321245894,40.142120786515875,5.269603471071473,36.88792093057972,4.5208109211231795,27.866909320024153,3.0123854877509646,20.876190217747006,2.243276608438576,39.57947058767665,5.139984882718895,36.89828467875601,4.523118840482662,27.8635036155662,3.011945822214043,13.292640012092916,1.6665035199669143,40.051433392362526,5.248844071123953,36.85731353296706,4.514000513189092,27.870384117529113,3.0128341396537346,15.95953035602916,1.844055168824021,40.26997047853993,5.298759395894901,36.80600977189143,4.502603953746083,29.651273965169533,3.2515347547731954,23.802145579236715,2.533547958530533]},{"theme":"dark-ic","bg":"#3A3A3C","fgs":["#46464E","#4F4F57","#F1F1FA","#BABAC4","#9D9DA6","#797982","#9D9DA6","#F1F1FA","#E1EFFF","#62ACFF","#0087F7","#0065BB","#FFF5F4","#FF928C","#FF3644","#CA0027","#FFF8F1","#FFA533","#DD8900","#AD6A00","#BCFFC2","#00D04C","#00AF3F","#00862E","#F1EFFF","#B29CFF","#956AFF","#7700F5"],"flat":[0,1.2140718035663858,0,1.3988859584097761,-88.35603271482154,10.107493939375463,-56.41682578047019,5.8952705955406675,-41.10063170437542,4.219157833086703,-23.840055313660137,2.6320437618590202,-41.10063170437542,4.219157833086703,-88.35603271482154,10.107493939375463,-85.70519954500536,9.72347127561709,-46.57313915269262,4.790554592637207,-29.772868283167547,3.1391774083572677,-14.678197720495364,1.9342213705917548,-91.71639880150975,10.602849175762582,-50.907190680193835,5.264997878479995,-30.103011927821978,3.1686137953283313,-14.381529067368087,1.9134497328938256,-92.9101803888625,10.781105347058572,-55.36632323767275,5.772792653136124,-40.27550194757439,4.135743433221995,-23.629833528615176,2.614848030728214,-86.56463892830851,9.847321829129962,-52.75275099572737,5.472775232316544,-37.83315401910713,3.893128667535661,-21.00389596511428,2.404636707585164,-87.71836703917482,10.014570561299498,-47.715877818006604,4.91379345402092,-29.619990398118716,3.125589171245837,-10.872649839108671,1.6769004806806627]},{"theme":"dark-ic","bg":"#007AFF","fgs":["#6F6F77","#65656D","#040408","#16151B","#36353D","#72727A","#36353D","#040408","#000106","#001632","#00366A","#005EAF","#0B0000","#360004","#730011","#BD0023","#100600","#241200","#502E00","#A36300","#000501","#001B04","#004012","#007D2B","#020009","#20004A","#48009A","#6F00E5"],"flat":[0,1.2399763057879079,9.137153276370956,1.4379357071162235,39.199487305374596,5.095159290353486,36.655643103420836,4.517612479062309,27.726113654933034,3.015791844568742,0,1.187212547453551,27.726113654933034,3.015791844568742,39.199487305374596,5.095159290353486,39.62660370456575,5.191620542906115,36.592103069401674,4.503545882983851,27.695057695096033,3.0117807086970667,12.482735608358766,1.623488823202914,39.46146930028483,5.1544680971312,36.631002505660305,4.512153756975423,27.677944212691237,3.0095726068531357,12.751768680957815,1.6398240151911772,38.729462058672325,4.987982714010286,36.579572970042136,4.500775701626332,27.747483785710887,3.0185550274007946,0,1.2039987886628472,39.28492308543262,5.114543979353608,36.632422880871374,4.512468289727634,27.610461383700073,3.00088106913278,0,1.3173837917708568,39.63684952401951,5.1939188146581685,36.601297620325695,4.505579426399357,27.609531401873983,3.0007614645527125,16.085712499624492,1.86220122646402]},{"theme":"dark-ic","bg":"#FF3B30","fgs":["#7F7F87","#74747D","#040408","#212128","#3E3D45","#76767F","#3E3D45","#040408","#000206","#002245","#003E78","#0062B6","#0B0000","#4C0008","#820015","#C50025","#110600","#341C00","#5B3600","#A96700","#000601","#002808","#004916","#00822D","#02000A","#2E0067","#5300AD","#7400EE"],"flat":[0,1.119564506502328,0,1.304916965157494,43.43238144483196,5.770041002680692,38.322111022898454,4.5094781825179275,29.108000765094282,3.0232304751839747,0,1.268226675946831,29.108000765094282,3.0232304751839747,43.43238144483196,5.770041002680692,43.7603252928922,5.854038847974277,38.29235457140463,4.502975854531618,29.083956028514045,3.020138635078335,15.054852030501879,1.729780743830801,43.694363439742204,5.837205585263101,38.354206470247746,4.516507237210082,29.087182234169767,3.020553277003921,15.230546565278194,1.740856512459411,42.92491991360228,5.63897133999608,38.33365423714702,4.512004338988724,28.93769973409828,3.0014083479801514,0,1.2794758858630608,43.42248485866928,5.7674953973596095,38.41370496023468,4.529580289565808,29.031977011275746,3.0134669332394415,8.949958172317846,1.3992774406692907,43.85966524740055,5.879321607935794,38.335090707081115,4.512318847459295,28.952846517354917,3.003342035233188,18.7969313728254,1.9885281036480773]},{"theme":"dark-ic","bg":"#101012","fgs":["#1C1C22","#24242A","#F0F0FA","#B3B3BD","#92929B","#686871","#92929B","#F0F0FA","#E0EEFF","#4FA3FF","#007DE4","#00559F","#FFF4F3","#FF817D","#F40031","#AD001F","#FFF7EF","#FB9C00","#CE7F00","#965B00","#B9FFBF","#00C849","#00A239","#007226","#F0EEFF","#AA90FF","#8C52FF","#6500D0"],"flat":[0,1.1210017368042908,0,1.2316217101091165,-97.35355975851269,16.788671896406843,-62.18912907483276,9.1408846014785,-45.183954583215964,6.160892481462449,-25.971291980892453,3.445784610130369,-45.183954583215964,6.160892481462449,-97.35355975851269,16.788671896406843,-94.7101738760577,16.149472101206463,-51.76844025191021,7.254462182627787,-34.605057818633654,4.573999892517157,-17.84521283217997,2.534242228411278,-100.79897840003042,17.636700891614694,-55.24750846744172,7.863491890193123,-33.54190885081095,4.42668652015819,-17.815136446883052,2.5311583129351276,-101.94670279716274,17.922901715066683,-61.02785966423507,8.921519321161206,-44.34904450398409,6.02788949767693,-25.86724540779468,3.4331609270477186,-95.74776769254933,16.399183837627458,-58.596724506079966,8.469603286006345,-41.840254848173814,5.636085625741139,-23.122294138224145,3.108849028833141,-96.71860922522349,16.634224259107555,-52.4354046324141,7.369572153296626,-32.71416296796099,4.3135863728502315,-14.766203746026353,2.2302399315399106]},{"theme":"dark-ic","bg":"#F6F8FA","fgs":["#E0E0EA","#D2D2DC","#0D0D12","#717179","#8F8F98","#BCBCC6","#8F8F98","#0D0D12","#000511","#005DAD","#0080EB","#67AEFF","#180001","#BB0023","#FB0032","#FF9690","#1D0D00","#A16200","#CC7E00","#FFA93F","#000E02","#007C2A","#00A63B","#00D24D","#060018","#6E00E1","#8F5BFF","#B49FFF"],"flat":[10.34292311627503,1.2313464424988367,18.024461551245693,1.4097592283337514,100.14533816071224,18.207162386274927,66.07133001527934,4.544848448940367,52.273633182943,3.011452358576948,29.740675372331037,1.769619110018133,52.273633182943,3.011452358576948,100.14533816071224,18.207162386274927,101.24417193888262,19.155084079579783,75.03748031320593,6.224334741672483,59.78706522107772,3.730817455350078,39.19256422935483,2.1736266322828217,101.04110588404839,18.980469423093126,75.30804346166417,6.287699296730837,60.6715256777025,3.8318416601446055,34.77914058378512,1.9691960254812915,99.64166503759763,17.774143327140518,66.61979519504256,4.627804134340593,52.265155427331,3.010761189364384,30.386657168564103,1.79343744066295,100.53634253876818,18.544800983402446,69.13022113160365,5.036635229225181,52.45807219092383,3.026547994099155,33.37740357317164,1.9103555042369325,101.43843214703563,19.321492322017065,78.73738474892319,7.17242701812758,60.92473206099399,3.861502331684902,37.91186813185219,2.111101535692422]},{"theme":"dark-ic","bg":"#1C1C1E","fgs":["#28282E","#303036","#F0F1FA","#B5B5BE","#94949D","#6C6C74","#94949D","#F0F1FA","#E0EEFF","#53A4FF","#007FE8","#0058A5","#FFF4F3","#FF8580","#F80032","#B30021","#FFF7F0","#FD9D00","#D18100","#9B5E00","#B9FFC0","#00CA4A","#00A43A","#007628","#F0EEFF","#AC93FF","#8D57FF","#6800D8"],"flat":[0,1.1612081374032734,0,1.2977584057597347,-96.00102363023473,15.124963081358866,-61.434200333395395,8.359778481952823,-44.37695589123639,5.656999216809453,-25.852207004995158,3.269134017520218,-44.37695589123639,5.656999216809453,-96.00102363023473,15.124963081358866,-92.91963933131836,14.457074514504098,-50.53751898728166,6.580638229837842,-33.762466759799054,4.213972880586457,-17.265259153354464,2.3814244063048684,-99.00844385529109,15.788447906049281,-54.621704682580784,7.2261694596451385,-32.708249696736004,4.081389020198301,-17.26088719592284,2.381011454094406,-100.19905346524207,16.054261379481122,-59.919533209261445,8.101702037099825,-43.64240726631874,5.55098822531801,-25.561703474916055,3.236683846808585,-93.99035989085725,14.687777164248876,-57.733604751916815,7.735299184328377,-40.893113879964474,5.162174617584753,-22.782862127638978,2.93464773079297,-94.92807468048419,14.891026660055605,-51.83505302329671,6.7828987244211,-32.07221654016657,4.002369709649521,-14.066989001346808,2.090531498955086]},{"theme":"dark-ic","bg":"#7C3AED","fgs":["#7A7A83","#85858D","#F2F2FD","#E3E4ED","#BBBCC5","#A6A6AF","#BBBCC5","#F2F2FD","#E5F1FF","#D2E7FF","#8AC0FF","#2091FF","#FFF9F8","#FFDDDA","#FFA49E","#FF5C5D","#FFFAF5","#FFE0C0","#FFAA42","#E99000","#C6FFCB","#7DFF91","#00DA50","#00B943","#F3F1FF","#E6E2FF","#C1B2FF","#9D7AFF"],"flat":[-8.022975593833932,1.3402714370624624,-13.06659651622355,1.5567826841029107,-72.79588351600884,5.127281558149197,-64.0643931275358,4.500912896664839,-41.08533982136385,3.0154992993085026,-29.446612137967147,2.3594628663401775,-41.08533982136385,3.0154992993085026,-72.79588351600884,5.127281558149197,-70.80493468751378,4.981574213000164,-64.1741844582375,4.5085838821814495,-40.86541522684489,3.0024791016401666,-17.915271666932362,1.7789289638170434,-77.39176152066469,5.470028106981068,-64.14420274941838,4.506488572747314,-40.82594869447877,3.0001450551263997,-20.102672577261966,1.8834970356793017,-77.70409895709017,5.493642615376888,-64.40976920815079,4.525061719384059,-40.93902681557826,3.00683450902807,-28.2154352545988,2.2940964528512438,-71.5855645088526,5.038503428518723,-64.0583201718401,4.500488740880354,-41.23137463469248,3.02415799426954,-25.961518214862377,2.176489332337808,-72.5833510184408,5.111647048756453,-64.45521953810703,4.528243512077896,-40.9348520371047,3.006587427640115,-18.521762858381592,1.807654812879132]},{"theme":"dark-ic","bg":"#123456","fgs":["#3E3E45","#47474E","#F0F0FC","#BDBDC6","#A1A1AA","#7F7F88","#A1A1AA","#F0F0FC","#E1EFFF","#68AEFF","#008BFD","#006AC4","#FFF6F5","#FF9791","#FF494F","#D30029","#FFF8F1","#FFA941","#E28C00","#B46E00","#BEFFC3","#00D34D","#00B340","#008C31","#F1EFFF","#B49FFF","#9971FF","#7D09FF"],"flat":[0,1.1989453999458657,0,1.3802668927515667,-90.21171279539291,11.248602775503162,-60.350304841650235,6.81783465078813,-45.467647083484636,4.962060105853706,-28.90763677945104,3.2057711392885686,-45.467647083484636,4.962060105853706,-90.21171279539291,11.248602775503162,-88.0351868676248,10.895768939711282,-50.01919534416472,5.502978516969682,-33.92042169291382,3.7009882121251625,-19.118481017052428,2.3367853131295435,-94.53061684959366,11.962030249162733,-54.89593536437227,6.108854061876529,-35.13675470036395,3.8260433618990066,-18.695569008603144,2.3023140000481574,-95.24016771148194,12.080915286992608,-59.18458546592085,6.6635751999987605,-44.37309985295556,4.8355935478331284,-28.125674388660414,3.1315039953558483,-89.11957165172129,11.070992163190612,-56.49372778683512,6.313154752438012,-41.901500594929324,4.555261373045625,-25.675484951698337,2.9041378624661793,-90.04835436179425,11.221964232051386,-51.2922333885473,5.658542947646642,-34.21126239038315,3.7307191421666435,-15.254686874750304,2.03178289437105]},{"theme":"dark-ic","bg":"#ABCDEF","fgs":["#B4B4BE","#A8A8B1","#09090F","#55545C","#706F78","#A1A1AB","#706F78","#09090F","#00030D","#004D92","#006CC7","#008BFE","#130001","#9F001C","#D60029","#FF4B50","#190B00","#7B4A00","#A06100","#E38C00","#000A01","#006320","#00822D","#00B341","#040013","#5B00BE","#7E16FF","#9971FF"],"flat":[8.489900665165298,1.2445786124510558,14.633674840112363,1.428005718026211,75.26124671135368,12.018395958758797,52.798813706484495,4.5250375920814765,41.423484798334584,3.0020546798073307,18.08917030758312,1.5497949541740348,41.423484798334584,3.0020546798073307,75.26124671135368,12.018395958758797,76.08600684668272,12.475516218126787,55.96473752983635,5.13221099097022,43.3369682989835,3.2018590596167122,29.318326289650187,2.0754572365320043,75.88156299830736,12.362776535253154,55.82217638546274,5.102669267083783,43.91931922104849,3.266436635421996,27.87409429449102,1.9940348577564484,74.63415754799017,11.66954886455628,52.68236753448497,4.504554642142053,41.632593181405234,3.023005829909607,19.021862742942993,1.5853635699211195,75.54552640875083,12.176514522007174,52.82929323710673,4.530419449281277,41.44477504659015,3.004178254346042,21.57431352051131,1.6892460110571705,76.18160530883091,12.528031661692317,58.96992438550627,5.808209180198148,47.36214126331064,3.68860336114861,29.106756402593504,2.0632235490419992]},{"theme":"dark-ic","bg":"#808080","fgs":["#F7F7FF","#0A0A10","#71717A","#fff","abcdef","#Ff3B30","#123","112233"],"flat":[-64.57463009518332,3.7055405145881393,38.97016765822309,4.9982958489854346,0,1.2236914579873204,-69.21596068658343,3.9494396480491156,-37.021615579693034,2.3904478169235754,0,1.1134158562260283,34.84722274356656,4.0887512719822805,34.84722274356656,4.0887512719822805]}],"resolveVars":[{"theme":"light","bg":"#FFFFFF","vars":{"--lab-bg-tone-2":"oklch(97.84197% 0.010603 286.202)","--lab-bg-tone-3":"oklch(97.84197% 0.010603 286.202)","--lab-label-primary":"oklch(19.12257% 0.014100 291.556)","--lab-label-secondary":"oklch(56.54196% 0.013721 285.953)","--lab-label-tertiary":"oklch(66.97448% 0.014606 285.999)","--lab-label-quaternary":"oklch(81.39504% 0.013897 286.087)","--lab-border-strong":"oklch(19.12257% 0.014100 291.556)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(19.39430% 0.069681 257.297)","--lab-label-brand-secondary":"oklch(57.33316% 0.205939 257.291)","--lab-label-brand-tertiary":"oklch(67.12978% 0.175419 257.690)","--lab-label-brand-quaternary":"oklch(81.31388% 0.094313 257.967)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(20.16318% 0.082740 29.234)","--lab-label-danger-secondary":"oklch(59.62536% 0.244212 28.655)","--lab-label-danger-tertiary":"oklch(69.12968% 0.198650 28.574)","--lab-label-danger-quaternary":"oklch(82.55135% 0.097676 29.389)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(19.32631% 0.042728 66.944)","--lab-label-warning-secondary":"oklch(57.27465% 0.125021 68.799)","--lab-label-warning-tertiary":"oklch(67.73500% 0.148484 68.161)","--lab-label-warning-quaternary":"oklch(82.04043% 0.139600 68.374)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(67.73500% 0.148484 68.161 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(18.59864% 0.054816 147.311)","--lab-label-success-secondary":"oklch(54.91588% 0.161394 147.418)","--lab-label-success-tertiary":"oklch(64.88263% 0.190555 147.443)","--lab-label-success-quaternary":"oklch(79.02491% 0.232159 147.432)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(64.96409% 0.172888 147.450 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(19.54489% 0.077696 259.509)","--lab-label-info-secondary":"oklch(57.68997% 0.232691 259.838)","--lab-label-info-tertiary":"oklch(67.26428% 0.173598 259.980)","--lab-label-info-quaternary":"oklch(81.49851% 0.092914 259.576)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.5","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.5","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.5","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.5","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(66.97448% 0.014606 285.999)"}},{"theme":"light","bg":"#000000","vars":{"--lab-bg-tone-2":"oklch(7.11623% 0.013707 282.350)","--lab-bg-tone-3":"oklch(7.11623% 0.013707 282.350)","--lab-label-primary":"oklch(98.65156% 0.006606 286.278)","--lab-label-secondary":"oklch(80.14049% 0.013952 286.081)","--lab-label-tertiary":"oklch(69.23260% 0.013029 286.055)","--lab-label-quaternary":"oklch(55.16643% 0.013808 285.938)","--lab-border-strong":"oklch(98.65156% 0.006606 286.278)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(98.69528% 0.006207 255.474)","--lab-label-brand-secondary":"oklch(80.06451% 0.101154 257.822)","--lab-label-brand-tertiary":"oklch(69.35433% 0.162198 257.610)","--lab-label-brand-quaternary":"oklch(55.96293% 0.201872 257.393)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(98.64532% 0.006567 28.833)","--lab-label-danger-secondary":"oklch(81.38408% 0.105319 28.863)","--lab-label-danger-tertiary":"oklch(71.19739% 0.181099 28.350)","--lab-label-danger-quaternary":"oklch(58.10538% 0.238004 28.677)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(98.72985% 0.009577 72.664)","--lab-label-warning-secondary":"oklch(80.98123% 0.149940 68.750)","--lab-label-warning-tertiary":"oklch(70.11346% 0.152989 68.857)","--lab-label-warning-quaternary":"oklch(55.86543% 0.122417 68.219)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(98.31403% 0.027558 147.033)","--lab-label-success-secondary":"oklch(77.69544% 0.228159 147.448)","--lab-label-success-tertiary":"oklch(67.10085% 0.197388 147.383)","--lab-label-success-quaternary":"oklch(53.45797% 0.157009 147.442)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(98.69528% 0.006207 255.474)","--lab-label-info-secondary":"oklch(80.30515% 0.099317 259.806)","--lab-label-info-tertiary":"oklch(69.49027% 0.160387 260.058)","--lab-label-info-quaternary":"oklch(56.23879% 0.227606 259.853)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.013010286081645773","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.012071078431372548","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.009560345877481427","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.00784313725490196","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(69.23260% 0.013029 286.055)"}},{"theme":"light","bg":"#808080","vars":{"--lab-bg-tone-2":"oklch(58.21536% 0.012099 286.018)","--lab-bg-tone-3":"oklch(58.21536% 0.012099 286.018)","--lab-label-primary":"oklch(13.77177% 0.013406 284.503)","--lab-label-secondary":"oklch(20.89710% 0.013787 291.711)","--lab-label-tertiary":"oklch(33.70211% 0.013945 291.371)","--lab-label-quaternary":"oklch(49.18380% 0.012632 285.926)","--lab-border-strong":"oklch(13.77177% 0.013406 284.503)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(13.49058% 0.050205 258.119)","--lab-label-brand-secondary":"oklch(20.89968% 0.076454 257.725)","--lab-label-brand-tertiary":"oklch(34.17043% 0.122830 257.309)","--lab-label-brand-quaternary":"oklch(49.70427% 0.178878 257.337)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.22004% 0.058352 29.234)","--lab-label-danger-secondary":"oklch(21.88171% 0.089792 29.234)","--lab-label-danger-tertiary":"oklch(35.54757% 0.145582 28.627)","--lab-label-danger-quaternary":"oklch(51.73054% 0.211869 28.643)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(13.56514% 0.029751 68.088)","--lab-label-warning-secondary":"oklch(20.90753% 0.046395 66.438)","--lab-label-warning-tertiary":"oklch(34.00266% 0.074904 67.452)","--lab-label-warning-quaternary":"oklch(49.79045% 0.108745 68.715)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(91.20808% 0.064865 69.118 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.01439% 0.039836 145.937)","--lab-label-success-secondary":"oklch(20.10741% 0.059351 147.255)","--lab-label-success-tertiary":"oklch(32.71649% 0.095649 147.616)","--lab-label-success-quaternary":"oklch(47.52181% 0.139141 147.559)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(88.67895% 0.198079 147.416 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(13.83602% 0.055501 259.684)","--lab-label-info-secondary":"oklch(21.26627% 0.087439 260.146)","--lab-label-info-tertiary":"oklch(34.39884% 0.140838 260.069)","--lab-label-info-quaternary":"oklch(50.11242% 0.202893 259.861)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.11057506131405687","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.11023622047244083","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.07169755954418727","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.04724409448818886","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(33.70211% 0.013945 291.371)","--lab-border-brand-strong":"oklch(34.17043% 0.122830 257.309 / 1)","--lab-border-danger-strong":"oklch(35.54757% 0.145582 28.627 / 1)","--lab-border-info-strong":"oklch(34.39884% 0.140838 260.069 / 1)"}},{"theme":"light","bg":"#3A3A3C","vars":{"--lab-bg-tone-2":"oklch(36.65084% 0.011912 285.797)","--lab-bg-tone-3":"oklch(36.65084% 0.011912 285.797)","--lab-label-primary":"oklch(98.92134% 0.005280 286.303)","--lab-label-secondary":"oklch(82.53513% 0.012530 281.039)","--lab-label-tertiary":"oklch(72.82755% 0.014297 286.039)","--lab-label-quaternary":"oklch(61.25907% 0.011943 286.042)","--lab-border-strong":"oklch(98.92134% 0.005280 286.303)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(98.77036% 0.005722 264.533)","--lab-label-brand-secondary":"oklch(82.44675% 0.088464 257.008)","--lab-label-brand-tertiary":"oklch(73.08383% 0.140495 257.442)","--lab-label-brand-quaternary":"oklch(61.77245% 0.208353 257.413)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-strong":"oklch(61.75781% 0.208491 257.338 / 1)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(98.86605% 0.005516 31.054)","--lab-label-danger-secondary":"oklch(83.38591% 0.092088 28.223)","--lab-label-danger-tertiary":"oklch(74.63167% 0.153784 28.842)","--lab-label-danger-quaternary":"oklch(64.10554% 0.244701 28.706)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-strong":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(98.75683% 0.008520 67.727)","--lab-label-warning-secondary":"oklch(83.08426% 0.131366 68.787)","--lab-label-warning-tertiary":"oklch(73.86147% 0.161425 68.614)","--lab-label-warning-quaternary":"oklch(61.96370% 0.135496 68.532)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(98.51065% 0.024195 147.300)","--lab-label-success-secondary":"oklch(80.08887% 0.235054 147.469)","--lab-label-success-tertiary":"oklch(70.67977% 0.207519 147.455)","--lab-label-success-quaternary":"oklch(59.24524% 0.173588 147.533)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(98.77036% 0.005722 264.533)","--lab-label-info-secondary":"oklch(82.42821% 0.087905 259.666)","--lab-label-info-tertiary":"oklch(73.17409% 0.139071 259.898)","--lab-label-info-quaternary":"oklch(61.97090% 0.205878 259.740)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-strong":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.06909778454881221","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.060913705583756306","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.040609137055837526","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.028061954965508236","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(72.82755% 0.014297 286.039)"}},{"theme":"light","bg":"#007AFF","vars":{"--lab-bg-tone-2":"oklch(57.87475% 0.012117 286.015)","--lab-bg-tone-3":"oklch(57.87475% 0.012117 286.015)","--lab-label-primary":"oklch(13.41536% 0.016099 291.497)","--lab-label-secondary":"oklch(20.01464% 0.013939 291.638)","--lab-label-tertiary":"oklch(33.31157% 0.013986 291.359)","--lab-label-quaternary":"oklch(48.82850% 0.012656 285.922)","--lab-border-strong":"oklch(13.41536% 0.016099 291.497)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(13.49058% 0.050205 258.119)","--lab-label-brand-secondary":"oklch(20.23588% 0.071518 256.892)","--lab-label-brand-tertiary":"oklch(33.52307% 0.122654 257.729)","--lab-label-brand-quaternary":"oklch(49.33014% 0.177503 257.333)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.22004% 0.058352 29.234)","--lab-label-danger-secondary":"oklch(20.90400% 0.085780 29.234)","--lab-label-danger-tertiary":"oklch(34.90075% 0.142917 28.593)","--lab-label-danger-quaternary":"oklch(51.33845% 0.210254 28.629)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(13.56514% 0.029751 68.088)","--lab-label-warning-secondary":"oklch(20.32691% 0.044866 67.175)","--lab-label-warning-tertiary":"oklch(33.70499% 0.073308 69.356)","--lab-label-warning-quaternary":"oklch(49.32505% 0.107532 68.994)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(90.50991% 0.070001 68.839 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.01439% 0.039836 145.937)","--lab-label-success-secondary":"oklch(19.36939% 0.056254 147.869)","--lab-label-success-tertiary":"oklch(32.05045% 0.093836 147.561)","--lab-label-success-quaternary":"oklch(47.21271% 0.138736 147.423)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(87.96697% 0.214930 147.350 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(13.83602% 0.055501 259.684)","--lab-label-info-secondary":"oklch(20.33878% 0.084139 260.257)","--lab-label-info-tertiary":"oklch(33.98919% 0.139378 260.097)","--lab-label-info-quaternary":"oklch(49.73960% 0.201561 259.877)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.1414396647356093","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.1805418331471749","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.09073588245366788","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.06430782839451565","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(33.31157% 0.013986 291.359)","--lab-border-brand-strong":"oklch(33.52307% 0.122654 257.729 / 1)","--lab-border-danger-strong":"oklch(34.90075% 0.142917 28.593 / 1)","--lab-border-info-strong":"oklch(33.98919% 0.139378 260.097 / 1)"}},{"theme":"light","bg":"#FF3B30","vars":{"--lab-bg-tone-2":"oklch(63.60048% 0.011829 286.059)","--lab-bg-tone-3":"oklch(63.60048% 0.011829 286.059)","--lab-label-primary":"oklch(13.83495% 0.015576 284.180)","--lab-label-secondary":"oklch(25.12484% 0.015017 285.269)","--lab-label-tertiary":"oklch(36.40556% 0.013673 291.446)","--lab-label-quaternary":"oklch(51.30243% 0.012497 285.951)","--lab-border-strong":"oklch(13.83495% 0.015576 284.180)","--lab-border-base":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-border-soft":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-primary":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-fill-secondary":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fill-tertiary":"oklch(57.53363% 0.012136 286.012 / 0.122)","--lab-fill-quaternary":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fx-shadow-minor":"oklch(17.39406% 0.004094 285.967 / 0.012)","--lab-fx-shadow-ambient":"oklch(17.39406% 0.004094 285.967 / 0.02)","--lab-fx-shadow-penumbra":"oklch(17.39406% 0.004094 285.967 / 0.039)","--lab-fx-shadow-major":"oklch(17.39406% 0.004094 285.967 / 0.122)","--lab-label-brand-primary":"oklch(14.05977% 0.051776 257.879)","--lab-label-brand-secondary":"oklch(25.33060% 0.091490 257.423)","--lab-label-brand-tertiary":"oklch(36.69778% 0.133197 257.540)","--lab-label-brand-quaternary":"oklch(51.93456% 0.187074 257.359)","--lab-fill-brand-primary":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-brand-secondary":"oklch(60.27647% 0.217712 257.424 / 0.078)","--lab-fill-brand-tertiary":"oklch(60.27647% 0.217712 257.424 / 0.039)","--lab-fill-brand-quaternary":"oklch(60.27647% 0.217712 257.424 / 0.02)","--lab-border-brand-base":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-brand-soft":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-label-danger-primary":"oklch(14.49010% 0.059461 29.234)","--lab-label-danger-secondary":"oklch(26.17120% 0.107130 28.474)","--lab-label-danger-tertiary":"oklch(38.31782% 0.156989 28.748)","--lab-label-danger-quaternary":"oklch(53.87750% 0.220648 28.624)","--lab-fill-danger-primary":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-fill-danger-secondary":"oklch(65.42146% 0.232135 28.659 / 0.078)","--lab-fill-danger-tertiary":"oklch(65.42146% 0.232135 28.659 / 0.039)","--lab-fill-danger-quaternary":"oklch(65.42146% 0.232135 28.659 / 0.02)","--lab-border-danger-base":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-danger-soft":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-warning-primary":"oklch(14.09840% 0.030367 70.955)","--lab-label-warning-secondary":"oklch(25.16306% 0.055216 68.014)","--lab-label-warning-tertiary":"oklch(36.95716% 0.080989 68.209)","--lab-label-warning-quaternary":"oklch(51.83499% 0.113346 68.533)","--lab-fill-warning-primary":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-fill-warning-secondary":"oklch(78.56796% 0.171718 68.607 / 0.078)","--lab-fill-warning-tertiary":"oklch(78.56796% 0.171718 68.607 / 0.039)","--lab-fill-warning-quaternary":"oklch(78.56796% 0.171718 68.607 / 0.02)","--lab-border-warning-strong":"oklch(94.55166% 0.039779 69.746 / 1)","--lab-border-warning-base":"oklch(78.56796% 0.171718 68.607 / 0.2)","--lab-border-warning-soft":"oklch(78.56796% 0.171718 68.607 / 0.122)","--lab-label-success-primary":"oklch(13.47470% 0.038038 148.984)","--lab-label-success-secondary":"oklch(24.13011% 0.070822 147.468)","--lab-label-success-tertiary":"oklch(35.33425% 0.103721 147.463)","--lab-label-success-quaternary":"oklch(49.62199% 0.145290 147.559)","--lab-fill-success-primary":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-fill-success-secondary":"oklch(73.03242% 0.194381 147.444 / 0.078)","--lab-fill-success-tertiary":"oklch(73.03242% 0.194381 147.444 / 0.039)","--lab-fill-success-quaternary":"oklch(73.03242% 0.194381 147.444 / 0.02)","--lab-border-success-strong":"oklch(93.08890% 0.111383 147.112 / 1)","--lab-border-success-base":"oklch(73.03242% 0.194381 147.444 / 0.2)","--lab-border-success-soft":"oklch(73.03242% 0.194381 147.444 / 0.122)","--lab-label-info-primary":"oklch(14.07469% 0.058967 260.480)","--lab-label-info-secondary":"oklch(25.53067% 0.104920 260.137)","--lab-label-info-tertiary":"oklch(37.14168% 0.149591 259.762)","--lab-label-info-quaternary":"oklch(52.13660% 0.212021 259.943)","--lab-fill-info-primary":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fill-info-secondary":"oklch(64.04613% 0.193058 259.892 / 0.078)","--lab-fill-info-tertiary":"oklch(64.04613% 0.193058 259.892 / 0.039)","--lab-fill-info-quaternary":"oklch(64.04613% 0.193058 259.892 / 0.02)","--lab-border-info-base":"oklch(64.04613% 0.193058 259.892 / 0.2)","--lab-border-info-soft":"oklch(64.04613% 0.193058 259.892 / 0.122)","--lab-fx-focus-ring-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fx-focus-ring-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-fx-focus-ring-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-fx-focus-ring-neutral":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-fx-glow-brand":"oklch(60.27647% 0.217712 257.424)","--lab-fx-glow-brand-core":"oklch(78.76611% 0.108476 257.256)","--lab-fx-glow-brand-alpha":"0.1835748792270531","--lab-fx-glow-danger":"oklch(65.42146% 0.232135 28.659)","--lab-fx-glow-danger-core":"oklch(81.77103% 0.102764 29.025)","--lab-fx-glow-danger-alpha":"0.4395613333149519","--lab-fx-glow-warning":"oklch(78.56796% 0.171718 68.607)","--lab-fx-glow-warning-core":"oklch(88.88181% 0.082838 68.777)","--lab-fx-glow-warning-alpha":"0.1777791862086449","--lab-fx-glow-neutral":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-core":"oklch(100.00000% 0.000000 89.876)","--lab-fx-glow-neutral-alpha":"0.1016772651089421","--lab-fx-glow-inverted":"oklch(75.99692% 0.012723 286.093 / 0.522)","--lab-fx-skeleton-highlight":"oklch(57.53363% 0.012136 286.012 / 0.039)","--lab-fill-neutral":"oklch(57.53363% 0.012136 286.012 / 1)","--lab-fill-accent-tinted":"oklch(60.27647% 0.217712 257.424 / 0.122)","--lab-fill-danger-tinted":"oklch(65.42146% 0.232135 28.659 / 0.122)","--lab-label-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-label-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-border-accent":"oklch(60.27647% 0.217712 257.424 / 0.2)","--lab-border-danger":"oklch(65.42146% 0.232135 28.659 / 0.2)","--lab-border-focus":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-brand":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-badge-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-badge-fill-warning":"oklch(78.56796% 0.171718 68.607 / 1)","--lab-badge-fill-success":"oklch(73.03242% 0.194381 147.444 / 1)","--lab-badge-fill-info":"oklch(64.04613% 0.193058 259.892 / 1)","--lab-badge-fill-static-dark":"oklch(17.39406% 0.004094 285.967 / 1)","--lab-badge-fill-static-light":"oklch(100.00000% 0.000000 89.876 / 1)","--lab-fill-neutral-tinted":"oklch(57.53363% 0.012136 286.012 / 0.2)","--lab-border-neutral":"oklch(57.53363% 0.012136 286.012 / 0.161)","--lab-fx-skeleton-base":"oklch(57.53363% 0.012136 286.012 / 0.078)","--lab-fill-accent":"oklch(60.27647% 0.217712 257.424 / 1)","--lab-fill-danger":"oklch(65.42146% 0.232135 28.659 / 1)","--lab-icon":"oklch(36.40556% 0.013673 291.446)","--lab-border-brand-strong":"oklch(36.69778% 0.133197 257.540 / 1)","--lab-border-danger-strong":"oklch(38.31782% 0.156989 28.748 / 1)","--lab-border-info-strong":"oklch(37.14168% 0.149591 259.762 / 1)"}}]} diff --git a/scripts/check-wasm-size-budget.mjs b/scripts/check-wasm-size-budget.mjs index 0827d509..196df707 100644 --- a/scripts/check-wasm-size-budget.mjs +++ b/scripts/check-wasm-size-budget.mjs @@ -14,7 +14,7 @@ export const DEFAULT_BUDGET = resolve( "packages/colors/bench/wasm.json", ); export const WASM_BUDGET_FILE_SHA256 = - "1195cf28878d0e717af7d56c51a77621dcb9b060478965180cfc66befea3c3c5"; + "f73a3f6110bc635678d235732dde2ab8ebe235c7b4e6d6314caa5b9efa9d30d0"; const SCHEMA_VERSION = 1; const CANONICAL_ARTIFACT = "packages/colors/pkg/labcolors_bg.wasm";