ranranrunforit commited on
Commit
0a876ec
·
verified ·
1 Parent(s): 13ee2aa

Update ui_kits/chan-compass/_ds_bundle.js

Browse files
Files changed (1) hide show
  1. ui_kits/chan-compass/_ds_bundle.js +2 -912
ui_kits/chan-compass/_ds_bundle.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @ds-bundle: {"format":3,"namespace":"ChanCompassSpectrum2DesignSystem_b52b37","components":[{"name":"Button","sourcePath":"components/actions/Button.jsx"},{"name":"Card","sourcePath":"components/containers/Card.jsx"},{"name":"InlineAlert","sourcePath":"components/containers/InlineAlert.jsx"},{"name":"Checkbox","sourcePath":"components/forms/Checkbox.jsx"},{"name":"Field","sourcePath":"components/forms/Field.jsx"},{"name":"Switch","sourcePath":"components/forms/Switch.jsx"},{"name":"Tabs","sourcePath":"components/navigation/Tabs.jsx"},{"name":"Badge","sourcePath":"components/status/Badge.jsx"},{"name":"SignalBadge","sourcePath":"components/status/SignalBadge.jsx"},{"name":"StatusLight","sourcePath":"components/status/StatusLight.jsx"}],"sourceHashes":{"components/actions/Button.jsx":"c9f7501c202c","components/containers/Card.jsx":"9316d0c88d32","components/containers/InlineAlert.jsx":"5ceb8bdaac5f","components/forms/Checkbox.jsx":"59c34e791a76","components/forms/Field.jsx":"39157a609b42","components/forms/Switch.jsx":"38f4684e0ef2","components/navigation/Tabs.jsx":"5488bca491fa","components/status/Badge.jsx":"3e62358e3a0b","components/status/SignalBadge.jsx":"df7989e74422","components/status/StatusLight.jsx":"f7d206a1642b","ui_kits/chan-compass/app.jsx":"4b80024bd468","ui_kits/chan-compass/data.js":"5821344b625c","ui_kits/chan-compass/views.jsx":"c9ec2aee076f"},"inlinedExternals":[],"unexposedExports":[]} */
2
 
3
  (() => {
4
 
@@ -602,916 +602,6 @@ function StatusLight({
602
  Object.assign(__ds_scope, { StatusLight });
603
  })(); } catch (e) { __ds_ns.__errors.push({ path: "components/status/StatusLight.jsx", error: String((e && e.message) || e) }); }
604
 
605
- // ui_kits/chan-compass/app.jsx
606
- try { (() => {
607
- /* Chan Compass UI kit — app shell. Header + Tabs + routed content + footer. */
608
- const _DS = window.ChanCompassSpectrum2DesignSystem_b52b37;
609
- const {
610
- Tabs: CCTabs,
611
- StatusLight: CCStatus,
612
- Badge: CCBadge
613
- } = _DS;
614
- const {
615
- useState: useS,
616
- useEffect: useE
617
- } = React;
618
- function Glyph({
619
- name,
620
- size = 18,
621
- color,
622
- style
623
- }) {
624
- useE(() => {
625
- if (window.lucide) window.lucide.createIcons();
626
- });
627
- return /*#__PURE__*/React.createElement("i", {
628
- "data-lucide": name,
629
- style: {
630
- width: size,
631
- height: size,
632
- color,
633
- display: 'inline-flex',
634
- ...style
635
- }
636
- });
637
- }
638
- function App() {
639
- const [tab, setTab] = useS('signals');
640
- const items = [{
641
- id: 'signals',
642
- label: 'Signals',
643
- icon: /*#__PURE__*/React.createElement(Glyph, {
644
- name: "trending-up",
645
- size: 16
646
- })
647
- }, {
648
- id: 'rotation',
649
- label: 'Sector Rotation',
650
- icon: /*#__PURE__*/React.createElement(Glyph, {
651
- name: "refresh-cw",
652
- size: 16
653
- })
654
- }, {
655
- id: 'news',
656
- label: 'Watchlist News',
657
- icon: /*#__PURE__*/React.createElement(Glyph, {
658
- name: "newspaper",
659
- size: 16
660
- }),
661
- count: 2
662
- }, {
663
- id: 'research',
664
- label: 'Auto Research',
665
- icon: /*#__PURE__*/React.createElement(Glyph, {
666
- name: "flask-conical",
667
- size: 16
668
- })
669
- }, {
670
- id: 'model',
671
- label: 'Model',
672
- icon: /*#__PURE__*/React.createElement(Glyph, {
673
- name: "cpu",
674
- size: 16
675
- })
676
- }];
677
- const View = {
678
- signals: window.SignalsView,
679
- rotation: window.RotationView,
680
- news: window.NewsView,
681
- research: window.ResearchView,
682
- model: window.ModelView
683
- }[tab];
684
- return /*#__PURE__*/React.createElement("div", {
685
- className: "cc-app"
686
- }, /*#__PURE__*/React.createElement("header", {
687
- className: "cc-header"
688
- }, /*#__PURE__*/React.createElement("div", {
689
- className: "cc-brand"
690
- }, /*#__PURE__*/React.createElement("div", {
691
- className: "cc-mark"
692
- }, /*#__PURE__*/React.createElement(Glyph, {
693
- name: "compass",
694
- size: 22,
695
- color: "#fff"
696
- })), /*#__PURE__*/React.createElement("div", {
697
- className: "cc-brand-text"
698
- }, /*#__PURE__*/React.createElement("div", {
699
- className: "cc-wordmark"
700
- }, "Chan Compass ", /*#__PURE__*/React.createElement("span", null, "\xB7 US Markets")), /*#__PURE__*/React.createElement("div", {
701
- className: "cc-tagline"
702
- }, "Multi-timeframe \u7F20\u8BBA signal engine \xB7 fully local"))), /*#__PURE__*/React.createElement("div", {
703
- className: "cc-header-right"
704
- }, /*#__PURE__*/React.createElement(CCBadge, {
705
- variant: "accent"
706
- }, /*#__PURE__*/React.createElement(Glyph, {
707
- name: "cpu",
708
- size: 12,
709
- style: {
710
- marginRight: 4
711
- }
712
- }), " Local \xB7 llama.cpp"), /*#__PURE__*/React.createElement(CCStatus, {
713
- variant: "positive",
714
- live: true
715
- }, "Market open"))), /*#__PURE__*/React.createElement("div", {
716
- className: "cc-navbar"
717
- }, /*#__PURE__*/React.createElement(CCTabs, {
718
- value: tab,
719
- onChange: setTab,
720
- items: items
721
- })), /*#__PURE__*/React.createElement("main", {
722
- className: "cc-main"
723
- }, View ? /*#__PURE__*/React.createElement(View, null) : null), /*#__PURE__*/React.createElement("footer", {
724
- className: "cc-footer"
725
- }, /*#__PURE__*/React.createElement("span", null, "Chan Compass \xB7 educational tool, not investment advice"), /*#__PURE__*/React.createElement("span", {
726
- className: "cc-foot-sep"
727
- }, "\xB7"), /*#__PURE__*/React.createElement("span", null, "data: Yahoo Finance"), /*#__PURE__*/React.createElement("span", {
728
- className: "cc-foot-sep"
729
- }, "\xB7"), /*#__PURE__*/React.createElement("span", null, "design language: Adobe Spectrum 2")));
730
- }
731
- ReactDOM.createRoot(document.getElementById('root')).render(/*#__PURE__*/React.createElement(App, null));
732
- })(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/chan-compass/app.jsx", error: String((e && e.message) || e) }); }
733
-
734
- // ui_kits/chan-compass/data.js
735
- try { (() => {
736
- // Fake data for the Chan Compass UI kit — shapes mirror the real signal_runner /
737
- // rotation engine output, values are illustrative.
738
- window.CC_DATA = {
739
- asof: 'Jun 12, 2026 · 18:10 ET',
740
- signals: [{
741
- t: 'NVDA',
742
- action: 'BUY',
743
- price: 178.42,
744
- chg: +2.43,
745
- conf: 0.82,
746
- weight: 8,
747
- stop: 172.40,
748
- zone: '176.9 – 179.2',
749
- note: 'Weekly pivot uplift confirmed; daily B1 armed off divergence low.'
750
- }, {
751
- t: 'MSFT',
752
- action: 'BUY',
753
- price: 472.10,
754
- chg: +0.91,
755
- conf: 0.74,
756
- weight: 6,
757
- stop: 458.00,
758
- zone: '468 – 474',
759
- note: '30m/15m nested-interval bottom confirms weekly hold-and-add.'
760
- }, {
761
- t: 'AMD',
762
- action: 'HOLD',
763
- price: 142.88,
764
- chg: +1.12,
765
- conf: 0.61,
766
- weight: 5,
767
- stop: 133.50,
768
- zone: '—',
769
- note: 'Unconfirmed daily sell inside weekly uptrend → hold (armed).'
770
- }, {
771
- t: 'AAPL',
772
- action: 'HOLD',
773
- price: 214.55,
774
- chg: -0.34,
775
- conf: 0.58,
776
- weight: 5,
777
- stop: 205.10,
778
- zone: '—',
779
- note: 'Riding pivot; no sublevel sell confirmation yet.'
780
- }, {
781
- t: 'TSLA',
782
- action: 'SELL',
783
- price: 243.17,
784
- chg: -3.08,
785
- conf: 0.69,
786
- weight: 0,
787
- stop: 251.00,
788
- zone: '242 – 246',
789
- note: 'Daily S3 pivot breakdown; nested-interval top confirmed.'
790
- }, {
791
- t: 'META',
792
- action: 'WATCH',
793
- price: 611.40,
794
- chg: +0.22,
795
- conf: 0.44,
796
- weight: 0,
797
- stop: '—',
798
- zone: '—',
799
- note: 'Approaching weekly pivot edge; no signal armed.'
800
- }, {
801
- t: 'AMZN',
802
- action: 'WAIT',
803
- price: 201.66,
804
- chg: -0.51,
805
- conf: 0.39,
806
- weight: 0,
807
- stop: '—',
808
- zone: '—',
809
- note: 'Inside consolidation; wait for level resolution.'
810
- }, {
811
- t: 'GOOGL',
812
- action: 'WAIT',
813
- price: 182.03,
814
- chg: +0.08,
815
- conf: 0.35,
816
- weight: 0,
817
- stop: '—',
818
- zone: '—',
819
- note: 'No multi-timeframe alignment.'
820
- }],
821
- rotation: [{
822
- s: 'Technology',
823
- sym: 'XLK',
824
- d1: +1.84,
825
- d5: +3.2,
826
- d20: +6.1,
827
- rs: +2.4
828
- }, {
829
- s: 'Comm. Services',
830
- sym: 'XLC',
831
- d1: +1.12,
832
- d5: +2.1,
833
- d20: +4.4,
834
- rs: +1.6
835
- }, {
836
- s: 'Financials',
837
- sym: 'XLF',
838
- d1: +0.64,
839
- d5: +1.0,
840
- d20: +2.2,
841
- rs: +0.5
842
- }, {
843
- s: 'Energy',
844
- sym: 'XLE',
845
- d1: +0.41,
846
- d5: -0.8,
847
- d20: -1.9,
848
- rs: -1.1
849
- }, {
850
- s: 'Industrials',
851
- sym: 'XLI',
852
- d1: +0.18,
853
- d5: +0.6,
854
- d20: +1.1,
855
- rs: +0.2
856
- }, {
857
- s: 'Health Care',
858
- sym: 'XLV',
859
- d1: -0.22,
860
- d5: -0.4,
861
- d20: +0.3,
862
- rs: -0.4
863
- }, {
864
- s: 'Cons. Staples',
865
- sym: 'XLP',
866
- d1: -0.38,
867
- d5: -0.9,
868
- d20: -1.2,
869
- rs: -0.9
870
- }, {
871
- s: 'Utilities',
872
- sym: 'XLU',
873
- d1: -0.51,
874
- d5: -1.3,
875
- d20: -2.0,
876
- rs: -1.3
877
- }, {
878
- s: 'Real Estate',
879
- sym: 'XLRE',
880
- d1: -0.74,
881
- d5: -1.6,
882
- d20: -2.8,
883
- rs: -1.7
884
- }, {
885
- s: 'Materials',
886
- sym: 'XLB',
887
- d1: -0.88,
888
- d5: -1.1,
889
- d20: -1.5,
890
- rs: -0.8
891
- }, {
892
- s: 'Cons. Disc.',
893
- sym: 'XLY',
894
- d1: -1.06,
895
- d5: -2.0,
896
- d20: -3.4,
897
- rs: -2.1
898
- }],
899
- reports: ['NVDA · 2026-06-12', 'TSLA · 2026-06-11', 'MSFT · 2026-06-10', 'AMD · 2026-06-09']
900
- };
901
- })(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/chan-compass/data.js", error: String((e && e.message) || e) }); }
902
-
903
- // ui_kits/chan-compass/views.jsx
904
- try { (() => {
905
- /* Chan Compass UI kit — view components. Each consumes the design-system
906
- primitives from the bundle namespace + Lucide line icons. Exported to window
907
- for app.jsx to compose. */
908
- const DS = window.ChanCompassSpectrum2DesignSystem_b52b37;
909
- const {
910
- Button,
911
- Field,
912
- Checkbox,
913
- Switch,
914
- Card,
915
- InlineAlert,
916
- Badge,
917
- StatusLight,
918
- SignalBadge,
919
- Tabs
920
- } = DS;
921
- const {
922
- useState,
923
- useEffect
924
- } = React;
925
- function Icon({
926
- name,
927
- size = 18,
928
- color,
929
- style
930
- }) {
931
- // Lucide renders by replacing <i data-lucide>. Re-run after mount.
932
- useEffect(() => {
933
- if (window.lucide) window.lucide.createIcons();
934
- });
935
- return /*#__PURE__*/React.createElement("i", {
936
- "data-lucide": name,
937
- style: {
938
- width: size,
939
- height: size,
940
- color,
941
- display: 'inline-flex',
942
- ...style
943
- }
944
- });
945
- }
946
- const fmtPct = v => typeof v === 'number' ? (v > 0 ? '+' : '') + v.toFixed(2) + '%' : v;
947
- const dirColor = v => v > 0 ? 'var(--up)' : v < 0 ? 'var(--down)' : 'var(--flat)';
948
-
949
- /* ─────────────────────────── KPI strip ─────────────────────────── */
950
- function Kpi({
951
- label,
952
- value,
953
- tone
954
- }) {
955
- return /*#__PURE__*/React.createElement("div", {
956
- style: {
957
- flex: 1,
958
- padding: '14px 18px',
959
- background: 'var(--surface-card)',
960
- border: '1px solid var(--border-hairline)',
961
- borderRadius: 'var(--radius-lg)',
962
- boxShadow: 'var(--shadow-raised)'
963
- }
964
- }, /*#__PURE__*/React.createElement("div", {
965
- style: {
966
- font: 'var(--font-weight-bold) 28px/1 var(--font-sans)',
967
- color: tone || 'var(--text-heading)'
968
- }
969
- }, value), /*#__PURE__*/React.createElement("div", {
970
- style: {
971
- font: 'var(--type-detail)',
972
- color: 'var(--text-muted)',
973
- marginTop: 4
974
- }
975
- }, label));
976
- }
977
-
978
- /* ─────────────────────────── Signals ─────────────────────────── */
979
- function SignalsView() {
980
- const D = window.CC_DATA;
981
- const [pool, setPool] = useState('AAPL, MSFT, NVDA, TSLA, AMZN, GOOGL, META, AMD');
982
- const [force, setForce] = useState(false);
983
- const [running, setRunning] = useState(false);
984
- const [ran, setRan] = useState(true);
985
- const [sel, setSel] = useState('NVDA');
986
- const [explained, setExplained] = useState(false);
987
- const rows = D.signals;
988
- const counts = rows.reduce((a, r) => {
989
- a[r.action] = (a[r.action] || 0) + 1;
990
- return a;
991
- }, {});
992
- const cur = rows.find(r => r.t === sel) || rows[0];
993
- const run = () => {
994
- setRunning(true);
995
- setRan(false);
996
- setExplained(false);
997
- setTimeout(() => {
998
- setRunning(false);
999
- setRan(true);
1000
- }, 1100);
1001
- };
1002
- return /*#__PURE__*/React.createElement("div", {
1003
- style: {
1004
- display: 'flex',
1005
- flexDirection: 'column',
1006
- gap: 'var(--space-300)'
1007
- }
1008
- }, /*#__PURE__*/React.createElement("div", {
1009
- style: {
1010
- display: 'flex',
1011
- gap: 'var(--space-200)'
1012
- }
1013
- }, /*#__PURE__*/React.createElement(Kpi, {
1014
- label: "BUY signals",
1015
- value: counts.BUY || 0,
1016
- tone: "var(--up)"
1017
- }), /*#__PURE__*/React.createElement(Kpi, {
1018
- label: "SELL signals",
1019
- value: counts.SELL || 0,
1020
- tone: "var(--down)"
1021
- }), /*#__PURE__*/React.createElement(Kpi, {
1022
- label: "Holding",
1023
- value: counts.HOLD || 0,
1024
- tone: "var(--accent)"
1025
- }), /*#__PURE__*/React.createElement(Kpi, {
1026
- label: "Watch / wait",
1027
- value: (counts.WATCH || 0) + (counts.WAIT || 0)
1028
- })), /*#__PURE__*/React.createElement(Card, {
1029
- title: "Tomorrow's plan",
1030
- subtitle: "Long-hold mode \xB7 sorted BUY \u2192 SELL \u2192 HOLD \u2192 WAIT",
1031
- action: /*#__PURE__*/React.createElement(Badge, {
1032
- variant: "neutral"
1033
- }, D.asof)
1034
- }, /*#__PURE__*/React.createElement("div", {
1035
- style: {
1036
- display: 'flex',
1037
- gap: 'var(--space-200)',
1038
- alignItems: 'flex-end',
1039
- marginBottom: 'var(--space-250)'
1040
- }
1041
- }, /*#__PURE__*/React.createElement(Field, {
1042
- label: "Ticker pool",
1043
- mono: true,
1044
- value: pool,
1045
- onChange: e => setPool(e.target.value),
1046
- className: "grow",
1047
- help: "Comma separated \xB7 the unchanged Chan engine runs over each"
1048
- }), /*#__PURE__*/React.createElement(Checkbox, {
1049
- checked: force,
1050
- onChange: e => setForce(e.target.checked)
1051
- }, "Force fresh download"), /*#__PURE__*/React.createElement(Button, {
1052
- variant: "accent",
1053
- onClick: run,
1054
- disabled: running
1055
- }, running ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Icon, {
1056
- name: "loader",
1057
- size: 15
1058
- }), " Running\u2026") : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Icon, {
1059
- name: "play",
1060
- size: 15
1061
- }), " Run analysis"))), /*#__PURE__*/React.createElement("div", {
1062
- className: "cc-table"
1063
- }, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "Ticker"), /*#__PURE__*/React.createElement("th", null, "Signal"), /*#__PURE__*/React.createElement("th", {
1064
- className: "num"
1065
- }, "Price"), /*#__PURE__*/React.createElement("th", {
1066
- className: "num"
1067
- }, "\u0394 Day"), /*#__PURE__*/React.createElement("th", null, "Buy/sell zone"), /*#__PURE__*/React.createElement("th", {
1068
- className: "num"
1069
- }, "Conf."), /*#__PURE__*/React.createElement("th", {
1070
- className: "num"
1071
- }, "Stop"), /*#__PURE__*/React.createElement("th", {
1072
- className: "num"
1073
- }, "Wt %"))), /*#__PURE__*/React.createElement("tbody", null, rows.map(r => /*#__PURE__*/React.createElement("tr", {
1074
- key: r.t,
1075
- className: r.t === sel ? 'sel' : '',
1076
- onClick: () => {
1077
- setSel(r.t);
1078
- setExplained(false);
1079
- }
1080
- }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", {
1081
- className: "mono bold"
1082
- }, r.t)), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(SignalBadge, {
1083
- action: r.action
1084
- })), /*#__PURE__*/React.createElement("td", {
1085
- className: "num mono"
1086
- }, r.price.toFixed(2)), /*#__PURE__*/React.createElement("td", {
1087
- className: "num mono",
1088
- style: {
1089
- color: dirColor(r.chg)
1090
- }
1091
- }, fmtPct(r.chg)), /*#__PURE__*/React.createElement("td", {
1092
- className: "mono dim"
1093
- }, r.zone), /*#__PURE__*/React.createElement("td", {
1094
- className: "num"
1095
- }, /*#__PURE__*/React.createElement(ConfBar, {
1096
- v: r.conf
1097
- })), /*#__PURE__*/React.createElement("td", {
1098
- className: "num mono dim"
1099
- }, r.stop === '—' ? '—' : typeof r.stop === 'number' ? r.stop.toFixed(2) : r.stop), /*#__PURE__*/React.createElement("td", {
1100
- className: "num mono"
1101
- }, r.weight ? r.weight : '—'))))))), /*#__PURE__*/React.createElement("div", {
1102
- style: {
1103
- display: 'grid',
1104
- gridTemplateColumns: '1fr 1fr',
1105
- gap: 'var(--space-300)',
1106
- alignItems: 'start'
1107
- }
1108
- }, /*#__PURE__*/React.createElement(Card, {
1109
- title: `Decision log · ${cur.t}`,
1110
- subtitle: "The engine's full multi-timeframe ruling chain"
1111
- }, /*#__PURE__*/React.createElement("div", {
1112
- className: "cc-log"
1113
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
1114
- className: "mono dim"
1115
- }, "\u6708\u7EBF monthly"), " \u4E0A\u6DA8\u8D8B\u52BF \xB7 \u4E2D\u67A2\u4E0A\u79FB \u2713"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
1116
- className: "mono dim"
1117
- }, "\u5468\u7EBF weekly"), " \u7B2C\u4E09\u7C7B\u4E70\u70B9 B3 \xB7 \u64CD\u4F5C\u7EA7\u522B \u2713"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
1118
- className: "mono dim"
1119
- }, "\u65E5\u7EBF daily"), " ", cur.action === 'SELL' ? 'S3 中枢破位 · 确认顶背驰' : 'B1 背驰 · 已武装 (armed)', " "), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
1120
- className: "mono dim"
1121
- }, "60m / 30m"), " \u533A\u95F4\u5957\u786E\u8BA4 nested-interval \u2713"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
1122
- className: "mono dim"
1123
- }, "15m / 5m"), " \u6B21\u7EA7\u522B", cur.action === 'SELL' ? '卖点确认' : '买点未确认 → 持有'), /*#__PURE__*/React.createElement("div", {
1124
- className: "cc-log-note"
1125
- }, cur.note)), /*#__PURE__*/React.createElement("div", {
1126
- style: {
1127
- marginTop: 'var(--space-200)'
1128
- }
1129
- }, /*#__PURE__*/React.createElement(Button, {
1130
- variant: "secondary",
1131
- size: "sm",
1132
- onClick: () => setExplained(true)
1133
- }, /*#__PURE__*/React.createElement(Icon, {
1134
- name: "languages",
1135
- size: 14
1136
- }), " Explain in English (local LLM)"))), explained ? /*#__PURE__*/React.createElement(InlineAlert, {
1137
- variant: "ai",
1138
- title: "Translator sub-agent \xB7 Qwen3-1.7B \xB7 llama.cpp"
1139
- }, /*#__PURE__*/React.createElement("div", {
1140
- style: {
1141
- display: 'flex',
1142
- flexDirection: 'column',
1143
- gap: 6,
1144
- marginTop: 4
1145
- }
1146
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("b", null, "Action:"), " ", cur.action, cur.action === 'BUY' ? ' — add on weekly pivot uplift' : cur.action === 'SELL' ? ' — exit, top confirmed' : ' — hold the position', "."), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("b", null, "Why:"), " Monthly & weekly gates passed; daily ", cur.action === 'SELL' ? 'broke the pivot (S3)' : 'B1 armed off the divergence low', "; intraday ", cur.action === 'SELL' ? 'confirmed the top' : 'has not confirmed a sell', "."), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("b", null, "Invalidation:"), " ", cur.stop === '—' ? 'no active stop' : `flips below ${typeof cur.stop === 'number' ? cur.stop.toFixed(2) : cur.stop}`, "."))) : /*#__PURE__*/React.createElement("div", {
1147
- className: "cc-empty"
1148
- }, /*#__PURE__*/React.createElement(Icon, {
1149
- name: "sparkles",
1150
- size: 22,
1151
- color: "var(--text-disabled)"
1152
- }), /*#__PURE__*/React.createElement("div", null, "AI explanation appears here.", /*#__PURE__*/React.createElement("br", null), "Select a ticker, then \u201CExplain in English\u201D."))));
1153
- }
1154
- function ConfBar({
1155
- v
1156
- }) {
1157
- return /*#__PURE__*/React.createElement("span", {
1158
- style: {
1159
- display: 'inline-flex',
1160
- alignItems: 'center',
1161
- gap: 6,
1162
- justifyContent: 'flex-end'
1163
- }
1164
- }, /*#__PURE__*/React.createElement("span", {
1165
- style: {
1166
- width: 46,
1167
- height: 6,
1168
- borderRadius: 'var(--radius-full)',
1169
- background: 'var(--surface-subtle)',
1170
- overflow: 'hidden'
1171
- }
1172
- }, /*#__PURE__*/React.createElement("span", {
1173
- style: {
1174
- display: 'block',
1175
- height: '100%',
1176
- width: `${v * 100}%`,
1177
- background: v > 0.7 ? 'var(--positive)' : v > 0.5 ? 'var(--accent)' : 'var(--s2-gray-400)'
1178
- }
1179
- })), /*#__PURE__*/React.createElement("span", {
1180
- className: "mono dim",
1181
- style: {
1182
- fontSize: 11
1183
- }
1184
- }, Math.round(v * 100)));
1185
- }
1186
-
1187
- /* ─────────────────────────── Rotation ─────────────────────────── */
1188
- function RotationView() {
1189
- const D = window.CC_DATA;
1190
- const [ai, setAi] = useState(false);
1191
- const max = Math.max(...D.rotation.map(r => Math.abs(r.d1)));
1192
- return /*#__PURE__*/React.createElement("div", {
1193
- style: {
1194
- display: 'flex',
1195
- flexDirection: 'column',
1196
- gap: 'var(--space-300)'
1197
- }
1198
- }, /*#__PURE__*/React.createElement(InlineAlert, {
1199
- variant: "informative",
1200
- title: "Where capital is flowing"
1201
- }, "11 SPDR sector ETFs (full S&P 500). Flow proxy = change % \xD7 dollar volume; RS = return minus SPY."), /*#__PURE__*/React.createElement("div", {
1202
- style: {
1203
- display: 'grid',
1204
- gridTemplateColumns: '1.4fr 1fr',
1205
- gap: 'var(--space-300)',
1206
- alignItems: 'start'
1207
- }
1208
- }, /*#__PURE__*/React.createElement(Card, {
1209
- title: "Sector rotation",
1210
- subtitle: "1-day flow \xB7 today",
1211
- action: /*#__PURE__*/React.createElement(Button, {
1212
- variant: "secondary",
1213
- size: "sm"
1214
- }, /*#__PURE__*/React.createElement(Icon, {
1215
- name: "refresh-cw",
1216
- size: 14
1217
- }), " Refresh")
1218
- }, /*#__PURE__*/React.createElement("div", {
1219
- className: "cc-flow"
1220
- }, D.rotation.map(r => /*#__PURE__*/React.createElement("div", {
1221
- key: r.sym,
1222
- className: "cc-flow-row"
1223
- }, /*#__PURE__*/React.createElement("span", {
1224
- className: "cc-flow-name"
1225
- }, /*#__PURE__*/React.createElement("span", {
1226
- className: "mono bold"
1227
- }, r.sym), " ", /*#__PURE__*/React.createElement("span", {
1228
- className: "dim"
1229
- }, r.s)), /*#__PURE__*/React.createElement("span", {
1230
- className: "cc-flow-track"
1231
- }, /*#__PURE__*/React.createElement("span", {
1232
- className: "cc-flow-bar",
1233
- style: {
1234
- width: `${Math.abs(r.d1) / max * 50}%`,
1235
- marginLeft: r.d1 < 0 ? `${50 - Math.abs(r.d1) / max * 50}%` : '50%',
1236
- background: dirColor(r.d1)
1237
- }
1238
- }), /*#__PURE__*/React.createElement("span", {
1239
- className: "cc-flow-mid"
1240
- })), /*#__PURE__*/React.createElement("span", {
1241
- className: "num mono",
1242
- style: {
1243
- color: dirColor(r.d1),
1244
- width: 54
1245
- }
1246
- }, fmtPct(r.d1)))))), /*#__PURE__*/React.createElement("div", {
1247
- style: {
1248
- display: 'flex',
1249
- flexDirection: 'column',
1250
- gap: 'var(--space-200)'
1251
- }
1252
- }, /*#__PURE__*/React.createElement(Card, {
1253
- title: "Multi-window trend",
1254
- elevation: "raised"
1255
- }, /*#__PURE__*/React.createElement("div", {
1256
- className: "cc-table compact"
1257
- }, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "ETF"), /*#__PURE__*/React.createElement("th", {
1258
- className: "num"
1259
- }, "5-day"), /*#__PURE__*/React.createElement("th", {
1260
- className: "num"
1261
- }, "20-day"), /*#__PURE__*/React.createElement("th", {
1262
- className: "num"
1263
- }, "RS vs SPY"))), /*#__PURE__*/React.createElement("tbody", null, D.rotation.slice(0, 6).map(r => /*#__PURE__*/React.createElement("tr", {
1264
- key: r.sym
1265
- }, /*#__PURE__*/React.createElement("td", {
1266
- className: "mono bold"
1267
- }, r.sym), /*#__PURE__*/React.createElement("td", {
1268
- className: "num mono",
1269
- style: {
1270
- color: dirColor(r.d5)
1271
- }
1272
- }, fmtPct(r.d5)), /*#__PURE__*/React.createElement("td", {
1273
- className: "num mono",
1274
- style: {
1275
- color: dirColor(r.d20)
1276
- }
1277
- }, fmtPct(r.d20)), /*#__PURE__*/React.createElement("td", {
1278
- className: "num mono",
1279
- style: {
1280
- color: dirColor(r.rs)
1281
- }
1282
- }, fmtPct(r.rs)))))))), /*#__PURE__*/React.createElement(Button, {
1283
- variant: "accent",
1284
- onClick: () => setAi(true)
1285
- }, /*#__PURE__*/React.createElement(Icon, {
1286
- name: "bot",
1287
- size: 15
1288
- }), " AI narrative (local LLM)"), ai && /*#__PURE__*/React.createElement(InlineAlert, {
1289
- variant: "ai",
1290
- title: "Narrator sub-agent \xB7 Qwen3-1.7B"
1291
- }, "Capital is rotating ", /*#__PURE__*/React.createElement("b", null, "into Technology & Comm. Services"), " (XLK +1.84%, leading on both 5- and 20-day) and", /*#__PURE__*/React.createElement("b", null, " out of Consumer Discretionary & Real Estate"), ". Today's moves agree with the monthly trend \u2014 risk-on persists. ", /*#__PURE__*/React.createElement("b", null, "Watch:"), " Energy's 1-day pop diverges from its negative 20-day; likely a bounce, not a turn."))));
1292
- }
1293
-
1294
- /* ─────────────────────────── Research ─────────────────────────── */
1295
- function ResearchView() {
1296
- const D = window.CC_DATA;
1297
- const [tic, setTic] = useState('');
1298
- const [step, setStep] = useState(0); // 0 idle, 1..5 running, 6 done
1299
- const steps = ['PLAN', 'Fundamentals', 'Quarterly financials', 'Price action + Chan engine', 'News', 'Report'];
1300
- const run = () => {
1301
- setStep(1);
1302
- let i = 1;
1303
- const tick = () => {
1304
- i++;
1305
- setStep(i);
1306
- if (i < 6) setTimeout(tick, 650);
1307
- };
1308
- setTimeout(tick, 650);
1309
- };
1310
- return /*#__PURE__*/React.createElement("div", {
1311
- style: {
1312
- display: 'grid',
1313
- gridTemplateColumns: '1fr 300px',
1314
- gap: 'var(--space-300)',
1315
- alignItems: 'start'
1316
- }
1317
- }, /*#__PURE__*/React.createElement(Card, {
1318
- title: "Auto research agent",
1319
- subtitle: "Fully local \xB7 PLAN \u2192 5 evidence tools \u2192 sectioned report"
1320
- }, /*#__PURE__*/React.createElement("div", {
1321
- style: {
1322
- display: 'flex',
1323
- gap: 'var(--space-150)',
1324
- alignItems: 'flex-end',
1325
- marginBottom: 'var(--space-250)'
1326
- }
1327
- }, /*#__PURE__*/React.createElement(Field, {
1328
- label: "Ticker",
1329
- placeholder: "e.g. NVDA",
1330
- value: tic,
1331
- onChange: e => setTic(e.target.value),
1332
- className: "grow"
1333
- }), /*#__PURE__*/React.createElement(Button, {
1334
- variant: "accent",
1335
- onClick: run,
1336
- disabled: step > 0 && step < 6
1337
- }, /*#__PURE__*/React.createElement(Icon, {
1338
- name: "bot",
1339
- size: 15
1340
- }), " Run research agent")), step === 0 ? /*#__PURE__*/React.createElement("div", {
1341
- className: "cc-empty tall"
1342
- }, /*#__PURE__*/React.createElement(Icon, {
1343
- name: "file-search",
1344
- size: 24,
1345
- color: "var(--text-disabled)"
1346
- }), /*#__PURE__*/React.createElement("div", null, "Agent trace + sectioned report appear here.")) : /*#__PURE__*/React.createElement("div", {
1347
- style: {
1348
- display: 'flex',
1349
- flexDirection: 'column',
1350
- gap: 10
1351
- }
1352
- }, steps.map((s, idx) => /*#__PURE__*/React.createElement("div", {
1353
- key: s,
1354
- className: "cc-step"
1355
- }, /*#__PURE__*/React.createElement("span", {
1356
- className: `cc-step-dot ${step > idx ? 'done' : step === idx + 1 ? 'active' : ''}`
1357
- }, step > idx + 1 ? /*#__PURE__*/React.createElement(Icon, {
1358
- name: "check",
1359
- size: 12,
1360
- color: "#fff"
1361
- }) : idx + 1), /*#__PURE__*/React.createElement("span", {
1362
- style: {
1363
- color: step > idx ? 'var(--text-body)' : 'var(--text-muted)'
1364
- }
1365
- }, s))), step >= 6 && /*#__PURE__*/React.createElement(InlineAlert, {
1366
- variant: "ai",
1367
- title: `Analyst · ${tic || 'NVDA'} · Qwen3-4B`
1368
- }, /*#__PURE__*/React.createElement("b", null, "Valuation:"), " rich vs 5-yr median but justified by datacenter demand.", /*#__PURE__*/React.createElement("b", null, " Moat:"), " CUDA lock-in + supply-chain priority. ", /*#__PURE__*/React.createElement("b", null, "Chan timing:"), " weekly B3 active, daily B1 armed \u2014 accumulation favorable. ", /*#__PURE__*/React.createElement("b", null, "Risks:"), " export controls, hyperscaler capex digestion."))), /*#__PURE__*/React.createElement(Card, {
1369
- title: "Report library",
1370
- subtitle: "Auto + manual \xB7 /data",
1371
- elevation: "raised"
1372
- }, /*#__PURE__*/React.createElement("div", {
1373
- className: "cc-list"
1374
- }, D.reports.map((r, i) => /*#__PURE__*/React.createElement("button", {
1375
- key: r,
1376
- className: `cc-list-item ${i === 0 ? 'sel' : ''}`
1377
- }, /*#__PURE__*/React.createElement(Icon, {
1378
- name: "file-text",
1379
- size: 15,
1380
- color: "var(--text-muted)"
1381
- }), /*#__PURE__*/React.createElement("span", {
1382
- className: "mono"
1383
- }, r))))));
1384
- }
1385
-
1386
- /* ─────────────────────────── News ─────────────────────────── */
1387
- function NewsView() {
1388
- const [hold, setHold] = useState('NVDA, TSLA, AAPL');
1389
- const [checked, setChecked] = useState(false);
1390
- return /*#__PURE__*/React.createElement("div", {
1391
- style: {
1392
- display: 'flex',
1393
- flexDirection: 'column',
1394
- gap: 'var(--space-300)',
1395
- maxWidth: 760
1396
- }
1397
- }, /*#__PURE__*/React.createElement(Card, {
1398
- title: "Watchlist news",
1399
- subtitle: "For each holding, only today's news is checked"
1400
- }, /*#__PURE__*/React.createElement("div", {
1401
- style: {
1402
- display: 'flex',
1403
- gap: 'var(--space-150)',
1404
- alignItems: 'flex-end',
1405
- marginBottom: 'var(--space-200)'
1406
- }
1407
- }, /*#__PURE__*/React.createElement(Field, {
1408
- label: "My holdings",
1409
- mono: true,
1410
- value: hold,
1411
- onChange: e => setHold(e.target.value),
1412
- className: "grow"
1413
- }), /*#__PURE__*/React.createElement(Button, {
1414
- variant: "secondary"
1415
- }, /*#__PURE__*/React.createElement(Icon, {
1416
- name: "save",
1417
- size: 14
1418
- }), " Save"), /*#__PURE__*/React.createElement(Button, {
1419
- variant: "accent",
1420
- onClick: () => setChecked(true)
1421
- }, /*#__PURE__*/React.createElement(Icon, {
1422
- name: "search",
1423
- size: 15
1424
- }), " Check today's news")), !checked ? /*#__PURE__*/React.createElement("div", {
1425
- className: "cc-empty"
1426
- }, /*#__PURE__*/React.createElement(Icon, {
1427
- name: "newspaper",
1428
- size: 22,
1429
- color: "var(--text-disabled)"
1430
- }), /*#__PURE__*/React.createElement("div", null, "News briefs appear here.")) : /*#__PURE__*/React.createElement("div", {
1431
- style: {
1432
- display: 'flex',
1433
- flexDirection: 'column',
1434
- gap: 'var(--space-150)'
1435
- }
1436
- }, /*#__PURE__*/React.createElement(InlineAlert, {
1437
- variant: "ai",
1438
- title: "NVDA \xB7 AI brief"
1439
- }, "New datacenter GPU order from a hyperscaler reported pre-market; reinforces the active weekly B3 buy structure."), /*#__PURE__*/React.createElement(InlineAlert, {
1440
- variant: "ai",
1441
- title: "TSLA \xB7 AI brief"
1442
- }, "Delivery-miss headline; aligns with today's daily S3 breakdown \u2014 confirms the SELL."), /*#__PURE__*/React.createElement("div", {
1443
- className: "cc-quiet"
1444
- }, /*#__PURE__*/React.createElement(StatusLight, {
1445
- variant: "neutral"
1446
- }, "Quiet today \xB7 AAPL")))));
1447
- }
1448
-
1449
- /* ─────────────────────────── Model ─────────────────────────── */
1450
- function ModelView() {
1451
- const models = ['Qwen3-1.7B', 'Qwen3-4B', 'Qwen3-8B', 'Qwen3-14B'];
1452
- const [pick, setPick] = useState('Qwen3-4B');
1453
- const [loaded, setLoaded] = useState('Qwen3-4B');
1454
- return /*#__PURE__*/React.createElement("div", {
1455
- style: {
1456
- display: 'flex',
1457
- flexDirection: 'column',
1458
- gap: 'var(--space-300)',
1459
- maxWidth: 680
1460
- }
1461
- }, /*#__PURE__*/React.createElement(InlineAlert, {
1462
- variant: "informative",
1463
- title: "Everything runs locally through llama.cpp"
1464
- }, "Qwen3 GGUF weights, all below the 32B cap. Nothing leaves the machine. Signals, rotation & news never depend on it."), /*#__PURE__*/React.createElement(Card, {
1465
- title: "Analyst (deep) model",
1466
- subtitle: "Sub-agent pool \xB7 fast 1.7B fixed + this deep model"
1467
- }, /*#__PURE__*/React.createElement("div", {
1468
- className: "cc-radios"
1469
- }, models.map(m => /*#__PURE__*/React.createElement("label", {
1470
- key: m,
1471
- className: `cc-radio ${pick === m ? 'sel' : ''}`,
1472
- onClick: () => setPick(m)
1473
- }, /*#__PURE__*/React.createElement("span", {
1474
- className: "cc-radio-dot"
1475
- }), /*#__PURE__*/React.createElement("span", {
1476
- className: "mono"
1477
- }, m), loaded === m && /*#__PURE__*/React.createElement(Badge, {
1478
- variant: "positive"
1479
- }, "loaded")))), /*#__PURE__*/React.createElement("div", {
1480
- style: {
1481
- display: 'flex',
1482
- gap: 'var(--space-150)',
1483
- marginTop: 'var(--space-250)',
1484
- alignItems: 'center'
1485
- }
1486
- }, /*#__PURE__*/React.createElement(Button, {
1487
- variant: "accent",
1488
- onClick: () => setLoaded(pick)
1489
- }, /*#__PURE__*/React.createElement(Icon, {
1490
- name: "download",
1491
- size: 15
1492
- }), " Load model"), /*#__PURE__*/React.createElement(Button, {
1493
- variant: "quiet"
1494
- }, /*#__PURE__*/React.createElement(Icon, {
1495
- name: "refresh-cw",
1496
- size: 14
1497
- }), " Refresh status"), /*#__PURE__*/React.createElement("span", {
1498
- style: {
1499
- marginLeft: 'auto'
1500
- }
1501
- }, /*#__PURE__*/React.createElement(StatusLight, {
1502
- variant: "positive",
1503
- live: true
1504
- }, loaded, " ready")))));
1505
- }
1506
- Object.assign(window, {
1507
- SignalsView,
1508
- RotationView,
1509
- ResearchView,
1510
- NewsView,
1511
- ModelView
1512
- });
1513
- })(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/chan-compass/views.jsx", error: String((e && e.message) || e) }); }
1514
-
1515
  __ds_ns.Button = __ds_scope.Button;
1516
 
1517
  __ds_ns.Card = __ds_scope.Card;
@@ -1532,4 +622,4 @@ __ds_ns.SignalBadge = __ds_scope.SignalBadge;
1532
 
1533
  __ds_ns.StatusLight = __ds_scope.StatusLight;
1534
 
1535
- })();
 
1
+ /* @ds-bundle: {"format":3,"namespace":"ChanCompassSpectrum2DesignSystem_b52b37","components":[{"name":"Button","sourcePath":"components/actions/Button.jsx"},{"name":"Card","sourcePath":"components/containers/Card.jsx"},{"name":"InlineAlert","sourcePath":"components/containers/InlineAlert.jsx"},{"name":"Checkbox","sourcePath":"components/forms/Checkbox.jsx"},{"name":"Field","sourcePath":"components/forms/Field.jsx"},{"name":"Switch","sourcePath":"components/forms/Switch.jsx"},{"name":"Tabs","sourcePath":"components/navigation/Tabs.jsx"},{"name":"Badge","sourcePath":"components/status/Badge.jsx"},{"name":"SignalBadge","sourcePath":"components/status/SignalBadge.jsx"},{"name":"StatusLight","sourcePath":"components/status/StatusLight.jsx"}],"sourceHashes":{"components/actions/Button.jsx":"c9f7501c202c","components/containers/Card.jsx":"9316d0c88d32","components/containers/InlineAlert.jsx":"5ceb8bdaac5f","components/forms/Checkbox.jsx":"59c34e791a76","components/forms/Field.jsx":"39157a609b42","components/forms/Switch.jsx":"38f4684e0ef2","components/navigation/Tabs.jsx":"5488bca491fa","components/status/Badge.jsx":"3e62358e3a0b","components/status/SignalBadge.jsx":"df7989e74422","components/status/StatusLight.jsx":"f7d206a1642b"},"inlinedExternals":[],"unexposedExports":[]} */
2
 
3
  (() => {
4
 
 
602
  Object.assign(__ds_scope, { StatusLight });
603
  })(); } catch (e) { __ds_ns.__errors.push({ path: "components/status/StatusLight.jsx", error: String((e && e.message) || e) }); }
604
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  __ds_ns.Button = __ds_scope.Button;
606
 
607
  __ds_ns.Card = __ds_scope.Card;
 
622
 
623
  __ds_ns.StatusLight = __ds_scope.StatusLight;
624
 
625
+ })();