tabby-sftp-ui 0.1.0 → 0.2.0

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 CHANGED
@@ -5,6 +5,8 @@
5
5
  This plugin adds a **Termius‑style two‑pane SFTP file manager** to [Tabby](https://tabby.sh).
6
6
  It integrates directly with your existing SSH tabs and uses Tabby's native SFTP backend.
7
7
 
8
+ If you find this useful, please **star the repo**: [growingupfirst/tabby-sftp-ui](https://github.com/growingupfirst/tabby-sftp-ui)
9
+
8
10
  ### Features
9
11
 
10
12
  - **SFTP‑UI button in terminal toolbar** – opens the SFTP manager for the active SSH session.
@@ -122,8 +124,13 @@ Then restart Tabby.
122
124
  - Optional inline file editor for small text files.
123
125
  - Configurable keyboard shortcuts for common actions.
124
126
 
125
- ### License
127
+ ### Changelog
126
128
 
127
- MIT — see `LICENSE`.
129
+ - **0.2.0**
130
+ - UI: removed the main toolbar SFTP icon next to Settings (terminal button remains).
131
+ - **0.1.0**
132
+ - Initial release.
128
133
 
134
+ ### Problems
135
+ - When reopening Tabby, the SFTP UI tabs are blank. Please contact me in [Telegram](https://t.me/Gr0w1ngUp) if you know how to fix this.
129
136
 
package/dist/index.js CHANGED
@@ -2191,69 +2191,6 @@ SftpTerminalDecorator = __decorate([
2191
2191
 
2192
2192
 
2193
2193
 
2194
- /***/ },
2195
-
2196
- /***/ "./src/sftp-toolbar-buttons.ts"
2197
- /*!*************************************!*\
2198
- !*** ./src/sftp-toolbar-buttons.ts ***!
2199
- \*************************************/
2200
- (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2201
-
2202
- __webpack_require__.r(__webpack_exports__);
2203
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2204
- /* harmony export */ SftpToolbarButtons: () => (/* binding */ SftpToolbarButtons)
2205
- /* harmony export */ });
2206
- /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "@angular/core");
2207
- /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_angular_core__WEBPACK_IMPORTED_MODULE_0__);
2208
- /* harmony import */ var tabby_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tabby-core */ "tabby-core");
2209
- /* harmony import */ var tabby_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(tabby_core__WEBPACK_IMPORTED_MODULE_1__);
2210
- /* harmony import */ var _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sftp-manager-tab.component */ "./src/sftp-manager-tab.component.ts");
2211
- var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
2212
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2213
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2214
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2215
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2216
- };
2217
- var __metadata = (undefined && undefined.__metadata) || function (k, v) {
2218
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2219
- };
2220
-
2221
-
2222
-
2223
- let SftpToolbarButtons = class SftpToolbarButtons extends tabby_core__WEBPACK_IMPORTED_MODULE_1__.ToolbarButtonProvider {
2224
- constructor(app) {
2225
- super();
2226
- this.app = app;
2227
- }
2228
- provide() {
2229
- return [
2230
- {
2231
- title: 'SFTP',
2232
- weight: 10,
2233
- icon: `
2234
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2235
- <path d="M3 7h5l2 2h11a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2z"/>
2236
- <path d="M12 12v6"/>
2237
- <path d="M9 15l3 3 3-3"/>
2238
- </svg>
2239
- `,
2240
- click: () => {
2241
- const tab = this.app.openNewTab({
2242
- type: _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_2__.SftpManagerTabComponent,
2243
- });
2244
- tab.setTitle('SFTP');
2245
- },
2246
- },
2247
- ];
2248
- }
2249
- };
2250
- SftpToolbarButtons = __decorate([
2251
- (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable)(),
2252
- __metadata("design:paramtypes", [tabby_core__WEBPACK_IMPORTED_MODULE_1__.AppService])
2253
- ], SftpToolbarButtons);
2254
-
2255
-
2256
-
2257
2194
  /***/ },
2258
2195
 
2259
2196
  /***/ "./src/sftp-ui.service.ts"
@@ -2551,7 +2488,7 @@ var __webpack_exports__ = {};
2551
2488
  \**********************/
2552
2489
  __webpack_require__.r(__webpack_exports__);
2553
2490
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2554
- /* harmony export */ SftpManagerTabComponent: () => (/* reexport safe */ _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_6__.SftpManagerTabComponent),
2491
+ /* harmony export */ SftpManagerTabComponent: () => (/* reexport safe */ _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_5__.SftpManagerTabComponent),
2555
2492
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2556
2493
  /* harmony export */ });
2557
2494
  /* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/common */ "@angular/common");
@@ -2564,12 +2501,11 @@ __webpack_require__.r(__webpack_exports__);
2564
2501
  /* harmony import */ var tabby_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(tabby_core__WEBPACK_IMPORTED_MODULE_3__);
2565
2502
  /* harmony import */ var tabby_terminal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tabby-terminal */ "tabby-terminal");
2566
2503
  /* harmony import */ var tabby_terminal__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(tabby_terminal__WEBPACK_IMPORTED_MODULE_4__);
2567
- /* harmony import */ var _sftp_toolbar_buttons__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./sftp-toolbar-buttons */ "./src/sftp-toolbar-buttons.ts");
2568
- /* harmony import */ var _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./sftp-manager-tab.component */ "./src/sftp-manager-tab.component.ts");
2569
- /* harmony import */ var _sftp_context_menu__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sftp-context-menu */ "./src/sftp-context-menu.ts");
2570
- /* harmony import */ var _sftp_hotkey__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sftp-hotkey */ "./src/sftp-hotkey.ts");
2571
- /* harmony import */ var _sftp_ui_service__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./sftp-ui.service */ "./src/sftp-ui.service.ts");
2572
- /* harmony import */ var _sftp_terminal_decorator__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./sftp-terminal-decorator */ "./src/sftp-terminal-decorator.ts");
2504
+ /* harmony import */ var _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./sftp-manager-tab.component */ "./src/sftp-manager-tab.component.ts");
2505
+ /* harmony import */ var _sftp_context_menu__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./sftp-context-menu */ "./src/sftp-context-menu.ts");
2506
+ /* harmony import */ var _sftp_hotkey__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sftp-hotkey */ "./src/sftp-hotkey.ts");
2507
+ /* harmony import */ var _sftp_ui_service__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sftp-ui.service */ "./src/sftp-ui.service.ts");
2508
+ /* harmony import */ var _sftp_terminal_decorator__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./sftp-terminal-decorator */ "./src/sftp-terminal-decorator.ts");
2573
2509
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
2574
2510
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2575
2511
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -2589,7 +2525,6 @@ var __metadata = (undefined && undefined.__metadata) || function (k, v) {
2589
2525
 
2590
2526
 
2591
2527
 
2592
-
2593
2528
  let SftpUiModule = class SftpUiModule {
2594
2529
  constructor(_) { }
2595
2530
  };
@@ -2600,17 +2535,16 @@ SftpUiModule = __decorate([
2600
2535
  _angular_forms__WEBPACK_IMPORTED_MODULE_1__.FormsModule,
2601
2536
  ],
2602
2537
  declarations: [
2603
- _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_6__.SftpManagerTabComponent,
2538
+ _sftp_manager_tab_component__WEBPACK_IMPORTED_MODULE_5__.SftpManagerTabComponent,
2604
2539
  ],
2605
2540
  providers: [
2606
- { provide: tabby_core__WEBPACK_IMPORTED_MODULE_3__.ToolbarButtonProvider, useClass: _sftp_toolbar_buttons__WEBPACK_IMPORTED_MODULE_5__.SftpToolbarButtons, multi: true },
2607
- { provide: tabby_core__WEBPACK_IMPORTED_MODULE_3__.TabContextMenuItemProvider, useClass: _sftp_context_menu__WEBPACK_IMPORTED_MODULE_7__.SftpContextMenuProvider, multi: true },
2608
- { provide: tabby_core__WEBPACK_IMPORTED_MODULE_3__.HotkeyProvider, useClass: _sftp_hotkey__WEBPACK_IMPORTED_MODULE_8__.SftpUiHotkeyProvider, multi: true },
2609
- { provide: tabby_terminal__WEBPACK_IMPORTED_MODULE_4__.TerminalDecorator, useClass: _sftp_terminal_decorator__WEBPACK_IMPORTED_MODULE_10__.SftpTerminalDecorator, multi: true },
2610
- _sftp_ui_service__WEBPACK_IMPORTED_MODULE_9__.SftpUiService,
2541
+ { provide: tabby_core__WEBPACK_IMPORTED_MODULE_3__.TabContextMenuItemProvider, useClass: _sftp_context_menu__WEBPACK_IMPORTED_MODULE_6__.SftpContextMenuProvider, multi: true },
2542
+ { provide: tabby_core__WEBPACK_IMPORTED_MODULE_3__.HotkeyProvider, useClass: _sftp_hotkey__WEBPACK_IMPORTED_MODULE_7__.SftpUiHotkeyProvider, multi: true },
2543
+ { provide: tabby_terminal__WEBPACK_IMPORTED_MODULE_4__.TerminalDecorator, useClass: _sftp_terminal_decorator__WEBPACK_IMPORTED_MODULE_9__.SftpTerminalDecorator, multi: true },
2544
+ _sftp_ui_service__WEBPACK_IMPORTED_MODULE_8__.SftpUiService,
2611
2545
  ],
2612
2546
  }),
2613
- __metadata("design:paramtypes", [_sftp_ui_service__WEBPACK_IMPORTED_MODULE_9__.SftpUiService])
2547
+ __metadata("design:paramtypes", [_sftp_ui_service__WEBPACK_IMPORTED_MODULE_8__.SftpUiService])
2614
2548
  ], SftpUiModule);
2615
2549
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SftpUiModule);
2616
2550
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;;;;;;;;;;;;;;;;;;;;;ACVwB;AACI;AAEyB;AAE9C,MAAM,mBAAoB,SAAQ,kDAAU;IAIjD,YAAqB,QAAgB;QACnC,KAAK,EAAE;QADY,aAAQ,GAAR,QAAQ,CAAQ;QAH7B,OAAE,GAAkB,IAAI;QACxB,aAAQ,GAAG,CAAC;IAIpB,CAAC;IAED,OAAO;QACL,OAAO,0CAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;IACrC,CAAC;IAED,OAAO;QACL,OAAO,KAAK;IACd,CAAC;IAED,OAAO;QACL,IAAI,CAAC;YACH,OAAO,wCAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,wCAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;QAC3C,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,IAAI,CAAC;QAC1C,MAAM,SAAS,GAAG,wCAAW,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;QACzE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,SAAS;QAC1B,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;QAChC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC;IACnC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,yCAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI;QAChB,CAAC;IACH,CAAC;CACF;AAEM,MAAM,qBAAsB,SAAQ,oDAAY;IAGrD,YAAqB,UAAkB,EAAU,IAAY,EAAU,IAAY;QACjF,KAAK,EAAE;QADY,eAAU,GAAV,UAAU,CAAQ;QAAU,SAAI,GAAJ,IAAI,CAAQ;QAAU,SAAI,GAAJ,IAAI,CAAQ;QAF3E,OAAE,GAAkB,IAAI;IAIhC,CAAC;IAED,OAAO;QACL,OAAO,0CAAa,CAAC,IAAI,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI;IAClB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI;IAClB,CAAC;IAED,KAAK,CAAC,KAAK,CAAE,MAAc;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,wCAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC;QAC7C,CAAC;QACD,yCAAY,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC;QAC7B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,yCAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI;QAChB,CAAC;IACH,CAAC;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClGyC;AACa;AAEN;AAG1C,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,kEAA0B;IACrE,YACU,MAAqB;QAE7B,KAAK,EAAE;QAFC,WAAM,GAAN,MAAM,CAAe;IAG/B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO;YACL;gBACE,KAAK,EAAE,cAAc;gBACrB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;aAChC;SACF;IACH,CAAC;CACF;AAfY,uBAAuB;IADnC,yDAAU,EAAE;qCAGO,2DAAa;GAFpB,uBAAuB,CAenC;;;;;;;;;;;;;;;;;;;;;;;;;;ACrByC;AACC;AAGpC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sDAAc;IACtD,KAAK,CAAC,OAAO;QACX,OAAO;YACL,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE;SAC7C;IACH,CAAC;CACF;AANY,oBAAoB;IADhC,yDAAU,EAAE;GACA,oBAAoB,CAMhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACV2B;AACJ;AACS;AACL;AAE6C;AAC4C;AAEvC;AACmB;AA2W1F,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,wDAAgB;IAsF3D,YACE,QAAkB,EACV,IAA2B,EAC3B,eAAgC,EAChC,GAAe;QAEvB,sGAAsG;QACtG,sDAAsD;QACtD,KAAK,CAAC,QAAQ,CAAC;QANP,SAAI,GAAJ,IAAI,CAAuB;QAC3B,oBAAe,GAAf,eAAe,CAAiB;QAChC,QAAG,GAAH,GAAG,CAAY;QAzFzB,2DAA2D;QAC3D,eAAU,GAA0B,IAAI;QACxC,YAAO,GAAQ,IAAI;QAEnB,eAAU,GAAG,KAAK;QAClB,cAAS,GAAG,KAAK;QAEjB,oEAAoE;QACpE,SAAI,GAAG,EAAE;QACT,SAAI,GAAG,EAAE;QACT,aAAQ,GAAG,EAAE;QACb,aAAQ,GAAG,EAAE;QAEb,cAAS,GAAG,uCAAU,EAAE;QACxB,iBAAY,GAAiB,EAAE;QAE/B,eAAU,GAAG,GAAG;QAChB,kBAAa,GAAe,EAAE;QAEtB,gBAAW,GAA2B,IAAI;QAElD,oBAAe,GAAG,KAAK;QACvB,qBAAgB,GAAG,KAAK;QAExB,cAAS,GAMJ,EAAE;QAEC,mBAAc,GAAkB,IAAI;QAC5C,gBAAW,GAAG,EAAE;QAChB,iBAAY,GAAG,EAAE;QACjB,oBAAe,GAAG,IAAI,CAAC,UAAU;QACjC,mBAAc,GAAG,IAAI,CAAC,SAAS;QACvB,2BAAsB,GAAgB,IAAI,GAAG,EAAE;QAC/C,4BAAuB,GAAgB,IAAI,GAAG,EAAE;QAChD,gBAAW,GAAiC,MAAM;QAClD,iBAAY,GAAG,IAAI;QACnB,iBAAY,GAAiC,MAAM;QACnD,kBAAa,GAAG,IAAI;QACpB,eAAU,GAOP,IAAI;QACP,gBAAW,GAOR,IAAI;QACf,oBAAe,GAAG,KAAK;QACvB,qBAAgB,GAAG,KAAK;QACxB,kBAAa,GAAiB,EAAE;QAChC,mBAAc,GAAe,EAAE;QAC/B,oBAAe,GAAG,EAAE;QACpB,qBAAgB,GAAG,EAAE;QACrB,qBAAgB,GAAG,EAAE;QACrB,sBAAiB,GAAG,EAAE;QACd,2BAAsB,GAAkB,IAAI;QAC5C,4BAAuB,GAAkB,IAAI;QAErD,yBAAoB,GAAG,KAAK;QAC5B,sBAAiB,GAA8B,IAAI;QACnD,sBAAiB,GAAG,EAAE;QACd,uBAAkB,GAAiB,EAAE;QACrC,wBAAmB,GAAe,EAAE;QAEpC,sBAAiB,GAAwF,IAAI,GAAG,EAAE;QAC1H,qBAAgB,GAAuD,EAAE;QACzE,mBAAc,GAAuD,EAAE;QACvE,mBAAc,GAAU,EAAE;QAC1B,qBAAgB,GAAG,KAAK;QACxB,eAAU,GAAG,CAAC;QACd,eAAU,GAAG,CAAC;QACd,mBAAc,GAA2C,EAAE;QAWzD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,uDAAsB,CAAC;QAEpD,gEAAgE;QAChE,MAAM,IAAI,GAAG,uCAAU,EAAE;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACrE,MAAM,OAAO,GAAG,sCAAS,CAAC,IAAI,EAAE,SAAS,CAAC;QAC1C,MAAM,SAAS,GAAG,sCAAS,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9C,MAAM,SAAS,GAAG,sCAAS,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9C,IAAI,0CAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAChF,CAAC;QACD,IAAI,0CAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtF,CAAC;QACD,IAAI,0CAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtF,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE;QACzB,KAAK,IAAI,CAAC,YAAY,EAAE;QAExB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACpG,CAAC,EAAE,IAAI,CAAC;IACV,CAAC;IAED,QAAQ;QACN,sEAAsE;QACtE,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YACzB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;QACpC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,KAAK,IAAI,CAAC,OAAO,EAAE;QACrB,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC;YACxD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;YACtE,IAAI,CAAC,SAAS,GAAG,IAAI;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,EAAE;YAC7C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;YACtC,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,WAAW,GAAG,IAAI;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK;QACtB,IAAI,CAAC,aAAa,GAAG,EAAE;IACzB,CAAC;IAED,UAAU;QACR,MAAM,MAAM,GAAG,yCAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,OAAO,MAAM,KAAK,IAAI,CAAC,SAAS;IAClC,CAAC;IAED,OAAO;QACL,MAAM,MAAM,GAAG,yCAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,MAAM;YACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;YACpC,KAAK,IAAI,CAAC,YAAY,EAAE;QAC1B,CAAC;IACH,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC/C,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,uCAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAChD,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAC3C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,gDAAU,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9C,MAAM,OAAO,GAAiB,EAAE;YAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,QAAQ,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,QAAQ,CAAC;oBAClC,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI;wBACJ,QAAQ;wBACR,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE;wBAC7B,IAAI,EAAE,EAAE,CAAC,IAAI;wBACb,OAAO,EAAE,EAAE,CAAC,OAAO;qBACpB,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,kCAAkC;gBACpC,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY,GAAG,OAAO;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,SAAS,CAAE,CAAa;QACtB,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,QAAQ;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;QACpC,KAAK,IAAI,CAAC,YAAY,EAAE;IAC1B,CAAC;IAED,UAAU,CAAE,CAAW;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,QAAQ;YAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;YACtC,KAAK,IAAI,CAAC,aAAa,EAAE;QAC3B,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,UAAU,CAAE,EAAa;QACvB,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,gBAAgB,CAAE,KAAiB,EAAE,KAAiB;QACpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;QACvC,CAAC;IACH,CAAC;IAED,iBAAiB,CAAE,KAAe,EAAE,KAAiB;QACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC;QACxC,CAAC;IACH,CAAC;IAED,WAAW,CAAE,KAAiB,EAAE,KAAiB;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,EAAE;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ;QAC9B,IAAI,OAAO,IAAI,IAAI,CAAC,sBAAsB,IAAI,IAAI,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,sBAAsB,GAAG,KAAK;gBACpD,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC;gBACtC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;YACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACtC,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC;YACjD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,sBAAsB,GAAG,KAAK;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC;YAC5B,IAAI,CAAC,sBAAsB,GAAG,KAAK;QACrC,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;QACnD,CAAC;IACH,CAAC;IAED,eAAe,CAAE,KAAiB;QAChC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC3C,CAAC;IAED,YAAY,CAAE,KAAe,EAAE,KAAiB;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,wBAAwB,EAAE;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ;QAC9B,IAAI,OAAO,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,EAAE,CAAC;YACpD,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,uBAAuB,GAAG,KAAK;gBACrD,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC;gBACvC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACvC,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC;YACvD,CAAC;YACD,IAAI,CAAC,uBAAuB,GAAG,KAAK;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,CAAC;YAC7B,IAAI,CAAC,uBAAuB,GAAG,KAAK;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI;YACnD,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,iBAAiB,GAAG,YAAY;QACvC,CAAC;IACH,CAAC;IAED,gBAAgB,CAAE,KAAe;QAC/B,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC5C,CAAC;IAED,YAAY,CAAE,KAAmC;QAC/C,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,GAAG,KAAK;YACxB,IAAI,CAAC,YAAY,GAAG,IAAI;QAC1B,CAAC;IACH,CAAC;IAED,aAAa,CAAE,KAAmC;QAChD,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,aAAa;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,KAAK;YACzB,IAAI,CAAC,aAAa,GAAG,IAAI;QAC3B,CAAC;IACH,CAAC;IAED,gBAAgB,CAAE,EAAa,EAAE,CAAa;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtG,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,wCAAwC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAE/F,8DAA8D;QAC9D,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YACvF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC;QACpD,CAAC;QACD,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,CAAE,EAAE,CAAC,MAAsB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,iBAAiB,CAAE,EAAa,EAAE,IAAc;QAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/G,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,yCAAyC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAEhG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,OAAO,GAAgB;gBAC3B,IAAI,EAAE,aAAa;gBACnB,UAAU,EAAE,IAAI,CAAC,QAAQ;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB;YACD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC;QACvD,CAAC;QACD,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,CAAE,EAAE,CAAC,MAAsB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,cAAc,CAAE,EAAa;QACjC,EAAE,CAAC,cAAc,EAAE;QACnB,IAAI,CAAC,gBAAgB,GAAG,KAAK;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,CAAC;QACnE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,OAAoB;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC;YACvE,MAAM,MAAM,GAAG,IAAI,iEAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,QAAQ,CAAC;YACxE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC;YACvD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,EAAa;QAChC,EAAE,CAAC,cAAc,EAAE;QACnB,IAAI,CAAC,eAAe,GAAG,KAAK;QAC5B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,CAAC;QACnE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,OAAoB;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC;YAClC,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACjF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC;YACvE,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACvD,MAAM,IAAI,CAAC,YAAY,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,uBAAuB;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY;QAE7B,IAAI,IAAI,CAAC,UAAU;YACjB,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,UAAU;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM;YACjC,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,UAAU;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM;YACjC,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM;QAC/B,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,IAAI,OAAO,GAAG,UAAU;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE;QACzE,OAAO,MAAM;IACf,CAAC;IAED,wBAAwB;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa;QAE9B,IAAI,IAAI,CAAC,WAAW;YAClB,IAAI,CAAC,WAAW,CAAC,UAAU,KAAK,UAAU;YAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,MAAM;YAClC,IAAI,CAAC,WAAW,CAAC,UAAU,KAAK,UAAU;YAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,MAAM;YAClC,IAAI,CAAC,WAAW,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM;QAChC,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,IAAI,OAAO,GAAG,UAAU;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE;QAC1E,OAAO,MAAM;IACf,CAAC;IAEO,gBAAgB,CAAE,OAAqB;QAC7C,MAAM,QAAQ,GAAG,CAAC,CAAa,EAAE,CAAa,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;QAChG,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW;QAC9B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC;YACrB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM;YAC9C,CAAC;YACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;YAC3B,CAAC;YACD,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC;YACzB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC;YACzB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;QAC3B,CAAC,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAE,OAAmB;QAC5C,MAAM,QAAQ,GAAG,CAAC,CAAW,EAAE,CAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5F,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY;QAC/B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC;YACrB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM;YAC9C,CAAC;YACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;YAC3B,CAAC;YACD,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC;YACvC,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC;YACvC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;QAC3B,CAAC,CAAC;IACJ,CAAC;IAEO,mBAAmB,CAAE,EAAa;QACxC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,wCAAwC,CAAC;QAC9E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI;QACb,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,GAAG;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI;IACb,CAAC;IAEO,oBAAoB,CAAE,EAAa;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,yCAAyC,CAAC;QAC/E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI;QACb,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,GAAG;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI;IACb,CAAC;IAED,UAAU,CAAE,KAAc;QACxB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE;QACX,CAAC;QACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,KAAK;QACd,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;QACjD,IAAI,KAAK,GAAG,KAAK;QACjB,IAAI,SAAS,GAAG,CAAC;QACjB,OAAO,KAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,IAAI,IAAI;YACb,SAAS,EAAE;QACb,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;IACvD,CAAC;IAED,WAAW,CAAE,cAAuB;QAClC,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5D,OAAO,EAAE;QACX,CAAC;QACD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,OAAO;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC7D,IAAI,KAAK,GAAG,cAAc;QAC1B,IAAI,SAAS,GAAG,CAAC;QACjB,OAAO,KAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,IAAI,IAAI;YACb,SAAS,EAAE;QACb,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;IACvD,CAAC;IAED,mBAAmB,CAAE,CAAa;QAChC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChD,OAAO,GAAG;QACZ,CAAC;QACD,OAAO,EAAE;IACX,CAAC;IAED,oBAAoB,CAAE,CAAW;QAC/B,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ;QACtB,IAAK,CAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU,CAAE,CAAS,CAAC,OAAO,CAAC;QAC5C,CAAC;QACD,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,GAAG;QACZ,CAAC;QACD,OAAO,EAAE;IACX,CAAC;IAED,oBAAoB,CAAE,KAAiB,EAAE,EAAa;QACpD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAE,KAAiB,EAAE,EAAa;QACtD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;QACnB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ;QAChC,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC9B,SAAQ;gBACV,CAAC;gBACD,gDAAgD;gBAChD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,qCAAQ,CAAC,EAAE,CAAC;oBACzC,SAAQ;gBACV,CAAC;gBACD,MAAM,IAAI,GAAG,0CAAa,CAAC,GAAG,CAAC;gBAC/B,MAAM,GAAG,GAAG,sCAAS,CAAC,SAAS,EAAE,IAAI,CAAC;gBACtC,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;oBAChB,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,+CAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAC3B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,CAAC,YAAY,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,qBAAqB,CAAE,KAAe,EAAE,EAAa;QACnD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAE,KAAe,EAAE,EAAa;QACrD,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/D,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;QACnB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ;QAChC,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC9B,SAAQ;gBACV,CAAC;gBACD,gDAAgD;gBAChD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;oBACpC,SAAQ;gBACV,CAAC;gBACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;gBACvD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,SAAQ;gBACV,CAAC;gBACD,MAAM,GAAG,GAAG,uCAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBAC5C,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;oBAChB,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC;gBACzC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACxD,MAAM,MAAM,GAA2C,EAAE;QACzD,IAAI,OAAO,GAAG,GAAG;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,EAAE;YACvD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,MAAM;IACf,CAAC;IAED,wBAAwB,CAAE,KAAa;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI;QAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,eAAe,IAAI,GAAG,CAAC;QACpE,IAAI,CAAC,UAAU,GAAG,MAAM;QACxB,IAAI,CAAC,eAAe,GAAG,MAAM;QAC7B,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,kBAAkB;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC;QAC7E,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,mBAAmB;QACjB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS;QAClC,MAAM,MAAM,GAAG,uCAAU,CAAC,WAAW,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,qCAAQ;QACpC,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QAClD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,qCAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACzD,MAAM,MAAM,GAA2C,EAAE;QAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,IAAI;QACtD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAE7C,IAAI,KAAK,GAAG,IAAI;QAChB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,GAAG,sCAAS,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,MAAM;IACf,CAAC;IAED,uBAAuB,CAAE,KAAa;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC;IAChC,CAAC;IAEO,aAAa,CAAE,MAAc;QACnC,IAAI,CAAC,SAAS,GAAG,MAAM;QACvB,IAAI,CAAC,cAAc,GAAG,MAAM;QAC5B,KAAK,IAAI,CAAC,YAAY,EAAE;IAC1B,CAAC;IAED,mBAAmB,CAAE,EAAU;QAC7B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC;IACjE,CAAC;IAED,qBAAqB;QACnB,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC;QACnF,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,kBAAkB,EAAE;YACzB,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,0CAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS;QAC7D,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACrF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7D,IAAI,CAAC,kBAAkB,EAAE;IAC3B,CAAC;IAED,qBAAqB,CAAE,EAAU;QAC/B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,4BAA4B,CAAE,KAAa,EAAE,KAAiB;QAC5D,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QAED,MAAM,SAAS,GAA2C,EAAE;QAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC9C,MAAM,WAAW,GAAG,KAAK,KAAK,CAAC;QAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI;QAE3B,0DAA0D;QAC1D,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAa,EAAE;YAC3B,KAAK,IAAI,IAAI,GAAG,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO;gBAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;gBACxC,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK;gBAC/B,IAAI,CAAC;oBACH,IAAI,0CAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAChC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;oBACvB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACvC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kEAAkE;YAClE,MAAM,UAAU,GAAG,yCAAY,CAAC,QAAQ,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,2CAAkB,CAAC,UAAU,CAAC;gBACpD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAG,sCAAS,CAAC,UAAU,EAAE,IAAI,CAAC;oBACxC,IAAI,CAAC;wBACH,MAAM,EAAE,GAAG,wCAAe,CAAC,IAAI,CAAC;wBAChC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;4BACrB,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;wBAC7C,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,SAAS;QAC/B,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO;QAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO;IACjC,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC1D,OAAM;YACR,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,+BAA+B,CAAC;YACxE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,cAAc,GAAG,MAAM;qBACzB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;qBAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACT,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACnE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,0CAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;oBACzD,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;iBACrB,CAAC,CAAC;YACP,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC1D,OAAM;YACR,CAAC;YACD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,+BAA+B,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnG,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,oBAAoB,CAAE,IAAqC;QACzD,IAAI,CAAC,gBAAgB,GAAG,KAAK;QAC7B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEO,kBAAkB,CAAE,CAAS;QACnC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,IAAI,CAAC,SAAS;QACvB,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE;QACrB,oFAAoF;QACpF,IAAI,uCAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,uCAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAM;QACf,CAAC;QACD,uCAAuC;QACvC,OAAO,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC;IAC1C,CAAC;IAEO,mBAAmB,CAAE,CAAS;QACpC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,GAAG;QACZ,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE;QACrB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,GAAG,MAAM;QACvB,CAAC;QACD,2BAA2B;QAC3B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;QACpC,OAAO,MAAM;IACf,CAAC;IAEO,oBAAoB;QAC1B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;QACvG,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,SAAS,QAAQ,EAAE;QAC5B,CAAC;QACD,OAAO,GAAG;IACZ,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,EAAE;YACtD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,cAAc,GAAG,GAAG;YAC3B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,cAAc,GAAG,EAAE;QAC1B,CAAC;IACH,CAAC;IAED,eAAe,CAAE,CAAM;QACrB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,EAAE;QACX,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,SAAS;IACvD,CAAC;IAED,qBAAqB,CAAE,CAAM;QAC3B,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAGD,eAAe;QACb,IAAI,CAAC,gBAAgB,GAAG,KAAK;IAC/B,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;YACrE,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;QACxC,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC9C,KAAK,+CAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;aACnC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,WAAW;QACT,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,OAAO;QAChC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC;QACpE,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAClC,CAAC;IAED,cAAc;QACZ,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC9C,KAAK,8CAAQ,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;aACvC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,oBAAoB;QAClB,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,EAAE,CAAC;YACtE,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC;YAC1D,OAAM;QACR,CAAC;QACD,KAAK,8CAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAW,CAAC;aACvC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACzE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5F,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;QACzC,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACrD,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;aACjD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,QAAQ;QACjC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC;QACrE,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAClC,CAAC;IAED,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE;QAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACrD,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;aAChC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,qBAAqB;QACnB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC7F,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC;YAC3D,OAAM;QACR,CAAC;QACD,KAAM,IAAI,CAAC,WAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;aACvD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3E,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrD,OAAM;QACR,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,SAAQ;YACV,CAAC;YACD,MAAM,eAAe,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7D,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7E,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC;YACnE,KAAK,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;iBAC/C,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,qBAAqB,CAAE,KAAiB;QACtC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC/C,KAAK,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;aAC7C,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,KAAK,CAAC,IAAI,GAAG,IAAI;QACnB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC;QACxD,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpD,CAAC,CAAC;IACN,CAAC;IAED,sBAAsB,CAAE,KAAe;QACrC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ;QAC1B,IAAK,KAAa,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC;QACrC,KAAK,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC;aACnC,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,CAAC;YAAC,KAAa,CAAC,OAAO,GAAG,IAAI;QAChC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,CAAC;QAC1C,CAAC,CAAC;IACN,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAE,IAAY;QAChD,IAAI,KAAK,GAAG,CAAC;QACb,MAAM,KAAK,GAAa,CAAC,IAAI,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI;QACvB,IAAI,OAAO,GAAG,CAAC;QACf,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY;YACjC,IAAI,KAAe;YACnB,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,gDAAU,CAAC,GAAG,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;oBAC3B,OAAO,KAAK;gBACd,CAAC;gBACD,MAAM,IAAI,GAAG,sCAAS,CAAC,GAAG,EAAE,IAAI,CAAC;gBACjC,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,IAAI,CAAC;oBAC9B,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;wBACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,KAAK,IAAI,EAAE,CAAC,IAAI;oBAClB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK;IACd,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAE,IAAY;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC;QACV,CAAC;QACD,IAAI,KAAK,GAAG,CAAC;QACb,MAAM,KAAK,GAAa,CAAC,IAAI,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI;QACvB,IAAI,OAAO,GAAG,CAAC;QACf,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY;YACjC,IAAI,OAAmB;YACvB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;oBAC3B,OAAO,KAAK;gBACd,CAAC;gBACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,KAAK,IAAI,IAAI,CAAC,IAAI;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK;IACd,CAAC;IAED,kBAAkB,CAAE,KAAiB,EAAE,KAAiB;QACtD,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,+EAA+E;IACjF,CAAC;IAED,mBAAmB,CAAE,KAAe,EAAE,KAAiB;QACrD,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QAEvB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,+EAA+E;IACjF,CAAC;IAEO,aAAa,CAAE,QAAsB,EAAE,SAAgC,EAAE,UAAkB,EAAE,SAAiB;QACpH,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAClB,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE;YACxB,UAAU;YACV,SAAS;SACV,CAAC;IACJ,CAAC;IAED,cAAc,CAAE,KAAiC;QAC/C,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,mBAAmB,CAAE,QAAsB;QACzC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,EAAE,EAAE;YAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACpF,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACjD,OAAO,OAAO;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,SAAS,CAAE,KAAoB;QAC7B,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;YACxD,KAAK,CAAC,cAAc,EAAE;YACtB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC/B,IAAI,CAAC,YAAY,EAAE;YACrB,CAAC;iBAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;gBACrC,IAAI,CAAC,WAAW,EAAE;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAEQ,OAAO;QACd,6CAA6C;QAC7C,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1D,IAAI,CAAC;gBACH,OAAO,EAAE,KAAK,EAAE;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;QAE9B,KAAK,IAAI,CAAC,UAAU,EAAE;QACtB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI;QAC5B,CAAC;QACD,KAAK,CAAC,OAAO,EAAE;IACjB,CAAC;IAED,6EAA6E;IAC7E,6CAA6C;IAC7C,iFAAiF;IACjF,6DAA6D;IACpD,KAAK,CAAC,gBAAgB,CAAE,QAAc;QAC7C,OAAO,IAAI;IACb,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB;QACnC,IAAI,CAAC,oBAAoB,GAAG,KAAK;QAEjC,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;gBAChD,IAAI,CAAC,kBAAkB,GAAG,EAAE;gBAC5B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBACpC,CAAC;gBACD,MAAM,IAAI,CAAC,YAAY,EAAE;gBACzB,IAAI,CAAC,aAAa,GAAG,EAAE;YACzB,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE;gBACjD,IAAI,CAAC,mBAAmB,GAAG,EAAE;gBAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBACrC,CAAC;gBACD,MAAM,IAAI,CAAC,aAAa,EAAE;gBAC1B,IAAI,CAAC,cAAc,GAAG,EAAE;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB,GAAG,IAAI;YAC7B,IAAI,CAAC,iBAAiB,GAAG,EAAE;QAC7B,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,oBAAoB,GAAG,KAAK;QACjC,IAAI,CAAC,iBAAiB,GAAG,IAAI;QAC7B,IAAI,CAAC,iBAAiB,GAAG,EAAE;QAC3B,IAAI,CAAC,kBAAkB,GAAG,EAAE;QAC5B,IAAI,CAAC,mBAAmB,GAAG,EAAE;IAC/B,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAE,KAAiB;QAC/C,MAAM,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAE,KAAe;QAC9C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtD,CAAC;IAEO,sBAAsB,CAAE,KAAyB,EAAE,KAAe;QACxE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM;QAC1B,MAAM,KAAK,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,yBAAyB,KAAK,GAAG;QAC1C,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACtB,OAAO,UAAU,KAAK,iBAAiB,KAAK,KAAK,IAAI,GAAG;QAC1D,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,GAAG,QAAQ;QAC7B,OAAO,UAAU,KAAK,iBAAiB,KAAK,KAAK,IAAI,QAAQ,IAAI,QAAQ;IAC3E,CAAC;IAEO,KAAK,CAAC,wBAAwB,CAAE,MAAc;QACpD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,MAAM,CAAC;YAChC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,MAAM,+CAAS,CAAC,MAAM,CAAC;gBACvB,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,CAAC,CAAC;YACxD,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,gDAAU,CAAC,MAAM,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,sCAAS,CAAC,MAAM,EAAE,IAAI,CAAC;gBACrC,MAAM,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC;YAC5C,CAAC;YACD,MAAM,8CAAQ,CAAC,MAAM,CAAC;QACxB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAE,MAAc;QACrD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAW,CAAC;YAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,gBAAgB;gBAChB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACvC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,OAAM;YACR,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAqB,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;gBAC1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;oBACrC,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;YACtC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAE,KAAe;QAC3C,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9D,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,sCAAS,CAAC,sCAAS,EAAE,EAAE,eAAe,CAAC;YACvD,MAAM,8CAAQ,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,sCAAS,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC;YAEhD,iEAAiE;YACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;YACtD,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YACvE,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC;YAC7D,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YAEnD,sDAAsD;YACtD,MAAM,OAAO,GAAG,qCAAY,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE;gBAC3E,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,KAAK,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC;gBACzC,CAAC;YACH,CAAC,CAAC;YACF,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YAEhG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAE,SAAiB;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;QAClD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,iEAAmB,CAAC,SAAS,CAAC;YACjD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC;YAChE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;YACtD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF;AA9gBC;IADC,2DAAY,CAAC,gBAAgB,CAAC;;;;8DAG9B;AA7gCU,uBAAuB;IA7VnC,wDAAS,CAAC;QACT,QAAQ,EAAE,wBAAwB;QAClC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiRT;QACD,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuER,CAAC;KACH,CAAC;qCAwFY,mDAAQ;QACJ,gEAAqB;QACV,uDAAe;QAC3B,kDAAU;GA1Fd,uBAAuB,CAyhDnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC74DyC;AACkC;AAE3B;AAG1C,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,6DAAiB;IAC1D,YACU,MAAqB;QAE7B,KAAK,EAAE;QAFC,WAAM,GAAN,MAAM,CAAe;IAG/B,CAAC;IAEQ,MAAM,CAAE,QAAkC;QACjD,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;QAEtB,yFAAyF;QACzF,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAuB,QAAQ,CAAC,OAAO,EAAE,aAAa,IAAI,IAAI;gBACxE,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO,KAAK;gBACd,CAAC;gBAED,2CAA2C;gBAC3C,MAAM,OAAO,GACV,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAwB;oBAC9D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAwB;oBAC7D,IAAI,CAAC,aAAa,CAAC,cAAc,CAAwB;gBAE5D,MAAM,SAAS,GAAG,OAAO,IAAI,IAAI;gBAEjC,IAAI,SAAS,CAAC,aAAa,CAAC,iCAAiC,CAAC,EAAE,CAAC;oBAC/D,OAAO,IAAI;gBACb,CAAC;gBAED,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;gBAC5C,GAAG,CAAC,IAAI,GAAG,QAAQ;gBACnB,iDAAiD;gBACjD,GAAG,CAAC,SAAS,GAAG,0BAA0B;gBAC1C,GAAG,CAAC,YAAY,CAAC,2BAA2B,EAAE,GAAG,CAAC;gBAClD,GAAG,CAAC,KAAK,GAAG,SAAS;gBACrB,GAAG,CAAC,WAAW,GAAG,SAAS;gBAC3B,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM;gBAChC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI;gBACvB,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU;gBAC/B,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE;oBACvC,EAAE,CAAC,eAAe,EAAE;gBACtB,CAAC,CAAC;gBACF,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;oBACnC,EAAE,CAAC,cAAc,EAAE;oBACnB,EAAE,CAAC,eAAe,EAAE;oBACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAe,CAAC;gBAC/C,CAAC,CAAC;gBAEF,oDAAoD;gBACpD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAwB;gBAC1F,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;oBAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE;oBACvG,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAC7D,CAAC,CAAC;gBAEF,IAAI,eAAe,EAAE,aAAa,EAAE,CAAC;oBACnC,uDAAuD;oBACvD,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,WAAW,CAAC;gBAC9E,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;gBAC5B,CAAC;gBAED,OAAO,IAAI;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK;YACd,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,IAAI,QAAQ,GAAG,CAAC;QAChB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,QAAQ,EAAE;YACV,IAAI,SAAS,EAAE,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;gBACjC,aAAa,CAAC,KAAK,CAAC;YACtB,CAAC;QACH,CAAC,EAAE,GAAG,CAAC;QAEP,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAS,CAAC;IAC3F,CAAC;CACF;AAhFY,qBAAqB;IADjC,yDAAU,EAAE;qCAGO,2DAAa;GAFpB,qBAAqB,CAgFjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtFyC;AACmC;AAEP;AAG/D,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,6DAAqB;IAC3D,YACU,GAAe;QAEvB,KAAK,EAAE;QAFC,QAAG,GAAH,GAAG,CAAY;IAGzB,CAAC;IAED,OAAO;QACL,OAAO;YACL;gBACE,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,EAAE;gBACV,IAAI,EAAE;;;;;;SAML;gBACD,KAAK,EAAE,GAAG,EAAE;oBACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;wBAC9B,IAAI,EAAE,gFAAuB;qBAC9B,CAAC;oBACF,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACtB,CAAC;aACF;SACF;IACH,CAAC;CACF;AA5BY,kBAAkB;IAD9B,yDAAU,EAAE;qCAGI,kDAAU;GAFd,kBAAkB,CA4B9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClCiD;AAC0D;AAEtC;AAG/D,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGxB,YACU,GAAe,EACf,OAAuB,EACvB,GAAe,EACf,IAAY,EACZ,aAAmC;QAJnC,QAAG,GAAH,GAAG,CAAY;QACf,YAAO,GAAP,OAAO,CAAgB;QACvB,QAAG,GAAH,GAAG,CAAY;QACf,SAAI,GAAJ,IAAI,CAAQ;QACZ,kBAAa,GAAb,aAAa,CAAsB;QAE3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;QAExC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;YACjC,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,EAAE;YACb,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAI;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;QACjC,MAAM,OAAO,GAAG,MAAM,YAAY,yDAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;QACjG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,gBAAgB,CAAE,SAAc;QAC9B,MAAM,UAAU,GAAG,SAAS,EAAE,UAAU,IAAI,IAAI;QAChD,MAAM,OAAO,GAAG,SAAS,EAAE,OAAO,IAAI,IAAI;QAE1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,+BAA+B,CAAC;oBACpE,OAAM;gBACR,CAAC;gBACD,MAAM,SAAS,GACb,SAAS,EAAE,WAAW;oBACtB,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,OAAO,EAAE,IAAI;oBACtB,MAAM;gBACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;oBAC9B,IAAI,EAAE,gFAAuB;oBAC7B,MAAM,EAAE;wBACN,UAAU;wBACV,OAAO;qBACR;iBACF,CAAC;gBACF,GAAG,CAAC,QAAQ,CAAC,GAAG,SAAS,SAAS,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC7C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CACF;AA1DY,aAAa;IADzB,yDAAU,EAAE;qCAKI,kDAAU;QACN,sDAAc;QAClB,kDAAU;QACT,iDAAM;QACG,4DAAoB;GARlC,aAAa,CA0DzB;;;;;;;;;;;;;;;;;;;;;;;;AChEyC;AA2BnC,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,KAAK,CAAC,kBAAkB,CAAE,UAA0B;QAClD,OAAO,MAAM,UAAU,CAAC,QAAQ,EAAE;IACpC,CAAC;CACF;AAJY,qBAAqB;IADjC,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;GACtB,qBAAqB,CAIjC;;;;;;;;;;;;AC/BD,wC;;;;;;;;;;ACAA,+B;;;;;;;;;;ACAA,6D;;;;;;;;;;ACAA,2D;;;;;;;;;;ACAA,4D;;;;;;;;;;ACAA,gD;;;;;;;;;;ACAA,kD;;;;;;;;;;ACAA,wD;;;;;;;;;;ACAA,4D;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;;;;;WC5BA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA,E;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D,E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACN8C;AACF;AACJ;AACsD;AAC5C;AAES;AACW;AACT;AACT;AACH;AACgB;AAkBlD,IAAM,YAAY,GAAlB,MAAM,YAAY;IAC/B,YAAa,CAAgB,IAAI,CAAC;CACnC;AAFoB,YAAY;IAhBhC,uDAAQ,CAAC;QACR,OAAO,EAAE;YACP,yDAAY;YACZ,uDAAW;SACZ;QACD,YAAY,EAAE;YACZ,gFAAuB;SACxB;QACD,SAAS,EAAE;YACT,EAAE,OAAO,EAAE,6DAAqB,EAAE,QAAQ,EAAE,qEAAkB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC7E,EAAE,OAAO,EAAE,kEAA0B,EAAE,QAAQ,EAAE,uEAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;YACvF,EAAE,OAAO,EAAE,sDAAc,EAAE,QAAQ,EAAE,8DAAoB,EAAE,KAAK,EAAE,IAAI,EAAE;YACxE,EAAE,OAAO,EAAE,6DAAiB,EAAE,QAAQ,EAAE,4EAAqB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC5E,2DAAa;SACd;KACF,CAAC;qCAEgB,2DAAa;GADV,YAAY,CAEhC;iEAFoB,YAAY;AAIC","sources":["webpack-tabby-sftp-ui:///webpack/universalModuleDefinition","webpack-tabby-sftp-ui:///./src/local-transfers.ts","webpack-tabby-sftp-ui:///./src/sftp-context-menu.ts","webpack-tabby-sftp-ui:///./src/sftp-hotkey.ts","webpack-tabby-sftp-ui:///./src/sftp-manager-tab.component.ts","webpack-tabby-sftp-ui:///./src/sftp-terminal-decorator.ts","webpack-tabby-sftp-ui:///./src/sftp-toolbar-buttons.ts","webpack-tabby-sftp-ui:///./src/sftp-ui.service.ts","webpack-tabby-sftp-ui:///./src/sftp.service.ts","webpack-tabby-sftp-ui:///external node-commonjs \"fs/promises\"","webpack-tabby-sftp-ui:///external node-commonjs \"os\"","webpack-tabby-sftp-ui:///external umd \"@angular/common\"","webpack-tabby-sftp-ui:///external umd \"@angular/core\"","webpack-tabby-sftp-ui:///external umd \"@angular/forms\"","webpack-tabby-sftp-ui:///external umd \"fs\"","webpack-tabby-sftp-ui:///external umd \"path\"","webpack-tabby-sftp-ui:///external umd \"tabby-core\"","webpack-tabby-sftp-ui:///external umd \"tabby-terminal\"","webpack-tabby-sftp-ui:///webpack/bootstrap","webpack-tabby-sftp-ui:///webpack/runtime/compat get default export","webpack-tabby-sftp-ui:///webpack/runtime/define property getters","webpack-tabby-sftp-ui:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-sftp-ui:///webpack/runtime/make namespace object","webpack-tabby-sftp-ui:///./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/forms\", \"@angular/core\", \"tabby-core\", \"tabby-terminal\", \"path\", \"fs\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\")) : factory(root[\"@angular/common\"], root[\"@angular/forms\"], root[\"@angular/core\"], root[\"tabby-core\"], root[\"tabby-terminal\"], root[\"path\"], root[\"fs\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(global, (__WEBPACK_EXTERNAL_MODULE__angular_common__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_fs__) => {\nreturn ","import * as fs from 'fs'\r\nimport * as path from 'path'\r\n\r\nimport { FileDownload, FileUpload } from 'tabby-core'\r\n\r\nexport class LocalPathFileUpload extends FileUpload {\r\n private fd: number | null = null\r\n private position = 0\r\n\r\n constructor (private filePath: string) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.filePath)\r\n }\r\n\r\n getMode (): number {\r\n return 0o644\r\n }\r\n\r\n getSize (): number {\r\n try {\r\n return fs.statSync(this.filePath).size\r\n } catch {\r\n return 0\r\n }\r\n }\r\n\r\n async read (): Promise<Buffer> {\r\n if (this.isCancelled()) {\r\n return Buffer.alloc(0)\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.filePath, 'r')\r\n }\r\n const buf = Buffer.allocUnsafe(256 * 1024)\r\n const bytesRead = fs.readSync(this.fd, buf, 0, buf.length, this.position)\r\n if (!bytesRead) {\r\n return Buffer.alloc(0)\r\n }\r\n this.position += bytesRead\r\n this.increaseProgress(bytesRead)\r\n return buf.subarray(0, bytesRead)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\nexport class LocalPathFileDownload extends FileDownload {\r\n private fd: number | null = null\r\n\r\n constructor (private targetPath: string, private mode: number, private size: number) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.targetPath)\r\n }\r\n\r\n getMode (): number {\r\n return this.mode\r\n }\r\n\r\n getSize (): number {\r\n return this.size\r\n }\r\n\r\n async write (buffer: Buffer): Promise<void> {\r\n if (this.isCancelled()) {\r\n return\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.targetPath, 'w')\r\n }\r\n fs.writeSync(this.fd, buffer)\r\n this.increaseProgress(buffer.length)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TabContextMenuItemProvider } from 'tabby-core'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpContextMenuProvider extends TabContextMenuItemProvider {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n async getItems (): Promise<Array<{ label: string, click: () => void }>> {\r\n return [\r\n {\r\n label: 'Open SFTP UI',\r\n click: () => this.sftpUi.open(),\r\n },\r\n ]\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { HotkeyProvider } from 'tabby-core'\r\n\r\n@Injectable()\r\nexport class SftpUiHotkeyProvider extends HotkeyProvider {\r\n async provide (): Promise<Array<{ id: string, name: string }>> {\r\n return [\r\n { id: 'open-sftp-ui', name: 'Open SFTP UI' },\r\n ]\r\n }\r\n}\r\n\r\n","import * as path from 'path'\r\nimport * as os from 'os'\r\nimport * as fs from 'fs/promises'\r\nimport * as fsSync from 'fs'\r\n\r\nimport { Component, Injector, OnInit, HostListener } from '@angular/core'\r\nimport { AppService, BaseTabComponent, FileTransfer, FileUpload, PlatformService, ProfilesService } from 'tabby-core'\r\n\r\nimport { LocalPathFileDownload, LocalPathFileUpload } from './local-transfers'\r\nimport { SftpConnectionService, SFTPFile, SFTPSessionLike, SSHSessionLike } from './sftp.service'\r\n\r\ntype LocalEntry = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n size?: number\r\n mtimeMs?: number\r\n}\r\n\r\ntype DragPayload =\r\n | { kind: 'local-file', fullPath: string, name: string }\r\n | { kind: 'remote-file', remotePath: string, name: string, size: number, mode: number }\r\n\r\n@Component({\r\n selector: 'tabby-sftp-manager-tab',\r\n template: `\r\n <div class=\"sftp-root\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\r\n <div class=\"top-profiles\" *ngIf=\"profile || recentProfiles.length\">\r\n <div class=\"current\" *ngIf=\"profile\">\r\n <span class=\"label\">Device:</span>\r\n <span class=\"value\">{{ getProfileLabel(profile) }}</span>\r\n </div>\r\n <div class=\"recent\" *ngIf=\"recentProfiles.length\">\r\n <span class=\"label\">Recent:</span>\r\n <button\r\n class=\"profile-chip\"\r\n *ngFor=\"let p of recentProfiles\"\r\n (click)=\"launchProfileFromSFTP(p)\"\r\n >\r\n {{ getProfileLabel(p) }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"sftp-body\">\r\n <div class=\"pane\">\r\n <div class=\"pane-title\">\r\n <div class=\"pane-label\">Local</div>\r\n <div class=\"pane-path\">\r\n <input\r\n [(ngModel)]=\"localPathInput\"\r\n (keyup.enter)=\"goToLocalPathInput()\"\r\n />\r\n </div>\r\n <div class=\"pane-actions\">\r\n <select class=\"path-preset\" (change)=\"onLocalPresetChange($event.target.value)\">\r\n <option value=\"\">Go to…</option>\r\n <option *ngFor=\"let p of localPathPresets\" [value]=\"p.id\">\r\n {{ p.label }}\r\n </option>\r\n </select>\r\n <button\r\n class=\"fav-toggle\"\r\n [class.active]=\"isCurrentFavorite()\"\r\n (click)=\"toggleCurrentFavorite()\"\r\n title=\"Toggle favorite for this path\"\r\n >\r\n ★\r\n </button>\r\n <select class=\"path-favorite\" (change)=\"onLocalFavoriteSelect($event.target.value)\">\r\n <option value=\"\">Favorites…</option>\r\n <option *ngFor=\"let f of localFavorites\" [value]=\"f.id\">\r\n {{ f.label }}\r\n </option>\r\n </select>\r\n <button (click)=\"localUp()\" [disabled]=\"!canLocalUp()\">Up</button>\r\n <button (click)=\"goToLocalPathInput()\">Go</button>\r\n <button (click)=\"refreshLocal()\">Refresh</button>\r\n </div>\r\n </div>\r\n <div class=\"pane-filters\">\r\n <div class=\"breadcrumbs\">\r\n <ng-container *ngFor=\"let part of getLocalBreadcrumbs(); let i = index; let last = last\">\r\n <button\r\n class=\"crumb-button\"\r\n (click)=\"navigateLocalBreadcrumb(i)\"\r\n (contextmenu)=\"onLocalBreadcrumbContextMenu(i, $event)\"\r\n >\r\n {{ part.label }}\r\n </button>\r\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\r\n </ng-container>\r\n </div>\r\n <input [(ngModel)]=\"localFilter\" placeholder=\"Filter files...\" />\r\n <label class=\"show-hidden-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenLocal\" />\r\n <span>Show hidden</span>\r\n </label>\r\n </div>\r\n <div class=\"pane-list\"\r\n (dragover)=\"onDragOver($event)\"\r\n (drop)=\"onDropOnLocal($event)\"\r\n >\r\n <div class=\"entry header\">\r\n <span class=\"icon\"></span>\r\n <span class=\"name sortable\" (click)=\"setLocalSort('name')\">Name</span>\r\n <span class=\"size sortable\" (click)=\"setLocalSort('size')\">Size</span>\r\n <span class=\"date sortable\" (click)=\"setLocalSort('modified')\">Modified</span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngFor=\"let e of getFilteredLocalEntries()\"\r\n (click)=\"selectLocal(e, $event)\"\r\n (dblclick)=\"openLocal(e)\"\r\n (mousedown)=\"onLocalMouseDown(e, $event)\"\r\n (contextmenu)=\"onLocalContextMenu(e, $event)\"\r\n (dragover)=\"onLocalEntryDragOver(e, $event)\"\r\n (drop)=\"onLocalEntryDrop(e, $event)\"\r\n [class.drop-target]=\"localDropActive\"\r\n [class.selected]=\"isLocalSelected(e)\"\r\n [draggable]=\"true\"\r\n (dragstart)=\"onDragStartLocal($event, e)\"\r\n >\r\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\r\n <span class=\"name\">{{ e.name }}</span>\r\n <span class=\"size\">{{ getLocalSizeDisplay(e) }}</span>\r\n <span class=\"date\">{{ e.mtimeMs ? (e.mtimeMs | date:'yyyy-MM-dd HH:mm') : '' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"pane-actions-bar\">\r\n <div class=\"selection\" *ngIf=\"selectedLocal.length\">\r\n Selected: {{ selectedLocal.length === 1 ? selectedLocal[0].name : (selectedLocal.length + ' items') }}\r\n </div>\r\n <div class=\"action-inputs\">\r\n <input [(ngModel)]=\"localActionName\" placeholder=\"Name / new name\" />\r\n <input [(ngModel)]=\"localActionPerms\" placeholder=\"Perms (e.g. 755)\" />\r\n </div>\r\n <div class=\"action-buttons\">\r\n <button (click)=\"localRename()\" [disabled]=\"selectedLocal.length !== 1 || !localActionName\">Rename</button>\r\n <button (click)=\"refreshLocal()\">Refresh</button>\r\n <button (click)=\"localDelete()\" [disabled]=\"!selectedLocal.length\">Delete</button>\r\n <button (click)=\"localNewFolder()\">New Folder</button>\r\n <button (click)=\"localEditPermissions()\" [disabled]=\"selectedLocal.length !== 1 || !localActionPerms\">Edit Permissions</button>\r\n <button (click)=\"localShowSize()\" [disabled]=\"selectedLocal.length !== 1 || !selectedLocal[0].isDirectory\">Show Size</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"pane\">\r\n <div class=\"pane-title\">\r\n <div class=\"pane-label\">\r\n Remote\r\n <span *ngIf=\"connected && profile?.options?.host\" class=\"pane-sub\">\r\n — {{ profile.options.host }}\r\n </span>\r\n </div>\r\n <div class=\"pane-path\">\r\n <input\r\n [(ngModel)]=\"remotePathInput\"\r\n (keyup.enter)=\"goToRemotePathInput()\"\r\n [disabled]=\"!connected\"\r\n />\r\n </div>\r\n <div class=\"pane-actions\">\r\n <button (click)=\"remoteUp()\" [disabled]=\"!connected || remotePath === '/'\">Up</button>\r\n <button (click)=\"goToRemotePathInput()\" [disabled]=\"!connected\">Go</button>\r\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\r\n </div>\r\n </div>\r\n <div class=\"pane-filters\">\r\n <div class=\"breadcrumbs\" *ngIf=\"connected\">\r\n <ng-container *ngFor=\"let part of getRemoteBreadcrumbs(); let i = index; let last = last\">\r\n <button\r\n class=\"crumb-button\"\r\n (click)=\"navigateRemoteBreadcrumb(i)\"\r\n >\r\n {{ part.label }}\r\n </button>\r\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\r\n </ng-container>\r\n </div>\r\n <input [(ngModel)]=\"remoteFilter\" placeholder=\"Filter files...\" />\r\n <label class=\"show-hidden-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenRemote\" />\r\n <span>Show hidden</span>\r\n </label>\r\n </div>\r\n <div class=\"pane-list\"\r\n (dragover)=\"onDragOver($event)\"\r\n (drop)=\"onDropOnRemote($event)\"\r\n >\r\n <div class=\"entry dim\" *ngIf=\"!connected\">\r\n <span class=\"name\">Not connected</span>\r\n </div>\r\n <div class=\"entry header\" *ngIf=\"connected\">\r\n <span class=\"icon\"></span>\r\n <span class=\"name sortable\" (click)=\"setRemoteSort('name')\">Name</span>\r\n <span class=\"size sortable\" (click)=\"setRemoteSort('size')\">Size</span>\r\n <span class=\"date sortable\" (click)=\"setRemoteSort('modified')\">Modified</span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngIf=\"connected && remotePath !== '/'\"\r\n (dblclick)=\"remoteUp()\"\r\n >\r\n <span class=\"icon\">⬆</span>\r\n <span class=\"name\">Go up</span>\r\n <span class=\"size\"></span>\r\n <span class=\"date\"></span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngFor=\"let e of getFilteredRemoteEntries()\"\r\n (click)=\"selectRemote(e, $event)\"\r\n (dblclick)=\"openRemote(e)\"\r\n (mousedown)=\"onRemoteMouseDown(e, $event)\"\r\n (contextmenu)=\"onRemoteContextMenu(e, $event)\"\r\n (dragover)=\"onRemoteEntryDragOver(e, $event)\"\r\n (drop)=\"onRemoteEntryDrop(e, $event)\"\r\n [class.drop-target]=\"remoteDropActive\"\r\n [class.selected]=\"isRemoteSelected(e)\"\r\n [draggable]=\"connected\"\r\n (dragstart)=\"onDragStartRemote($event, e)\"\r\n >\r\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\r\n <span class=\"name\">{{ e.name }}</span>\r\n <span class=\"size\">{{ getRemoteSizeDisplay(e) }}</span>\r\n <span class=\"date\">{{ e.modified | date:'yyyy-MM-dd HH:mm' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"pane-actions-bar\">\r\n <div class=\"selection\" *ngIf=\"selectedRemote.length\">\r\n Selected: {{ selectedRemote.length === 1 ? selectedRemote[0].name : (selectedRemote.length + ' items') }}\r\n </div>\r\n <div class=\"action-inputs\">\r\n <input [(ngModel)]=\"remoteActionName\" placeholder=\"Name / new name\" />\r\n <input [(ngModel)]=\"remoteActionPerms\" placeholder=\"Perms (e.g. 755)\" />\r\n </div>\r\n <div class=\"action-buttons\">\r\n <button (click)=\"remoteRename()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionName\">Rename</button>\r\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\r\n <button (click)=\"remoteDelete()\" [disabled]=\"!selectedRemote.length\">Delete</button>\r\n <button (click)=\"remoteNewFolder()\" [disabled]=\"!connected\">New Folder</button>\r\n <button (click)=\"remoteEditPermissions()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionPerms\">Edit Permissions</button>\r\n <button (click)=\"remoteShowSize()\" [disabled]=\"selectedRemote.length !== 1 || !selectedRemote[0].isDirectory\">Show Size</button>\r\n <button (click)=\"remoteDownload()\" [disabled]=\"!selectedRemote.length\">Download</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"sftp-transfers\" *ngIf=\"transfers.length\">\r\n <div class=\"transfer\" *ngFor=\"let t of transfers\">\r\n <div class=\"transfer-main\">\r\n <div class=\"transfer-title\">\r\n <span class=\"direction\">{{ t.direction === 'upload' ? 'Upload' : 'Download' }}</span>\r\n <span class=\"name\">{{ t.name }}</span>\r\n </div>\r\n <div class=\"transfer-path\">\r\n <span class=\"label\">Remote:</span>\r\n <span class=\"value\">{{ t.remotePath }}</span>\r\n </div>\r\n <div class=\"transfer-path\">\r\n <span class=\"label\">Local:</span>\r\n <span class=\"value\">{{ t.localPath }}</span>\r\n </div>\r\n <div class=\"bar\">\r\n <div class=\"fill\" [style.width.%]=\"getTransferProgress(t.transfer)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"transfer-stats\">\r\n <div class=\"percent\">{{ getTransferProgress(t.transfer) | number:'1.0-0' }}%</div>\r\n <div class=\"speed\">{{ formatSpeed(t.transfer.getSpeed()) }}</div>\r\n <button class=\"btn-cancel\" (click)=\"cancelTransfer(t)\" [disabled]=\"t.transfer.isComplete() || t.transfer.isCancelled()\">Cancel</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"delete-overlay\" *ngIf=\"deleteConfirmVisible\">\r\n <div class=\"delete-dialog\">\r\n <div class=\"delete-text\">{{ deleteConfirmText }}</div>\r\n <div class=\"delete-buttons\">\r\n <button class=\"danger\" (click)=\"confirmDelete()\">Delete</button>\r\n <button (click)=\"cancelDelete()\">Cancel</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"local-menu\"\r\n *ngIf=\"localMenuVisible\"\r\n [style.left.px]=\"localMenuX\"\r\n [style.top.px]=\"localMenuY\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"local-menu-item\" *ngFor=\"let item of localMenuItems\" (click)=\"onLocalMenuItemClick(item)\">\r\n {{ item.label }}\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .sftp-root { display: flex; flex-direction: column; height: 100%; padding: 10px; gap: 10px; position: relative; }\r\n button { padding: 6px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.06); color: inherit; cursor: pointer; }\r\n button:disabled { opacity: 0.5; cursor: default; }\r\n .top-profiles { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px 8px; gap: 12px; font-size: 11px; opacity: 0.9; }\r\n .top-profiles .current .label,\r\n .top-profiles .recent .label { text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.7; margin-right: 4px; }\r\n .top-profiles .value { font-weight: 600; }\r\n .top-profiles .profile-chip { padding: 2px 8px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\r\n .top-profiles .profile-chip:hover { background: rgba(255,255,255,0.12); }\r\n .sftp-body { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; flex: 1; min-height: 0; }\r\n .pane { display: flex; flex-direction: column; border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; overflow: hidden; min-height: 0; }\r\n .pane-title { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; padding: 8px 10px; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); }\r\n .pane-label { font-weight: 600; display: flex; align-items: baseline; gap: 6px; }\r\n .pane-sub { font-weight: 400; font-size: 11px; opacity: 0.75; }\r\n .pane-path { opacity: 0.8; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .pane-path input { width: 100%; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-family: inherit; font-size: 12px; }\r\n .pane-actions { display: flex; gap: 8px; align-items: center; }\r\n .pane-actions .path-preset,\r\n .pane-actions .path-favorite { max-width: 150px; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.22); background: rgba(20,20,20,0.95); color: inherit; font-size: 11px; }\r\n .pane-actions .path-preset option { background: #151515; color: #f5f5f5; }\r\n .pane-actions .path-favorite option { background: #151515; color: #f5f5f5; }\r\n .pane-actions .fav-toggle { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.05); font-size: 11px; line-height: 1; }\r\n .pane-actions .fav-toggle.active { background: rgba(255,215,0,0.2); border-color: rgba(255,215,0,0.6); color: #ffd700; }\r\n .pane-filters { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.12); }\r\n .pane-filters input { flex: 1; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 12px; }\r\n .show-hidden-toggle { display: flex; align-items: center; gap: 4px; font-size: 11px; opacity: 0.8; white-space: nowrap; }\r\n .show-hidden-toggle input[type=\"checkbox\"] { margin: 0; }\r\n .breadcrumbs { display: flex; flex-wrap: wrap; gap: 4px; font-size: 11px; opacity: 0.9; align-items: center; }\r\n .crumb-button { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\r\n .crumb-button:hover { background: rgba(255,255,255,0.10); }\r\n .crumb-separator { opacity: 0.6; }\r\n .pane-list { flex: 1; overflow: auto; padding: 4px; }\r\n .entry { display: grid; grid-template-columns: 24px minmax(0, 1.5fr) 80px 140px; gap: 8px; padding: 6px 8px; border-radius: 8px; user-select: none; align-items: center; }\r\n .entry:hover { background: rgba(255,255,255,0.06); }\r\n .entry.drop-target { outline: 1px dashed rgba(255,255,255,0.35); background: rgba(80, 160, 255, 0.10); }\r\n .entry.dim { opacity: 0.7; }\r\n .icon { text-align: center; opacity: 0.85; }\r\n .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .size { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; text-align: right; opacity: 0.8; }\r\n .date { font-size: 11px; opacity: 0.75; text-align: right; white-space: nowrap; }\r\n .entry.header { font-weight: 600; opacity: 0.9; background: rgba(255,255,255,0.02); }\r\n .sortable { cursor: pointer; }\r\n .entry.selected { background: rgba(80,160,255,0.18); }\r\n .pane-actions-bar { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border-top: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.18); }\r\n .pane-actions-bar .selection { font-size: 11px; opacity: 0.85; }\r\n .pane-actions-bar .action-inputs { display: flex; gap: 6px; }\r\n .pane-actions-bar .action-inputs input { flex: 1; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 11px; }\r\n .pane-actions-bar .action-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }\r\n .sftp-transfers { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; max-height: 120px; overflow-y: auto; }\r\n .transfer { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 6px 8px; border-radius: 8px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); font-size: 11px; }\r\n .transfer-title { display: flex; gap: 6px; align-items: baseline; margin-bottom: 2px; }\r\n .transfer-title .direction { text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; font-weight: 600; font-size: 10px; }\r\n .transfer-title .name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .transfer-path { display: flex; gap: 4px; opacity: 0.75; }\r\n .transfer-path .label { min-width: 48px; }\r\n .transfer-path .value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\r\n .bar { position: relative; height: 4px; border-radius: 999px; background: rgba(255,255,255,0.07); margin-top: 4px; overflow: hidden; }\r\n .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: inherit; background: linear-gradient(90deg, #4dabff, #78ffce); transition: width 0.15s linear; }\r\n .transfer-stats { display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 4px; opacity: 0.8; }\r\n .transfer-stats .percent { font-weight: 600; }\r\n .transfer-stats .speed { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\r\n .btn-cancel { padding: 2px 6px; font-size: 10px; border-radius: 999px; }\r\n .delete-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; z-index: 20; }\r\n .delete-dialog { min-width: 260px; max-width: 360px; padding: 14px 16px; border-radius: 10px; background: rgba(20,20,20,0.96); border: 1px solid rgba(255,255,255,0.15); box-shadow: 0 18px 45px rgba(0,0,0,0.75); display: flex; flex-direction: column; gap: 10px; }\r\n .delete-text { font-size: 13px; }\r\n .delete-buttons { display: flex; justify-content: flex-end; gap: 8px; }\r\n .delete-buttons .danger { background: rgba(255,80,80,0.85); border-color: rgba(255,120,120,0.85); }\r\n .local-menu { position: absolute; min-width: 180px; max-width: 260px; max-height: 260px; overflow-y: auto; padding: 4px 0; border-radius: 10px; background: rgba(18,18,22,0.98); border: 1px solid rgba(255,255,255,0.16); box-shadow: 0 18px 45px rgba(0,0,0,0.8); z-index: 30; backdrop-filter: blur(12px); }\r\n .local-menu-item { padding: 6px 12px; font-size: 12px; cursor: pointer; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }\r\n .local-menu-item:hover { background: linear-gradient(90deg, rgba(120,200,255,0.24), rgba(120,255,206,0.15)); }\r\n `],\r\n})\r\nexport class SftpManagerTabComponent extends BaseTabComponent implements OnInit {\r\n // injected from the SSH tab when opened via SFTP-UI button\r\n sshSession: SSHSessionLike | null = null\r\n profile: any = null\r\n\r\n connecting = false\r\n connected = false\r\n\r\n // legacy UI fields kept for now (not used when opened from SSH tab)\r\n host = ''\r\n port = 22\r\n username = ''\r\n password = ''\r\n\r\n localPath = os.homedir()\r\n localEntries: LocalEntry[] = []\r\n\r\n remotePath = '/'\r\n remoteEntries: SFTPFile[] = []\r\n\r\n private sftpSession: SFTPSessionLike | null = null\r\n\r\n localDropActive = false\r\n remoteDropActive = false\r\n\r\n transfers: Array<{\r\n transfer: FileTransfer\r\n direction: 'upload' | 'download'\r\n name: string\r\n remotePath: string\r\n localPath: string\r\n }> = []\r\n\r\n private transfersTimer: number | null = null\r\n localFilter = ''\r\n remoteFilter = ''\r\n remotePathInput = this.remotePath\r\n localPathInput = this.localPath\r\n private localFolderSizeLoading: Set<string> = new Set()\r\n private remoteFolderSizeLoading: Set<string> = new Set()\r\n private localSortBy: 'name' | 'size' | 'modified' = 'name'\r\n private localSortAsc = true\r\n private remoteSortBy: 'name' | 'size' | 'modified' = 'name'\r\n private remoteSortAsc = true\r\n private localCache: {\r\n entriesRef: LocalEntry[]\r\n filter: string\r\n showHidden: boolean\r\n sortBy: 'name' | 'size' | 'modified'\r\n asc: boolean\r\n result: LocalEntry[]\r\n } | null = null\r\n private remoteCache: {\r\n entriesRef: SFTPFile[]\r\n filter: string\r\n showHidden: boolean\r\n sortBy: 'name' | 'size' | 'modified'\r\n asc: boolean\r\n result: SFTPFile[]\r\n } | null = null\r\n showHiddenLocal = false\r\n showHiddenRemote = false\r\n selectedLocal: LocalEntry[] = []\r\n selectedRemote: SFTPFile[] = []\r\n localActionName = ''\r\n localActionPerms = ''\r\n remoteActionName = ''\r\n remoteActionPerms = ''\r\n private localLastSelectedIndex: number | null = null\r\n private remoteLastSelectedIndex: number | null = null\r\n\r\n deleteConfirmVisible = false\r\n deleteConfirmMode: 'local' | 'remote' | null = null\r\n deleteConfirmText = ''\r\n private pendingLocalDelete: LocalEntry[] = []\r\n private pendingRemoteDelete: SFTPFile[] = []\r\n private platform!: PlatformService\r\n private openedRemoteFiles: Map<string, { remotePath: string, mode: number, watcher: fsSync.FSWatcher | null }> = new Map()\r\n localPathPresets: Array<{ id: string, label: string, path: string }> = []\r\n localFavorites: Array<{ id: string, label: string, path: string }> = []\r\n recentProfiles: any[] = []\r\n localMenuVisible = false\r\n localMenuX = 0\r\n localMenuY = 0\r\n localMenuItems: Array<{ label: string, path: string }> = []\r\n\r\n constructor (\r\n injector: Injector,\r\n private sftp: SftpConnectionService,\r\n private profilesService: ProfilesService,\r\n private app: AppService,\r\n ) {\r\n // Tabby runtime BaseTabComponent expects Injector in constructor, but typings in this SDK may differ.\r\n // @ts-expect-error runtime-compatible super(injector)\r\n super(injector)\r\n this.platform = injector.get(PlatformService as any)\r\n\r\n // build local path presets (similar to Termius quick locations)\r\n const home = os.homedir()\r\n this.localPathPresets.push({ id: 'home', label: 'Home', path: home })\r\n const desktop = path.join(home, 'Desktop')\r\n const documents = path.join(home, 'Documents')\r\n const downloads = path.join(home, 'Downloads')\r\n if (fsSync.existsSync(desktop)) {\r\n this.localPathPresets.push({ id: 'desktop', label: 'Desktop', path: desktop })\r\n }\r\n if (fsSync.existsSync(documents)) {\r\n this.localPathPresets.push({ id: 'documents', label: 'Documents', path: documents })\r\n }\r\n if (fsSync.existsSync(downloads)) {\r\n this.localPathPresets.push({ id: 'downloads', label: 'Downloads', path: downloads })\r\n }\r\n\r\n this.loadLocalFavorites()\r\n void this.refreshLocal()\r\n\r\n this.transfersTimer = window.setInterval(() => {\r\n this.transfers = this.transfers.filter(t => !t.transfer.isComplete() && !t.transfer.isCancelled())\r\n }, 1000)\r\n }\r\n\r\n ngOnInit (): void {\r\n // If there's no live SSH session, this tab was likely restored across\r\n // restart or opened in an invalid context. Close it immediately to avoid\r\n // an empty, nameless SFTP tab lingering after restart.\r\n if (!this.sshSession) {\r\n try {\r\n this.app.closeTab(this)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Failed to close invalid SFTP tab', e)\r\n }\r\n return\r\n }\r\n\r\n this.remotePathInput = this.remotePath\r\n this.localPathInput = this.localPath\r\n if (this.sshSession) {\r\n void this.connect()\r\n }\r\n this.loadRecentProfiles()\r\n }\r\n\r\n async connect (): Promise<void> {\r\n if (this.connecting || this.connected) {\r\n return\r\n }\r\n if (!this.sshSession) {\r\n console.error('[SFTP-UI] No SSH session on current tab')\r\n return\r\n }\r\n this.connecting = true\r\n try {\r\n this.sftpSession = await this.sftp.openFromSSHSession(this.sshSession)\r\n this.connected = true\r\n this.remotePath = this.getDefaultRemotePath()\r\n this.remotePathInput = this.remotePath\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] SFTP connection failed', e)\r\n } finally {\r\n this.connecting = false\r\n }\r\n }\r\n\r\n async disconnect (): Promise<void> {\r\n this.sftpSession = null\r\n this.connected = false\r\n this.remoteEntries = []\r\n }\r\n\r\n canLocalUp (): boolean {\r\n const parent = path.dirname(this.localPath)\r\n return parent !== this.localPath\r\n }\r\n\r\n localUp (): void {\r\n const parent = path.dirname(this.localPath)\r\n if (parent !== this.localPath) {\r\n this.localPath = parent\r\n this.localPathInput = this.localPath\r\n void this.refreshLocal()\r\n }\r\n }\r\n\r\n remoteUp (): void {\r\n if (!this.connected || this.remotePath === '/') {\r\n return\r\n }\r\n const next = path.posix.dirname(this.remotePath)\r\n this.remotePath = next === '.' ? '/' : next\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n }\r\n\r\n async refreshLocal (): Promise<void> {\r\n try {\r\n const names = await fs.readdir(this.localPath)\r\n const entries: LocalEntry[] = []\r\n for (const name of names) {\r\n const fullPath = path.join(this.localPath, name)\r\n try {\r\n const st = await fs.stat(fullPath)\r\n entries.push({\r\n name,\r\n fullPath,\r\n isDirectory: st.isDirectory(),\r\n size: st.size,\r\n mtimeMs: st.mtimeMs,\r\n })\r\n } catch {\r\n // ignore entries that disappeared\r\n }\r\n }\r\n this.localEntries = entries\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local listing failed', e)\r\n }\r\n }\r\n\r\n async refreshRemote (): Promise<void> {\r\n if (!this.connected) {\r\n return\r\n }\r\n try {\r\n if (!this.sftpSession) {\r\n throw new Error('Not connected')\r\n }\r\n this.remoteEntries = await this.sftpSession.readdir(this.remotePath)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote listing failed', e)\r\n }\r\n }\r\n\r\n openLocal (e: LocalEntry): void {\r\n if (!e.isDirectory) {\r\n return\r\n }\r\n this.localPath = e.fullPath\r\n this.localPathInput = this.localPath\r\n void this.refreshLocal()\r\n }\r\n\r\n openRemote (e: SFTPFile): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n if (e.isDirectory) {\r\n this.remotePath = e.fullPath\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n } else {\r\n void this.openRemoteFile(e)\r\n }\r\n }\r\n\r\n onDragOver (ev: DragEvent): void {\r\n ev.preventDefault()\r\n }\r\n\r\n onLocalMouseDown (entry: LocalEntry, event: MouseEvent): void {\r\n if (event.button === 2) {\r\n this.onLocalContextMenu(entry, event)\r\n }\r\n }\r\n\r\n onRemoteMouseDown (entry: SFTPFile, event: MouseEvent): void {\r\n if (event.button === 2) {\r\n this.onRemoteContextMenu(entry, event)\r\n }\r\n }\r\n\r\n selectLocal (entry: LocalEntry, event: MouseEvent): void {\r\n const list = this.getFilteredLocalEntries()\r\n const index = list.indexOf(entry)\r\n if (index === -1) {\r\n return\r\n }\r\n const isCtrl = event.ctrlKey || event.metaKey\r\n const isShift = event.shiftKey\r\n if (isShift && this.localLastSelectedIndex != null) {\r\n const [from, to] = this.localLastSelectedIndex < index\r\n ? [this.localLastSelectedIndex, index]\r\n : [index, this.localLastSelectedIndex]\r\n const range = list.slice(from, to + 1)\r\n const set = new Set(this.selectedLocal)\r\n for (const e of range) {\r\n set.add(e)\r\n }\r\n this.selectedLocal = Array.from(set)\r\n } else if (isCtrl) {\r\n const exists = this.selectedLocal.includes(entry)\r\n if (exists) {\r\n this.selectedLocal = this.selectedLocal.filter(e => e !== entry)\r\n } else {\r\n this.selectedLocal = [...this.selectedLocal, entry]\r\n }\r\n this.localLastSelectedIndex = index\r\n } else {\r\n this.selectedLocal = [entry]\r\n this.localLastSelectedIndex = index\r\n }\r\n if (this.selectedLocal.length === 1) {\r\n this.localActionName = this.selectedLocal[0].name\r\n }\r\n }\r\n\r\n isLocalSelected (entry: LocalEntry): boolean {\r\n return this.selectedLocal.includes(entry)\r\n }\r\n\r\n selectRemote (entry: SFTPFile, event: MouseEvent): void {\r\n const list = this.getFilteredRemoteEntries()\r\n const index = list.indexOf(entry)\r\n if (index === -1) {\r\n return\r\n }\r\n const isCtrl = event.ctrlKey || event.metaKey\r\n const isShift = event.shiftKey\r\n if (isShift && this.remoteLastSelectedIndex != null) {\r\n const [from, to] = this.remoteLastSelectedIndex < index\r\n ? [this.remoteLastSelectedIndex, index]\r\n : [index, this.remoteLastSelectedIndex]\r\n const range = list.slice(from, to + 1)\r\n const set = new Set(this.selectedRemote)\r\n for (const e of range) {\r\n set.add(e)\r\n }\r\n this.selectedRemote = Array.from(set)\r\n } else if (isCtrl) {\r\n const exists = this.selectedRemote.includes(entry)\r\n if (exists) {\r\n this.selectedRemote = this.selectedRemote.filter(e => e !== entry)\r\n } else {\r\n this.selectedRemote = [...this.selectedRemote, entry]\r\n }\r\n this.remoteLastSelectedIndex = index\r\n } else {\r\n this.selectedRemote = [entry]\r\n this.remoteLastSelectedIndex = index\r\n }\r\n if (this.selectedRemote.length === 1) {\r\n this.remoteActionName = this.selectedRemote[0].name\r\n const currentPerms = (this.selectedRemote[0].mode & 0o777).toString(8)\r\n this.remoteActionPerms = currentPerms\r\n }\r\n }\r\n\r\n isRemoteSelected (entry: SFTPFile): boolean {\r\n return this.selectedRemote.includes(entry)\r\n }\r\n\r\n setLocalSort (field: 'name' | 'size' | 'modified'): void {\r\n if (this.localSortBy === field) {\r\n this.localSortAsc = !this.localSortAsc\r\n } else {\r\n this.localSortBy = field\r\n this.localSortAsc = true\r\n }\r\n }\r\n\r\n setRemoteSort (field: 'name' | 'size' | 'modified'): void {\r\n if (this.remoteSortBy === field) {\r\n this.remoteSortAsc = !this.remoteSortAsc\r\n } else {\r\n this.remoteSortBy = field\r\n this.remoteSortAsc = true\r\n }\r\n }\r\n\r\n onDragStartLocal (ev: DragEvent, e: LocalEntry): void {\r\n const sources = this.selectedLocal.includes(e) && this.selectedLocal.length ? this.selectedLocal : [e]\r\n const movePayload = sources.map(x => x.fullPath)\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-local-move', JSON.stringify(movePayload))\r\n\r\n // Existing cross-device drag (local -> remote) only for files\r\n if (!e.isDirectory) {\r\n const payload: DragPayload = { kind: 'local-file', fullPath: e.fullPath, name: e.name }\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\r\n ev.dataTransfer?.setData('text/plain', e.fullPath)\r\n }\r\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\r\n }\r\n\r\n onDragStartRemote (ev: DragEvent, item: SFTPFile): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n const sources = this.selectedRemote.includes(item) && this.selectedRemote.length ? this.selectedRemote : [item]\r\n const movePayload = sources.map(x => x.fullPath)\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-remote-move', JSON.stringify(movePayload))\r\n\r\n // Existing cross-device drag (remote -> local) only for files\r\n if (!item.isDirectory) {\r\n const payload: DragPayload = {\r\n kind: 'remote-file',\r\n remotePath: item.fullPath,\r\n name: item.name,\r\n size: item.size,\r\n mode: item.mode,\r\n }\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\r\n ev.dataTransfer?.setData('text/plain', item.fullPath)\r\n }\r\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\r\n }\r\n\r\n async onDropOnRemote (ev: DragEvent): Promise<void> {\r\n ev.preventDefault()\r\n this.remoteDropActive = false\r\n if (!this.connected) {\r\n return\r\n }\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\r\n if (!raw) {\r\n return\r\n }\r\n let payload: DragPayload\r\n try {\r\n payload = JSON.parse(raw) as DragPayload\r\n } catch {\r\n return\r\n }\r\n if (payload.kind !== 'local-file') {\r\n return\r\n }\r\n try {\r\n const targetRemotePath = path.posix.join(this.remotePath, payload.name)\r\n const upload = new LocalPathFileUpload(payload.fullPath)\r\n this.trackTransfer(upload, 'upload', targetRemotePath, payload.fullPath)\r\n await this.sftpSession.upload(targetRemotePath, upload)\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Upload failed', e)\r\n }\r\n }\r\n\r\n async onDropOnLocal (ev: DragEvent): Promise<void> {\r\n ev.preventDefault()\r\n this.localDropActive = false\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\r\n if (!raw) {\r\n return\r\n }\r\n let payload: DragPayload\r\n try {\r\n payload = JSON.parse(raw) as DragPayload\r\n } catch {\r\n return\r\n }\r\n if (payload.kind !== 'remote-file') {\r\n return\r\n }\r\n try {\r\n const targetLocalPath = path.join(this.localPath, payload.name)\r\n if (!this.sftpSession) {\r\n throw new Error('Not connected')\r\n }\r\n const dl = new LocalPathFileDownload(targetLocalPath, payload.mode, payload.size)\r\n this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath)\r\n await this.sftpSession.download(payload.remotePath, dl)\r\n await this.refreshLocal()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Download failed', e)\r\n }\r\n }\r\n\r\n getFilteredLocalEntries (): LocalEntry[] {\r\n const entriesRef = this.localEntries\r\n const filter = this.localFilter\r\n const showHidden = this.showHiddenLocal\r\n const sortBy = this.localSortBy\r\n const asc = this.localSortAsc\r\n\r\n if (this.localCache &&\r\n this.localCache.entriesRef === entriesRef &&\r\n this.localCache.filter === filter &&\r\n this.localCache.showHidden === showHidden &&\r\n this.localCache.sortBy === sortBy &&\r\n this.localCache.asc === asc) {\r\n return this.localCache.result\r\n }\r\n\r\n const term = filter.trim().toLowerCase()\r\n let entries = entriesRef\r\n if (!showHidden) {\r\n entries = entries.filter(e => !e.name.startsWith('.'))\r\n }\r\n if (term) {\r\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\r\n }\r\n const result = this.sortLocalEntries(entries.slice())\r\n this.localCache = { entriesRef, filter, showHidden, sortBy, asc, result }\r\n return result\r\n }\r\n\r\n getFilteredRemoteEntries (): SFTPFile[] {\r\n const entriesRef = this.remoteEntries\r\n const filter = this.remoteFilter\r\n const showHidden = this.showHiddenRemote\r\n const sortBy = this.remoteSortBy\r\n const asc = this.remoteSortAsc\r\n\r\n if (this.remoteCache &&\r\n this.remoteCache.entriesRef === entriesRef &&\r\n this.remoteCache.filter === filter &&\r\n this.remoteCache.showHidden === showHidden &&\r\n this.remoteCache.sortBy === sortBy &&\r\n this.remoteCache.asc === asc) {\r\n return this.remoteCache.result\r\n }\r\n\r\n const term = filter.trim().toLowerCase()\r\n let entries = entriesRef\r\n if (!showHidden) {\r\n entries = entries.filter(e => !e.name.startsWith('.'))\r\n }\r\n if (term) {\r\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\r\n }\r\n const result = this.sortRemoteEntries(entries.slice())\r\n this.remoteCache = { entriesRef, filter, showHidden, sortBy, asc, result }\r\n return result\r\n }\r\n\r\n private sortLocalEntries (entries: LocalEntry[]): LocalEntry[] {\r\n const dirFirst = (a: LocalEntry, b: LocalEntry) => Number(b.isDirectory) - Number(a.isDirectory)\r\n const factor = this.localSortAsc ? 1 : -1\r\n const field = this.localSortBy\r\n return entries.sort((a, b) => {\r\n const d = dirFirst(a, b)\r\n if (d !== 0) return d\r\n if (field === 'name') {\r\n return a.name.localeCompare(b.name) * factor\r\n }\r\n if (field === 'size') {\r\n const av = a.size ?? 0\r\n const bv = b.size ?? 0\r\n return (av - bv) * factor\r\n }\r\n const av = a.mtimeMs ?? 0\r\n const bv = b.mtimeMs ?? 0\r\n return (av - bv) * factor\r\n })\r\n }\r\n\r\n private sortRemoteEntries (entries: SFTPFile[]): SFTPFile[] {\r\n const dirFirst = (a: SFTPFile, b: SFTPFile) => Number(b.isDirectory) - Number(a.isDirectory)\r\n const factor = this.remoteSortAsc ? 1 : -1\r\n const field = this.remoteSortBy\r\n return entries.sort((a, b) => {\r\n const d = dirFirst(a, b)\r\n if (d !== 0) return d\r\n if (field === 'name') {\r\n return a.name.localeCompare(b.name) * factor\r\n }\r\n if (field === 'size') {\r\n const av = a.size ?? 0\r\n const bv = b.size ?? 0\r\n return (av - bv) * factor\r\n }\r\n const av = a.modified?.getTime?.() ?? 0\r\n const bv = b.modified?.getTime?.() ?? 0\r\n return (av - bv) * factor\r\n })\r\n }\r\n\r\n private getLocalMovePayload (ev: DragEvent): string[] | null {\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-local-move')\r\n if (!raw) {\r\n return null\r\n }\r\n try {\r\n const arr = JSON.parse(raw) as string[]\r\n if (Array.isArray(arr)) {\r\n return arr\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n return null\r\n }\r\n\r\n private getRemoteMovePayload (ev: DragEvent): string[] | null {\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-remote-move')\r\n if (!raw) {\r\n return null\r\n }\r\n try {\r\n const arr = JSON.parse(raw) as string[]\r\n if (Array.isArray(arr)) {\r\n return arr\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n return null\r\n }\r\n\r\n formatSize (bytes?: number): string {\r\n if (bytes === undefined || bytes === null) {\r\n return ''\r\n }\r\n if (bytes === 0) {\r\n return '0 B'\r\n }\r\n const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']\r\n let value = bytes\r\n let unitIndex = 0\r\n while (value >= 1024 && unitIndex < units.length - 1) {\r\n value /= 1024\r\n unitIndex++\r\n }\r\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\r\n return `${value.toFixed(digits)} ${units[unitIndex]}`\r\n }\r\n\r\n formatSpeed (bytesPerSecond?: number): string {\r\n if (bytesPerSecond === undefined || bytesPerSecond === null) {\r\n return ''\r\n }\r\n if (bytesPerSecond === 0) {\r\n return '0 B/s'\r\n }\r\n const units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s']\r\n let value = bytesPerSecond\r\n let unitIndex = 0\r\n while (value >= 1024 && unitIndex < units.length - 1) {\r\n value /= 1024\r\n unitIndex++\r\n }\r\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\r\n return `${value.toFixed(digits)} ${units[unitIndex]}`\r\n }\r\n\r\n getLocalSizeDisplay (e: LocalEntry): string {\r\n if (!e.isDirectory) {\r\n return this.formatSize(e.size)\r\n }\r\n if (e.size !== undefined) {\r\n return this.formatSize(e.size)\r\n }\r\n if (this.localFolderSizeLoading.has(e.fullPath)) {\r\n return '…'\r\n }\r\n return ''\r\n }\r\n\r\n getRemoteSizeDisplay (e: SFTPFile): string {\r\n if (!e.isDirectory) {\r\n return this.formatSize(e.size)\r\n }\r\n const key = e.fullPath\r\n if ((e as any).dirSize !== undefined) {\r\n return this.formatSize((e as any).dirSize)\r\n }\r\n if (this.remoteFolderSizeLoading.has(key)) {\r\n return '…'\r\n }\r\n return ''\r\n }\r\n\r\n onLocalEntryDragOver (entry: LocalEntry, ev: DragEvent): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (!this.getLocalMovePayload(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n }\r\n\r\n async onLocalEntryDrop (entry: LocalEntry, ev: DragEvent): Promise<void> {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n const sources = this.getLocalMovePayload(ev)\r\n if (!sources || !sources.length) {\r\n return\r\n }\r\n ev.preventDefault()\r\n const targetDir = entry.fullPath\r\n try {\r\n for (const src of sources) {\r\n if (!src || src === targetDir) {\r\n continue\r\n }\r\n // avoid moving a directory into its own subtree\r\n if (targetDir.startsWith(src + path.sep)) {\r\n continue\r\n }\r\n const name = path.basename(src)\r\n const dst = path.join(targetDir, name)\r\n if (dst === src) {\r\n continue\r\n }\r\n try {\r\n await fs.rename(src, dst)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local move failed', e)\r\n }\r\n }\r\n await this.refreshLocal()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local move batch failed', e)\r\n }\r\n }\r\n\r\n onRemoteEntryDragOver (entry: SFTPFile, ev: DragEvent): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (!this.getRemoteMovePayload(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n }\r\n\r\n async onRemoteEntryDrop (entry: SFTPFile, ev: DragEvent): Promise<void> {\r\n if (!entry.isDirectory || !this.sftpSession || !this.connected) {\r\n return\r\n }\r\n const sources = this.getRemoteMovePayload(ev)\r\n if (!sources || !sources.length) {\r\n return\r\n }\r\n ev.preventDefault()\r\n const targetDir = entry.fullPath\r\n try {\r\n for (const src of sources) {\r\n if (!src || src === targetDir) {\r\n continue\r\n }\r\n // avoid moving a directory into its own subtree\r\n if (targetDir.startsWith(src + '/')) {\r\n continue\r\n }\r\n const name = src.split('/').filter(Boolean).pop() || ''\r\n if (!name) {\r\n continue\r\n }\r\n const dst = path.posix.join(targetDir, name)\r\n if (dst === src) {\r\n continue\r\n }\r\n try {\r\n await this.sftpSession.rename(src, dst)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote move failed', e)\r\n }\r\n }\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote move batch failed', e)\r\n }\r\n }\r\n\r\n getRemoteBreadcrumbs (): Array<{ label: string, path: string }> {\r\n const parts = this.remotePath.split('/').filter(Boolean)\r\n const crumbs: Array<{ label: string, path: string }> = []\r\n let current = '/'\r\n crumbs.push({ label: '/', path: '/' })\r\n for (const p of parts) {\r\n current = current === '/' ? `/${p}` : `${current}/${p}`\r\n crumbs.push({ label: p, path: current })\r\n }\r\n return crumbs\r\n }\r\n\r\n navigateRemoteBreadcrumb (index: number): void {\r\n const crumbs = this.getRemoteBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n this.remotePath = crumb.path\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n }\r\n\r\n goToRemotePathInput (): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n const target = this.normalizeRemotePath(this.remotePathInput || '/')\r\n this.remotePath = target\r\n this.remotePathInput = target\r\n void this.refreshRemote()\r\n }\r\n\r\n goToLocalPathInput (): void {\r\n const target = this.normalizeLocalPath(this.localPathInput || this.localPath)\r\n this.goToLocalPath(target)\r\n }\r\n\r\n getLocalBreadcrumbs (): Array<{ label: string, path: string }> {\r\n const currentPath = this.localPath\r\n const parsed = path.parse(currentPath)\r\n const root = parsed.root || path.sep\r\n const withoutRoot = currentPath.slice(root.length)\r\n const parts = withoutRoot.split(path.sep).filter(Boolean)\r\n const crumbs: Array<{ label: string, path: string }> = []\r\n\r\n const rootLabel = root.replace(/[\\\\\\/]+$/, '') || root\r\n crumbs.push({ label: rootLabel, path: root })\r\n\r\n let accum = root\r\n for (const p of parts) {\r\n accum = path.join(accum, p)\r\n crumbs.push({ label: p, path: accum })\r\n }\r\n return crumbs\r\n }\r\n\r\n navigateLocalBreadcrumb (index: number): void {\r\n const crumbs = this.getLocalBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n this.goToLocalPath(crumb.path)\r\n }\r\n\r\n private goToLocalPath (target: string): void {\r\n this.localPath = target\r\n this.localPathInput = target\r\n void this.refreshLocal()\r\n }\r\n\r\n onLocalPresetChange (id: string): void {\r\n if (!id) {\r\n return\r\n }\r\n const preset = this.localPathPresets.find(p => p.id === id)\r\n if (!preset) {\r\n return\r\n }\r\n this.goToLocalPath(preset.path)\r\n }\r\n\r\n isCurrentFavorite (): boolean {\r\n return this.localFavorites.some(f => f.path === this.localPath)\r\n }\r\n\r\n toggleCurrentFavorite (): void {\r\n const existingIndex = this.localFavorites.findIndex(f => f.path === this.localPath)\r\n if (existingIndex >= 0) {\r\n this.localFavorites.splice(existingIndex, 1)\r\n this.saveLocalFavorites()\r\n return\r\n }\r\n const label = path.basename(this.localPath) || this.localPath\r\n const id = `fav-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\r\n this.localFavorites.push({ id, label, path: this.localPath })\r\n this.saveLocalFavorites()\r\n }\r\n\r\n onLocalFavoriteSelect (id: string): void {\r\n if (!id) {\r\n return\r\n }\r\n const fav = this.localFavorites.find(f => f.id === id)\r\n if (!fav) {\r\n return\r\n }\r\n this.goToLocalPath(fav.path)\r\n }\r\n\r\n onLocalBreadcrumbContextMenu (index: number, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n const crumbs = this.getLocalBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n\r\n const menuItems: Array<{ label: string, path: string }> = []\r\n const isWindows = process.platform === 'win32'\r\n const isRootCrumb = index === 0\r\n\r\n const basePath = crumb.path\r\n\r\n // Root crumb on Windows: offer other drives as \"siblings\"\r\n if (isWindows && isRootCrumb) {\r\n const drives: string[] = []\r\n for (let code = 67; code <= 90; code++) { // C..Z\r\n const letter = String.fromCharCode(code)\r\n const rootPath = `${letter}:\\\\`\r\n try {\r\n if (fsSync.existsSync(rootPath)) {\r\n drives.push(rootPath)\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n for (const d of drives) {\r\n menuItems.push({ label: d, path: d })\r\n }\r\n } else {\r\n // For non-root crumbs (or non-Windows), show sibling folders only\r\n const parentPath = path.dirname(basePath)\r\n try {\r\n const parentEntries = fsSync.readdirSync(parentPath)\r\n for (const name of parentEntries) {\r\n const full = path.join(parentPath, name)\r\n try {\r\n const st = fsSync.statSync(full)\r\n if (st.isDirectory()) {\r\n menuItems.push({ label: name, path: full })\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n if (!menuItems.length) {\r\n return\r\n }\r\n\r\n this.localMenuItems = menuItems\r\n this.localMenuVisible = true\r\n this.localMenuX = event.clientX\r\n this.localMenuY = event.clientY\r\n }\r\n\r\n private loadLocalFavorites (): void {\r\n try {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return\r\n }\r\n const raw = window.localStorage.getItem('tabby-sftp-ui-local-favorites')\r\n if (!raw) {\r\n return\r\n }\r\n const parsed = JSON.parse(raw)\r\n if (Array.isArray(parsed)) {\r\n this.localFavorites = parsed\r\n .filter(f => f && typeof f.path === 'string')\r\n .map(f => ({\r\n id: String(f.id || `fav-${Math.random().toString(36).slice(2, 8)}`),\r\n label: String(f.label || path.basename(f.path) || f.path),\r\n path: String(f.path),\r\n }))\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n private saveLocalFavorites (): void {\r\n try {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return\r\n }\r\n window.localStorage.setItem('tabby-sftp-ui-local-favorites', JSON.stringify(this.localFavorites))\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n onLocalMenuItemClick (item: { label: string, path: string }): void {\r\n this.localMenuVisible = false\r\n this.goToLocalPath(item.path)\r\n }\r\n\r\n private normalizeLocalPath (p: string): string {\r\n if (!p) {\r\n return this.localPath\r\n }\r\n let result = p.trim()\r\n // On Windows allow drive letters and backslashes, but normalize to current OS-style\r\n if (path.win32.isAbsolute(result) || path.posix.isAbsolute(result)) {\r\n return result\r\n }\r\n // relative path from current localPath\r\n return path.join(this.localPath, result)\r\n }\r\n\r\n private normalizeRemotePath (p: string): string {\r\n if (!p) {\r\n return '/'\r\n }\r\n let result = p.trim()\r\n if (!result.startsWith('/')) {\r\n result = '/' + result\r\n }\r\n // remove duplicate slashes\r\n result = result.replace(/\\/+/g, '/')\r\n return result\r\n }\r\n\r\n private getDefaultRemotePath (): string {\r\n const username = (this.profile && (this.profile.options?.username || this.profile.options?.user)) || ''\r\n if (username) {\r\n return `/home/${username}`\r\n }\r\n return '/'\r\n }\r\n\r\n private loadRecentProfiles (): void {\r\n try {\r\n const rec = this.profilesService.getRecentProfiles?.()\r\n if (Array.isArray(rec)) {\r\n this.recentProfiles = rec\r\n }\r\n } catch {\r\n this.recentProfiles = []\r\n }\r\n }\r\n\r\n getProfileLabel (p: any): string {\r\n if (!p) {\r\n return ''\r\n }\r\n return p.name || p.options?.host || p.id || 'Profile'\r\n }\r\n\r\n launchProfileFromSFTP (p: any): void {\r\n try {\r\n void this.profilesService.launchProfile(p)\r\n } catch (e) {\r\n console.error('[SFTP-UI] launchProfile failed', e)\r\n }\r\n }\r\n\r\n @HostListener('document:click')\r\n onDocumentClick (): void {\r\n this.localMenuVisible = false\r\n }\r\n\r\n localRename (): void {\r\n if (this.selectedLocal.length !== 1 || !this.localActionName?.trim()) {\r\n return\r\n }\r\n const entry = this.selectedLocal[0]\r\n const name = this.localActionName.trim()\r\n if (name === entry.name) {\r\n return\r\n }\r\n const target = path.join(this.localPath, name)\r\n void fs.rename(entry.fullPath, target)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local rename failed', e))\r\n }\r\n\r\n localDelete (): void {\r\n if (!this.selectedLocal.length) {\r\n return\r\n }\r\n this.deleteConfirmMode = 'local'\r\n this.pendingLocalDelete = this.selectedLocal.slice()\r\n const names = this.pendingLocalDelete.map(e => e.name)\r\n this.deleteConfirmText = this.buildDeleteConfirmText('local', names)\r\n this.deleteConfirmVisible = true\r\n }\r\n\r\n localNewFolder (): void {\r\n const name = (this.localActionName || 'New folder').trim()\r\n if (!name) {\r\n return\r\n }\r\n const target = path.join(this.localPath, name)\r\n void fs.mkdir(target, { recursive: true })\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local mkdir failed', e))\r\n }\r\n\r\n localEditPermissions (): void {\r\n if (this.selectedLocal.length !== 1 || !this.localActionPerms?.trim()) {\r\n return\r\n }\r\n const entry = this.selectedLocal[0]\r\n const mode = parseInt(this.localActionPerms.trim(), 8)\r\n if (Number.isNaN(mode)) {\r\n console.error('[SFTP-UI] Invalid local permissions value')\r\n return\r\n }\r\n void fs.chmod(entry.fullPath, mode as any)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local chmod failed', e))\r\n }\r\n\r\n localShowSize (): void {\r\n if (this.selectedLocal.length === 1 && this.selectedLocal[0].isDirectory) {\r\n this.ensureLocalFolderSize(this.selectedLocal[0])\r\n }\r\n }\r\n\r\n remoteRename (): void {\r\n if (this.selectedRemote.length !== 1 || !this.remoteActionName?.trim() || !this.sftpSession) {\r\n return\r\n }\r\n const entry = this.selectedRemote[0]\r\n const name = this.remoteActionName.trim()\r\n if (name === entry.name) {\r\n return\r\n }\r\n const target = path.posix.join(this.remotePath, name)\r\n void this.sftpSession.rename(entry.fullPath, target)\r\n .then(() => this.refreshRemote())\r\n .catch(e => console.error('[SFTP-UI] Remote rename failed', e))\r\n }\r\n\r\n remoteDelete (): void {\r\n if (!this.selectedRemote.length || !this.sftpSession) {\r\n return\r\n }\r\n this.deleteConfirmMode = 'remote'\r\n this.pendingRemoteDelete = this.selectedRemote.slice()\r\n const names = this.pendingRemoteDelete.map(e => e.name)\r\n this.deleteConfirmText = this.buildDeleteConfirmText('remote', names)\r\n this.deleteConfirmVisible = true\r\n }\r\n\r\n remoteNewFolder (): void {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n const name = (this.remoteActionName || 'New folder').trim()\r\n if (!name) {\r\n return\r\n }\r\n const target = path.posix.join(this.remotePath, name)\r\n void this.sftpSession.mkdir(target)\r\n .then(() => this.refreshRemote())\r\n .catch(e => console.error('[SFTP-UI] Remote mkdir failed', e))\r\n }\r\n\r\n remoteEditPermissions (): void {\r\n if (this.selectedRemote.length !== 1 || !this.remoteActionPerms?.trim() || !this.sftpSession) {\r\n return\r\n }\r\n const entry = this.selectedRemote[0]\r\n const mode = parseInt(this.remoteActionPerms.trim(), 8)\r\n if (Number.isNaN(mode)) {\r\n console.error('[SFTP-UI] Invalid remote permissions value')\r\n return\r\n }\r\n void (this.sftpSession as any).chmod(entry.fullPath, mode)\r\n .then(() => this.refreshRemote())\r\n .catch((e: any) => console.error('[SFTP-UI] Remote chmod failed', e))\r\n }\r\n\r\n remoteShowSize (): void {\r\n if (this.selectedRemote.length === 1 && this.selectedRemote[0].isDirectory) {\r\n this.ensureRemoteFolderSize(this.selectedRemote[0])\r\n }\r\n }\r\n\r\n remoteDownload (): void {\r\n if (!this.selectedRemote.length || !this.sftpSession) {\r\n return\r\n }\r\n for (const entry of this.selectedRemote) {\r\n if (entry.isDirectory) {\r\n continue\r\n }\r\n const targetLocalPath = path.join(this.localPath, entry.name)\r\n const dl = new LocalPathFileDownload(targetLocalPath, entry.mode, entry.size)\r\n this.trackTransfer(dl, 'download', entry.fullPath, targetLocalPath)\r\n void this.sftpSession.download(entry.fullPath, dl)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Remote download failed', e))\r\n }\r\n }\r\n\r\n ensureLocalFolderSize (entry: LocalEntry): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (entry.size !== undefined) {\r\n return\r\n }\r\n if (this.localFolderSizeLoading.has(entry.fullPath)) {\r\n return\r\n }\r\n this.localFolderSizeLoading.add(entry.fullPath)\r\n void this.computeLocalFolderSize(entry.fullPath)\r\n .then(size => {\r\n entry.size = size\r\n })\r\n .catch(e => {\r\n console.error('[SFTP-UI] Local folder size failed', e)\r\n })\r\n .finally(() => {\r\n this.localFolderSizeLoading.delete(entry.fullPath)\r\n })\r\n }\r\n\r\n ensureRemoteFolderSize (entry: SFTPFile): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n const key = entry.fullPath\r\n if ((entry as any).dirSize !== undefined) {\r\n return\r\n }\r\n if (this.remoteFolderSizeLoading.has(key)) {\r\n return\r\n }\r\n if (!this.sftpSession || !this.connected) {\r\n return\r\n }\r\n this.remoteFolderSizeLoading.add(key)\r\n void this.computeRemoteFolderSize(key)\r\n .then(size => {\r\n ;(entry as any).dirSize = size\r\n })\r\n .catch(e => {\r\n console.error('[SFTP-UI] Remote folder size failed', e)\r\n })\r\n .finally(() => {\r\n this.remoteFolderSizeLoading.delete(key)\r\n })\r\n }\r\n\r\n private async computeLocalFolderSize (root: string): Promise<number> {\r\n let total = 0\r\n const stack: string[] = [root]\r\n const maxEntries = 5000\r\n let visited = 0\r\n while (stack.length) {\r\n const dir = stack.pop() as string\r\n let names: string[]\r\n try {\r\n names = await fs.readdir(dir)\r\n } catch {\r\n continue\r\n }\r\n for (const name of names) {\r\n if (visited++ > maxEntries) {\r\n return total\r\n }\r\n const full = path.join(dir, name)\r\n try {\r\n const st = await fs.stat(full)\r\n if (st.isDirectory()) {\r\n stack.push(full)\r\n } else {\r\n total += st.size\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n }\r\n return total\r\n }\r\n\r\n private async computeRemoteFolderSize (root: string): Promise<number> {\r\n if (!this.sftpSession) {\r\n return 0\r\n }\r\n let total = 0\r\n const stack: string[] = [root]\r\n const maxEntries = 5000\r\n let visited = 0\r\n while (stack.length) {\r\n const dir = stack.pop() as string\r\n let entries: SFTPFile[]\r\n try {\r\n entries = await this.sftpSession.readdir(dir)\r\n } catch {\r\n continue\r\n }\r\n for (const item of entries) {\r\n if (visited++ > maxEntries) {\r\n return total\r\n }\r\n if (item.isDirectory) {\r\n stack.push(item.fullPath)\r\n } else {\r\n total += item.size\r\n }\r\n }\r\n }\r\n return total\r\n }\r\n\r\n onLocalContextMenu (entry: LocalEntry, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\r\n }\r\n\r\n onRemoteContextMenu (entry: SFTPFile, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\r\n }\r\n\r\n private trackTransfer (transfer: FileTransfer, direction: 'upload' | 'download', remotePath: string, localPath: string): void {\r\n this.transfers.push({\r\n transfer,\r\n direction,\r\n name: transfer.getName(),\r\n remotePath,\r\n localPath,\r\n })\r\n }\r\n\r\n cancelTransfer (entry: { transfer: FileTransfer }): void {\r\n try {\r\n if (entry.transfer.isComplete() || entry.transfer.isCancelled()) {\r\n return\r\n }\r\n entry.transfer.cancel?.()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Cancel transfer failed', e)\r\n }\r\n }\r\n\r\n getTransferProgress (transfer: FileTransfer): number {\r\n try {\r\n const total = transfer.getSize?.()\r\n const done = transfer.getCompletedBytes?.()\r\n if (typeof total !== 'number' || total <= 0 || typeof done !== 'number' || done < 0) {\r\n return transfer.isComplete() ? 100 : 0\r\n }\r\n const value = (done / total) * 100\r\n const clamped = Math.max(0, Math.min(100, value))\r\n return clamped\r\n } catch {\r\n return transfer.isComplete() ? 100 : 0\r\n }\r\n }\r\n\r\n onKeyDown (event: KeyboardEvent): void {\r\n if (event.key === 'Delete' || event.key === 'Backspace') {\r\n event.preventDefault()\r\n if (this.selectedRemote.length) {\r\n this.remoteDelete()\r\n } else if (this.selectedLocal.length) {\r\n this.localDelete()\r\n }\r\n }\r\n }\r\n\r\n override destroy (): void {\r\n // stop file watchers for opened remote files\r\n for (const { watcher } of this.openedRemoteFiles.values()) {\r\n try {\r\n watcher?.close()\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n this.openedRemoteFiles.clear()\r\n\r\n void this.disconnect()\r\n if (this.transfersTimer !== null) {\r\n clearInterval(this.transfersTimer)\r\n this.transfersTimer = null\r\n }\r\n super.destroy()\r\n }\r\n\r\n // Prevent Tabby from restoring SFTP-UI tabs across restarts, since they rely\r\n // on a live SSH session from a terminal tab.\r\n // Typинги допускают RecoveryToken | null, нам достаточно всегда возвращать null.\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n override async getRecoveryToken (_options?: any): Promise<null> {\r\n return null\r\n }\r\n\r\n async confirmDelete (): Promise<void> {\r\n if (!this.deleteConfirmVisible) {\r\n return\r\n }\r\n const mode = this.deleteConfirmMode\r\n this.deleteConfirmVisible = false\r\n\r\n try {\r\n if (mode === 'local') {\r\n const toDelete = this.pendingLocalDelete.slice()\r\n this.pendingLocalDelete = []\r\n for (const entry of toDelete) {\r\n await this.deleteLocalEntry(entry)\r\n }\r\n await this.refreshLocal()\r\n this.selectedLocal = []\r\n } else if (mode === 'remote' && this.sftpSession) {\r\n const toDelete = this.pendingRemoteDelete.slice()\r\n this.pendingRemoteDelete = []\r\n for (const entry of toDelete) {\r\n await this.deleteRemoteEntry(entry)\r\n }\r\n await this.refreshRemote()\r\n this.selectedRemote = []\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Delete failed', e)\r\n } finally {\r\n this.deleteConfirmMode = null\r\n this.deleteConfirmText = ''\r\n }\r\n }\r\n\r\n cancelDelete (): void {\r\n this.deleteConfirmVisible = false\r\n this.deleteConfirmMode = null\r\n this.deleteConfirmText = ''\r\n this.pendingLocalDelete = []\r\n this.pendingRemoteDelete = []\r\n }\r\n\r\n private async deleteLocalEntry (entry: LocalEntry): Promise<void> {\r\n await this.deleteLocalPathRecursive(entry.fullPath)\r\n }\r\n\r\n private async deleteRemoteEntry (entry: SFTPFile): Promise<void> {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n await this.deleteRemotePathRecursive(entry.fullPath)\r\n }\r\n\r\n private buildDeleteConfirmText (scope: 'local' | 'remote', names: string[]): string {\r\n const total = names.length\r\n const label = scope === 'local' ? 'local' : 'remote'\r\n if (!total) {\r\n return `Delete 0 item(s) from ${label}?`\r\n }\r\n const maxShown = 5\r\n const shown = names.slice(0, maxShown)\r\n const list = shown.join(', ')\r\n if (total <= maxShown) {\r\n return `Delete ${total} item(s) from ${label}: ${list}?`\r\n }\r\n const rest = total - maxShown\r\n return `Delete ${total} item(s) from ${label}: ${list} and ${rest} more?`\r\n }\r\n\r\n private async deleteLocalPathRecursive (target: string): Promise<void> {\r\n try {\r\n const st = await fs.stat(target)\r\n if (!st.isDirectory()) {\r\n await fs.unlink(target)\r\n return\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local delete failed (stat)', e)\r\n return\r\n }\r\n\r\n try {\r\n const names = await fs.readdir(target)\r\n for (const name of names) {\r\n const child = path.join(target, name)\r\n await this.deleteLocalPathRecursive(child)\r\n }\r\n await fs.rmdir(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local recursive delete failed', e)\r\n }\r\n }\r\n\r\n private async deleteRemotePathRecursive (target: string): Promise<void> {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n try {\r\n const entries = await this.sftpSession.readdir(target).catch(() => null as any)\r\n if (!entries) {\r\n // treat as file\r\n try {\r\n await this.sftpSession.unlink(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote delete failed', e)\r\n }\r\n return\r\n }\r\n for (const item of entries as SFTPFile[]) {\r\n const full = item.fullPath\r\n if (item.isDirectory) {\r\n await this.deleteRemotePathRecursive(full)\r\n } else {\r\n try {\r\n await this.sftpSession.unlink(full)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote unlink failed', e)\r\n }\r\n }\r\n }\r\n try {\r\n await this.sftpSession.rmdir(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote rmdir failed', e)\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote recursive delete failed', e)\r\n }\r\n }\r\n\r\n private async openRemoteFile (entry: SFTPFile): Promise<void> {\r\n if (!this.sftpSession || !this.connected || entry.isDirectory) {\r\n return\r\n }\r\n try {\r\n const tmpRoot = path.join(os.tmpdir(), 'tabby-sftp-ui')\r\n await fs.mkdir(tmpRoot, { recursive: true })\r\n const localPath = path.join(tmpRoot, entry.name)\r\n\r\n // если уже есть watcher на этот файл – закроем его и перезапишем\r\n const existing = this.openedRemoteFiles.get(localPath)\r\n if (existing?.watcher) {\r\n try {\r\n existing.watcher.close()\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n const dl = new LocalPathFileDownload(localPath, entry.mode, entry.size)\r\n this.trackTransfer(dl, 'download', entry.fullPath, localPath)\r\n await this.sftpSession.download(entry.fullPath, dl)\r\n\r\n // настроим наблюдение за изменениями локального файла\r\n const watcher = fsSync.watch(localPath, { persistent: false }, (eventType) => {\r\n if (eventType === 'change') {\r\n void this.syncBackRemoteFile(localPath)\r\n }\r\n })\r\n this.openedRemoteFiles.set(localPath, { remotePath: entry.fullPath, mode: entry.mode, watcher })\r\n\r\n this.platform.openPath(localPath)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Open remote file failed', e)\r\n }\r\n }\r\n\r\n private async syncBackRemoteFile (localPath: string): Promise<void> {\r\n if (!this.sftpSession || !this.connected) {\r\n return\r\n }\r\n const info = this.openedRemoteFiles.get(localPath)\r\n if (!info) {\r\n return\r\n }\r\n try {\r\n const upload = new LocalPathFileUpload(localPath)\r\n this.trackTransfer(upload, 'upload', info.remotePath, localPath)\r\n await this.sftpSession.upload(info.remotePath, upload)\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Sync-back remote file failed', e)\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpTerminalDecorator extends TerminalDecorator {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n override attach (terminal: BaseTerminalTabComponent): void {\r\n super.attach(terminal)\r\n\r\n // Best-effort DOM injection: place button near the existing Reconnect button if present.\r\n const tryInsert = () => {\r\n try {\r\n const host: HTMLElement | null = terminal.element?.nativeElement ?? null\r\n if (!host) {\r\n return false\r\n }\r\n\r\n // Find a likely toolbar area in the tab UI\r\n const toolbar =\r\n (host.querySelector('.terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('.btn-toolbar') as HTMLElement | null)\r\n\r\n const container = toolbar ?? host\r\n\r\n if (container.querySelector('[data-tabby-sftp-ui-button=\"1\"]')) {\r\n return true\r\n }\r\n\r\n const btn = document.createElement('button')\r\n btn.type = 'button'\r\n // Match Tabby's terminal toolbar buttons styling\r\n btn.className = 'btn btn-sm btn-link me-2'\r\n btn.setAttribute('data-tabby-sftp-ui-button', '1')\r\n btn.title = 'SFTP-UI'\r\n btn.textContent = 'SFTP-UI'\r\n btn.style.pointerEvents = 'auto'\r\n btn.style.zIndex = '10'\r\n btn.style.position = 'relative'\r\n btn.addEventListener('mousedown', (ev) => {\r\n ev.stopPropagation()\r\n })\r\n btn.addEventListener('click', (ev) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n this.sftpUi.openForSourceTab(terminal as any)\r\n })\r\n\r\n // If there's a Reconnect button, insert next to it.\r\n const allButtons = Array.from(container.querySelectorAll('button')) as HTMLButtonElement[]\r\n const reconnectButton = allButtons.find(b => {\r\n const t = `${b.textContent ?? ''} ${b.title ?? ''} ${b.getAttribute('aria-label') ?? ''}`.toLowerCase()\r\n return t.includes('reconnect') || t.includes('переподключ')\r\n })\r\n\r\n if (reconnectButton?.parentElement) {\r\n // Put it right after Reconnect to avoid overlay issues\r\n reconnectButton.parentElement.insertBefore(btn, reconnectButton.nextSibling)\r\n } else {\r\n container.appendChild(btn)\r\n }\r\n\r\n return true\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n // try a few times while the view is settling\r\n let attempts = 0\r\n const timer = setInterval(() => {\r\n attempts++\r\n if (tryInsert() || attempts > 20) {\r\n clearInterval(timer)\r\n }\r\n }, 500)\r\n\r\n this.subscribeUntilDetached(terminal, { unsubscribe: () => clearInterval(timer) } as any)\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { AppService, ToolbarButton, ToolbarButtonProvider } from 'tabby-core'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\n\r\n@Injectable()\r\nexport class SftpToolbarButtons extends ToolbarButtonProvider {\r\n constructor (\r\n private app: AppService,\r\n ) {\r\n super()\r\n }\r\n\r\n provide (): ToolbarButton[] {\r\n return [\r\n {\r\n title: 'SFTP',\r\n weight: 10,\r\n icon: `\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M3 7h5l2 2h11a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2z\"/>\r\n <path d=\"M12 12v6\"/>\r\n <path d=\"M9 15l3 3 3-3\"/>\r\n </svg>\r\n `,\r\n click: () => {\r\n const tab = this.app.openNewTab({\r\n type: SftpManagerTabComponent,\r\n })\r\n tab.setTitle('SFTP')\r\n },\r\n },\r\n ]\r\n }\r\n}\r\n\r\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, HotkeysService, LogService, NotificationsService, SplitTabComponent } from 'tabby-core'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\n\r\n@Injectable()\r\nexport class SftpUiService {\r\n private logger: any\r\n\r\n constructor (\r\n private app: AppService,\r\n private hotkeys: HotkeysService,\r\n private log: LogService,\r\n private zone: NgZone,\r\n private notifications: NotificationsService,\r\n ) {\r\n this.logger = this.log.create('sftp-ui')\r\n\r\n this.hotkeys.hotkey$.subscribe(h => {\r\n if (h === 'open-sftp-ui') {\r\n this.open()\r\n }\r\n })\r\n\r\n this.logger.info('loaded')\r\n }\r\n\r\n open (): void {\r\n const active = this.app.activeTab\r\n const focused = active instanceof SplitTabComponent ? (active.getFocusedTab?.() ?? null) : active\r\n this.openForSourceTab(focused)\r\n }\r\n\r\n openForSourceTab (sourceTab: any): void {\r\n const sshSession = sourceTab?.sshSession ?? null\r\n const profile = sourceTab?.profile ?? null\r\n\r\n this.zone.run(() => {\r\n try {\r\n if (!sshSession) {\r\n this.notifications.error('SFTP-UI', 'No SSH session on current tab')\r\n return\r\n }\r\n const baseTitle =\r\n sourceTab?.customTitle ||\r\n sourceTab?.title ||\r\n profile?.name ||\r\n profile?.options?.host ||\r\n 'SFTP'\r\n const tab = this.app.openNewTab({\r\n type: SftpManagerTabComponent,\r\n inputs: {\r\n sshSession,\r\n profile,\r\n },\r\n })\r\n tab.setTitle(`${baseTitle} + SFTP`)\r\n this.notifications.notice('SFTP-UI opened')\r\n } catch (e) {\r\n this.notifications.error('SFTP-UI failed to open', String(e))\r\n this.logger.error('openForSourceTab failed', e)\r\n }\r\n })\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\n\r\nexport type SFTPFile = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n isSymlink: boolean\r\n mode: number\r\n size: number\r\n modified: Date\r\n}\r\n\r\nexport type SFTPSessionLike = {\r\n readdir: (p: string) => Promise<SFTPFile[]>\r\n mkdir: (p: string) => Promise<void>\r\n rmdir: (p: string) => Promise<void>\r\n unlink: (p: string) => Promise<void>\r\n rename: (oldPath: string, newPath: string) => Promise<void>\r\n upload: (remotePath: string, transfer: import('tabby-core').FileUpload) => Promise<void>\r\n download: (remotePath: string, transfer: import('tabby-core').FileDownload) => Promise<void>\r\n}\r\n\r\nexport type SSHSessionLike = {\r\n openSFTP: () => Promise<SFTPSessionLike>\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SftpConnectionService {\r\n async openFromSSHSession (sshSession: SSHSessionLike): Promise<SFTPSessionLike> {\r\n return await sshSession.openSFTP()\r\n }\r\n}\r\n\r\n","module.exports = require(\"fs/promises\");","module.exports = require(\"os\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tif (!(moduleId in __webpack_modules__)) {\n\t\tdelete __webpack_module_cache__[moduleId];\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport { NgModule } from '@angular/core'\r\nimport { HotkeyProvider, TabContextMenuItemProvider, ToolbarButtonProvider } from 'tabby-core'\r\nimport { TerminalDecorator } from 'tabby-terminal'\r\n\r\nimport { SftpToolbarButtons } from './sftp-toolbar-buttons'\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\nimport { SftpContextMenuProvider } from './sftp-context-menu'\r\nimport { SftpUiHotkeyProvider } from './sftp-hotkey'\r\nimport { SftpUiService } from './sftp-ui.service'\r\nimport { SftpTerminalDecorator } from './sftp-terminal-decorator'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ],\r\n declarations: [\r\n SftpManagerTabComponent,\r\n ],\r\n providers: [\r\n { provide: ToolbarButtonProvider, useClass: SftpToolbarButtons, multi: true },\r\n { provide: TabContextMenuItemProvider, useClass: SftpContextMenuProvider, multi: true },\r\n { provide: HotkeyProvider, useClass: SftpUiHotkeyProvider, multi: true },\r\n { provide: TerminalDecorator, useClass: SftpTerminalDecorator, multi: true },\r\n SftpUiService,\r\n ],\r\n})\r\nexport default class SftpUiModule {\r\n constructor (_: SftpUiService) { }\r\n}\r\n\r\nexport { SftpManagerTabComponent }\r\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;;;;;;;;;;;;;;;;;;;;;ACVwB;AACI;AAEyB;AAE9C,MAAM,mBAAoB,SAAQ,kDAAU;IAIjD,YAAqB,QAAgB;QACnC,KAAK,EAAE;QADY,aAAQ,GAAR,QAAQ,CAAQ;QAH7B,OAAE,GAAkB,IAAI;QACxB,aAAQ,GAAG,CAAC;IAIpB,CAAC;IAED,OAAO;QACL,OAAO,0CAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;IACrC,CAAC;IAED,OAAO;QACL,OAAO,KAAK;IACd,CAAC;IAED,OAAO;QACL,IAAI,CAAC;YACH,OAAO,wCAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,wCAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;QAC3C,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,IAAI,CAAC;QAC1C,MAAM,SAAS,GAAG,wCAAW,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;QACzE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,SAAS;QAC1B,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;QAChC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC;IACnC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,yCAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI;QAChB,CAAC;IACH,CAAC;CACF;AAEM,MAAM,qBAAsB,SAAQ,oDAAY;IAGrD,YAAqB,UAAkB,EAAU,IAAY,EAAU,IAAY;QACjF,KAAK,EAAE;QADY,eAAU,GAAV,UAAU,CAAQ;QAAU,SAAI,GAAJ,IAAI,CAAQ;QAAU,SAAI,GAAJ,IAAI,CAAQ;QAF3E,OAAE,GAAkB,IAAI;IAIhC,CAAC;IAED,OAAO;QACL,OAAO,0CAAa,CAAC,IAAI,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI;IAClB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI;IAClB,CAAC;IAED,KAAK,CAAC,KAAK,CAAE,MAAc;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,wCAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC;QAC7C,CAAC;QACD,yCAAY,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC;QAC7B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,yCAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI;QAChB,CAAC;IACH,CAAC;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClGyC;AACa;AAEN;AAG1C,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,kEAA0B;IACrE,YACU,MAAqB;QAE7B,KAAK,EAAE;QAFC,WAAM,GAAN,MAAM,CAAe;IAG/B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO;YACL;gBACE,KAAK,EAAE,cAAc;gBACrB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;aAChC;SACF;IACH,CAAC;CACF;AAfY,uBAAuB;IADnC,yDAAU,EAAE;qCAGO,2DAAa;GAFpB,uBAAuB,CAenC;;;;;;;;;;;;;;;;;;;;;;;;;;ACrByC;AACC;AAGpC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sDAAc;IACtD,KAAK,CAAC,OAAO;QACX,OAAO;YACL,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE;SAC7C;IACH,CAAC;CACF;AANY,oBAAoB;IADhC,yDAAU,EAAE;GACA,oBAAoB,CAMhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACV2B;AACJ;AACS;AACL;AAE6C;AAC4C;AAEvC;AACmB;AA2W1F,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,wDAAgB;IAsF3D,YACE,QAAkB,EACV,IAA2B,EAC3B,eAAgC,EAChC,GAAe;QAEvB,sGAAsG;QACtG,sDAAsD;QACtD,KAAK,CAAC,QAAQ,CAAC;QANP,SAAI,GAAJ,IAAI,CAAuB;QAC3B,oBAAe,GAAf,eAAe,CAAiB;QAChC,QAAG,GAAH,GAAG,CAAY;QAzFzB,2DAA2D;QAC3D,eAAU,GAA0B,IAAI;QACxC,YAAO,GAAQ,IAAI;QAEnB,eAAU,GAAG,KAAK;QAClB,cAAS,GAAG,KAAK;QAEjB,oEAAoE;QACpE,SAAI,GAAG,EAAE;QACT,SAAI,GAAG,EAAE;QACT,aAAQ,GAAG,EAAE;QACb,aAAQ,GAAG,EAAE;QAEb,cAAS,GAAG,uCAAU,EAAE;QACxB,iBAAY,GAAiB,EAAE;QAE/B,eAAU,GAAG,GAAG;QAChB,kBAAa,GAAe,EAAE;QAEtB,gBAAW,GAA2B,IAAI;QAElD,oBAAe,GAAG,KAAK;QACvB,qBAAgB,GAAG,KAAK;QAExB,cAAS,GAMJ,EAAE;QAEC,mBAAc,GAAkB,IAAI;QAC5C,gBAAW,GAAG,EAAE;QAChB,iBAAY,GAAG,EAAE;QACjB,oBAAe,GAAG,IAAI,CAAC,UAAU;QACjC,mBAAc,GAAG,IAAI,CAAC,SAAS;QACvB,2BAAsB,GAAgB,IAAI,GAAG,EAAE;QAC/C,4BAAuB,GAAgB,IAAI,GAAG,EAAE;QAChD,gBAAW,GAAiC,MAAM;QAClD,iBAAY,GAAG,IAAI;QACnB,iBAAY,GAAiC,MAAM;QACnD,kBAAa,GAAG,IAAI;QACpB,eAAU,GAOP,IAAI;QACP,gBAAW,GAOR,IAAI;QACf,oBAAe,GAAG,KAAK;QACvB,qBAAgB,GAAG,KAAK;QACxB,kBAAa,GAAiB,EAAE;QAChC,mBAAc,GAAe,EAAE;QAC/B,oBAAe,GAAG,EAAE;QACpB,qBAAgB,GAAG,EAAE;QACrB,qBAAgB,GAAG,EAAE;QACrB,sBAAiB,GAAG,EAAE;QACd,2BAAsB,GAAkB,IAAI;QAC5C,4BAAuB,GAAkB,IAAI;QAErD,yBAAoB,GAAG,KAAK;QAC5B,sBAAiB,GAA8B,IAAI;QACnD,sBAAiB,GAAG,EAAE;QACd,uBAAkB,GAAiB,EAAE;QACrC,wBAAmB,GAAe,EAAE;QAEpC,sBAAiB,GAAwF,IAAI,GAAG,EAAE;QAC1H,qBAAgB,GAAuD,EAAE;QACzE,mBAAc,GAAuD,EAAE;QACvE,mBAAc,GAAU,EAAE;QAC1B,qBAAgB,GAAG,KAAK;QACxB,eAAU,GAAG,CAAC;QACd,eAAU,GAAG,CAAC;QACd,mBAAc,GAA2C,EAAE;QAWzD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,uDAAsB,CAAC;QAEpD,gEAAgE;QAChE,MAAM,IAAI,GAAG,uCAAU,EAAE;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACrE,MAAM,OAAO,GAAG,sCAAS,CAAC,IAAI,EAAE,SAAS,CAAC;QAC1C,MAAM,SAAS,GAAG,sCAAS,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9C,MAAM,SAAS,GAAG,sCAAS,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9C,IAAI,0CAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAChF,CAAC;QACD,IAAI,0CAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtF,CAAC;QACD,IAAI,0CAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtF,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE;QACzB,KAAK,IAAI,CAAC,YAAY,EAAE;QAExB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACpG,CAAC,EAAE,IAAI,CAAC;IACV,CAAC;IAED,QAAQ;QACN,sEAAsE;QACtE,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YACzB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;QACpC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,KAAK,IAAI,CAAC,OAAO,EAAE;QACrB,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC;YACxD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;YACtE,IAAI,CAAC,SAAS,GAAG,IAAI;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,EAAE;YAC7C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;YACtC,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,WAAW,GAAG,IAAI;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK;QACtB,IAAI,CAAC,aAAa,GAAG,EAAE;IACzB,CAAC;IAED,UAAU;QACR,MAAM,MAAM,GAAG,yCAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,OAAO,MAAM,KAAK,IAAI,CAAC,SAAS;IAClC,CAAC;IAED,OAAO;QACL,MAAM,MAAM,GAAG,yCAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,MAAM;YACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;YACpC,KAAK,IAAI,CAAC,YAAY,EAAE;QAC1B,CAAC;IACH,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC/C,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,uCAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAChD,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAC3C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,gDAAU,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9C,MAAM,OAAO,GAAiB,EAAE;YAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,QAAQ,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,QAAQ,CAAC;oBAClC,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI;wBACJ,QAAQ;wBACR,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE;wBAC7B,IAAI,EAAE,EAAE,CAAC,IAAI;wBACb,OAAO,EAAE,EAAE,CAAC,OAAO;qBACpB,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,kCAAkC;gBACpC,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY,GAAG,OAAO;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,SAAS,CAAE,CAAa;QACtB,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,QAAQ;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS;QACpC,KAAK,IAAI,CAAC,YAAY,EAAE;IAC1B,CAAC;IAED,UAAU,CAAE,CAAW;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,QAAQ;YAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;YACtC,KAAK,IAAI,CAAC,aAAa,EAAE;QAC3B,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,UAAU,CAAE,EAAa;QACvB,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,gBAAgB,CAAE,KAAiB,EAAE,KAAiB;QACpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;QACvC,CAAC;IACH,CAAC;IAED,iBAAiB,CAAE,KAAe,EAAE,KAAiB;QACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC;QACxC,CAAC;IACH,CAAC;IAED,WAAW,CAAE,KAAiB,EAAE,KAAiB;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,EAAE;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ;QAC9B,IAAI,OAAO,IAAI,IAAI,CAAC,sBAAsB,IAAI,IAAI,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,sBAAsB,GAAG,KAAK;gBACpD,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC;gBACtC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;YACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACtC,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC;YACjD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,sBAAsB,GAAG,KAAK;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC;YAC5B,IAAI,CAAC,sBAAsB,GAAG,KAAK;QACrC,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;QACnD,CAAC;IACH,CAAC;IAED,eAAe,CAAE,KAAiB;QAChC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC3C,CAAC;IAED,YAAY,CAAE,KAAe,EAAE,KAAiB;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,wBAAwB,EAAE;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ;QAC9B,IAAI,OAAO,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,EAAE,CAAC;YACpD,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,uBAAuB,GAAG,KAAK;gBACrD,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC;gBACvC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACvC,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC;YACvD,CAAC;YACD,IAAI,CAAC,uBAAuB,GAAG,KAAK;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,CAAC;YAC7B,IAAI,CAAC,uBAAuB,GAAG,KAAK;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI;YACnD,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,iBAAiB,GAAG,YAAY;QACvC,CAAC;IACH,CAAC;IAED,gBAAgB,CAAE,KAAe;QAC/B,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC5C,CAAC;IAED,YAAY,CAAE,KAAmC;QAC/C,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,GAAG,KAAK;YACxB,IAAI,CAAC,YAAY,GAAG,IAAI;QAC1B,CAAC;IACH,CAAC;IAED,aAAa,CAAE,KAAmC;QAChD,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,aAAa;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,KAAK;YACzB,IAAI,CAAC,aAAa,GAAG,IAAI;QAC3B,CAAC;IACH,CAAC;IAED,gBAAgB,CAAE,EAAa,EAAE,CAAa;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtG,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,wCAAwC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAE/F,8DAA8D;QAC9D,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YACvF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC;QACpD,CAAC;QACD,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,CAAE,EAAE,CAAC,MAAsB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,iBAAiB,CAAE,EAAa,EAAE,IAAc;QAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/G,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAChD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,yCAAyC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAEhG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,OAAO,GAAgB;gBAC3B,IAAI,EAAE,aAAa;gBACnB,UAAU,EAAE,IAAI,CAAC,QAAQ;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB;YACD,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChF,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC;QACvD,CAAC;QACD,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,CAAE,EAAE,CAAC,MAAsB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,cAAc,CAAE,EAAa;QACjC,EAAE,CAAC,cAAc,EAAE;QACnB,IAAI,CAAC,gBAAgB,GAAG,KAAK;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,CAAC;QACnE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,OAAoB;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC;YACvE,MAAM,MAAM,GAAG,IAAI,iEAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,QAAQ,CAAC;YACxE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC;YACvD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,EAAa;QAChC,EAAE,CAAC,cAAc,EAAE;QACnB,IAAI,CAAC,eAAe,GAAG,KAAK;QAC5B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,6BAA6B,CAAC;QACnE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,OAAoB;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC;YAClC,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACjF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC;YACvE,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACvD,MAAM,IAAI,CAAC,YAAY,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,uBAAuB;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY;QAE7B,IAAI,IAAI,CAAC,UAAU;YACjB,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,UAAU;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM;YACjC,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,UAAU;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM;YACjC,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM;QAC/B,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,IAAI,OAAO,GAAG,UAAU;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE;QACzE,OAAO,MAAM;IACf,CAAC;IAED,wBAAwB;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa;QAE9B,IAAI,IAAI,CAAC,WAAW;YAClB,IAAI,CAAC,WAAW,CAAC,UAAU,KAAK,UAAU;YAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,MAAM;YAClC,IAAI,CAAC,WAAW,CAAC,UAAU,KAAK,UAAU;YAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,MAAM;YAClC,IAAI,CAAC,WAAW,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM;QAChC,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,IAAI,OAAO,GAAG,UAAU;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE;QAC1E,OAAO,MAAM;IACf,CAAC;IAEO,gBAAgB,CAAE,OAAqB;QAC7C,MAAM,QAAQ,GAAG,CAAC,CAAa,EAAE,CAAa,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;QAChG,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW;QAC9B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC;YACrB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM;YAC9C,CAAC;YACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;YAC3B,CAAC;YACD,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC;YACzB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC;YACzB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;QAC3B,CAAC,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAE,OAAmB;QAC5C,MAAM,QAAQ,GAAG,CAAC,CAAW,EAAE,CAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5F,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY;QAC/B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC;YACrB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM;YAC9C,CAAC;YACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;gBACtB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;YAC3B,CAAC;YACD,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC;YACvC,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC;YACvC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM;QAC3B,CAAC,CAAC;IACJ,CAAC;IAEO,mBAAmB,CAAE,EAAa;QACxC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,wCAAwC,CAAC;QAC9E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI;QACb,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,GAAG;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI;IACb,CAAC;IAEO,oBAAoB,CAAE,EAAa;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,yCAAyC,CAAC;QAC/E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI;QACb,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,GAAG;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,IAAI;IACb,CAAC;IAED,UAAU,CAAE,KAAc;QACxB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE;QACX,CAAC;QACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,KAAK;QACd,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;QACjD,IAAI,KAAK,GAAG,KAAK;QACjB,IAAI,SAAS,GAAG,CAAC;QACjB,OAAO,KAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,IAAI,IAAI;YACb,SAAS,EAAE;QACb,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;IACvD,CAAC;IAED,WAAW,CAAE,cAAuB;QAClC,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5D,OAAO,EAAE;QACX,CAAC;QACD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,OAAO;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC7D,IAAI,KAAK,GAAG,cAAc;QAC1B,IAAI,SAAS,GAAG,CAAC;QACjB,OAAO,KAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,IAAI,IAAI;YACb,SAAS,EAAE;QACb,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE;IACvD,CAAC;IAED,mBAAmB,CAAE,CAAa;QAChC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChD,OAAO,GAAG;QACZ,CAAC;QACD,OAAO,EAAE;IACX,CAAC;IAED,oBAAoB,CAAE,CAAW;QAC/B,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ;QACtB,IAAK,CAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU,CAAE,CAAS,CAAC,OAAO,CAAC;QAC5C,CAAC;QACD,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,GAAG;QACZ,CAAC;QACD,OAAO,EAAE;IACX,CAAC;IAED,oBAAoB,CAAE,KAAiB,EAAE,EAAa;QACpD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAE,KAAiB,EAAE,EAAa;QACtD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;QACnB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ;QAChC,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC9B,SAAQ;gBACV,CAAC;gBACD,gDAAgD;gBAChD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,qCAAQ,CAAC,EAAE,CAAC;oBACzC,SAAQ;gBACV,CAAC;gBACD,MAAM,IAAI,GAAG,0CAAa,CAAC,GAAG,CAAC;gBAC/B,MAAM,GAAG,GAAG,sCAAS,CAAC,SAAS,EAAE,IAAI,CAAC;gBACtC,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;oBAChB,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,+CAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAC3B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,CAAC,YAAY,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,qBAAqB,CAAE,KAAe,EAAE,EAAa;QACnD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;IACrB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAE,KAAe,EAAE,EAAa;QACrD,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/D,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,EAAE,CAAC,cAAc,EAAE;QACnB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ;QAChC,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC9B,SAAQ;gBACV,CAAC;gBACD,gDAAgD;gBAChD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;oBACpC,SAAQ;gBACV,CAAC;gBACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;gBACvD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,SAAQ;gBACV,CAAC;gBACD,MAAM,GAAG,GAAG,uCAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;gBAC5C,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;oBAChB,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC;gBACzC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACxD,MAAM,MAAM,GAA2C,EAAE;QACzD,IAAI,OAAO,GAAG,GAAG;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,EAAE;YACvD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,MAAM;IACf,CAAC;IAED,wBAAwB,CAAE,KAAa;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI;QAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;QACtC,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,eAAe,IAAI,GAAG,CAAC;QACpE,IAAI,CAAC,UAAU,GAAG,MAAM;QACxB,IAAI,CAAC,eAAe,GAAG,MAAM;QAC7B,KAAK,IAAI,CAAC,aAAa,EAAE;IAC3B,CAAC;IAED,kBAAkB;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC;QAC7E,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,mBAAmB;QACjB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS;QAClC,MAAM,MAAM,GAAG,uCAAU,CAAC,WAAW,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,qCAAQ;QACpC,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QAClD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,qCAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACzD,MAAM,MAAM,GAA2C,EAAE;QAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,IAAI;QACtD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAE7C,IAAI,KAAK,GAAG,IAAI;QAChB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,GAAG,sCAAS,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,MAAM;IACf,CAAC;IAED,uBAAuB,CAAE,KAAa;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC;IAChC,CAAC;IAEO,aAAa,CAAE,MAAc;QACnC,IAAI,CAAC,SAAS,GAAG,MAAM;QACvB,IAAI,CAAC,cAAc,GAAG,MAAM;QAC5B,KAAK,IAAI,CAAC,YAAY,EAAE;IAC1B,CAAC;IAED,mBAAmB,CAAE,EAAU;QAC7B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC;IACjE,CAAC;IAED,qBAAqB;QACnB,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC;QACnF,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,kBAAkB,EAAE;YACzB,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,0CAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS;QAC7D,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACrF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7D,IAAI,CAAC,kBAAkB,EAAE;IAC3B,CAAC;IAED,qBAAqB,CAAE,EAAU;QAC/B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,4BAA4B,CAAE,KAAa,EAAE,KAAiB;QAC5D,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QAED,MAAM,SAAS,GAA2C,EAAE;QAC5D,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC9C,MAAM,WAAW,GAAG,KAAK,KAAK,CAAC;QAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI;QAE3B,0DAA0D;QAC1D,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAa,EAAE;YAC3B,KAAK,IAAI,IAAI,GAAG,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO;gBAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;gBACxC,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK;gBAC/B,IAAI,CAAC;oBACH,IAAI,0CAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAChC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;oBACvB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACvC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kEAAkE;YAClE,MAAM,UAAU,GAAG,yCAAY,CAAC,QAAQ,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,2CAAkB,CAAC,UAAU,CAAC;gBACpD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAG,sCAAS,CAAC,UAAU,EAAE,IAAI,CAAC;oBACxC,IAAI,CAAC;wBACH,MAAM,EAAE,GAAG,wCAAe,CAAC,IAAI,CAAC;wBAChC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;4BACrB,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;wBAC7C,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,SAAS;QAC/B,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO;QAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO;IACjC,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC1D,OAAM;YACR,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,+BAA+B,CAAC;YACxE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,cAAc,GAAG,MAAM;qBACzB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;qBAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACT,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACnE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,0CAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;oBACzD,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;iBACrB,CAAC,CAAC;YACP,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC1D,OAAM;YACR,CAAC;YACD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,+BAA+B,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnG,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,oBAAoB,CAAE,IAAqC;QACzD,IAAI,CAAC,gBAAgB,GAAG,KAAK;QAC7B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEO,kBAAkB,CAAE,CAAS;QACnC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,IAAI,CAAC,SAAS;QACvB,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE;QACrB,oFAAoF;QACpF,IAAI,uCAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,uCAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAM;QACf,CAAC;QACD,uCAAuC;QACvC,OAAO,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC;IAC1C,CAAC;IAEO,mBAAmB,CAAE,CAAS;QACpC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,GAAG;QACZ,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE;QACrB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,GAAG,MAAM;QACvB,CAAC;QACD,2BAA2B;QAC3B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;QACpC,OAAO,MAAM;IACf,CAAC;IAEO,oBAAoB;QAC1B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;QACvG,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,SAAS,QAAQ,EAAE;QAC5B,CAAC;QACD,OAAO,GAAG;IACZ,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,EAAE;YACtD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,cAAc,GAAG,GAAG;YAC3B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,cAAc,GAAG,EAAE;QAC1B,CAAC;IACH,CAAC;IAED,eAAe,CAAE,CAAM;QACrB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,EAAE;QACX,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,SAAS;IACvD,CAAC;IAED,qBAAqB,CAAE,CAAM;QAC3B,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAGD,eAAe;QACb,IAAI,CAAC,gBAAgB,GAAG,KAAK;IAC/B,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;YACrE,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;QACxC,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC9C,KAAK,+CAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;aACnC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,WAAW;QACT,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,OAAO;QAChC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC;QACpE,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAClC,CAAC;IAED,cAAc;QACZ,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC9C,KAAK,8CAAQ,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;aACvC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,oBAAoB;QAClB,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,EAAE,CAAC;YACtE,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC;YAC1D,OAAM;QACR,CAAC;QACD,KAAK,8CAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAW,CAAC;aACvC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACzE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5F,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;QACzC,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACrD,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;aACjD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,QAAQ;QACjC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC;QACrE,IAAI,CAAC,oBAAoB,GAAG,IAAI;IAClC,CAAC;IAED,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE;QAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,uCAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACrD,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;aAChC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,qBAAqB;QACnB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC7F,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC;YAC3D,OAAM;QACR,CAAC;QACD,KAAM,IAAI,CAAC,WAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;aACvD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAChC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3E,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrD,OAAM;QACR,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,SAAQ;YACV,CAAC;YACD,MAAM,eAAe,GAAG,sCAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7D,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7E,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC;YACnE,KAAK,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;iBAC/C,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBAC/B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,qBAAqB,CAAE,KAAiB;QACtC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC/C,KAAK,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;aAC7C,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,KAAK,CAAC,IAAI,GAAG,IAAI;QACnB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC;QACxD,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpD,CAAC,CAAC;IACN,CAAC;IAED,sBAAsB,CAAE,KAAe;QACrC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ;QAC1B,IAAK,KAAa,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC;QACrC,KAAK,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC;aACnC,IAAI,CAAC,IAAI,CAAC,EAAE;YACX,CAAC;YAAC,KAAa,CAAC,OAAO,GAAG,IAAI;QAChC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,CAAC;QAC1C,CAAC,CAAC;IACN,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAE,IAAY;QAChD,IAAI,KAAK,GAAG,CAAC;QACb,MAAM,KAAK,GAAa,CAAC,IAAI,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI;QACvB,IAAI,OAAO,GAAG,CAAC;QACf,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY;YACjC,IAAI,KAAe;YACnB,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,gDAAU,CAAC,GAAG,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;oBAC3B,OAAO,KAAK;gBACd,CAAC;gBACD,MAAM,IAAI,GAAG,sCAAS,CAAC,GAAG,EAAE,IAAI,CAAC;gBACjC,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,IAAI,CAAC;oBAC9B,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;wBACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,KAAK,IAAI,EAAE,CAAC,IAAI;oBAClB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK;IACd,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAE,IAAY;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC;QACV,CAAC;QACD,IAAI,KAAK,GAAG,CAAC;QACb,MAAM,KAAK,GAAa,CAAC,IAAI,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI;QACvB,IAAI,OAAO,GAAG,CAAC;QACf,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY;YACjC,IAAI,OAAmB;YACvB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,SAAQ;YACV,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;oBAC3B,OAAO,KAAK;gBACd,CAAC;gBACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,KAAK,IAAI,IAAI,CAAC,IAAI;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK;IACd,CAAC;IAED,kBAAkB,CAAE,KAAiB,EAAE,KAAiB;QACtD,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,+EAA+E;IACjF,CAAC;IAED,mBAAmB,CAAE,KAAe,EAAE,KAAiB;QACrD,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QAEvB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,+EAA+E;IACjF,CAAC;IAEO,aAAa,CAAE,QAAsB,EAAE,SAAgC,EAAE,UAAkB,EAAE,SAAiB;QACpH,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAClB,QAAQ;YACR,SAAS;YACT,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE;YACxB,UAAU;YACV,SAAS;SACV,CAAC;IACJ,CAAC;IAED,cAAc,CAAE,KAAiC;QAC/C,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;gBAChE,OAAM;YACR,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;QAC3B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,mBAAmB,CAAE,QAAsB;QACzC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,EAAE,EAAE;YAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACpF,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACjD,OAAO,OAAO;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,SAAS,CAAE,KAAoB;QAC7B,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;YACxD,KAAK,CAAC,cAAc,EAAE;YACtB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC/B,IAAI,CAAC,YAAY,EAAE;YACrB,CAAC;iBAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;gBACrC,IAAI,CAAC,WAAW,EAAE;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAEQ,OAAO;QACd,6CAA6C;QAC7C,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1D,IAAI,CAAC;gBACH,OAAO,EAAE,KAAK,EAAE;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;QAE9B,KAAK,IAAI,CAAC,UAAU,EAAE;QACtB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI;QAC5B,CAAC;QACD,KAAK,CAAC,OAAO,EAAE;IACjB,CAAC;IAED,6EAA6E;IAC7E,6CAA6C;IAC7C,iFAAiF;IACjF,6DAA6D;IACpD,KAAK,CAAC,gBAAgB,CAAE,QAAc;QAC7C,OAAO,IAAI;IACb,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB;QACnC,IAAI,CAAC,oBAAoB,GAAG,KAAK;QAEjC,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;gBAChD,IAAI,CAAC,kBAAkB,GAAG,EAAE;gBAC5B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBACpC,CAAC;gBACD,MAAM,IAAI,CAAC,YAAY,EAAE;gBACzB,IAAI,CAAC,aAAa,GAAG,EAAE;YACzB,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE;gBACjD,IAAI,CAAC,mBAAmB,GAAG,EAAE;gBAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBACrC,CAAC;gBACD,MAAM,IAAI,CAAC,aAAa,EAAE;gBAC1B,IAAI,CAAC,cAAc,GAAG,EAAE;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB,GAAG,IAAI;YAC7B,IAAI,CAAC,iBAAiB,GAAG,EAAE;QAC7B,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,oBAAoB,GAAG,KAAK;QACjC,IAAI,CAAC,iBAAiB,GAAG,IAAI;QAC7B,IAAI,CAAC,iBAAiB,GAAG,EAAE;QAC3B,IAAI,CAAC,kBAAkB,GAAG,EAAE;QAC5B,IAAI,CAAC,mBAAmB,GAAG,EAAE;IAC/B,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAE,KAAiB;QAC/C,MAAM,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAE,KAAe;QAC9C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC;IACtD,CAAC;IAEO,sBAAsB,CAAE,KAAyB,EAAE,KAAe;QACxE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM;QAC1B,MAAM,KAAK,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,yBAAyB,KAAK,GAAG;QAC1C,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACtB,OAAO,UAAU,KAAK,iBAAiB,KAAK,KAAK,IAAI,GAAG;QAC1D,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,GAAG,QAAQ;QAC7B,OAAO,UAAU,KAAK,iBAAiB,KAAK,KAAK,IAAI,QAAQ,IAAI,QAAQ;IAC3E,CAAC;IAEO,KAAK,CAAC,wBAAwB,CAAE,MAAc;QACpD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,6CAAO,CAAC,MAAM,CAAC;YAChC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,MAAM,+CAAS,CAAC,MAAM,CAAC;gBACvB,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,CAAC,CAAC;YACxD,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,gDAAU,CAAC,MAAM,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,sCAAS,CAAC,MAAM,EAAE,IAAI,CAAC;gBACrC,MAAM,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC;YAC5C,CAAC;YACD,MAAM,8CAAQ,CAAC,MAAM,CAAC;QACxB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAE,MAAc;QACrD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAW,CAAC;YAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,gBAAgB;gBAChB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACvC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,OAAM;YACR,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAqB,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;gBAC1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;oBACrC,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;YACtC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAE,KAAe;QAC3C,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9D,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,sCAAS,CAAC,sCAAS,EAAE,EAAE,eAAe,CAAC;YACvD,MAAM,8CAAQ,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,sCAAS,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC;YAEhD,iEAAiE;YACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;YACtD,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,MAAM,EAAE,GAAG,IAAI,mEAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YACvE,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC;YAC7D,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YAEnD,sDAAsD;YACtD,MAAM,OAAO,GAAG,qCAAY,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE;gBAC3E,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,KAAK,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC;gBACzC,CAAC;YACH,CAAC,CAAC;YACF,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YAEhG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAE,SAAiB;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;QAClD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,iEAAmB,CAAC,SAAS,CAAC;YACjD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC;YAChE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;YACtD,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF;AA9gBC;IADC,2DAAY,CAAC,gBAAgB,CAAC;;;;8DAG9B;AA7gCU,uBAAuB;IA7VnC,wDAAS,CAAC;QACT,QAAQ,EAAE,wBAAwB;QAClC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiRT;QACD,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuER,CAAC;KACH,CAAC;qCAwFY,mDAAQ;QACJ,gEAAqB;QACV,uDAAe;QAC3B,kDAAU;GA1Fd,uBAAuB,CAyhDnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC74DyC;AACkC;AAE3B;AAG1C,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,6DAAiB;IAC1D,YACU,MAAqB;QAE7B,KAAK,EAAE;QAFC,WAAM,GAAN,MAAM,CAAe;IAG/B,CAAC;IAEQ,MAAM,CAAE,QAAkC;QACjD,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;QAEtB,yFAAyF;QACzF,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAuB,QAAQ,CAAC,OAAO,EAAE,aAAa,IAAI,IAAI;gBACxE,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO,KAAK;gBACd,CAAC;gBAED,2CAA2C;gBAC3C,MAAM,OAAO,GACV,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAwB;oBAC9D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAwB;oBAC7D,IAAI,CAAC,aAAa,CAAC,cAAc,CAAwB;gBAE5D,MAAM,SAAS,GAAG,OAAO,IAAI,IAAI;gBAEjC,IAAI,SAAS,CAAC,aAAa,CAAC,iCAAiC,CAAC,EAAE,CAAC;oBAC/D,OAAO,IAAI;gBACb,CAAC;gBAED,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;gBAC5C,GAAG,CAAC,IAAI,GAAG,QAAQ;gBACnB,iDAAiD;gBACjD,GAAG,CAAC,SAAS,GAAG,0BAA0B;gBAC1C,GAAG,CAAC,YAAY,CAAC,2BAA2B,EAAE,GAAG,CAAC;gBAClD,GAAG,CAAC,KAAK,GAAG,SAAS;gBACrB,GAAG,CAAC,WAAW,GAAG,SAAS;gBAC3B,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM;gBAChC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI;gBACvB,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU;gBAC/B,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE;oBACvC,EAAE,CAAC,eAAe,EAAE;gBACtB,CAAC,CAAC;gBACF,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;oBACnC,EAAE,CAAC,cAAc,EAAE;oBACnB,EAAE,CAAC,eAAe,EAAE;oBACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAe,CAAC;gBAC/C,CAAC,CAAC;gBAEF,oDAAoD;gBACpD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAwB;gBAC1F,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;oBAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE;oBACvG,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAC7D,CAAC,CAAC;gBAEF,IAAI,eAAe,EAAE,aAAa,EAAE,CAAC;oBACnC,uDAAuD;oBACvD,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,WAAW,CAAC;gBAC9E,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;gBAC5B,CAAC;gBAED,OAAO,IAAI;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK;YACd,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,IAAI,QAAQ,GAAG,CAAC;QAChB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,QAAQ,EAAE;YACV,IAAI,SAAS,EAAE,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;gBACjC,aAAa,CAAC,KAAK,CAAC;YACtB,CAAC;QACH,CAAC,EAAE,GAAG,CAAC;QAEP,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAS,CAAC;IAC3F,CAAC;CACF;AAhFY,qBAAqB;IADjC,yDAAU,EAAE;qCAGO,2DAAa;GAFpB,qBAAqB,CAgFjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtFiD;AAC0D;AAEtC;AAG/D,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGxB,YACU,GAAe,EACf,OAAuB,EACvB,GAAe,EACf,IAAY,EACZ,aAAmC;QAJnC,QAAG,GAAH,GAAG,CAAY;QACf,YAAO,GAAP,OAAO,CAAgB;QACvB,QAAG,GAAH,GAAG,CAAY;QACf,SAAI,GAAJ,IAAI,CAAQ;QACZ,kBAAa,GAAb,aAAa,CAAsB;QAE3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;QAExC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;YACjC,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,EAAE;YACb,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAI;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;QACjC,MAAM,OAAO,GAAG,MAAM,YAAY,yDAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;QACjG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,gBAAgB,CAAE,SAAc;QAC9B,MAAM,UAAU,GAAG,SAAS,EAAE,UAAU,IAAI,IAAI;QAChD,MAAM,OAAO,GAAG,SAAS,EAAE,OAAO,IAAI,IAAI;QAE1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,+BAA+B,CAAC;oBACpE,OAAM;gBACR,CAAC;gBACD,MAAM,SAAS,GACb,SAAS,EAAE,WAAW;oBACtB,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,OAAO,EAAE,IAAI;oBACtB,MAAM;gBACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;oBAC9B,IAAI,EAAE,gFAAuB;oBAC7B,MAAM,EAAE;wBACN,UAAU;wBACV,OAAO;qBACR;iBACF,CAAC;gBACF,GAAG,CAAC,QAAQ,CAAC,GAAG,SAAS,SAAS,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC7C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CACF;AA1DY,aAAa;IADzB,yDAAU,EAAE;qCAKI,kDAAU;QACN,sDAAc;QAClB,kDAAU;QACT,iDAAM;QACG,4DAAoB;GARlC,aAAa,CA0DzB;;;;;;;;;;;;;;;;;;;;;;;;AChEyC;AA2BnC,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,KAAK,CAAC,kBAAkB,CAAE,UAA0B;QAClD,OAAO,MAAM,UAAU,CAAC,QAAQ,EAAE;IACpC,CAAC;CACF;AAJY,qBAAqB;IADjC,yDAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;GACtB,qBAAqB,CAIjC;;;;;;;;;;;;AC/BD,wC;;;;;;;;;;ACAA,+B;;;;;;;;;;ACAA,6D;;;;;;;;;;ACAA,2D;;;;;;;;;;ACAA,4D;;;;;;;;;;ACAA,gD;;;;;;;;;;ACAA,kD;;;;;;;;;;ACAA,wD;;;;;;;;;;ACAA,4D;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;;;;;WC5BA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA,E;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D,E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACN8C;AACF;AACJ;AAC+B;AACrB;AAEoB;AACT;AACT;AACH;AACgB;AAiBlD,IAAM,YAAY,GAAlB,MAAM,YAAY;IAC/B,YAAa,CAAgB,IAAI,CAAC;CACnC;AAFoB,YAAY;IAfhC,uDAAQ,CAAC;QACR,OAAO,EAAE;YACP,yDAAY;YACZ,uDAAW;SACZ;QACD,YAAY,EAAE;YACZ,gFAAuB;SACxB;QACD,SAAS,EAAE;YACT,EAAE,OAAO,EAAE,kEAA0B,EAAE,QAAQ,EAAE,uEAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;YACvF,EAAE,OAAO,EAAE,sDAAc,EAAE,QAAQ,EAAE,8DAAoB,EAAE,KAAK,EAAE,IAAI,EAAE;YACxE,EAAE,OAAO,EAAE,6DAAiB,EAAE,QAAQ,EAAE,2EAAqB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC5E,2DAAa;SACd;KACF,CAAC;qCAEgB,2DAAa;GADV,YAAY,CAEhC;iEAFoB,YAAY;AAIC","sources":["webpack-tabby-sftp-ui:///webpack/universalModuleDefinition","webpack-tabby-sftp-ui:///./src/local-transfers.ts","webpack-tabby-sftp-ui:///./src/sftp-context-menu.ts","webpack-tabby-sftp-ui:///./src/sftp-hotkey.ts","webpack-tabby-sftp-ui:///./src/sftp-manager-tab.component.ts","webpack-tabby-sftp-ui:///./src/sftp-terminal-decorator.ts","webpack-tabby-sftp-ui:///./src/sftp-ui.service.ts","webpack-tabby-sftp-ui:///./src/sftp.service.ts","webpack-tabby-sftp-ui:///external node-commonjs \"fs/promises\"","webpack-tabby-sftp-ui:///external node-commonjs \"os\"","webpack-tabby-sftp-ui:///external umd \"@angular/common\"","webpack-tabby-sftp-ui:///external umd \"@angular/core\"","webpack-tabby-sftp-ui:///external umd \"@angular/forms\"","webpack-tabby-sftp-ui:///external umd \"fs\"","webpack-tabby-sftp-ui:///external umd \"path\"","webpack-tabby-sftp-ui:///external umd \"tabby-core\"","webpack-tabby-sftp-ui:///external umd \"tabby-terminal\"","webpack-tabby-sftp-ui:///webpack/bootstrap","webpack-tabby-sftp-ui:///webpack/runtime/compat get default export","webpack-tabby-sftp-ui:///webpack/runtime/define property getters","webpack-tabby-sftp-ui:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-sftp-ui:///webpack/runtime/make namespace object","webpack-tabby-sftp-ui:///./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/forms\", \"@angular/core\", \"tabby-core\", \"tabby-terminal\", \"path\", \"fs\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\")) : factory(root[\"@angular/common\"], root[\"@angular/forms\"], root[\"@angular/core\"], root[\"tabby-core\"], root[\"tabby-terminal\"], root[\"path\"], root[\"fs\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(global, (__WEBPACK_EXTERNAL_MODULE__angular_common__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_fs__) => {\nreturn ","import * as fs from 'fs'\r\nimport * as path from 'path'\r\n\r\nimport { FileDownload, FileUpload } from 'tabby-core'\r\n\r\nexport class LocalPathFileUpload extends FileUpload {\r\n private fd: number | null = null\r\n private position = 0\r\n\r\n constructor (private filePath: string) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.filePath)\r\n }\r\n\r\n getMode (): number {\r\n return 0o644\r\n }\r\n\r\n getSize (): number {\r\n try {\r\n return fs.statSync(this.filePath).size\r\n } catch {\r\n return 0\r\n }\r\n }\r\n\r\n async read (): Promise<Buffer> {\r\n if (this.isCancelled()) {\r\n return Buffer.alloc(0)\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.filePath, 'r')\r\n }\r\n const buf = Buffer.allocUnsafe(256 * 1024)\r\n const bytesRead = fs.readSync(this.fd, buf, 0, buf.length, this.position)\r\n if (!bytesRead) {\r\n return Buffer.alloc(0)\r\n }\r\n this.position += bytesRead\r\n this.increaseProgress(bytesRead)\r\n return buf.subarray(0, bytesRead)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\nexport class LocalPathFileDownload extends FileDownload {\r\n private fd: number | null = null\r\n\r\n constructor (private targetPath: string, private mode: number, private size: number) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.targetPath)\r\n }\r\n\r\n getMode (): number {\r\n return this.mode\r\n }\r\n\r\n getSize (): number {\r\n return this.size\r\n }\r\n\r\n async write (buffer: Buffer): Promise<void> {\r\n if (this.isCancelled()) {\r\n return\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.targetPath, 'w')\r\n }\r\n fs.writeSync(this.fd, buffer)\r\n this.increaseProgress(buffer.length)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TabContextMenuItemProvider } from 'tabby-core'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpContextMenuProvider extends TabContextMenuItemProvider {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n async getItems (): Promise<Array<{ label: string, click: () => void }>> {\r\n return [\r\n {\r\n label: 'Open SFTP UI',\r\n click: () => this.sftpUi.open(),\r\n },\r\n ]\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { HotkeyProvider } from 'tabby-core'\r\n\r\n@Injectable()\r\nexport class SftpUiHotkeyProvider extends HotkeyProvider {\r\n async provide (): Promise<Array<{ id: string, name: string }>> {\r\n return [\r\n { id: 'open-sftp-ui', name: 'Open SFTP UI' },\r\n ]\r\n }\r\n}\r\n\r\n","import * as path from 'path'\r\nimport * as os from 'os'\r\nimport * as fs from 'fs/promises'\r\nimport * as fsSync from 'fs'\r\n\r\nimport { Component, Injector, OnInit, HostListener } from '@angular/core'\r\nimport { AppService, BaseTabComponent, FileTransfer, FileUpload, PlatformService, ProfilesService } from 'tabby-core'\r\n\r\nimport { LocalPathFileDownload, LocalPathFileUpload } from './local-transfers'\r\nimport { SftpConnectionService, SFTPFile, SFTPSessionLike, SSHSessionLike } from './sftp.service'\r\n\r\ntype LocalEntry = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n size?: number\r\n mtimeMs?: number\r\n}\r\n\r\ntype DragPayload =\r\n | { kind: 'local-file', fullPath: string, name: string }\r\n | { kind: 'remote-file', remotePath: string, name: string, size: number, mode: number }\r\n\r\n@Component({\r\n selector: 'tabby-sftp-manager-tab',\r\n template: `\r\n <div class=\"sftp-root\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\r\n <div class=\"top-profiles\" *ngIf=\"profile || recentProfiles.length\">\r\n <div class=\"current\" *ngIf=\"profile\">\r\n <span class=\"label\">Device:</span>\r\n <span class=\"value\">{{ getProfileLabel(profile) }}</span>\r\n </div>\r\n <div class=\"recent\" *ngIf=\"recentProfiles.length\">\r\n <span class=\"label\">Recent:</span>\r\n <button\r\n class=\"profile-chip\"\r\n *ngFor=\"let p of recentProfiles\"\r\n (click)=\"launchProfileFromSFTP(p)\"\r\n >\r\n {{ getProfileLabel(p) }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"sftp-body\">\r\n <div class=\"pane\">\r\n <div class=\"pane-title\">\r\n <div class=\"pane-label\">Local</div>\r\n <div class=\"pane-path\">\r\n <input\r\n [(ngModel)]=\"localPathInput\"\r\n (keyup.enter)=\"goToLocalPathInput()\"\r\n />\r\n </div>\r\n <div class=\"pane-actions\">\r\n <select class=\"path-preset\" (change)=\"onLocalPresetChange($event.target.value)\">\r\n <option value=\"\">Go to…</option>\r\n <option *ngFor=\"let p of localPathPresets\" [value]=\"p.id\">\r\n {{ p.label }}\r\n </option>\r\n </select>\r\n <button\r\n class=\"fav-toggle\"\r\n [class.active]=\"isCurrentFavorite()\"\r\n (click)=\"toggleCurrentFavorite()\"\r\n title=\"Toggle favorite for this path\"\r\n >\r\n ★\r\n </button>\r\n <select class=\"path-favorite\" (change)=\"onLocalFavoriteSelect($event.target.value)\">\r\n <option value=\"\">Favorites…</option>\r\n <option *ngFor=\"let f of localFavorites\" [value]=\"f.id\">\r\n {{ f.label }}\r\n </option>\r\n </select>\r\n <button (click)=\"localUp()\" [disabled]=\"!canLocalUp()\">Up</button>\r\n <button (click)=\"goToLocalPathInput()\">Go</button>\r\n <button (click)=\"refreshLocal()\">Refresh</button>\r\n </div>\r\n </div>\r\n <div class=\"pane-filters\">\r\n <div class=\"breadcrumbs\">\r\n <ng-container *ngFor=\"let part of getLocalBreadcrumbs(); let i = index; let last = last\">\r\n <button\r\n class=\"crumb-button\"\r\n (click)=\"navigateLocalBreadcrumb(i)\"\r\n (contextmenu)=\"onLocalBreadcrumbContextMenu(i, $event)\"\r\n >\r\n {{ part.label }}\r\n </button>\r\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\r\n </ng-container>\r\n </div>\r\n <input [(ngModel)]=\"localFilter\" placeholder=\"Filter files...\" />\r\n <label class=\"show-hidden-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenLocal\" />\r\n <span>Show hidden</span>\r\n </label>\r\n </div>\r\n <div class=\"pane-list\"\r\n (dragover)=\"onDragOver($event)\"\r\n (drop)=\"onDropOnLocal($event)\"\r\n >\r\n <div class=\"entry header\">\r\n <span class=\"icon\"></span>\r\n <span class=\"name sortable\" (click)=\"setLocalSort('name')\">Name</span>\r\n <span class=\"size sortable\" (click)=\"setLocalSort('size')\">Size</span>\r\n <span class=\"date sortable\" (click)=\"setLocalSort('modified')\">Modified</span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngFor=\"let e of getFilteredLocalEntries()\"\r\n (click)=\"selectLocal(e, $event)\"\r\n (dblclick)=\"openLocal(e)\"\r\n (mousedown)=\"onLocalMouseDown(e, $event)\"\r\n (contextmenu)=\"onLocalContextMenu(e, $event)\"\r\n (dragover)=\"onLocalEntryDragOver(e, $event)\"\r\n (drop)=\"onLocalEntryDrop(e, $event)\"\r\n [class.drop-target]=\"localDropActive\"\r\n [class.selected]=\"isLocalSelected(e)\"\r\n [draggable]=\"true\"\r\n (dragstart)=\"onDragStartLocal($event, e)\"\r\n >\r\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\r\n <span class=\"name\">{{ e.name }}</span>\r\n <span class=\"size\">{{ getLocalSizeDisplay(e) }}</span>\r\n <span class=\"date\">{{ e.mtimeMs ? (e.mtimeMs | date:'yyyy-MM-dd HH:mm') : '' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"pane-actions-bar\">\r\n <div class=\"selection\" *ngIf=\"selectedLocal.length\">\r\n Selected: {{ selectedLocal.length === 1 ? selectedLocal[0].name : (selectedLocal.length + ' items') }}\r\n </div>\r\n <div class=\"action-inputs\">\r\n <input [(ngModel)]=\"localActionName\" placeholder=\"Name / new name\" />\r\n <input [(ngModel)]=\"localActionPerms\" placeholder=\"Perms (e.g. 755)\" />\r\n </div>\r\n <div class=\"action-buttons\">\r\n <button (click)=\"localRename()\" [disabled]=\"selectedLocal.length !== 1 || !localActionName\">Rename</button>\r\n <button (click)=\"refreshLocal()\">Refresh</button>\r\n <button (click)=\"localDelete()\" [disabled]=\"!selectedLocal.length\">Delete</button>\r\n <button (click)=\"localNewFolder()\">New Folder</button>\r\n <button (click)=\"localEditPermissions()\" [disabled]=\"selectedLocal.length !== 1 || !localActionPerms\">Edit Permissions</button>\r\n <button (click)=\"localShowSize()\" [disabled]=\"selectedLocal.length !== 1 || !selectedLocal[0].isDirectory\">Show Size</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"pane\">\r\n <div class=\"pane-title\">\r\n <div class=\"pane-label\">\r\n Remote\r\n <span *ngIf=\"connected && profile?.options?.host\" class=\"pane-sub\">\r\n — {{ profile.options.host }}\r\n </span>\r\n </div>\r\n <div class=\"pane-path\">\r\n <input\r\n [(ngModel)]=\"remotePathInput\"\r\n (keyup.enter)=\"goToRemotePathInput()\"\r\n [disabled]=\"!connected\"\r\n />\r\n </div>\r\n <div class=\"pane-actions\">\r\n <button (click)=\"remoteUp()\" [disabled]=\"!connected || remotePath === '/'\">Up</button>\r\n <button (click)=\"goToRemotePathInput()\" [disabled]=\"!connected\">Go</button>\r\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\r\n </div>\r\n </div>\r\n <div class=\"pane-filters\">\r\n <div class=\"breadcrumbs\" *ngIf=\"connected\">\r\n <ng-container *ngFor=\"let part of getRemoteBreadcrumbs(); let i = index; let last = last\">\r\n <button\r\n class=\"crumb-button\"\r\n (click)=\"navigateRemoteBreadcrumb(i)\"\r\n >\r\n {{ part.label }}\r\n </button>\r\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\r\n </ng-container>\r\n </div>\r\n <input [(ngModel)]=\"remoteFilter\" placeholder=\"Filter files...\" />\r\n <label class=\"show-hidden-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenRemote\" />\r\n <span>Show hidden</span>\r\n </label>\r\n </div>\r\n <div class=\"pane-list\"\r\n (dragover)=\"onDragOver($event)\"\r\n (drop)=\"onDropOnRemote($event)\"\r\n >\r\n <div class=\"entry dim\" *ngIf=\"!connected\">\r\n <span class=\"name\">Not connected</span>\r\n </div>\r\n <div class=\"entry header\" *ngIf=\"connected\">\r\n <span class=\"icon\"></span>\r\n <span class=\"name sortable\" (click)=\"setRemoteSort('name')\">Name</span>\r\n <span class=\"size sortable\" (click)=\"setRemoteSort('size')\">Size</span>\r\n <span class=\"date sortable\" (click)=\"setRemoteSort('modified')\">Modified</span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngIf=\"connected && remotePath !== '/'\"\r\n (dblclick)=\"remoteUp()\"\r\n >\r\n <span class=\"icon\">⬆</span>\r\n <span class=\"name\">Go up</span>\r\n <span class=\"size\"></span>\r\n <span class=\"date\"></span>\r\n </div>\r\n <div\r\n class=\"entry\"\r\n *ngFor=\"let e of getFilteredRemoteEntries()\"\r\n (click)=\"selectRemote(e, $event)\"\r\n (dblclick)=\"openRemote(e)\"\r\n (mousedown)=\"onRemoteMouseDown(e, $event)\"\r\n (contextmenu)=\"onRemoteContextMenu(e, $event)\"\r\n (dragover)=\"onRemoteEntryDragOver(e, $event)\"\r\n (drop)=\"onRemoteEntryDrop(e, $event)\"\r\n [class.drop-target]=\"remoteDropActive\"\r\n [class.selected]=\"isRemoteSelected(e)\"\r\n [draggable]=\"connected\"\r\n (dragstart)=\"onDragStartRemote($event, e)\"\r\n >\r\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\r\n <span class=\"name\">{{ e.name }}</span>\r\n <span class=\"size\">{{ getRemoteSizeDisplay(e) }}</span>\r\n <span class=\"date\">{{ e.modified | date:'yyyy-MM-dd HH:mm' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"pane-actions-bar\">\r\n <div class=\"selection\" *ngIf=\"selectedRemote.length\">\r\n Selected: {{ selectedRemote.length === 1 ? selectedRemote[0].name : (selectedRemote.length + ' items') }}\r\n </div>\r\n <div class=\"action-inputs\">\r\n <input [(ngModel)]=\"remoteActionName\" placeholder=\"Name / new name\" />\r\n <input [(ngModel)]=\"remoteActionPerms\" placeholder=\"Perms (e.g. 755)\" />\r\n </div>\r\n <div class=\"action-buttons\">\r\n <button (click)=\"remoteRename()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionName\">Rename</button>\r\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\r\n <button (click)=\"remoteDelete()\" [disabled]=\"!selectedRemote.length\">Delete</button>\r\n <button (click)=\"remoteNewFolder()\" [disabled]=\"!connected\">New Folder</button>\r\n <button (click)=\"remoteEditPermissions()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionPerms\">Edit Permissions</button>\r\n <button (click)=\"remoteShowSize()\" [disabled]=\"selectedRemote.length !== 1 || !selectedRemote[0].isDirectory\">Show Size</button>\r\n <button (click)=\"remoteDownload()\" [disabled]=\"!selectedRemote.length\">Download</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"sftp-transfers\" *ngIf=\"transfers.length\">\r\n <div class=\"transfer\" *ngFor=\"let t of transfers\">\r\n <div class=\"transfer-main\">\r\n <div class=\"transfer-title\">\r\n <span class=\"direction\">{{ t.direction === 'upload' ? 'Upload' : 'Download' }}</span>\r\n <span class=\"name\">{{ t.name }}</span>\r\n </div>\r\n <div class=\"transfer-path\">\r\n <span class=\"label\">Remote:</span>\r\n <span class=\"value\">{{ t.remotePath }}</span>\r\n </div>\r\n <div class=\"transfer-path\">\r\n <span class=\"label\">Local:</span>\r\n <span class=\"value\">{{ t.localPath }}</span>\r\n </div>\r\n <div class=\"bar\">\r\n <div class=\"fill\" [style.width.%]=\"getTransferProgress(t.transfer)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"transfer-stats\">\r\n <div class=\"percent\">{{ getTransferProgress(t.transfer) | number:'1.0-0' }}%</div>\r\n <div class=\"speed\">{{ formatSpeed(t.transfer.getSpeed()) }}</div>\r\n <button class=\"btn-cancel\" (click)=\"cancelTransfer(t)\" [disabled]=\"t.transfer.isComplete() || t.transfer.isCancelled()\">Cancel</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"delete-overlay\" *ngIf=\"deleteConfirmVisible\">\r\n <div class=\"delete-dialog\">\r\n <div class=\"delete-text\">{{ deleteConfirmText }}</div>\r\n <div class=\"delete-buttons\">\r\n <button class=\"danger\" (click)=\"confirmDelete()\">Delete</button>\r\n <button (click)=\"cancelDelete()\">Cancel</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"local-menu\"\r\n *ngIf=\"localMenuVisible\"\r\n [style.left.px]=\"localMenuX\"\r\n [style.top.px]=\"localMenuY\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"local-menu-item\" *ngFor=\"let item of localMenuItems\" (click)=\"onLocalMenuItemClick(item)\">\r\n {{ item.label }}\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .sftp-root { display: flex; flex-direction: column; height: 100%; padding: 10px; gap: 10px; position: relative; }\r\n button { padding: 6px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.06); color: inherit; cursor: pointer; }\r\n button:disabled { opacity: 0.5; cursor: default; }\r\n .top-profiles { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px 8px; gap: 12px; font-size: 11px; opacity: 0.9; }\r\n .top-profiles .current .label,\r\n .top-profiles .recent .label { text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.7; margin-right: 4px; }\r\n .top-profiles .value { font-weight: 600; }\r\n .top-profiles .profile-chip { padding: 2px 8px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\r\n .top-profiles .profile-chip:hover { background: rgba(255,255,255,0.12); }\r\n .sftp-body { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; flex: 1; min-height: 0; }\r\n .pane { display: flex; flex-direction: column; border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; overflow: hidden; min-height: 0; }\r\n .pane-title { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; padding: 8px 10px; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); }\r\n .pane-label { font-weight: 600; display: flex; align-items: baseline; gap: 6px; }\r\n .pane-sub { font-weight: 400; font-size: 11px; opacity: 0.75; }\r\n .pane-path { opacity: 0.8; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .pane-path input { width: 100%; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-family: inherit; font-size: 12px; }\r\n .pane-actions { display: flex; gap: 8px; align-items: center; }\r\n .pane-actions .path-preset,\r\n .pane-actions .path-favorite { max-width: 150px; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.22); background: rgba(20,20,20,0.95); color: inherit; font-size: 11px; }\r\n .pane-actions .path-preset option { background: #151515; color: #f5f5f5; }\r\n .pane-actions .path-favorite option { background: #151515; color: #f5f5f5; }\r\n .pane-actions .fav-toggle { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.05); font-size: 11px; line-height: 1; }\r\n .pane-actions .fav-toggle.active { background: rgba(255,215,0,0.2); border-color: rgba(255,215,0,0.6); color: #ffd700; }\r\n .pane-filters { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.12); }\r\n .pane-filters input { flex: 1; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 12px; }\r\n .show-hidden-toggle { display: flex; align-items: center; gap: 4px; font-size: 11px; opacity: 0.8; white-space: nowrap; }\r\n .show-hidden-toggle input[type=\"checkbox\"] { margin: 0; }\r\n .breadcrumbs { display: flex; flex-wrap: wrap; gap: 4px; font-size: 11px; opacity: 0.9; align-items: center; }\r\n .crumb-button { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\r\n .crumb-button:hover { background: rgba(255,255,255,0.10); }\r\n .crumb-separator { opacity: 0.6; }\r\n .pane-list { flex: 1; overflow: auto; padding: 4px; }\r\n .entry { display: grid; grid-template-columns: 24px minmax(0, 1.5fr) 80px 140px; gap: 8px; padding: 6px 8px; border-radius: 8px; user-select: none; align-items: center; }\r\n .entry:hover { background: rgba(255,255,255,0.06); }\r\n .entry.drop-target { outline: 1px dashed rgba(255,255,255,0.35); background: rgba(80, 160, 255, 0.10); }\r\n .entry.dim { opacity: 0.7; }\r\n .icon { text-align: center; opacity: 0.85; }\r\n .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .size { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; text-align: right; opacity: 0.8; }\r\n .date { font-size: 11px; opacity: 0.75; text-align: right; white-space: nowrap; }\r\n .entry.header { font-weight: 600; opacity: 0.9; background: rgba(255,255,255,0.02); }\r\n .sortable { cursor: pointer; }\r\n .entry.selected { background: rgba(80,160,255,0.18); }\r\n .pane-actions-bar { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border-top: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.18); }\r\n .pane-actions-bar .selection { font-size: 11px; opacity: 0.85; }\r\n .pane-actions-bar .action-inputs { display: flex; gap: 6px; }\r\n .pane-actions-bar .action-inputs input { flex: 1; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 11px; }\r\n .pane-actions-bar .action-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }\r\n .sftp-transfers { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; max-height: 120px; overflow-y: auto; }\r\n .transfer { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 6px 8px; border-radius: 8px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); font-size: 11px; }\r\n .transfer-title { display: flex; gap: 6px; align-items: baseline; margin-bottom: 2px; }\r\n .transfer-title .direction { text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; font-weight: 600; font-size: 10px; }\r\n .transfer-title .name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n .transfer-path { display: flex; gap: 4px; opacity: 0.75; }\r\n .transfer-path .label { min-width: 48px; }\r\n .transfer-path .value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\r\n .bar { position: relative; height: 4px; border-radius: 999px; background: rgba(255,255,255,0.07); margin-top: 4px; overflow: hidden; }\r\n .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: inherit; background: linear-gradient(90deg, #4dabff, #78ffce); transition: width 0.15s linear; }\r\n .transfer-stats { display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 4px; opacity: 0.8; }\r\n .transfer-stats .percent { font-weight: 600; }\r\n .transfer-stats .speed { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\r\n .btn-cancel { padding: 2px 6px; font-size: 10px; border-radius: 999px; }\r\n .delete-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; z-index: 20; }\r\n .delete-dialog { min-width: 260px; max-width: 360px; padding: 14px 16px; border-radius: 10px; background: rgba(20,20,20,0.96); border: 1px solid rgba(255,255,255,0.15); box-shadow: 0 18px 45px rgba(0,0,0,0.75); display: flex; flex-direction: column; gap: 10px; }\r\n .delete-text { font-size: 13px; }\r\n .delete-buttons { display: flex; justify-content: flex-end; gap: 8px; }\r\n .delete-buttons .danger { background: rgba(255,80,80,0.85); border-color: rgba(255,120,120,0.85); }\r\n .local-menu { position: absolute; min-width: 180px; max-width: 260px; max-height: 260px; overflow-y: auto; padding: 4px 0; border-radius: 10px; background: rgba(18,18,22,0.98); border: 1px solid rgba(255,255,255,0.16); box-shadow: 0 18px 45px rgba(0,0,0,0.8); z-index: 30; backdrop-filter: blur(12px); }\r\n .local-menu-item { padding: 6px 12px; font-size: 12px; cursor: pointer; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }\r\n .local-menu-item:hover { background: linear-gradient(90deg, rgba(120,200,255,0.24), rgba(120,255,206,0.15)); }\r\n `],\r\n})\r\nexport class SftpManagerTabComponent extends BaseTabComponent implements OnInit {\r\n // injected from the SSH tab when opened via SFTP-UI button\r\n sshSession: SSHSessionLike | null = null\r\n profile: any = null\r\n\r\n connecting = false\r\n connected = false\r\n\r\n // legacy UI fields kept for now (not used when opened from SSH tab)\r\n host = ''\r\n port = 22\r\n username = ''\r\n password = ''\r\n\r\n localPath = os.homedir()\r\n localEntries: LocalEntry[] = []\r\n\r\n remotePath = '/'\r\n remoteEntries: SFTPFile[] = []\r\n\r\n private sftpSession: SFTPSessionLike | null = null\r\n\r\n localDropActive = false\r\n remoteDropActive = false\r\n\r\n transfers: Array<{\r\n transfer: FileTransfer\r\n direction: 'upload' | 'download'\r\n name: string\r\n remotePath: string\r\n localPath: string\r\n }> = []\r\n\r\n private transfersTimer: number | null = null\r\n localFilter = ''\r\n remoteFilter = ''\r\n remotePathInput = this.remotePath\r\n localPathInput = this.localPath\r\n private localFolderSizeLoading: Set<string> = new Set()\r\n private remoteFolderSizeLoading: Set<string> = new Set()\r\n private localSortBy: 'name' | 'size' | 'modified' = 'name'\r\n private localSortAsc = true\r\n private remoteSortBy: 'name' | 'size' | 'modified' = 'name'\r\n private remoteSortAsc = true\r\n private localCache: {\r\n entriesRef: LocalEntry[]\r\n filter: string\r\n showHidden: boolean\r\n sortBy: 'name' | 'size' | 'modified'\r\n asc: boolean\r\n result: LocalEntry[]\r\n } | null = null\r\n private remoteCache: {\r\n entriesRef: SFTPFile[]\r\n filter: string\r\n showHidden: boolean\r\n sortBy: 'name' | 'size' | 'modified'\r\n asc: boolean\r\n result: SFTPFile[]\r\n } | null = null\r\n showHiddenLocal = false\r\n showHiddenRemote = false\r\n selectedLocal: LocalEntry[] = []\r\n selectedRemote: SFTPFile[] = []\r\n localActionName = ''\r\n localActionPerms = ''\r\n remoteActionName = ''\r\n remoteActionPerms = ''\r\n private localLastSelectedIndex: number | null = null\r\n private remoteLastSelectedIndex: number | null = null\r\n\r\n deleteConfirmVisible = false\r\n deleteConfirmMode: 'local' | 'remote' | null = null\r\n deleteConfirmText = ''\r\n private pendingLocalDelete: LocalEntry[] = []\r\n private pendingRemoteDelete: SFTPFile[] = []\r\n private platform!: PlatformService\r\n private openedRemoteFiles: Map<string, { remotePath: string, mode: number, watcher: fsSync.FSWatcher | null }> = new Map()\r\n localPathPresets: Array<{ id: string, label: string, path: string }> = []\r\n localFavorites: Array<{ id: string, label: string, path: string }> = []\r\n recentProfiles: any[] = []\r\n localMenuVisible = false\r\n localMenuX = 0\r\n localMenuY = 0\r\n localMenuItems: Array<{ label: string, path: string }> = []\r\n\r\n constructor (\r\n injector: Injector,\r\n private sftp: SftpConnectionService,\r\n private profilesService: ProfilesService,\r\n private app: AppService,\r\n ) {\r\n // Tabby runtime BaseTabComponent expects Injector in constructor, but typings in this SDK may differ.\r\n // @ts-expect-error runtime-compatible super(injector)\r\n super(injector)\r\n this.platform = injector.get(PlatformService as any)\r\n\r\n // build local path presets (similar to Termius quick locations)\r\n const home = os.homedir()\r\n this.localPathPresets.push({ id: 'home', label: 'Home', path: home })\r\n const desktop = path.join(home, 'Desktop')\r\n const documents = path.join(home, 'Documents')\r\n const downloads = path.join(home, 'Downloads')\r\n if (fsSync.existsSync(desktop)) {\r\n this.localPathPresets.push({ id: 'desktop', label: 'Desktop', path: desktop })\r\n }\r\n if (fsSync.existsSync(documents)) {\r\n this.localPathPresets.push({ id: 'documents', label: 'Documents', path: documents })\r\n }\r\n if (fsSync.existsSync(downloads)) {\r\n this.localPathPresets.push({ id: 'downloads', label: 'Downloads', path: downloads })\r\n }\r\n\r\n this.loadLocalFavorites()\r\n void this.refreshLocal()\r\n\r\n this.transfersTimer = window.setInterval(() => {\r\n this.transfers = this.transfers.filter(t => !t.transfer.isComplete() && !t.transfer.isCancelled())\r\n }, 1000)\r\n }\r\n\r\n ngOnInit (): void {\r\n // If there's no live SSH session, this tab was likely restored across\r\n // restart or opened in an invalid context. Close it immediately to avoid\r\n // an empty, nameless SFTP tab lingering after restart.\r\n if (!this.sshSession) {\r\n try {\r\n this.app.closeTab(this)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Failed to close invalid SFTP tab', e)\r\n }\r\n return\r\n }\r\n\r\n this.remotePathInput = this.remotePath\r\n this.localPathInput = this.localPath\r\n if (this.sshSession) {\r\n void this.connect()\r\n }\r\n this.loadRecentProfiles()\r\n }\r\n\r\n async connect (): Promise<void> {\r\n if (this.connecting || this.connected) {\r\n return\r\n }\r\n if (!this.sshSession) {\r\n console.error('[SFTP-UI] No SSH session on current tab')\r\n return\r\n }\r\n this.connecting = true\r\n try {\r\n this.sftpSession = await this.sftp.openFromSSHSession(this.sshSession)\r\n this.connected = true\r\n this.remotePath = this.getDefaultRemotePath()\r\n this.remotePathInput = this.remotePath\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] SFTP connection failed', e)\r\n } finally {\r\n this.connecting = false\r\n }\r\n }\r\n\r\n async disconnect (): Promise<void> {\r\n this.sftpSession = null\r\n this.connected = false\r\n this.remoteEntries = []\r\n }\r\n\r\n canLocalUp (): boolean {\r\n const parent = path.dirname(this.localPath)\r\n return parent !== this.localPath\r\n }\r\n\r\n localUp (): void {\r\n const parent = path.dirname(this.localPath)\r\n if (parent !== this.localPath) {\r\n this.localPath = parent\r\n this.localPathInput = this.localPath\r\n void this.refreshLocal()\r\n }\r\n }\r\n\r\n remoteUp (): void {\r\n if (!this.connected || this.remotePath === '/') {\r\n return\r\n }\r\n const next = path.posix.dirname(this.remotePath)\r\n this.remotePath = next === '.' ? '/' : next\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n }\r\n\r\n async refreshLocal (): Promise<void> {\r\n try {\r\n const names = await fs.readdir(this.localPath)\r\n const entries: LocalEntry[] = []\r\n for (const name of names) {\r\n const fullPath = path.join(this.localPath, name)\r\n try {\r\n const st = await fs.stat(fullPath)\r\n entries.push({\r\n name,\r\n fullPath,\r\n isDirectory: st.isDirectory(),\r\n size: st.size,\r\n mtimeMs: st.mtimeMs,\r\n })\r\n } catch {\r\n // ignore entries that disappeared\r\n }\r\n }\r\n this.localEntries = entries\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local listing failed', e)\r\n }\r\n }\r\n\r\n async refreshRemote (): Promise<void> {\r\n if (!this.connected) {\r\n return\r\n }\r\n try {\r\n if (!this.sftpSession) {\r\n throw new Error('Not connected')\r\n }\r\n this.remoteEntries = await this.sftpSession.readdir(this.remotePath)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote listing failed', e)\r\n }\r\n }\r\n\r\n openLocal (e: LocalEntry): void {\r\n if (!e.isDirectory) {\r\n return\r\n }\r\n this.localPath = e.fullPath\r\n this.localPathInput = this.localPath\r\n void this.refreshLocal()\r\n }\r\n\r\n openRemote (e: SFTPFile): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n if (e.isDirectory) {\r\n this.remotePath = e.fullPath\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n } else {\r\n void this.openRemoteFile(e)\r\n }\r\n }\r\n\r\n onDragOver (ev: DragEvent): void {\r\n ev.preventDefault()\r\n }\r\n\r\n onLocalMouseDown (entry: LocalEntry, event: MouseEvent): void {\r\n if (event.button === 2) {\r\n this.onLocalContextMenu(entry, event)\r\n }\r\n }\r\n\r\n onRemoteMouseDown (entry: SFTPFile, event: MouseEvent): void {\r\n if (event.button === 2) {\r\n this.onRemoteContextMenu(entry, event)\r\n }\r\n }\r\n\r\n selectLocal (entry: LocalEntry, event: MouseEvent): void {\r\n const list = this.getFilteredLocalEntries()\r\n const index = list.indexOf(entry)\r\n if (index === -1) {\r\n return\r\n }\r\n const isCtrl = event.ctrlKey || event.metaKey\r\n const isShift = event.shiftKey\r\n if (isShift && this.localLastSelectedIndex != null) {\r\n const [from, to] = this.localLastSelectedIndex < index\r\n ? [this.localLastSelectedIndex, index]\r\n : [index, this.localLastSelectedIndex]\r\n const range = list.slice(from, to + 1)\r\n const set = new Set(this.selectedLocal)\r\n for (const e of range) {\r\n set.add(e)\r\n }\r\n this.selectedLocal = Array.from(set)\r\n } else if (isCtrl) {\r\n const exists = this.selectedLocal.includes(entry)\r\n if (exists) {\r\n this.selectedLocal = this.selectedLocal.filter(e => e !== entry)\r\n } else {\r\n this.selectedLocal = [...this.selectedLocal, entry]\r\n }\r\n this.localLastSelectedIndex = index\r\n } else {\r\n this.selectedLocal = [entry]\r\n this.localLastSelectedIndex = index\r\n }\r\n if (this.selectedLocal.length === 1) {\r\n this.localActionName = this.selectedLocal[0].name\r\n }\r\n }\r\n\r\n isLocalSelected (entry: LocalEntry): boolean {\r\n return this.selectedLocal.includes(entry)\r\n }\r\n\r\n selectRemote (entry: SFTPFile, event: MouseEvent): void {\r\n const list = this.getFilteredRemoteEntries()\r\n const index = list.indexOf(entry)\r\n if (index === -1) {\r\n return\r\n }\r\n const isCtrl = event.ctrlKey || event.metaKey\r\n const isShift = event.shiftKey\r\n if (isShift && this.remoteLastSelectedIndex != null) {\r\n const [from, to] = this.remoteLastSelectedIndex < index\r\n ? [this.remoteLastSelectedIndex, index]\r\n : [index, this.remoteLastSelectedIndex]\r\n const range = list.slice(from, to + 1)\r\n const set = new Set(this.selectedRemote)\r\n for (const e of range) {\r\n set.add(e)\r\n }\r\n this.selectedRemote = Array.from(set)\r\n } else if (isCtrl) {\r\n const exists = this.selectedRemote.includes(entry)\r\n if (exists) {\r\n this.selectedRemote = this.selectedRemote.filter(e => e !== entry)\r\n } else {\r\n this.selectedRemote = [...this.selectedRemote, entry]\r\n }\r\n this.remoteLastSelectedIndex = index\r\n } else {\r\n this.selectedRemote = [entry]\r\n this.remoteLastSelectedIndex = index\r\n }\r\n if (this.selectedRemote.length === 1) {\r\n this.remoteActionName = this.selectedRemote[0].name\r\n const currentPerms = (this.selectedRemote[0].mode & 0o777).toString(8)\r\n this.remoteActionPerms = currentPerms\r\n }\r\n }\r\n\r\n isRemoteSelected (entry: SFTPFile): boolean {\r\n return this.selectedRemote.includes(entry)\r\n }\r\n\r\n setLocalSort (field: 'name' | 'size' | 'modified'): void {\r\n if (this.localSortBy === field) {\r\n this.localSortAsc = !this.localSortAsc\r\n } else {\r\n this.localSortBy = field\r\n this.localSortAsc = true\r\n }\r\n }\r\n\r\n setRemoteSort (field: 'name' | 'size' | 'modified'): void {\r\n if (this.remoteSortBy === field) {\r\n this.remoteSortAsc = !this.remoteSortAsc\r\n } else {\r\n this.remoteSortBy = field\r\n this.remoteSortAsc = true\r\n }\r\n }\r\n\r\n onDragStartLocal (ev: DragEvent, e: LocalEntry): void {\r\n const sources = this.selectedLocal.includes(e) && this.selectedLocal.length ? this.selectedLocal : [e]\r\n const movePayload = sources.map(x => x.fullPath)\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-local-move', JSON.stringify(movePayload))\r\n\r\n // Existing cross-device drag (local -> remote) only for files\r\n if (!e.isDirectory) {\r\n const payload: DragPayload = { kind: 'local-file', fullPath: e.fullPath, name: e.name }\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\r\n ev.dataTransfer?.setData('text/plain', e.fullPath)\r\n }\r\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\r\n }\r\n\r\n onDragStartRemote (ev: DragEvent, item: SFTPFile): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n const sources = this.selectedRemote.includes(item) && this.selectedRemote.length ? this.selectedRemote : [item]\r\n const movePayload = sources.map(x => x.fullPath)\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-remote-move', JSON.stringify(movePayload))\r\n\r\n // Existing cross-device drag (remote -> local) only for files\r\n if (!item.isDirectory) {\r\n const payload: DragPayload = {\r\n kind: 'remote-file',\r\n remotePath: item.fullPath,\r\n name: item.name,\r\n size: item.size,\r\n mode: item.mode,\r\n }\r\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\r\n ev.dataTransfer?.setData('text/plain', item.fullPath)\r\n }\r\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\r\n }\r\n\r\n async onDropOnRemote (ev: DragEvent): Promise<void> {\r\n ev.preventDefault()\r\n this.remoteDropActive = false\r\n if (!this.connected) {\r\n return\r\n }\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\r\n if (!raw) {\r\n return\r\n }\r\n let payload: DragPayload\r\n try {\r\n payload = JSON.parse(raw) as DragPayload\r\n } catch {\r\n return\r\n }\r\n if (payload.kind !== 'local-file') {\r\n return\r\n }\r\n try {\r\n const targetRemotePath = path.posix.join(this.remotePath, payload.name)\r\n const upload = new LocalPathFileUpload(payload.fullPath)\r\n this.trackTransfer(upload, 'upload', targetRemotePath, payload.fullPath)\r\n await this.sftpSession.upload(targetRemotePath, upload)\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Upload failed', e)\r\n }\r\n }\r\n\r\n async onDropOnLocal (ev: DragEvent): Promise<void> {\r\n ev.preventDefault()\r\n this.localDropActive = false\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\r\n if (!raw) {\r\n return\r\n }\r\n let payload: DragPayload\r\n try {\r\n payload = JSON.parse(raw) as DragPayload\r\n } catch {\r\n return\r\n }\r\n if (payload.kind !== 'remote-file') {\r\n return\r\n }\r\n try {\r\n const targetLocalPath = path.join(this.localPath, payload.name)\r\n if (!this.sftpSession) {\r\n throw new Error('Not connected')\r\n }\r\n const dl = new LocalPathFileDownload(targetLocalPath, payload.mode, payload.size)\r\n this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath)\r\n await this.sftpSession.download(payload.remotePath, dl)\r\n await this.refreshLocal()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Download failed', e)\r\n }\r\n }\r\n\r\n getFilteredLocalEntries (): LocalEntry[] {\r\n const entriesRef = this.localEntries\r\n const filter = this.localFilter\r\n const showHidden = this.showHiddenLocal\r\n const sortBy = this.localSortBy\r\n const asc = this.localSortAsc\r\n\r\n if (this.localCache &&\r\n this.localCache.entriesRef === entriesRef &&\r\n this.localCache.filter === filter &&\r\n this.localCache.showHidden === showHidden &&\r\n this.localCache.sortBy === sortBy &&\r\n this.localCache.asc === asc) {\r\n return this.localCache.result\r\n }\r\n\r\n const term = filter.trim().toLowerCase()\r\n let entries = entriesRef\r\n if (!showHidden) {\r\n entries = entries.filter(e => !e.name.startsWith('.'))\r\n }\r\n if (term) {\r\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\r\n }\r\n const result = this.sortLocalEntries(entries.slice())\r\n this.localCache = { entriesRef, filter, showHidden, sortBy, asc, result }\r\n return result\r\n }\r\n\r\n getFilteredRemoteEntries (): SFTPFile[] {\r\n const entriesRef = this.remoteEntries\r\n const filter = this.remoteFilter\r\n const showHidden = this.showHiddenRemote\r\n const sortBy = this.remoteSortBy\r\n const asc = this.remoteSortAsc\r\n\r\n if (this.remoteCache &&\r\n this.remoteCache.entriesRef === entriesRef &&\r\n this.remoteCache.filter === filter &&\r\n this.remoteCache.showHidden === showHidden &&\r\n this.remoteCache.sortBy === sortBy &&\r\n this.remoteCache.asc === asc) {\r\n return this.remoteCache.result\r\n }\r\n\r\n const term = filter.trim().toLowerCase()\r\n let entries = entriesRef\r\n if (!showHidden) {\r\n entries = entries.filter(e => !e.name.startsWith('.'))\r\n }\r\n if (term) {\r\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\r\n }\r\n const result = this.sortRemoteEntries(entries.slice())\r\n this.remoteCache = { entriesRef, filter, showHidden, sortBy, asc, result }\r\n return result\r\n }\r\n\r\n private sortLocalEntries (entries: LocalEntry[]): LocalEntry[] {\r\n const dirFirst = (a: LocalEntry, b: LocalEntry) => Number(b.isDirectory) - Number(a.isDirectory)\r\n const factor = this.localSortAsc ? 1 : -1\r\n const field = this.localSortBy\r\n return entries.sort((a, b) => {\r\n const d = dirFirst(a, b)\r\n if (d !== 0) return d\r\n if (field === 'name') {\r\n return a.name.localeCompare(b.name) * factor\r\n }\r\n if (field === 'size') {\r\n const av = a.size ?? 0\r\n const bv = b.size ?? 0\r\n return (av - bv) * factor\r\n }\r\n const av = a.mtimeMs ?? 0\r\n const bv = b.mtimeMs ?? 0\r\n return (av - bv) * factor\r\n })\r\n }\r\n\r\n private sortRemoteEntries (entries: SFTPFile[]): SFTPFile[] {\r\n const dirFirst = (a: SFTPFile, b: SFTPFile) => Number(b.isDirectory) - Number(a.isDirectory)\r\n const factor = this.remoteSortAsc ? 1 : -1\r\n const field = this.remoteSortBy\r\n return entries.sort((a, b) => {\r\n const d = dirFirst(a, b)\r\n if (d !== 0) return d\r\n if (field === 'name') {\r\n return a.name.localeCompare(b.name) * factor\r\n }\r\n if (field === 'size') {\r\n const av = a.size ?? 0\r\n const bv = b.size ?? 0\r\n return (av - bv) * factor\r\n }\r\n const av = a.modified?.getTime?.() ?? 0\r\n const bv = b.modified?.getTime?.() ?? 0\r\n return (av - bv) * factor\r\n })\r\n }\r\n\r\n private getLocalMovePayload (ev: DragEvent): string[] | null {\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-local-move')\r\n if (!raw) {\r\n return null\r\n }\r\n try {\r\n const arr = JSON.parse(raw) as string[]\r\n if (Array.isArray(arr)) {\r\n return arr\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n return null\r\n }\r\n\r\n private getRemoteMovePayload (ev: DragEvent): string[] | null {\r\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-remote-move')\r\n if (!raw) {\r\n return null\r\n }\r\n try {\r\n const arr = JSON.parse(raw) as string[]\r\n if (Array.isArray(arr)) {\r\n return arr\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n return null\r\n }\r\n\r\n formatSize (bytes?: number): string {\r\n if (bytes === undefined || bytes === null) {\r\n return ''\r\n }\r\n if (bytes === 0) {\r\n return '0 B'\r\n }\r\n const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']\r\n let value = bytes\r\n let unitIndex = 0\r\n while (value >= 1024 && unitIndex < units.length - 1) {\r\n value /= 1024\r\n unitIndex++\r\n }\r\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\r\n return `${value.toFixed(digits)} ${units[unitIndex]}`\r\n }\r\n\r\n formatSpeed (bytesPerSecond?: number): string {\r\n if (bytesPerSecond === undefined || bytesPerSecond === null) {\r\n return ''\r\n }\r\n if (bytesPerSecond === 0) {\r\n return '0 B/s'\r\n }\r\n const units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s']\r\n let value = bytesPerSecond\r\n let unitIndex = 0\r\n while (value >= 1024 && unitIndex < units.length - 1) {\r\n value /= 1024\r\n unitIndex++\r\n }\r\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\r\n return `${value.toFixed(digits)} ${units[unitIndex]}`\r\n }\r\n\r\n getLocalSizeDisplay (e: LocalEntry): string {\r\n if (!e.isDirectory) {\r\n return this.formatSize(e.size)\r\n }\r\n if (e.size !== undefined) {\r\n return this.formatSize(e.size)\r\n }\r\n if (this.localFolderSizeLoading.has(e.fullPath)) {\r\n return '…'\r\n }\r\n return ''\r\n }\r\n\r\n getRemoteSizeDisplay (e: SFTPFile): string {\r\n if (!e.isDirectory) {\r\n return this.formatSize(e.size)\r\n }\r\n const key = e.fullPath\r\n if ((e as any).dirSize !== undefined) {\r\n return this.formatSize((e as any).dirSize)\r\n }\r\n if (this.remoteFolderSizeLoading.has(key)) {\r\n return '…'\r\n }\r\n return ''\r\n }\r\n\r\n onLocalEntryDragOver (entry: LocalEntry, ev: DragEvent): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (!this.getLocalMovePayload(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n }\r\n\r\n async onLocalEntryDrop (entry: LocalEntry, ev: DragEvent): Promise<void> {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n const sources = this.getLocalMovePayload(ev)\r\n if (!sources || !sources.length) {\r\n return\r\n }\r\n ev.preventDefault()\r\n const targetDir = entry.fullPath\r\n try {\r\n for (const src of sources) {\r\n if (!src || src === targetDir) {\r\n continue\r\n }\r\n // avoid moving a directory into its own subtree\r\n if (targetDir.startsWith(src + path.sep)) {\r\n continue\r\n }\r\n const name = path.basename(src)\r\n const dst = path.join(targetDir, name)\r\n if (dst === src) {\r\n continue\r\n }\r\n try {\r\n await fs.rename(src, dst)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local move failed', e)\r\n }\r\n }\r\n await this.refreshLocal()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local move batch failed', e)\r\n }\r\n }\r\n\r\n onRemoteEntryDragOver (entry: SFTPFile, ev: DragEvent): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (!this.getRemoteMovePayload(ev)) {\r\n return\r\n }\r\n ev.preventDefault()\r\n }\r\n\r\n async onRemoteEntryDrop (entry: SFTPFile, ev: DragEvent): Promise<void> {\r\n if (!entry.isDirectory || !this.sftpSession || !this.connected) {\r\n return\r\n }\r\n const sources = this.getRemoteMovePayload(ev)\r\n if (!sources || !sources.length) {\r\n return\r\n }\r\n ev.preventDefault()\r\n const targetDir = entry.fullPath\r\n try {\r\n for (const src of sources) {\r\n if (!src || src === targetDir) {\r\n continue\r\n }\r\n // avoid moving a directory into its own subtree\r\n if (targetDir.startsWith(src + '/')) {\r\n continue\r\n }\r\n const name = src.split('/').filter(Boolean).pop() || ''\r\n if (!name) {\r\n continue\r\n }\r\n const dst = path.posix.join(targetDir, name)\r\n if (dst === src) {\r\n continue\r\n }\r\n try {\r\n await this.sftpSession.rename(src, dst)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote move failed', e)\r\n }\r\n }\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote move batch failed', e)\r\n }\r\n }\r\n\r\n getRemoteBreadcrumbs (): Array<{ label: string, path: string }> {\r\n const parts = this.remotePath.split('/').filter(Boolean)\r\n const crumbs: Array<{ label: string, path: string }> = []\r\n let current = '/'\r\n crumbs.push({ label: '/', path: '/' })\r\n for (const p of parts) {\r\n current = current === '/' ? `/${p}` : `${current}/${p}`\r\n crumbs.push({ label: p, path: current })\r\n }\r\n return crumbs\r\n }\r\n\r\n navigateRemoteBreadcrumb (index: number): void {\r\n const crumbs = this.getRemoteBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n this.remotePath = crumb.path\r\n this.remotePathInput = this.remotePath\r\n void this.refreshRemote()\r\n }\r\n\r\n goToRemotePathInput (): void {\r\n if (!this.connected) {\r\n return\r\n }\r\n const target = this.normalizeRemotePath(this.remotePathInput || '/')\r\n this.remotePath = target\r\n this.remotePathInput = target\r\n void this.refreshRemote()\r\n }\r\n\r\n goToLocalPathInput (): void {\r\n const target = this.normalizeLocalPath(this.localPathInput || this.localPath)\r\n this.goToLocalPath(target)\r\n }\r\n\r\n getLocalBreadcrumbs (): Array<{ label: string, path: string }> {\r\n const currentPath = this.localPath\r\n const parsed = path.parse(currentPath)\r\n const root = parsed.root || path.sep\r\n const withoutRoot = currentPath.slice(root.length)\r\n const parts = withoutRoot.split(path.sep).filter(Boolean)\r\n const crumbs: Array<{ label: string, path: string }> = []\r\n\r\n const rootLabel = root.replace(/[\\\\\\/]+$/, '') || root\r\n crumbs.push({ label: rootLabel, path: root })\r\n\r\n let accum = root\r\n for (const p of parts) {\r\n accum = path.join(accum, p)\r\n crumbs.push({ label: p, path: accum })\r\n }\r\n return crumbs\r\n }\r\n\r\n navigateLocalBreadcrumb (index: number): void {\r\n const crumbs = this.getLocalBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n this.goToLocalPath(crumb.path)\r\n }\r\n\r\n private goToLocalPath (target: string): void {\r\n this.localPath = target\r\n this.localPathInput = target\r\n void this.refreshLocal()\r\n }\r\n\r\n onLocalPresetChange (id: string): void {\r\n if (!id) {\r\n return\r\n }\r\n const preset = this.localPathPresets.find(p => p.id === id)\r\n if (!preset) {\r\n return\r\n }\r\n this.goToLocalPath(preset.path)\r\n }\r\n\r\n isCurrentFavorite (): boolean {\r\n return this.localFavorites.some(f => f.path === this.localPath)\r\n }\r\n\r\n toggleCurrentFavorite (): void {\r\n const existingIndex = this.localFavorites.findIndex(f => f.path === this.localPath)\r\n if (existingIndex >= 0) {\r\n this.localFavorites.splice(existingIndex, 1)\r\n this.saveLocalFavorites()\r\n return\r\n }\r\n const label = path.basename(this.localPath) || this.localPath\r\n const id = `fav-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\r\n this.localFavorites.push({ id, label, path: this.localPath })\r\n this.saveLocalFavorites()\r\n }\r\n\r\n onLocalFavoriteSelect (id: string): void {\r\n if (!id) {\r\n return\r\n }\r\n const fav = this.localFavorites.find(f => f.id === id)\r\n if (!fav) {\r\n return\r\n }\r\n this.goToLocalPath(fav.path)\r\n }\r\n\r\n onLocalBreadcrumbContextMenu (index: number, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n const crumbs = this.getLocalBreadcrumbs()\r\n const crumb = crumbs[index]\r\n if (!crumb) {\r\n return\r\n }\r\n\r\n const menuItems: Array<{ label: string, path: string }> = []\r\n const isWindows = process.platform === 'win32'\r\n const isRootCrumb = index === 0\r\n\r\n const basePath = crumb.path\r\n\r\n // Root crumb on Windows: offer other drives as \"siblings\"\r\n if (isWindows && isRootCrumb) {\r\n const drives: string[] = []\r\n for (let code = 67; code <= 90; code++) { // C..Z\r\n const letter = String.fromCharCode(code)\r\n const rootPath = `${letter}:\\\\`\r\n try {\r\n if (fsSync.existsSync(rootPath)) {\r\n drives.push(rootPath)\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n for (const d of drives) {\r\n menuItems.push({ label: d, path: d })\r\n }\r\n } else {\r\n // For non-root crumbs (or non-Windows), show sibling folders only\r\n const parentPath = path.dirname(basePath)\r\n try {\r\n const parentEntries = fsSync.readdirSync(parentPath)\r\n for (const name of parentEntries) {\r\n const full = path.join(parentPath, name)\r\n try {\r\n const st = fsSync.statSync(full)\r\n if (st.isDirectory()) {\r\n menuItems.push({ label: name, path: full })\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n if (!menuItems.length) {\r\n return\r\n }\r\n\r\n this.localMenuItems = menuItems\r\n this.localMenuVisible = true\r\n this.localMenuX = event.clientX\r\n this.localMenuY = event.clientY\r\n }\r\n\r\n private loadLocalFavorites (): void {\r\n try {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return\r\n }\r\n const raw = window.localStorage.getItem('tabby-sftp-ui-local-favorites')\r\n if (!raw) {\r\n return\r\n }\r\n const parsed = JSON.parse(raw)\r\n if (Array.isArray(parsed)) {\r\n this.localFavorites = parsed\r\n .filter(f => f && typeof f.path === 'string')\r\n .map(f => ({\r\n id: String(f.id || `fav-${Math.random().toString(36).slice(2, 8)}`),\r\n label: String(f.label || path.basename(f.path) || f.path),\r\n path: String(f.path),\r\n }))\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n private saveLocalFavorites (): void {\r\n try {\r\n if (typeof window === 'undefined' || !window.localStorage) {\r\n return\r\n }\r\n window.localStorage.setItem('tabby-sftp-ui-local-favorites', JSON.stringify(this.localFavorites))\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n onLocalMenuItemClick (item: { label: string, path: string }): void {\r\n this.localMenuVisible = false\r\n this.goToLocalPath(item.path)\r\n }\r\n\r\n private normalizeLocalPath (p: string): string {\r\n if (!p) {\r\n return this.localPath\r\n }\r\n let result = p.trim()\r\n // On Windows allow drive letters and backslashes, but normalize to current OS-style\r\n if (path.win32.isAbsolute(result) || path.posix.isAbsolute(result)) {\r\n return result\r\n }\r\n // relative path from current localPath\r\n return path.join(this.localPath, result)\r\n }\r\n\r\n private normalizeRemotePath (p: string): string {\r\n if (!p) {\r\n return '/'\r\n }\r\n let result = p.trim()\r\n if (!result.startsWith('/')) {\r\n result = '/' + result\r\n }\r\n // remove duplicate slashes\r\n result = result.replace(/\\/+/g, '/')\r\n return result\r\n }\r\n\r\n private getDefaultRemotePath (): string {\r\n const username = (this.profile && (this.profile.options?.username || this.profile.options?.user)) || ''\r\n if (username) {\r\n return `/home/${username}`\r\n }\r\n return '/'\r\n }\r\n\r\n private loadRecentProfiles (): void {\r\n try {\r\n const rec = this.profilesService.getRecentProfiles?.()\r\n if (Array.isArray(rec)) {\r\n this.recentProfiles = rec\r\n }\r\n } catch {\r\n this.recentProfiles = []\r\n }\r\n }\r\n\r\n getProfileLabel (p: any): string {\r\n if (!p) {\r\n return ''\r\n }\r\n return p.name || p.options?.host || p.id || 'Profile'\r\n }\r\n\r\n launchProfileFromSFTP (p: any): void {\r\n try {\r\n void this.profilesService.launchProfile(p)\r\n } catch (e) {\r\n console.error('[SFTP-UI] launchProfile failed', e)\r\n }\r\n }\r\n\r\n @HostListener('document:click')\r\n onDocumentClick (): void {\r\n this.localMenuVisible = false\r\n }\r\n\r\n localRename (): void {\r\n if (this.selectedLocal.length !== 1 || !this.localActionName?.trim()) {\r\n return\r\n }\r\n const entry = this.selectedLocal[0]\r\n const name = this.localActionName.trim()\r\n if (name === entry.name) {\r\n return\r\n }\r\n const target = path.join(this.localPath, name)\r\n void fs.rename(entry.fullPath, target)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local rename failed', e))\r\n }\r\n\r\n localDelete (): void {\r\n if (!this.selectedLocal.length) {\r\n return\r\n }\r\n this.deleteConfirmMode = 'local'\r\n this.pendingLocalDelete = this.selectedLocal.slice()\r\n const names = this.pendingLocalDelete.map(e => e.name)\r\n this.deleteConfirmText = this.buildDeleteConfirmText('local', names)\r\n this.deleteConfirmVisible = true\r\n }\r\n\r\n localNewFolder (): void {\r\n const name = (this.localActionName || 'New folder').trim()\r\n if (!name) {\r\n return\r\n }\r\n const target = path.join(this.localPath, name)\r\n void fs.mkdir(target, { recursive: true })\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local mkdir failed', e))\r\n }\r\n\r\n localEditPermissions (): void {\r\n if (this.selectedLocal.length !== 1 || !this.localActionPerms?.trim()) {\r\n return\r\n }\r\n const entry = this.selectedLocal[0]\r\n const mode = parseInt(this.localActionPerms.trim(), 8)\r\n if (Number.isNaN(mode)) {\r\n console.error('[SFTP-UI] Invalid local permissions value')\r\n return\r\n }\r\n void fs.chmod(entry.fullPath, mode as any)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Local chmod failed', e))\r\n }\r\n\r\n localShowSize (): void {\r\n if (this.selectedLocal.length === 1 && this.selectedLocal[0].isDirectory) {\r\n this.ensureLocalFolderSize(this.selectedLocal[0])\r\n }\r\n }\r\n\r\n remoteRename (): void {\r\n if (this.selectedRemote.length !== 1 || !this.remoteActionName?.trim() || !this.sftpSession) {\r\n return\r\n }\r\n const entry = this.selectedRemote[0]\r\n const name = this.remoteActionName.trim()\r\n if (name === entry.name) {\r\n return\r\n }\r\n const target = path.posix.join(this.remotePath, name)\r\n void this.sftpSession.rename(entry.fullPath, target)\r\n .then(() => this.refreshRemote())\r\n .catch(e => console.error('[SFTP-UI] Remote rename failed', e))\r\n }\r\n\r\n remoteDelete (): void {\r\n if (!this.selectedRemote.length || !this.sftpSession) {\r\n return\r\n }\r\n this.deleteConfirmMode = 'remote'\r\n this.pendingRemoteDelete = this.selectedRemote.slice()\r\n const names = this.pendingRemoteDelete.map(e => e.name)\r\n this.deleteConfirmText = this.buildDeleteConfirmText('remote', names)\r\n this.deleteConfirmVisible = true\r\n }\r\n\r\n remoteNewFolder (): void {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n const name = (this.remoteActionName || 'New folder').trim()\r\n if (!name) {\r\n return\r\n }\r\n const target = path.posix.join(this.remotePath, name)\r\n void this.sftpSession.mkdir(target)\r\n .then(() => this.refreshRemote())\r\n .catch(e => console.error('[SFTP-UI] Remote mkdir failed', e))\r\n }\r\n\r\n remoteEditPermissions (): void {\r\n if (this.selectedRemote.length !== 1 || !this.remoteActionPerms?.trim() || !this.sftpSession) {\r\n return\r\n }\r\n const entry = this.selectedRemote[0]\r\n const mode = parseInt(this.remoteActionPerms.trim(), 8)\r\n if (Number.isNaN(mode)) {\r\n console.error('[SFTP-UI] Invalid remote permissions value')\r\n return\r\n }\r\n void (this.sftpSession as any).chmod(entry.fullPath, mode)\r\n .then(() => this.refreshRemote())\r\n .catch((e: any) => console.error('[SFTP-UI] Remote chmod failed', e))\r\n }\r\n\r\n remoteShowSize (): void {\r\n if (this.selectedRemote.length === 1 && this.selectedRemote[0].isDirectory) {\r\n this.ensureRemoteFolderSize(this.selectedRemote[0])\r\n }\r\n }\r\n\r\n remoteDownload (): void {\r\n if (!this.selectedRemote.length || !this.sftpSession) {\r\n return\r\n }\r\n for (const entry of this.selectedRemote) {\r\n if (entry.isDirectory) {\r\n continue\r\n }\r\n const targetLocalPath = path.join(this.localPath, entry.name)\r\n const dl = new LocalPathFileDownload(targetLocalPath, entry.mode, entry.size)\r\n this.trackTransfer(dl, 'download', entry.fullPath, targetLocalPath)\r\n void this.sftpSession.download(entry.fullPath, dl)\r\n .then(() => this.refreshLocal())\r\n .catch(e => console.error('[SFTP-UI] Remote download failed', e))\r\n }\r\n }\r\n\r\n ensureLocalFolderSize (entry: LocalEntry): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n if (entry.size !== undefined) {\r\n return\r\n }\r\n if (this.localFolderSizeLoading.has(entry.fullPath)) {\r\n return\r\n }\r\n this.localFolderSizeLoading.add(entry.fullPath)\r\n void this.computeLocalFolderSize(entry.fullPath)\r\n .then(size => {\r\n entry.size = size\r\n })\r\n .catch(e => {\r\n console.error('[SFTP-UI] Local folder size failed', e)\r\n })\r\n .finally(() => {\r\n this.localFolderSizeLoading.delete(entry.fullPath)\r\n })\r\n }\r\n\r\n ensureRemoteFolderSize (entry: SFTPFile): void {\r\n if (!entry.isDirectory) {\r\n return\r\n }\r\n const key = entry.fullPath\r\n if ((entry as any).dirSize !== undefined) {\r\n return\r\n }\r\n if (this.remoteFolderSizeLoading.has(key)) {\r\n return\r\n }\r\n if (!this.sftpSession || !this.connected) {\r\n return\r\n }\r\n this.remoteFolderSizeLoading.add(key)\r\n void this.computeRemoteFolderSize(key)\r\n .then(size => {\r\n ;(entry as any).dirSize = size\r\n })\r\n .catch(e => {\r\n console.error('[SFTP-UI] Remote folder size failed', e)\r\n })\r\n .finally(() => {\r\n this.remoteFolderSizeLoading.delete(key)\r\n })\r\n }\r\n\r\n private async computeLocalFolderSize (root: string): Promise<number> {\r\n let total = 0\r\n const stack: string[] = [root]\r\n const maxEntries = 5000\r\n let visited = 0\r\n while (stack.length) {\r\n const dir = stack.pop() as string\r\n let names: string[]\r\n try {\r\n names = await fs.readdir(dir)\r\n } catch {\r\n continue\r\n }\r\n for (const name of names) {\r\n if (visited++ > maxEntries) {\r\n return total\r\n }\r\n const full = path.join(dir, name)\r\n try {\r\n const st = await fs.stat(full)\r\n if (st.isDirectory()) {\r\n stack.push(full)\r\n } else {\r\n total += st.size\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n }\r\n return total\r\n }\r\n\r\n private async computeRemoteFolderSize (root: string): Promise<number> {\r\n if (!this.sftpSession) {\r\n return 0\r\n }\r\n let total = 0\r\n const stack: string[] = [root]\r\n const maxEntries = 5000\r\n let visited = 0\r\n while (stack.length) {\r\n const dir = stack.pop() as string\r\n let entries: SFTPFile[]\r\n try {\r\n entries = await this.sftpSession.readdir(dir)\r\n } catch {\r\n continue\r\n }\r\n for (const item of entries) {\r\n if (visited++ > maxEntries) {\r\n return total\r\n }\r\n if (item.isDirectory) {\r\n stack.push(item.fullPath)\r\n } else {\r\n total += item.size\r\n }\r\n }\r\n }\r\n return total\r\n }\r\n\r\n onLocalContextMenu (entry: LocalEntry, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\r\n }\r\n\r\n onRemoteContextMenu (entry: SFTPFile, event: MouseEvent): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\r\n }\r\n\r\n private trackTransfer (transfer: FileTransfer, direction: 'upload' | 'download', remotePath: string, localPath: string): void {\r\n this.transfers.push({\r\n transfer,\r\n direction,\r\n name: transfer.getName(),\r\n remotePath,\r\n localPath,\r\n })\r\n }\r\n\r\n cancelTransfer (entry: { transfer: FileTransfer }): void {\r\n try {\r\n if (entry.transfer.isComplete() || entry.transfer.isCancelled()) {\r\n return\r\n }\r\n entry.transfer.cancel?.()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Cancel transfer failed', e)\r\n }\r\n }\r\n\r\n getTransferProgress (transfer: FileTransfer): number {\r\n try {\r\n const total = transfer.getSize?.()\r\n const done = transfer.getCompletedBytes?.()\r\n if (typeof total !== 'number' || total <= 0 || typeof done !== 'number' || done < 0) {\r\n return transfer.isComplete() ? 100 : 0\r\n }\r\n const value = (done / total) * 100\r\n const clamped = Math.max(0, Math.min(100, value))\r\n return clamped\r\n } catch {\r\n return transfer.isComplete() ? 100 : 0\r\n }\r\n }\r\n\r\n onKeyDown (event: KeyboardEvent): void {\r\n if (event.key === 'Delete' || event.key === 'Backspace') {\r\n event.preventDefault()\r\n if (this.selectedRemote.length) {\r\n this.remoteDelete()\r\n } else if (this.selectedLocal.length) {\r\n this.localDelete()\r\n }\r\n }\r\n }\r\n\r\n override destroy (): void {\r\n // stop file watchers for opened remote files\r\n for (const { watcher } of this.openedRemoteFiles.values()) {\r\n try {\r\n watcher?.close()\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n this.openedRemoteFiles.clear()\r\n\r\n void this.disconnect()\r\n if (this.transfersTimer !== null) {\r\n clearInterval(this.transfersTimer)\r\n this.transfersTimer = null\r\n }\r\n super.destroy()\r\n }\r\n\r\n // Prevent Tabby from restoring SFTP-UI tabs across restarts, since they rely\r\n // on a live SSH session from a terminal tab.\r\n // Typинги допускают RecoveryToken | null, нам достаточно всегда возвращать null.\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n override async getRecoveryToken (_options?: any): Promise<null> {\r\n return null\r\n }\r\n\r\n async confirmDelete (): Promise<void> {\r\n if (!this.deleteConfirmVisible) {\r\n return\r\n }\r\n const mode = this.deleteConfirmMode\r\n this.deleteConfirmVisible = false\r\n\r\n try {\r\n if (mode === 'local') {\r\n const toDelete = this.pendingLocalDelete.slice()\r\n this.pendingLocalDelete = []\r\n for (const entry of toDelete) {\r\n await this.deleteLocalEntry(entry)\r\n }\r\n await this.refreshLocal()\r\n this.selectedLocal = []\r\n } else if (mode === 'remote' && this.sftpSession) {\r\n const toDelete = this.pendingRemoteDelete.slice()\r\n this.pendingRemoteDelete = []\r\n for (const entry of toDelete) {\r\n await this.deleteRemoteEntry(entry)\r\n }\r\n await this.refreshRemote()\r\n this.selectedRemote = []\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Delete failed', e)\r\n } finally {\r\n this.deleteConfirmMode = null\r\n this.deleteConfirmText = ''\r\n }\r\n }\r\n\r\n cancelDelete (): void {\r\n this.deleteConfirmVisible = false\r\n this.deleteConfirmMode = null\r\n this.deleteConfirmText = ''\r\n this.pendingLocalDelete = []\r\n this.pendingRemoteDelete = []\r\n }\r\n\r\n private async deleteLocalEntry (entry: LocalEntry): Promise<void> {\r\n await this.deleteLocalPathRecursive(entry.fullPath)\r\n }\r\n\r\n private async deleteRemoteEntry (entry: SFTPFile): Promise<void> {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n await this.deleteRemotePathRecursive(entry.fullPath)\r\n }\r\n\r\n private buildDeleteConfirmText (scope: 'local' | 'remote', names: string[]): string {\r\n const total = names.length\r\n const label = scope === 'local' ? 'local' : 'remote'\r\n if (!total) {\r\n return `Delete 0 item(s) from ${label}?`\r\n }\r\n const maxShown = 5\r\n const shown = names.slice(0, maxShown)\r\n const list = shown.join(', ')\r\n if (total <= maxShown) {\r\n return `Delete ${total} item(s) from ${label}: ${list}?`\r\n }\r\n const rest = total - maxShown\r\n return `Delete ${total} item(s) from ${label}: ${list} and ${rest} more?`\r\n }\r\n\r\n private async deleteLocalPathRecursive (target: string): Promise<void> {\r\n try {\r\n const st = await fs.stat(target)\r\n if (!st.isDirectory()) {\r\n await fs.unlink(target)\r\n return\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local delete failed (stat)', e)\r\n return\r\n }\r\n\r\n try {\r\n const names = await fs.readdir(target)\r\n for (const name of names) {\r\n const child = path.join(target, name)\r\n await this.deleteLocalPathRecursive(child)\r\n }\r\n await fs.rmdir(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Local recursive delete failed', e)\r\n }\r\n }\r\n\r\n private async deleteRemotePathRecursive (target: string): Promise<void> {\r\n if (!this.sftpSession) {\r\n return\r\n }\r\n try {\r\n const entries = await this.sftpSession.readdir(target).catch(() => null as any)\r\n if (!entries) {\r\n // treat as file\r\n try {\r\n await this.sftpSession.unlink(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote delete failed', e)\r\n }\r\n return\r\n }\r\n for (const item of entries as SFTPFile[]) {\r\n const full = item.fullPath\r\n if (item.isDirectory) {\r\n await this.deleteRemotePathRecursive(full)\r\n } else {\r\n try {\r\n await this.sftpSession.unlink(full)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote unlink failed', e)\r\n }\r\n }\r\n }\r\n try {\r\n await this.sftpSession.rmdir(target)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote rmdir failed', e)\r\n }\r\n } catch (e) {\r\n console.error('[SFTP-UI] Remote recursive delete failed', e)\r\n }\r\n }\r\n\r\n private async openRemoteFile (entry: SFTPFile): Promise<void> {\r\n if (!this.sftpSession || !this.connected || entry.isDirectory) {\r\n return\r\n }\r\n try {\r\n const tmpRoot = path.join(os.tmpdir(), 'tabby-sftp-ui')\r\n await fs.mkdir(tmpRoot, { recursive: true })\r\n const localPath = path.join(tmpRoot, entry.name)\r\n\r\n // если уже есть watcher на этот файл – закроем его и перезапишем\r\n const existing = this.openedRemoteFiles.get(localPath)\r\n if (existing?.watcher) {\r\n try {\r\n existing.watcher.close()\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n const dl = new LocalPathFileDownload(localPath, entry.mode, entry.size)\r\n this.trackTransfer(dl, 'download', entry.fullPath, localPath)\r\n await this.sftpSession.download(entry.fullPath, dl)\r\n\r\n // настроим наблюдение за изменениями локального файла\r\n const watcher = fsSync.watch(localPath, { persistent: false }, (eventType) => {\r\n if (eventType === 'change') {\r\n void this.syncBackRemoteFile(localPath)\r\n }\r\n })\r\n this.openedRemoteFiles.set(localPath, { remotePath: entry.fullPath, mode: entry.mode, watcher })\r\n\r\n this.platform.openPath(localPath)\r\n } catch (e) {\r\n console.error('[SFTP-UI] Open remote file failed', e)\r\n }\r\n }\r\n\r\n private async syncBackRemoteFile (localPath: string): Promise<void> {\r\n if (!this.sftpSession || !this.connected) {\r\n return\r\n }\r\n const info = this.openedRemoteFiles.get(localPath)\r\n if (!info) {\r\n return\r\n }\r\n try {\r\n const upload = new LocalPathFileUpload(localPath)\r\n this.trackTransfer(upload, 'upload', info.remotePath, localPath)\r\n await this.sftpSession.upload(info.remotePath, upload)\r\n await this.refreshRemote()\r\n } catch (e) {\r\n console.error('[SFTP-UI] Sync-back remote file failed', e)\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpTerminalDecorator extends TerminalDecorator {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n override attach (terminal: BaseTerminalTabComponent): void {\r\n super.attach(terminal)\r\n\r\n // Best-effort DOM injection: place button near the existing Reconnect button if present.\r\n const tryInsert = () => {\r\n try {\r\n const host: HTMLElement | null = terminal.element?.nativeElement ?? null\r\n if (!host) {\r\n return false\r\n }\r\n\r\n // Find a likely toolbar area in the tab UI\r\n const toolbar =\r\n (host.querySelector('.terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('.btn-toolbar') as HTMLElement | null)\r\n\r\n const container = toolbar ?? host\r\n\r\n if (container.querySelector('[data-tabby-sftp-ui-button=\"1\"]')) {\r\n return true\r\n }\r\n\r\n const btn = document.createElement('button')\r\n btn.type = 'button'\r\n // Match Tabby's terminal toolbar buttons styling\r\n btn.className = 'btn btn-sm btn-link me-2'\r\n btn.setAttribute('data-tabby-sftp-ui-button', '1')\r\n btn.title = 'SFTP-UI'\r\n btn.textContent = 'SFTP-UI'\r\n btn.style.pointerEvents = 'auto'\r\n btn.style.zIndex = '10'\r\n btn.style.position = 'relative'\r\n btn.addEventListener('mousedown', (ev) => {\r\n ev.stopPropagation()\r\n })\r\n btn.addEventListener('click', (ev) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n this.sftpUi.openForSourceTab(terminal as any)\r\n })\r\n\r\n // If there's a Reconnect button, insert next to it.\r\n const allButtons = Array.from(container.querySelectorAll('button')) as HTMLButtonElement[]\r\n const reconnectButton = allButtons.find(b => {\r\n const t = `${b.textContent ?? ''} ${b.title ?? ''} ${b.getAttribute('aria-label') ?? ''}`.toLowerCase()\r\n return t.includes('reconnect') || t.includes('переподключ')\r\n })\r\n\r\n if (reconnectButton?.parentElement) {\r\n // Put it right after Reconnect to avoid overlay issues\r\n reconnectButton.parentElement.insertBefore(btn, reconnectButton.nextSibling)\r\n } else {\r\n container.appendChild(btn)\r\n }\r\n\r\n return true\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n // try a few times while the view is settling\r\n let attempts = 0\r\n const timer = setInterval(() => {\r\n attempts++\r\n if (tryInsert() || attempts > 20) {\r\n clearInterval(timer)\r\n }\r\n }, 500)\r\n\r\n this.subscribeUntilDetached(terminal, { unsubscribe: () => clearInterval(timer) } as any)\r\n }\r\n}\r\n\r\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, HotkeysService, LogService, NotificationsService, SplitTabComponent } from 'tabby-core'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\n\r\n@Injectable()\r\nexport class SftpUiService {\r\n private logger: any\r\n\r\n constructor (\r\n private app: AppService,\r\n private hotkeys: HotkeysService,\r\n private log: LogService,\r\n private zone: NgZone,\r\n private notifications: NotificationsService,\r\n ) {\r\n this.logger = this.log.create('sftp-ui')\r\n\r\n this.hotkeys.hotkey$.subscribe(h => {\r\n if (h === 'open-sftp-ui') {\r\n this.open()\r\n }\r\n })\r\n\r\n this.logger.info('loaded')\r\n }\r\n\r\n open (): void {\r\n const active = this.app.activeTab\r\n const focused = active instanceof SplitTabComponent ? (active.getFocusedTab?.() ?? null) : active\r\n this.openForSourceTab(focused)\r\n }\r\n\r\n openForSourceTab (sourceTab: any): void {\r\n const sshSession = sourceTab?.sshSession ?? null\r\n const profile = sourceTab?.profile ?? null\r\n\r\n this.zone.run(() => {\r\n try {\r\n if (!sshSession) {\r\n this.notifications.error('SFTP-UI', 'No SSH session on current tab')\r\n return\r\n }\r\n const baseTitle =\r\n sourceTab?.customTitle ||\r\n sourceTab?.title ||\r\n profile?.name ||\r\n profile?.options?.host ||\r\n 'SFTP'\r\n const tab = this.app.openNewTab({\r\n type: SftpManagerTabComponent,\r\n inputs: {\r\n sshSession,\r\n profile,\r\n },\r\n })\r\n tab.setTitle(`${baseTitle} + SFTP`)\r\n this.notifications.notice('SFTP-UI opened')\r\n } catch (e) {\r\n this.notifications.error('SFTP-UI failed to open', String(e))\r\n this.logger.error('openForSourceTab failed', e)\r\n }\r\n })\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\n\r\nexport type SFTPFile = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n isSymlink: boolean\r\n mode: number\r\n size: number\r\n modified: Date\r\n}\r\n\r\nexport type SFTPSessionLike = {\r\n readdir: (p: string) => Promise<SFTPFile[]>\r\n mkdir: (p: string) => Promise<void>\r\n rmdir: (p: string) => Promise<void>\r\n unlink: (p: string) => Promise<void>\r\n rename: (oldPath: string, newPath: string) => Promise<void>\r\n upload: (remotePath: string, transfer: import('tabby-core').FileUpload) => Promise<void>\r\n download: (remotePath: string, transfer: import('tabby-core').FileDownload) => Promise<void>\r\n}\r\n\r\nexport type SSHSessionLike = {\r\n openSFTP: () => Promise<SFTPSessionLike>\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SftpConnectionService {\r\n async openFromSSHSession (sshSession: SSHSessionLike): Promise<SFTPSessionLike> {\r\n return await sshSession.openSFTP()\r\n }\r\n}\r\n\r\n","module.exports = require(\"fs/promises\");","module.exports = require(\"os\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tif (!(moduleId in __webpack_modules__)) {\n\t\tdelete __webpack_module_cache__[moduleId];\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport { NgModule } from '@angular/core'\r\nimport { HotkeyProvider, TabContextMenuItemProvider } from 'tabby-core'\r\nimport { TerminalDecorator } from 'tabby-terminal'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\nimport { SftpContextMenuProvider } from './sftp-context-menu'\r\nimport { SftpUiHotkeyProvider } from './sftp-hotkey'\r\nimport { SftpUiService } from './sftp-ui.service'\r\nimport { SftpTerminalDecorator } from './sftp-terminal-decorator'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ],\r\n declarations: [\r\n SftpManagerTabComponent,\r\n ],\r\n providers: [\r\n { provide: TabContextMenuItemProvider, useClass: SftpContextMenuProvider, multi: true },\r\n { provide: HotkeyProvider, useClass: SftpUiHotkeyProvider, multi: true },\r\n { provide: TerminalDecorator, useClass: SftpTerminalDecorator, multi: true },\r\n SftpUiService,\r\n ],\r\n})\r\nexport default class SftpUiModule {\r\n constructor (_: SftpUiService) { }\r\n}\r\n\r\nexport { SftpManagerTabComponent }\r\n"],"names":[],"sourceRoot":""}
@@ -1,6 +0,0 @@
1
- import { AppService, ToolbarButton, ToolbarButtonProvider } from 'tabby-core';
2
- export declare class SftpToolbarButtons extends ToolbarButtonProvider {
3
- private app;
4
- constructor(app: AppService);
5
- provide(): ToolbarButton[];
6
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tabby-sftp-ui",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "SFTP UI for Tabby (Termius-like file manager).",
5
5
  "keywords": [
6
6
  "tabby-plugin"