ttyd-mux 0.4.3 → 0.5.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/README.md +98 -0
- package/dist/daemon/toolbar/index.d.ts.map +1 -1
- package/dist/daemon/toolbar/index.js +3 -1
- package/dist/daemon/toolbar/index.js.map +1 -1
- package/dist/daemon/toolbar/styles.d.ts +1 -1
- package/dist/daemon/toolbar/styles.d.ts.map +1 -1
- package/dist/daemon/toolbar/styles.js +181 -0
- package/dist/daemon/toolbar/styles.js.map +1 -1
- package/dist/daemon/toolbar/template.d.ts +1 -1
- package/dist/daemon/toolbar/template.d.ts.map +1 -1
- package/dist/daemon/toolbar/template.js +30 -0
- package/dist/daemon/toolbar/template.js.map +1 -1
- package/dist/toolbar.js +27 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ A CLI tool for managing multiple ttyd+tmux web terminal sessions.
|
|
|
23
23
|
- [Configuration](#configuration--設定)
|
|
24
24
|
- [Architecture](#architecture--アーキテクチャ)
|
|
25
25
|
- [Toolbar Features](#toolbar-features--ツールバー機能)
|
|
26
|
+
- [Notifications](#notifications--通知機能)
|
|
27
|
+
- [Share Links](#share-links--共有リンク)
|
|
26
28
|
- [PWA Support](#pwa-support--pwa-対応)
|
|
27
29
|
- [Caddy Integration](#caddy-integration--caddy-との連携)
|
|
28
30
|
- [Development](#development--開発)
|
|
@@ -73,6 +75,8 @@ That's it! No configuration needed for basic usage.
|
|
|
73
75
|
| **Touch Zoom** | Pinch to resize font / ピンチでフォントサイズ変更 |
|
|
74
76
|
| **Double-tap Enter** | Quick command execution / ダブルタップで Enter |
|
|
75
77
|
| **Scroll Buttons** | Easy scrollback navigation / スクロール用ボタン |
|
|
78
|
+
| **Search** | Find text in terminal scrollback / スクロールバック内検索 |
|
|
79
|
+
| **Push Notifications** | Bell icon for remote alerts / 通知用ベルアイコン |
|
|
76
80
|
|
|
77
81
|
### PC Features / PC 機能
|
|
78
82
|
|
|
@@ -260,6 +264,14 @@ ttyd-mux daemon stop --stop-sessions
|
|
|
260
264
|
| `ttyd-mux list --url` | List with access URLs / URL 表示 |
|
|
261
265
|
| `ttyd-mux attach [name]` | Attach to tmux session directly / tmux に直接接続 |
|
|
262
266
|
|
|
267
|
+
### Share Commands / 共有コマンド
|
|
268
|
+
|
|
269
|
+
| Command | Description |
|
|
270
|
+
|---------|-------------|
|
|
271
|
+
| `ttyd-mux share` | Create read-only share link / 読み取り専用共有リンク作成 |
|
|
272
|
+
| `ttyd-mux share list` | List active shares / アクティブな共有一覧 |
|
|
273
|
+
| `ttyd-mux share revoke <token>` | Revoke a share / 共有を取り消し |
|
|
274
|
+
|
|
263
275
|
### Daemon Control / デーモン制御
|
|
264
276
|
|
|
265
277
|
| Command | Description |
|
|
@@ -443,6 +455,92 @@ In proxy mode, ttyd-mux injects a toolbar for improved input experience:
|
|
|
443
455
|
- **Ctrl+Scroll Zoom**: Mouse wheel with Ctrl key / Ctrl+マウスホイールでサイズ変更
|
|
444
456
|
- **Trackpad Pinch Zoom** (Mac): Two-finger pinch gesture / トラックパッドピンチ
|
|
445
457
|
- **Ctrl+J Toggle**: Show/hide toolbar / ツールバー表示切替
|
|
458
|
+
- **Ctrl+Shift+F**: Open search bar / 検索バーを開く
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Notifications / 通知機能
|
|
463
|
+
|
|
464
|
+
Get notified when something happens in your terminal sessions.
|
|
465
|
+
|
|
466
|
+
ターミナルセッションで何かが起きたときに通知を受け取れます。
|
|
467
|
+
|
|
468
|
+
### Push Notifications / プッシュ通知
|
|
469
|
+
|
|
470
|
+
Receive browser push notifications even when the tab is closed.
|
|
471
|
+
|
|
472
|
+
タブを閉じていてもブラウザのプッシュ通知を受け取れます。
|
|
473
|
+
|
|
474
|
+
**Setup / 設定:**
|
|
475
|
+
1. Click the bell icon (🔔) in the toolbar / ツールバーのベルアイコンをクリック
|
|
476
|
+
2. Allow notifications when prompted / 通知を許可
|
|
477
|
+
3. Notifications are sent on terminal bell (`\a`) / ターミナルベル(`\a`)で通知
|
|
478
|
+
|
|
479
|
+
**Use cases / 活用例:**
|
|
480
|
+
```bash
|
|
481
|
+
# Notify when command completes / コマンド完了時に通知
|
|
482
|
+
long-running-command; echo -e '\a'
|
|
483
|
+
|
|
484
|
+
# Or use bell directly / または直接ベルを使用
|
|
485
|
+
sleep 300 && printf '\a'
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Custom Notification Patterns / カスタム通知パターン
|
|
489
|
+
|
|
490
|
+
Configure patterns to trigger notifications:
|
|
491
|
+
|
|
492
|
+
通知トリガーのパターンを設定:
|
|
493
|
+
|
|
494
|
+
```yaml
|
|
495
|
+
# ~/.config/ttyd-mux/config.yaml
|
|
496
|
+
notifications:
|
|
497
|
+
triggers:
|
|
498
|
+
- type: bell # Terminal bell (default)
|
|
499
|
+
- type: pattern
|
|
500
|
+
pattern: "ERROR|FAILED"
|
|
501
|
+
flags: "i"
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Share Links / 共有リンク
|
|
507
|
+
|
|
508
|
+
Share read-only access to your terminal sessions.
|
|
509
|
+
|
|
510
|
+
ターミナルセッションへの読み取り専用アクセスを共有できます。
|
|
511
|
+
|
|
512
|
+
### Create Share Link / 共有リンク作成
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
# Share current session for 1 hour (default)
|
|
516
|
+
# 現在のセッションを1時間共有(デフォルト)
|
|
517
|
+
ttyd-mux share
|
|
518
|
+
|
|
519
|
+
# Share specific session for 24 hours
|
|
520
|
+
# 特定のセッションを24時間共有
|
|
521
|
+
ttyd-mux share my-session --expires 24h
|
|
522
|
+
|
|
523
|
+
# Share with custom expiry
|
|
524
|
+
# カスタム有効期限で共有
|
|
525
|
+
ttyd-mux share --expires 30m # 30 minutes
|
|
526
|
+
ttyd-mux share --expires 7d # 7 days
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### Manage Shares / 共有の管理
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
# List active shares / アクティブな共有一覧
|
|
533
|
+
ttyd-mux share list
|
|
534
|
+
|
|
535
|
+
# Revoke a share / 共有を取り消し
|
|
536
|
+
ttyd-mux share revoke <token>
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Features / 機能
|
|
540
|
+
|
|
541
|
+
- **Read-only**: Viewers can see but not interact / 閲覧のみ、操作不可
|
|
542
|
+
- **Time-limited**: Links expire automatically / 自動的に期限切れ
|
|
543
|
+
- **Revocable**: Cancel access anytime / いつでもアクセス取り消し可能
|
|
446
544
|
|
|
447
545
|
---
|
|
448
546
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAClC,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,aAAsC,GAC7C,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAClC,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,aAAsC,GAC7C,MAAM,CAYR"}
|
|
@@ -34,7 +34,9 @@ export { DEFAULT_TOOLBAR_CONFIG };
|
|
|
34
34
|
* @returns Modified HTML with toolbar injected
|
|
35
35
|
*/
|
|
36
36
|
export function injectToolbar(html, basePath, config = DEFAULT_TOOLBAR_CONFIG) {
|
|
37
|
-
|
|
37
|
+
// Merge basePath into config for client-side use
|
|
38
|
+
const clientConfig = { ...config, base_path: basePath };
|
|
39
|
+
const configScript = `<script>window.__TOOLBAR_CONFIG__ = ${JSON.stringify(clientConfig)};</script>`;
|
|
38
40
|
const injection = `
|
|
39
41
|
<style>${toolbarStyles}</style>
|
|
40
42
|
${toolbarHtml}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,sBAAsB,EAAsB,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5D,sDAAsD;AACtD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAE3D,8BAA8B;AAC9B,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAEtD,oCAAoC;AACpC,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAGlC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,QAAgB,EAChB,SAAwB,sBAAsB;IAE9C,MAAM,YAAY,GAAG,uCAAuC,IAAI,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,sBAAsB,EAAsB,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5D,sDAAsD;AACtD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAE3D,8BAA8B;AAC9B,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAEtD,oCAAoC;AACpC,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAGlC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,QAAgB,EAChB,SAAwB,sBAAsB;IAE9C,iDAAiD;IACjD,MAAM,YAAY,GAAG,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACxD,MAAM,YAAY,GAAG,uCAAuC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;IACrG,MAAM,SAAS,GAAG;SACX,aAAa;EACpB,WAAW;EACX,cAAc,CAAC,OAAO,CAAC,8BAA8B,EAAE,mDAAmD,CAAC;EAC3G,YAAY;eACC,QAAQ;CACtB,CAAC;IACA,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,SAAS,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Terminal Toolbar CSS Styles
|
|
3
3
|
*/
|
|
4
|
-
export declare const toolbarStyles = "\n#ttyd-toolbar {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-top: 2px solid #007acc;\n padding: 8px;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n box-shadow: 0 -2px 10px rgba(0,0,0,0.3);\n}\n\n#ttyd-toolbar.hidden {\n display: none;\n}\n\n#ttyd-toolbar-buttons {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n flex-wrap: wrap;\n}\n\n#ttyd-toolbar-buttons button {\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 13px;\n padding: 8px 12px;\n min-height: 40px;\n min-width: 44px;\n touch-action: manipulation;\n flex-shrink: 0;\n}\n\n#ttyd-toolbar-buttons button:hover, #ttyd-toolbar-buttons button:active {\n background: #4a4a4a;\n}\n\n#ttyd-toolbar-buttons button.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-toolbar-buttons button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-toolbar-buttons button.modifier.active {\n background: #d9534f;\n border-color: #c9302c;\n}\n\n#ttyd-toolbar-send {\n background: #007acc !important;\n border-color: #005a9e !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-send:hover, #ttyd-toolbar-send:active {\n background: #005a9e !important;\n}\n\n#ttyd-toolbar-run {\n background: #28a745 !important;\n border-color: #1e7e34 !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-run:hover, #ttyd-toolbar-run:active {\n background: #1e7e34 !important;\n}\n\n#ttyd-toolbar-auto.active {\n background: #f0ad4e !important;\n border-color: #eea236 !important;\n color: #000;\n}\n\n#ttyd-toolbar-scroll.active {\n background: #17a2b8 !important;\n border-color: #138496 !important;\n}\n\n#ttyd-toolbar-input-row {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n}\n\n#ttyd-toolbar-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 8px;\n color: #fff;\n font-family: monospace;\n font-size: 16px;\n padding: 12px;\n outline: none;\n resize: none;\n min-height: 44px;\n max-height: 120px;\n line-height: 1.4;\n}\n\n#ttyd-toolbar-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-toolbar-input::placeholder {\n color: #888;\n}\n\n#ttyd-toolbar-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n background: #007acc;\n border: 2px solid #005a9e;\n border-radius: 50%;\n color: #fff;\n cursor: pointer;\n font-size: 20px;\n width: 56px;\n height: 56px;\n z-index: 10001;\n touch-action: manipulation;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#ttyd-toolbar-toggle:hover, #ttyd-toolbar-toggle:active {\n background: #005a9e;\n transform: scale(1.05);\n}\n\n#ttyd-toolbar.hidden ~ #ttyd-toolbar-toggle {\n bottom: 16px;\n}\n\n/* Adjust terminal height when toolbar is visible */\nbody:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 140px) !important;\n}\n\n/* Minimized mode - compact toolbar with input only */\n#ttyd-toolbar.minimized #ttyd-toolbar-buttons {\n display: none;\n}\n\n#ttyd-toolbar.minimized {\n padding: 4px 8px;\n}\n\n#ttyd-toolbar-minimize {\n background: #555 !important;\n border-color: #666 !important;\n font-size: 10px;\n padding: 4px 8px;\n min-width: 32px;\n min-height: 32px;\n}\n\n/* Onboarding tooltip */\n#ttyd-toolbar-onboarding {\n position: fixed;\n bottom: 90px;\n right: 16px;\n background: #333;\n border: 1px solid #007acc;\n border-radius: 8px;\n padding: 12px 16px;\n color: #fff;\n font-size: 13px;\n max-width: 280px;\n z-index: 10002;\n box-shadow: 0 4px 12px rgba(0,0,0,0.4);\n line-height: 1.5;\n}\n\n#ttyd-toolbar-onboarding::after {\n content: '';\n position: absolute;\n bottom: -8px;\n right: 24px;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-top: 8px solid #333;\n}\n\n#ttyd-toolbar-onboarding-close {\n position: absolute;\n top: 4px;\n right: 8px;\n background: none;\n border: none;\n color: #888;\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n#ttyd-toolbar-onboarding-close:hover {\n color: #fff;\n}\n\n#ttyd-toolbar-onboarding ul {\n margin: 8px 0 0 0;\n padding-left: 20px;\n}\n\n#ttyd-toolbar-onboarding li {\n margin: 4px 0;\n}\n\n#ttyd-toolbar-onboarding code {\n background: #444;\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\n}\n\n/* Mobile optimizations */\n@media (max-width: 768px) {\n #ttyd-toolbar {\n padding: 6px;\n }\n\n #ttyd-toolbar-buttons {\n gap: 4px;\n margin-bottom: 6px;\n }\n\n #ttyd-toolbar-buttons button {\n font-size: 12px;\n padding: 6px 10px;\n min-height: 36px;\n min-width: 40px;\n }\n\n #ttyd-toolbar-input {\n font-size: 16px;\n padding: 10px;\n }\n\n #ttyd-toolbar-toggle {\n width: 64px;\n height: 64px;\n font-size: 24px;\n }\n\n body:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 130px) !important;\n }\n\n body:has(#ttyd-toolbar.minimized:not(.hidden)) .xterm {\n height: calc(100vh - 60px) !important;\n }\n\n #ttyd-toolbar-onboarding {\n left: 16px;\n right: 16px;\n max-width: none;\n }\n\n #ttyd-search-bar {\n padding: 6px;\n }\n\n #ttyd-search-input {\n font-size: 14px;\n padding: 8px 10px;\n }\n}\n\n/* Search bar styles */\n#ttyd-search-bar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-bottom: 2px solid #007acc;\n padding: 8px 12px;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n box-shadow: 0 2px 10px rgba(0,0,0,0.3);\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n#ttyd-search-bar.hidden {\n display: none;\n}\n\n#ttyd-search-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n font-family: monospace;\n font-size: 14px;\n padding: 8px 12px;\n outline: none;\n min-width: 100px;\n}\n\n#ttyd-search-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-search-input::placeholder {\n color: #888;\n}\n\n#ttyd-search-count {\n color: #888;\n font-size: 12px;\n white-space: nowrap;\n min-width: 50px;\n text-align: center;\n}\n\n#ttyd-search-bar button {\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 13px;\n padding: 6px 10px;\n min-height: 32px;\n min-width: 32px;\n touch-action: manipulation;\n}\n\n#ttyd-search-bar button:hover,\n#ttyd-search-bar button:active {\n background: #4a4a4a;\n}\n\n#ttyd-search-bar button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-search-bar button.modifier.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-search-close {\n color: #888;\n}\n\n#ttyd-search-close:hover {\n color: #fff;\n}\n\n/* Visual bell effect */\n.xterm.bell-flash {\n animation: bell-flash 100ms ease-out;\n}\n\n@keyframes bell-flash {\n 0% { filter: brightness(1); }\n 50% { filter: brightness(1.5); }\n 100% { filter: brightness(1); }\n}\n";
|
|
4
|
+
export declare const toolbarStyles = "\n#ttyd-toolbar {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-top: 2px solid #007acc;\n padding: 8px;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n box-shadow: 0 -2px 10px rgba(0,0,0,0.3);\n}\n\n#ttyd-toolbar.hidden {\n display: none;\n}\n\n#ttyd-toolbar-buttons {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n flex-wrap: wrap;\n}\n\n#ttyd-toolbar-buttons button {\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 13px;\n padding: 8px 12px;\n min-height: 40px;\n min-width: 44px;\n touch-action: manipulation;\n flex-shrink: 0;\n}\n\n#ttyd-toolbar-buttons button:hover, #ttyd-toolbar-buttons button:active {\n background: #4a4a4a;\n}\n\n#ttyd-toolbar-buttons button.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-toolbar-buttons button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-toolbar-buttons button.modifier.active {\n background: #d9534f;\n border-color: #c9302c;\n}\n\n#ttyd-toolbar-send {\n background: #007acc !important;\n border-color: #005a9e !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-send:hover, #ttyd-toolbar-send:active {\n background: #005a9e !important;\n}\n\n#ttyd-toolbar-run {\n background: #28a745 !important;\n border-color: #1e7e34 !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-run:hover, #ttyd-toolbar-run:active {\n background: #1e7e34 !important;\n}\n\n#ttyd-toolbar-auto.active {\n background: #f0ad4e !important;\n border-color: #eea236 !important;\n color: #000;\n}\n\n#ttyd-toolbar-scroll.active {\n background: #17a2b8 !important;\n border-color: #138496 !important;\n}\n\n#ttyd-toolbar-input-row {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n}\n\n#ttyd-toolbar-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 8px;\n color: #fff;\n font-family: monospace;\n font-size: 16px;\n padding: 12px;\n outline: none;\n resize: none;\n min-height: 44px;\n max-height: 120px;\n line-height: 1.4;\n}\n\n#ttyd-toolbar-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-toolbar-input::placeholder {\n color: #888;\n}\n\n#ttyd-toolbar-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n background: #007acc;\n border: 2px solid #005a9e;\n border-radius: 50%;\n color: #fff;\n cursor: pointer;\n font-size: 20px;\n width: 56px;\n height: 56px;\n z-index: 10001;\n touch-action: manipulation;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#ttyd-toolbar-toggle:hover, #ttyd-toolbar-toggle:active {\n background: #005a9e;\n transform: scale(1.05);\n}\n\n#ttyd-toolbar.hidden ~ #ttyd-toolbar-toggle {\n bottom: 16px;\n}\n\n/* Adjust terminal height when toolbar is visible */\nbody:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 140px) !important;\n}\n\n/* Minimized mode - compact toolbar with input only */\n#ttyd-toolbar.minimized #ttyd-toolbar-buttons {\n display: none;\n}\n\n#ttyd-toolbar.minimized {\n padding: 4px 8px;\n}\n\n#ttyd-toolbar-minimize {\n background: #555 !important;\n border-color: #666 !important;\n font-size: 10px;\n padding: 4px 8px;\n min-width: 32px;\n min-height: 32px;\n}\n\n/* Onboarding tooltip */\n#ttyd-toolbar-onboarding {\n position: fixed;\n bottom: 90px;\n right: 16px;\n background: #333;\n border: 1px solid #007acc;\n border-radius: 8px;\n padding: 12px 16px;\n color: #fff;\n font-size: 13px;\n max-width: 280px;\n z-index: 10002;\n box-shadow: 0 4px 12px rgba(0,0,0,0.4);\n line-height: 1.5;\n}\n\n#ttyd-toolbar-onboarding::after {\n content: '';\n position: absolute;\n bottom: -8px;\n right: 24px;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-top: 8px solid #333;\n}\n\n#ttyd-toolbar-onboarding-close {\n position: absolute;\n top: 4px;\n right: 8px;\n background: none;\n border: none;\n color: #888;\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n#ttyd-toolbar-onboarding-close:hover {\n color: #fff;\n}\n\n#ttyd-toolbar-onboarding ul {\n margin: 8px 0 0 0;\n padding-left: 20px;\n}\n\n#ttyd-toolbar-onboarding li {\n margin: 4px 0;\n}\n\n#ttyd-toolbar-onboarding code {\n background: #444;\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\n}\n\n/* Mobile optimizations */\n@media (max-width: 768px) {\n #ttyd-toolbar {\n padding: 6px;\n }\n\n #ttyd-toolbar-buttons {\n gap: 4px;\n margin-bottom: 6px;\n }\n\n #ttyd-toolbar-buttons button {\n font-size: 12px;\n padding: 6px 10px;\n min-height: 36px;\n min-width: 40px;\n }\n\n #ttyd-toolbar-input {\n font-size: 16px;\n padding: 10px;\n }\n\n #ttyd-toolbar-toggle {\n width: 64px;\n height: 64px;\n font-size: 24px;\n }\n\n body:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 130px) !important;\n }\n\n body:has(#ttyd-toolbar.minimized:not(.hidden)) .xterm {\n height: calc(100vh - 60px) !important;\n }\n\n #ttyd-toolbar-onboarding {\n left: 16px;\n right: 16px;\n max-width: none;\n }\n\n #ttyd-search-bar {\n padding: 6px;\n }\n\n #ttyd-search-input {\n font-size: 14px;\n padding: 8px 10px;\n }\n}\n\n/* Search bar styles */\n#ttyd-search-bar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-bottom: 2px solid #007acc;\n padding: 8px 12px;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n box-shadow: 0 2px 10px rgba(0,0,0,0.3);\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n#ttyd-search-bar.hidden {\n display: none;\n}\n\n#ttyd-search-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n font-family: monospace;\n font-size: 14px;\n padding: 8px 12px;\n outline: none;\n min-width: 100px;\n}\n\n#ttyd-search-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-search-input::placeholder {\n color: #888;\n}\n\n#ttyd-search-count {\n color: #888;\n font-size: 12px;\n white-space: nowrap;\n min-width: 50px;\n text-align: center;\n}\n\n#ttyd-search-bar button {\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 13px;\n padding: 6px 10px;\n min-height: 32px;\n min-width: 32px;\n touch-action: manipulation;\n}\n\n#ttyd-search-bar button:hover,\n#ttyd-search-bar button:active {\n background: #4a4a4a;\n}\n\n#ttyd-search-bar button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-search-bar button.modifier.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-search-close {\n color: #888;\n}\n\n#ttyd-search-close:hover {\n color: #fff;\n}\n\n/* Visual bell effect */\n.xterm.bell-flash {\n animation: bell-flash 100ms ease-out;\n}\n\n@keyframes bell-flash {\n 0% { filter: brightness(1); }\n 50% { filter: brightness(1.5); }\n 100% { filter: brightness(1); }\n}\n\n/* Share modal styles */\n#ttyd-share-modal {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0,0,0,0.7);\n z-index: 10010;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#ttyd-share-modal.hidden {\n display: none;\n}\n\n#ttyd-share-modal-content {\n background: #2d2d2d;\n border-radius: 12px;\n max-width: 400px;\n width: 90%;\n box-shadow: 0 4px 20px rgba(0,0,0,0.5);\n}\n\n#ttyd-share-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid #444;\n font-size: 16px;\n font-weight: bold;\n}\n\n#ttyd-share-modal-close {\n background: none;\n border: none;\n color: #888;\n font-size: 20px;\n cursor: pointer;\n padding: 4px 8px;\n line-height: 1;\n}\n\n#ttyd-share-modal-close:hover {\n color: #fff;\n}\n\n#ttyd-share-modal-body {\n padding: 16px;\n}\n\n#ttyd-share-expiry {\n margin-bottom: 16px;\n}\n\n#ttyd-share-expiry > label {\n display: block;\n margin-bottom: 8px;\n color: #aaa;\n font-size: 14px;\n}\n\n#ttyd-share-expiry-options {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n#ttyd-share-expiry-options label {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 14px;\n}\n\n#ttyd-share-expiry-options input[type=\"radio\"] {\n accent-color: #007acc;\n}\n\n#ttyd-share-create {\n width: 100%;\n background: #007acc;\n border: none;\n border-radius: 8px;\n color: #fff;\n cursor: pointer;\n font-size: 15px;\n font-weight: bold;\n padding: 12px 16px;\n transition: background 0.2s;\n}\n\n#ttyd-share-create:hover {\n background: #005a9e;\n}\n\n#ttyd-share-create:disabled {\n background: #555;\n cursor: not-allowed;\n}\n\n#ttyd-share-create.hidden {\n display: none;\n}\n\n#ttyd-share-result {\n margin-top: 16px;\n}\n\n#ttyd-share-result.hidden {\n display: none;\n}\n\n#ttyd-share-url {\n width: 100%;\n background: #1e1e1e;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n font-family: monospace;\n font-size: 13px;\n padding: 10px;\n margin-bottom: 12px;\n box-sizing: border-box;\n}\n\n#ttyd-share-url:focus {\n outline: none;\n border-color: #007acc;\n}\n\n#ttyd-share-actions {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n#ttyd-share-actions button {\n flex: 1;\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 14px;\n padding: 10px 16px;\n transition: background 0.2s;\n}\n\n#ttyd-share-actions button:hover {\n background: #4a4a4a;\n}\n\n#ttyd-share-warning {\n background: rgba(255, 193, 7, 0.15);\n border: 1px solid rgba(255, 193, 7, 0.3);\n border-radius: 6px;\n color: #ffc107;\n font-size: 12px;\n padding: 10px;\n text-align: center;\n}\n\n/* Mobile adjustments for share modal */\n@media (max-width: 768px) {\n #ttyd-share-modal-content {\n max-width: none;\n width: calc(100% - 32px);\n margin: 16px;\n }\n\n #ttyd-share-expiry-options {\n flex-direction: column;\n gap: 10px;\n }\n}\n";
|
|
5
5
|
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa,kjUAgjBzB,CAAC"}
|
|
@@ -380,5 +380,186 @@ body:has(#ttyd-toolbar:not(.hidden)) .xterm {
|
|
|
380
380
|
50% { filter: brightness(1.5); }
|
|
381
381
|
100% { filter: brightness(1); }
|
|
382
382
|
}
|
|
383
|
+
|
|
384
|
+
/* Share modal styles */
|
|
385
|
+
#ttyd-share-modal {
|
|
386
|
+
position: fixed;
|
|
387
|
+
top: 0;
|
|
388
|
+
left: 0;
|
|
389
|
+
right: 0;
|
|
390
|
+
bottom: 0;
|
|
391
|
+
background: rgba(0,0,0,0.7);
|
|
392
|
+
z-index: 10010;
|
|
393
|
+
display: flex;
|
|
394
|
+
align-items: center;
|
|
395
|
+
justify-content: center;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
#ttyd-share-modal.hidden {
|
|
399
|
+
display: none;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
#ttyd-share-modal-content {
|
|
403
|
+
background: #2d2d2d;
|
|
404
|
+
border-radius: 12px;
|
|
405
|
+
max-width: 400px;
|
|
406
|
+
width: 90%;
|
|
407
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
#ttyd-share-modal-header {
|
|
411
|
+
display: flex;
|
|
412
|
+
justify-content: space-between;
|
|
413
|
+
align-items: center;
|
|
414
|
+
padding: 16px;
|
|
415
|
+
border-bottom: 1px solid #444;
|
|
416
|
+
font-size: 16px;
|
|
417
|
+
font-weight: bold;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
#ttyd-share-modal-close {
|
|
421
|
+
background: none;
|
|
422
|
+
border: none;
|
|
423
|
+
color: #888;
|
|
424
|
+
font-size: 20px;
|
|
425
|
+
cursor: pointer;
|
|
426
|
+
padding: 4px 8px;
|
|
427
|
+
line-height: 1;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
#ttyd-share-modal-close:hover {
|
|
431
|
+
color: #fff;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
#ttyd-share-modal-body {
|
|
435
|
+
padding: 16px;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
#ttyd-share-expiry {
|
|
439
|
+
margin-bottom: 16px;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
#ttyd-share-expiry > label {
|
|
443
|
+
display: block;
|
|
444
|
+
margin-bottom: 8px;
|
|
445
|
+
color: #aaa;
|
|
446
|
+
font-size: 14px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
#ttyd-share-expiry-options {
|
|
450
|
+
display: flex;
|
|
451
|
+
gap: 16px;
|
|
452
|
+
flex-wrap: wrap;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
#ttyd-share-expiry-options label {
|
|
456
|
+
display: flex;
|
|
457
|
+
align-items: center;
|
|
458
|
+
gap: 6px;
|
|
459
|
+
cursor: pointer;
|
|
460
|
+
font-size: 14px;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
#ttyd-share-expiry-options input[type="radio"] {
|
|
464
|
+
accent-color: #007acc;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
#ttyd-share-create {
|
|
468
|
+
width: 100%;
|
|
469
|
+
background: #007acc;
|
|
470
|
+
border: none;
|
|
471
|
+
border-radius: 8px;
|
|
472
|
+
color: #fff;
|
|
473
|
+
cursor: pointer;
|
|
474
|
+
font-size: 15px;
|
|
475
|
+
font-weight: bold;
|
|
476
|
+
padding: 12px 16px;
|
|
477
|
+
transition: background 0.2s;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
#ttyd-share-create:hover {
|
|
481
|
+
background: #005a9e;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
#ttyd-share-create:disabled {
|
|
485
|
+
background: #555;
|
|
486
|
+
cursor: not-allowed;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
#ttyd-share-create.hidden {
|
|
490
|
+
display: none;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
#ttyd-share-result {
|
|
494
|
+
margin-top: 16px;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
#ttyd-share-result.hidden {
|
|
498
|
+
display: none;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
#ttyd-share-url {
|
|
502
|
+
width: 100%;
|
|
503
|
+
background: #1e1e1e;
|
|
504
|
+
border: 1px solid #555;
|
|
505
|
+
border-radius: 6px;
|
|
506
|
+
color: #fff;
|
|
507
|
+
font-family: monospace;
|
|
508
|
+
font-size: 13px;
|
|
509
|
+
padding: 10px;
|
|
510
|
+
margin-bottom: 12px;
|
|
511
|
+
box-sizing: border-box;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
#ttyd-share-url:focus {
|
|
515
|
+
outline: none;
|
|
516
|
+
border-color: #007acc;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
#ttyd-share-actions {
|
|
520
|
+
display: flex;
|
|
521
|
+
gap: 8px;
|
|
522
|
+
margin-bottom: 12px;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
#ttyd-share-actions button {
|
|
526
|
+
flex: 1;
|
|
527
|
+
background: #3a3a3a;
|
|
528
|
+
border: 1px solid #555;
|
|
529
|
+
border-radius: 6px;
|
|
530
|
+
color: #fff;
|
|
531
|
+
cursor: pointer;
|
|
532
|
+
font-size: 14px;
|
|
533
|
+
padding: 10px 16px;
|
|
534
|
+
transition: background 0.2s;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
#ttyd-share-actions button:hover {
|
|
538
|
+
background: #4a4a4a;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
#ttyd-share-warning {
|
|
542
|
+
background: rgba(255, 193, 7, 0.15);
|
|
543
|
+
border: 1px solid rgba(255, 193, 7, 0.3);
|
|
544
|
+
border-radius: 6px;
|
|
545
|
+
color: #ffc107;
|
|
546
|
+
font-size: 12px;
|
|
547
|
+
padding: 10px;
|
|
548
|
+
text-align: center;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/* Mobile adjustments for share modal */
|
|
552
|
+
@media (max-width: 768px) {
|
|
553
|
+
#ttyd-share-modal-content {
|
|
554
|
+
max-width: none;
|
|
555
|
+
width: calc(100% - 32px);
|
|
556
|
+
margin: 16px;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
#ttyd-share-expiry-options {
|
|
560
|
+
flex-direction: column;
|
|
561
|
+
gap: 10px;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
383
564
|
`;
|
|
384
565
|
//# sourceMappingURL=styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgjB5B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Terminal Toolbar HTML Template
|
|
3
3
|
*/
|
|
4
|
-
export declare const toolbarHtml = "\n<div id=\"ttyd-toolbar\" class=\"hidden\">\n <div id=\"ttyd-toolbar-buttons\">\n <button id=\"ttyd-toolbar-ctrl\" class=\"modifier\">Ctrl</button>\n <button id=\"ttyd-toolbar-alt\" class=\"modifier\">Alt</button>\n <button id=\"ttyd-toolbar-shift\" class=\"modifier\">Shift</button>\n <button id=\"ttyd-toolbar-scroll\" class=\"modifier\">Scroll</button>\n <button id=\"ttyd-toolbar-esc\">Esc</button>\n <button id=\"ttyd-toolbar-tab\">Tab</button>\n <button id=\"ttyd-toolbar-up\">\u2191</button>\n <button id=\"ttyd-toolbar-down\">\u2193</button>\n <button id=\"ttyd-toolbar-pageup\">PgUp</button>\n <button id=\"ttyd-toolbar-pagedown\">PgDn</button>\n <button id=\"ttyd-toolbar-enter\">Enter</button>\n <button id=\"ttyd-toolbar-zoomout\">A-</button>\n <button id=\"ttyd-toolbar-zoomin\">A+</button>\n <button id=\"ttyd-toolbar-copy\">Copy</button>\n <button id=\"ttyd-toolbar-copyall\">All</button>\n <button id=\"ttyd-toolbar-search\">\uD83D\uDD0D</button>\n <button id=\"ttyd-toolbar-notify\" title=\"Push\u901A\u77E5\">\uD83D\uDD14</button>\n <button id=\"ttyd-toolbar-send\">Send</button>\n <button id=\"ttyd-toolbar-run\">Run</button>\n <button id=\"ttyd-toolbar-auto\" class=\"modifier\">Auto</button>\n <button id=\"ttyd-toolbar-minimize\">\u25BC</button>\n </div>\n <div id=\"ttyd-toolbar-input-row\">\n <textarea id=\"ttyd-toolbar-input\" rows=\"1\" placeholder=\"\u65E5\u672C\u8A9E\u5165\u529B (Enter: \u9001\u4FE1)\"></textarea>\n </div>\n</div>\n<div id=\"ttyd-search-bar\" class=\"hidden\">\n <input id=\"ttyd-search-input\" type=\"text\" placeholder=\"\u691C\u7D22...\" />\n <span id=\"ttyd-search-count\">0/0</span>\n <button id=\"ttyd-search-prev\" title=\"\u524D\u3078 (Shift+Enter)\">\u25C0</button>\n <button id=\"ttyd-search-next\" title=\"\u6B21\u3078 (Enter)\">\u25B6</button>\n <button id=\"ttyd-search-case\" class=\"modifier\" title=\"\u5927\u6587\u5B57\u5C0F\u6587\u5B57\u3092\u533A\u5225\">Aa</button>\n <button id=\"ttyd-search-regex\" class=\"modifier\" title=\"\u6B63\u898F\u8868\u73FE\">.*</button>\n <button id=\"ttyd-search-close\" title=\"\u9589\u3058\u308B (Esc)\">\u2715</button>\n</div>\n<button id=\"ttyd-toolbar-toggle\">\u2328</button>\n";
|
|
4
|
+
export declare const toolbarHtml = "\n<div id=\"ttyd-toolbar\" class=\"hidden\">\n <div id=\"ttyd-toolbar-buttons\">\n <button id=\"ttyd-toolbar-ctrl\" class=\"modifier\">Ctrl</button>\n <button id=\"ttyd-toolbar-alt\" class=\"modifier\">Alt</button>\n <button id=\"ttyd-toolbar-shift\" class=\"modifier\">Shift</button>\n <button id=\"ttyd-toolbar-scroll\" class=\"modifier\">Scroll</button>\n <button id=\"ttyd-toolbar-esc\">Esc</button>\n <button id=\"ttyd-toolbar-tab\">Tab</button>\n <button id=\"ttyd-toolbar-up\">\u2191</button>\n <button id=\"ttyd-toolbar-down\">\u2193</button>\n <button id=\"ttyd-toolbar-pageup\">PgUp</button>\n <button id=\"ttyd-toolbar-pagedown\">PgDn</button>\n <button id=\"ttyd-toolbar-enter\">Enter</button>\n <button id=\"ttyd-toolbar-zoomout\">A-</button>\n <button id=\"ttyd-toolbar-zoomin\">A+</button>\n <button id=\"ttyd-toolbar-copy\">Copy</button>\n <button id=\"ttyd-toolbar-copyall\">All</button>\n <button id=\"ttyd-toolbar-search\">\uD83D\uDD0D</button>\n <button id=\"ttyd-toolbar-notify\" title=\"Push\u901A\u77E5\">\uD83D\uDD14</button>\n <button id=\"ttyd-toolbar-share\" title=\"\u5171\u6709\u30EA\u30F3\u30AF\">\uD83D\uDD17</button>\n <button id=\"ttyd-toolbar-send\">Send</button>\n <button id=\"ttyd-toolbar-run\">Run</button>\n <button id=\"ttyd-toolbar-auto\" class=\"modifier\">Auto</button>\n <button id=\"ttyd-toolbar-minimize\">\u25BC</button>\n </div>\n <div id=\"ttyd-toolbar-input-row\">\n <textarea id=\"ttyd-toolbar-input\" rows=\"1\" placeholder=\"\u65E5\u672C\u8A9E\u5165\u529B (Enter: \u9001\u4FE1)\"></textarea>\n </div>\n</div>\n<div id=\"ttyd-search-bar\" class=\"hidden\">\n <input id=\"ttyd-search-input\" type=\"text\" placeholder=\"\u691C\u7D22...\" />\n <span id=\"ttyd-search-count\">0/0</span>\n <button id=\"ttyd-search-prev\" title=\"\u524D\u3078 (Shift+Enter)\">\u25C0</button>\n <button id=\"ttyd-search-next\" title=\"\u6B21\u3078 (Enter)\">\u25B6</button>\n <button id=\"ttyd-search-case\" class=\"modifier\" title=\"\u5927\u6587\u5B57\u5C0F\u6587\u5B57\u3092\u533A\u5225\">Aa</button>\n <button id=\"ttyd-search-regex\" class=\"modifier\" title=\"\u6B63\u898F\u8868\u73FE\">.*</button>\n <button id=\"ttyd-search-close\" title=\"\u9589\u3058\u308B (Esc)\">\u2715</button>\n</div>\n<button id=\"ttyd-toolbar-toggle\">\u2328</button>\n<div id=\"ttyd-share-modal\" class=\"hidden\">\n <div id=\"ttyd-share-modal-content\">\n <div id=\"ttyd-share-modal-header\">\n <span>\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u30EA\u30F3\u30AF\u3092\u4F5C\u6210</span>\n <button id=\"ttyd-share-modal-close\">\u00D7</button>\n </div>\n <div id=\"ttyd-share-modal-body\">\n <div id=\"ttyd-share-expiry\">\n <label>\u6709\u52B9\u671F\u9650:</label>\n <div id=\"ttyd-share-expiry-options\">\n <label><input type=\"radio\" name=\"ttyd-share-expiry\" value=\"1h\"> 1\u6642\u9593</label>\n <label><input type=\"radio\" name=\"ttyd-share-expiry\" value=\"24h\" checked> 24\u6642\u9593</label>\n <label><input type=\"radio\" name=\"ttyd-share-expiry\" value=\"7d\"> 7\u65E5</label>\n </div>\n </div>\n <button id=\"ttyd-share-create\">\u30EA\u30F3\u30AF\u3092\u4F5C\u6210</button>\n <div id=\"ttyd-share-result\" class=\"hidden\">\n <input id=\"ttyd-share-url\" type=\"text\" readonly>\n <div id=\"ttyd-share-actions\">\n <button id=\"ttyd-share-copy\">\u30B3\u30D4\u30FC</button>\n <button id=\"ttyd-share-qr\">QR\u30B3\u30FC\u30C9</button>\n </div>\n <div id=\"ttyd-share-warning\">\n \u26A0 \u3053\u306E\u30EA\u30F3\u30AF\u3092\u77E5\u3063\u3066\u3044\u308B\u4EBA\u306F\u8AB0\u3067\u3082\u3053\u306E\u7AEF\u672B\u3092\u95B2\u89A7\u3067\u304D\u307E\u3059\n </div>\n </div>\n </div>\n </div>\n</div>\n";
|
|
5
5
|
export declare const onboardingHtml = "\n<div id=\"ttyd-toolbar-onboarding\">\n <button id=\"ttyd-toolbar-onboarding-close\">\u00D7</button>\n <strong>Toolbar Tips</strong>\n <ul>\n <li><code>Ctrl+J</code> \u3067\u30C4\u30FC\u30EB\u30D0\u30FC\u8868\u793A/\u975E\u8868\u793A</li>\n <li>\u30D4\u30F3\u30C1\u64CD\u4F5C\u3067\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA\u5909\u66F4</li>\n <li>\u30C0\u30D6\u30EB\u30BF\u30C3\u30D7\u3067 Enter \u9001\u4FE1</li>\n <li><code>\u25BC</code> \u3067\u30B3\u30F3\u30D1\u30AF\u30C8\u8868\u793A</li>\n </ul>\n</div>\n";
|
|
6
6
|
//# sourceMappingURL=template.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,yxHAqEvB,CAAC;AAEF,eAAO,MAAM,cAAc,qhBAW1B,CAAC"}
|
|
@@ -21,6 +21,7 @@ export const toolbarHtml = `
|
|
|
21
21
|
<button id="ttyd-toolbar-copyall">All</button>
|
|
22
22
|
<button id="ttyd-toolbar-search">🔍</button>
|
|
23
23
|
<button id="ttyd-toolbar-notify" title="Push通知">🔔</button>
|
|
24
|
+
<button id="ttyd-toolbar-share" title="共有リンク">🔗</button>
|
|
24
25
|
<button id="ttyd-toolbar-send">Send</button>
|
|
25
26
|
<button id="ttyd-toolbar-run">Run</button>
|
|
26
27
|
<button id="ttyd-toolbar-auto" class="modifier">Auto</button>
|
|
@@ -40,6 +41,35 @@ export const toolbarHtml = `
|
|
|
40
41
|
<button id="ttyd-search-close" title="閉じる (Esc)">✕</button>
|
|
41
42
|
</div>
|
|
42
43
|
<button id="ttyd-toolbar-toggle">⌨</button>
|
|
44
|
+
<div id="ttyd-share-modal" class="hidden">
|
|
45
|
+
<div id="ttyd-share-modal-content">
|
|
46
|
+
<div id="ttyd-share-modal-header">
|
|
47
|
+
<span>読み取り専用リンクを作成</span>
|
|
48
|
+
<button id="ttyd-share-modal-close">×</button>
|
|
49
|
+
</div>
|
|
50
|
+
<div id="ttyd-share-modal-body">
|
|
51
|
+
<div id="ttyd-share-expiry">
|
|
52
|
+
<label>有効期限:</label>
|
|
53
|
+
<div id="ttyd-share-expiry-options">
|
|
54
|
+
<label><input type="radio" name="ttyd-share-expiry" value="1h"> 1時間</label>
|
|
55
|
+
<label><input type="radio" name="ttyd-share-expiry" value="24h" checked> 24時間</label>
|
|
56
|
+
<label><input type="radio" name="ttyd-share-expiry" value="7d"> 7日</label>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<button id="ttyd-share-create">リンクを作成</button>
|
|
60
|
+
<div id="ttyd-share-result" class="hidden">
|
|
61
|
+
<input id="ttyd-share-url" type="text" readonly>
|
|
62
|
+
<div id="ttyd-share-actions">
|
|
63
|
+
<button id="ttyd-share-copy">コピー</button>
|
|
64
|
+
<button id="ttyd-share-qr">QRコード</button>
|
|
65
|
+
</div>
|
|
66
|
+
<div id="ttyd-share-warning">
|
|
67
|
+
⚠ このリンクを知っている人は誰でもこの端末を閲覧できます
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
43
73
|
`;
|
|
44
74
|
export const onboardingHtml = `
|
|
45
75
|
<div id="ttyd-toolbar-onboarding">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE1B,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;CAW7B,CAAC"}
|
package/dist/toolbar.js
CHANGED
|
@@ -1,2 +1,27 @@
|
|
|
1
|
-
"use strict";(()=>{var s={FONT_SIZE:"ttyd-toolbar-font-size",ONBOARDING_SHOWN:"ttyd-toolbar-onboarding-shown",AUTO_RUN:"ttyd-toolbar-auto-run",NOTIFY_SUBSCRIPTION:"ttyd-mux-notify-subscription"};var u=class{constructor(){this.active=!1;this.autoBtn=null}bindElement(t){this.autoBtn=t,this.restore()}isActive(){return this.active}toggle(){return this.active=!this.active,this.autoBtn?.classList.toggle("active",this.active),this.save(),this.active}save(){try{localStorage.setItem(s.AUTO_RUN,this.active?"1":"0")}catch(t){console.warn("[Toolbar] Failed to save auto-run state:",t)}}restore(){try{localStorage.getItem(s.AUTO_RUN)==="1"&&(this.active=!0,this.autoBtn?.classList.add("active"),console.log("[Toolbar] Restored auto-run mode: enabled"))}catch(t){console.warn("[Toolbar] Failed to load auto-run state:",t)}}};var m=class{constructor(t){this.config=t}save(t){try{localStorage.setItem(s.FONT_SIZE,String(t))}catch(e){console.warn("[Toolbar] Failed to save font size:",e)}}load(){let e=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?this.config.font_size_default_mobile:this.config.font_size_default_pc;try{let n=localStorage.getItem(s.FONT_SIZE);if(n){let i=parseInt(n,10);if(!isNaN(i)&&i>=this.config.font_size_min&&i<=this.config.font_size_max)return i}}catch(n){console.warn("[Toolbar] Failed to load font size:",n)}return e}};var f=class{constructor(t,e){this.ws=t,this.modifiers=e}sendKey(t){if(this.modifiers.isCtrlActive()&&t.length===1){let e=t.toUpperCase().charCodeAt(0)-64;e>0&&e<32&&this.ws.sendBytes([e]),this.modifiers.resetCtrlAlt()}else if(this.modifiers.isAltActive()&&t.length===1){let e=t.charCodeAt(0);this.ws.sendBytes([27,e]),this.modifiers.resetCtrlAlt()}else this.ws.sendText(t)}sendEnter(){this.ws.sendBytes([13])}sendEsc(){this.ws.sendBytes([27])}sendTab(){this.ws.sendBytes([9])}sendArrow(t){let e={up:[27,91,65],down:[27,91,66],right:[27,91,67],left:[27,91,68]};this.ws.sendBytes(e[t])}sendPage(t){t==="up"?this.ws.sendBytes([27,91,53,126]):this.ws.sendBytes([27,91,54,126])}sendText(t){return this.ws.sendText(t)}};var p=class{constructor(){this.ctrlActive=!1;this.altActive=!1;this.shiftActive=!1;this.ctrlBtn=null;this.altBtn=null;this.shiftBtn=null}bindElements(t,e,n){this.ctrlBtn=t,this.altBtn=e,this.shiftBtn=n}isCtrlActive(){return this.ctrlActive}isAltActive(){return this.altActive}isShiftActive(){return this.shiftActive}toggle(t){switch(t){case"ctrl":return this.ctrlActive=!this.ctrlActive,this.ctrlBtn?.classList.toggle("active",this.ctrlActive),this.ctrlActive&&(this.altActive=!1,this.altBtn?.classList.remove("active")),this.ctrlActive;case"alt":return this.altActive=!this.altActive,this.altBtn?.classList.toggle("active",this.altActive),this.altActive&&(this.ctrlActive=!1,this.ctrlBtn?.classList.remove("active")),this.altActive;case"shift":return this.shiftActive=!this.shiftActive,this.shiftBtn?.classList.toggle("active",this.shiftActive),this.shiftActive}}resetCtrlAlt(){this.ctrlActive=!1,this.altActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active")}reset(){this.ctrlActive=!1,this.altActive=!1,this.shiftActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active"),this.shiftBtn?.classList.remove("active")}};var v=class{constructor(){this.subscribed=!1;this.subscriptionId=null;this.notifyBtn=null;this.loadSubscription()}bindElement(t){this.notifyBtn=t,this.updateButton()}getBasePath(){return"/"+(window.location.pathname.split("/")[1]||"ttyd-mux")}getSessionName(){return window.location.pathname.split("/")[2]||""}urlBase64ToUint8Array(t){let e="=".repeat((4-t.length%4)%4),n=(t+e).replace(/-/g,"+").replace(/_/g,"/"),i=atob(n),o=new Uint8Array(i.length);for(let r=0;r<i.length;++r)o[r]=i.charCodeAt(r);return o}loadSubscription(){try{let t=localStorage.getItem(s.NOTIFY_SUBSCRIPTION);if(t){let e=JSON.parse(t);this.subscriptionId=e.id,this.subscribed=!0,console.log("[Toolbar] Loaded notification subscription: "+e.id)}}catch(t){console.warn("[Toolbar] Failed to load notification subscription:",t)}}saveSubscription(t){try{localStorage.setItem(s.NOTIFY_SUBSCRIPTION,JSON.stringify({id:t}))}catch(e){console.warn("[Toolbar] Failed to save notification subscription:",e)}}clearSubscription(){try{localStorage.removeItem(s.NOTIFY_SUBSCRIPTION)}catch(t){console.warn("[Toolbar] Failed to clear notification subscription:",t)}}updateButton(){this.notifyBtn&&(this.subscribed?(this.notifyBtn.classList.add("active"),this.notifyBtn.textContent="\u{1F514}",this.notifyBtn.title="Push\u901A\u77E5: ON (\u30AF\u30EA\u30C3\u30AF\u3067\u89E3\u9664)"):(this.notifyBtn.classList.remove("active"),this.notifyBtn.textContent="\u{1F515}",this.notifyBtn.title="Push\u901A\u77E5: OFF (\u30AF\u30EA\u30C3\u30AF\u3067\u6709\u52B9\u5316)"))}isSubscribed(){return this.subscribed}async subscribe(){let t=this.getBasePath(),e=this.getSessionName();try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){alert("\u3053\u306E\u30D6\u30E9\u30A6\u30B6\u306FPush\u901A\u77E5\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u305B\u3093");return}if(await Notification.requestPermission()!=="granted"){alert("\u901A\u77E5\u306E\u8A31\u53EF\u304C\u5FC5\u8981\u3067\u3059");return}let i=await fetch(t+"/api/notifications/vapid-key");if(!i.ok)throw new Error("VAPID key fetch failed");let{publicKey:o}=await i.json(),l=await(await navigator.serviceWorker.ready).pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.urlBase64ToUint8Array(o)}),d=l.getKey("p256dh"),E=l.getKey("auth");if(!d||!E)throw new Error("Failed to get subscription keys");let h=await fetch(t+"/api/notifications/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:l.endpoint,keys:{p256dh:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(d)))),auth:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(E))))},sessionName:e||void 0})});if(!h.ok)throw new Error("Subscription failed");let y=await h.json();this.subscriptionId=y.id,this.subscribed=!0,this.saveSubscription(y.id),this.updateButton(),console.log("[Toolbar] Push notification subscribed: "+y.id)}catch(n){console.error("[Toolbar] Push notification subscription failed:",n),alert("Push\u901A\u77E5\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F: "+n.message)}}async unsubscribe(){let t=this.getBasePath();try{this.subscriptionId&&await fetch(t+"/api/notifications/subscribe/"+encodeURIComponent(this.subscriptionId),{method:"DELETE"});let n=await(await navigator.serviceWorker.ready).pushManager.getSubscription();n&&await n.unsubscribe(),this.subscribed=!1,this.subscriptionId=null,this.clearSubscription(),this.updateButton(),console.log("[Toolbar] Push notification unsubscribed")}catch(e){console.error("[Toolbar] Push notification unsubscribe failed:",e)}}async toggle(){this.subscribed?await this.unsubscribe():await this.subscribe()}};var M="https://cdn.jsdelivr.net/npm/@xterm/addon-search@0.15.0/lib/addon-search.min.js",g=class{constructor(t){this.searchAddon=null;this.caseSensitive=!1;this.regex=!1;this.currentMatchIndex=0;this.totalMatches=0;this.searchBar=null;this.searchInput=null;this.searchCount=null;this.searchCaseBtn=null;this.searchRegexBtn=null;this.findTerminal=t}bindElements(t,e,n,i,o){this.searchBar=t,this.searchInput=e,this.searchCount=n,this.searchCaseBtn=i,this.searchRegexBtn=o}loadAddon(){if(this.searchAddon)return Promise.resolve(this.searchAddon);if(window.SearchAddon){let t=this.findTerminal();if(t)return this.searchAddon=new window.SearchAddon.SearchAddon,t.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded"),Promise.resolve(this.searchAddon)}return new Promise((t,e)=>{let n=document.createElement("script");n.src=M,n.onload=()=>{let i=this.findTerminal();i&&window.SearchAddon?(this.searchAddon=new window.SearchAddon.SearchAddon,i.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded from CDN"),t(this.searchAddon)):e(new Error("Failed to initialize SearchAddon"))},n.onerror=()=>{e(new Error("Failed to load SearchAddon"))},document.head.appendChild(n)})}toggle(t){this.searchBar&&(typeof t=="boolean"?this.searchBar.classList.toggle("hidden",!t):this.searchBar.classList.toggle("hidden"),this.searchBar.classList.contains("hidden")?(this.searchAddon?.clearDecorations&&this.searchAddon.clearDecorations(),this.updateMatchCount(0,0),document.querySelector(".xterm-helper-textarea")?.focus()):this.loadAddon().then(()=>{this.searchInput?.focus(),this.searchInput?.select()}).catch(e=>{console.error("[Toolbar] Failed to load search:",e)}))}updateMatchCount(t,e){this.currentMatchIndex=t,this.totalMatches=e,this.searchCount&&(this.searchCount.textContent=e===0?"0/0":`${t}/${e}`)}countMatches(t){if(!this.searchAddon||!t){this.updateMatchCount(0,0);return}let e=this.findTerminal();if(!e?.buffer?.active){this.updateMatchCount(0,0);return}let n=e.buffer.active,i=this.caseSensitive?"g":"gi",o=0,r;try{r=this.regex?new RegExp(t,i):new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i)}catch{this.updateMatchCount(0,0);return}for(let l=0;l<n.length;l++){let d=n.getLine(l);if(d){let h=d.translateToString(!0).match(r);h&&(o+=h.length)}}this.updateMatchCount(this.currentMatchIndex,o)}findNext(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex,incremental:!1},e=this.searchAddon.findNext(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.min(this.currentMatchIndex+1,this.totalMatches),this.currentMatchIndex>this.totalMatches&&(this.currentMatchIndex=1),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}findPrevious(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex},e=this.searchAddon.findPrevious(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.max(this.currentMatchIndex-1,1),this.currentMatchIndex<1&&(this.currentMatchIndex=this.totalMatches),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}doSearch(){let t=this.searchInput?.value;if(!t){this.updateMatchCount(0,0);return}this.loadAddon().then(()=>{this.countMatches(t),this.currentMatchIndex=0,this.findNext()})}toggleCaseSensitive(){return this.caseSensitive=!this.caseSensitive,this.searchCaseBtn?.classList.toggle("active",this.caseSensitive),this.doSearch(),this.caseSensitive}toggleRegex(){return this.regex=!this.regex,this.searchRegexBtn?.classList.toggle("active",this.regex),this.doSearch(),this.regex}isVisible(){return this.searchBar?!this.searchBar.classList.contains("hidden"):!1}};var b=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}getDefaultFontSize(){return this.isMobile?this.config.font_size_default_mobile:this.config.font_size_default_pc}findTerminal(){if(window.term)return window.term;let t=document.querySelector(".xterm");return t&&t._core?t._core:null}fitTerminal(){if(window.fitAddon&&typeof window.fitAddon.fit=="function"){window.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via fitAddon");return}let t=window.term;if(t&&t.fitAddon&&typeof t.fitAddon.fit=="function"){t.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via term.fitAddon");return}window.dispatchEvent(new Event("resize")),console.log("[Toolbar] Dispatched resize event")}getCurrentFontSize(){let t=this.findTerminal();return t?.options?t.options.fontSize??this.getDefaultFontSize():this.getDefaultFontSize()}setFontSize(t){let e=this.findTerminal();if(!e?.options)return console.log("[Toolbar] Terminal not found for zoom"),!1;let n=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,t));return e.options.fontSize=n,this.fitTerminal(),console.log("[Toolbar] Font size changed to "+n),!0}zoomTerminal(t){let e=this.getCurrentFontSize();return this.setFontSize(e+t)}copySelection(){let t=this.findTerminal();if(!t)return console.log("[Toolbar] Terminal not found for copy"),Promise.resolve(!1);let e=t.getSelection();return e?navigator.clipboard.writeText(e).then(()=>(console.log("[Toolbar] Copied selection to clipboard"),!0)).catch(n=>(console.error("[Toolbar] Failed to copy:",n),!1)):(console.log("[Toolbar] No text selected"),Promise.resolve(!1))}copyAll(){let t=this.findTerminal();if(!t?.buffer?.active)return console.log("[Toolbar] Terminal buffer not found"),Promise.resolve(!1);let e=t.buffer.active,n=[];for(let o=0;o<e.length;o++){let r=e.getLine(o);r&&n.push(r.translateToString(!0))}let i=n.join(`
|
|
2
|
-
`).trimEnd();return navigator.clipboard.writeText(i).then(()=>(console.log("[Toolbar] Copied all text to clipboard"),!0)).catch(o=>(console.error("[Toolbar] Failed to copy:",o),!1))}setupBellHandler(t){let e=this.findTerminal();if(!e?.onBell){setTimeout(()=>this.setupBellHandler(t),500);return}e.onBell(()=>{console.log("[Toolbar] Bell detected (visual feedback)"),t();let n=e.element;n&&(n.classList.add("bell-flash"),setTimeout(()=>{n.classList.remove("bell-flash")},100))}),console.log("[Toolbar] Visual bell handler registered")}};var T=class{constructor(t,e,n,i){this.touchStartPos=null;this.shiftTouchActive=!1;this.scrollTouchActive=!1;this.scrollLastY=0;this.pinchStartDistance=0;this.lastTapTime=0;this.scrollActive=!1;this.scrollBtn=null;this.config=t,this.terminal=e,this.input=n,this.modifiers=i,this.pinchStartFontSize=e.getDefaultFontSize()}bindScrollButton(t){this.scrollBtn=t}toggleScrollMode(){return this.scrollActive=!this.scrollActive,this.scrollBtn?.classList.toggle("active",this.scrollActive),this.scrollActive?console.log("[Toolbar] Scroll mode enabled - drag to scroll"):console.log("[Toolbar] Scroll mode disabled"),this.scrollActive}isScrollActive(){return this.scrollActive}setup(){this.setupShiftMouseInjection(),this.setupTouchSelection(),this.setupPinchZoom(),this.setupWheelZoom(),this.setupDoubleTap()}setupShiftMouseInjection(){let t=["mousedown","mousemove","mouseup"];for(let e of t)document.addEventListener(e,n=>{if(!(n.target.closest("#ttyd-toolbar")||n.target.closest("#ttyd-toolbar-toggle"))&&this.modifiers.isShiftActive()&&!n.shiftKey){let i=new MouseEvent(n.type,{bubbles:n.bubbles,cancelable:n.cancelable,view:n.view,detail:n.detail,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:!0,metaKey:n.metaKey,button:n.button,buttons:n.buttons,relatedTarget:n.relatedTarget});n.stopImmediatePropagation(),n.preventDefault(),n.target.dispatchEvent(i)}},!0)}dispatchMouseEvent(t,e,n){let i=new MouseEvent(t,{bubbles:!0,cancelable:!0,view:window,detail:1,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,ctrlKey:!1,altKey:!1,shiftKey:n,metaKey:!1,button:0,buttons:t==="mouseup"?0:1,relatedTarget:null});e.target.dispatchEvent(i)}setupTouchSelection(){document.addEventListener("touchstart",t=>{let e=t.target;if(!(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle"))){if(t.touches.length===1&&this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.scrollLastY=n.clientY,this.scrollTouchActive=!0,t.preventDefault()}else if(t.touches.length===1&&this.modifiers.isShiftActive()){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.shiftTouchActive=!0,t.preventDefault(),this.dispatchMouseEvent("mousedown",n,!0)}else if(t.touches.length===2&&(this.shiftTouchActive||this.scrollTouchActive))this.shiftTouchActive&&this.dispatchMouseEvent("mouseup",t.touches[0],!0),this.shiftTouchActive=!1,this.scrollTouchActive=!1,this.touchStartPos=null;else if(t.touches.length===1&&!this.modifiers.isShiftActive()&&!this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY}}}},{passive:!1,capture:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===1&&this.scrollTouchActive){t.preventDefault();let e=t.touches[0],n=this.scrollLastY-e.clientY;Math.abs(n)>=30&&(n>0?this.input.sendPage("down"):this.input.sendPage("up"),this.scrollLastY=e.clientY)}else t.touches.length===1&&this.shiftTouchActive&&(t.preventDefault(),this.dispatchMouseEvent("mousemove",t.touches[0],!0))},{passive:!1,capture:!0}),document.addEventListener("touchend",t=>{if(this.scrollTouchActive&&t.touches.length===0)this.scrollTouchActive=!1,this.touchStartPos=null;else if(this.shiftTouchActive&&t.touches.length===0){let e=t.changedTouches[0];this.dispatchMouseEvent("mouseup",e,!0),this.shiftTouchActive=!1,this.touchStartPos=null}},{passive:!0,capture:!0})}getTouchDistance(t){let e=t[0].clientX-t[1].clientX,n=t[0].clientY-t[1].clientY;return Math.sqrt(e*e+n*n)}setupPinchZoom(){document.addEventListener("touchstart",t=>{t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&(this.pinchStartDistance=this.getTouchDistance(t.touches),this.pinchStartFontSize=this.terminal.getCurrentFontSize())},{passive:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&this.pinchStartDistance>0){t.preventDefault();let n=this.getTouchDistance(t.touches)/this.pinchStartDistance,i=Math.round(this.pinchStartFontSize*n),o=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,i));this.terminal.getCurrentFontSize()!==o&&this.terminal.setFontSize(o)}},{passive:!1}),document.addEventListener("touchend",t=>{t.touches.length<2&&(this.pinchStartDistance=0)},{passive:!0})}setupWheelZoom(){document.addEventListener("wheel",t=>{if(t.ctrlKey){t.preventDefault();let e=t.deltaY>0?-2:2;this.terminal.zoomTerminal(e)}},{passive:!1})}setupDoubleTap(){document.addEventListener("touchend",t=>{let e=t.target;if(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle")||t.changedTouches.length!==1)return;let n=Date.now();n-this.lastTapTime<this.config.double_tap_delay?(this.input.sendEnter(),this.lastTapTime=0):this.lastTapTime=n},{passive:!0})}};var c=window.WebSocket,B=class{constructor(){this.ws=null;this.interceptWebSocketCreation()}interceptWebSocketCreation(){let t=this;window.WebSocket=function(e,n){let i=new c(e,n);return e.includes("/ws")&&(t.ws=i),i},window.WebSocket.prototype=c.prototype,Object.defineProperty(window.WebSocket,"CONNECTING",{value:c.CONNECTING}),Object.defineProperty(window.WebSocket,"OPEN",{value:c.OPEN}),Object.defineProperty(window.WebSocket,"CLOSING",{value:c.CLOSING}),Object.defineProperty(window.WebSocket,"CLOSED",{value:c.CLOSED})}findWebSocket(){return this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws:window.socket&&window.socket.readyState===WebSocket.OPEN?(this.ws=window.socket,this.ws):null}isConnected(){return this.findWebSocket()!==null}sendText(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let i=new TextEncoder().encode(t),o=new Uint8Array(i.length+1);return o[0]=48,o.set(i,1),e.send(o),!0}sendBytes(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let n=new Uint8Array(t.length+1);return n[0]=48,n.set(t,1),e.send(n),!0}};var S=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),this.elements=this.getElements(),this.ws=new B,this.terminal=new b(t),this.modifiers=new p,this.input=new f(this.ws,this.modifiers),this.search=new g(()=>this.terminal.findTerminal()),this.notifications=new v,this.touch=new T(t,this.terminal,this.input,this.modifiers),this.fontSizeManager=new m(t),this.autoRun=new u}getElements(){return{container:document.getElementById("ttyd-toolbar"),input:document.getElementById("ttyd-toolbar-input"),sendBtn:document.getElementById("ttyd-toolbar-send"),enterBtn:document.getElementById("ttyd-toolbar-enter"),zoomInBtn:document.getElementById("ttyd-toolbar-zoomin"),zoomOutBtn:document.getElementById("ttyd-toolbar-zoomout"),runBtn:document.getElementById("ttyd-toolbar-run"),toggleBtn:document.getElementById("ttyd-toolbar-toggle"),ctrlBtn:document.getElementById("ttyd-toolbar-ctrl"),altBtn:document.getElementById("ttyd-toolbar-alt"),shiftBtn:document.getElementById("ttyd-toolbar-shift"),escBtn:document.getElementById("ttyd-toolbar-esc"),tabBtn:document.getElementById("ttyd-toolbar-tab"),upBtn:document.getElementById("ttyd-toolbar-up"),downBtn:document.getElementById("ttyd-toolbar-down"),copyBtn:document.getElementById("ttyd-toolbar-copy"),copyAllBtn:document.getElementById("ttyd-toolbar-copyall"),autoBtn:document.getElementById("ttyd-toolbar-auto"),minimizeBtn:document.getElementById("ttyd-toolbar-minimize"),scrollBtn:document.getElementById("ttyd-toolbar-scroll"),pageUpBtn:document.getElementById("ttyd-toolbar-pageup"),pageDownBtn:document.getElementById("ttyd-toolbar-pagedown"),notifyBtn:document.getElementById("ttyd-toolbar-notify"),searchBar:document.getElementById("ttyd-search-bar"),searchInput:document.getElementById("ttyd-search-input"),searchCount:document.getElementById("ttyd-search-count"),searchPrevBtn:document.getElementById("ttyd-search-prev"),searchNextBtn:document.getElementById("ttyd-search-next"),searchCaseBtn:document.getElementById("ttyd-search-case"),searchRegexBtn:document.getElementById("ttyd-search-regex"),searchCloseBtn:document.getElementById("ttyd-search-close"),searchToolbarBtn:document.getElementById("ttyd-toolbar-search")}}initialize(){this.modifiers.bindElements(this.elements.ctrlBtn,this.elements.altBtn,this.elements.shiftBtn),this.search.bindElements(this.elements.searchBar,this.elements.searchInput,this.elements.searchCount,this.elements.searchCaseBtn,this.elements.searchRegexBtn),this.notifications.bindElement(this.elements.notifyBtn),this.touch.bindScrollButton(this.elements.scrollBtn),this.autoRun.bindElement(this.elements.autoBtn),this.setupEventListeners(),this.touch.setup(),setTimeout(()=>{this.terminal.setupBellHandler(()=>{})},1e3),this.applyStoredFontSize(),this.setupVisibilityHandler(),this.isMobile&&(setTimeout(()=>this.toggleToolbar(!0),1e3),setTimeout(()=>this.showOnboarding(),1500)),console.log("[Toolbar] Loaded. "+(this.isMobile?"Mobile mode.":"Press Ctrl+J or click keyboard button to toggle."))}setupEventListeners(){let{elements:t}=this;t.sendBtn.addEventListener("click",e=>{e.preventDefault(),this.submitInput()}),t.enterBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEnter()}),t.runBtn.addEventListener("click",e=>{e.preventDefault(),this.runInput()}),t.zoomInBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.zoomOutBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(-2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.ctrlBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("ctrl")}),t.altBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("alt")}),t.shiftBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("shift")}),t.autoBtn.addEventListener("click",e=>{e.preventDefault(),this.autoRun.toggle()}),t.escBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEsc()}),t.tabBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendTab()}),t.upBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("up")}),t.downBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("down")}),t.pageUpBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("up")}),t.pageDownBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("down")}),t.copyBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copySelection()}),t.copyAllBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copyAll()}),t.scrollBtn.addEventListener("click",e=>{e.preventDefault(),this.touch.toggleScrollMode()}),t.notifyBtn.addEventListener("click",e=>{e.preventDefault(),this.notifications.toggle()}),t.minimizeBtn.addEventListener("click",e=>{e.preventDefault(),t.container.classList.toggle("minimized"),t.minimizeBtn.textContent=t.container.classList.contains("minimized")?"\u25B2":"\u25BC",setTimeout(()=>this.terminal.fitTerminal(),100)}),t.toggleBtn.addEventListener("click",e=>{e.preventDefault(),this.toggleToolbar()}),this.setupSearchEvents(),this.setupInputEvents(),this.setupKeyboardShortcuts()}setupSearchEvents(){let{elements:t}=this;t.searchToolbarBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle()}),t.searchCloseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle(!1)}),t.searchNextBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findNext()}),t.searchPrevBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findPrevious()}),t.searchCaseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleCaseSensitive()}),t.searchRegexBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleRegex()}),t.searchInput.addEventListener("input",()=>{this.search.doSearch()}),t.searchInput.addEventListener("keydown",e=>{e.key==="Enter"&&!e.isComposing?(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext()):e.key==="Escape"?(e.preventDefault(),this.search.toggle(!1)):e.key==="F3"&&(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext())})}setupInputEvents(){let{input:t}=this.elements;t.addEventListener("input",()=>this.adjustTextareaHeight()),t.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&!e.isComposing?(e.preventDefault(),this.submitInput()):e.key==="Escape"&&(e.preventDefault(),this.toggleToolbar(!1))})}setupKeyboardShortcuts(){document.addEventListener("keydown",t=>{t.ctrlKey&&t.key==="j"&&(t.preventDefault(),this.toggleToolbar()),t.ctrlKey&&t.shiftKey&&t.key==="F"&&(t.preventDefault(),this.search.toggle())})}adjustTextareaHeight(){let t=this.elements.input;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,120)+"px"}submitInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),this.autoRun.isActive()&&setTimeout(()=>this.input.sendEnter(),1e3))}runInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),setTimeout(()=>this.input.sendEnter(),1e3))}toggleToolbar(t){let{container:e,input:n}=this.elements;typeof t=="boolean"?e.classList.toggle("hidden",!t):e.classList.toggle("hidden"),e.classList.contains("hidden")?(document.querySelector(".xterm-helper-textarea")?.focus(),setTimeout(()=>this.terminal.fitTerminal(),100)):(n.focus(),setTimeout(()=>this.terminal.fitTerminal(),100))}applyStoredFontSize(){let t=()=>{let e=this.terminal.findTerminal();if(e?.options){let n=this.fontSizeManager.load();e.options.fontSize=n,this.terminal.fitTerminal(),console.log("[Toolbar] Restored font size: "+n)}};setTimeout(t,500),setTimeout(t,1500)}setupVisibilityHandler(){document.addEventListener("visibilitychange",()=>{document.hidden||this.ws.isConnected()||(console.log("[Toolbar] Connection lost, reloading..."),location.reload())})}showOnboarding(){let t=document.getElementById("ttyd-toolbar-onboarding");if(!t)return;try{if(localStorage.getItem(s.ONBOARDING_SHOWN)){t.remove();return}}catch{}t.style.display="block";let e=document.getElementById("ttyd-toolbar-onboarding-close");e&&e.addEventListener("click",()=>{t.remove();try{localStorage.setItem(s.ONBOARDING_SHOWN,"1")}catch{}}),setTimeout(()=>{if(t.parentNode){t.remove();try{localStorage.setItem(s.ONBOARDING_SHOWN,"1")}catch{}}},15e3)}},L=window.__TOOLBAR_CONFIG__;L?new S(L).initialize():console.error("[Toolbar] Configuration not found. Make sure __TOOLBAR_CONFIG__ is set.");})();
|
|
1
|
+
"use strict";(()=>{var C={FONT_SIZE:"ttyd-toolbar-font-size",ONBOARDING_SHOWN:"ttyd-toolbar-onboarding-shown",AUTO_RUN:"ttyd-toolbar-auto-run",NOTIFY_SUBSCRIPTION:"ttyd-mux-notify-subscription"};var j=class{constructor(){this.active=!1;this.autoBtn=null}bindElement(t){this.autoBtn=t,this.restore()}isActive(){return this.active}toggle(){return this.active=!this.active,this.autoBtn?.classList.toggle("active",this.active),this.save(),this.active}save(){try{localStorage.setItem(C.AUTO_RUN,this.active?"1":"0")}catch(t){console.warn("[Toolbar] Failed to save auto-run state:",t)}}restore(){try{localStorage.getItem(C.AUTO_RUN)==="1"&&(this.active=!0,this.autoBtn?.classList.add("active"),console.log("[Toolbar] Restored auto-run mode: enabled"))}catch(t){console.warn("[Toolbar] Failed to load auto-run state:",t)}}};var W=class{constructor(t){this.config=t}save(t){try{localStorage.setItem(C.FONT_SIZE,String(t))}catch(e){console.warn("[Toolbar] Failed to save font size:",e)}}load(){let e=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?this.config.font_size_default_mobile:this.config.font_size_default_pc;try{let n=localStorage.getItem(C.FONT_SIZE);if(n){let s=parseInt(n,10);if(!isNaN(s)&&s>=this.config.font_size_min&&s<=this.config.font_size_max)return s}}catch(n){console.warn("[Toolbar] Failed to load font size:",n)}return e}};var Y=class{constructor(t,e){this.ws=t,this.modifiers=e}sendKey(t){if(this.modifiers.isCtrlActive()&&t.length===1){let e=t.toUpperCase().charCodeAt(0)-64;e>0&&e<32&&this.ws.sendBytes([e]),this.modifiers.resetCtrlAlt()}else if(this.modifiers.isAltActive()&&t.length===1){let e=t.charCodeAt(0);this.ws.sendBytes([27,e]),this.modifiers.resetCtrlAlt()}else this.ws.sendText(t)}sendEnter(){this.ws.sendBytes([13])}sendEsc(){this.ws.sendBytes([27])}sendTab(){this.ws.sendBytes([9])}sendArrow(t){let e={up:[27,91,65],down:[27,91,66],right:[27,91,67],left:[27,91,68]};this.ws.sendBytes(e[t])}sendPage(t){t==="up"?this.ws.sendBytes([27,91,53,126]):this.ws.sendBytes([27,91,54,126])}sendText(t){return this.ws.sendText(t)}};var G=class{constructor(){this.ctrlActive=!1;this.altActive=!1;this.shiftActive=!1;this.ctrlBtn=null;this.altBtn=null;this.shiftBtn=null}bindElements(t,e,n){this.ctrlBtn=t,this.altBtn=e,this.shiftBtn=n}isCtrlActive(){return this.ctrlActive}isAltActive(){return this.altActive}isShiftActive(){return this.shiftActive}toggle(t){switch(t){case"ctrl":return this.ctrlActive=!this.ctrlActive,this.ctrlBtn?.classList.toggle("active",this.ctrlActive),this.ctrlActive&&(this.altActive=!1,this.altBtn?.classList.remove("active")),this.ctrlActive;case"alt":return this.altActive=!this.altActive,this.altBtn?.classList.toggle("active",this.altActive),this.altActive&&(this.ctrlActive=!1,this.ctrlBtn?.classList.remove("active")),this.altActive;case"shift":return this.shiftActive=!this.shiftActive,this.shiftBtn?.classList.toggle("active",this.shiftActive),this.shiftActive}}resetCtrlAlt(){this.ctrlActive=!1,this.altActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active")}reset(){this.ctrlActive=!1,this.altActive=!1,this.shiftActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active"),this.shiftBtn?.classList.remove("active")}};var Q=class{constructor(t){this.subscribed=!1;this.subscriptionId=null;this.notifyBtn=null;this.config=t,this.loadSubscription()}bindElement(t){this.notifyBtn=t,this.updateButton()}getSessionName(){return window.location.pathname.split("/")[2]||""}urlBase64ToUint8Array(t){let e="=".repeat((4-t.length%4)%4),n=(t+e).replace(/-/g,"+").replace(/_/g,"/"),s=atob(n),l=new Uint8Array(s.length);for(let o=0;o<s.length;++o)l[o]=s.charCodeAt(o);return l}loadSubscription(){try{let t=localStorage.getItem(C.NOTIFY_SUBSCRIPTION);if(t){let e=JSON.parse(t);this.subscriptionId=e.id,this.subscribed=!0,console.log("[Toolbar] Loaded notification subscription: "+e.id)}}catch(t){console.warn("[Toolbar] Failed to load notification subscription:",t)}}saveSubscription(t){try{localStorage.setItem(C.NOTIFY_SUBSCRIPTION,JSON.stringify({id:t}))}catch(e){console.warn("[Toolbar] Failed to save notification subscription:",e)}}clearSubscription(){try{localStorage.removeItem(C.NOTIFY_SUBSCRIPTION)}catch(t){console.warn("[Toolbar] Failed to clear notification subscription:",t)}}updateButton(){this.notifyBtn&&(this.subscribed?(this.notifyBtn.classList.add("active"),this.notifyBtn.textContent="\u{1F514}",this.notifyBtn.title="Push\u901A\u77E5: ON (\u30AF\u30EA\u30C3\u30AF\u3067\u89E3\u9664)"):(this.notifyBtn.classList.remove("active"),this.notifyBtn.textContent="\u{1F515}",this.notifyBtn.title="Push\u901A\u77E5: OFF (\u30AF\u30EA\u30C3\u30AF\u3067\u6709\u52B9\u5316)"))}isSubscribed(){return this.subscribed}async subscribe(){let t=this.config.base_path,e=this.getSessionName();try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){alert("\u3053\u306E\u30D6\u30E9\u30A6\u30B6\u306FPush\u901A\u77E5\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u305B\u3093");return}if(await Notification.requestPermission()!=="granted"){alert("\u901A\u77E5\u306E\u8A31\u53EF\u304C\u5FC5\u8981\u3067\u3059");return}let s=await fetch(t+"/api/notifications/vapid-key");if(!s.ok)throw new Error("VAPID key fetch failed");let{publicKey:l}=await s.json(),i=await(await navigator.serviceWorker.ready).pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.urlBase64ToUint8Array(l)}),u=i.getKey("p256dh"),g=i.getKey("auth");if(!u||!g)throw new Error("Failed to get subscription keys");let b=await fetch(t+"/api/notifications/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:i.endpoint,keys:{p256dh:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(u)))),auth:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(g))))},sessionName:e||void 0})});if(!b.ok)throw new Error("Subscription failed");let m=await b.json();this.subscriptionId=m.id,this.subscribed=!0,this.saveSubscription(m.id),this.updateButton(),console.log("[Toolbar] Push notification subscribed: "+m.id)}catch(n){console.error("[Toolbar] Push notification subscription failed:",n),alert("Push\u901A\u77E5\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F: "+n.message)}}async unsubscribe(){let t=this.config.base_path;try{this.subscriptionId&&await fetch(t+"/api/notifications/subscribe/"+encodeURIComponent(this.subscriptionId),{method:"DELETE"});let n=await(await navigator.serviceWorker.ready).pushManager.getSubscription();n&&await n.unsubscribe(),this.subscribed=!1,this.subscriptionId=null,this.clearSubscription(),this.updateButton(),console.log("[Toolbar] Push notification unsubscribed")}catch(e){console.error("[Toolbar] Push notification unsubscribe failed:",e)}}async toggle(){this.subscribed?await this.unsubscribe():await this.subscribe()}};var ht="https://cdn.jsdelivr.net/npm/@xterm/addon-search@0.15.0/lib/addon-search.min.js",X=class{constructor(t){this.searchAddon=null;this.caseSensitive=!1;this.regex=!1;this.currentMatchIndex=0;this.totalMatches=0;this.searchBar=null;this.searchInput=null;this.searchCount=null;this.searchCaseBtn=null;this.searchRegexBtn=null;this.findTerminal=t}bindElements(t,e,n,s,l){this.searchBar=t,this.searchInput=e,this.searchCount=n,this.searchCaseBtn=s,this.searchRegexBtn=l}loadAddon(){if(this.searchAddon)return Promise.resolve(this.searchAddon);if(window.SearchAddon){let t=this.findTerminal();if(t)return this.searchAddon=new window.SearchAddon.SearchAddon,t.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded"),Promise.resolve(this.searchAddon)}return new Promise((t,e)=>{let n=document.createElement("script");n.src=ht,n.onload=()=>{let s=this.findTerminal();s&&window.SearchAddon?(this.searchAddon=new window.SearchAddon.SearchAddon,s.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded from CDN"),t(this.searchAddon)):e(new Error("Failed to initialize SearchAddon"))},n.onerror=()=>{e(new Error("Failed to load SearchAddon"))},document.head.appendChild(n)})}toggle(t){this.searchBar&&(typeof t=="boolean"?this.searchBar.classList.toggle("hidden",!t):this.searchBar.classList.toggle("hidden"),this.searchBar.classList.contains("hidden")?(this.searchAddon?.clearDecorations&&this.searchAddon.clearDecorations(),this.updateMatchCount(0,0),document.querySelector(".xterm-helper-textarea")?.focus()):this.loadAddon().then(()=>{this.searchInput?.focus(),this.searchInput?.select()}).catch(e=>{console.error("[Toolbar] Failed to load search:",e)}))}updateMatchCount(t,e){this.currentMatchIndex=t,this.totalMatches=e,this.searchCount&&(this.searchCount.textContent=e===0?"0/0":`${t}/${e}`)}countMatches(t){if(!this.searchAddon||!t){this.updateMatchCount(0,0);return}let e=this.findTerminal();if(!e?.buffer?.active){this.updateMatchCount(0,0);return}let n=e.buffer.active,s=this.caseSensitive?"g":"gi",l=0,o;try{o=this.regex?new RegExp(t,s):new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),s)}catch{this.updateMatchCount(0,0);return}for(let i=0;i<n.length;i++){let u=n.getLine(i);if(u){let b=u.translateToString(!0).match(o);b&&(l+=b.length)}}this.updateMatchCount(this.currentMatchIndex,l)}findNext(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex,incremental:!1},e=this.searchAddon.findNext(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.min(this.currentMatchIndex+1,this.totalMatches),this.currentMatchIndex>this.totalMatches&&(this.currentMatchIndex=1),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}findPrevious(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex},e=this.searchAddon.findPrevious(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.max(this.currentMatchIndex-1,1),this.currentMatchIndex<1&&(this.currentMatchIndex=this.totalMatches),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}doSearch(){let t=this.searchInput?.value;if(!t){this.updateMatchCount(0,0);return}this.loadAddon().then(()=>{this.countMatches(t),this.currentMatchIndex=0,this.findNext()})}toggleCaseSensitive(){return this.caseSensitive=!this.caseSensitive,this.searchCaseBtn?.classList.toggle("active",this.caseSensitive),this.doSearch(),this.caseSensitive}toggleRegex(){return this.regex=!this.regex,this.searchRegexBtn?.classList.toggle("active",this.regex),this.doSearch(),this.regex}isVisible(){return this.searchBar?!this.searchBar.classList.contains("hidden"):!1}};var z=function(f,t){let s=f,l=K[t],o=null,i=0,u=null,g=[],b={},m=function(a,d){i=s*4+17,o=function(r){let h=new Array(r);for(let c=0;c<r;c+=1){h[c]=new Array(r);for(let v=0;v<r;v+=1)h[c][v]=null}return h}(i),p(0,0),p(i-7,0),p(0,i-7),x(),_(),k(a,d),s>=7&&S(a),u==null&&(u=ct(s,l,g)),H(u,d)},p=function(a,d){for(let r=-1;r<=7;r+=1)if(!(a+r<=-1||i<=a+r))for(let h=-1;h<=7;h+=1)d+h<=-1||i<=d+h||(0<=r&&r<=6&&(h==0||h==6)||0<=h&&h<=6&&(r==0||r==6)||2<=r&&r<=4&&2<=h&&h<=4?o[a+r][d+h]=!0:o[a+r][d+h]=!1)},B=function(){let a=0,d=0;for(let r=0;r<8;r+=1){m(!0,r);let h=O.getLostPoint(b);(r==0||a>h)&&(a=h,d=r)}return d},_=function(){for(let a=8;a<i-8;a+=1)o[a][6]==null&&(o[a][6]=a%2==0);for(let a=8;a<i-8;a+=1)o[6][a]==null&&(o[6][a]=a%2==0)},x=function(){let a=O.getPatternPosition(s);for(let d=0;d<a.length;d+=1)for(let r=0;r<a.length;r+=1){let h=a[d],c=a[r];if(o[h][c]==null)for(let v=-2;v<=2;v+=1)for(let T=-2;T<=2;T+=1)v==-2||v==2||T==-2||T==2||v==0&&T==0?o[h+v][c+T]=!0:o[h+v][c+T]=!1}},S=function(a){let d=O.getBCHTypeNumber(s);for(let r=0;r<18;r+=1){let h=!a&&(d>>r&1)==1;o[Math.floor(r/3)][r%3+i-8-3]=h}for(let r=0;r<18;r+=1){let h=!a&&(d>>r&1)==1;o[r%3+i-8-3][Math.floor(r/3)]=h}},k=function(a,d){let r=l<<3|d,h=O.getBCHTypeInfo(r);for(let c=0;c<15;c+=1){let v=!a&&(h>>c&1)==1;c<6?o[c][8]=v:c<8?o[c+1][8]=v:o[i-15+c][8]=v}for(let c=0;c<15;c+=1){let v=!a&&(h>>c&1)==1;c<8?o[8][i-c-1]=v:c<9?o[8][15-c-1+1]=v:o[8][15-c-1]=v}o[i-8][8]=!a},H=function(a,d){let r=-1,h=i-1,c=7,v=0,T=O.getMaskFunction(d);for(let E=i-1;E>0;E-=2)for(E==6&&(E-=1);;){for(let w=0;w<2;w+=1)if(o[h][E-w]==null){let L=!1;v<a.length&&(L=(a[v]>>>c&1)==1),T(h,E-w)&&(L=!L),o[h][E-w]=L,c-=1,c==-1&&(v+=1,c=7)}if(h+=r,h<0||i<=h){h-=r,r=-r;break}}},lt=function(a,d){let r=0,h=0,c=0,v=new Array(d.length),T=new Array(d.length);for(let y=0;y<d.length;y+=1){let M=d[y].dataCount,I=d[y].totalCount-M;h=Math.max(h,M),c=Math.max(c,I),v[y]=new Array(M);for(let D=0;D<v[y].length;D+=1)v[y][D]=255&a.getBuffer()[D+r];r+=M;let q=O.getErrorCorrectPolynomial(I),et=U(v[y],q.getLength()-1).mod(q);T[y]=new Array(q.getLength()-1);for(let D=0;D<T[y].length;D+=1){let nt=D+et.getLength()-T[y].length;T[y][D]=nt>=0?et.getAt(nt):0}}let E=0;for(let y=0;y<d.length;y+=1)E+=d[y].totalCount;let w=new Array(E),L=0;for(let y=0;y<h;y+=1)for(let M=0;M<d.length;M+=1)y<v[M].length&&(w[L]=v[M][y],L+=1);for(let y=0;y<c;y+=1)for(let M=0;M<d.length;M+=1)y<T[M].length&&(w[L]=T[M][y],L+=1);return w},ct=function(a,d,r){let h=it.getRSBlocks(a,d),c=ot();for(let T=0;T<r.length;T+=1){let E=r[T];c.put(E.getMode(),4),c.put(E.getLength(),O.getLengthInBits(E.getMode(),a)),E.write(c)}let v=0;for(let T=0;T<h.length;T+=1)v+=h[T].dataCount;if(c.getLengthInBits()>v*8)throw"code length overflow. ("+c.getLengthInBits()+">"+v*8+")";for(c.getLengthInBits()+4<=v*8&&c.put(0,4);c.getLengthInBits()%8!=0;)c.putBit(!1);for(;!(c.getLengthInBits()>=v*8||(c.put(236,8),c.getLengthInBits()>=v*8));)c.put(17,8);return lt(c,h)};b.addData=function(a,d){d=d||"Byte";let r=null;switch(d){case"Numeric":r=dt(a);break;case"Alphanumeric":r=ft(a);break;case"Byte":r=mt(a);break;case"Kanji":r=pt(a);break;default:throw"mode:"+d}g.push(r),u=null},b.isDark=function(a,d){if(a<0||i<=a||d<0||i<=d)throw a+","+d;return o[a][d]},b.getModuleCount=function(){return i},b.make=function(){if(s<1){let a=1;for(;a<40;a++){let d=it.getRSBlocks(a,l),r=ot();for(let c=0;c<g.length;c++){let v=g[c];r.put(v.getMode(),4),r.put(v.getLength(),O.getLengthInBits(v.getMode(),a)),v.write(r)}let h=0;for(let c=0;c<d.length;c++)h+=d[c].dataCount;if(r.getLengthInBits()<=h*8)break}s=a}m(!1,B())},b.createTableTag=function(a,d){a=a||2,d=typeof d>"u"?a*4:d;let r="";r+='<table style="',r+=" border-width: 0px; border-style: none;",r+=" border-collapse: collapse;",r+=" padding: 0px; margin: "+d+"px;",r+='">',r+="<tbody>";for(let h=0;h<b.getModuleCount();h+=1){r+="<tr>";for(let c=0;c<b.getModuleCount();c+=1)r+='<td style="',r+=" border-width: 0px; border-style: none;",r+=" border-collapse: collapse;",r+=" padding: 0px; margin: 0px;",r+=" width: "+a+"px;",r+=" height: "+a+"px;",r+=" background-color: ",r+=b.isDark(h,c)?"#000000":"#ffffff",r+=";",r+='"/>';r+="</tr>"}return r+="</tbody>",r+="</table>",r},b.createSvgTag=function(a,d,r,h){let c={};typeof arguments[0]=="object"&&(c=arguments[0],a=c.cellSize,d=c.margin,r=c.alt,h=c.title),a=a||2,d=typeof d>"u"?a*4:d,r=typeof r=="string"?{text:r}:r||{},r.text=r.text||null,r.id=r.text?r.id||"qrcode-description":null,h=typeof h=="string"?{text:h}:h||{},h.text=h.text||null,h.id=h.text?h.id||"qrcode-title":null;let v=b.getModuleCount()*a+d*2,T,E,w,L,y="",M;for(M="l"+a+",0 0,"+a+" -"+a+",0 0,-"+a+"z ",y+='<svg version="1.1" xmlns="http://www.w3.org/2000/svg"',y+=c.scalable?"":' width="'+v+'px" height="'+v+'px"',y+=' viewBox="0 0 '+v+" "+v+'" ',y+=' preserveAspectRatio="xMinYMin meet"',y+=h.text||r.text?' role="img" aria-labelledby="'+R([h.id,r.id].join(" ").trim())+'"':"",y+=">",y+=h.text?'<title id="'+R(h.id)+'">'+R(h.text)+"</title>":"",y+=r.text?'<description id="'+R(r.id)+'">'+R(r.text)+"</description>":"",y+='<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>',y+='<path d="',w=0;w<b.getModuleCount();w+=1)for(L=w*a+d,T=0;T<b.getModuleCount();T+=1)b.isDark(w,T)&&(E=T*a+d,y+="M"+E+","+L+M);return y+='" stroke="transparent" fill="black"/>',y+="</svg>",y},b.createDataURL=function(a,d){a=a||2,d=typeof d>"u"?a*4:d;let r=b.getModuleCount()*a+d*2,h=d,c=r-d;return Tt(r,r,function(v,T){if(h<=v&&v<c&&h<=T&&T<c){let E=Math.floor((v-h)/a),w=Math.floor((T-h)/a);return b.isDark(w,E)?0:1}else return 1})},b.createImgTag=function(a,d,r){a=a||2,d=typeof d>"u"?a*4:d;let h=b.getModuleCount()*a+d*2,c="";return c+="<img",c+=' src="',c+=b.createDataURL(a,d),c+='"',c+=' width="',c+=h,c+='"',c+=' height="',c+=h,c+='"',r&&(c+=' alt="',c+=R(r),c+='"'),c+="/>",c};let R=function(a){let d="";for(let r=0;r<a.length;r+=1){let h=a.charAt(r);switch(h){case"<":d+="<";break;case">":d+=">";break;case"&":d+="&";break;case'"':d+=""";break;default:d+=h;break}}return d},ut=function(a){a=typeof a>"u"?1*2:a;let r=b.getModuleCount()*1+a*2,h=a,c=r-a,v,T,E,w,L,y={"\u2588\u2588":"\u2588","\u2588 ":"\u2580"," \u2588":"\u2584"," ":" "},M={"\u2588\u2588":"\u2580","\u2588 ":"\u2580"," \u2588":" "," ":" "},I="";for(v=0;v<r;v+=2){for(E=Math.floor((v-h)/1),w=Math.floor((v+1-h)/1),T=0;T<r;T+=1)L="\u2588",h<=T&&T<c&&h<=v&&v<c&&b.isDark(E,Math.floor((T-h)/1))&&(L=" "),h<=T&&T<c&&h<=v+1&&v+1<c&&b.isDark(w,Math.floor((T-h)/1))?L+=" ":L+="\u2588",I+=a<1&&v+1>=c?M[L]:y[L];I+=`
|
|
2
|
+
`}return r%2&&a>0?I.substring(0,I.length-r-1)+Array(r+1).join("\u2580"):I.substring(0,I.length-1)};return b.createASCII=function(a,d){if(a=a||1,a<2)return ut(d);a-=1,d=typeof d>"u"?a*2:d;let r=b.getModuleCount()*a+d*2,h=d,c=r-d,v,T,E,w,L=Array(a+1).join("\u2588\u2588"),y=Array(a+1).join(" "),M="",I="";for(v=0;v<r;v+=1){for(E=Math.floor((v-h)/a),I="",T=0;T<r;T+=1)w=1,h<=T&&T<c&&h<=v&&v<c&&b.isDark(E,Math.floor((T-h)/a))&&(w=0),I+=w?L:y;for(E=0;E<a;E+=1)M+=I+`
|
|
3
|
+
`}return M.substring(0,M.length-1)},b.renderTo2dContext=function(a,d){d=d||2;let r=b.getModuleCount();for(let h=0;h<r;h++)for(let c=0;c<r;c++)a.fillStyle=b.isDark(h,c)?"black":"white",a.fillRect(c*d,h*d,d,d)},b};z.stringToBytes=function(f){let t=[];for(let e=0;e<f.length;e+=1){let n=f.charCodeAt(e);t.push(n&255)}return t};z.createStringToBytes=function(f,t){let e=function(){let s=vt(f),l=function(){let u=s.read();if(u==-1)throw"eof";return u},o=0,i={};for(;;){let u=s.read();if(u==-1)break;let g=l(),b=l(),m=l(),p=String.fromCharCode(u<<8|g),B=b<<8|m;i[p]=B,o+=1}if(o!=t)throw o+" != "+t;return i}(),n=63;return function(s){let l=[];for(let o=0;o<s.length;o+=1){let i=s.charCodeAt(o);if(i<128)l.push(i);else{let u=e[s.charAt(o)];typeof u=="number"?(u&255)==u?l.push(u):(l.push(u>>>8),l.push(u&255)):l.push(n)}}return l}};var A={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},K={L:1,M:0,Q:3,H:2},P={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},O=function(){let f=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],t=1335,e=7973,n=21522,s={},l=function(o){let i=0;for(;o!=0;)i+=1,o>>>=1;return i};return s.getBCHTypeInfo=function(o){let i=o<<10;for(;l(i)-l(t)>=0;)i^=t<<l(i)-l(t);return(o<<10|i)^n},s.getBCHTypeNumber=function(o){let i=o<<12;for(;l(i)-l(e)>=0;)i^=e<<l(i)-l(e);return o<<12|i},s.getPatternPosition=function(o){return f[o-1]},s.getMaskFunction=function(o){switch(o){case P.PATTERN000:return function(i,u){return(i+u)%2==0};case P.PATTERN001:return function(i,u){return i%2==0};case P.PATTERN010:return function(i,u){return u%3==0};case P.PATTERN011:return function(i,u){return(i+u)%3==0};case P.PATTERN100:return function(i,u){return(Math.floor(i/2)+Math.floor(u/3))%2==0};case P.PATTERN101:return function(i,u){return i*u%2+i*u%3==0};case P.PATTERN110:return function(i,u){return(i*u%2+i*u%3)%2==0};case P.PATTERN111:return function(i,u){return(i*u%3+(i+u)%2)%2==0};default:throw"bad maskPattern:"+o}},s.getErrorCorrectPolynomial=function(o){let i=U([1],0);for(let u=0;u<o;u+=1)i=i.multiply(U([1,N.gexp(u)],0));return i},s.getLengthInBits=function(o,i){if(1<=i&&i<10)switch(o){case A.MODE_NUMBER:return 10;case A.MODE_ALPHA_NUM:return 9;case A.MODE_8BIT_BYTE:return 8;case A.MODE_KANJI:return 8;default:throw"mode:"+o}else if(i<27)switch(o){case A.MODE_NUMBER:return 12;case A.MODE_ALPHA_NUM:return 11;case A.MODE_8BIT_BYTE:return 16;case A.MODE_KANJI:return 10;default:throw"mode:"+o}else if(i<41)switch(o){case A.MODE_NUMBER:return 14;case A.MODE_ALPHA_NUM:return 13;case A.MODE_8BIT_BYTE:return 16;case A.MODE_KANJI:return 12;default:throw"mode:"+o}else throw"type:"+i},s.getLostPoint=function(o){let i=o.getModuleCount(),u=0;for(let m=0;m<i;m+=1)for(let p=0;p<i;p+=1){let B=0,_=o.isDark(m,p);for(let x=-1;x<=1;x+=1)if(!(m+x<0||i<=m+x))for(let S=-1;S<=1;S+=1)p+S<0||i<=p+S||x==0&&S==0||_==o.isDark(m+x,p+S)&&(B+=1);B>5&&(u+=3+B-5)}for(let m=0;m<i-1;m+=1)for(let p=0;p<i-1;p+=1){let B=0;o.isDark(m,p)&&(B+=1),o.isDark(m+1,p)&&(B+=1),o.isDark(m,p+1)&&(B+=1),o.isDark(m+1,p+1)&&(B+=1),(B==0||B==4)&&(u+=3)}for(let m=0;m<i;m+=1)for(let p=0;p<i-6;p+=1)o.isDark(m,p)&&!o.isDark(m,p+1)&&o.isDark(m,p+2)&&o.isDark(m,p+3)&&o.isDark(m,p+4)&&!o.isDark(m,p+5)&&o.isDark(m,p+6)&&(u+=40);for(let m=0;m<i;m+=1)for(let p=0;p<i-6;p+=1)o.isDark(p,m)&&!o.isDark(p+1,m)&&o.isDark(p+2,m)&&o.isDark(p+3,m)&&o.isDark(p+4,m)&&!o.isDark(p+5,m)&&o.isDark(p+6,m)&&(u+=40);let g=0;for(let m=0;m<i;m+=1)for(let p=0;p<i;p+=1)o.isDark(p,m)&&(g+=1);let b=Math.abs(100*g/i/i-50)/5;return u+=b*10,u},s}(),N=function(){let f=new Array(256),t=new Array(256);for(let n=0;n<8;n+=1)f[n]=1<<n;for(let n=8;n<256;n+=1)f[n]=f[n-4]^f[n-5]^f[n-6]^f[n-8];for(let n=0;n<255;n+=1)t[f[n]]=n;let e={};return e.glog=function(n){if(n<1)throw"glog("+n+")";return t[n]},e.gexp=function(n){for(;n<0;)n+=255;for(;n>=256;)n-=255;return f[n]},e}(),U=function(f,t){if(typeof f.length>"u")throw f.length+"/"+t;let e=function(){let s=0;for(;s<f.length&&f[s]==0;)s+=1;let l=new Array(f.length-s+t);for(let o=0;o<f.length-s;o+=1)l[o]=f[o+s];return l}(),n={};return n.getAt=function(s){return e[s]},n.getLength=function(){return e.length},n.multiply=function(s){let l=new Array(n.getLength()+s.getLength()-1);for(let o=0;o<n.getLength();o+=1)for(let i=0;i<s.getLength();i+=1)l[o+i]^=N.gexp(N.glog(n.getAt(o))+N.glog(s.getAt(i)));return U(l,0)},n.mod=function(s){if(n.getLength()-s.getLength()<0)return n;let l=N.glog(n.getAt(0))-N.glog(s.getAt(0)),o=new Array(n.getLength());for(let i=0;i<n.getLength();i+=1)o[i]=n.getAt(i);for(let i=0;i<s.getLength();i+=1)o[i]^=N.gexp(N.glog(s.getAt(i))+l);return U(o,0).mod(s)},n},it=function(){let f=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],t=function(s,l){let o={};return o.totalCount=s,o.dataCount=l,o},e={},n=function(s,l){switch(l){case K.L:return f[(s-1)*4+0];case K.M:return f[(s-1)*4+1];case K.Q:return f[(s-1)*4+2];case K.H:return f[(s-1)*4+3];default:return}};return e.getRSBlocks=function(s,l){let o=n(s,l);if(typeof o>"u")throw"bad rs block @ typeNumber:"+s+"/errorCorrectionLevel:"+l;let i=o.length/3,u=[];for(let g=0;g<i;g+=1){let b=o[g*3+0],m=o[g*3+1],p=o[g*3+2];for(let B=0;B<b;B+=1)u.push(t(m,p))}return u},e}(),ot=function(){let f=[],t=0,e={};return e.getBuffer=function(){return f},e.getAt=function(n){let s=Math.floor(n/8);return(f[s]>>>7-n%8&1)==1},e.put=function(n,s){for(let l=0;l<s;l+=1)e.putBit((n>>>s-l-1&1)==1)},e.getLengthInBits=function(){return t},e.putBit=function(n){let s=Math.floor(t/8);f.length<=s&&f.push(0),n&&(f[s]|=128>>>t%8),t+=1},e},dt=function(f){let t=A.MODE_NUMBER,e=f,n={};n.getMode=function(){return t},n.getLength=function(o){return e.length},n.write=function(o){let i=e,u=0;for(;u+2<i.length;)o.put(s(i.substring(u,u+3)),10),u+=3;u<i.length&&(i.length-u==1?o.put(s(i.substring(u,u+1)),4):i.length-u==2&&o.put(s(i.substring(u,u+2)),7))};let s=function(o){let i=0;for(let u=0;u<o.length;u+=1)i=i*10+l(o.charAt(u));return i},l=function(o){if("0"<=o&&o<="9")return o.charCodeAt(0)-48;throw"illegal char :"+o};return n},ft=function(f){let t=A.MODE_ALPHA_NUM,e=f,n={};n.getMode=function(){return t},n.getLength=function(l){return e.length},n.write=function(l){let o=e,i=0;for(;i+1<o.length;)l.put(s(o.charAt(i))*45+s(o.charAt(i+1)),11),i+=2;i<o.length&&l.put(s(o.charAt(i)),6)};let s=function(l){if("0"<=l&&l<="9")return l.charCodeAt(0)-48;if("A"<=l&&l<="Z")return l.charCodeAt(0)-65+10;switch(l){case" ":return 36;case"$":return 37;case"%":return 38;case"*":return 39;case"+":return 40;case"-":return 41;case".":return 42;case"/":return 43;case":":return 44;default:throw"illegal char :"+l}};return n},mt=function(f){let t=A.MODE_8BIT_BYTE,e=f,n=z.stringToBytes(f),s={};return s.getMode=function(){return t},s.getLength=function(l){return n.length},s.write=function(l){for(let o=0;o<n.length;o+=1)l.put(n[o],8)},s},pt=function(f){let t=A.MODE_KANJI,e=f,n=z.stringToBytes;(function(o,i){let u=n(o);if(u.length!=2||(u[0]<<8|u[1])!=i)throw"sjis not supported."})("\u53CB",38726);let s=n(f),l={};return l.getMode=function(){return t},l.getLength=function(o){return~~(s.length/2)},l.write=function(o){let i=s,u=0;for(;u+1<i.length;){let g=(255&i[u])<<8|255&i[u+1];if(33088<=g&&g<=40956)g-=33088;else if(57408<=g&&g<=60351)g-=49472;else throw"illegal char at "+(u+1)+"/"+g;g=(g>>>8&255)*192+(g&255),o.put(g,13),u+=2}if(u<i.length)throw"illegal char at "+(u+1)},l},st=function(){let f=[],t={};return t.writeByte=function(e){f.push(e&255)},t.writeShort=function(e){t.writeByte(e),t.writeByte(e>>>8)},t.writeBytes=function(e,n,s){n=n||0,s=s||e.length;for(let l=0;l<s;l+=1)t.writeByte(e[l+n])},t.writeString=function(e){for(let n=0;n<e.length;n+=1)t.writeByte(e.charCodeAt(n))},t.toByteArray=function(){return f},t.toString=function(){let e="";e+="[";for(let n=0;n<f.length;n+=1)n>0&&(e+=","),e+=f[n];return e+="]",e},t},gt=function(){let f=0,t=0,e=0,n="",s={},l=function(i){n+=String.fromCharCode(o(i&63))},o=function(i){if(i<0)throw"n:"+i;if(i<26)return 65+i;if(i<52)return 97+(i-26);if(i<62)return 48+(i-52);if(i==62)return 43;if(i==63)return 47;throw"n:"+i};return s.writeByte=function(i){for(f=f<<8|i&255,t+=8,e+=1;t>=6;)l(f>>>t-6),t-=6},s.flush=function(){if(t>0&&(l(f<<6-t),f=0,t=0),e%3!=0){let i=3-e%3;for(let u=0;u<i;u+=1)n+="="}},s.toString=function(){return n},s},vt=function(f){let t=f,e=0,n=0,s=0,l={};l.read=function(){for(;s<8;){if(e>=t.length){if(s==0)return-1;throw"unexpected end of file./"+s}let u=t.charAt(e);if(e+=1,u=="=")return s=0,-1;if(u.match(/^\s$/))continue;n=n<<6|o(u.charCodeAt(0)),s+=6}let i=n>>>s-8&255;return s-=8,i};let o=function(i){if(65<=i&&i<=90)return i-65;if(97<=i&&i<=122)return i-97+26;if(48<=i&&i<=57)return i-48+52;if(i==43)return 62;if(i==47)return 63;throw"c:"+i};return l},bt=function(f,t){let e=f,n=t,s=new Array(f*t),l={};l.setPixel=function(g,b,m){s[b*e+g]=m},l.write=function(g){g.writeString("GIF87a"),g.writeShort(e),g.writeShort(n),g.writeByte(128),g.writeByte(0),g.writeByte(0),g.writeByte(0),g.writeByte(0),g.writeByte(0),g.writeByte(255),g.writeByte(255),g.writeByte(255),g.writeString(","),g.writeShort(0),g.writeShort(0),g.writeShort(e),g.writeShort(n),g.writeByte(0);let b=2,m=i(b);g.writeByte(b);let p=0;for(;m.length-p>255;)g.writeByte(255),g.writeBytes(m,p,255),p+=255;g.writeByte(m.length-p),g.writeBytes(m,p,m.length-p),g.writeByte(0),g.writeString(";")};let o=function(g){let b=g,m=0,p=0,B={};return B.write=function(_,x){if(_>>>x)throw"length over";for(;m+x>=8;)b.writeByte(255&(_<<m|p)),x-=8-m,_>>>=8-m,p=0,m=0;p=_<<m|p,m=m+x},B.flush=function(){m>0&&b.writeByte(p)},B},i=function(g){let b=1<<g,m=(1<<g)+1,p=g+1,B=u();for(let H=0;H<b;H+=1)B.add(String.fromCharCode(H));B.add(String.fromCharCode(b)),B.add(String.fromCharCode(m));let _=st(),x=o(_);x.write(b,p);let S=0,k=String.fromCharCode(s[S]);for(S+=1;S<s.length;){let H=String.fromCharCode(s[S]);S+=1,B.contains(k+H)?k=k+H:(x.write(B.indexOf(k),p),B.size()<4095&&(B.size()==1<<p&&(p+=1),B.add(k+H)),k=H)}return x.write(B.indexOf(k),p),x.write(m,p),x.flush(),_.toByteArray()},u=function(){let g={},b=0,m={};return m.add=function(p){if(m.contains(p))throw"dup key:"+p;g[p]=b,b+=1},m.size=function(){return b},m.indexOf=function(p){return g[p]},m.contains=function(p){return typeof g[p]<"u"},m};return l},Tt=function(f,t,e){let n=bt(f,t);for(let i=0;i<t;i+=1)for(let u=0;u<f;u+=1)n.setPixel(u,i,e(u,i));let s=st();n.write(s);let l=gt(),o=s.toByteArray();for(let i=0;i<o.length;i+=1)l.writeByte(o[i]);return l.flush(),"data:image/gif;base64,"+l},rt=z,_t=z.stringToBytes;var $=class{constructor(t){this.shareBtn=null;this.modal=null;this.modalClose=null;this.createBtn=null;this.resultSection=null;this.urlInput=null;this.copyBtn=null;this.qrBtn=null;this.expiryOptions=null;this.config=t}bindElements(t,e,n,s,l,o,i,u){this.shareBtn=t,this.modal=e,this.modalClose=n,this.createBtn=s,this.resultSection=l,this.urlInput=o,this.copyBtn=i,this.qrBtn=u,this.expiryOptions=document.querySelectorAll('input[name="ttyd-share-expiry"]'),this.setupEventListeners()}setupEventListeners(){this.shareBtn?.addEventListener("click",t=>{t.preventDefault(),this.show()}),this.modalClose?.addEventListener("click",t=>{t.preventDefault(),this.hide()}),this.modal?.addEventListener("click",t=>{t.target===this.modal&&this.hide()}),this.createBtn?.addEventListener("click",async t=>{t.preventDefault(),await this.createShare()}),this.copyBtn?.addEventListener("click",t=>{t.preventDefault(),this.copyUrl()}),this.qrBtn?.addEventListener("click",t=>{t.preventDefault(),this.showQR()}),document.addEventListener("keydown",t=>{t.key==="Escape"&&this.isVisible()&&this.hide()})}getSessionName(){return window.location.pathname.split("/")[2]||""}getSelectedExpiry(){if(!this.expiryOptions)return"24h";for(let t of this.expiryOptions)if(t.checked)return t.value;return"24h"}isVisible(){return this.modal?!this.modal.classList.contains("hidden"):!1}show(){this.modal&&(this.modal.classList.remove("hidden"),this.resultSection?.classList.add("hidden"),this.createBtn?.classList.remove("hidden"))}hide(){this.modal&&this.modal.classList.add("hidden")}async createShare(){let t=this.config.base_path,e=this.getSessionName(),n=this.getSelectedExpiry();if(!e){alert("\u30BB\u30C3\u30B7\u30E7\u30F3\u540D\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");return}try{this.createBtn&&(this.createBtn.textContent="\u4F5C\u6210\u4E2D...",this.createBtn.disabled=!0);let s=await fetch(`${t}/api/shares`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionName:e,expiresIn:n})});if(!s.ok){let i=await s.json().catch(()=>({}));throw new Error(i.error||"Failed to create share link")}let l=await s.json(),o=`${window.location.origin}${t}/s/${l.token}`;this.showResult(o),console.log(`[Toolbar] Share link created: ${o}`)}catch(s){console.error("[Toolbar] Failed to create share link:",s),alert(`\u5171\u6709\u30EA\u30F3\u30AF\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${s.message}`)}finally{this.createBtn&&(this.createBtn.textContent="\u30EA\u30F3\u30AF\u3092\u4F5C\u6210",this.createBtn.disabled=!1)}}showResult(t){this.urlInput&&(this.urlInput.value=t),this.resultSection?.classList.remove("hidden"),this.createBtn?.classList.add("hidden")}async copyUrl(){if(this.urlInput)try{await navigator.clipboard.writeText(this.urlInput.value);let t=this.copyBtn?.textContent;this.copyBtn&&(this.copyBtn.textContent="\u30B3\u30D4\u30FC\u5B8C\u4E86!",setTimeout(()=>{this.copyBtn&&(this.copyBtn.textContent=t||"\u30B3\u30D4\u30FC")},2e3))}catch{this.urlInput.select(),document.execCommand("copy"),alert("URL\u3092\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F")}}showQR(){if(!this.urlInput)return;let t=this.urlInput.value;try{let e=rt(0,"L");e.addData(t),e.make();let n=e.createDataURL(4,4),s=window.open("","qrcode","width=250,height=280");s&&(s.document.write(`
|
|
4
|
+
<!DOCTYPE html>
|
|
5
|
+
<html>
|
|
6
|
+
<head>
|
|
7
|
+
<title>QR\u30B3\u30FC\u30C9</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family: sans-serif;
|
|
11
|
+
text-align: center;
|
|
12
|
+
background: #1e1e1e;
|
|
13
|
+
color: #fff;
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 16px;
|
|
16
|
+
}
|
|
17
|
+
img { display: block; margin: 0 auto; }
|
|
18
|
+
p { font-size: 12px; margin-top: 8px; word-break: break-all; }
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<img src="${n}" alt="QR Code" />
|
|
23
|
+
<p>\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u30EA\u30F3\u30AF</p>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
26
|
+
`),s.document.close())}catch(e){console.error("[Toolbar] Failed to generate QR code:",e),alert("QR\u30B3\u30FC\u30C9\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}};var J=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}getDefaultFontSize(){return this.isMobile?this.config.font_size_default_mobile:this.config.font_size_default_pc}findTerminal(){if(window.term)return window.term;let t=document.querySelector(".xterm");return t&&t._core?t._core:null}fitTerminal(){if(window.fitAddon&&typeof window.fitAddon.fit=="function"){window.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via fitAddon");return}let t=window.term;if(t&&t.fitAddon&&typeof t.fitAddon.fit=="function"){t.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via term.fitAddon");return}window.dispatchEvent(new Event("resize")),console.log("[Toolbar] Dispatched resize event")}getCurrentFontSize(){let t=this.findTerminal();return t?.options?t.options.fontSize??this.getDefaultFontSize():this.getDefaultFontSize()}setFontSize(t){let e=this.findTerminal();if(!e?.options)return console.log("[Toolbar] Terminal not found for zoom"),!1;let n=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,t));return e.options.fontSize=n,this.fitTerminal(),console.log("[Toolbar] Font size changed to "+n),!0}zoomTerminal(t){let e=this.getCurrentFontSize();return this.setFontSize(e+t)}copySelection(){let t=this.findTerminal();if(!t)return console.log("[Toolbar] Terminal not found for copy"),Promise.resolve(!1);let e=t.getSelection();return e?navigator.clipboard.writeText(e).then(()=>(console.log("[Toolbar] Copied selection to clipboard"),!0)).catch(n=>(console.error("[Toolbar] Failed to copy:",n),!1)):(console.log("[Toolbar] No text selected"),Promise.resolve(!1))}copyAll(){let t=this.findTerminal();if(!t?.buffer?.active)return console.log("[Toolbar] Terminal buffer not found"),Promise.resolve(!1);let e=t.buffer.active,n=[];for(let l=0;l<e.length;l++){let o=e.getLine(l);o&&n.push(o.translateToString(!0))}let s=n.join(`
|
|
27
|
+
`).trimEnd();return navigator.clipboard.writeText(s).then(()=>(console.log("[Toolbar] Copied all text to clipboard"),!0)).catch(l=>(console.error("[Toolbar] Failed to copy:",l),!1))}setupBellHandler(t){let e=this.findTerminal();if(!e?.onBell){setTimeout(()=>this.setupBellHandler(t),500);return}e.onBell(()=>{console.log("[Toolbar] Bell detected (visual feedback)"),t();let n=e.element;n&&(n.classList.add("bell-flash"),setTimeout(()=>{n.classList.remove("bell-flash")},100))}),console.log("[Toolbar] Visual bell handler registered")}};var Z=class{constructor(t,e,n,s){this.touchStartPos=null;this.shiftTouchActive=!1;this.scrollTouchActive=!1;this.scrollLastY=0;this.pinchStartDistance=0;this.lastTapTime=0;this.scrollActive=!1;this.scrollBtn=null;this.config=t,this.terminal=e,this.input=n,this.modifiers=s,this.pinchStartFontSize=e.getDefaultFontSize()}bindScrollButton(t){this.scrollBtn=t}toggleScrollMode(){return this.scrollActive=!this.scrollActive,this.scrollBtn?.classList.toggle("active",this.scrollActive),this.scrollActive?console.log("[Toolbar] Scroll mode enabled - drag to scroll"):console.log("[Toolbar] Scroll mode disabled"),this.scrollActive}isScrollActive(){return this.scrollActive}setup(){this.setupShiftMouseInjection(),this.setupTouchSelection(),this.setupPinchZoom(),this.setupWheelZoom(),this.setupDoubleTap()}setupShiftMouseInjection(){let t=["mousedown","mousemove","mouseup"];for(let e of t)document.addEventListener(e,n=>{if(!(n.target.closest("#ttyd-toolbar")||n.target.closest("#ttyd-toolbar-toggle"))&&this.modifiers.isShiftActive()&&!n.shiftKey){let s=new MouseEvent(n.type,{bubbles:n.bubbles,cancelable:n.cancelable,view:n.view,detail:n.detail,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:!0,metaKey:n.metaKey,button:n.button,buttons:n.buttons,relatedTarget:n.relatedTarget});n.stopImmediatePropagation(),n.preventDefault(),n.target.dispatchEvent(s)}},!0)}dispatchMouseEvent(t,e,n){let s=new MouseEvent(t,{bubbles:!0,cancelable:!0,view:window,detail:1,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,ctrlKey:!1,altKey:!1,shiftKey:n,metaKey:!1,button:0,buttons:t==="mouseup"?0:1,relatedTarget:null});e.target.dispatchEvent(s)}setupTouchSelection(){document.addEventListener("touchstart",t=>{let e=t.target;if(!(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle"))){if(t.touches.length===1&&this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.scrollLastY=n.clientY,this.scrollTouchActive=!0,t.preventDefault()}else if(t.touches.length===1&&this.modifiers.isShiftActive()){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.shiftTouchActive=!0,t.preventDefault(),this.dispatchMouseEvent("mousedown",n,!0)}else if(t.touches.length===2&&(this.shiftTouchActive||this.scrollTouchActive))this.shiftTouchActive&&this.dispatchMouseEvent("mouseup",t.touches[0],!0),this.shiftTouchActive=!1,this.scrollTouchActive=!1,this.touchStartPos=null;else if(t.touches.length===1&&!this.modifiers.isShiftActive()&&!this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY}}}},{passive:!1,capture:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===1&&this.scrollTouchActive){t.preventDefault();let e=t.touches[0],n=this.scrollLastY-e.clientY;Math.abs(n)>=30&&(n>0?this.input.sendPage("down"):this.input.sendPage("up"),this.scrollLastY=e.clientY)}else t.touches.length===1&&this.shiftTouchActive&&(t.preventDefault(),this.dispatchMouseEvent("mousemove",t.touches[0],!0))},{passive:!1,capture:!0}),document.addEventListener("touchend",t=>{if(this.scrollTouchActive&&t.touches.length===0)this.scrollTouchActive=!1,this.touchStartPos=null;else if(this.shiftTouchActive&&t.touches.length===0){let e=t.changedTouches[0];this.dispatchMouseEvent("mouseup",e,!0),this.shiftTouchActive=!1,this.touchStartPos=null}},{passive:!0,capture:!0})}getTouchDistance(t){let e=t[0].clientX-t[1].clientX,n=t[0].clientY-t[1].clientY;return Math.sqrt(e*e+n*n)}setupPinchZoom(){document.addEventListener("touchstart",t=>{t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&(this.pinchStartDistance=this.getTouchDistance(t.touches),this.pinchStartFontSize=this.terminal.getCurrentFontSize())},{passive:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&this.pinchStartDistance>0){t.preventDefault();let n=this.getTouchDistance(t.touches)/this.pinchStartDistance,s=Math.round(this.pinchStartFontSize*n),l=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,s));this.terminal.getCurrentFontSize()!==l&&this.terminal.setFontSize(l)}},{passive:!1}),document.addEventListener("touchend",t=>{t.touches.length<2&&(this.pinchStartDistance=0)},{passive:!0})}setupWheelZoom(){document.addEventListener("wheel",t=>{if(t.ctrlKey){t.preventDefault();let e=t.deltaY>0?-2:2;this.terminal.zoomTerminal(e)}},{passive:!1})}setupDoubleTap(){document.addEventListener("touchend",t=>{let e=t.target;if(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle")||t.changedTouches.length!==1)return;let n=Date.now();n-this.lastTapTime<this.config.double_tap_delay?(this.input.sendEnter(),this.lastTapTime=0):this.lastTapTime=n},{passive:!0})}};var F=window.WebSocket,V=class{constructor(){this.ws=null;this.interceptWebSocketCreation()}interceptWebSocketCreation(){let t=this;window.WebSocket=function(e,n){let s=new F(e,n);return e.includes("/ws")&&(t.ws=s),s},window.WebSocket.prototype=F.prototype,Object.defineProperty(window.WebSocket,"CONNECTING",{value:F.CONNECTING}),Object.defineProperty(window.WebSocket,"OPEN",{value:F.OPEN}),Object.defineProperty(window.WebSocket,"CLOSING",{value:F.CLOSING}),Object.defineProperty(window.WebSocket,"CLOSED",{value:F.CLOSED})}findWebSocket(){return this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws:window.socket&&window.socket.readyState===WebSocket.OPEN?(this.ws=window.socket,this.ws):null}isConnected(){return this.findWebSocket()!==null}sendText(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let s=new TextEncoder().encode(t),l=new Uint8Array(s.length+1);return l[0]=48,l.set(s,1),e.send(l),!0}sendBytes(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let n=new Uint8Array(t.length+1);return n[0]=48,n.set(t,1),e.send(n),!0}};var tt=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),this.elements=this.getElements(),this.ws=new V,this.terminal=new J(t),this.modifiers=new G,this.input=new Y(this.ws,this.modifiers),this.search=new X(()=>this.terminal.findTerminal()),this.notifications=new Q(t),this.touch=new Z(t,this.terminal,this.input,this.modifiers),this.fontSizeManager=new W(t),this.autoRun=new j}getElements(){return{container:document.getElementById("ttyd-toolbar"),input:document.getElementById("ttyd-toolbar-input"),sendBtn:document.getElementById("ttyd-toolbar-send"),enterBtn:document.getElementById("ttyd-toolbar-enter"),zoomInBtn:document.getElementById("ttyd-toolbar-zoomin"),zoomOutBtn:document.getElementById("ttyd-toolbar-zoomout"),runBtn:document.getElementById("ttyd-toolbar-run"),toggleBtn:document.getElementById("ttyd-toolbar-toggle"),ctrlBtn:document.getElementById("ttyd-toolbar-ctrl"),altBtn:document.getElementById("ttyd-toolbar-alt"),shiftBtn:document.getElementById("ttyd-toolbar-shift"),escBtn:document.getElementById("ttyd-toolbar-esc"),tabBtn:document.getElementById("ttyd-toolbar-tab"),upBtn:document.getElementById("ttyd-toolbar-up"),downBtn:document.getElementById("ttyd-toolbar-down"),copyBtn:document.getElementById("ttyd-toolbar-copy"),copyAllBtn:document.getElementById("ttyd-toolbar-copyall"),autoBtn:document.getElementById("ttyd-toolbar-auto"),minimizeBtn:document.getElementById("ttyd-toolbar-minimize"),scrollBtn:document.getElementById("ttyd-toolbar-scroll"),pageUpBtn:document.getElementById("ttyd-toolbar-pageup"),pageDownBtn:document.getElementById("ttyd-toolbar-pagedown"),notifyBtn:document.getElementById("ttyd-toolbar-notify"),shareBtn:document.getElementById("ttyd-toolbar-share"),shareModal:document.getElementById("ttyd-share-modal"),shareModalClose:document.getElementById("ttyd-share-modal-close"),shareCreate:document.getElementById("ttyd-share-create"),shareResult:document.getElementById("ttyd-share-result"),shareUrl:document.getElementById("ttyd-share-url"),shareCopy:document.getElementById("ttyd-share-copy"),shareQr:document.getElementById("ttyd-share-qr"),searchBar:document.getElementById("ttyd-search-bar"),searchInput:document.getElementById("ttyd-search-input"),searchCount:document.getElementById("ttyd-search-count"),searchPrevBtn:document.getElementById("ttyd-search-prev"),searchNextBtn:document.getElementById("ttyd-search-next"),searchCaseBtn:document.getElementById("ttyd-search-case"),searchRegexBtn:document.getElementById("ttyd-search-regex"),searchCloseBtn:document.getElementById("ttyd-search-close"),searchToolbarBtn:document.getElementById("ttyd-toolbar-search")}}initialize(){this.modifiers.bindElements(this.elements.ctrlBtn,this.elements.altBtn,this.elements.shiftBtn),this.search.bindElements(this.elements.searchBar,this.elements.searchInput,this.elements.searchCount,this.elements.searchCaseBtn,this.elements.searchRegexBtn),this.notifications.bindElement(this.elements.notifyBtn),this.share=new $(this.config),this.share.bindElements(this.elements.shareBtn,this.elements.shareModal,this.elements.shareModalClose,this.elements.shareCreate,this.elements.shareResult,this.elements.shareUrl,this.elements.shareCopy,this.elements.shareQr),this.touch.bindScrollButton(this.elements.scrollBtn),this.autoRun.bindElement(this.elements.autoBtn),this.setupEventListeners(),this.touch.setup(),setTimeout(()=>{this.terminal.setupBellHandler(()=>{})},1e3),this.applyStoredFontSize(),this.setupVisibilityHandler(),this.isMobile&&(setTimeout(()=>this.toggleToolbar(!0),1e3),setTimeout(()=>this.showOnboarding(),1500)),console.log("[Toolbar] Loaded. "+(this.isMobile?"Mobile mode.":"Press Ctrl+J or click keyboard button to toggle."))}setupEventListeners(){let{elements:t}=this;t.sendBtn.addEventListener("click",e=>{e.preventDefault(),this.submitInput()}),t.enterBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEnter()}),t.runBtn.addEventListener("click",e=>{e.preventDefault(),this.runInput()}),t.zoomInBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.zoomOutBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(-2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.ctrlBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("ctrl")}),t.altBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("alt")}),t.shiftBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("shift")}),t.autoBtn.addEventListener("click",e=>{e.preventDefault(),this.autoRun.toggle()}),t.escBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEsc()}),t.tabBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendTab()}),t.upBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("up")}),t.downBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("down")}),t.pageUpBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("up")}),t.pageDownBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("down")}),t.copyBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copySelection()}),t.copyAllBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copyAll()}),t.scrollBtn.addEventListener("click",e=>{e.preventDefault(),this.touch.toggleScrollMode()}),t.notifyBtn.addEventListener("click",e=>{e.preventDefault(),this.notifications.toggle()}),t.minimizeBtn.addEventListener("click",e=>{e.preventDefault(),t.container.classList.toggle("minimized"),t.minimizeBtn.textContent=t.container.classList.contains("minimized")?"\u25B2":"\u25BC",setTimeout(()=>this.terminal.fitTerminal(),100)}),t.toggleBtn.addEventListener("click",e=>{e.preventDefault(),this.toggleToolbar()}),this.setupSearchEvents(),this.setupInputEvents(),this.setupKeyboardShortcuts()}setupSearchEvents(){let{elements:t}=this;t.searchToolbarBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle()}),t.searchCloseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle(!1)}),t.searchNextBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findNext()}),t.searchPrevBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findPrevious()}),t.searchCaseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleCaseSensitive()}),t.searchRegexBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleRegex()}),t.searchInput.addEventListener("input",()=>{this.search.doSearch()}),t.searchInput.addEventListener("keydown",e=>{e.key==="Enter"&&!e.isComposing?(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext()):e.key==="Escape"?(e.preventDefault(),this.search.toggle(!1)):e.key==="F3"&&(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext())})}setupInputEvents(){let{input:t}=this.elements;t.addEventListener("input",()=>this.adjustTextareaHeight()),t.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&!e.isComposing?(e.preventDefault(),this.submitInput()):e.key==="Escape"&&(e.preventDefault(),this.toggleToolbar(!1))})}setupKeyboardShortcuts(){document.addEventListener("keydown",t=>{t.ctrlKey&&t.key==="j"&&(t.preventDefault(),this.toggleToolbar()),t.ctrlKey&&t.shiftKey&&t.key==="F"&&(t.preventDefault(),this.search.toggle())})}adjustTextareaHeight(){let t=this.elements.input;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,120)+"px"}submitInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),this.autoRun.isActive()&&setTimeout(()=>this.input.sendEnter(),1e3))}runInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),setTimeout(()=>this.input.sendEnter(),1e3))}toggleToolbar(t){let{container:e,input:n}=this.elements;typeof t=="boolean"?e.classList.toggle("hidden",!t):e.classList.toggle("hidden"),e.classList.contains("hidden")?(document.querySelector(".xterm-helper-textarea")?.focus(),setTimeout(()=>this.terminal.fitTerminal(),100)):(n.focus(),setTimeout(()=>this.terminal.fitTerminal(),100))}applyStoredFontSize(){let t=()=>{let e=this.terminal.findTerminal();if(e?.options){let n=this.fontSizeManager.load();e.options.fontSize=n,this.terminal.fitTerminal(),console.log("[Toolbar] Restored font size: "+n)}};setTimeout(t,500),setTimeout(t,1500)}setupVisibilityHandler(){document.addEventListener("visibilitychange",()=>{document.hidden||this.ws.isConnected()||(console.log("[Toolbar] Connection lost, reloading..."),location.reload())})}showOnboarding(){let t=document.getElementById("ttyd-toolbar-onboarding");if(!t)return;try{if(localStorage.getItem(C.ONBOARDING_SHOWN)){t.remove();return}}catch{}t.style.display="block";let e=document.getElementById("ttyd-toolbar-onboarding-close");e&&e.addEventListener("click",()=>{t.remove();try{localStorage.setItem(C.ONBOARDING_SHOWN,"1")}catch{}}),setTimeout(()=>{if(t.parentNode){t.remove();try{localStorage.setItem(C.ONBOARDING_SHOWN,"1")}catch{}}},15e3)}},at=window.__TOOLBAR_CONFIG__;at?new tt(at).initialize():console.error("[Toolbar] Configuration not found. Make sure __TOOLBAR_CONFIG__ is set.");})();
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ttyd-mux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "ttyd session multiplexer - manage multiple ttyd+tmux web terminal sessions / 複数の ttyd+tmux Web ターミナルセッションを管理する CLI ツール",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@biomejs/biome": "^1.9.0",
|
|
33
|
-
"esbuild": "^0.24.0",
|
|
34
33
|
"@playwright/test": "^1.58.2",
|
|
35
34
|
"@types/bun": "latest",
|
|
36
35
|
"@types/http-proxy": "^1.17.14",
|
|
@@ -38,6 +37,7 @@
|
|
|
38
37
|
"@types/proper-lockfile": "^4.1.4",
|
|
39
38
|
"@types/web-push": "^3.6.4",
|
|
40
39
|
"@types/ws": "^8.18.1",
|
|
40
|
+
"esbuild": "^0.24.0",
|
|
41
41
|
"playwright": "^1.58.2",
|
|
42
42
|
"tsc-alias": "^1.8.16",
|
|
43
43
|
"typescript": "^5.6.0"
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"commander": "^14.0.2",
|
|
73
73
|
"http-proxy": "^1.18.1",
|
|
74
74
|
"proper-lockfile": "^4.1.2",
|
|
75
|
+
"qrcode-generator": "^2.0.4",
|
|
75
76
|
"web-push": "^3.6.7",
|
|
76
77
|
"ws": "^8.19.0",
|
|
77
78
|
"yaml": "^2.6.0",
|