dsh-cmdk 0.0.0-stage → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client.js ADDED
@@ -0,0 +1,2210 @@
1
+ /**
2
+ * dsh-cmdk — client half: the ⌘K palette.
3
+ *
4
+ * One overlay (shell.overlay) plus a small sidebar footer button. Navigation,
5
+ * renaming, archiving, forking and theming all go through public Client
6
+ * services; only the things a browser cannot do (reveal a directory, export a
7
+ * transcript) come from the tiny Host route.
8
+ */
9
+ window.__ModuleLoader__.load({
10
+ id: 'dsh-cmdk',
11
+ factory: (require) => {
12
+ var module = { exports: {} };
13
+ var exports = module.exports;
14
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
15
+ var react = require('react');
16
+ var h = react.createElement;
17
+ var useEffect = react.useEffect;
18
+ var useRef = react.useRef;
19
+ var useState = react.useState;
20
+
21
+ var API = '/cmdk';
22
+ var RECENT_KEY = 'dsh-cmdk/recent';
23
+ var MONO = 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace';
24
+
25
+ var C = {
26
+ text: 'var(--dsw-alias-label-primary)',
27
+ sub: 'var(--dsw-alias-label-secondary)',
28
+ line: 'var(--dsw-alias-border-l1)',
29
+ lineStrong: 'var(--dsw-alias-border-l2)',
30
+ layer: 'var(--dsw-alias-bg-layer-1)',
31
+ layerAlt: 'var(--dsw-alias-bg-layer-2)',
32
+ overlay: 'var(--dsw-alias-bg-overlay)',
33
+ base: 'var(--dsw-alias-bg-base)',
34
+ brand: 'var(--dsw-alias-brand-primary)',
35
+ err: 'var(--dsw-alias-state-error-primary)',
36
+ ok: 'var(--dsw-alias-state-success-primary)',
37
+ warn: 'var(--dsw-alias-state-warn-primary)',
38
+ };
39
+
40
+ var STRINGS = {
41
+ zh: {
42
+ placeholder: '搜索会话、工作区,或直接执行…',
43
+ emptyTitle: '没有匹配的结果',
44
+ emptyFor: '没有找到 “{q}”',
45
+ emptySub: '试试会话标题、工作区路径,或直接输入命令',
46
+ results: '项结果',
47
+ resultsLabel: '搜索结果',
48
+ palette: '命令面板',
49
+ clear: '清除',
50
+ hintSelect: '选择',
51
+ hintOpen: '打开',
52
+ hintActions: '更多',
53
+ hintRun: '执行',
54
+ hintBack: '返回',
55
+ hintClose: '关闭',
56
+ searching: '正在搜索…',
57
+ action: '动作',
58
+ session: '会话',
59
+ workspace: '工作区',
60
+ theme: '外观',
61
+ system: '系统',
62
+ recent: '最近使用',
63
+ footer: '搜索',
64
+ newSession: '新建会话',
65
+ newSessionHint: '在当前工作区开一个新会话',
66
+ switchWorkspace: '切换工作区',
67
+ themeLight: '外观:浅色',
68
+ themeDark: '外观:深色',
69
+ themeSystem: '外观:跟随系统',
70
+ fontBigger: '字号:放大',
71
+ fontSmaller: '字号:缩小',
72
+ fontReset: '字号:恢复默认',
73
+ langZh: '语言:中文',
74
+ langEn: 'Language: English',
75
+ openProfile: '打开 profile 目录',
76
+ openProfileHint: '在访达里定位当前 profile',
77
+ openSessions: '打开 sessions 目录',
78
+ openSessionsHint: '所有会话日志的存放位置',
79
+ plugin: '插件',
80
+ ext: '插件命令',
81
+ pluginOn: '已启用',
82
+ pluginOff: '已禁用',
83
+ enablePlugin: '启用插件',
84
+ disablePlugin: '禁用插件',
85
+ pluginDir: '打开插件目录',
86
+ restartHint: '重启后生效',
87
+ openLogs: '打开日志目录',
88
+ openLogsHint: '宿主运行日志',
89
+ reload: '刷新页面',
90
+ reloadHint: '重新加载客户端(插件更新后用)',
91
+ sessionOpen: '打开会话',
92
+ sessionOpenHint: '跳到这条会话',
93
+ rename: '重命名…',
94
+ renameHint: '改这条会话的标题',
95
+ archive: '归档会话',
96
+ archiveHint: '从侧栏移走(可在归档里找回)',
97
+ fork: 'Fork 到新会话',
98
+ forkHint: '从这条会话分叉出一条新的',
99
+ copyId: '复制会话 ID',
100
+ copyPath: '复制工作目录路径',
101
+ revealPath: '在访达打开工作目录',
102
+ exportMd: '导出为 Markdown…',
103
+ exportMdHint: '把整段对话存成 .md',
104
+ wsOpen: '打开工作区',
105
+ wsNew: '在工作区新建会话',
106
+ wsCopyPath: '复制工作区路径',
107
+ wsReveal: '在访达打开工作区',
108
+ renamePrompt: '输入新标题,回车确认',
109
+ cancelled: '已取消',
110
+ copied: '已复制',
111
+ done: '完成',
112
+ failed: '失败',
113
+ fontNow: '字号',
114
+ },
115
+ en: {
116
+ footer: 'Search',
117
+ placeholder: 'Search sessions and workspaces, or run a command…',
118
+ emptyTitle: 'No matching results',
119
+ emptyFor: 'No results for “{q}”',
120
+ emptySub: 'Try a session title, a workspace path, or a command',
121
+ results: 'results',
122
+ resultsLabel: 'Search results',
123
+ palette: 'Command palette',
124
+ clear: 'Clear',
125
+ hintSelect: 'select',
126
+ hintOpen: 'open',
127
+ hintActions: 'more',
128
+ hintRun: 'run',
129
+ hintBack: 'back',
130
+ hintClose: 'close',
131
+ searching: 'Searching…',
132
+ action: 'Actions',
133
+ session: 'Sessions',
134
+ workspace: 'Workspaces',
135
+ theme: 'Appearance',
136
+ system: 'System',
137
+ recent: 'Recent',
138
+ newSession: 'New session',
139
+ newSessionHint: 'Start a fresh session in the current workspace',
140
+ switchWorkspace: 'Switch workspace',
141
+ themeLight: 'Appearance: light',
142
+ themeDark: 'Appearance: dark',
143
+ themeSystem: 'Appearance: follow system',
144
+ fontBigger: 'Font: larger',
145
+ fontSmaller: 'Font: smaller',
146
+ fontReset: 'Font: reset',
147
+ langZh: '语言:中文',
148
+ langEn: 'Language: English',
149
+ plugin: 'Plugins',
150
+ ext: 'Plugin commands',
151
+ pluginOn: 'enabled',
152
+ pluginOff: 'disabled',
153
+ enablePlugin: 'Enable plugin',
154
+ disablePlugin: 'Disable plugin',
155
+ pluginDir: 'Open plugin folder',
156
+ restartHint: 'takes effect after restart',
157
+ openProfile: 'Open profile folder',
158
+ openProfileHint: 'Reveal the running profile in Finder',
159
+ openSessions: 'Open sessions folder',
160
+ openSessionsHint: 'Where every session log lives',
161
+ openLogs: 'Open log folder',
162
+ openLogsHint: 'Host runtime logs',
163
+ reload: 'Reload page',
164
+ reloadHint: 'Reload the client after a plugin update',
165
+ sessionOpen: 'Open session',
166
+ sessionOpenHint: 'Jump to this session',
167
+ rename: 'Rename…',
168
+ renameHint: 'Change this session title',
169
+ archive: 'Archive session',
170
+ archiveHint: 'Move it out of the sidebar (recoverable)',
171
+ fork: 'Fork into a new session',
172
+ forkHint: 'Branch a new session from this one',
173
+ copyId: 'Copy session id',
174
+ copyPath: 'Copy working directory',
175
+ revealPath: 'Reveal working directory',
176
+ exportMd: 'Export as Markdown…',
177
+ exportMdHint: 'Save the whole conversation as .md',
178
+ wsOpen: 'Open workspace',
179
+ wsNew: 'New session in workspace',
180
+ wsCopyPath: 'Copy workspace path',
181
+ wsReveal: 'Reveal workspace',
182
+ renamePrompt: 'Type a new title, ↵ to confirm',
183
+ cancelled: 'Cancelled',
184
+ copied: 'Copied',
185
+ done: 'Done',
186
+ failed: 'Failed',
187
+ fontNow: 'Font size',
188
+ },
189
+ };
190
+
191
+ // ---------------------------------------------------------------------
192
+ // pinyin initials (one letter per code point, 0x4E00 ↔ index 0)
193
+ // ---------------------------------------------------------------------
194
+ var PINYIN_LO = 0x4e00;
195
+ var PINYIN_HI = 0x9fff;
196
+ var PINYIN = 'ydkqsxhwzssxjbymgcczqpssqbycdscdqldylybsgjgyqzjjfgcclzzbwdwzjljpfyynwjjtmyyzwzhflyppqhgccyyymjqyxxgjxhsdsjnjjsmhmlzrxyfsngsyzzqzggllyjlgyzss.cykyyhqwjssggyxyqyjtwkdjhychmyxjtlxjyqbyxdldwrrjjwysrldzjpcbzjjbrcfslbczstzfxxthtrqggbdlyccscymmrfcyqzpwwjjyfcrwfdfzqpyddwyxkyj.wjffxjpdftzyhhycyswccyqsclcxxwzcxnbgnnxbxlzsqcbsgpysyzdhmdzbqbzcwdzzyytzhbtsyyfzgntnxqywqykbphhlxgybfmj.bjhhgqtjcysxstkzglyckglysmzxy.lm.ldccxgzyrcxsdltjzcqkcnnjwhjczzcqljststbnxbtyxc.qxgkwjyflzqlyhjqspsfxlfpbyqxxxydcczylllsjxfhjxpjbcffy.byxbhczbjyclwlczggbtssmdtjcxpthyqtgjjscjfzkjzjqnlzwlslhdzbwjncjzyzsqnycqyrzcjjwybrtwpyftw.xcskdzctbxhyzcyyjxzcfbzzmjyxxcdcz.ttbzljwfcgszsxfyrlnyjmbdthjxsqjccsbxyytsyfbjdztgbcnclcyzzbs.cyzzscjcshzqydxlbpjllmqxtydzxsqjtzpxlcglqccwjbhctdjjsfxj.jjtlbgxsxjmyjjqpfz.syjncydjxkjcdjszcb.rtcclnjqmwnqnclllkbybzzsyhqcltwlccrshllzntyln.wyzyxczxxgdkdmtc.d.jtsyys.dqdfmsd.jlhrwnqlybglxhlgtgxbqjdzfyjsjyjcjmrnymgrcjczgjmzmgxmmryxkjnymsgmzjymklfxmbdtgfbhcjhkylpfmdxlqjjsmtqgzsjlqdldgjyc.lcmzcsdjllnxdjffffjczfmzffpfkhkgdpqxkt.cjdhhzdddrrcfqyjkqccwjdxhwjlyllzgcfcqdsmlzpbjjplsbcjggdckkd.zsqsckjgcgkdjtjllzycxklqscgjcltfpcqczgwbjdqsdjjbyjhsjddwgfsjgdkccctllpspkjgqjhzzljplgjgjjthjjyjzcjmlzlyqbgjwmljkxzdznjqsyzmljlljkywxmkjlhskjgbmclyymkxjqlbmclkmdxxkwyxwslmlpsjqjcqxyjfjtjdxmxxllcrqbsyjbgwywxggbcyxpjtgp.pfgdjgbhbnsfjyzjkjkhxqfgqzkfhygkhdgllsdjjxpqykybnqsxqnszswhbsxwhxwbzzxdmndjbsbkbbzklylxgwxjjw.qzmywsjqlcjxxjqwj.qxscw.tlzhlyyysdzpyqyzcptlshtzcfycyxyljsdcjj.gyslcllyyysglrqq.ldxzscccc.dycjysfsgbfrsszqsbxjpsjwsdrckgjlgdkzjzbdktcsyqpyhstcldjlhmxmcgxyzhjdctmhltxzxylym.hyjcltyfbqqjbfbdf.htksqhzywwcnxxcdwhhwgyjl.gmdqcwgfjhcsntwyd.lbygqqw.sjpwn.lrydzsztxyqpzgcwxhngpyxshmdqjgztdppbfyhzhhjyfdzwkgkzbldntsxhq..gzxylzmmzyjzgszxkhkhtx.xxgyly.psthxdwhzydpx.gkydxbhnhxkdfjnmyhylpmg.cslnzhkxxlbzzlbmlsfbhhgsgyyggbhscy.jtxwlxtzqcwzydqdqmmgdqllszhlsjzwfjhqswsc.lq.zynytlsxth.znkzzsdhlacxtwwcsgqqtddyzbcchyqzflxpslzygpzsznglydqcbdlxjtct.jdkywnsyzljhhdzcwnyyzy.mhychhhxhjkzwsxhdnxlyscqydpclyzwmypbkxyjlkzhtyh.xqsyshx.smchkdscrswjpwqsgzjlwwschs.hsqnhzs.gnd.qtb..lzzmsstdqjcjktscj.xplggxhhg.xzcxpdmmhldgtybysjmxhmrcplxjzckzxshflqxccdhx.zfchzccdytcjyxqhlxdhypjqxnlsyydz.zjnyxq.zysjy.yjkypdgxddxsppyzndlthrhxydpcjjhtcxmctlhbynyhmhzllhnxmylllmdcppxhmxdkycyrdltxjchhznxclcclylnzsxzjzzlnnllwhyqsnjhxynttdkyjpychhy.gkcttwlgqrlggtgtygyhpyhylqyqgcwyqkpyyyttttlhyhlltyttsplkyzwgywgpydqqzzdqxskcqnmjjzzbxyqmjrtfbbtkhzkbjdjjkdjjtlbwfzpbtkqtztgpdgntpjyf.lqmkgxbcclzfhzcllll.dpmxdjhlcclgyhdzfgyddgcyyfgydxkss.bdhykdkdkhn.xxybfbyyhxcqg.bfqyjjdmljcsjzllpchbsxgjyndybyqspqwjlzkcddt.ccbkzdyzypjzqsjnkktknjdjgy.pgtlfyqk.sdntcyhblgdzhbbydmjrygkzyh.yybcmcdtyfzjjhgcjplxhldwxjjkytcyksssmtwcttqzlzbszdtwzxgz.gyktywxlhlcpbcll.qmmzsslcmbjcszzkydczxgqjdsmcytzqqlwzqzxssbpkdfqmddzdsddtdmfhtdyzj.qjqkypbdjyyxtljhdrqxxxh.ydhrjlklytwhllrllrcxylbwsrszzsymkzzhhkyhxksmzsyzgcjfbzbsqlfcxxxnxkxwymsddyqwggqmmyhcdzttfgyyhgstttybykjdhkyjb.lhdypjqnfxfdqkzhqkzbyjtzbxhfdxbd.swh.w.jldyjsfhbldnndnqjtjnchxfjsrfwhzfmdrfjyhwzpdjkzyjymfcyznynxfbytfwfwygdbnzzzdnytxz.mmqbsq.hxfzmbmflzzsrsymjgsxwzjsprydjsjgxhjjgljjynzjjxhgjkymlp.yycsysgqzswhwlyrjlpxslcxmfsmwkcctnxnynpnjszhdz.ptxmwyw.yysywlxjqzqxzdcl...lmcpjpclwbxsqhfwrtffjtnqjhjqdxhwlbyccfjl.lkyyjldxhhycstdywncjtxywdrmdrqhwqcmfjdyzmhm.yxjwmyzqsxtlmrspwwch.jbxtgcypxyyrrclmp.mgkqjszyjrmyjsnxtplnb.ppypylxmyzkynldgyjzczhnlmzhh.nqmpgwqtzmxxmllhgdzxyhxkrxycjmffxyhjfsbssqlhxndyc.nnmtcjcyprrnytyqnyymbmsxndlylysljnlqyshqmllyzlzjjjkymzcsfbzxxmstbjgnxyzhlsnmcqscyznfzlxbrnnnylmnrtgzqys.tswryhyjzmzdhzgzdwybsscskxsyhytsxgcqgxzzbhyxjscrhmkkbsczjyjymkqhzjfnbhmqhysnjnzybknqmcjgqhwlsnzswxkhljhyybqcbfcdsxdldspfzfskjjzwzxsddxjs...gjscssmgclxxkywyllymwwwgydkzjgggtggsycknjwnjpcxbjjtqtjwdsspjxzxnzxwm.lptfsxtllxcljxjjljsxctnswxl.hhlyqrwhsycsqryby.ywj.jqfwqcqqcjqgx.ldbzzyjgkgxpltqyfxjltp.dkyqhpm.tlcpdhkxmtxybhbl.fxdl..gqdyms.whzmljtwyqxlyjzlj..yxbqqffnlyxrdsctgjgxyylkllxqkcctlhjlqmkkzgcyygllljdzgydhzwxpysjbzkdzgyzzhywyfqytyzszy.zklymhjjhtsmqwyzlkyywzcsrkqyqltdxwcdrjklwsqzwbdcqyncjsrszjlkcdcdtlzzz.cqqczddxyplxcbqjylzllljddzjgyjyjzyxnyyynxjxkxd.zwyrdljyyyrjlglldrxjcykywnqcclddnyyykyckczhjxcclgzqjgjwggcqqjysbzzxyjxjbxjfzbsbdsfnsfpzxhdwztdmpptblzzbzdmyypqjrsdzsqzsqxbdgcpzswdwcsqzgmdhzxmwwfybpdgphtmjthzsmmbgzmbzjcfzhfcbbzmqcfmbcmcjxlgpnjbbxgyhyyjgptzgzmqbqdcgybjxlwzkydpdymgcftpfxyztzxdzxtgkmtybbclbj.skytssqyymscxfj.glsllszbqjjj.klyldlycctsxmcwfgkkbqxlllljyxtyltyxytdpjhnhgnkbyqnfjyyzbyy.ss.ssgdyhfhwtcjbsdzjtfdmxhcnjzymqwsrxjdzjqpdqbbsdjggfbkjbxdgjhmgwjjjgdllthzhhyyyyyysxwtyyyccbdbpypzyccztjpzywcbdlfwzcwjdxxhyhlhwczxjtcclcdpxdjczczlyxjjsjbhfxwpywxzptdzzbdccjhjhmlxbqxxbylrddgjrrctttgqsczwmxfytmwzcwjwxjywcskybzqccttqnhxnkxxkhkfhtsw.ccjybcmpzzyjbnnzpbthhjdlscddytyfjpxyngfxbyqxcbhxcbsxtyzdmzysnxsxlhkmzxlthdhkghxjsshqyhhcjyxglhzxcsnh.kdtgqxqypkdh.qtykcnymyyypkqyytjxzlthhqtbyqhxbmyhsqckwwyllhcyylnn.qxqwmcfbdccmljggxdqktlxkgnqcdgzjwyjjlyhhqtttnwchhxcxwh.szjydjccdbqcdgdnyxzdhcqrxcbmztqcbxwgqwyybxhmbymykdy.cmqky.qyngyzslfykkqgyssqyshjgjcnxkzycxsbkyxhyylstycxqthysmgscpmmgcccccmtzt.smgqzjhkl.sqylswtmqsyqkdzljqqyplcycztcqqpbbqjzclpkhqcyyxxdtdddsjcxffllchqxmjlwcjcxtspycxndtjshjwxdqqjckxy.mylsjhml.lykxcyydm.mdqmlmcznnyybzkkyflmchcmlhxrcjjhsylnmtjggzgywjxsrxcwjgjqhqzdqjdzjjzkjkgdzqgjjyjylhzxxcdqhhh.stmhlfsbdjsyyshfyssczqlpbdrfrztzdkykgsctgkwdqzrkmsynbcrxqbjyf.xpzz.dzcjykbcjwhyjbqdzywnyszptdkzpfpb.ztklqyhbbzpnbptyzzybhnydcpjmmcycqmcjfzzdcmnlfpbplngqjtbtt.jzpzbbdnjkljqylnbzqhksjznggqsczkyxchpzsnbcgzkddzq.nzgjkdntlzldwjljzlywtxndjzjhxy.tncbgtzcsskmnjpjytsrwxcfjwjjtkhtzplbhsnjzsyjbwbzyzlstlsbjhdwwqpslmmfbjdw.jyzccjtbnnrzwqxcdslqgdsdpdzhjtqqpsqlyyjzlgyhszlctcbjtktyczjtqkbpjlgmjzdmcsgpynjzjjyyknhrpwszxmtncszzyxybyhyz.xywkcjtllckjjtjhgcxdxyqyczbywblwqcglzgjgqrqcczssbcrbcskydznljsqgxssjm.cnstztpbdlthzwhqwqtz.xnqczgw.skssbybstscsjccgbfsdqszlccglllzghzcthcnmjgyz.znmckcstjmmzckbjygqljyjppldxrgzyxccsnhshgdznlzhzjjcddcbcjflbfqbczzwpqdnhxljcthqwjgylnlszzpcjdscqqhjqkdxkpb.jy.msmjtzdxlcjyryynwjbngzzkmjxltbsllrtpylcsznxjhllhyllqqzqlxymrcwcxsljmczltzldwdjjllnzggqxppskygyggbfzpdkmwghcxmcgdxjmcjsdyc.bxjdlnbcddygskydjtxdjjyxms.q.zdzfslqxyjsjzylblxxwxqqzbjzlfbblylwdsljhxjyzjwtdjcyfqzqzzdcsxzzqlzcdzfchyspympqzmlpplffxjjnzzylsjyyqzfpfzksywjjjhrdjzzxtxxglghtdxcskyswmmtcwyb.zbjkshfhgcxmhfqhyxxyzftsjyzbxyxpzlchmzmbxhzzssyfdmncwd.b.zlxktcshhxkxjjzjsthygxsxyyhhhjwxkzxcsbzzwwhhcwtzzzpjxsnxqqjgzyz.wllcwxzfxgyxyhxmkyyswsqmnjn.ycyspmjkgwcqhyl.jjmzxhmmcnzhbhxclxtjpltxyjhdyylttxfszhyxxsjbjy.yrsmxyplckdlyhlxrlnllstyzyyqygyhhsccsmcctzcxhyqfpyyrpfflfqtntszllzmhwtcjqyzwtllmlmdwmbzssmzrbpdddlgjjbxccsrzqqygwcsxfwzlxccrbtdzmcyggdlqsgtjmwljmymmsyhfbjdgyxccpshxczcsbsjwjgjmpbw.ffyfnxhydxzylr.mzgzcyhsszdlljcsqfzxxkptxzgxjjgbmyyysnbdylbnlhbfzdcyfbmgqrrmsszxysgtznnydzzcdgbj.fjbdknzblcsscpsgzycjszlmlrzzbzzldlsllysxsqzqlyxzlsgkbrxbrbzcycxzjz..yfgklzlyyhgysgzlfjhgtgwkr..jyzkzqtsshjjxdzyz.yjlzyrzdqqhgjzxsszbtkjpbfrtjxllfqwjgslqtymblpzdxtz.gbdhzzrbgjhwnjtjxlhscfsmwlldqysjtxkzscfwjlbxftzlljzllqblcqmqqcgcdfpbbhzczjlpyygjdtgwdcfczqyyyqysrclqzfklzzzgffsqnwglhjycjjczlqzcyjbjzzbpdccmhjgxdqdgdlzqmfgpsytsdyfwwdjzjysxyycjcyhzwpbyhxrylybhkjksfxtzjmmchhlltnyymsxxyzpyjjycdyzwmtjjkqyrhllqxpsgtlwycljscbxjyzfnmlrgjjtyzbsyzmsjyjhgfzqmsyxrszcwtlrtqzsstkxgqggsptgcdnjsgcqcqhmxggztqydjkzdlbzsxjlhyqgggthqscpyhjhhgnygkggcmjdzllcclxqsftgzslllmlcskctbljzzszmmnytpzsxqhjcjyqxy.xzqzcpshkzzysxcdfgmwqrllqxrfztlysdctmjcsjjdhjnxtnrztzfqrhqgllgcxszzjdjlxcytsjtlnyxhszxcgjzyqpylfhdjsbpcczgjjjqzjqdybssllcmyttmqtbhjqnnygkynqyqmzgcjkpdcgmyzhqllsllclmh.lzgdylfzsljcqzlylzcj.shnyllqxgjxlyjyyyxnbcljsswcqqcjyllcldjyllzllbnylgqchxyyq.xccqkyjxxhyklksx.yqccqkkkkcsgyxxyqxygwtj.hthxpxxcsshcy.ychzzcbwqbbwjqcscszsslzylgd.sjzmmymcytsdsxxscjpqqsqylyfzychdjdzywcbtjsydjhcyddjlbdjjs.dzyqysqkxxdhhgqjy.hdyxwgmmm.jdybbbppbcmhcpljzsmtx.rxjmhqdstpjdcbssmsssthjtslmmtrcplzszmlqdsdmjmqpnqdxcfynnfsdqqyxhy.ykqyddlqyyysszbydslntfgtzqbzmchdhczcwfdxtmqqsphqwwxsrgjcwtjtzzqmgwjjrjhtqjbbgwzfxjhnqfxxqywyyhyscdydhhqmnmdmmcpbszppzzglmzf.llcfwhmmsjzttthlmyffytzzgzyskjjxqyjzqphmbzzlyghgfmshpcfzsnclpbqsnjszslxjfpmtyjygbxlldlxpzjypjyhhzcywhjylsj.xfsszywxkzjll.dtmlymqjpwxxhxsktqj.zrpxxzghmhwqpwqlyjjqjjzszcfhjlchhnxjlqwzjhbmzyxbdhhypylhlhlgfwlcfyytlhjjcjmscpxstkpnhjxsntyxxt.stjctlsslstdlllwwyhdhrjzsfgxssyczykwhtdhwjslhtzdqdjzxxqggyltzphcsqfzlnjtclzpfstpdynylgmjllycqhynsbchylhqyqtmzybbywrfqykjsyslzdyjmpxyyssrhzjnyqtqdfzbwwdwwrxcwhgyhxmkmyyyhmsmzhngc.pmlqqmtcwctmhmxjpjjhfxyyzsjzhtybmstsyjdtjjqytlhynbyqzlcxcnzwsmylkfjxlwgbypjytysylymzckttwlgsmzsylmpwlzwxwqzss.qsyxyrhssntsr.pccpwcmgdhhxzdzxfjhgzttsbjhgyglzysmyclllybtyxhbbzjkssdm.lhhycfygmqypjycqxjllljgclzgqlycjcct.tyxmtmshllwcgfxymzmklpszzzxhhjyslctyjcyhxsgyxzkxlzwpyjpdhjwpjpwsqqxlxxdhmrslzcyzwstcxkystzshbsccstplwsscjchjlcgchssphylhfhhxjsx.llnylmzdhzxylsxlwzyhcldy.hzcmddyspjtqjzlngjfsjshctsdszlblmssmnyymjqbjhrcwtyydchqlj.pzwbgqybkfcmjwlzllyylszydwhxpsbcmljpscgbhxlqhyrljxyswxhxzlldfhlslymjljyflyjycdrjlfsyzfsllcqyqfgjyhyszlylmstdjcyhbzllnwlxxygyyhbmgdhxxhhlzzjzxczzzcyqzfnjwpylcpkpykpmclqkdgxzggwqbdxzzkzfbxxlzxjtpjpttbytszzdwslchzhsltjxhqlhyxxxywzyswtmzkhlxzxzpyhgchkjfsyh.tjrlxfjxptztwhplyxfcrhxshxkjxxyhzjdxjwylhyhmjdbflkhtxcwhcfwjcfpqrxqxcyyyjygrpxgscsxngqchkzdxhflxxhjjbyzwtsxnncyjjymswzjqrmhxzwfqsylzjzgbhynshbgttcs.bhxxwxyhhxyxnsqyxmlywrgyqlxbbcljsylpsytjzyhyz.wlh.rjmksczjxxxyxchcytryxqjddsjfslyltsffyxlmtyjmzjyyyxltzcsxqzlhzxlwyxzhdnlrxhxjcdyhlbrlmbrll.xksllljlyxxlycrylcjcgqcmtlzllcyzzpzpcy.whjjfybdyyzs.pckzdqyqpbpcjpdcyzbdbbcyydycnnpjmtmlrmfmmgwygbsjgygsmdqqqztxmkqwgxllpjgzbqcdjjjfpkjkcxbljmswmdtqjxldlppbxcwkcqqbfqjcz.gzgmykbhyyhzykndkzmbpjyspxthlfpnyygxjdbkxnhhjhzjxstrstldxskzysybmxjlxyslbzyslhxjpfxbqnbylljqkygzmcyzzymccsldlhzgwfwyxzmwcxtynxjhbyymcysbmhysmydyshqyzchmjjmzc..hcbjbbhplxtylsxsdjgjdhkxxtxxnbhnmlngsltxmrhnlxqjxmzllyswqgdlbjhdcgjyqycmhwfwjybbbyjmjwjmdpwhxqldy.pdfxxbcgjspckrssyzjmslbzzjfljjjlgxzgyxyxlszqyxb.xyxhgcxbpldyhw.cdwwcjmbtxchxyqxllxflyxlljlssfwdpzsmyjclmswtczbchq.kcqbwlcgydblqppqzqfjqdjhymmcxtxdrmjwrhxcjzclqxdyynhyyhrslsrsywwzjymtltllgzqcjzy.bsckzcjyccqljsqx.lmzyyywlwdxzxqdllqshgpjfjljhj.bcqzdjgthhsstcyjlbswzlxzxrwgldlzrlzqtgsllllzlymxqgdzhgbdbhzpbrlw.xqbpfdw...thlypcbjcc.dmbzpbzz.cyqxld.mzblzwpdwyygdstthcsqsccrsssyslfybfntyjszdfndpthtzzmbblxlcmyffgtjjqwftmdpjwdnlbzcmmctgbdzlqlpyfhsymjylsdchdzjwjcctljcldtljjcpddpjdsszynndbjlggjzxsxnlycybjjqxcbylzcfzppgkcxzdzfztjjfjsjxzbnzyjqttyjwhtyczhymdjxttmpxsflzcdwslshxybzgtfmlcjt.cbbmgd.wycyzcdszcyhflyctygwhkjyylsjcxgywjcbhlcsnddbtzbsclyzczzssqdllmqyyhfllqllxfdyh.bxggnywyypllsdldllbjcyxjzmlhljdxyyqytdlllbbgbfdfbbqjzzmdpjhgclgmjjpg..hhbwcqx.xhhhzchxyphj.xhlphjpgpzjqcqzgjjzzgzdmqyybzzphyhybwh.zyjhykfgdpfqsdlzmljxjpg.lxzd.glmdgxmwzqytxdxxpfdmmssympfmdmmkxksyzyshdzkjsysmmzzzmsydnzzczxbmlstmddnmxckjmztyymzmzzmsshhdccj.mxxkljstgwlsqlyjzllsjssdbpmhnlyjczyhmxxhgzcjmdhxtkgrmxfwmckmwkdcksxqmmmfzzydkmsclcmpcgmwrpxqpzdsslcxkyxtmlgjy.hzjgzqmcsnxyhmmpmlkjxmhlmlgmxctkzmjjyszjsyszhsyjzjcd.jzybsdqjzgwzkgxfkdmsdjlfm.hkzqkjb.ypzyszcdwyjffmzjykttdzz.fmzlbnpplplpbpsz.lltylkckqzkg.nqlw.gxxydpxlhsxqhwqykxqclhyxxmlyccwlymqyskychlcjnszkpyzkcqzqljbdmdjhl.sqlbydwqlwdnbqcrydddtjybkbwszdxdtnpjdtctqdfxqqmgns.clstbhpwslctxxlpwydzklzygzcq.pllkccylbqmqczqcljslqzdjxldthpzqdljjxzqdjyzhkzljcyqdyjppyp..kjyrmpcbymcxkllzllfqpylllmbsglcysslrsysqtmxyxqqzbdzrysyztffmzzsmzqhzssccmlyxwtpzgxzjgzgsjsgkddhtqggzllbjdzlcbzhyxyzhzfywxyzymsdbzzyjgtsmtfxqyxjscdgslnmdlrytzlryylxqhtxsrtzcgyxbnqqzfhykmzjbzymkbpnlyzpblmcnqyzzzsjzhjctzhhyzzjrdyzhnfxglfxslkgjtctssyllgzrzbbjzzklpkbczyslxyxbjfpnjzzxcdwxzyjxzzdjjgggrsrjkmcmzjlsjywqshyhqjsxpjzzzlsnshrnypjtwchklbsrzlcxwjqxqkysjycztlqzybbybwzjqdwgyzcytjcjxckcwdkkzxsgkdzxwwyyjqyytcytdjlxwkczkklcclzcqqdzlqlcsfqchqhsfsmqzzllbjjzbsjhtsjdysjqjpdlzcdcwjkjzzlpycgmzwdjjbsjqzsyzyhhxcbbjydssddzncglqmbtsfcbfdzdlznfgfjgfsmpsjqlmblgqcyyxbqkdxjqsrfkztjdhczklbsdzcfytplljgjhtxzcsszzxstcygkgckgy.qxjplzbbbgtgyjdgczqszlbjlsjfzgkqqjcgyczbzqtldxrjxbsxxpzxhyzyclwdsjjhxmfczpfzhqhqmqgkylyhtycgfrzgnqxclpdlbzcsczqlljblhbdcypczppdymtzsgyhckcpzjgslclnscdsldzxbmsdlddfjmkdjdhslzxlszqpqpgjllybdszgqlbzlslkyyhzttncjyqtzzfszqztlljtyyllqllqyzqlbdzlslyyzymdfszsnhlxznczqzbbwskrfbcyzmthblgjpmczzcstlxshtzcyzlzblf.qhlxflcjlyljqcbzlzjghsstbrmhxzhjzclxfnbgxgtqjcztmsfzkjmssnxljkbhszxntnlzdntlmsjxgzjyjczxyhyhwrwwqnztnfjscpzshzjfyrdjsfscjzhjfzqzchzlxfxsbzqlzsgyftzdcszxzjbqmszkjrhxjzcgbjkhchgtjkjqglxbxfgdrtylxjxgdtsjxhjzjjcmzlcqsbtxhqgxttxhxftsdkfjhzyjfjxrzcdlllcqsqqzqwqxswqtwgwbzcgcllqzbclmqqtzgzxzxljfrmyzflxyszxxjkxrmjdcdmmyxbsqbhgcmwfwtgmxlzbyytgzyccdxyzxswgxyjyznbgpzjcqsyxcxrtfycgrhztxszzthcbfclsyxzljqmzlmplmxzjssflbysmyqhxjzxrxsqzzzsslyflczjrcrxhhzxqwdshxsjjhzcxjbdynsysxjbqlpxzqpymlxzkyxlxcjlcycrxzzlldlllsjyhzxgyjwkjrwyhcpsgnrzlfzwfzznsxgxflzsxzzzbfcsyjdbrjkrdhhgxjljjtgxjxxstjtjxlyxqfcsgswmsbctlqzzwlzzkxjmltmjyhsddbxgzhdlbmyjfrzfcgclyjbpmlysmsxlszjqqhjzfxgfqfqbpxzgyyqxgztcqwyltlgwwgwhllfsfgzjmgmgbgtjfsyzzgzyz.flsspmlbflcwbjzcljjmzlpjjlymqdmyyyfbgygqzglyzdxqyxrqqqhsxyyqqygjtyxfsfsllgnqcygycwfhcccfxbylypllzqxxxxxkqhhxshjdcfdsczjxcpzwhhhhh.pylh.lpq.fyhxdyllkmzqgggdd.srnndltzgchybpysqjjhclljt.lnjpzljlhymh.ydydsqycddhgzpndzclzywllznt.ytgxlhslpjjbdgwxpcdntjcklkclwkllc.sstknzdnqnttlyyzssysszzryljqkcgbhhcrxrzydgrgcwcgzhfffppjfzyn.krgywyqpqxxfkjtszzxswzddfbbqtbgtzfznpzfpzxzpjszbmqhkcyxyldkljnypkyghgdcjxx..hpnzgctzcmxcxmmjxnkszqnmnlwbwwxjjyhclstmcsqtjcxxtpcnpdtnnpglllzcjlspblplkcdtnjnlyyrscffjfqwdpgzdwmnzccl.d.xnssnyzr.styjwjyjdbcfxnmwttbqlwstszgybljpxglb.clgpcbjftmxzljylzxcltpnclcgxtfzjshcrxsfyszdkntlbyjcyjllstgqcbxnwzxbxklylhzlqzlnzcqwgzlgzjncjgcmnzzgjdzxtzjxycyycxxjyyxjjxsssjstssttppghtcsxwzdcsyfptfbchfbblzjclzzdbxgcxlqpxkfzflsyltywbmnjhskbmddbcysccldxycddqlyjjhmqllcsgljjsyfpyyccyltj.ntjjpwycmmgqyysqdhqmzhszxpftwwzqswqrfkjlxjqqyfbrxjhhfwjgzyq.cmyfrhcyybyqwlp.xcczstyrltsdmqlykmbbgmyyjprknnbbsxyxbhyzdjdnghpmfsgbwfzmfjmmbcmzzcjjlcnyxyqgmlrygqccyhzlwjgcjcggmcjjfyzzjhycfrrcmtzqzxhfqgdjxccj..qcrjthpljlszdjrbcqhjdzrhxlyxjsymhzydwldfryhbbydtssccwbxglpzmlzztqsscpjmmxjcsjytycghycjwsnsxlf.mwjnmkllswtxhyyygcmmcwjdqdjzglljwjnkhpzggflccsczmcbltbhbqjxqdjpdjqtghglfq.wbzyjjltstdhqhctcbchflqmpwdshyytqwcnztjtlbypbpdyyyxsqkxwyyflxxncwcxybm..lykkjmzzzbrxy.qjfljpfhhhytzzxrgqqmhspgdzjwbwpjhzjdyscqwzkthxsqlzyymysdzgrxckkhjlwpysyscsyzlrmlqsyljxbcxtlhdqzpcycykpppnsxfyzjjrc.mhszmsxlxglrwgcstlrsxbygbzgztcpldjlslylymdtmtcp.lcxpqjcjwtcyyzlblxbzlqmyljbghdslssdmxmbdczsxwh.mlczcpjmcnhjyjnsygchskqmzzqdllk.blwjqsfm.cdxjrrlyqchjmybyqlrh.tfjzfrfksryxfjdwdsxxlwsqjyslyxwjhsnlxyyxhbh.whhjcxwmyljcsqlkydttxbzsxfdxgxsjhhsxxybssxdpwncmrptjzcz.nygcxqfjxkjbdmljcmqqxl.xslyxxlylljdzbtymhbfsttqqwlh.gyblsc.lzxqlhtwrrqhlstmypyxjjxmqsjpnbryxyjllyqylthylqyfmhkljdmllhfzwkzhljmlhljkljstlqxylmbhhlnlsxqchxcfxxlhyhjjgbyzzkbxscqdjqdsxjzsyhzhhmgsxcsymxf.bcqwwrbpyyjqtyqcyjhqqzyhmwffhgzfrjfcdbxndqyzpcyhhjlfrzgppxzdbbgzqstlgdgylcqmgchhmfywlzyxkjlypqhsywmqqgqzmlzjnsqxjqsyjtcb.hsxfssfxzwfllbcyyjdytdthwzsfjmqqyjlmqsxlldttkhhybfpwdyysqqrnqwlgwd.bdwcyygcdlkjxtmxmyjsxhybrwfymwfrxyqmxysctzztfykmldhqdlwyqnlcryjtlpsxcxywlsbrrjwxhqybhtydnhhgmmywytzcsqmdssccd.lwztcpqpyjllqzyjswxwzzmmglmxclmxczmxmzsqtzppjqblpgxjzhfljjhycjsnxwcxsccdlxsyjdcqcxslqyclzxlzzxmxqrjmhrhzjphmfljlmlclqnldxzlllfypngjysxcqqdcmqjzzxhnpnxzm.kmxxykyqlxsxtxjxyhwdcwdzhqyybgybcyscfgfsjnzdyzzjzxrzrqjjymc.nhrjtldbpyzbstjhxxzypbdwfgzzrpymtngxzqbyxmbbfcckrjjjbj.grzgyclkhzdxkknsjkcljspgyyzlqqjybzssqlllkjfcbktylcccdblsppfylgydtzjyqggkqttfcxbdkdxxhybbfytyhbclpdytgdhryrnjsbtcsnyjqhklllzslydxxwbcjqsbxbfjzjcjdzfbxxbrml.zgcsnclbjdstblfrzdswsbxbcllxxlzdjzsjpylyxxyftfffbhjjjgbygjpmmmmsscljmtlyzjxswxtyl.dqpjmygqzjgdjlqjwjqllsdgjgygmscljjxdtygjqjqjcjzcjgdzdshqgsjggcjhqxsnjlzzbxhsgzxcxyljxyxyydfqqjhjfxdhctxjyrxysqtjxy.fyyssyxjxncyzxfxcsyszxyyschshxzzzgzzzgfjdldylnpzgyjyzyyqzpbxqbdztzczyxxyhhscxshcggqhjhgxwsztmzm.hyxg.btylzkkwytjzrcl.k.stdbcykqqs.yxcjxwwgsbhjszsdhcsjkqcxswxfctynydpzcczjqtzwjqdzzzqzljchlsbhpydxpsxshh.zdxfptjqyzzxhy.xncfzyyhxgnqmywxtzsjpkhhgymxmxqcxtsbcqsjyxhtyylybcqlmmszmjzjllc.gxz..jzyhjmchhcxzsxzdznl.yjjzjbhzwzzsqtzpsxztdsxjjjzny.zphhyysrnqdthzh.yjyjhdzxzlswclybzy.cwcycrylcxnhzydzydyjdfrjjhtrsqtxyxjrjh.jynx.lxsfsfjzghpzsxzszdzcqzbyyklsgsjhczshdgqgxyzgxchxzjwyqwgyhkss.qzzndzfkwyssdclzstsymcdhjxxyw.yxcz.ydmpxmdsxybsqmjmzjmtzqlpjyqzcgqhxjhhhxxhlhdldjqsldwbsxfzzyyschtytyjbh.cxhjkgjfxbhyzjfxbwhbdzfyzbc.pnpgnydmsxhkhhm.mlnbyjtmpxyjmcthjbzyfcgtyhwphftgzz.zsbz.gpbmdskftycmhbllhgpzjxzjgzjyxzsbbqsczzlzccstpgxmjsftcczjzdjxcybzlfcjsyzfgszlybcwzzbyzdzypswyjgxzbdsysxlgzbzfygczxbzhzftpbgzg.jbstgkdmfhyzzjhzllzzgjqzlsfdjsscbzgpdlfzfzszyzyzsygcxsntxchczxtzzljfzgqsqyxzjqccccdjcdxzjyqjccgxztdlgscxzsyjjqtcclqdqztqchqqjzt.zzzpbkkdjfcjfztybqyqttynlmbdktjcpqzjdzfpjsbnjlgyjdxjdzqkzgqkxclpzjtcjdqbxdjjjstcjnxbxcmslyjcqmtjqwwcjjnjnlllhjcwqtbzqyczczpzzdzyddcyzdzccjgtjfzdprntctjdcqtqndtjnplzbcllctdsxkjzqdpzlbznbtjdcxfczdbccjjltqjpldcgzdbbzjcqdcjwynllzlzccdwllxwzlxrsntqjccxkjlsgdfqtddglrl.jjtklymkqlldzytdyycygjwyxdxfrskstcd.nqmrkqzhhqkdld.zfkypbggpzr.bzzykyzsp.gjjglkqzzzslysywyzwfqznlzzlzhwcgkypqgnpgblplrrjyxcccgyhsfzfwbzywtgzxyljczwhxzjzblfflgskhyjz.yjhlpllllcygxdrz.lrhgklzzyhzlyqszzjzqljzflnbhgwlczcfjwspyxnlzlxgccpzbllcxbbbbxbbcbbcrnncccyrbbsyldcgqyyqxygmqzwtzydyjhyfwd.hzdjywlccntzyjjcd.dpzdztstqjhdymbjnyjzlxtsstphndjxxbyxqtzqddtjtdyztgwscszqflshlglbcjbhdlyzjyckwtydylbnydsdsycctyszyy.bg.xhqddwnygyclxtdcystqmygz.sccszzddlcclzrqxyy.ljsbymxshzt.mbbllyyllytdqyshymrqxkfkbfxnxsbychxbwjyhtqbpbsbwdzylkgzskyghqzjhhxjxgnljkzlyycdxlfwfghljgjybxblybxqpqgztzplncybxdjyqydymrb.sjyyhkxxstmxrczzywxyhybmcflyzhqyzmqxdbxbzwzmslpdmyckfmzklzcyjycclhxfzlydqzpzygyjyzmzxdzfyfyttqtchgspczmlccytzxjcytjmkslpzhysnwllytpzctzzcktxdhxxtqcypksmqccyy.zhtjpcylzlyjbjxtfnyljyynrxcylmmnxjsmybcsysslzylljjgyldzdpqbfzzblfndsqkczfhhhgqmrdsxycstxnqqjpyjbfcxdyqfbnx.jdgyqbsrcnfyyqpghyjdyzxgrhtkyl.qdzntsmgklbsgbpyszbytjzsstjcssxzbhbscsbzczptqfzmqflypybbjgszmxxdjmthyskkbjtxhjc.gbsmjyjzcxtmljyxrzzqscxxqptzxmkyxxxjcljprmyyg.dyskqls.dhrskqxzxztcghztlmlwxybwsycdbhjhcfcwzsxhytkzlxqshlyczjx.mplprcgltbzztlzjcyjgdtclglpllqpjmzp.pxyzl.ktkdnczzbnzctdqqzjyjgmctxltgcszlmlhbglkfbnwzhdxphlfmkydlgxdtwzfrj.jctzhydxykshwfzcqshktmqqhtchymjdjskhxzjzbzzxymp.jjmsdbxlsklyynwrtsqlscbpdbsgzwyhtlkssswhzzlyytnxjgmjszsxfwnls.ztxgxls.mmlbwldszyl.kqcqctmycfjbslxclzjclxxksbjqclhjphqplsxsckslnhpsfqqytxjjzlqldxzjjzdyydjnzptfcdskjfsljhylzqjzlbthydgdjfdby.zxdzhzjnhhqbyknxjjqczmlljzkspldsclbblxkl.lxjlbjycxjxgcnlcqplzlznjtzljgyzdzpltqcssfdmnycxgbtjdcznbgbqyqjwgkfhtnbyqzqgbkpbbyzmtjdytblsqmbsxtbnpdxkl.myycjynzdtldykzzxddxhqshdgmzsjycct.yrzlpwltlkxslzcgg.xclfxlkjrtlqj.qzncmbqdkkcxglczjzxjhptdjjmzqykqs.cqzdshh.dmlzfmmzbgntjnnlgbyjbrbtmlbyjdzxlcjlpldlpcqdhlhzlycblcxzcj.dqlmzmmsshmybhbskkbhrsxxjmxsdznzpxlbbr.gggfchgmsklltsjyycqlcskywy.hywhbhqywb.wykqldqftntkhqcgdqktgpkxhcpdhtwtmssyhbwcrwxhjmkmzngwtmlkfghkjyldyycxwhy.clqhkqhtdqhhffldxqwgzyyd.sbpkyrzpjfyyzjc.qdzzdl.ttbbfjllcxdlmjsdx.gygsjqxcfbxsszpdyzcxdnyxpfzydlyjccpltxlsxyzyrxcyysdylwwnds.hjsygyhgywk.xtjzd.xysrltdjss.xfn.jdxyzhlxlllzhzsjnyqyqqxyjghzgjcyjchzlycdshwsgczyjxcllnxzjjyyxnfsmwfpylcyll.bwddhwdxjmcxztzpmlqzhsfhzynztlldywlslxhymmylmbwwkyxy.dtxylldjpybpwfxjmmmllh.fdll.flbhhhbqqjtzjcqjjdjtffkmmmbythygdcqrddwrqjxnbysnmzdbyytbjhpybygtjx..hgqdqtmystqxkbtsbkjlxrb.qqhqmjjbdjwtgtbxpgbktlgqxjjjcdhxqdwjlwrfmqgwqhckryswgbtgygbwsdwdwrfhwytjjxxxjyzyslphyyp.yxhydqkxshxyx.skqhywbdddpplcjlhq..wxksyyhdyplfjthkjltcyyhhjttpltzzcdlthqkcxqyst..ywkyzyxxyysddjkllpwmcyhqgxyhcrmbxpllnqydqhxsxxwgdqbshyllpjjjthyjkyphthyykty.zy.nmdshlcrpqfbgfxzbsbtlgxsjbswyysksflxlpplbbblbsfxfyzbsjssylpbbffffsscjdstzsxtryjcyffsytyzbjtbctsbsdhrtjjbytcxyj.ygxcbn.bjdsysyhgsjzbxbytfzwg.nyhhthjh.tfwgcstbgxklstywmtmbyxjskzscdyjrcytwxzfhmymcxlznsdjtttxrycfyjsbsdy.rxhljxbbd.ynjghxgckgscymblxjmsznskgxfbnbbthfj..fxyxfpxmyfhdtzcxzzpxrsywzdlybbjtyqwqjpzypzjznjpzjlztfysbttslmptzrtdxqsj.hbzylzdhljsqmlhtxtj.cx.lzzspktlzkqqyfsygywpcpqfhqhytqxzkrsgtgsqczlptxcdyyzssqzslxlzm.cbcqbzyxhbsxlzdltcdjtylzjyytpzylltxjsjxhlbmytxcqrblzssfjzztnjydxmyjhlhpblcyxqjqqkzzscpzksw.lqsblcczjsxgwwwygy.tjbbctdkhqhkgtgpbkqyslbxbbckbmllxdzstbklggqkqlsbkkdfxrmdkbftpzfrtbbmf.rqgxkjpzsstlbzdpszqzsjthljqlzbpmsmmsxlqqnhknblrddnhxdhddjcyygyfqgzlgsygmjqgkhbpmxyxlytqwlwgcpbmjxcyzydrjbhtdjx..shtmjsbyplwhlzffnypmhxqhpltbqpfbcwjdbygpnxtbfzjgsddtjshx..wzzyllttybwjkgxghlfkxdjtmszsqynzggswqsphtlsskmclzxyszqzxncjdqgzdlfnykljcjllzlmzznhydsshthxzlzzbbhqzwwycrdhlyqqjb.yfsgxthsrxwqhwfslmssgztty.yqqwrsl.lhmjtqjsmxqbjjzjxzyzkxbyqxbjxshzssfglxmxzxfghkzszggylcls.rjxhslllmzx.lglxydjytlfbhbpnlyzfbbhptgjkw.tzhkjjxzxxglljlstgshjjyqlqzfkcgnndjsszfdbctwws.qfhqjbs.qtgypjlbxbmmywxgslzhglzgnyfljbyfdjfrgsfmbyzhqfbwjsyfyjjphzbyyzffw.dgrlmftmlbzgycqxcdjygzyyyytytydw.g.zyhxjlzythlrmgrjxzclhn.ljjthtbwjybjjbxjjtjt..khwslzplpsf.zpqqbdlqjjtyyqlyzkdksqjyyjzldqcgjjyzjsycmr.qtht.jmfctyhypkmhycwjdcfhyyxwshctxrljgjshccyyyjltkttytmxgtcjtz.yy.czlylbszywjytsjyhbyshfjlygjxxtmzyyltxxypclxyjzyzyypnhmymdyylblhlsyygqllnjjyms.ycbzgdlyxylcqyxtsz.gxhzglhwbljg.yxtwqm.kbpqcgyshh.gqcmwyywljyjhyyzlljjylhzyhmgsljljxcjjyclycjpcpzjzjmmylcjlnqljjjlxxjmlszljqlycmmhcfmmfpqqmfxlqmcffqmmmmhmznfhhjgtthhkhslnchhyqdxtmmqdcydyxyqmyqylddcyyyd.zdcymzydlzfffmmycqcwzzm.btbyctdmndzggdftypcgqyttssffwbdtzqssystwjjhjytsxxylbyqhwwhx.zxwznnqzjzjjqjccchyyxbzxccyjtllcqxknjycyycynzzqyy..wyczdcjycchyjlbtzkycqwlpgpyllgkdldlgkgqbgychjxy....z.w...z....s.....l.......sl..z....lgtm....gd......................tn..hbltdzl.tmmbj.lx';
197
+
198
+ function initialOf(code) {
199
+ if (code < PINYIN_LO || code > PINYIN_HI) return '';
200
+ var letter = PINYIN.charAt(code - PINYIN_LO);
201
+ return letter === '.' ? '' : letter;
202
+ }
203
+
204
+ /** Latin text is kept; CJK turns into the pinyin initial; everything else is dropped. */
205
+ function initials(text) {
206
+ var out = '';
207
+ var source = String(text || '');
208
+ for (var i = 0; i < source.length; i += 1) {
209
+ var code = source.charCodeAt(i);
210
+ if (code >= 48 && code <= 57) out += source.charAt(i);
211
+ else if (code >= 97 && code <= 122) out += source.charAt(i);
212
+ else if (code >= 65 && code <= 90) out += source.charAt(i).toLowerCase();
213
+ else out += initialOf(code);
214
+ }
215
+ return out;
216
+ }
217
+
218
+ // ---------------------------------------------------------------------
219
+ // shared open/closed store: the overlay and the footer button both drive it
220
+ // ---------------------------------------------------------------------
221
+ var store = {
222
+ open: false,
223
+ listeners: new Set(),
224
+ set(next) {
225
+ if (store.open === next) return;
226
+ store.open = next;
227
+ store.listeners.forEach((fn) => {
228
+ try {
229
+ fn(next);
230
+ } catch {
231
+ /* a broken listener must not break the palette */
232
+ }
233
+ });
234
+ },
235
+ toggle() {
236
+ store.set(!store.open);
237
+ },
238
+ };
239
+
240
+ var extCommands = [];
241
+ var extListeners = new Set();
242
+
243
+ function emitExt() {
244
+ extListeners.forEach((fn) => {
245
+ try {
246
+ fn();
247
+ } catch {
248
+ /* ignore */
249
+ }
250
+ });
251
+ }
252
+
253
+ /** A plugin can contribute a row: { id, title, sub?, group?, run(ctx) }. */
254
+ function registerCommand(command) {
255
+ if (!command || typeof command.id !== 'string' || !command.id) return false;
256
+ if (typeof command.title !== 'string' || !command.title) return false;
257
+ if (typeof command.run !== 'function') return false;
258
+ extCommands = extCommands.filter((entry) => entry.id !== command.id);
259
+ extCommands.push(command);
260
+ emitExt();
261
+ return true;
262
+ }
263
+
264
+ function unregisterCommand(id) {
265
+ var before = extCommands.length;
266
+ extCommands = extCommands.filter((entry) => entry.id !== id);
267
+ if (extCommands.length !== before) emitExt();
268
+ }
269
+
270
+ function useExtCommands() {
271
+ var [, bump] = useState(0);
272
+ useEffect(() => {
273
+ var listener = () => bump((value) => value + 1);
274
+ extListeners.add(listener);
275
+ return () => extListeners.delete(listener);
276
+ }, []);
277
+ return extCommands;
278
+ }
279
+
280
+ function useOpen() {
281
+ var [open, setOpen] = useState(store.open);
282
+ useEffect(() => {
283
+ var listener = (value) => setOpen(value);
284
+ store.listeners.add(listener);
285
+ setOpen(store.open);
286
+ return () => store.listeners.delete(listener);
287
+ }, []);
288
+ return open;
289
+ }
290
+
291
+ function activeLocale(ctx) {
292
+ try {
293
+ var snapshot = ctx.locale.getLocale();
294
+ return (snapshot && snapshot.active) || 'zh';
295
+ } catch {
296
+ return 'zh';
297
+ }
298
+ }
299
+
300
+ function useLang(ctx) {
301
+ var [locale, setLocale] = useState(() => activeLocale(ctx));
302
+ useEffect(() => {
303
+ if (!ctx.locale || typeof ctx.locale.subscribe !== 'function') return undefined;
304
+ return ctx.locale.subscribe(() => setLocale(activeLocale(ctx)));
305
+ }, []);
306
+ return /^zh/i.test(String(locale)) ? 'zh' : 'en';
307
+ }
308
+
309
+ function copy(lang) {
310
+ return STRINGS[lang] || STRINGS.zh;
311
+ }
312
+
313
+ function request(path, body) {
314
+ var init = body === undefined ? { headers: { Accept: 'application/json' } } : {
315
+ method: 'POST',
316
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
317
+ body: JSON.stringify(body),
318
+ };
319
+ return fetch(path, init).then((response) =>
320
+ response.json().then(
321
+ (payload) => {
322
+ if (!response.ok || !payload || payload.ok !== true) {
323
+ var message = payload && payload.error ? payload.error : 'HTTP ' + response.status;
324
+ throw new Error(message);
325
+ }
326
+ return payload;
327
+ },
328
+ () => {
329
+ throw new Error('HTTP ' + response.status);
330
+ },
331
+ ),
332
+ );
333
+ }
334
+
335
+ function getJson(path) {
336
+ return request(path);
337
+ }
338
+
339
+ // ---------------------------------------------------------------------
340
+ // ranking
341
+ // ---------------------------------------------------------------------
342
+ function fuzzy(query, text) {
343
+ var needle = String(query || '').toLowerCase();
344
+ var hay = String(text || '').toLowerCase();
345
+ if (!needle) return 0.12;
346
+ if (!hay) return 0;
347
+ var direct = hay.indexOf(needle);
348
+ if (direct === 0) return 1;
349
+ if (direct > 0) return 0.86 - Math.min(direct, 40) * 0.004;
350
+ // pinyin initials: "cj" should reach 插件
351
+ var py = initials(hay);
352
+ if (py) {
353
+ var at = py.indexOf(needle);
354
+ if (at === 0) return 0.78;
355
+ if (at > 0) return 0.62 - Math.min(at, 30) * 0.004;
356
+ }
357
+ // subsequence, in order, on the raw text
358
+ var cursor = 0;
359
+ var hits = 0;
360
+ for (var i = 0; i < hay.length && cursor < needle.length; i += 1) {
361
+ if (hay.charAt(i) === needle.charAt(cursor)) {
362
+ cursor += 1;
363
+ hits += 1;
364
+ }
365
+ }
366
+ if (cursor === needle.length) return 0.4 + Math.min(hits, 12) * 0.01 - Math.min(hay.length, 200) * 0.0004;
367
+ return 0;
368
+ }
369
+
370
+ function scoreOf(query, item) {
371
+ var best = fuzzy(query, item.title);
372
+ if (item.sub) best = Math.max(best, fuzzy(query, item.sub) * 0.72);
373
+ if (item.keys) {
374
+ for (var i = 0; i < item.keys.length; i += 1) {
375
+ best = Math.max(best, fuzzy(query, item.keys[i]) * 0.9);
376
+ }
377
+ }
378
+ return best;
379
+ }
380
+
381
+ // ---------------------------------------------------------------------
382
+ // recency memory: a small weight on things the user already reached for
383
+ // ---------------------------------------------------------------------
384
+ function readRecent() {
385
+ try {
386
+ var raw = window.localStorage.getItem(RECENT_KEY);
387
+ var parsed = raw ? JSON.parse(raw) : null;
388
+ return parsed && typeof parsed === 'object' ? parsed : {};
389
+ } catch {
390
+ return {};
391
+ }
392
+ }
393
+
394
+ function bumpRecent(key) {
395
+ if (!key) return;
396
+ try {
397
+ var map = readRecent();
398
+ var entry = map[key] || { count: 0, at: 0 };
399
+ entry.count = Math.min((entry.count || 0) + 1, 40);
400
+ entry.at = Date.now();
401
+ map[key] = entry;
402
+ var keys = Object.keys(map);
403
+ if (keys.length > 60) {
404
+ keys
405
+ .sort((a, b) => (map[a].at || 0) - (map[b].at || 0))
406
+ .slice(0, keys.length - 60)
407
+ .forEach((old) => {
408
+ delete map[old];
409
+ });
410
+ }
411
+ window.localStorage.setItem(RECENT_KEY, JSON.stringify(map));
412
+ return map;
413
+ } catch {
414
+ return {};
415
+ }
416
+ }
417
+
418
+ // ---------------------------------------------------------------------
419
+ // item helpers
420
+ // ---------------------------------------------------------------------
421
+ function item(key, group, title, sub, run, actions) {
422
+ return { key: key, group: group, title: title, sub: sub || '', run: run, actions: actions || null };
423
+ }
424
+
425
+ function copyText(text) {
426
+ if (!text) return Promise.reject(new Error('empty'));
427
+ if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(text);
428
+ return Promise.reject(new Error('clipboard unavailable'));
429
+ }
430
+
431
+ function revealPath(path) {
432
+ return request(API + '/open-profile', { path: path }).then(() => null);
433
+ }
434
+
435
+ function shortPath(value) {
436
+ var text = typeof value === 'string' ? value.trim() : '';
437
+ if (!text) return '';
438
+ var home = /^\/Users\/[^/]+/;
439
+ if (home.test(text)) text = text.replace(home, '~');
440
+ var parts = text.split('/');
441
+ if (text.length > 38 && parts.length > 3) text = '…/' + parts.slice(-2).join('/');
442
+ return text;
443
+ }
444
+
445
+ function sessionItem(ctx, lang, entry) {
446
+ var t = copy(lang);
447
+ var id = entry.sessionId;
448
+ var title = entry.title || t.untitled;
449
+ var run = () => {
450
+ ctx.uiWorkspace.openSession(id);
451
+ return undefined;
452
+ };
453
+ var actions = () => sessionActions(ctx, lang, entry);
454
+ return item('session:' + id, 'session', title, entry.snippet || shortPath(entry.cwd), run, actions);
455
+ }
456
+
457
+ function renameOf(ctx, id, title) {
458
+ var ref = ctx.sessions.retain(id, { source: 'controllerOperation' });
459
+ var finish = () => {
460
+ try {
461
+ ref.release();
462
+ } catch {
463
+ /* already released */
464
+ }
465
+ };
466
+ return Promise.resolve(ref.ready).then(
467
+ (binding) =>
468
+ Promise.resolve(binding.session.rename(title)).then(
469
+ (result) => {
470
+ finish();
471
+ if (!result || result.ok === false) throw new Error('rename rejected');
472
+ try {
473
+ ctx.sessions.refreshProjections(id);
474
+ } catch {
475
+ /* projection refresh is best-effort */
476
+ }
477
+ return result.value;
478
+ },
479
+ (error) => {
480
+ finish();
481
+ throw error;
482
+ },
483
+ ),
484
+ (error) => {
485
+ finish();
486
+ throw error;
487
+ },
488
+ );
489
+ }
490
+
491
+ function sessionActions(ctx, lang, entry) {
492
+ var t = copy(lang);
493
+ var id = entry.sessionId;
494
+ var cwd = entry.cwd || '';
495
+ return [
496
+ item('action:open', 'action', t.sessionOpen, t.sessionOpenHint, () => {
497
+ ctx.uiWorkspace.openSession(id);
498
+ return undefined;
499
+ }),
500
+ item('action:rename', 'action', t.rename, t.renameHint, () => ({
501
+ input: {
502
+ kind: 'rename',
503
+ title: t.renamePrompt,
504
+ value: entry.title || '',
505
+ submit: (value) =>
506
+ renameOf(ctx, id, value.trim()).then(
507
+ () => ({ status: t.done }),
508
+ (error) => {
509
+ throw error;
510
+ },
511
+ ),
512
+ },
513
+ })),
514
+ item('action:fork', 'action', t.fork, t.forkHint, () =>
515
+ Promise.resolve(ctx.uiWorkspace.forkSession(id)).then((childId) => {
516
+ if (childId) ctx.uiWorkspace.openSession(childId);
517
+ return { status: t.done };
518
+ }),
519
+ ),
520
+ item('action:archive', 'action', t.archive, t.archiveHint, () =>
521
+ Promise.resolve(ctx.uiWorkspace.archiveSession(id, { stopActivity: true })).then(() => ({
522
+ status: t.done,
523
+ })),
524
+ ),
525
+ item('action:copy-id', 'action', t.copyId, id, () =>
526
+ copyText(id).then(() => ({ status: t.copied })),
527
+ ),
528
+ item('action:copy-cwd', 'action', t.copyPath, shortPath(cwd), () =>
529
+ copyText(cwd).then(() => ({ status: t.copied })),
530
+ ),
531
+ item('action:reveal', 'action', t.revealPath, shortPath(cwd), () =>
532
+ revealPath(cwd).then(() => ({ status: t.done })),
533
+ ),
534
+ item('action:export', 'action', t.exportMd, t.exportMdHint, () =>
535
+ getJson(API + '/export?id=' + encodeURIComponent(id)).then((payload) => {
536
+ var blob = new Blob([payload.markdown], { type: 'text/markdown;charset=utf-8' });
537
+ var url = URL.createObjectURL(blob);
538
+ var anchor = document.createElement('a');
539
+ anchor.href = url;
540
+ anchor.download = payload.filename || 'session.md';
541
+ document.body.appendChild(anchor);
542
+ anchor.click();
543
+ anchor.remove();
544
+ setTimeout(() => URL.revokeObjectURL(url), 4000);
545
+ return { status: t.done };
546
+ }),
547
+ ),
548
+ ];
549
+ }
550
+
551
+ function workspaceActions(ctx, lang, workspace) {
552
+ var t = copy(lang);
553
+ var id = workspace.workspaceId;
554
+ var path = workspace.path || '';
555
+ return [
556
+ item('action:ws-open', 'action', t.wsOpen, shortPath(path), () =>
557
+ Promise.resolve(ctx.uiWorkspace.openWorkspace(id)).then(() => undefined),
558
+ ),
559
+ item('action:ws-new', 'action', t.wsNew, shortPath(path), () => {
560
+ ctx.uiWorkspace.startSession(id);
561
+ return undefined;
562
+ }),
563
+ item('action:ws-copy', 'action', t.wsCopyPath, shortPath(path), () =>
564
+ copyText(path).then(() => ({ status: t.copied })),
565
+ ),
566
+ item('action:ws-reveal', 'action', t.wsReveal, shortPath(path), () =>
567
+ revealPath(path).then(() => ({ status: t.done })),
568
+ ),
569
+ ];
570
+ }
571
+
572
+ function buildActions(ctx, lang) {
573
+ var t = copy(lang);
574
+ var list = [
575
+ item('cmd:new', 'action', t.newSession, t.newSessionHint, () => {
576
+ ctx.uiWorkspace.startSession();
577
+ return undefined;
578
+ }),
579
+ item('cmd:profile', 'action', t.openProfile, t.openProfileHint, () =>
580
+ request(API + '/open-profile', {}).then(() => ({ status: t.done })),
581
+ ),
582
+ item('cmd:sessions', 'action', t.openSessions, t.openSessionsHint, () =>
583
+ getJson(API + '/info').then((info) => revealPath(info.home + '/sessions')).then(() => ({
584
+ status: t.done,
585
+ })),
586
+ ),
587
+ item('cmd:logs', 'action', t.openLogs, t.openLogsHint, () =>
588
+ getJson(API + '/info').then((info) => revealPath(info.home + '/logs')).then(() => ({
589
+ status: t.done,
590
+ })),
591
+ ),
592
+ item('cmd:reload', 'action', t.reload, t.reloadHint, () => {
593
+ window.location.reload();
594
+ return undefined;
595
+ }),
596
+ ];
597
+ return list;
598
+ }
599
+
600
+ function buildThemes(ctx, lang) {
601
+ var t = copy(lang);
602
+ return ['light', 'dark', 'system'].map((id) =>
603
+ item(
604
+ 'theme:' + id,
605
+ 'theme',
606
+ id === 'light' ? t.themeLight : id === 'dark' ? t.themeDark : t.themeSystem,
607
+ '',
608
+ () => {
609
+ ctx.theme.setTheme(id);
610
+ return { status: t.done };
611
+ },
612
+ ),
613
+ );
614
+ }
615
+
616
+ function buildLanguages(ctx, lang) {
617
+ var t = copy(lang);
618
+ var locales = [];
619
+ try {
620
+ var snapshot = ctx.locale.getLocale();
621
+ locales = (snapshot && snapshot.locales) || [];
622
+ } catch {
623
+ locales = [];
624
+ }
625
+ var installed = [];
626
+ for (var i = 0; i < locales.length; i++) {
627
+ var raw = locales[i];
628
+ var id = raw && typeof raw === 'object' ? raw.id : raw;
629
+ var label = raw && typeof raw === 'object' ? raw.label || raw.id : raw;
630
+ if (!id || id === 'en' || id === 'zh') continue;
631
+ installed.push(
632
+ item('lang:' + id, 'system', label, id, () => {
633
+ ctx.locale.setLocale(id);
634
+ return { status: t.done };
635
+ }),
636
+ );
637
+ }
638
+ return installed.concat([
639
+ item('lang:zh', 'system', t.langZh, 'zh', () => {
640
+ ctx.locale.setLocale('zh');
641
+ return { status: t.done };
642
+ }),
643
+ item('lang:en', 'system', t.langEn, 'en', () => {
644
+ ctx.locale.setLocale('en');
645
+ return { status: t.done };
646
+ }),
647
+ ]);
648
+ }
649
+
650
+ function workspaceItem(ctx, lang, workspace) {
651
+ var path = workspace.path || '';
652
+ return item(
653
+ 'workspace:' + workspace.workspaceId,
654
+ 'workspace',
655
+ (workspace.title || path || '').trim(),
656
+ shortPath(path),
657
+ () => Promise.resolve(ctx.uiWorkspace.openWorkspace(workspace.workspaceId)).then(() => undefined),
658
+ () => workspaceActions(ctx, lang, workspace),
659
+ );
660
+ }
661
+
662
+ function pluginItem(ctx, lang, plugin, reload) {
663
+ var t = copy(lang);
664
+ var key = 'plugin:' + plugin.name;
665
+ var toggle = () => {
666
+ var next = !plugin.enabled;
667
+ return request(API + '/plugin', { name: plugin.name, enabled: next }).then((payload) => {
668
+ if (reload) reload();
669
+ var status = next ? t.pluginOn : t.pluginOff;
670
+ var suffix = payload && payload.application === 'restart-required' ? ' · ' + t.restartHint : '';
671
+ return { status: plugin.name + ' · ' + status + suffix };
672
+ });
673
+ };
674
+ var actions = () => [
675
+ item(key + ':toggle', 'action', plugin.enabled ? t.disablePlugin : t.enablePlugin, plugin.name, toggle, null),
676
+ item(key + ':dir', 'action', t.pluginDir, plugin.name, () => revealPath(plugin.dir), null),
677
+ ];
678
+ var sub = [plugin.version ? 'v' + plugin.version : '', plugin.enabled ? t.pluginOn : t.pluginOff]
679
+ .filter(Boolean)
680
+ .join(' · ');
681
+ var row = item(key, 'plugin', plugin.name, sub, toggle, actions);
682
+ row.dot = plugin.enabled ? C.ok : C.sub;
683
+ return row;
684
+ }
685
+
686
+ function extItem(ctx, lang, command) {
687
+ var key = 'ext:' + command.id;
688
+ return item(
689
+ key,
690
+ 'ext',
691
+ command.title,
692
+ command.sub || '',
693
+ () => {
694
+ var out = command.run(ctx);
695
+ if (out && typeof out.then === 'function') {
696
+ return out.then((value) => (value && value.status ? { status: value.status } : null));
697
+ }
698
+ return out && out.status ? { status: out.status } : null;
699
+ },
700
+ null,
701
+ );
702
+ }
703
+
704
+ // ---------------------------------------------------------------------
705
+ // root list
706
+ // ---------------------------------------------------------------------
707
+ var GROUP_ORDER = ['recent', 'session', 'plugin', 'action', 'workspace', 'theme', 'system', 'ext'];
708
+
709
+ function groupLabel(group, lang) {
710
+ var t = copy(lang);
711
+ if (group === 'session') return t.session;
712
+ if (group === 'workspace') return t.workspace;
713
+ if (group === 'action') return t.action;
714
+ if (group === 'theme') return t.theme;
715
+ if (group === 'system') return t.system;
716
+ if (group === 'plugin') return t.plugin;
717
+ if (group === 'ext') return t.ext;
718
+ return t.recent;
719
+ }
720
+
721
+ function buildRoot(ctx, lang, query, catalog, workspaces, recent, plugins, ext, reloadPlugins) {
722
+ var items = [];
723
+ // keep the verbs reachable: a long transcript list would push them away
724
+ catalog.slice(0, query.trim() ? catalog.length : 5).forEach((entry) => items.push(sessionItem(ctx, lang, entry)));
725
+ (plugins || []).slice(0, query.trim() ? plugins.length : 6).forEach((plugin) => items.push(pluginItem(ctx, lang, plugin, reloadPlugins)));
726
+ buildActions(ctx, lang).forEach((entry) => items.push(entry));
727
+ workspaces.forEach((workspace) => items.push(workspaceItem(ctx, lang, workspace)));
728
+ (ext || []).forEach((command) => items.push(extItem(ctx, lang, command)));
729
+ buildThemes(ctx, lang).forEach((entry) => items.push(entry));
730
+ buildLanguages(ctx, lang).forEach((entry) => items.push(entry));
731
+
732
+ if (!query.trim()) {
733
+ // a short "recent" band on top, then the natural groups
734
+ var ranked = items
735
+ .map((entry) => ({ entry: entry, hit: recent[entry.key] }))
736
+ .filter((row) => row.hit && row.hit.at)
737
+ .sort((a, b) => (b.hit.at || 0) - (a.hit.at || 0))
738
+ .slice(0, 4)
739
+ .map((row) => row.entry);
740
+ var seen = new Set(ranked.map((entry) => entry.key));
741
+ return ranked
742
+ .map((entry) => Object.assign({}, entry, { group: 'recent' }))
743
+ .concat(items.filter((entry) => !seen.has(entry.key)));
744
+ }
745
+
746
+ var scored = [];
747
+ items.forEach((entry) => {
748
+ var score = scoreOf(query, entry);
749
+ if (!entry.key.startsWith('session:')) {
750
+ // the Host already filtered sessions; local items need their own match
751
+ if (score <= 0) return;
752
+ }
753
+ var bump = recent[entry.key] && recent[entry.key].at ? Math.min(recent[entry.key].count || 0, 6) * 0.02 : 0;
754
+ scored.push({ entry: entry, score: score + bump });
755
+ });
756
+ // keep every group contiguous: a group's place comes from its best hit, the
757
+ // rows inside keep their own order. Otherwise one group shows up twice.
758
+ var best = {};
759
+ scored.forEach((row) => {
760
+ var key = row.entry.group;
761
+ if (!(key in best) || row.score > best[key]) best[key] = row.score;
762
+ });
763
+ scored.sort((a, b) => {
764
+ var ga = a.entry.group;
765
+ var gb = b.entry.group;
766
+ if (ga !== gb) {
767
+ if (best[gb] !== best[ga]) return best[gb] - best[ga];
768
+ return GROUP_ORDER.indexOf(ga) - GROUP_ORDER.indexOf(gb);
769
+ }
770
+ return b.score - a.score;
771
+ });
772
+ return scored.map((row) => row.entry);
773
+ }
774
+
775
+ // ---------------------------------------------------------------------
776
+ // visual helpers
777
+ // ---------------------------------------------------------------------
778
+ function mix(color, percent, over) {
779
+ return 'color-mix(in srgb, ' + color + ' ' + percent + '%, ' + (over || 'transparent') + ')';
780
+ }
781
+
782
+ var ICONS = {
783
+ search: [
784
+ ['circle', { cx: 11, cy: 11, r: 7 }],
785
+ ['path', { d: 'm20 20-3.2-3.2' }],
786
+ ],
787
+ session: [['path', { d: 'M21 15a2 2 0 0 1-2 2H8l-5 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z' }]],
788
+ workspace: [['path', { d: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' }]],
789
+ plugin: [
790
+ ['path', { d: 'M21 8v8a2 2 0 0 1-1 1.73l-7 4a2 2 0 0 1-2 0l-7-4A2 2 0 0 1 3 16V8a2 2 0 0 1 1-1.73l7-4a2 2 0 0 1 2 0l7 4A2 2 0 0 1 21 8z' }],
791
+ ['path', { d: 'm3.3 7 8.7 5 8.7-5' }],
792
+ ['path', { d: 'M12 22V12' }],
793
+ ],
794
+ action: [['path', { d: 'M13 2 4 14h7l-1 8 9-12h-7z' }]],
795
+ theme: [
796
+ ['circle', { cx: 12, cy: 12, r: 4 }],
797
+ ['path', { d: 'M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4' }],
798
+ ],
799
+ system: [
800
+ ['path', { d: 'M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3' }],
801
+ ['path', { d: 'M1 14h6M9 8h6M17 16h6' }],
802
+ ],
803
+ recent: [
804
+ ['circle', { cx: 12, cy: 12, r: 9 }],
805
+ ['path', { d: 'M12 7v5l3 2' }],
806
+ ],
807
+ ext: [['path', { d: 'M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z' }]],
808
+ more: [
809
+ ['circle', { cx: 5, cy: 12, r: 1.4 }],
810
+ ['circle', { cx: 12, cy: 12, r: 1.4 }],
811
+ ['circle', { cx: 19, cy: 12, r: 1.4 }],
812
+ ],
813
+ back: [['path', { d: 'm15 18-6-6 6-6' }]],
814
+ 'arrow-up-right': [['path', { d: 'M7 17 17 7M8 7h9v9' }]],
815
+ external: [['path', { d: 'M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6' }]],
816
+ pencil: [
817
+ ['path', { d: 'M12 20h9' }],
818
+ ['path', { d: 'M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z' }],
819
+ ],
820
+ branch: [
821
+ ['circle', { cx: 6, cy: 6, r: 2.5 }],
822
+ ['circle', { cx: 6, cy: 18, r: 2.5 }],
823
+ ['circle', { cx: 18, cy: 6, r: 2.5 }],
824
+ ['path', { d: 'M6 8.5v7M18 8.5c0 3-2 4-5 4H8' }],
825
+ ],
826
+ archive: [
827
+ ['rect', { x: 3, y: 4, width: 18, height: 4, rx: 1 }],
828
+ ['path', { d: 'M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8M10 12h4' }],
829
+ ],
830
+ copy: [
831
+ ['rect', { x: 9, y: 9, width: 11, height: 11, rx: 2 }],
832
+ ['path', { d: 'M5 15V5a2 2 0 0 1 2-2h10' }],
833
+ ],
834
+ folder: [['path', { d: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' }]],
835
+ download: [['path', { d: 'M12 3v12M7 10l5 5 5-5M5 21h14' }]],
836
+ power: [
837
+ ['path', { d: 'M12 3v9' }],
838
+ ['path', { d: 'M7 6.5a7 7 0 1 0 10 0' }],
839
+ ],
840
+ plus: [['path', { d: 'M12 5v14M5 12h14' }]],
841
+ refresh: [
842
+ ['path', { d: 'M20 11a8 8 0 1 0-2.3 5.7' }],
843
+ ['path', { d: 'M20 4v7h-7' }],
844
+ ],
845
+ globe: [
846
+ ['circle', { cx: 12, cy: 12, r: 9 }],
847
+ ['path', { d: 'M3 12h18M12 3c2.5 2.7 3.8 5.7 3.8 9S14.5 18.3 12 21c-2.5-2.7-3.8-5.7-3.8-9S9.5 5.7 12 3z' }],
848
+ ],
849
+ check: [['path', { d: 'm20 6-11 11-5-5' }]],
850
+ x: [['path', { d: 'M18 6 6 18M6 6l12 12' }]],
851
+ };
852
+
853
+ function Icon(props) {
854
+ var paint = ICONS[props.name] || ICONS.action;
855
+ var size = props.size || 16;
856
+ return h(
857
+ 'svg',
858
+ {
859
+ width: size,
860
+ height: size,
861
+ viewBox: '0 0 24 24',
862
+ fill: 'none',
863
+ stroke: 'currentColor',
864
+ strokeWidth: props.stroke || 1.7,
865
+ strokeLinecap: 'round',
866
+ strokeLinejoin: 'round',
867
+ 'aria-hidden': 'true',
868
+ style: { display: 'block', flex: '0 0 auto' },
869
+ },
870
+ paint.map(function (entry, position) {
871
+ return h(entry[0], Object.assign({ key: position }, entry[1]));
872
+ }),
873
+ );
874
+ }
875
+
876
+ function iconForGroup(group) {
877
+ if (group === 'recent') return 'recent';
878
+ if (group === 'session') return 'session';
879
+ if (group === 'workspace') return 'workspace';
880
+ if (group === 'plugin') return 'plugin';
881
+ if (group === 'theme') return 'theme';
882
+ if (group === 'system') return 'system';
883
+ if (group === 'ext') return 'ext';
884
+ return 'action';
885
+ }
886
+
887
+ function iconForEntry(entry) {
888
+ if (!entry) return 'action';
889
+ var key = String(entry.key || '');
890
+ if (/:toggle$/.test(key)) return 'power';
891
+ if (/:dir$/.test(key)) return 'folder';
892
+ if (key.indexOf('theme:') === 0) return 'theme';
893
+ if (key.indexOf('lang:') === 0) return 'globe';
894
+ if (key.indexOf('plugin:') === 0) return 'plugin';
895
+ if (key.indexOf('workspace:') === 0) return 'workspace';
896
+ if (key.indexOf('session:') === 0) return 'session';
897
+ if (key.indexOf('ext:') === 0) return 'ext';
898
+ if (key.indexOf('cmd:reload') === 0) return 'refresh';
899
+ if (key.indexOf('cmd:new') === 0) return 'plus';
900
+ if (key.indexOf('cmd:profile') === 0) return 'folder';
901
+ if (key.indexOf('cmd:sessions') === 0) return 'folder';
902
+ if (key.indexOf('cmd:logs') === 0) return 'folder';
903
+ if (key.indexOf('action:rename') === 0) return 'pencil';
904
+ if (key.indexOf('action:fork') === 0) return 'branch';
905
+ if (key.indexOf('action:archive') === 0) return 'archive';
906
+ if (key.indexOf('action:copy') === 0) return 'copy';
907
+ if (key.indexOf('action:ws-copy') === 0) return 'copy';
908
+ if (key.indexOf('action:reveal') === 0) return 'external';
909
+ if (key.indexOf('action:ws-reveal') === 0) return 'external';
910
+ if (key.indexOf('action:export') === 0) return 'download';
911
+ if (key.indexOf('action:ws-new') === 0) return 'plus';
912
+ if (key.indexOf('action:open') === 0) return 'arrow-up-right';
913
+ if (key.indexOf('action:ws-open') === 0) return 'arrow-up-right';
914
+ return iconForGroup(entry.group);
915
+ }
916
+
917
+ function Kbd(props) {
918
+ return h(
919
+ 'span',
920
+ {
921
+ style: {
922
+ display: 'inline-flex',
923
+ alignItems: 'center',
924
+ justifyContent: 'center',
925
+ minWidth: 20,
926
+ height: 20,
927
+ padding: '0 5px',
928
+ boxSizing: 'border-box',
929
+ flex: '0 0 auto',
930
+ fontFamily: MONO,
931
+ fontSize: 10.5,
932
+ fontWeight: 600,
933
+ lineHeight: 1,
934
+ color: C.sub,
935
+ background: mix(C.layerAlt, 72),
936
+ border: '1px solid ' + mix(C.lineStrong, 65),
937
+ borderBottomColor: mix(C.lineStrong, 88),
938
+ borderRadius: 5,
939
+ boxShadow: '0 1px 0 ' + mix(C.text, 5),
940
+ whiteSpace: 'nowrap',
941
+ },
942
+ },
943
+ props.children,
944
+ );
945
+ }
946
+
947
+ function IconTile(props) {
948
+ var active = props.active;
949
+ return h(
950
+ 'span',
951
+ {
952
+ style: {
953
+ position: 'relative',
954
+ flex: '0 0 auto',
955
+ width: 30,
956
+ height: 30,
957
+ display: 'inline-flex',
958
+ alignItems: 'center',
959
+ justifyContent: 'center',
960
+ borderRadius: 8,
961
+ color: active ? C.brand : C.sub,
962
+ background: active ? mix(C.brand, 13) : mix(C.layerAlt, 76),
963
+ border: '1px solid ' + (active ? mix(C.brand, 24) : mix(C.line, 70)),
964
+ transition: 'background 120ms ease, color 120ms ease, border-color 120ms ease',
965
+ },
966
+ },
967
+ h(Icon, { name: props.name, size: 15 }),
968
+ props.dot
969
+ ? h('span', {
970
+ style: {
971
+ position: 'absolute',
972
+ right: -1,
973
+ bottom: -1,
974
+ width: 7,
975
+ height: 7,
976
+ borderRadius: 4,
977
+ background: props.dot,
978
+ border: '2px solid ' + C.overlay,
979
+ boxSizing: 'content-box',
980
+ },
981
+ })
982
+ : null,
983
+ );
984
+ }
985
+
986
+ var SHIMMER =
987
+ 'linear-gradient(90deg, ' +
988
+ mix(C.layerAlt, 78) +
989
+ ' 25%, ' +
990
+ mix(C.lineStrong, 58) +
991
+ ' 37%, ' +
992
+ mix(C.layerAlt, 78) +
993
+ ' 63%)';
994
+
995
+ var PANEL_CSS = [
996
+ '@keyframes dsh-cmdk-in{from{opacity:0;transform:translateY(-10px) scale(.985)}to{opacity:1;transform:none}}',
997
+ '@keyframes dsh-cmdk-fade{from{opacity:0}}',
998
+ '@keyframes dsh-cmdk-shimmer{0%{background-position:-240px 0}100%{background-position:240px 0}}',
999
+ '@keyframes dsh-cmdk-spin{to{transform:rotate(360deg)}}',
1000
+ '.dsh-cmdk-input::placeholder{color:' + C.sub + ';opacity:.72}',
1001
+ '.dsh-cmdk-back:hover,.dsh-cmdk-more:hover{background:' + mix(C.layerAlt, 82) + '!important;color:' + C.text + '!important}',
1002
+ '.dsh-cmdk-clear:hover{color:' + C.text + '!important}',
1003
+ '.dsh-cmdk-scroll{scrollbar-width:thin;scrollbar-color:' + mix(C.sub, 30) + ' transparent}',
1004
+ '.dsh-cmdk-scroll::-webkit-scrollbar{width:10px;height:10px}',
1005
+ '.dsh-cmdk-scroll::-webkit-scrollbar-track{background:transparent}',
1006
+ '.dsh-cmdk-scroll::-webkit-scrollbar-thumb{background:' + mix(C.sub, 26) + ';border-radius:999px;border:3px solid transparent;background-clip:content-box}',
1007
+ '.dsh-cmdk-scroll::-webkit-scrollbar-thumb:hover{background:' + mix(C.sub, 44) + ';border:3px solid transparent;background-clip:content-box}',
1008
+ '@media (prefers-reduced-motion:reduce){.dsh-cmdk-panel,.dsh-cmdk-scrim{animation:none!important}.dsh-cmdk-panel *{transition:none!important}.dsh-cmdk-shimmer{animation:none!important}}',
1009
+ ].join('');
1010
+
1011
+ function Hints(props) {
1012
+ return h(
1013
+ 'div',
1014
+ { style: { display: 'flex', alignItems: 'center', gap: 12, minWidth: 0, overflow: 'hidden' } },
1015
+ props.items.map(function (pair, position) {
1016
+ return h(
1017
+ 'span',
1018
+ {
1019
+ key: position,
1020
+ style: { display: 'inline-flex', alignItems: 'center', gap: 5, whiteSpace: 'nowrap' },
1021
+ },
1022
+ h(Kbd, null, pair[0]),
1023
+ pair[1],
1024
+ );
1025
+ }),
1026
+ );
1027
+ }
1028
+
1029
+ function Highlight(props) {
1030
+ var text = props.text == null ? '' : String(props.text);
1031
+ var query = String(props.query || '').trim();
1032
+ if (!query) return text;
1033
+ var lower = text.toLowerCase();
1034
+ var needle = query.toLowerCase();
1035
+ var at = lower.indexOf(needle);
1036
+ if (at < 0) return text;
1037
+ var parts = [];
1038
+ var from = 0;
1039
+ var guard = 0;
1040
+ while (at >= 0 && guard < 40) {
1041
+ if (at > from) parts.push(text.slice(from, at));
1042
+ parts.push(
1043
+ h(
1044
+ 'mark',
1045
+ {
1046
+ key: 'm' + parts.length,
1047
+ style: {
1048
+ backgroundColor: mix(C.brand, 22),
1049
+ boxShadow: 'inset 0 -1px 0 ' + mix(C.brand, 62),
1050
+ color: 'inherit',
1051
+ borderRadius: 3,
1052
+ padding: '0 1px',
1053
+ fontWeight: 600,
1054
+ },
1055
+ },
1056
+ text.slice(at, at + needle.length),
1057
+ ),
1058
+ );
1059
+ from = at + needle.length;
1060
+ at = lower.indexOf(needle, from);
1061
+ guard += 1;
1062
+ }
1063
+ if (from < text.length) parts.push(text.slice(from));
1064
+ return parts;
1065
+ }
1066
+
1067
+ function EmptyState(props) {
1068
+ var query = String(props.query || '').trim();
1069
+ if (query.length > 30) query = query.slice(0, 30) + '…';
1070
+ return h(
1071
+ 'div',
1072
+ {
1073
+ style: {
1074
+ display: 'flex',
1075
+ flexDirection: 'column',
1076
+ alignItems: 'center',
1077
+ textAlign: 'center',
1078
+ gap: 9,
1079
+ padding: '54px 24px 60px',
1080
+ },
1081
+ },
1082
+ h(
1083
+ 'span',
1084
+ {
1085
+ style: {
1086
+ width: 46,
1087
+ height: 46,
1088
+ borderRadius: 14,
1089
+ display: 'inline-flex',
1090
+ alignItems: 'center',
1091
+ justifyContent: 'center',
1092
+ background: mix(C.layerAlt, 80),
1093
+ border: '1px solid ' + mix(C.lineStrong, 55),
1094
+ color: C.sub,
1095
+ marginBottom: 2,
1096
+ },
1097
+ },
1098
+ h(Icon, { name: 'search', size: 20 }),
1099
+ ),
1100
+ h(
1101
+ 'div',
1102
+ {
1103
+ style: {
1104
+ fontSize: 13.5,
1105
+ fontWeight: 600,
1106
+ color: C.text,
1107
+ maxWidth: 380,
1108
+ lineHeight: 1.4,
1109
+ overflowWrap: 'anywhere',
1110
+ },
1111
+ },
1112
+ query ? props.t.emptyFor.replace('{q}', function () { return query; }) : props.t.emptyTitle,
1113
+ ),
1114
+ h(
1115
+ 'div',
1116
+ { style: { fontSize: 12, color: C.sub, maxWidth: 300, lineHeight: 1.55 } },
1117
+ props.t.emptySub,
1118
+ ),
1119
+ );
1120
+ }
1121
+
1122
+ function Skeleton() {
1123
+ return h(
1124
+ 'div',
1125
+ { style: { padding: '8px 2px' } },
1126
+ [0, 1, 2, 3].map(function (row) {
1127
+ var shimmer = {
1128
+ background: SHIMMER,
1129
+ backgroundSize: '400px 100%',
1130
+ animation: 'dsh-cmdk-shimmer 1.3s linear infinite',
1131
+ };
1132
+ return h(
1133
+ 'div',
1134
+ { key: row, style: { display: 'flex', alignItems: 'center', gap: 11, padding: '8px 10px' } },
1135
+ h('div', { style: Object.assign({ width: 30, height: 30, borderRadius: 8, flex: '0 0 auto' }, shimmer) }),
1136
+ h(
1137
+ 'div',
1138
+ { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 6 } },
1139
+ h(
1140
+ 'div',
1141
+ { style: Object.assign({ height: 10, width: 46 + ((row * 13) % 34) + '%', borderRadius: 4 }, shimmer) },
1142
+ ),
1143
+ h(
1144
+ 'div',
1145
+ {
1146
+ style: Object.assign(
1147
+ { height: 8, width: 28 + ((row * 9) % 26) + '%', borderRadius: 4, opacity: 0.7 },
1148
+ shimmer,
1149
+ ),
1150
+ },
1151
+ ),
1152
+ ),
1153
+ );
1154
+ }),
1155
+ );
1156
+ }
1157
+
1158
+ // ---------------------------------------------------------------------
1159
+ // the palette itself
1160
+ // ---------------------------------------------------------------------
1161
+ function Palette(props) {
1162
+ var ctx = props.ctx;
1163
+ var lang = useLang(ctx);
1164
+ var t = copy(lang);
1165
+ var open = useOpen();
1166
+ var [query, setQuery] = useState('');
1167
+ var [catalog, setCatalog] = useState({ items: [], loading: true });
1168
+ var [index, setIndex] = useState(0);
1169
+ var [stack, setStack] = useState([]);
1170
+ var [input, setInput] = useState(null);
1171
+ var [status, setStatus] = useState(null);
1172
+ var [busy, setBusy] = useState(false);
1173
+ var [focused, setFocused] = useState(false);
1174
+ var [canFade, setCanFade] = useState(false);
1175
+ var inputRef = useRef(null);
1176
+ var listRef = useRef(null);
1177
+ var [workspaces, setWorkspaces] = useState([]);
1178
+ var [archived, setArchived] = useState({});
1179
+ var [recent, setRecent] = useState(() => readRecent());
1180
+ var [plugins, setPlugins] = useState([]);
1181
+ var ext = useExtCommands();
1182
+
1183
+ function reloadPlugins() {
1184
+ getJson(API + '/plugins')
1185
+ .then((payload) => setPlugins(Array.isArray(payload.items) ? payload.items : []))
1186
+ .catch(() => undefined);
1187
+ }
1188
+
1189
+ var panelRef = useRef(null);
1190
+ var handlerRef = useRef(null);
1191
+
1192
+ // After a mode change the text input unmounts, so focus falls back to the
1193
+ // body: pull it onto the panel and relay keys that escape our dialog.
1194
+ useEffect(() => {
1195
+ if (!open) return;
1196
+ var node = panelRef.current;
1197
+ if (node && document.activeElement !== node) {
1198
+ try {
1199
+ node.focus({ preventScroll: true });
1200
+ } catch (error) {
1201
+ node.focus();
1202
+ }
1203
+ }
1204
+ }, [open, stack.length, input]);
1205
+
1206
+ useEffect(() => {
1207
+ if (!open) return undefined;
1208
+ function relay(event) {
1209
+ var node = panelRef.current;
1210
+ var target = event.target;
1211
+ if (node && target && target.nodeType && node.contains(target)) return;
1212
+ if (handlerRef.current) handlerRef.current(event);
1213
+ }
1214
+ window.addEventListener('keydown', relay, true);
1215
+ return () => window.removeEventListener('keydown', relay, true);
1216
+ }, [open]);
1217
+
1218
+ handlerRef.current = onKeyDown;
1219
+
1220
+ // workspaces + archived ids come from the Host store mirror
1221
+ useEffect(() => {
1222
+ if (!open) return undefined;
1223
+ reloadPlugins();
1224
+ return undefined;
1225
+ }, [open]);
1226
+
1227
+ useEffect(() => {
1228
+ if (!open) return undefined;
1229
+ var alive = true;
1230
+ getJson(API + '/workspaces')
1231
+ .then((payload) => {
1232
+ if (!alive) return;
1233
+ setWorkspaces(Array.isArray(payload.items) ? payload.items : []);
1234
+ var map = {};
1235
+ (payload.archived || []).forEach((id) => {
1236
+ map[id] = true;
1237
+ });
1238
+ setArchived(map);
1239
+ })
1240
+ .catch(() => {
1241
+ /* the palette still works without the workspace list */
1242
+ });
1243
+ return () => {
1244
+ alive = false;
1245
+ };
1246
+ }, [open]);
1247
+
1248
+ // session catalogue comes from the Host: titles + content hits
1249
+ useEffect(() => {
1250
+ if (!open) return undefined;
1251
+ var alive = true;
1252
+ var text = query.trim();
1253
+ setStatus(null);
1254
+ var timer = setTimeout(
1255
+ () => {
1256
+ setCatalog((prev) => (prev.items.length ? prev : { items: [], loading: true }));
1257
+ getJson(API + '/sessions?limit=24' + (text ? '&q=' + encodeURIComponent(text) : ''))
1258
+ .then((payload) => {
1259
+ if (!alive) return;
1260
+ var live = (payload.items || []).filter((entry) => !archived[entry.sessionId]);
1261
+ setCatalog({ items: live, loading: false });
1262
+ })
1263
+ .catch(() => {
1264
+ if (!alive) return;
1265
+ setCatalog({ items: [], loading: false });
1266
+ });
1267
+ },
1268
+ text ? 180 : 0,
1269
+ );
1270
+ return () => {
1271
+ alive = false;
1272
+ clearTimeout(timer);
1273
+ };
1274
+ }, [open, query]);
1275
+
1276
+ useEffect(() => {
1277
+ if (!open) {
1278
+ setQuery('');
1279
+ setIndex(0);
1280
+ setStack([]);
1281
+ setInput(null);
1282
+ setStatus(null);
1283
+ return;
1284
+ }
1285
+ setRecent(readRecent());
1286
+ var handle = setTimeout(() => {
1287
+ if (inputRef.current) {
1288
+ inputRef.current.focus({ preventScroll: true });
1289
+ inputRef.current.select && inputRef.current.select();
1290
+ }
1291
+ }, 30);
1292
+ return () => clearTimeout(handle);
1293
+ }, [open]);
1294
+
1295
+ useEffect(() => {
1296
+ if (!open) return undefined;
1297
+ var handle = setTimeout(() => {
1298
+ var node = inputRef.current;
1299
+ if (node && typeof node.focus === 'function') node.focus({ preventScroll: true });
1300
+ }, 20);
1301
+ return () => clearTimeout(handle);
1302
+ }, [open, stack.length, input]);
1303
+
1304
+ useEffect(() => {
1305
+ if (!status) return undefined;
1306
+ var handle = setTimeout(() => setStatus(null), 2200);
1307
+ return () => clearTimeout(handle);
1308
+ }, [status]);
1309
+
1310
+ var visible = [];
1311
+ for (var vi = 0; vi < catalog.items.length; vi += 1) {
1312
+ if (!archived[catalog.items[vi].sessionId]) visible.push(catalog.items[vi]);
1313
+ }
1314
+ var root = buildRoot(ctx, lang, query, visible, workspaces, recent, plugins, ext, reloadPlugins);
1315
+ var current = stack.length ? stack[stack.length - 1] : null;
1316
+ var items = input ? [] : current ? current.items : root;
1317
+ var active = Math.min(index, Math.max(items.length - 1, 0));
1318
+
1319
+ function close() {
1320
+ setFocused(false);
1321
+ store.set(false);
1322
+ }
1323
+
1324
+ function goBack() {
1325
+ if (input) {
1326
+ setInput(null);
1327
+ return;
1328
+ }
1329
+ if (stack.length) {
1330
+ setStack((prev) => prev.slice(0, -1));
1331
+ setIndex(0);
1332
+ }
1333
+ }
1334
+
1335
+ function syncScrollFade() {
1336
+ var node = listRef.current;
1337
+ if (!node) return;
1338
+ setCanFade(node.scrollHeight - node.scrollTop - node.clientHeight > 4);
1339
+ }
1340
+
1341
+ // Keep the highlighted row inside the viewport when the keyboard moves it.
1342
+ useEffect(() => {
1343
+ if (!open) return;
1344
+ var node = listRef.current;
1345
+ if (!node) return;
1346
+ var option = node.querySelector('#dsh-cmdk-opt-' + active);
1347
+ if (option && typeof option.scrollIntoView === 'function') {
1348
+ option.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'instant' });
1349
+ }
1350
+ }, [open, active, stack.length, input, items.length]);
1351
+
1352
+ useEffect(() => {
1353
+ syncScrollFade();
1354
+ }, [open, items.length, query, stack.length, input, catalog.loading]);
1355
+
1356
+ function remember(key) {
1357
+ var next = bumpRecent(key);
1358
+ if (next) setRecent(next);
1359
+ }
1360
+
1361
+ function settle(result) {
1362
+ if (!result) {
1363
+ close();
1364
+ return;
1365
+ }
1366
+ if (result.input) {
1367
+ setInput({ title: result.input.title, value: result.input.value || '', submit: result.input.submit });
1368
+ setStatus(null);
1369
+ return;
1370
+ }
1371
+ if (result.status) {
1372
+ setStatus(result.status);
1373
+ // keep the palette open so the toast is visible, but leave action mode
1374
+ setStack([]);
1375
+ return;
1376
+ }
1377
+ close();
1378
+ }
1379
+
1380
+ function run(entry) {
1381
+ if (!entry || busy) return;
1382
+ remember(entry.key);
1383
+ var result;
1384
+ try {
1385
+ result = entry.run();
1386
+ } catch (error) {
1387
+ setStatus(t.failed + ':' + String((error && error.message) || error));
1388
+ return;
1389
+ }
1390
+ if (result && typeof result.then === 'function') {
1391
+ setBusy(true);
1392
+ result.then(
1393
+ (value) => {
1394
+ setBusy(false);
1395
+ settle(value);
1396
+ },
1397
+ (error) => {
1398
+ setBusy(false);
1399
+ setStatus(t.failed + ':' + String((error && error.message) || error));
1400
+ },
1401
+ );
1402
+ return;
1403
+ }
1404
+ settle(result);
1405
+ }
1406
+
1407
+ function openActions(entry) {
1408
+ if (!entry || !entry.actions) return false;
1409
+ setStack((prev) => prev.concat([{ title: entry.title, group: entry.group, items: entry.actions() }]));
1410
+ setIndex(0);
1411
+ return true;
1412
+ }
1413
+
1414
+ function submitInput() {
1415
+ if (!input) return;
1416
+ var value = String(input.value || '').trim();
1417
+ if (!value) {
1418
+ setStatus(t.cancelled);
1419
+ setInput(null);
1420
+ return;
1421
+ }
1422
+ var pending;
1423
+ try {
1424
+ pending = input.submit(value);
1425
+ } catch (error) {
1426
+ setStatus(t.failed + ':' + String((error && error.message) || error));
1427
+ return;
1428
+ }
1429
+ setBusy(true);
1430
+ Promise.resolve(pending).then(
1431
+ (result) => {
1432
+ setBusy(false);
1433
+ setInput(null);
1434
+ settle(result || { status: t.done });
1435
+ },
1436
+ (error) => {
1437
+ setBusy(false);
1438
+ setStatus(t.failed + ':' + String((error && error.message) || error));
1439
+ },
1440
+ );
1441
+ }
1442
+
1443
+ function onKeyDown(event) {
1444
+ if (event.isComposing || (event.nativeEvent && event.nativeEvent.isComposing) || event.keyCode === 229) {
1445
+ return;
1446
+ }
1447
+ if (event.key === 'Escape') {
1448
+ event.preventDefault();
1449
+ event.stopPropagation();
1450
+ if (input) {
1451
+ setInput(null);
1452
+ return;
1453
+ }
1454
+ if (stack.length) {
1455
+ setStack((prev) => prev.slice(0, -1));
1456
+ setIndex(0);
1457
+ return;
1458
+ }
1459
+ close();
1460
+ return;
1461
+ }
1462
+ if (input) {
1463
+ if (event.key === 'Enter') {
1464
+ event.preventDefault();
1465
+ submitInput();
1466
+ }
1467
+ return;
1468
+ }
1469
+ if (event.key === 'ArrowDown') {
1470
+ event.preventDefault();
1471
+ if (items.length) setIndex((active + 1) % items.length);
1472
+ return;
1473
+ }
1474
+ if (event.key === 'ArrowUp') {
1475
+ event.preventDefault();
1476
+ if (items.length) setIndex((active - 1 + items.length) % items.length);
1477
+ return;
1478
+ }
1479
+ if (event.key === 'ArrowRight' || event.key === 'Tab') {
1480
+ if (openActions(items[active])) {
1481
+ event.preventDefault();
1482
+ return;
1483
+ }
1484
+ if (event.key === 'Tab') event.preventDefault();
1485
+ return;
1486
+ }
1487
+ if (event.key === 'ArrowLeft' && stack.length) {
1488
+ event.preventDefault();
1489
+ setStack((prev) => prev.slice(0, -1));
1490
+ setIndex(0);
1491
+ return;
1492
+ }
1493
+ if (event.key === 'Enter') {
1494
+ event.preventDefault();
1495
+ run(items[active]);
1496
+ return;
1497
+ }
1498
+ if (event.key === 'Backspace' && !query && stack.length) {
1499
+ event.preventDefault();
1500
+ setStack((prev) => prev.slice(0, -1));
1501
+ setIndex(0);
1502
+ }
1503
+ }
1504
+
1505
+ if (!open) return null;
1506
+
1507
+ var sections = [];
1508
+ var lastGroup = null;
1509
+ var counts = {};
1510
+ items.forEach((entry) => {
1511
+ counts[entry.group] = (counts[entry.group] || 0) + 1;
1512
+ });
1513
+ items.forEach((entry, position) => {
1514
+ if (entry.group !== lastGroup) {
1515
+ lastGroup = entry.group;
1516
+ sections.push({
1517
+ key: 'group:' + entry.group + ':' + position,
1518
+ group: entry.group,
1519
+ rows: [],
1520
+ });
1521
+ }
1522
+ sections[sections.length - 1].rows.push(
1523
+ renderRow(
1524
+ entry,
1525
+ position === active,
1526
+ () => run(entry),
1527
+ () => openActions(entry),
1528
+ () => setIndex(position),
1529
+ position,
1530
+ t.hintActions,
1531
+ stack.length ? '' : query,
1532
+ ),
1533
+ );
1534
+ });
1535
+ var rows = sections.map(function (section) {
1536
+ return h(
1537
+ 'div',
1538
+ {
1539
+ key: section.key,
1540
+ role: 'group',
1541
+ 'aria-label': groupLabel(section.group, lang),
1542
+ },
1543
+ h(
1544
+ 'div',
1545
+ {
1546
+ style: {
1547
+ position: 'sticky',
1548
+ top: 0,
1549
+ zIndex: 1,
1550
+ display: 'flex',
1551
+ alignItems: 'center',
1552
+ justifyContent: 'space-between',
1553
+ gap: 8,
1554
+ padding: '11px 10px 5px',
1555
+ background: C.overlay,
1556
+ },
1557
+ },
1558
+ h(
1559
+ 'span',
1560
+ {
1561
+ style: {
1562
+ fontSize: 10.5,
1563
+ fontWeight: 700,
1564
+ letterSpacing: '.09em',
1565
+ textTransform: 'uppercase',
1566
+ color: C.sub,
1567
+ },
1568
+ },
1569
+ groupLabel(section.group, lang),
1570
+ ),
1571
+ h(
1572
+ 'span',
1573
+ {
1574
+ style: {
1575
+ fontSize: 10.5,
1576
+ fontVariantNumeric: 'tabular-nums',
1577
+ color: mix(C.sub, 72),
1578
+ },
1579
+ },
1580
+ counts[section.group],
1581
+ ),
1582
+ ),
1583
+ section.rows,
1584
+ );
1585
+ });
1586
+
1587
+ var headerStyle = {
1588
+ display: 'flex',
1589
+ alignItems: 'center',
1590
+ gap: 9,
1591
+ padding: '12px 14px',
1592
+ borderBottom: '1px solid ' + mix(C.lineStrong, 55),
1593
+ position: 'relative',
1594
+ zIndex: 2,
1595
+ background: mix(C.overlay, 70),
1596
+ };
1597
+ var fieldStyle = {
1598
+ flex: 1,
1599
+ minWidth: 0,
1600
+ display: 'flex',
1601
+ alignItems: 'center',
1602
+ gap: 9,
1603
+ height: 42,
1604
+ padding: '0 11px',
1605
+ boxSizing: 'border-box',
1606
+ borderRadius: 10,
1607
+ background: mix(C.base, 66),
1608
+ border: '1px solid ' + (focused ? mix(C.brand, 55) : mix(C.lineStrong, 62)),
1609
+ boxShadow: focused
1610
+ ? '0 0 0 3px ' + mix(C.brand, 14) + ', inset 0 1px 2px ' + mix(C.text, 5)
1611
+ : 'inset 0 1px 2px ' + mix(C.text, 4),
1612
+ transition: 'border-color 140ms ease, box-shadow 140ms ease',
1613
+ };
1614
+ var inputStyle = {
1615
+ flex: 1,
1616
+ minWidth: 0,
1617
+ width: '100%',
1618
+ height: '100%',
1619
+ padding: 0,
1620
+ border: 'none',
1621
+ outline: 'none',
1622
+ background: 'transparent',
1623
+ color: C.text,
1624
+ fontSize: 15,
1625
+ fontFamily: 'inherit',
1626
+ caretColor: C.brand,
1627
+ };
1628
+ var backButton = h(
1629
+ 'button',
1630
+ {
1631
+ type: 'button',
1632
+ className: 'dsh-cmdk-back',
1633
+ title: t.hintBack,
1634
+ 'aria-label': t.hintBack,
1635
+ onClick: goBack,
1636
+ style: {
1637
+ flex: '0 0 auto',
1638
+ width: 28,
1639
+ height: 28,
1640
+ display: 'inline-flex',
1641
+ alignItems: 'center',
1642
+ justifyContent: 'center',
1643
+ padding: 0,
1644
+ border: 'none',
1645
+ borderRadius: 8,
1646
+ background: 'transparent',
1647
+ color: C.sub,
1648
+ cursor: 'pointer',
1649
+ transition: 'background 120ms ease, color 120ms ease',
1650
+ },
1651
+ },
1652
+ h(Icon, { name: 'back', size: 16 }),
1653
+ );
1654
+
1655
+ var header;
1656
+ if (input) {
1657
+ header = h(
1658
+ 'div',
1659
+ { style: headerStyle },
1660
+ backButton,
1661
+ h(
1662
+ 'div',
1663
+ { style: fieldStyle },
1664
+ h(Icon, { name: 'pencil', size: 16 }),
1665
+ h('input', {
1666
+ ref: inputRef,
1667
+ value: input.value,
1668
+ placeholder: input.title,
1669
+ className: 'dsh-cmdk-input',
1670
+ onChange: (event) => setInput(Object.assign({}, input, { value: event.target.value })),
1671
+ onFocus: () => setFocused(true),
1672
+ onBlur: () => setFocused(false),
1673
+ style: inputStyle,
1674
+ 'aria-label': input.title,
1675
+ spellCheck: false,
1676
+ autoComplete: 'off',
1677
+ }),
1678
+ ),
1679
+ h(Kbd, null, '↵'),
1680
+ h(Kbd, null, 'esc'),
1681
+ );
1682
+ } else if (current) {
1683
+ header = h(
1684
+ 'div',
1685
+ { style: headerStyle },
1686
+ backButton,
1687
+ h(
1688
+ 'div',
1689
+ { style: { flex: 1, minWidth: 0, display: 'flex', alignItems: 'center', gap: 10 } },
1690
+ h(IconTile, { name: iconForGroup(current.group || 'action'), active: true }),
1691
+ h(
1692
+ 'span',
1693
+ {
1694
+ style: {
1695
+ minWidth: 0,
1696
+ overflow: 'hidden',
1697
+ textOverflow: 'ellipsis',
1698
+ whiteSpace: 'nowrap',
1699
+ fontSize: 14,
1700
+ fontWeight: 600,
1701
+ color: C.text,
1702
+ letterSpacing: '-.005em',
1703
+ },
1704
+ },
1705
+ current.title,
1706
+ ),
1707
+ ),
1708
+ h(Kbd, null, 'esc'),
1709
+ );
1710
+ } else {
1711
+ header = h(
1712
+ 'div',
1713
+ { style: headerStyle },
1714
+ h(
1715
+ 'div',
1716
+ { style: fieldStyle },
1717
+ h(Icon, { name: 'search', size: 17 }),
1718
+ h('input', {
1719
+ ref: inputRef,
1720
+ value: query,
1721
+ placeholder: t.placeholder,
1722
+ className: 'dsh-cmdk-input',
1723
+ onChange: (event) => {
1724
+ setQuery(event.target.value);
1725
+ setIndex(0);
1726
+ },
1727
+ onFocus: () => setFocused(true),
1728
+ onBlur: () => setFocused(false),
1729
+ style: inputStyle,
1730
+ 'aria-label': t.placeholder,
1731
+ 'aria-controls': 'dsh-cmdk-list',
1732
+ 'aria-activedescendant': items.length ? 'dsh-cmdk-opt-' + active : undefined,
1733
+ spellCheck: false,
1734
+ autoComplete: 'off',
1735
+ }),
1736
+ query
1737
+ ? h(
1738
+ 'button',
1739
+ {
1740
+ type: 'button',
1741
+ className: 'dsh-cmdk-clear',
1742
+ 'aria-label': t.clear,
1743
+ onClick: () => {
1744
+ setQuery('');
1745
+ setIndex(0);
1746
+ if (inputRef.current) inputRef.current.focus({ preventScroll: true });
1747
+ },
1748
+ style: {
1749
+ flex: '0 0 auto',
1750
+ width: 22,
1751
+ height: 22,
1752
+ display: 'inline-flex',
1753
+ alignItems: 'center',
1754
+ justifyContent: 'center',
1755
+ padding: 0,
1756
+ border: 'none',
1757
+ borderRadius: 6,
1758
+ background: 'transparent',
1759
+ color: C.sub,
1760
+ cursor: 'pointer',
1761
+ transition: 'color 120ms ease',
1762
+ },
1763
+ },
1764
+ h(Icon, { name: 'x', size: 14 }),
1765
+ )
1766
+ : null,
1767
+ ),
1768
+ h(Kbd, null, 'esc'),
1769
+ );
1770
+ }
1771
+
1772
+ var statusKind = status && status.indexOf(t.failed) === 0 ? 'err' : 'ok';
1773
+ var footerLeft;
1774
+ if (status) {
1775
+ footerLeft = h(
1776
+ 'span',
1777
+ {
1778
+ style: {
1779
+ display: 'inline-flex',
1780
+ alignItems: 'center',
1781
+ gap: 7,
1782
+ minWidth: 0,
1783
+ overflow: 'hidden',
1784
+ color: statusKind === 'err' ? C.err : C.ok,
1785
+ fontWeight: 500,
1786
+ textOverflow: 'ellipsis',
1787
+ whiteSpace: 'nowrap',
1788
+ },
1789
+ },
1790
+ h('span', {
1791
+ style: {
1792
+ flex: '0 0 auto',
1793
+ width: 6,
1794
+ height: 6,
1795
+ borderRadius: 3,
1796
+ background: 'currentColor',
1797
+ },
1798
+ }),
1799
+ status,
1800
+ );
1801
+ } else if (busy) {
1802
+ footerLeft = h(
1803
+ 'span',
1804
+ {
1805
+ style: {
1806
+ display: 'inline-flex',
1807
+ alignItems: 'center',
1808
+ gap: 7,
1809
+ color: C.brand,
1810
+ },
1811
+ },
1812
+ h('span', {
1813
+ style: {
1814
+ width: 11,
1815
+ height: 11,
1816
+ borderRadius: 6,
1817
+ border: '1.6px solid ' + mix(C.brand, 35),
1818
+ borderTopColor: C.brand,
1819
+ animation: 'dsh-cmdk-spin .7s linear infinite',
1820
+ },
1821
+ }),
1822
+ t.searching,
1823
+ );
1824
+ } else {
1825
+ var hints;
1826
+ if (!items.length) {
1827
+ hints = [['esc', t.hintClose]];
1828
+ } else if (current) {
1829
+ hints = [
1830
+ ['↵', t.hintRun],
1831
+ ['←', t.hintBack],
1832
+ ['esc', t.hintClose],
1833
+ ];
1834
+ } else {
1835
+ hints = [
1836
+ ['↑↓', t.hintSelect],
1837
+ ['↵', t.hintOpen],
1838
+ ['→', t.hintActions],
1839
+ ['esc', t.hintClose],
1840
+ ];
1841
+ }
1842
+ footerLeft = h(Hints, { items: hints });
1843
+ }
1844
+
1845
+ var tree = h(
1846
+ 'div',
1847
+ {
1848
+ className: 'dsh-cmdk-scrim',
1849
+ style: {
1850
+ position: 'fixed',
1851
+ inset: 0,
1852
+ zIndex: 60,
1853
+ display: 'flex',
1854
+ justifyContent: 'center',
1855
+ alignItems: 'flex-start',
1856
+ padding: 'clamp(48px, 12vh, 120px) 20px 20px',
1857
+ boxSizing: 'border-box',
1858
+ background: 'color-mix(in srgb, #000 36%, transparent)',
1859
+ animation: 'dsh-cmdk-fade 140ms ease-out',
1860
+ },
1861
+ onMouseDown: (event) => {
1862
+ if (event.target === event.currentTarget) close();
1863
+ },
1864
+ },
1865
+ h(
1866
+ 'div',
1867
+ {
1868
+ role: 'dialog',
1869
+ 'aria-modal': 'true',
1870
+ 'aria-label': t.palette,
1871
+ className: 'dsh-cmdk-panel',
1872
+ ref: panelRef,
1873
+ tabIndex: -1,
1874
+ onKeyDown: onKeyDown,
1875
+ style: {
1876
+ position: 'relative',
1877
+ width: 'min(680px, calc(100vw - 40px))',
1878
+ maxHeight: 'min(72vh, 720px)',
1879
+ display: 'flex',
1880
+ flexDirection: 'column',
1881
+ boxSizing: 'border-box',
1882
+ background: C.overlay,
1883
+ color: C.text,
1884
+ border: '1px solid ' + mix(C.lineStrong, 72),
1885
+ borderRadius: 16,
1886
+ boxShadow:
1887
+ '0 0 0 1px ' +
1888
+ mix(C.text, 4) +
1889
+ ' inset, 0 32px 80px -18px rgba(0,0,0,.6), 0 12px 28px -14px rgba(0,0,0,.45)',
1890
+ overflow: 'hidden',
1891
+ outline: 'none',
1892
+ fontFamily: 'inherit',
1893
+ animation: 'dsh-cmdk-in 180ms cubic-bezier(.16,1,.3,1)',
1894
+ },
1895
+ },
1896
+ h('style', null, PANEL_CSS),
1897
+ h('div', {
1898
+ 'aria-hidden': 'true',
1899
+ style: {
1900
+ position: 'absolute',
1901
+ left: 0,
1902
+ right: 0,
1903
+ top: 0,
1904
+ height: 110,
1905
+ pointerEvents: 'none',
1906
+ background:
1907
+ 'radial-gradient(120% 100% at 50% -30%, ' + mix(C.brand, 12) + ', transparent 72%)',
1908
+ },
1909
+ }),
1910
+ h('div', {
1911
+ 'aria-hidden': 'true',
1912
+ style: {
1913
+ position: 'absolute',
1914
+ top: 0,
1915
+ left: '12%',
1916
+ right: '12%',
1917
+ height: 1,
1918
+ zIndex: 3,
1919
+ pointerEvents: 'none',
1920
+ background:
1921
+ 'linear-gradient(90deg, transparent, ' + mix(C.brand, 55) + ', transparent)',
1922
+ },
1923
+ }),
1924
+ header,
1925
+ h(
1926
+ 'div',
1927
+ {
1928
+ id: 'dsh-cmdk-list',
1929
+ role: 'listbox',
1930
+ 'aria-label': input ? input.title : t.resultsLabel,
1931
+ className: 'dsh-cmdk-scroll',
1932
+ ref: listRef,
1933
+ onScroll: syncScrollFade,
1934
+ style: {
1935
+ overflowY: 'auto',
1936
+ flex: 1,
1937
+ minHeight: 0,
1938
+ padding: '4px 8px 10px',
1939
+ WebkitMaskImage: canFade
1940
+ ? 'linear-gradient(to bottom, #000 calc(100% - 26px), transparent)'
1941
+ : undefined,
1942
+ maskImage: canFade
1943
+ ? 'linear-gradient(to bottom, #000 calc(100% - 26px), transparent)'
1944
+ : undefined,
1945
+ },
1946
+ },
1947
+ input
1948
+ ? null
1949
+ : items.length
1950
+ ? rows
1951
+ : catalog.loading
1952
+ ? h(Skeleton)
1953
+ : h(EmptyState, { t: t, query: query }),
1954
+ ),
1955
+ h(
1956
+ 'div',
1957
+ {
1958
+ style: {
1959
+ display: 'flex',
1960
+ alignItems: 'center',
1961
+ justifyContent: 'space-between',
1962
+ gap: 12,
1963
+ padding: '8px 14px',
1964
+ borderTop: '1px solid ' + mix(C.lineStrong, 50),
1965
+ background: mix(C.layerAlt, 34),
1966
+ fontSize: 11,
1967
+ color: C.sub,
1968
+ minHeight: 37,
1969
+ boxSizing: 'border-box',
1970
+ },
1971
+ },
1972
+ h(
1973
+ 'span',
1974
+ {
1975
+ role: 'status',
1976
+ 'aria-live': 'polite',
1977
+ 'aria-atomic': 'true',
1978
+ style: {
1979
+ position: 'absolute',
1980
+ width: 1,
1981
+ height: 1,
1982
+ padding: 0,
1983
+ margin: -1,
1984
+ overflow: 'hidden',
1985
+ clip: 'rect(0 0 0 0)',
1986
+ whiteSpace: 'nowrap',
1987
+ border: 0,
1988
+ },
1989
+ },
1990
+ !input && query && !catalog.loading ? items.length + ' ' + t.results : '',
1991
+ ),
1992
+ footerLeft,
1993
+ h(
1994
+ 'span',
1995
+ {
1996
+ style: {
1997
+ flex: '0 0 auto',
1998
+ fontFamily: MONO,
1999
+ fontSize: 10.5,
2000
+ fontVariantNumeric: 'tabular-nums',
2001
+ color: mix(C.sub, 80),
2002
+ },
2003
+ },
2004
+ items.length ? active + 1 + ' / ' + items.length : '',
2005
+ ),
2006
+ ),
2007
+ ),
2008
+ );
2009
+ return tree;
2010
+ }
2011
+
2012
+ function renderRow(entry, active, onRun, onActions, onHover, position, moreLabel, query) {
2013
+ return h(
2014
+ 'div',
2015
+ {
2016
+ key: entry.key,
2017
+ id: 'dsh-cmdk-opt-' + position,
2018
+ role: 'option',
2019
+ 'aria-selected': active ? 'true' : 'false',
2020
+ onClick: onRun,
2021
+ onMouseEnter: onHover,
2022
+ onDoubleClick: onActions,
2023
+ style: {
2024
+ display: 'flex',
2025
+ alignItems: 'center',
2026
+ gap: 11,
2027
+ margin: '1px 0',
2028
+ padding: '7px 10px',
2029
+ borderRadius: 10,
2030
+ cursor: 'pointer',
2031
+ scrollMarginTop: 30,
2032
+ scrollMarginBottom: 30,
2033
+ background: active ? mix(C.brand, 11, C.layerAlt) : 'transparent',
2034
+ boxShadow: active ? 'inset 0 0 0 1px ' + mix(C.brand, 20) : 'none',
2035
+ transition: 'background 110ms ease, box-shadow 110ms ease',
2036
+ outline: 'none',
2037
+ },
2038
+ },
2039
+ h(IconTile, { name: iconForEntry(entry), active: active, dot: entry.dot }),
2040
+ h(
2041
+ 'div',
2042
+ { style: { minWidth: 0, flex: 1, display: 'flex', flexDirection: 'column', gap: 2 } },
2043
+ h(
2044
+ 'div',
2045
+ {
2046
+ style: {
2047
+ fontSize: 13.5,
2048
+ fontWeight: 500,
2049
+ color: C.text,
2050
+ letterSpacing: '-.005em',
2051
+ overflow: 'hidden',
2052
+ textOverflow: 'ellipsis',
2053
+ whiteSpace: 'nowrap',
2054
+ },
2055
+ },
2056
+ h(Highlight, { text: entry.title, query: query }),
2057
+ ),
2058
+ entry.sub
2059
+ ? h(
2060
+ 'div',
2061
+ {
2062
+ style: {
2063
+ fontSize: 11.5,
2064
+ color: C.sub,
2065
+ overflow: 'hidden',
2066
+ textOverflow: 'ellipsis',
2067
+ whiteSpace: 'nowrap',
2068
+ },
2069
+ },
2070
+ h(Highlight, { text: entry.sub, query: query }),
2071
+ )
2072
+ : null,
2073
+ ),
2074
+ active ? h(Kbd, null, '↵') : null,
2075
+ entry.actions
2076
+ ? h(
2077
+ 'button',
2078
+ {
2079
+ type: 'button',
2080
+ className: 'dsh-cmdk-more',
2081
+ title: moreLabel,
2082
+ 'aria-label': moreLabel,
2083
+ tabIndex: -1,
2084
+ onClick: (event) => {
2085
+ event.stopPropagation();
2086
+ onActions();
2087
+ },
2088
+ style: {
2089
+ flex: '0 0 auto',
2090
+ width: 24,
2091
+ height: 24,
2092
+ display: 'inline-flex',
2093
+ alignItems: 'center',
2094
+ justifyContent: 'center',
2095
+ padding: 0,
2096
+ border: 'none',
2097
+ borderRadius: 6,
2098
+ background: 'transparent',
2099
+ color: C.sub,
2100
+ cursor: 'pointer',
2101
+ opacity: active ? 0.95 : 0.45,
2102
+ transition: 'opacity 120ms ease, background 120ms ease, color 120ms ease',
2103
+ },
2104
+ },
2105
+ h(Icon, { name: 'more', size: 15 }),
2106
+ )
2107
+ : null,
2108
+ );
2109
+ }
2110
+
2111
+ function FooterButton(props) {
2112
+ var lang = useLang(props.ctx);
2113
+ var t = copy(lang);
2114
+ var [hover, setHover] = useState(false);
2115
+ return h(
2116
+ 'button',
2117
+ {
2118
+ type: 'button',
2119
+ onClick: () => store.toggle(),
2120
+ title: '⌘K / Ctrl+K',
2121
+ onMouseEnter: () => setHover(true),
2122
+ onMouseLeave: () => setHover(false),
2123
+ style: {
2124
+ display: 'flex',
2125
+ alignItems: 'center',
2126
+ gap: 8,
2127
+ width: '100%',
2128
+ padding: '7px 9px',
2129
+ boxSizing: 'border-box',
2130
+ border: '1px solid ' + (hover ? mix(C.lineStrong, 72) : mix(C.lineStrong, 45)),
2131
+ borderRadius: 9,
2132
+ background: hover ? mix(C.layerAlt, 80) : 'transparent',
2133
+ color: hover ? C.text : C.sub,
2134
+ cursor: 'pointer',
2135
+ fontSize: 12,
2136
+ fontFamily: 'inherit',
2137
+ textAlign: 'left',
2138
+ transition: 'background 120ms ease, border-color 120ms ease, color 120ms ease',
2139
+ },
2140
+ },
2141
+ h(Icon, { name: 'search', size: 14 }),
2142
+ h(
2143
+ 'span',
2144
+ { style: { flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } },
2145
+ t.footer || '搜索',
2146
+ ),
2147
+ h(Kbd, null, '⌘K'),
2148
+ );
2149
+ }
2150
+
2151
+ // ---------------------------------------------------------------------
2152
+ // registration
2153
+ // ---------------------------------------------------------------------
2154
+ var inject = ['slots', 'sessions', 'uiWorkspace', 'workspaces', 'theme', 'locale'];
2155
+
2156
+ var hotkey = false;
2157
+
2158
+ function onKey(event) {
2159
+ var mod = event.metaKey || event.ctrlKey;
2160
+ if (!mod || event.altKey) return;
2161
+ if (String(event.key || '').toLowerCase() !== 'k') return;
2162
+ event.preventDefault();
2163
+ event.stopPropagation();
2164
+ store.toggle();
2165
+ }
2166
+
2167
+ function apply(ctx) {
2168
+ var overlay = ctx.slots.inject('shell.overlay', () =>
2169
+ ctx.slots.register({ name: 'shell.overlay', id: 'dsh-cmdk-panel', order: 500 }, () =>
2170
+ h(Palette, { ctx: ctx }),
2171
+ ),
2172
+ );
2173
+ var button = ctx.slots.inject('sidebar.footer.action', () =>
2174
+ ctx.slots.register({ name: 'sidebar.footer.action', id: 'dsh-cmdk-button', order: 40 }, () =>
2175
+ h(FooterButton, { ctx: ctx }),
2176
+ ),
2177
+ );
2178
+ window.addEventListener('keydown', onKey, true);
2179
+ hotkey = true;
2180
+
2181
+ // Extension point: another plugin can contribute rows.
2182
+ // window.__DSH_CMDK__.register({ id, title, sub, run(ctx) })
2183
+ var api = {
2184
+ version: 1,
2185
+ register: registerCommand,
2186
+ unregister: unregisterCommand,
2187
+ open: () => store.set(true),
2188
+ close: () => store.set(false),
2189
+ };
2190
+ window.__DSH_CMDK__ = api;
2191
+ function onExternal(event) {
2192
+ if (event && event.detail) registerCommand(event.detail);
2193
+ }
2194
+ window.addEventListener('dsh-cmdk:command', onExternal);
2195
+
2196
+ return () => {
2197
+ if (typeof overlay === 'function') overlay();
2198
+ if (typeof button === 'function') button();
2199
+ if (hotkey) window.removeEventListener('keydown', onKey, true);
2200
+ hotkey = false;
2201
+ window.removeEventListener('dsh-cmdk:command', onExternal);
2202
+ if (window.__DSH_CMDK__ === api) delete window.__DSH_CMDK__;
2203
+ };
2204
+ }
2205
+
2206
+ exports.apply = apply;
2207
+ exports.inject = inject;
2208
+ return module.exports;
2209
+ },
2210
+ });